Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add cluster addons support #893

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ example-klog: install
# INTEGRATION TESTS

.PHONY: integration
integration: integration-basic integration-external-policies
integration: integration-basic integration-cluster-addons integration-external-policies

.PHONY: integration-reset
integration-reset:
Expand All @@ -113,6 +113,13 @@ integration-basic: integration-reset
@terraform -chdir=./tests/basic plan
@terraform -chdir=./tests/basic apply -auto-approve

.PHONY: integration-cluster-addons
integration-cluster-addons: integration-reset
@terraform -chdir=./tests/cluster-addons init
@terraform -chdir=./tests/cluster-addons validate
@terraform -chdir=./tests/cluster-addons plan
@terraform -chdir=./tests/cluster-addons apply -auto-approve

.PHONY: integration-external-policies
integration-external-policies: integration-reset
@terraform -chdir=./tests/external-policies init
Expand Down
1 change: 1 addition & 0 deletions docs/data-sources/cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ The following arguments are supported:
- `annotations` - (Computed) - Map(String) - Annotations is an unstructured key value map stored with a resource that may be<br />set by external tools to store and retrieve arbitrary metadata. They are not<br />queryable and should be preserved when modifying objects.
- `name` - (Required) - String - Name defines the cluster name.
- `admin_ssh_key` - (Computed) - String - AdminSshKey defines the cluster admin ssh key.
- `cluster_addons` - (Computed) - List(String) - ClusterAddons defines the cluster addons.
- `secrets` - (Computed) - [cluster_secrets](#cluster_secrets) - Secrets defines the cluster secret.

## Nested resources
Expand Down
1 change: 1 addition & 0 deletions docs/resources/cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ The following arguments are supported:
- `annotations` - (Optional) - Map(String) - Annotations is an unstructured key value map stored with a resource that may be<br />set by external tools to store and retrieve arbitrary metadata. They are not<br />queryable and should be preserved when modifying objects.
- `name` - (Required) - (Force new) - String - Name defines the cluster name.
- `admin_ssh_key` - (Optional) - (Sensitive) - String - AdminSshKey defines the cluster admin ssh key.
- `cluster_addons` - (Optional) - List(String) - ClusterAddons defines the cluster addons.
- `secrets` - (Optional) - [cluster_secrets](#cluster_secrets) - Secrets defines the cluster secret.
- `revision` - (Computed) - Int - Revision is incremented every time the resource changes, this is useful for triggering cluster updater.

Expand Down
59 changes: 57 additions & 2 deletions pkg/api/resources/Cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import (

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kops/pkg/apis/kops"
kopsutil "k8s.io/kops/pkg/apis/kops/util"
"k8s.io/kops/pkg/client/simple"
"k8s.io/kops/pkg/clusteraddons"
"k8s.io/kops/pkg/resources"
"k8s.io/kops/pkg/resources/ops"
"k8s.io/kops/pkg/wellknownoperators"
"k8s.io/kops/upup/pkg/fi/cloudup"
)

Expand All @@ -27,6 +30,8 @@ type Cluster struct {
Name string
// AdminSshKey defines the cluster admin ssh key
AdminSshKey string
// ClusterAddons defines the cluster addons
ClusterAddons []string
// Secrets defines the cluster secret
Secrets *ClusterSecrets
// Revision is incremented every time the resource changes, this is useful for triggering cluster updater
Expand Down Expand Up @@ -88,7 +93,7 @@ func GetCluster(name string, clientset simple.Clientset) (*Cluster, error) {
return cluster, nil
}

func CreateCluster(name string, labels map[string]string, annotations map[string]string, adminSshKey string, secrets *ClusterSecrets, spec kops.ClusterSpec, clientset simple.Clientset) (*Cluster, error) {
func CreateCluster(name string, labels map[string]string, annotations map[string]string, adminSshKey string, secrets *ClusterSecrets, clusterAddons []string, spec kops.ClusterSpec, clientset simple.Clientset) (*Cluster, error) {
kc := makeKopsCluster(name, labels, annotations, spec)
cloud, err := cloudup.BuildCloud(kc)
if err != nil {
Expand All @@ -97,6 +102,27 @@ func CreateCluster(name string, labels map[string]string, annotations map[string
if err := cloudup.PerformAssignments(kc, cloud); err != nil {
return nil, err
}
// TODO: deep validate ?
// TODO: assets builder ?
channel, err := cloudup.ChannelForCluster(kc)
if err != nil {
return nil, err
}
kubernetesVersion, err := kopsutil.ParseKubernetesVersion(kc.Spec.KubernetesVersion)
if err != nil {
return nil, err
}
addons, err := wellknownoperators.CreateAddons(channel, kubernetesVersion, kc)
if err != nil {
return nil, err
}
for _, addon := range clusterAddons {
addon, err := clusteraddons.ParseClusterAddon([]byte(addon))
if err != nil {
return nil, err
}
addons = append(addons, addon.Objects...)
}
_, err = clientset.CreateCluster(context.Background(), kc)
if err != nil {
return nil, err
Expand All @@ -105,6 +131,10 @@ func CreateCluster(name string, labels map[string]string, annotations map[string
if err != nil {
return nil, err
}
addonsClient := clientset.AddonsFor(kc)
if err := addonsClient.Replace(addons); err != nil {
return nil, err
}
if adminSshKey != "" {
sshCredentialStore, err := clientset.SSHCredentialStore(kc)
if err != nil {
Expand Down Expand Up @@ -133,7 +163,7 @@ func CreateCluster(name string, labels map[string]string, annotations map[string
return makeCluster(adminSshKey, secrets, kc), nil
}

func UpdateCluster(name string, labels map[string]string, annotations map[string]string, adminSshKey string, secrets *ClusterSecrets, spec kops.ClusterSpec, clientset simple.Clientset) (*Cluster, error) {
func UpdateCluster(name string, labels map[string]string, annotations map[string]string, adminSshKey string, secrets *ClusterSecrets, clusterAddons []string, spec kops.ClusterSpec, clientset simple.Clientset) (*Cluster, error) {
kc := makeKopsCluster(name, labels, annotations, spec)
cloud, err := cloudup.BuildCloud(kc)
if err != nil {
Expand All @@ -142,10 +172,35 @@ func UpdateCluster(name string, labels map[string]string, annotations map[string
if err := cloudup.PerformAssignments(kc, cloud); err != nil {
return nil, err
}
// TODO: deep validate ?
// TODO: assets builder ?
channel, err := cloudup.ChannelForCluster(kc)
if err != nil {
return nil, err
}
kubernetesVersion, err := kopsutil.ParseKubernetesVersion(kc.Spec.KubernetesVersion)
if err != nil {
return nil, err
}
addons, err := wellknownoperators.CreateAddons(channel, kubernetesVersion, kc)
if err != nil {
return nil, err
}
for _, addon := range clusterAddons {
addon, err := clusteraddons.ParseClusterAddon([]byte(addon))
if err != nil {
return nil, err
}
addons = append(addons, addon.Objects...)
}
kc, err = clientset.UpdateCluster(context.Background(), kc, nil)
if err != nil {
return nil, err
}
addonsClient := clientset.AddonsFor(kc)
if err := addonsClient.Replace(addons); err != nil {
return nil, err
}
sshCredentialStore, err := clientset.SSHCredentialStore(kc)
if err != nil {
return nil, err
Expand Down
22 changes: 20 additions & 2 deletions pkg/resources/Cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ func Cluster() *schema.Resource {

func ClusterCreate(c context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
in := resourcesschema.ExpandResourceCluster(d.Get("").(map[string]interface{}))
if cluster, err := resources.CreateCluster(in.Name, in.Labels, in.Annotations, in.AdminSshKey, in.Secrets, in.ClusterSpec, config.Clientset(m)); err != nil {
if cluster, err := resources.CreateCluster(
in.Name,
in.Labels,
in.Annotations,
in.AdminSshKey,
in.Secrets,
in.ClusterAddons,
in.ClusterSpec,
config.Clientset(m),
); err != nil {
return diag.FromErr(err)
} else {
d.SetId(cluster.Name)
Expand All @@ -40,7 +49,16 @@ func ClusterCreate(c context.Context, d *schema.ResourceData, m interface{}) dia

func ClusterUpdate(c context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
in := resourcesschema.ExpandResourceCluster(d.Get("").(map[string]interface{}))
if cluster, err := resources.UpdateCluster(in.Name, in.Labels, in.Annotations, in.AdminSshKey, in.Secrets, in.ClusterSpec, config.Clientset(m)); err != nil {
if cluster, err := resources.UpdateCluster(
in.Name,
in.Labels,
in.Annotations,
in.AdminSshKey,
in.Secrets,
in.ClusterAddons,
in.ClusterSpec,
config.Clientset(m),
); err != nil {
return diag.FromErr(err)
} else {
d.SetId(cluster.Name)
Expand Down
22 changes: 22 additions & 0 deletions pkg/schemas/resources/DataSource_Cluster.generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func DataSourceCluster() *schema.Resource {
"annotations": ComputedMap(String()),
"name": RequiredString(),
"admin_ssh_key": ComputedString(),
"cluster_addons": ComputedList(String()),
"secrets": ComputedStruct(DataSourceClusterSecrets()),
},
}
Expand Down Expand Up @@ -181,6 +182,18 @@ func ExpandDataSourceCluster(in map[string]interface{}) resources.Cluster {
AdminSshKey: func(in interface{}) string {
return string(ExpandString(in))
}(in["admin_ssh_key"]),
ClusterAddons: func(in interface{}) []string {
return func(in interface{}) []string {
if in == nil {
return nil
}
var out []string
for _, in := range in.([]interface{}) {
out = append(out, string(ExpandString(in)))
}
return out
}(in)
}(in["cluster_addons"]),
Secrets: func(in interface{}) *resources.ClusterSecrets {
return func(in interface{}) *resources.ClusterSecrets {
if in == nil {
Expand Down Expand Up @@ -234,6 +247,15 @@ func FlattenDataSourceClusterInto(in resources.Cluster, out map[string]interface
out["admin_ssh_key"] = func(in string) interface{} {
return FlattenString(string(in))
}(in.AdminSshKey)
out["cluster_addons"] = func(in []string) interface{} {
return func(in []string) []interface{} {
var out []interface{}
for _, in := range in {
out = append(out, FlattenString(string(in)))
}
return out
}(in)
}(in.ClusterAddons)
out["secrets"] = func(in *resources.ClusterSecrets) interface{} {
return func(in *resources.ClusterSecrets) interface{} {
if in == nil {
Expand Down
25 changes: 25 additions & 0 deletions pkg/schemas/resources/DataSource_Cluster.generated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ func TestExpandDataSourceCluster(t *testing.T) {
"annotations": func() map[string]interface{} { return nil }(),
"name": "",
"admin_ssh_key": "",
"cluster_addons": func() []interface{} { return nil }(),
"secrets": nil,
},
},
Expand Down Expand Up @@ -197,6 +198,7 @@ func TestFlattenDataSourceClusterInto(t *testing.T) {
"annotations": func() map[string]interface{} { return nil }(),
"name": "",
"admin_ssh_key": "",
"cluster_addons": func() []interface{} { return nil }(),
"secrets": nil,
}
type args struct {
Expand Down Expand Up @@ -1050,6 +1052,17 @@ func TestFlattenDataSourceClusterInto(t *testing.T) {
},
want: _default,
},
{
name: "ClusterAddons - default",
args: args{
in: func() resources.Cluster {
subject := resources.Cluster{}
subject.ClusterAddons = nil
return subject
}(),
},
want: _default,
},
{
name: "Secrets - default",
args: args{
Expand Down Expand Up @@ -1153,6 +1166,7 @@ func TestFlattenDataSourceCluster(t *testing.T) {
"annotations": func() map[string]interface{} { return nil }(),
"name": "",
"admin_ssh_key": "",
"cluster_addons": func() []interface{} { return nil }(),
"secrets": nil,
}
type args struct {
Expand Down Expand Up @@ -2006,6 +2020,17 @@ func TestFlattenDataSourceCluster(t *testing.T) {
},
want: _default,
},
{
name: "ClusterAddons - default",
args: args{
in: func() resources.Cluster {
subject := resources.Cluster{}
subject.ClusterAddons = nil
return subject
}(),
},
want: _default,
},
{
name: "Secrets - default",
args: args{
Expand Down
22 changes: 22 additions & 0 deletions pkg/schemas/resources/Resource_Cluster.generated.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func ResourceCluster() *schema.Resource {
"annotations": OptionalMap(String()),
"name": ForceNew(RequiredString()),
"admin_ssh_key": Sensitive(OptionalString()),
"cluster_addons": OptionalList(String()),
"secrets": OptionalStruct(ResourceClusterSecrets()),
"revision": ComputedInt(),
},
Expand Down Expand Up @@ -182,6 +183,18 @@ func ExpandResourceCluster(in map[string]interface{}) resources.Cluster {
AdminSshKey: func(in interface{}) string {
return string(ExpandString(in))
}(in["admin_ssh_key"]),
ClusterAddons: func(in interface{}) []string {
return func(in interface{}) []string {
if in == nil {
return nil
}
var out []string
for _, in := range in.([]interface{}) {
out = append(out, string(ExpandString(in)))
}
return out
}(in)
}(in["cluster_addons"]),
Secrets: func(in interface{}) *resources.ClusterSecrets {
return func(in interface{}) *resources.ClusterSecrets {
if in == nil {
Expand Down Expand Up @@ -238,6 +251,15 @@ func FlattenResourceClusterInto(in resources.Cluster, out map[string]interface{}
out["admin_ssh_key"] = func(in string) interface{} {
return FlattenString(string(in))
}(in.AdminSshKey)
out["cluster_addons"] = func(in []string) interface{} {
return func(in []string) []interface{} {
var out []interface{}
for _, in := range in {
out = append(out, FlattenString(string(in)))
}
return out
}(in)
}(in.ClusterAddons)
out["secrets"] = func(in *resources.ClusterSecrets) interface{} {
return func(in *resources.ClusterSecrets) interface{} {
if in == nil {
Expand Down
25 changes: 25 additions & 0 deletions pkg/schemas/resources/Resource_Cluster.generated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ func TestExpandResourceCluster(t *testing.T) {
"annotations": func() map[string]interface{} { return nil }(),
"name": "",
"admin_ssh_key": "",
"cluster_addons": func() []interface{} { return nil }(),
"secrets": nil,
"revision": 0,
},
Expand Down Expand Up @@ -198,6 +199,7 @@ func TestFlattenResourceClusterInto(t *testing.T) {
"annotations": func() map[string]interface{} { return nil }(),
"name": "",
"admin_ssh_key": "",
"cluster_addons": func() []interface{} { return nil }(),
"secrets": nil,
"revision": 0,
}
Expand Down Expand Up @@ -1052,6 +1054,17 @@ func TestFlattenResourceClusterInto(t *testing.T) {
},
want: _default,
},
{
name: "ClusterAddons - default",
args: args{
in: func() resources.Cluster {
subject := resources.Cluster{}
subject.ClusterAddons = nil
return subject
}(),
},
want: _default,
},
{
name: "Secrets - default",
args: args{
Expand Down Expand Up @@ -1166,6 +1179,7 @@ func TestFlattenResourceCluster(t *testing.T) {
"annotations": func() map[string]interface{} { return nil }(),
"name": "",
"admin_ssh_key": "",
"cluster_addons": func() []interface{} { return nil }(),
"secrets": nil,
"revision": 0,
}
Expand Down Expand Up @@ -2020,6 +2034,17 @@ func TestFlattenResourceCluster(t *testing.T) {
},
want: _default,
},
{
name: "ClusterAddons - default",
args: args{
in: func() resources.Cluster {
subject := resources.Cluster{}
subject.ClusterAddons = nil
return subject
}(),
},
want: _default,
},
{
name: "Secrets - default",
args: args{
Expand Down
Loading