diff --git a/.changelog/39335.txt b/.changelog/39335.txt new file mode 100644 index 00000000000..23dd6be82fa --- /dev/null +++ b/.changelog/39335.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_api_gateway_api_keys +``` \ No newline at end of file diff --git a/internal/service/apigateway/api_keys_data_source.go b/internal/service/apigateway/api_keys_data_source.go new file mode 100644 index 00000000000..7d6c52dbce2 --- /dev/null +++ b/internal/service/apigateway/api_keys_data_source.go @@ -0,0 +1,165 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package apigateway + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/service/apigateway" + awstypes "github.com/aws/aws-sdk-go-v2/service/apigateway/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/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" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// @FrameworkDataSource("aws_api_gateway_api_keys", name="API Keys") +func newDataSourceAPIKeys(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceAPIKeys{}, nil +} + +const ( + DSNameAPIKeys = "API Keys" +) + +type dataSourceAPIKeys struct { + framework.DataSourceWithConfigure +} + +func (d *dataSourceAPIKeys) Metadata(_ context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) { + response.TypeName = "aws_api_gateway_api_keys" +} + +func (d *dataSourceAPIKeys) Schema(ctx context.Context, request datasource.SchemaRequest, response *datasource.SchemaResponse) { + response.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "customer_id": schema.StringAttribute{ + Optional: true, + }, + "id": framework.IDAttribute(), + "include_values": schema.BoolAttribute{ + Optional: true, + }, + }, + Blocks: map[string]schema.Block{ + "items": schema.ListNestedBlock{ + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + names.AttrCreatedDate: schema.StringAttribute{ + Computed: true, + }, + "customer_id": schema.StringAttribute{ + Computed: true, + }, + names.AttrDescription: schema.StringAttribute{ + Computed: true, + }, + names.AttrEnabled: schema.BoolAttribute{ + Computed: true, + }, + names.AttrID: framework.IDAttribute(), + names.AttrLastUpdatedDate: schema.StringAttribute{ + Computed: true, + }, + names.AttrName: schema.StringAttribute{ + Computed: true, + }, + "stage_keys": schema.ListAttribute{ + ElementType: types.StringType, + Computed: true, + }, + names.AttrTags: tftags.TagsAttribute(), + names.AttrValue: schema.StringAttribute{ + Computed: true, + Sensitive: true, + }, + }, + }, + }, + }, + } +} + +func (d *dataSourceAPIKeys) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { + var data dataSourceAPIKeysModel + + response.Diagnostics.Append(request.Config.Get(ctx, &data)...) + data.ID = flex.StringValueToFramework(ctx, d.Meta().Region) + + if response.Diagnostics.HasError() { + return + } + + var apiKeyItems []awstypes.ApiKey + + conn := d.Meta().APIGatewayClient(ctx) + input := &apigateway.GetApiKeysInput{ + IncludeValues: flex.BoolFromFramework(ctx, data.IncludeValues), + CustomerId: flex.StringFromFramework(ctx, data.CustomerID), + } + + pages := apigateway.NewGetApiKeysPaginator(conn, input) + for pages.HasMorePages() { + page, err := pages.NextPage(ctx) + if err != nil { + response.Diagnostics.AddError( + create.ProblemStandardMessage(names.APIGateway, create.ErrActionReading, DSNameAPIKeys, data.ID.ValueString(), err), + err.Error(), + ) + return + } + + apiKeyItems = append(apiKeyItems, page.Items...) + } + + items, diags := flattenAPIKeyItems(ctx, apiKeyItems) + response.Diagnostics.Append(diags...) + data.Items = items + + response.Diagnostics.Append(response.State.Set(ctx, &data)...) +} + +func flattenAPIKeyItems(ctx context.Context, apiKeyItems []awstypes.ApiKey) ([]apiKeyModel, diag.Diagnostics) { + var diags diag.Diagnostics + + if len(apiKeyItems) == 0 { + return []apiKeyModel{}, diags + } + + var apiKeys []apiKeyModel + + for _, apiKeyItem := range apiKeyItems { + var ak apiKeyModel + diags.Append(flex.Flatten(ctx, apiKeyItem, &ak, flex.WithNoIgnoredFieldNames())...) + apiKeys = append(apiKeys, ak) + } + + return apiKeys, diags +} + +type dataSourceAPIKeysModel struct { + CustomerID types.String `tfsdk:"customer_id"` + ID types.String `tfsdk:"id"` + IncludeValues types.Bool `tfsdk:"include_values"` + Items []apiKeyModel `tfsdk:"items"` +} + +type apiKeyModel struct { + CreatedDate timetypes.RFC3339 `tfsdk:"created_date"` + CustomerID types.String `tfsdk:"customer_id"` + Description types.String `tfsdk:"description"` + Enabled types.Bool `tfsdk:"enabled"` + ID types.String `tfsdk:"id"` + LastUpdatedDate timetypes.RFC3339 `tfsdk:"last_updated_date"` + Name types.String `tfsdk:"name"` + StageKeys types.List `tfsdk:"stage_keys"` + Tags types.Map `tfsdk:"tags"` + Value types.String `tfsdk:"value"` +} diff --git a/internal/service/apigateway/api_keys_data_source_test.go b/internal/service/apigateway/api_keys_data_source_test.go new file mode 100644 index 00000000000..27a2ef05cf1 --- /dev/null +++ b/internal/service/apigateway/api_keys_data_source_test.go @@ -0,0 +1,142 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package apigateway_test + +import ( + "fmt" + "testing" + + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccAPIGatewayAPIKeysDataSource_serial(t *testing.T) { + t.Parallel() + + testCases := map[string]map[string]func(t *testing.T){ + "APIKeys": { + acctest.CtBasic: testAccAPIGatewayKeysDataSource_basic, + "includeValues": testAccAPIGatewayKeysDataSource_includeValues, + "manyKeys": testAccAPIGatewayKeysDataSource_manyKeys, + }, + } + + acctest.RunSerialTests2Levels(t, testCases, 0) +} + +func testAccAPIGatewayKeysDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_api_gateway_api_key.test" + dataSourceName := "data.aws_api_gateway_api_keys.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.APIGatewayServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckAPIKeyDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccAPIKeysDataSourceConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "items.#", acctest.Ct1), + resource.TestCheckTypeSetElemAttrPair(dataSourceName, "items.0.created_date", resourceName, names.AttrCreatedDate), + resource.TestCheckTypeSetElemAttrPair(dataSourceName, "items.0.description", resourceName, names.AttrDescription), + resource.TestCheckTypeSetElemAttrPair(dataSourceName, "items.0.enabled", resourceName, names.AttrEnabled), + resource.TestCheckTypeSetElemAttrPair(dataSourceName, "items.0.id", resourceName, names.AttrID), + resource.TestCheckTypeSetElemAttrPair(dataSourceName, "items.0.last_updated_date", resourceName, names.AttrLastUpdatedDate), + resource.TestCheckTypeSetElemAttrPair(dataSourceName, "items.0.name", resourceName, names.AttrName), + resource.TestCheckNoResourceAttr(dataSourceName, names.AttrValue), + ), + }, + }, + }) +} + +func testAccAPIGatewayKeysDataSource_includeValues(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + dataSourceName := "data.aws_api_gateway_api_keys.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.APIGatewayServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckAPIKeyDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccAPIKeysDataSourceConfig_includeValues(rName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(dataSourceName, "items.0.value"), + ), + }, + }, + }) +} + +func testAccAPIGatewayKeysDataSource_manyKeys(t *testing.T) { + ctx := acctest.Context(t) + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + + dataSourceName := "data.aws_api_gateway_api_keys.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.APIGatewayServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckAPIKeyDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccAPIKeysDataSourceConfig_manyKeys(rName, 3), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "items.#", acctest.Ct3), + ), + }, + }, + }) +} + +func testAccAPIKeysDataSourceConfig_basic(rName string) string { + return fmt.Sprintf(` +resource "aws_api_gateway_api_key" "test" { + name = %[1]q +} + +data "aws_api_gateway_api_keys" "test" { + depends_on = [aws_api_gateway_api_key.test] +} +`, rName) +} + +func testAccAPIKeysDataSourceConfig_includeValues(rName string) string { + return fmt.Sprintf(` +resource "aws_api_gateway_api_key" "test" { + name = %[1]q +} + +data "aws_api_gateway_api_keys" "test" { + depends_on = [aws_api_gateway_api_key.test] + + include_values = true +} +`, rName) +} + +func testAccAPIKeysDataSourceConfig_manyKeys(rName string, count int) string { + return fmt.Sprintf(` +resource "aws_api_gateway_api_key" "test" { + count = %[2]d + name = "%[1]s-${count.index}" +} + +data "aws_api_gateway_api_keys" "test" { + depends_on = [aws_api_gateway_api_key.test] + + include_values = true +} +`, rName, count) +} diff --git a/internal/service/apigateway/service_package_gen.go b/internal/service/apigateway/service_package_gen.go index 0c9dbd98479..7ac91a09d35 100644 --- a/internal/service/apigateway/service_package_gen.go +++ b/internal/service/apigateway/service_package_gen.go @@ -13,7 +13,12 @@ import ( type servicePackage struct{} func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.ServicePackageFrameworkDataSource { - return []*types.ServicePackageFrameworkDataSource{} + return []*types.ServicePackageFrameworkDataSource{ + { + Factory: newDataSourceAPIKeys, + Name: "API Keys", + }, + } } func (p *servicePackage) FrameworkResources(ctx context.Context) []*types.ServicePackageFrameworkResource { diff --git a/website/docs/d/api_gateway_api_keys.html.markdown b/website/docs/d/api_gateway_api_keys.html.markdown new file mode 100644 index 00000000000..28fcc6f5304 --- /dev/null +++ b/website/docs/d/api_gateway_api_keys.html.markdown @@ -0,0 +1,44 @@ +--- +subcategory: "API Gateway" +layout: "aws" +page_title: "AWS: aws_apigateway_api_keys" +description: |- + Terraform data source for managing an AWS API Gateway API Keys. +--- + +# Data Source: aws_apigateway_api_keys + +Use this data source to get pre-existing API Key list. + +## Example Usage + +```terraform +data "aws_api_gateway_api_keys" "my_api_keys" {} +``` + +## Argument Reference + +This resource supports the following arguments: + +* `customer_id` - (Optional) Amazon Web Services Marketplace customer identifier, when integrating with the Amazon Web Services SaaS Marketplace. + +* `include_values` - (Optional) Set this value to `true` if you wish the result contains the key value. Defaults to `false`. + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `id` - AWS Region. +* `items` - List of objects containing API Key information. See below. + +### `items` + +* `id` - Set to the ID of the API Key. +* `name` - Set to the name of the API Key. +* `value` - Set to the value of the API Key. +* `created_date` - Date and time when the API Key was created. +* `last_updated_date` - Date and time when the API Key was last updated. +* `customer_id` - Amazon Web Services Marketplace customer identifier, when integrating with the Amazon Web Services SaaS Marketplace. +* `description` - Description of the API Key. +* `enabled` - Whether the API Key is enabled. +* `tags` - Map of tags for the resource.