diff --git a/docs/data-sources/ske_cluster.md b/docs/data-sources/ske_cluster.md index be663d6d9..781b1ec5c 100644 --- a/docs/data-sources/ske_cluster.md +++ b/docs/data-sources/ske_cluster.md @@ -33,6 +33,7 @@ data "stackit_ske_cluster" "example" { ### Read-Only +- `access` (Attributes) Configure access to the cluster (see [below for nested schema](#nestedatt--access)) - `egress_address_ranges` (List of String) The outgoing network ranges (in CIDR notation) of traffic originating from workload on the cluster. - `extensions` (Attributes) A single extensions block as defined below (see [below for nested schema](#nestedatt--extensions)) - `hibernations` (Attributes List) One or more hibernation block as defined below. (see [below for nested schema](#nestedatt--hibernations)) @@ -44,6 +45,23 @@ data "stackit_ske_cluster" "example" { - `node_pools` (Attributes List) One or more `node_pool` block as defined below. (see [below for nested schema](#nestedatt--node_pools)) - `pod_address_ranges` (List of String) The network ranges (in CIDR notation) used by pods of the cluster. + +### Nested Schema for `access` + +Read-Only: + +- `idp` (Attributes) Configure IDP (see [below for nested schema](#nestedatt--access--idp)) + + +### Nested Schema for `access.idp` + +Read-Only: + +- `enabled` (Boolean) Enable IDP integration for the cluster. +- `type` (String) The IDP type. Possible values: 'stackit'. + + + ### Nested Schema for `extensions` diff --git a/docs/resources/ske_cluster.md b/docs/resources/ske_cluster.md index 572ba210c..5850f36bc 100644 --- a/docs/resources/ske_cluster.md +++ b/docs/resources/ske_cluster.md @@ -65,6 +65,7 @@ To keep your Terraform plans clean and readable, always append new node pools to ### Optional +- `access` (Attributes) Configure access to the cluster (see [below for nested schema](#nestedatt--access)) - `extensions` (Attributes) A single extensions block as defined below. (see [below for nested schema](#nestedatt--extensions)) - `hibernations` (Attributes List) One or more hibernation block as defined below. (see [below for nested schema](#nestedatt--hibernations)) - `kubernetes_version_min` (String) The minimum Kubernetes version. This field will be used to set the minimum kubernetes version on creation/update of the cluster. If unset, the latest supported Kubernetes version will be used. SKE automatically updates the cluster Kubernetes version if you have set `maintenance.enable_kubernetes_version_updates` to true or if there is a mandatory update, as described in [General information for Kubernetes & OS updates](https://docs.stackit.cloud/products/runtime/kubernetes-engine/basics/version-updates/). To get the current kubernetes version being used for your cluster, use the read-only `kubernetes_version_used` field. @@ -122,6 +123,23 @@ Optional: + +### Nested Schema for `access` + +Optional: + +- `idp` (Attributes) Configure IDP (see [below for nested schema](#nestedatt--access--idp)) + + +### Nested Schema for `access.idp` + +Optional: + +- `enabled` (Boolean) Enable IDP integration for the cluster. +- `type` (String) The IDP type. Possible values: 'stackit'. + + + ### Nested Schema for `extensions` diff --git a/stackit/internal/services/ske/cluster/datasource.go b/stackit/internal/services/ske/cluster/datasource.go index b32a0a8c5..242ab2250 100644 --- a/stackit/internal/services/ske/cluster/datasource.go +++ b/stackit/internal/services/ske/cluster/datasource.go @@ -330,6 +330,26 @@ func (r *clusterDataSource) Schema(_ context.Context, _ datasource.SchemaRequest Optional: true, Description: "The resource region. If not defined, the provider region is used.", }, + "access": schema.SingleNestedAttribute{ + Description: descriptions["access"], + Computed: true, + Attributes: map[string]schema.Attribute{ + "idp": schema.SingleNestedAttribute{ + Description: descriptions["access_idp"], + Computed: true, + Attributes: map[string]schema.Attribute{ + "enabled": schema.BoolAttribute{ + Description: descriptions["access_idp_enabled"], + Computed: true, + }, + "type": schema.StringAttribute{ + Description: descriptions["access_idp_type"], + Computed: true, + }, + }, + }, + }, + }, }, } } diff --git a/stackit/internal/services/ske/cluster/resource.go b/stackit/internal/services/ske/cluster/resource.go index 70aa7a2b0..8c395ce59 100644 --- a/stackit/internal/services/ske/cluster/resource.go +++ b/stackit/internal/services/ske/cluster/resource.go @@ -95,6 +95,7 @@ type Model struct { EgressAddressRanges types.List `tfsdk:"egress_address_ranges"` PodAddressRanges types.List `tfsdk:"pod_address_ranges"` Region types.String `tfsdk:"region"` + Access types.Object `tfsdk:"access"` } // Struct corresponding to Model.NodePools[i] @@ -280,6 +281,24 @@ type clusterResource struct { providerData core.ProviderData } +type access struct { + IDP types.Object `tfsdk:"idp"` +} + +var accessTypes = map[string]attr.Type{ + "idp": basetypes.ObjectType{AttrTypes: idpTypes}, +} + +type idp struct { + Enabled types.Bool `tfsdk:"enabled"` + Type types.String `tfsdk:"type"` +} + +var idpTypes = map[string]attr.Type{ + "enabled": basetypes.BoolType{}, + "type": basetypes.StringType{}, +} + // ModifyPlan implements resource.ResourceWithModifyPlan. // Use the modifier to set the effective region in the current plan. func (r *clusterResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) { // nolint:gocritic // function signature required by Terraform @@ -380,18 +399,22 @@ func (r *clusterResource) Configure(ctx context.Context, req resource.ConfigureR tflog.Info(ctx, "SKE cluster clients configured") } +var descriptions = map[string]string{ + "main": "SKE Cluster Resource schema. Must have a `region` specified in the provider configuration.", + "node_pools_plan_note": "When updating `node_pools` of a `stackit_ske_cluster`, the Terraform plan might appear incorrect as it matches the node pools by index rather than by name. " + + "However, the SKE API correctly identifies node pools by name and applies the intended changes. Please review your changes carefully to ensure the correct configuration will be applied.", + "max_surge": "Maximum number of additional VMs that are created during an update.", + "max_unavailable": "Maximum number of VMs that that can be unavailable during an update.", + "nodepool_validators": "If set (larger than 0), then it must be at least the amount of zones configured for the nodepool. The `max_surge` and `max_unavailable` fields cannot both be unset at the same time.", + "region": "The resource region. If not defined, the provider region is used.", + "access": "Configure access to the cluster", + "access_idp": "Configure IDP", + "access_idp_enabled": "Enable IDP integration for the cluster.", + "access_idp_type": "The IDP type. Possible values: 'stackit'.", +} + // Schema defines the schema for the resource. func (r *clusterResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { - descriptions := map[string]string{ - "main": "SKE Cluster Resource schema. Must have a `region` specified in the provider configuration.", - "node_pools_plan_note": "When updating `node_pools` of a `stackit_ske_cluster`, the Terraform plan might appear incorrect as it matches the node pools by index rather than by name. " + - "However, the SKE API correctly identifies node pools by name and applies the intended changes. Please review your changes carefully to ensure the correct configuration will be applied.", - "max_surge": "Maximum number of additional VMs that are created during an update.", - "max_unavailable": "Maximum number of VMs that that can be unavailable during an update.", - "nodepool_validators": "If set (larger than 0), then it must be at least the amount of zones configured for the nodepool. The `max_surge` and `max_unavailable` fields cannot both be unset at the same time.", - "region": "The resource region. If not defined, the provider region is used.", - } - resp.Schema = schema.Schema{ Description: fmt.Sprintf("%s\n%s", descriptions["main"], descriptions["node_pools_plan_note"]), // Callout block: https://developer.hashicorp.com/terraform/registry/providers/docs#callouts @@ -795,6 +818,35 @@ func (r *clusterResource) Schema(_ context.Context, _ resource.SchemaRequest, re stringplanmodifier.RequiresReplace(), }, }, + "access": schema.SingleNestedAttribute{ + Description: descriptions["access"], + Optional: true, + Computed: true, + Attributes: map[string]schema.Attribute{ + "idp": schema.SingleNestedAttribute{ + Description: descriptions["access_idp"], + Optional: true, + Computed: true, + Attributes: map[string]schema.Attribute{ + "enabled": schema.BoolAttribute{ + Description: descriptions["access_idp_enabled"], + Optional: true, + Computed: true, + Default: booldefault.StaticBool(false), + }, + "type": schema.StringAttribute{ + Description: descriptions["access_idp_type"], + Optional: true, + Computed: true, + Default: stringdefault.StaticString("stackit"), + Validators: []validator.String{ + stringvalidator.OneOf("stackit"), + }, + }, + }, + }, + }, + }, }, } } @@ -912,7 +964,7 @@ func sortK8sVersions(versions []ske.KubernetesVersion) { } // loadAvailableVersions loads the available k8s and machine versions from the API. -// The k8s versions are sorted descending order, i.e. the latest versions (including previews) +// The k8s versions are sorted descending order, i.e. the latest versions (including previews) // are listed first func (r *clusterResource) loadAvailableVersions(ctx context.Context, region string) ([]ske.KubernetesVersion, []ske.MachineImage, error) { res, err := r.skeClient.DefaultAPI.ListProviderOptions(ctx, region).Execute() @@ -995,6 +1047,11 @@ func (r *clusterResource) createOrUpdateCluster(ctx context.Context, diags *diag core.LogAndAddError(ctx, diags, "Error creating/updating cluster", fmt.Sprintf("Creating extension API payload: %v", err)) return } + access, err := toAccessPayload(ctx, model) + if err != nil { + core.LogAndAddError(ctx, diags, "Error creating/updating cluster", fmt.Sprintf("Creating access API payload: %v", err)) + return + } payload := ske.CreateOrUpdateClusterPayload{ Extensions: extensions, @@ -1003,6 +1060,7 @@ func (r *clusterResource) createOrUpdateCluster(ctx context.Context, diags *diag Maintenance: maintenance, Network: network, Nodepools: nodePools, + Access: access, } _, err = r.skeClient.DefaultAPI.CreateOrUpdateCluster(ctx, projectId, region, name).CreateOrUpdateClusterPayload(payload).Execute() if err != nil { @@ -1409,6 +1467,26 @@ func toExtensionsPayload(ctx context.Context, m *Model) (*ske.Extension, error) }, nil } +func toAccessPayload(ctx context.Context, m *Model) (*ske.Access, error) { + if utils.IsUndefined(m.Access) { + return nil, nil + } + access := access{} + diags := m.Access.As(ctx, &access, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return nil, fmt.Errorf("converting access object: %v", diags.Errors()) + } + idp := idp{} + diags = access.IDP.As(ctx, &idp, basetypes.ObjectAsOptions{}) + if diags.HasError() { + return nil, fmt.Errorf("converting idp object: %v", diags.Errors()) + } + + return &ske.Access{ + Idp: ske.NewIDP(idp.Enabled.ValueBool(), idp.Type.ValueString()), + }, nil +} + func parseMaintenanceWindowTime(t string) (time.Time, error) { v, err := time.Parse("15:04:05-07:00", t) if err != nil { @@ -1548,6 +1626,10 @@ func mapFields(ctx context.Context, cl *ske.Cluster, m *Model, region string) er if err != nil { return fmt.Errorf("map extensions: %w", err) } + err = mapAccess(ctx, cl, m) + if err != nil { + return fmt.Errorf("map access: %w", err) + } return nil } @@ -2043,6 +2125,31 @@ func mapExtensions(ctx context.Context, cl *ske.Cluster, m *Model) error { return nil } +func mapAccess(ctx context.Context, cl *ske.Cluster, m *Model) error { + var diags diag.Diagnostics + + // explicitly no nil checks, the API won't return nil values here, despite the types suggesting the possibility + idp := idp{ + Enabled: types.BoolValue(cl.Access.Idp.Enabled), + Type: types.StringValue(cl.Access.Idp.Type), + } + idpObject, diags := types.ObjectValueFrom(ctx, idpTypes, idp) + if diags.HasError() { + return fmt.Errorf("creating idp object: %w", core.DiagsToError(diags)) + } + + access := access{ + IDP: idpObject, + } + accessObject, diags := types.ObjectValueFrom(ctx, accessTypes, access) + if diags.HasError() { + return fmt.Errorf("creating access object: %w", core.DiagsToError(diags)) + } + + m.Access = accessObject + return nil +} + func toKubernetesPayload(m *Model, availableVersions []ske.KubernetesVersion, currentKubernetesVersion *string, diags *diag.Diagnostics) (kubernetesPayload *ske.Kubernetes, hasDeprecatedVersion bool, err error) { providedVersionMin := m.KubernetesVersionMin.ValueStringPointer() versionUsed, hasDeprecatedVersion, err := latestMatchingKubernetesVersion(availableVersions, providedVersionMin, currentKubernetesVersion, diags) diff --git a/stackit/internal/services/ske/cluster/resource_test.go b/stackit/internal/services/ske/cluster/resource_test.go index cf272de95..5112cd777 100644 --- a/stackit/internal/services/ske/cluster/resource_test.go +++ b/stackit/internal/services/ske/cluster/resource_test.go @@ -39,6 +39,12 @@ func TestMapFields(t *testing.T) { types.ListNull(types.ObjectType{AttrTypes: nodePoolTypes}), &ske.Cluster{ Name: new("name"), + Access: &ske.Access{ + Idp: &ske.IDP{ + Enabled: false, + Type: "stackit", + }, + }, }, testRegion, Model{ @@ -54,6 +60,7 @@ func TestMapFields(t *testing.T) { PodAddressRanges: types.ListNull(types.StringType), Region: types.StringValue(testRegion), KubernetesVersionUsed: types.StringValue(""), + Access: defaultAccess, }, true, }, @@ -145,6 +152,12 @@ func TestMapFields(t *testing.T) { EgressAddressRanges: []string{"0.0.0.0/32", "1.1.1.1/32"}, PodAddressRanges: []string{"0.0.0.0/32", "1.1.1.1/32"}, }, + Access: &ske.Access{ + Idp: &ske.IDP{ + Enabled: true, + Type: "stackit", + }, + }, }, testRegion, Model{ @@ -261,6 +274,12 @@ func TestMapFields(t *testing.T) { }), }), Region: types.StringValue(testRegion), + Access: types.ObjectValueMust(accessTypes, map[string]attr.Value{ + "idp": types.ObjectValueMust(idpTypes, map[string]attr.Value{ + "enabled": types.BoolValue(true), + "type": types.StringValue("stackit"), + }), + }), }, true, }, @@ -271,6 +290,12 @@ func TestMapFields(t *testing.T) { &ske.Cluster{ Name: new("name"), Network: &ske.Network{}, + Access: &ske.Access{ + Idp: &ske.IDP{ + Enabled: false, + Type: "stackit", + }, + }, }, testRegion, Model{ @@ -286,6 +311,7 @@ func TestMapFields(t *testing.T) { PodAddressRanges: types.ListNull(types.StringType), KubernetesVersionUsed: types.StringValue(""), Region: types.StringValue(testRegion), + Access: defaultAccess, }, true, }, @@ -309,6 +335,12 @@ func TestMapFields(t *testing.T) { }, }, Name: new("name"), + Access: &ske.Access{ + Idp: &ske.IDP{ + Enabled: false, + Type: "stackit", + }, + }, }, testRegion, Model{ @@ -337,6 +369,7 @@ func TestMapFields(t *testing.T) { }), KubernetesVersionUsed: types.StringValue(""), Region: types.StringValue(testRegion), + Access: defaultAccess, }, true, }, @@ -361,6 +394,12 @@ func TestMapFields(t *testing.T) { &ske.Cluster{ Extensions: &ske.Extension{}, Name: new("name"), + Access: &ske.Access{ + Idp: &ske.IDP{ + Enabled: false, + Type: "stackit", + }, + }, }, testRegion, Model{ @@ -389,6 +428,7 @@ func TestMapFields(t *testing.T) { }), KubernetesVersionUsed: types.StringValue(""), Region: types.StringValue(testRegion), + Access: defaultAccess, }, true, }, @@ -424,6 +464,12 @@ func TestMapFields(t *testing.T) { }, }, Name: new("name"), + Access: &ske.Access{ + Idp: &ske.IDP{ + Enabled: false, + Type: "stackit", + }, + }, }, testRegion, Model{ @@ -454,6 +500,7 @@ func TestMapFields(t *testing.T) { }), KubernetesVersionUsed: types.StringValue(""), Region: types.StringValue(testRegion), + Access: defaultAccess, }, true, }, @@ -464,6 +511,12 @@ func TestMapFields(t *testing.T) { &ske.Cluster{ Extensions: &ske.Extension{}, Name: new("name"), + Access: &ske.Access{ + Idp: &ske.IDP{ + Enabled: false, + Type: "stackit", + }, + }, }, testRegion, Model{ @@ -478,6 +531,7 @@ func TestMapFields(t *testing.T) { PodAddressRanges: types.ListNull(types.StringType), KubernetesVersionUsed: types.StringValue(""), Region: types.StringValue(testRegion), + Access: defaultAccess, }, true, }, @@ -597,6 +651,12 @@ func TestMapFields(t *testing.T) { Error: nil, Hibernated: nil, }, + Access: &ske.Access{ + Idp: &ske.IDP{ + Enabled: false, + Type: "stackit", + }, + }, }, testRegion, Model{ @@ -689,6 +749,7 @@ func TestMapFields(t *testing.T) { }), }), Region: types.StringValue(testRegion), + Access: defaultAccess, }, true, }, @@ -2683,3 +2744,120 @@ func TestValidateConfig(t *testing.T) { }) } } + +func TestMapAccess(t *testing.T) { + t.Parallel() + tests := []struct { + name string + input *ske.Access + want basetypes.ObjectValue + wantErr bool + }{ + { + name: "valid IDP", + input: &ske.Access{ + Idp: &ske.IDP{ + Enabled: true, + Type: "stackit", + }, + }, + want: types.ObjectValueMust(accessTypes, map[string]attr.Value{ + "idp": types.ObjectValueMust(idpTypes, map[string]attr.Value{ + "enabled": types.BoolValue(true), + "type": types.StringValue("stackit"), + }), + }), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + m := &Model{} + cluster := &ske.Cluster{ + Access: tt.input, + } + + err := mapAccess(t.Context(), cluster, m) + if !tt.wantErr && err != nil { + t.Fatalf("unexpected error: %v", err) + } + if tt.wantErr && err == nil { + t.Fatalf("expected error, but got none") + } + if diff := cmp.Diff(tt.want, m.Access); diff != "" { + t.Errorf("mismatch (-want +got):\n%s", diff) + } + }) + } +} + +func TestToAccessPayload(t *testing.T) { + t.Parallel() + tests := []struct { + name string + input basetypes.ObjectValue + want *ske.Access + wantErr bool + }{ + { + name: "null access", + input: types.ObjectNull(accessTypes), + want: nil, + }, + { + name: "unknown access", + input: types.ObjectUnknown(accessTypes), + want: nil, + }, + { + name: "valid access", + input: types.ObjectValueMust(accessTypes, map[string]attr.Value{ + "idp": types.ObjectValueMust(idpTypes, map[string]attr.Value{ + "enabled": types.BoolValue(true), + "type": types.StringValue("stackit"), + }), + }), + want: &ske.Access{ + Idp: &ske.IDP{ + Enabled: true, + Type: "stackit", + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + m := &Model{ + Access: tt.input, + } + got, err := toAccessPayload(t.Context(), m) + if err != nil && !tt.wantErr { + t.Fatalf("unexpected error: %v", err) + } + if err == nil && tt.wantErr { + t.Fatalf("expected error, but got none") + } + if diff := cmp.Diff(tt.want, got); diff != "" { + t.Errorf("mismatch (-want +got):\n%s", diff) + } + }) + } +} + +var defaultIdp = types.ObjectValueMust( + idpTypes, + map[string]attr.Value{ + "enabled": types.BoolValue(false), + "type": types.StringValue("stackit"), + }, +) + +var defaultAccess = types.ObjectValueMust( + accessTypes, + map[string]attr.Value{ + "idp": defaultIdp, + }, +) diff --git a/stackit/internal/services/ske/ske_acc_test.go b/stackit/internal/services/ske/ske_acc_test.go index 0efaff3ee..b1b97243d 100644 --- a/stackit/internal/services/ske/ske_acc_test.go +++ b/stackit/internal/services/ske/ske_acc_test.go @@ -93,6 +93,7 @@ var testConfigVarsMax = config.Variables{ "dns_zone_name": config.StringVariable("acc-" + acctest.RandStringFromCharSet(6, acctest.CharSetAlpha)), "dns_name": config.StringVariable("acc-" + acctest.RandStringFromCharSet(6, acctest.CharSetAlpha) + ".runs.onstackit.cloud"), "network_control_plane_access_scope": config.StringVariable("PUBLIC"), + "access_idp_enabled": config.BoolVariable(true), } var testConfigDatasource = config.Variables{ @@ -111,6 +112,7 @@ func configVarsMaxUpdated() config.Variables { updatedConfig["kubernetes_version_min"] = config.StringVariable(skeProviderOptions.GetUpdateK8sVersion()) updatedConfig["nodepool_os_version_min"] = config.StringVariable(skeProviderOptions.GetUpdateMachineVersion()) updatedConfig["maintenance_end"] = config.StringVariable("03:03:03+00:00") + updatedConfig["access_idp_enabled"] = config.BoolVariable(false) return updatedConfig } @@ -156,6 +158,10 @@ func TestAccSKEMin(t *testing.T) { "stackit_ske_kubeconfig.kubeconfig", "cluster_name", "stackit_ske_cluster.cluster", "name", ), + + // Access: resource-min does not define an access block, we expect idp: { enabled: false, type: stackit } here because of the default + resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "access.idp.enabled", "false"), + resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "access.idp.type", "stackit"), ), }, // 2) Data source @@ -322,6 +328,9 @@ func TestAccSKEMax(t *testing.T) { resource.TestCheckResourceAttrSet("stackit_ske_cluster.cluster", "kubernetes_version_used"), resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "network.control_plane.access_scope", testutil.ConvertConfigVariable(testConfigVarsMax["network_control_plane_access_scope"])), + // Access + resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "access.idp.enabled", testutil.ConvertConfigVariable(testConfigVarsMax["access_idp_enabled"])), + resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "access.idp.type", "stackit"), // Kubeconfig resource.TestCheckResourceAttrPair( @@ -396,6 +405,9 @@ func TestAccSKEMax(t *testing.T) { resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "pod_address_ranges.#", "1"), resource.TestCheckResourceAttrSet("data.stackit_ske_cluster.cluster", "pod_address_ranges.0"), resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "network.control_plane.access_scope", testutil.ConvertConfigVariable(testConfigVarsMax["network_control_plane_access_scope"])), + // Access + resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "access.idp.enabled", testutil.ConvertConfigVariable(testConfigVarsMax["access_idp_enabled"])), + resource.TestCheckResourceAttr("data.stackit_ske_cluster.cluster", "access.idp.type", "stackit"), ), }, // 3) Import cluster @@ -422,7 +434,7 @@ func TestAccSKEMax(t *testing.T) { // The fields are not provided in the SKE API when disabled, although set actively. ImportStateVerifyIgnore: []string{"kubernetes_version_min", "node_pools.0.os_version_min", "extensions.observability.%", "extensions.observability.instance_id", "extensions.observability.enabled"}, }, - // 4) Update kubernetes version, OS version and maintenance end, downgrade of kubernetes version + // 4) Update kubernetes version, OS version and maintenance end, downgrade of kubernetes version, set access.idp.enabled to false { Config: resourceMax, ConfigVariables: configVarsMaxUpdated(), @@ -483,6 +495,9 @@ func TestAccSKEMax(t *testing.T) { resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "pod_address_ranges.#", "1"), resource.TestCheckResourceAttrSet("stackit_ske_cluster.cluster", "pod_address_ranges.0"), resource.TestCheckResourceAttrSet("stackit_ske_cluster.cluster", "kubernetes_version_used"), + // Access + resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "access.idp.enabled", testutil.ConvertConfigVariable(configVarsMaxUpdated()["access_idp_enabled"])), + resource.TestCheckResourceAttr("stackit_ske_cluster.cluster", "access.idp.type", "stackit"), ), }, // Deletion is done by the framework implicitly diff --git a/stackit/internal/services/ske/ske_test.go b/stackit/internal/services/ske/ske_test.go index 721d31b44..7c08a530d 100644 --- a/stackit/internal/services/ske/ske_test.go +++ b/stackit/internal/services/ske/ske_test.go @@ -245,6 +245,12 @@ resource "stackit_ske_cluster" "cluster" { PodAddressRanges: []string{"100.64.0.0/10"}, }), Extensions: new(ske.Extension{}), + Access: &ske.Access{ + Idp: &ske.IDP{ + Enabled: false, + Type: "stackit", + }, + }, } resource.UnitTest(t, resource.TestCase{ diff --git a/stackit/internal/services/ske/testdata/resource-max.tf b/stackit/internal/services/ske/testdata/resource-max.tf index fde7ff1cc..92377aa0e 100644 --- a/stackit/internal/services/ske/testdata/resource-max.tf +++ b/stackit/internal/services/ske/testdata/resource-max.tf @@ -36,6 +36,7 @@ variable "refresh_before" {} variable "dns_zone_name" {} variable "dns_name" {} variable "network_control_plane_access_scope" {} +variable "access_idp_enabled" {} resource "stackit_ske_cluster" "cluster" { project_id = var.project_id @@ -98,6 +99,12 @@ resource "stackit_ske_cluster" "cluster" { access_scope = var.network_control_plane_access_scope } } + access = { + idp = { + enabled = var.access_idp_enabled + type = "stackit" + } + } } resource "stackit_ske_kubeconfig" "kubeconfig" {