diff --git a/docs/data-sources/ske_cluster.md b/docs/data-sources/ske_cluster.md index be663d6d9..c67608119 100644 --- a/docs/data-sources/ske_cluster.md +++ b/docs/data-sources/ske_cluster.md @@ -43,6 +43,7 @@ data "stackit_ske_cluster" "example" { - `network` (Attributes) Network block as defined below. (see [below for nested schema](#nestedatt--network)) - `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. +- `service_account_issuer` (String) Service Account Issuer of the cluster. ### Nested Schema for `extensions` diff --git a/docs/resources/ske_cluster.md b/docs/resources/ske_cluster.md index 572ba210c..25198846a 100644 --- a/docs/resources/ske_cluster.md +++ b/docs/resources/ske_cluster.md @@ -78,6 +78,7 @@ To keep your Terraform plans clean and readable, always append new node pools to - `id` (String) Terraform's internal resource ID. It is structured as "`project_id`,`region`,`name`". - `kubernetes_version_used` (String) Full Kubernetes version used. For example, if 1.22 was set in `kubernetes_version_min`, this value may result to 1.22.15. 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/). - `pod_address_ranges` (List of String) The network ranges (in CIDR notation) used by pods of the cluster. +- `service_account_issuer` (String) Service Account Issuer of the cluster. ### Nested Schema for `node_pools` diff --git a/stackit/internal/services/ske/cluster/datasource.go b/stackit/internal/services/ske/cluster/datasource.go index b32a0a8c5..7993cd8e4 100644 --- a/stackit/internal/services/ske/cluster/datasource.go +++ b/stackit/internal/services/ske/cluster/datasource.go @@ -96,6 +96,10 @@ func (r *clusterDataSource) Schema(_ context.Context, _ datasource.SchemaRequest Computed: true, ElementType: types.StringType, }, + "service_account_issuer": schema.StringAttribute{ + Description: "Service Account Issuer of the cluster.", + Computed: true, + }, "node_pools": schema.ListNestedAttribute{ Description: "One or more `node_pool` block as defined below.", Computed: true, diff --git a/stackit/internal/services/ske/cluster/resource.go b/stackit/internal/services/ske/cluster/resource.go index 70aa7a2b0..7807c716a 100644 --- a/stackit/internal/services/ske/cluster/resource.go +++ b/stackit/internal/services/ske/cluster/resource.go @@ -94,6 +94,7 @@ type Model struct { Extensions types.Object `tfsdk:"extensions"` EgressAddressRanges types.List `tfsdk:"egress_address_ranges"` PodAddressRanges types.List `tfsdk:"pod_address_ranges"` + ServiceAccountIssuer types.String `tfsdk:"service_account_issuer"` Region types.String `tfsdk:"region"` } @@ -455,6 +456,13 @@ func (r *clusterResource) Schema(_ context.Context, _ resource.SchemaRequest, re listplanmodifier.UseStateForUnknown(), }, }, + "service_account_issuer": schema.StringAttribute{ + Description: "Service Account Issuer of the cluster.", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, "node_pools": schema.ListNestedAttribute{ Description: "One or more `node_pool` block as defined below.\n" + "To keep your Terraform plans clean and readable, always append new node pools to the end of the list.", @@ -1528,6 +1536,11 @@ func mapFields(ctx context.Context, cl *ske.Cluster, m *Model, region string) er } } + m.ServiceAccountIssuer = types.StringNull() + if cl.Status != nil && cl.Status.ServiceAccountIssuer != nil { + m.ServiceAccountIssuer = types.StringValue(*cl.Status.ServiceAccountIssuer) + } + err := mapNodePools(ctx, cl, m) if err != nil { return fmt.Errorf("map node_pools: %w", err) diff --git a/stackit/internal/services/ske/cluster/resource_test.go b/stackit/internal/services/ske/cluster/resource_test.go index cf272de95..b7c5695d8 100644 --- a/stackit/internal/services/ske/cluster/resource_test.go +++ b/stackit/internal/services/ske/cluster/resource_test.go @@ -52,6 +52,7 @@ func TestMapFields(t *testing.T) { Extensions: types.ObjectNull(extensionsTypes), EgressAddressRanges: types.ListNull(types.StringType), PodAddressRanges: types.ListNull(types.StringType), + ServiceAccountIssuer: types.StringNull(), Region: types.StringValue(testRegion), KubernetesVersionUsed: types.StringValue(""), }, @@ -139,11 +140,12 @@ func TestMapFields(t *testing.T) { }, }, Status: &ske.ClusterStatus{ - Aggregated: &cs, - Error: nil, - Hibernated: nil, - EgressAddressRanges: []string{"0.0.0.0/32", "1.1.1.1/32"}, - PodAddressRanges: []string{"0.0.0.0/32", "1.1.1.1/32"}, + Aggregated: &cs, + Error: nil, + Hibernated: nil, + EgressAddressRanges: []string{"0.0.0.0/32", "1.1.1.1/32"}, + PodAddressRanges: []string{"0.0.0.0/32", "1.1.1.1/32"}, + ServiceAccountIssuer: new("issuer"), }, }, testRegion, @@ -166,6 +168,7 @@ func TestMapFields(t *testing.T) { types.StringValue("1.1.1.1/32"), }, ), + ServiceAccountIssuer: types.StringValue("issuer"), NodePools: types.ListValueMust( types.ObjectType{AttrTypes: nodePoolTypes}, []attr.Value{ @@ -284,6 +287,7 @@ func TestMapFields(t *testing.T) { Extensions: types.ObjectNull(extensionsTypes), EgressAddressRanges: types.ListNull(types.StringType), PodAddressRanges: types.ListNull(types.StringType), + ServiceAccountIssuer: types.StringNull(), KubernetesVersionUsed: types.StringValue(""), Region: types.StringValue(testRegion), }, @@ -312,14 +316,15 @@ func TestMapFields(t *testing.T) { }, testRegion, Model{ - Id: types.StringValue("pid,region,name"), - ProjectId: types.StringValue("pid"), - Name: types.StringValue("name"), - NodePools: types.ListNull(types.ObjectType{AttrTypes: nodePoolTypes}), - Maintenance: types.ObjectNull(maintenanceTypes), - Hibernations: types.ListNull(types.ObjectType{AttrTypes: hibernationTypes}), - EgressAddressRanges: types.ListNull(types.StringType), - PodAddressRanges: types.ListNull(types.StringType), + Id: types.StringValue("pid,region,name"), + ProjectId: types.StringValue("pid"), + Name: types.StringValue("name"), + NodePools: types.ListNull(types.ObjectType{AttrTypes: nodePoolTypes}), + Maintenance: types.ObjectNull(maintenanceTypes), + Hibernations: types.ListNull(types.ObjectType{AttrTypes: hibernationTypes}), + EgressAddressRanges: types.ListNull(types.StringType), + PodAddressRanges: types.ListNull(types.StringType), + ServiceAccountIssuer: types.StringNull(), Extensions: types.ObjectValueMust(extensionsTypes, map[string]attr.Value{ "acl": types.ObjectValueMust(aclTypes, map[string]attr.Value{ "enabled": types.BoolValue(true), @@ -364,14 +369,15 @@ func TestMapFields(t *testing.T) { }, testRegion, Model{ - Id: types.StringValue("pid,region,name"), - ProjectId: types.StringValue("pid"), - Name: types.StringValue("name"), - NodePools: types.ListNull(types.ObjectType{AttrTypes: nodePoolTypes}), - Maintenance: types.ObjectNull(maintenanceTypes), - Hibernations: types.ListNull(types.ObjectType{AttrTypes: hibernationTypes}), - EgressAddressRanges: types.ListNull(types.StringType), - PodAddressRanges: types.ListNull(types.StringType), + Id: types.StringValue("pid,region,name"), + ProjectId: types.StringValue("pid"), + Name: types.StringValue("name"), + NodePools: types.ListNull(types.ObjectType{AttrTypes: nodePoolTypes}), + Maintenance: types.ObjectNull(maintenanceTypes), + Hibernations: types.ListNull(types.ObjectType{AttrTypes: hibernationTypes}), + EgressAddressRanges: types.ListNull(types.StringType), + PodAddressRanges: types.ListNull(types.StringType), + ServiceAccountIssuer: types.StringNull(), Extensions: types.ObjectValueMust(extensionsTypes, map[string]attr.Value{ "acl": types.ObjectValueMust(aclTypes, map[string]attr.Value{ "enabled": types.BoolValue(false), @@ -427,14 +433,15 @@ func TestMapFields(t *testing.T) { }, testRegion, Model{ - Id: types.StringValue("pid,region,name"), - ProjectId: types.StringValue("pid"), - Name: types.StringValue("name"), - NodePools: types.ListNull(types.ObjectType{AttrTypes: nodePoolTypes}), - Maintenance: types.ObjectNull(maintenanceTypes), - Hibernations: types.ListNull(types.ObjectType{AttrTypes: hibernationTypes}), - EgressAddressRanges: types.ListNull(types.StringType), - PodAddressRanges: types.ListNull(types.StringType), + Id: types.StringValue("pid,region,name"), + ProjectId: types.StringValue("pid"), + Name: types.StringValue("name"), + NodePools: types.ListNull(types.ObjectType{AttrTypes: nodePoolTypes}), + Maintenance: types.ObjectNull(maintenanceTypes), + Hibernations: types.ListNull(types.ObjectType{AttrTypes: hibernationTypes}), + EgressAddressRanges: types.ListNull(types.StringType), + PodAddressRanges: types.ListNull(types.StringType), + ServiceAccountIssuer: types.StringNull(), Extensions: types.ObjectValueMust(extensionsTypes, map[string]attr.Value{ "acl": types.ObjectValueMust(aclTypes, map[string]attr.Value{ "enabled": types.BoolValue(true), @@ -476,6 +483,7 @@ func TestMapFields(t *testing.T) { Extensions: types.ObjectNull(extensionsTypes), EgressAddressRanges: types.ListNull(types.StringType), PodAddressRanges: types.ListNull(types.StringType), + ServiceAccountIssuer: types.StringNull(), KubernetesVersionUsed: types.StringValue(""), Region: types.StringValue(testRegion), }, @@ -606,6 +614,7 @@ func TestMapFields(t *testing.T) { KubernetesVersionUsed: types.StringValue("1.2.3"), EgressAddressRanges: types.ListNull(types.StringType), PodAddressRanges: types.ListNull(types.StringType), + ServiceAccountIssuer: types.StringNull(), NodePools: types.ListValueMust( types.ObjectType{AttrTypes: nodePoolTypes}, []attr.Value{ diff --git a/stackit/internal/services/ske/ske_acc_test.go b/stackit/internal/services/ske/ske_acc_test.go index 0efaff3ee..9d6045d65 100644 --- a/stackit/internal/services/ske/ske_acc_test.go +++ b/stackit/internal/services/ske/ske_acc_test.go @@ -319,6 +319,7 @@ func TestAccSKEMax(t *testing.T) { resource.TestCheckResourceAttrSet("stackit_ske_cluster.cluster", "egress_address_ranges.0"), 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", "service_account_issuer"), 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"])), @@ -396,6 +397,7 @@ 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"])), + resource.TestCheckResourceAttrSet("data.stackit_ske_cluster.cluster", "service_account_issuer"), ), }, // 3) Import cluster @@ -483,6 +485,7 @@ 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"), + resource.TestCheckResourceAttrSet("stackit_ske_cluster.cluster", "service_account_issuer"), ), }, // Deletion is done by the framework implicitly