diff --git a/.changelog/40741.txt b/.changelog/40741.txt new file mode 100644 index 000000000000..b9eab1b7ea92 --- /dev/null +++ b/.changelog/40741.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_eks_cluster_versions +``` diff --git a/internal/service/eks/cluster_versions_data_source.go b/internal/service/eks/cluster_versions_data_source.go new file mode 100644 index 000000000000..39540f909e0b --- /dev/null +++ b/internal/service/eks/cluster_versions_data_source.go @@ -0,0 +1,127 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package eks + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/service/eks" + awstypes "github.com/aws/aws-sdk-go-v2/service/eks/types" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkDataSource("aws_eks_cluster_versions", name="Cluster Versions") +func newDataSourceClusterVersions(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceClusterVersions{}, nil +} + +const ( + DSNameClusterVersions = "Cluster Versions Data Source" +) + +type dataSourceClusterVersions struct { + framework.DataSourceWithConfigure +} + +func (d *dataSourceClusterVersions) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "cluster_type": schema.StringAttribute{ + Optional: true, + }, + "cluster_versions": framework.DataSourceComputedListOfObjectAttribute[customDataSourceClusterVersion](ctx), + "cluster_versions_only": schema.ListAttribute{ + CustomType: fwtypes.ListOfStringType, + Optional: true, + }, + "default_only": schema.BoolAttribute{ + Optional: true, + }, + "include_all": schema.BoolAttribute{ + Optional: true, + }, + "version_status": schema.StringAttribute{ + CustomType: fwtypes.StringEnumType[awstypes.VersionStatus](), + Optional: true, + }, + }, + } +} + +func (d *dataSourceClusterVersions) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + conn := d.Meta().EKSClient(ctx) + + var data dataSourceClusterVersionsModel + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + input := eks.DescribeClusterVersionsInput{} + resp.Diagnostics.Append(flex.Expand(ctx, data, &input)...) + if resp.Diagnostics.HasError() { + return + } + + out, err := findClusterVersions(ctx, conn, &input) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.EKS, create.ErrActionReading, DSNameClusterVersions, "", err), + err.Error(), + ) + return + } + + resp.Diagnostics.Append(flex.Flatten(ctx, out, &data.ClusterVersions)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func findClusterVersions(ctx context.Context, conn *eks.Client, input *eks.DescribeClusterVersionsInput) ([]awstypes.ClusterVersionInformation, error) { + out := make([]awstypes.ClusterVersionInformation, 0) + + pages := eks.NewDescribeClusterVersionsPaginator(conn, input) + for pages.HasMorePages() { + page, err := pages.NextPage(ctx) + if err != nil { + return nil, err + } + + out = append(out, page.ClusterVersions...) + } + + return out, nil +} + +type dataSourceClusterVersionsModel struct { + ClusterType types.String `tfsdk:"cluster_type"` + ClusterVersions fwtypes.ListNestedObjectValueOf[customDataSourceClusterVersion] `tfsdk:"cluster_versions"` + ClusterVersionsOnly fwtypes.ListValueOf[types.String] `tfsdk:"cluster_versions_only"` + DefaultOnly types.Bool `tfsdk:"default_only"` + IncludeAll types.Bool `tfsdk:"include_all"` + VersionStatus fwtypes.StringEnum[awstypes.VersionStatus] `tfsdk:"version_status"` +} + +type customDataSourceClusterVersion struct { + ClusterType types.String `tfsdk:"cluster_type"` + ClusterVersion types.String `tfsdk:"cluster_version"` + DefaultPlatformVersion types.String `tfsdk:"default_platform_version"` + DefaultVersion types.Bool `tfsdk:"default_version"` + EndOfExtendedSupportDate timetypes.RFC3339 `tfsdk:"end_of_extended_support_date"` + EndOfStandardSupportDate timetypes.RFC3339 `tfsdk:"end_of_standard_support_date"` + KubernetesPatchVersion types.String `tfsdk:"kubernetes_patch_version"` + ReleaseDate timetypes.RFC3339 `tfsdk:"release_date"` + VersionStatus fwtypes.StringEnum[awstypes.VersionStatus] `tfsdk:"version_status"` +} diff --git a/internal/service/eks/cluster_versions_data_source_test.go b/internal/service/eks/cluster_versions_data_source_test.go new file mode 100644 index 000000000000..c1b3c404446d --- /dev/null +++ b/internal/service/eks/cluster_versions_data_source_test.go @@ -0,0 +1,125 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package eks_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccEKSClusterVersionsDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + + dataSourceName := "data.aws_eks_cluster_versions.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.EKSServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccClusterVersionsDataSourceConfig_basic(), + Check: resource.ComposeAggregateTestCheckFunc( + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "cluster_versions.#", 0), + acctest.CheckResourceAttrContains(dataSourceName, "cluster_versions.0.default_version", acctest.CtTrue), + ), + }, + }, + }) +} + +func TestAccEKSClusterVersionsDataSource_clusterType(t *testing.T) { + ctx := acctest.Context(t) + + dataSourceName := "data.aws_eks_cluster_versions.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.EKSServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccClusterVersionsDataSourceConfig_clusterType(), + Check: resource.ComposeTestCheckFunc( + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "cluster_versions.#", 0), + ), + }, + }, + }) +} + +func TestAccEKSClusterVersionsDataSource_defaultOnly(t *testing.T) { + ctx := acctest.Context(t) + + dataSourceName := "data.aws_eks_cluster_versions.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.EKSServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccClusterVersionsDataSourceConfig_defaultOnly(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "cluster_versions.#", "1"), + acctest.CheckResourceAttrContains(dataSourceName, "cluster_versions.0.default_version", acctest.CtTrue), + ), + }, + }, + }) +} + +func TestAccEKSClusterVersionsDataSource_versionStatus(t *testing.T) { + ctx := acctest.Context(t) + + dataSourceName := "data.aws_eks_cluster_versions.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.EKSServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccClusterVersionsDataSourceConfig_versionStatus(), + Check: resource.ComposeTestCheckFunc( + acctest.CheckResourceAttrGreaterThanValue(dataSourceName, "cluster_versions.#", 0), + acctest.CheckResourceAttrContains(dataSourceName, "cluster_versions.0.version_status", "STANDARD_SUPPORT"), + ), + }, + }, + }) +} + +func testAccClusterVersionsDataSourceConfig_basic() string { + return ` +data "aws_eks_cluster_versions" "test" {} +` +} + +func testAccClusterVersionsDataSourceConfig_clusterType() string { + return ` +data "aws_eks_cluster_versions" "test" { + cluster_type = "eks" +} +` +} + +func testAccClusterVersionsDataSourceConfig_defaultOnly() string { + return ` +data "aws_eks_cluster_versions" "test" { + default_only = true +} +` +} + +func testAccClusterVersionsDataSourceConfig_versionStatus() string { + return ` +data "aws_eks_cluster_versions" "test" { + version_status = "STANDARD_SUPPORT" +} +` +} diff --git a/internal/service/eks/service_package_gen.go b/internal/service/eks/service_package_gen.go index 3d56499938d8..efe2e4ecec70 100644 --- a/internal/service/eks/service_package_gen.go +++ b/internal/service/eks/service_package_gen.go @@ -25,7 +25,13 @@ func (p *servicePackage) EphemeralResources(ctx context.Context) []*types.Servic } func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.ServicePackageFrameworkDataSource { - return []*types.ServicePackageFrameworkDataSource{} + return []*types.ServicePackageFrameworkDataSource{ + { + Factory: newDataSourceClusterVersions, + TypeName: "aws_eks_cluster_versions", + Name: "Cluster Versions", + }, + } } func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { diff --git a/website/docs/d/eks_cluster_versions.html.markdown b/website/docs/d/eks_cluster_versions.html.markdown new file mode 100644 index 000000000000..0c0e4cf98fb0 --- /dev/null +++ b/website/docs/d/eks_cluster_versions.html.markdown @@ -0,0 +1,61 @@ +--- +subcategory: "EKS (Elastic Kubernetes)" +layout: "aws" +page_title: "AWS: aws_eks_cluster_versions" +description: |- + Terraform data source for managing AWS EKS (Elastic Kubernetes) Cluster Versions. +--- + +# Data Source: aws_eks_cluster_versions + +Terraform data source for managing AWS EKS (Elastic Kubernetes) Cluster Versions. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_eks_cluster_versions" "example" {} +``` + +### Filter by Cluster Type + +```terraform +data "aws_eks_cluster_versions" "example" { + cluster_type = "eks" +} +``` + +### Filter by Version Status + +```terraform +data "aws_eks_cluster_versions" "example" { + version_status = "STANDARD_SUPPORT" +} +``` + +## Argument Reference + +The following arguments are optional: + +* `cluster_type` - (Optional) Type of clusters to filter by. +Currently, the only valid value is `eks`. +* `cluster_versions` - (Optional) A list of Kubernetes versions that you can use to check if EKS supports it. +* `default_only` - (Optional) Whether to show only the default versions of Kubernetes supported by EKS. +* `include_all` - (Optional) Whether to include all kubernetes versions in the response. +* `version_status` - (Optional) Status of the EKS cluster versions to list. +Valid values are `STANDARD_SUPPORT` or `UNSUPPORTED` or `EXTENDED_SUPPORT`. + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `cluster_type` - Type of cluster that the version belongs to. +* `cluster_version` - Kubernetes version supported by EKS. +* `default_platform_version` - Default eks platform version for the cluster version. +* `default_version` - Default Kubernetes version for the cluster version. +* `end_of_extended_support_date` - End of extended support date for the cluster version. +* `end_of_standard_support_date` - End of standard support date for the cluster version. +* `kubernetes_patch_version` - Kubernetes patch version for the cluster version. +* `release_date` - Release date of the cluster version. +* `version_status` - Status of the EKS cluster version.