From d7fab1b33e6fec46464c476594867733c1738e01 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 27 Jun 2023 11:19:46 -0500 Subject: [PATCH 01/10] aws_opensearchserverless_collection: add data source --- .../collection_data_source.go | 129 ++++++++++++++++++ .../collection_data_source_test.go | 72 ++++++++++ ...nsearchserverless_collection.html.markdown | 37 +++++ 3 files changed, 238 insertions(+) create mode 100644 internal/service/opensearchserverless/collection_data_source.go create mode 100644 internal/service/opensearchserverless/collection_data_source_test.go create mode 100644 website/docs/d/opensearchserverless_collection.html.markdown diff --git a/internal/service/opensearchserverless/collection_data_source.go b/internal/service/opensearchserverless/collection_data_source.go new file mode 100644 index 000000000000..370ad014e284 --- /dev/null +++ b/internal/service/opensearchserverless/collection_data_source.go @@ -0,0 +1,129 @@ +package opensearchserverless + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "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" +) + +// Function annotations are used for datasource registration to the Provider. DO NOT EDIT. +// @FrameworkDataSource(name="Collection") +func newDataSourceCollection(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceCollection{}, nil +} + +const ( + DSNameCollection = "Collection Data Source" +) + +type dataSourceCollection struct { + framework.DataSourceWithConfigure +} + +func (d *dataSourceCollection) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { // nosemgrep:ci.meta-in-func-name + resp.TypeName = "aws_opensearchserverless_collection" +} + +func (d *dataSourceCollection) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "arn": framework.ARNAttributeComputedOnly(), + "collection_endpoint": schema.StringAttribute{ + Computed: true, + }, + "dashboard_endpoint": schema.StringAttribute{ + Computed: true, + }, + "description": schema.StringAttribute{ + Computed: true, + }, + "id": schema.StringAttribute{ + Optional: true, + Computed: true, + Validators: []validator.String{ + stringvalidator.ExactlyOneOf( + path.MatchRelative().AtParent().AtName("id"), + path.MatchRelative().AtParent().AtName("name"), + ), + }, + }, + "kms_key_arn": schema.StringAttribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Optional: true, + Computed: true, + }, + names.AttrTags: tftags.TagsAttributeComputedOnly(), + "type": schema.StringAttribute{ + Computed: true, + }, + }, + } +} +func (d *dataSourceCollection) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + conn := d.Meta().OpenSearchServerlessClient(ctx) + + var data dataSourceCollectionData + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + out, err := FindCollectionByID(ctx, conn, data.ID.ValueString()) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.OpenSearchServerless, create.ErrActionReading, DSNameCollection, data.ID.String(), err), + err.Error(), + ) + return + } + + data.ARN = flex.StringToFramework(ctx, out.Arn) + data.CollectionEndpoint = flex.StringToFramework(ctx, out.CollectionEndpoint) + data.DashboardEndpoint = flex.StringToFramework(ctx, out.DashboardEndpoint) + data.Description = flex.StringToFramework(ctx, out.Description) + data.ID = flex.StringToFramework(ctx, out.Id) + data.KmsKeyARN = flex.StringToFramework(ctx, out.KmsKeyArn) + data.Name = flex.StringToFramework(ctx, out.Name) + data.Type = flex.StringValueToFramework(ctx, out.Type) + + ignoreTagsConfig := d.Meta().IgnoreTagsConfig + tags, err := listTags(ctx, conn, aws.ToString(out.Arn)) + + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.OpenSearchServerless, create.ErrActionReading, DSNameCollection, data.ID.String(), err), + err.Error(), + ) + return + } + + tags = tags.IgnoreConfig(ignoreTagsConfig) + data.Tags = flex.FlattenFrameworkStringValueMapLegacy(ctx, tags.Map()) + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +type dataSourceCollectionData struct { + ARN types.String `tfsdk:"arn"` + CollectionEndpoint types.String `tfsdk:"collection_endpoint"` + DashboardEndpoint types.String `tfsdk:"dashboard_endpoint"` + Description types.String `tfsdk:"description"` + ID types.String `tfsdk:"id"` + KmsKeyARN types.String `tfsdk:"kms_key_arn"` + Name types.String `tfsdk:"name"` + Tags types.Map `tfsdk:"tags"` + Type types.String `tfsdk:"type"` +} diff --git a/internal/service/opensearchserverless/collection_data_source_test.go b/internal/service/opensearchserverless/collection_data_source_test.go new file mode 100644 index 000000000000..b4b9db0890a2 --- /dev/null +++ b/internal/service/opensearchserverless/collection_data_source_test.go @@ -0,0 +1,72 @@ +package opensearchserverless_test + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go-v2/service/opensearchserverless/types" + 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 TestAccOpenSearchServerlessCollectionDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var collection types.CollectionDetail + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_opensearchserverless_collection.test" + resourceName := ".aws_opensearchserverless_collection.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.OpenSearchServerlessEndpointID) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.OpenSearchServerlessEndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckCollectionDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccCollectionDataSourceConfig_basic(rName, "encryption"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCollectionExists(ctx, dataSourceName, &collection), + resource.TestCheckResourceAttrPair(dataSourceName, "name", resourceName, "name"), + ), + }, + }, + }) +} + +func testAccCollectionDataSourceConfig_basic(rName, policyType string) string { + return fmt.Sprintf(` +resource "aws_opensearchserverless_collection" "test" { + name = %[1]q + depends_on = [aws_opensearchserverless_security_policy.test] +} +resource "aws_opensearchserverless_security_policy" "test" { + name = %[1]q + type = %[2]q + policy = jsonencode({ + Rules = [ + { + Resource = [ + "collection/%[1]s" + ], + ResourceType = "collection" + } + ], + AWSOwnedKey = true + }) +} + +data "aws_opensearchserverless_collection" "test" { + id = aws_opensearchserverless_collection.test.id +} +`, rName, policyType) +} diff --git a/website/docs/d/opensearchserverless_collection.html.markdown b/website/docs/d/opensearchserverless_collection.html.markdown new file mode 100644 index 000000000000..e85d4eb6be63 --- /dev/null +++ b/website/docs/d/opensearchserverless_collection.html.markdown @@ -0,0 +1,37 @@ +--- +subcategory: "OpenSearch Serverless" +layout: "aws" +page_title: "AWS: aws_opensearchserverless_collection" +description: |- + Terraform data source for managing an AWS OpenSearch Serverless Collection. +--- + +# Data Source: aws_opensearchserverless_collection + +Terraform data source for managing an AWS OpenSearch Serverless Collection. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_opensearchserverless_collection" "example" { +} +``` + +## Argument Reference + +The following arguments are required: + +* `example_arg` - (Required) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. + +The following arguments are optional: + +* `optional_arg` - (Optional) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - ARN of the Collection. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. +* `example_attribute` - Concise description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. From 8924d5b54c69d1148b587276a2ef14bd8b2bf510 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 27 Jun 2023 11:23:49 -0500 Subject: [PATCH 02/10] aws_opensearchserverless_collection: register data source --- internal/service/opensearchserverless/service_package_gen.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/service/opensearchserverless/service_package_gen.go b/internal/service/opensearchserverless/service_package_gen.go index 7e043b1f5e9c..70f13be6e45c 100644 --- a/internal/service/opensearchserverless/service_package_gen.go +++ b/internal/service/opensearchserverless/service_package_gen.go @@ -20,6 +20,10 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*types.Serv Factory: newDataSourceAccessPolicy, Name: "Access Policy", }, + { + Factory: newDataSourceCollection, + Name: "Collection", + }, } } From 4d9ab5b5927c6ea6689f462e68d0be10199ee6ef Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 27 Jun 2023 12:19:35 -0500 Subject: [PATCH 03/10] aws_opensearchserverless_collection: update documentation --- .../collection_data_source.go | 8 ++++++-- .../collection_data_source_test.go | 11 ++++++----- ...pensearchserverless_collection.html.markdown | 17 ++++++++++------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/internal/service/opensearchserverless/collection_data_source.go b/internal/service/opensearchserverless/collection_data_source.go index 370ad014e284..841b3cd917b0 100644 --- a/internal/service/opensearchserverless/collection_data_source.go +++ b/internal/service/opensearchserverless/collection_data_source.go @@ -52,8 +52,7 @@ func (d *dataSourceCollection) Schema(ctx context.Context, req datasource.Schema Optional: true, Computed: true, Validators: []validator.String{ - stringvalidator.ExactlyOneOf( - path.MatchRelative().AtParent().AtName("id"), + stringvalidator.ConflictsWith( path.MatchRelative().AtParent().AtName("name"), ), }, @@ -64,6 +63,11 @@ func (d *dataSourceCollection) Schema(ctx context.Context, req datasource.Schema "name": schema.StringAttribute{ Optional: true, Computed: true, + Validators: []validator.String{ + stringvalidator.ConflictsWith( + path.MatchRelative().AtParent().AtName("id"), + ), + }, }, names.AttrTags: tftags.TagsAttributeComputedOnly(), "type": schema.StringAttribute{ diff --git a/internal/service/opensearchserverless/collection_data_source_test.go b/internal/service/opensearchserverless/collection_data_source_test.go index b4b9db0890a2..840501b34113 100644 --- a/internal/service/opensearchserverless/collection_data_source_test.go +++ b/internal/service/opensearchserverless/collection_data_source_test.go @@ -20,7 +20,7 @@ func TestAccOpenSearchServerlessCollectionDataSource_basic(t *testing.T) { var collection types.CollectionDetail rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) dataSourceName := "data.aws_opensearchserverless_collection.test" - resourceName := ".aws_opensearchserverless_collection.test" + resourceName := "aws_opensearchserverless_collection.test" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { @@ -45,10 +45,6 @@ func TestAccOpenSearchServerlessCollectionDataSource_basic(t *testing.T) { func testAccCollectionDataSourceConfig_basic(rName, policyType string) string { return fmt.Sprintf(` -resource "aws_opensearchserverless_collection" "test" { - name = %[1]q - depends_on = [aws_opensearchserverless_security_policy.test] -} resource "aws_opensearchserverless_security_policy" "test" { name = %[1]q type = %[2]q @@ -65,6 +61,11 @@ resource "aws_opensearchserverless_security_policy" "test" { }) } +resource "aws_opensearchserverless_collection" "test" { + name = %[1]q + depends_on = [aws_opensearchserverless_security_policy.test] +} + data "aws_opensearchserverless_collection" "test" { id = aws_opensearchserverless_collection.test.id } diff --git a/website/docs/d/opensearchserverless_collection.html.markdown b/website/docs/d/opensearchserverless_collection.html.markdown index e85d4eb6be63..e9886fec3f10 100644 --- a/website/docs/d/opensearchserverless_collection.html.markdown +++ b/website/docs/d/opensearchserverless_collection.html.markdown @@ -16,6 +16,7 @@ Terraform data source for managing an AWS OpenSearch Serverless Collection. ```terraform data "aws_opensearchserverless_collection" "example" { + name = "example" } ``` @@ -23,15 +24,17 @@ data "aws_opensearchserverless_collection" "example" { The following arguments are required: -* `example_arg` - (Required) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. - -The following arguments are optional: - -* `optional_arg` - (Optional) Concise argument description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. +* `id` - (Required) ID of the collection. Either `id` or `name` must be provided. +* `name` - (Required) Name of the collection. Either `name` or `id` must be provided. ## Attributes Reference In addition to all arguments above, the following attributes are exported: -* `arn` - ARN of the Collection. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. -* `example_attribute` - Concise description. Do not begin the description with "An", "The", "Defines", "Indicates", or "Specifies," as these are verbose. In other words, "Indicates the amount of storage," can be rewritten as "Amount of storage," without losing any information. +* `arn` - Amazon Resource Name (ARN) of the collection. +* `collection_endpoint` - Collection-specific endpoint used to submit index, search, and data upload requests to an OpenSearch Serverless collection. +* `dashboard_endpont` - Collection-specific endpoint used to access OpenSearch Dashboards. +* `description` - (Optional) Description of the collection. +* `kms_key_arn` - The ARN of the Amazon Web Services KMS key used to encrypt the collection. +* `tags` - A map of tags to assign to the collection. +* `type` - Type of collection. \ No newline at end of file From 3bf99423e2bba8e035bdb3bd14cec026c3f55e48 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 27 Jun 2023 13:22:58 -0500 Subject: [PATCH 04/10] aws_opensearchserverless_collection: add lookup by name --- .../collection_data_source.go | 38 +++++++++++++++---- .../collection_data_source_test.go | 7 ++++ internal/service/opensearchserverless/find.go | 24 ++++++++++++ ...nsearchserverless_collection.html.markdown | 2 +- 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/internal/service/opensearchserverless/collection_data_source.go b/internal/service/opensearchserverless/collection_data_source.go index 841b3cd917b0..2dfcc56ddbf1 100644 --- a/internal/service/opensearchserverless/collection_data_source.go +++ b/internal/service/opensearchserverless/collection_data_source.go @@ -4,6 +4,7 @@ import ( "context" "github.com/aws/aws-sdk-go-v2/aws" + awstypes "github.com/aws/aws-sdk-go-v2/service/opensearchserverless/types" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/datasource/schema" @@ -17,7 +18,6 @@ import ( "github.com/hashicorp/terraform-provider-aws/names" ) -// Function annotations are used for datasource registration to the Provider. DO NOT EDIT. // @FrameworkDataSource(name="Collection") func newDataSourceCollection(context.Context) (datasource.DataSourceWithConfigure, error) { return &dataSourceCollection{}, nil @@ -55,6 +55,9 @@ func (d *dataSourceCollection) Schema(ctx context.Context, req datasource.Schema stringvalidator.ConflictsWith( path.MatchRelative().AtParent().AtName("name"), ), + stringvalidator.ExactlyOneOf( + path.MatchRelative().AtParent().AtName("name"), + ), }, }, "kms_key_arn": schema.StringAttribute{ @@ -85,13 +88,32 @@ func (d *dataSourceCollection) Read(ctx context.Context, req datasource.ReadRequ return } - out, err := FindCollectionByID(ctx, conn, data.ID.ValueString()) - if err != nil { - resp.Diagnostics.AddError( - create.ProblemStandardMessage(names.OpenSearchServerless, create.ErrActionReading, DSNameCollection, data.ID.String(), err), - err.Error(), - ) - return + var out *awstypes.CollectionDetail + + if !data.ID.IsNull() && !data.ID.IsUnknown() { + output, err := FindCollectionByID(ctx, conn, data.ID.ValueString()) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.OpenSearchServerless, create.ErrActionReading, DSNameCollection, data.ID.String(), err), + err.Error(), + ) + return + } + + out = output + } + + if !data.Name.IsNull() && !data.Name.IsUnknown() { + output, err := FindCollectionByName(ctx, conn, data.Name.ValueString()) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.OpenSearchServerless, create.ErrActionReading, DSNameCollection, data.ID.String(), err), + err.Error(), + ) + return + } + + out = output } data.ARN = flex.StringToFramework(ctx, out.Arn) diff --git a/internal/service/opensearchserverless/collection_data_source_test.go b/internal/service/opensearchserverless/collection_data_source_test.go index 840501b34113..c6b0d1b6bb26 100644 --- a/internal/service/opensearchserverless/collection_data_source_test.go +++ b/internal/service/opensearchserverless/collection_data_source_test.go @@ -37,6 +37,13 @@ func TestAccOpenSearchServerlessCollectionDataSource_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCollectionExists(ctx, dataSourceName, &collection), resource.TestCheckResourceAttrPair(dataSourceName, "name", resourceName, "name"), + resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "collection_endpoint", resourceName, "collection_endpoint"), + resource.TestCheckResourceAttrPair(dataSourceName, "dashboard_endpoint", resourceName, "dashboard_endpoint"), + resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceName, "kms_key_arn", resourceName, "kms_key_arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "type", resourceName, "type"), ), }, }, diff --git a/internal/service/opensearchserverless/find.go b/internal/service/opensearchserverless/find.go index b78cdf8f5b93..37bb27a766de 100644 --- a/internal/service/opensearchserverless/find.go +++ b/internal/service/opensearchserverless/find.go @@ -60,6 +60,30 @@ func FindCollectionByID(ctx context.Context, conn *opensearchserverless.Client, return &out.CollectionDetails[0], nil } +func FindCollectionByName(ctx context.Context, conn *opensearchserverless.Client, name string) (*types.CollectionDetail, error) { + in := &opensearchserverless.BatchGetCollectionInput{ + Names: []string{name}, + } + out, err := conn.BatchGetCollection(ctx, in) + if err != nil { + var nfe *types.ResourceNotFoundException + if errors.As(err, &nfe) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: in, + } + } + + return nil, err + } + + if out == nil || out.CollectionDetails == nil || len(out.CollectionDetails) == 0 { + return nil, tfresource.NewEmptyResultError(in) + } + + return &out.CollectionDetails[0], nil +} + func FindSecurityConfigByID(ctx context.Context, conn *opensearchserverless.Client, id string) (*types.SecurityConfigDetail, error) { in := &opensearchserverless.GetSecurityConfigInput{ Id: aws.String(id), diff --git a/website/docs/d/opensearchserverless_collection.html.markdown b/website/docs/d/opensearchserverless_collection.html.markdown index e9886fec3f10..a6c5fee5eef1 100644 --- a/website/docs/d/opensearchserverless_collection.html.markdown +++ b/website/docs/d/opensearchserverless_collection.html.markdown @@ -37,4 +37,4 @@ In addition to all arguments above, the following attributes are exported: * `description` - (Optional) Description of the collection. * `kms_key_arn` - The ARN of the Amazon Web Services KMS key used to encrypt the collection. * `tags` - A map of tags to assign to the collection. -* `type` - Type of collection. \ No newline at end of file +* `type` - Type of collection. From 7c7545dcc0a77dcbc9ef40d452fadbb39df9236e Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 27 Jun 2023 13:28:27 -0500 Subject: [PATCH 05/10] aws_opensearchserverless_collection: add test --- .../collection_data_source_test.go | 59 ++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/internal/service/opensearchserverless/collection_data_source_test.go b/internal/service/opensearchserverless/collection_data_source_test.go index c6b0d1b6bb26..67cdf2d99644 100644 --- a/internal/service/opensearchserverless/collection_data_source_test.go +++ b/internal/service/opensearchserverless/collection_data_source_test.go @@ -50,7 +50,46 @@ func TestAccOpenSearchServerlessCollectionDataSource_basic(t *testing.T) { }) } -func testAccCollectionDataSourceConfig_basic(rName, policyType string) string { +func TestAccOpenSearchServerlessCollectionDataSource_name(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var collection types.CollectionDetail + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + dataSourceName := "data.aws_opensearchserverless_collection.test" + resourceName := "aws_opensearchserverless_collection.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + acctest.PreCheckPartitionHasService(t, names.OpenSearchServerlessEndpointID) + testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.OpenSearchServerlessEndpointID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckCollectionDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccCollectionDataSourceConfig_name(rName, "encryption"), + Check: resource.ComposeTestCheckFunc( + testAccCheckCollectionExists(ctx, dataSourceName, &collection), + resource.TestCheckResourceAttrPair(dataSourceName, "name", resourceName, "name"), + resource.TestCheckResourceAttrPair(dataSourceName, "id", resourceName, "id"), + resource.TestCheckResourceAttrPair(dataSourceName, "arn", resourceName, "arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "collection_endpoint", resourceName, "collection_endpoint"), + resource.TestCheckResourceAttrPair(dataSourceName, "dashboard_endpoint", resourceName, "dashboard_endpoint"), + resource.TestCheckResourceAttrPair(dataSourceName, "description", resourceName, "description"), + resource.TestCheckResourceAttrPair(dataSourceName, "kms_key_arn", resourceName, "kms_key_arn"), + resource.TestCheckResourceAttrPair(dataSourceName, "type", resourceName, "type"), + ), + }, + }, + }) +} + +func testAccCollectionDataSourceBaseConfig(rName, policyType string) string { return fmt.Sprintf(` resource "aws_opensearchserverless_security_policy" "test" { name = %[1]q @@ -72,9 +111,25 @@ resource "aws_opensearchserverless_collection" "test" { name = %[1]q depends_on = [aws_opensearchserverless_security_policy.test] } +`, rName, policyType) +} +func testAccCollectionDataSourceConfig_basic(rName, policyType string) string { + return acctest.ConfigCompose( + testAccCollectionDataSourceBaseConfig(rName, policyType), + ` data "aws_opensearchserverless_collection" "test" { id = aws_opensearchserverless_collection.test.id } -`, rName, policyType) +`) +} + +func testAccCollectionDataSourceConfig_name(rName, policyType string) string { + return acctest.ConfigCompose( + testAccCollectionDataSourceBaseConfig(rName, policyType), + ` +data "aws_opensearchserverless_collection" "test" { + name = aws_opensearchserverless_collection.test.name +} +`) } From 41ec56df3b344cd81ba6ede1e9ba8dbaf7959c36 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 27 Jun 2023 15:45:23 -0500 Subject: [PATCH 06/10] aws_opensearchserverless_collection: add created and last modified dates --- .../collection_data_source.go | 15 +++++++++++++++ .../opensearchserverless_collection.html.markdown | 2 ++ 2 files changed, 17 insertions(+) diff --git a/internal/service/opensearchserverless/collection_data_source.go b/internal/service/opensearchserverless/collection_data_source.go index 2dfcc56ddbf1..655666e87556 100644 --- a/internal/service/opensearchserverless/collection_data_source.go +++ b/internal/service/opensearchserverless/collection_data_source.go @@ -2,6 +2,7 @@ package opensearchserverless import ( "context" + "time" "github.com/aws/aws-sdk-go-v2/aws" awstypes "github.com/aws/aws-sdk-go-v2/service/opensearchserverless/types" @@ -42,6 +43,9 @@ func (d *dataSourceCollection) Schema(ctx context.Context, req datasource.Schema "collection_endpoint": schema.StringAttribute{ Computed: true, }, + "created_date": schema.StringAttribute{ + Computed: true, + }, "dashboard_endpoint": schema.StringAttribute{ Computed: true, }, @@ -63,6 +67,9 @@ func (d *dataSourceCollection) Schema(ctx context.Context, req datasource.Schema "kms_key_arn": schema.StringAttribute{ Computed: true, }, + "last_modified_date": schema.StringAttribute{ + Computed: true, + }, "name": schema.StringAttribute{ Optional: true, Computed: true, @@ -125,6 +132,12 @@ func (d *dataSourceCollection) Read(ctx context.Context, req datasource.ReadRequ data.Name = flex.StringToFramework(ctx, out.Name) data.Type = flex.StringValueToFramework(ctx, out.Type) + createdDate := time.UnixMilli(aws.ToInt64(out.CreatedDate)) + data.CreatedDate = flex.StringValueToFramework(ctx, createdDate.Format(time.RFC3339)) + + lastModifiedDate := time.UnixMilli(aws.ToInt64(out.LastModifiedDate)) + data.LastModifiedDate = flex.StringValueToFramework(ctx, lastModifiedDate.Format(time.RFC3339)) + ignoreTagsConfig := d.Meta().IgnoreTagsConfig tags, err := listTags(ctx, conn, aws.ToString(out.Arn)) @@ -145,10 +158,12 @@ func (d *dataSourceCollection) Read(ctx context.Context, req datasource.ReadRequ type dataSourceCollectionData struct { ARN types.String `tfsdk:"arn"` CollectionEndpoint types.String `tfsdk:"collection_endpoint"` + CreatedDate types.String `tfsdk:"created_date"` DashboardEndpoint types.String `tfsdk:"dashboard_endpoint"` Description types.String `tfsdk:"description"` ID types.String `tfsdk:"id"` KmsKeyARN types.String `tfsdk:"kms_key_arn"` + LastModifiedDate types.String `tfsdk:"last_modified_date"` Name types.String `tfsdk:"name"` Tags types.Map `tfsdk:"tags"` Type types.String `tfsdk:"type"` diff --git a/website/docs/d/opensearchserverless_collection.html.markdown b/website/docs/d/opensearchserverless_collection.html.markdown index a6c5fee5eef1..0bb23834b4dd 100644 --- a/website/docs/d/opensearchserverless_collection.html.markdown +++ b/website/docs/d/opensearchserverless_collection.html.markdown @@ -33,8 +33,10 @@ In addition to all arguments above, the following attributes are exported: * `arn` - Amazon Resource Name (ARN) of the collection. * `collection_endpoint` - Collection-specific endpoint used to submit index, search, and data upload requests to an OpenSearch Serverless collection. +* `created_date` - Date the Collection was created. * `dashboard_endpont` - Collection-specific endpoint used to access OpenSearch Dashboards. * `description` - (Optional) Description of the collection. * `kms_key_arn` - The ARN of the Amazon Web Services KMS key used to encrypt the collection. +* `last_modified_date` - Date the Collection was last modified. * `tags` - A map of tags to assign to the collection. * `type` - Type of collection. From 8e2acd84e7d3b4f1589bb33884417c02449fdd33 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 27 Jun 2023 15:46:47 -0500 Subject: [PATCH 07/10] add CHANGELOG entry --- .changelog/32247.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/32247.txt diff --git a/.changelog/32247.txt b/.changelog/32247.txt new file mode 100644 index 000000000000..f59487ddd3a7 --- /dev/null +++ b/.changelog/32247.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_opensearchserverless_collection +``` \ No newline at end of file From 585f481327f7d177cb5abfeedacac932dfb0efca Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 27 Jun 2023 16:57:36 -0500 Subject: [PATCH 08/10] chore: cleanup func signatures --- .../service/opensearchserverless/collection_data_source.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/opensearchserverless/collection_data_source.go b/internal/service/opensearchserverless/collection_data_source.go index 655666e87556..3e20ae26fa5c 100644 --- a/internal/service/opensearchserverless/collection_data_source.go +++ b/internal/service/opensearchserverless/collection_data_source.go @@ -32,11 +32,11 @@ type dataSourceCollection struct { framework.DataSourceWithConfigure } -func (d *dataSourceCollection) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { // nosemgrep:ci.meta-in-func-name +func (d *dataSourceCollection) Metadata(_ context.Context, _ datasource.MetadataRequest, resp *datasource.MetadataResponse) { // nosemgrep:ci.meta-in-func-name resp.TypeName = "aws_opensearchserverless_collection" } -func (d *dataSourceCollection) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { +func (d *dataSourceCollection) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { resp.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ "arn": framework.ARNAttributeComputedOnly(), From a0b0b2a94a0a6eec4b9d8a12f05ff2868eb3a76f Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Wed, 28 Jun 2023 08:53:34 -0500 Subject: [PATCH 09/10] correct documentation Co-authored-by: Jared Baker --- website/docs/d/opensearchserverless_collection.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/d/opensearchserverless_collection.html.markdown b/website/docs/d/opensearchserverless_collection.html.markdown index 0bb23834b4dd..357bdbbab971 100644 --- a/website/docs/d/opensearchserverless_collection.html.markdown +++ b/website/docs/d/opensearchserverless_collection.html.markdown @@ -35,7 +35,7 @@ In addition to all arguments above, the following attributes are exported: * `collection_endpoint` - Collection-specific endpoint used to submit index, search, and data upload requests to an OpenSearch Serverless collection. * `created_date` - Date the Collection was created. * `dashboard_endpont` - Collection-specific endpoint used to access OpenSearch Dashboards. -* `description` - (Optional) Description of the collection. +* `description` - Description of the collection. * `kms_key_arn` - The ARN of the Amazon Web Services KMS key used to encrypt the collection. * `last_modified_date` - Date the Collection was last modified. * `tags` - A map of tags to assign to the collection. From a6c7598c35fe78e5808fa96bf227327fc0c0d49b Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Wed, 28 Jun 2023 09:13:22 -0500 Subject: [PATCH 10/10] aws_opensearchserverless_collection: add check for too many results --- internal/service/opensearchserverless/find.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/service/opensearchserverless/find.go b/internal/service/opensearchserverless/find.go index 37bb27a766de..271d0d35d61b 100644 --- a/internal/service/opensearchserverless/find.go +++ b/internal/service/opensearchserverless/find.go @@ -81,6 +81,10 @@ func FindCollectionByName(ctx context.Context, conn *opensearchserverless.Client return nil, tfresource.NewEmptyResultError(in) } + if len(out.CollectionDetails) > 1 { + return nil, tfresource.NewTooManyResultsError(len(out.CollectionDetails), in) + } + return &out.CollectionDetails[0], nil }