From 25d67096758f02dcfdd1fbde40300d7027bf828b Mon Sep 17 00:00:00 2001 From: Jared Baker Date: Mon, 20 Nov 2023 11:33:51 -0500 Subject: [PATCH] d/aws_emr_supported_instance_types: new data source --- internal/service/emr/service_package_gen.go | 20 +- .../supported_instance_types_data_source.go | 179 ++++++++++++++++++ ...pported_instance_types_data_source_test.go | 50 +++++ ...emr_supported_instance_types.html.markdown | 47 +++++ 4 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 internal/service/emr/supported_instance_types_data_source.go create mode 100644 internal/service/emr/supported_instance_types_data_source_test.go create mode 100644 website/docs/d/emr_supported_instance_types.html.markdown diff --git a/internal/service/emr/service_package_gen.go b/internal/service/emr/service_package_gen.go index 94d5db4633c..284c1409547 100644 --- a/internal/service/emr/service_package_gen.go +++ b/internal/service/emr/service_package_gen.go @@ -5,6 +5,8 @@ package emr import ( "context" + aws_sdkv2 "github.com/aws/aws-sdk-go-v2/aws" + emr_sdkv2 "github.com/aws/aws-sdk-go-v2/service/emr" aws_sdkv1 "github.com/aws/aws-sdk-go/aws" session_sdkv1 "github.com/aws/aws-sdk-go/aws/session" emr_sdkv1 "github.com/aws/aws-sdk-go/service/emr" @@ -16,7 +18,12 @@ import ( type servicePackage struct{} func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.ServicePackageFrameworkDataSource { - return []*types.ServicePackageFrameworkDataSource{} + return []*types.ServicePackageFrameworkDataSource{ + { + Factory: newDataSourceSupportedInstanceTypes, + Name: "Supported Instance Types", + }, + } } func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { @@ -88,6 +95,17 @@ func (p *servicePackage) NewConn(ctx context.Context, config map[string]any) (*e return emr_sdkv1.New(sess.Copy(&aws_sdkv1.Config{Endpoint: aws_sdkv1.String(config["endpoint"].(string))})), nil } +// NewClient returns a new AWS SDK for Go v2 client for this service package's AWS API. +func (p *servicePackage) NewClient(ctx context.Context, config map[string]any) (*emr_sdkv2.Client, error) { + cfg := *(config["aws_sdkv2_config"].(*aws_sdkv2.Config)) + + return emr_sdkv2.NewFromConfig(cfg, func(o *emr_sdkv2.Options) { + if endpoint := config["endpoint"].(string); endpoint != "" { + o.BaseEndpoint = aws_sdkv2.String(endpoint) + } + }), nil +} + func ServicePackage(ctx context.Context) conns.ServicePackage { return &servicePackage{} } diff --git a/internal/service/emr/supported_instance_types_data_source.go b/internal/service/emr/supported_instance_types_data_source.go new file mode 100644 index 00000000000..2ffe5e1c7ba --- /dev/null +++ b/internal/service/emr/supported_instance_types_data_source.go @@ -0,0 +1,179 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package emr + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/emr" + awstypes "github.com/aws/aws-sdk-go-v2/service/emr/types" + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/diag" + "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" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkDataSource(name="Supported Instance Types") +func newDataSourceSupportedInstanceTypes(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceSupportedInstanceTypes{}, nil +} + +const ( + DSNameSupportedInstanceTypes = "Supported Instance Types Data Source" +) + +type dataSourceSupportedInstanceTypes struct { + framework.DataSourceWithConfigure +} + +func (d *dataSourceSupportedInstanceTypes) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { // nosemgrep:ci.meta-in-func-name + resp.TypeName = "aws_emr_supported_instance_types" +} + +func (d *dataSourceSupportedInstanceTypes) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": framework.IDAttribute(), + "release_label": schema.StringAttribute{ + Required: true, + }, + }, + Blocks: map[string]schema.Block{ + "supported_instance_types": schema.ListNestedBlock{ + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "architecture": schema.StringAttribute{ + Computed: true, + }, + "ebs_optimized_available": schema.BoolAttribute{ + Computed: true, + }, + "ebs_optimized_by_default": schema.BoolAttribute{ + Computed: true, + }, + "ebs_storage_only": schema.BoolAttribute{ + Computed: true, + }, + "instance_family_id": schema.StringAttribute{ + Computed: true, + }, + "is_64_bits_only": schema.BoolAttribute{ + Computed: true, + }, + "memory_gb": schema.Float64Attribute{ + Computed: true, + }, + "number_of_disks": schema.Int64Attribute{ + Computed: true, + }, + "storage_gb": schema.Int64Attribute{ + Computed: true, + }, + "type": schema.StringAttribute{ + Computed: true, + }, + "vcpu": schema.Int64Attribute{ + Computed: true, + }, + }, + }, + }, + }, + } +} +func (d *dataSourceSupportedInstanceTypes) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + conn := d.Meta().EMRClient(ctx) + + var data dataSourceSupportedInstanceTypesData + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + data.ID = types.StringValue(data.ReleaseLabel.ValueString()) + + input := &emr.ListSupportedInstanceTypesInput{ + ReleaseLabel: aws.String(data.ReleaseLabel.ValueString()), + } + + var results []awstypes.SupportedInstanceType + paginator := emr.NewListSupportedInstanceTypesPaginator(conn, input) + for paginator.HasMorePages() { + output, err := paginator.NextPage(ctx) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.EMR, create.ErrActionReading, DSNameSupportedInstanceTypes, data.ID.String(), err), + err.Error(), + ) + return + } + results = append(results, output.SupportedInstanceTypes...) + } + + supportedInstanceTypes, diag := flattenSupportedInstanceTypes(ctx, results) + resp.Diagnostics.Append(diag...) + data.SupportedInstanceTypes = supportedInstanceTypes + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +type dataSourceSupportedInstanceTypesData struct { + ID types.String `tfsdk:"id"` + ReleaseLabel types.String `tfsdk:"release_label"` + SupportedInstanceTypes types.List `tfsdk:"supported_instance_types"` +} + +var supportedInstanceTypeAttrTypes = map[string]attr.Type{ + "architecture": types.StringType, + "ebs_optimized_available": types.BoolType, + "ebs_optimized_by_default": types.BoolType, + "ebs_storage_only": types.BoolType, + "instance_family_id": types.StringType, + "is_64_bits_only": types.BoolType, + "memory_gb": types.Float64Type, + "number_of_disks": types.Int64Type, + "storage_gb": types.Int64Type, + "type": types.StringType, + "vcpu": types.Int64Type, +} + +func flattenSupportedInstanceTypes(ctx context.Context, apiObjects []awstypes.SupportedInstanceType) (types.List, diag.Diagnostics) { + var diags diag.Diagnostics + elemType := types.ObjectType{AttrTypes: supportedInstanceTypeAttrTypes} + + if len(apiObjects) == 0 { + return types.ListNull(elemType), diags + } + + elems := []attr.Value{} + for _, apiObject := range apiObjects { + obj := map[string]attr.Value{ + "architecture": flex.StringToFramework(ctx, apiObject.Architecture), + "ebs_optimized_available": flex.BoolToFramework(ctx, apiObject.EbsOptimizedAvailable), + "ebs_optimized_by_default": flex.BoolToFramework(ctx, apiObject.EbsOptimizedByDefault), + "ebs_storage_only": flex.BoolToFramework(ctx, apiObject.EbsStorageOnly), + "instance_family_id": flex.StringToFramework(ctx, apiObject.InstanceFamilyId), + "is_64_bits_only": flex.BoolToFramework(ctx, apiObject.Is64BitsOnly), + "memory_gb": flex.Float32ToFramework(ctx, apiObject.MemoryGB), + "number_of_disks": flex.Int32ToFramework(ctx, apiObject.NumberOfDisks), + "storage_gb": flex.Int32ToFramework(ctx, apiObject.StorageGB), + "type": flex.StringToFramework(ctx, apiObject.Type), + "vcpu": flex.Int32ToFramework(ctx, apiObject.VCPU), + } + objVal, d := types.ObjectValue(supportedInstanceTypeAttrTypes, obj) + diags.Append(d...) + + elems = append(elems, objVal) + } + + listVal, d := types.ListValue(elemType, elems) + diags.Append(d...) + + return listVal, diags +} diff --git a/internal/service/emr/supported_instance_types_data_source_test.go b/internal/service/emr/supported_instance_types_data_source_test.go new file mode 100644 index 00000000000..eb3bd68bf21 --- /dev/null +++ b/internal/service/emr/supported_instance_types_data_source_test.go @@ -0,0 +1,50 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package emr_test + +import ( + "fmt" + "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 TestAccEMRSupportedInstanceTypesDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + dataSourceName := "data.aws_emr_supported_instance_types.test" + releaseLabel := "emr-6.15.0" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.EMREndpointID) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.EMREndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: testAccSupportedInstanceTypesDataSourceConfig_basic(releaseLabel), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "release_label", releaseLabel), + // Verify a known supported type is included in the output + resource.TestCheckTypeSetElemNestedAttrs(dataSourceName, "supported_instance_types.*", map[string]string{ + "type": "m5.xlarge", + }), + ), + }, + }, + }) +} + +func testAccSupportedInstanceTypesDataSourceConfig_basic(releaseLabel string) string { + return fmt.Sprintf(` +data "aws_emr_supported_instance_types" "test" { + release_label = %[1]q +} +`, releaseLabel) +} diff --git a/website/docs/d/emr_supported_instance_types.html.markdown b/website/docs/d/emr_supported_instance_types.html.markdown new file mode 100644 index 00000000000..dead160c605 --- /dev/null +++ b/website/docs/d/emr_supported_instance_types.html.markdown @@ -0,0 +1,47 @@ +--- +subcategory: "EMR" +layout: "aws" +page_title: "AWS: aws_emr_supported_instance_types" +description: |- + Terraform data source for managing AWS EMR Supported Instance Types. +--- + +# Data Source: aws_emr_supported_instance_types + +Terraform data source for managing AWS EMR Supported Instance Types. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_emr_supported_instance_types" "example" { + release_label = "ebs-6.15.0" +} +``` + +## Argument Reference + +The following arguments are required: + +* `release_label` - (Required) Amazon EMR release label. For more information about Amazon EMR releases and their included application versions and features, see the [Amazon EMR Release Guide](https://docs.aws.amazon.com/emr/latest/ReleaseGuide/emr-release-components.html). + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `supported_instance_types` - List of supported instance types. See [`supported_instance_types`](#supported_instance_types-attribute-reference) below. + +### `supported_instance_types` Attribute Reference + +* `architecture` - CPU architecture. +* `ebs_optimized_available` - Indicates whether the instance type supports Amazon EBS optimization. +* `ebs_optimized_by_default` - Indicates whether the instance type uses Amazon EBS optimization by default. +* `ebs_storage_only` - Indicates whether the instance type only supports Amazon EBS. +* `instance_family_id` - The Amazon EC2 family and generation for the instance type. +* `is_64_bits_only` - Indicates whether the instance type only supports 64-bit architecture. +* `memory_gb` - Memory that is available to Amazon EMR from the instance type. +* `number_of_disks` - Number of disks for the instance type. +* `storage_gb` - Storage capacity of the instance type. +* `type` - Amazon EC2 instance type. For example, `m5.xlarge`. +* `vcpu` - The number of vCPUs available for the instance type.