Skip to content

Commit

Permalink
Merge pull request hashicorp#36778 from acwwat/b-aws_resourceexplorer…
Browse files Browse the repository at this point in the history
…2_search-view_arn_not_used

Fix: Set view_arn and other attrs properly for aws_resourcexplorer2_search data source
  • Loading branch information
nam054 authored May 9, 2024
2 parents 7d38d26 + c7762c0 commit 4f5ca45
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 83 deletions.
11 changes: 11 additions & 0 deletions .changelog/36778.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```release-note:bug
data-source/aws_resourceexplorer2_search: Fix panic caused by bad mappping between Terraform and AWS schemas
```

```release-note:bug
data-source/aws_resourceexplorer2_search: Fix 401 unauthorized error due to missing `view_arn` in the AWS API request
```

```release-note:bug
data-source/aws_resourceexplorer2_search: Fix state persistence and data types
```
127 changes: 49 additions & 78 deletions internal/service/resourceexplorer2/search_data_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ package resourceexplorer2

import (
"context"
"fmt"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/resourceexplorer2"
"github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes"
"github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes"
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
Expand Down Expand Up @@ -40,75 +43,28 @@ func (d *dataSourceSearch) Metadata(_ context.Context, req datasource.MetadataRe
func (d *dataSourceSearch) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
names.AttrID: framework.IDAttribute(),
"query_string": schema.StringAttribute{
Required: true,
},
names.AttrID: framework.IDAttribute(),
"resource_count": schema.ListAttribute{
CustomType: fwtypes.NewListNestedObjectTypeOf[countData](ctx),
Computed: true,
},
"resources": schema.ListAttribute{
CustomType: fwtypes.NewListNestedObjectTypeOf[resourcesData](ctx),
ElementType: fwtypes.NewObjectTypeOf[resourcesData](ctx),
Computed: true,
},
"view_arn": schema.StringAttribute{
Optional: true,
CustomType: fwtypes.ARNType,
Optional: true,
Computed: true,
Validators: []validator.String{
stringvalidator.LengthBetween(0, 1011),
},
},
},
Blocks: map[string]schema.Block{
"resource_count": schema.ListNestedBlock{
CustomType: fwtypes.NewListNestedObjectTypeOf[countData](ctx),
NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{
"complete": schema.BoolAttribute{
Computed: true,
},
"total_resources": schema.Int64Attribute{
Computed: true,
},
},
},
},
"resources": schema.ListNestedBlock{
CustomType: fwtypes.NewListNestedObjectTypeOf[resourcesData](ctx),
NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{
names.AttrARN: schema.StringAttribute{
Computed: true,
},
"last_reported_at": schema.StringAttribute{
Computed: true,
},
"owning_account_id": schema.StringAttribute{
Computed: true,
},
"region": schema.StringAttribute{
Computed: true,
},
"resource_type": schema.StringAttribute{
Computed: true,
},
"service": schema.StringAttribute{
Computed: true,
},
},
Blocks: map[string]schema.Block{
"resource_property": schema.ListNestedBlock{
CustomType: fwtypes.NewListNestedObjectTypeOf[resourcePropertyData](ctx),
NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{
"data": schema.StringAttribute{
Computed: true,
},
"last_reported_at": schema.StringAttribute{
Computed: true,
},
names.AttrName: schema.StringAttribute{
Computed: true,
},
},
},
},
},
},
},
},
}
}

Expand All @@ -121,15 +77,23 @@ func (d *dataSourceSearch) Read(ctx context.Context, req datasource.ReadRequest,
return
}

data.ID = types.StringValue(data.QueryString.ValueString())
if data.ViewArn.IsNull() {
data.ID = types.StringValue(fmt.Sprintf(",%s", data.QueryString.ValueString()))
} else {
data.ID = types.StringValue(fmt.Sprintf("%s,%s", data.ViewArn.ValueString(), data.QueryString.ValueString()))
}

input := &resourceexplorer2.SearchInput{
QueryString: aws.String(data.QueryString.ValueString()),
}
if !data.ViewArn.IsNull() {
input.ViewArn = aws.String(data.ViewArn.ValueString())
}

paginator := resourceexplorer2.NewSearchPaginator(conn, input)

var out resourceexplorer2.SearchOutput
commonFieldsSet := false
for paginator.HasMorePages() {
page, err := paginator.NextPage(ctx)
if err != nil {
Expand All @@ -141,6 +105,11 @@ func (d *dataSourceSearch) Read(ctx context.Context, req datasource.ReadRequest,
}

if page != nil && len(page.Resources) > 0 {
if !commonFieldsSet {
out.Count = page.Count
out.ViewArn = page.ViewArn
commonFieldsSet = true
}
out.Resources = append(out.Resources, page.Resources...)
}
}
Expand All @@ -149,33 +118,35 @@ func (d *dataSourceSearch) Read(ctx context.Context, req datasource.ReadRequest,
if resp.Diagnostics.HasError() {
return
}

resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
}

type dataSourceSearchData struct {
ResourceCount fwtypes.ListNestedObjectValueOf[countData] `tfsdk:"resource_count"`
Resources fwtypes.ListNestedObjectValueOf[resourcesData] `tfsdk:"resources"`
ID types.String `tfsdk:"id"`
ViewArn types.String `tfsdk:"view_arn"`
QueryString types.String `tfsdk:"query_string"`
Count fwtypes.ListNestedObjectValueOf[countData] `tfsdk:"resource_count"`
ID types.String `tfsdk:"id"`
QueryString types.String `tfsdk:"query_string"`
Resources fwtypes.ListNestedObjectValueOf[resourcesData] `tfsdk:"resources"`
ViewArn fwtypes.ARN `tfsdk:"view_arn"`
}

type countData struct {
Completed types.Bool `tfsdk:"completed"`
Complete types.Bool `tfsdk:"complete"`
TotalResources types.Int64 `tfsdk:"total_resources"`
}

type resourcesData struct {
ARN types.String `tfsdk:"arn"`
LastReportedAt types.String `tfsdk:"last_reported_at"`
OwningAccountID types.String `tfsdk:"owning_account_id"`
Region types.String `tfsdk:"region"`
ResourceProperty fwtypes.ListNestedObjectValueOf[resourcePropertyData] `tfsdk:"resource_property"`
ResourceType types.String `tfsdk:"resource_type"`
Service types.String `tfsdk:"service"`
ARN fwtypes.ARN `tfsdk:"arn"`
LastReportedAt timetypes.RFC3339 `tfsdk:"last_reported_at"`
OwningAccountID types.String `tfsdk:"owning_account_id"`
Properties fwtypes.ListNestedObjectValueOf[propertiesData] `tfsdk:"properties"`
Region types.String `tfsdk:"region"`
ResourceType types.String `tfsdk:"resource_type"`
Service types.String `tfsdk:"service"`
}

type resourcePropertyData struct {
Data types.String `tfsdk:"data"`
LastReportedAt types.String `tfsdk:"last_reported_at"`
Name types.String `tfsdk:"name"`
type propertiesData struct {
Data jsontypes.Normalized `tfsdk:"data"`
LastReportedAt timetypes.RFC3339 `tfsdk:"last_reported_at"`
Name types.String `tfsdk:"name"`
}
26 changes: 23 additions & 3 deletions internal/service/resourceexplorer2/search_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ func testAccSearchDataSource_basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "view_arn", viewResourceName, names.AttrARN),
resource.TestCheckResourceAttrSet(dataSourceName, "resource_count.#"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.#"),
resource.TestCheckResourceAttrSet(dataSourceName, "resource_count.0.total_resources"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.arn"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.last_reported_at"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.owning_account_id"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.properties.#"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.region"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.resource_type"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.service"),
),
},
},
Expand Down Expand Up @@ -73,7 +80,14 @@ func testAccSearchDataSource_IndexType(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrPair(dataSourceName, "view_arn", viewResourceName, names.AttrARN),
resource.TestCheckResourceAttrSet(dataSourceName, "resource_count.#"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.#"),
resource.TestCheckResourceAttrSet(dataSourceName, "resource_count.0.total_resources"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.arn"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.last_reported_at"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.owning_account_id"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.properties.#"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.region"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.resource_type"),
resource.TestCheckResourceAttrSet(dataSourceName, "resources.0.service"),
),
},
},
Expand All @@ -82,6 +96,8 @@ func testAccSearchDataSource_IndexType(t *testing.T) {

func testAccSearchDataSourceConfig_basic(rName, indexType string) string {
return fmt.Sprintf(`
data "aws_region" "current" {}
resource "aws_resourceexplorer2_index" "test" {
type = %[2]q
Expand All @@ -95,12 +111,16 @@ resource "aws_resourceexplorer2_view" "test" {
name = %[1]q
default_view = true
included_property {
name = "tags"
}
}
data "aws_resourceexplorer2_search" "test" {
depends_on = [aws_resourceexplorer2_view.test]
query_string = "region:global"
query_string = "region:${data.aws_region.current.name}"
view_arn = aws_resourceexplorer2_view.test.arn
}
`, rName, indexType)
Expand Down
4 changes: 2 additions & 2 deletions website/docs/d/resourceexplorer2_search.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ This data source exports the following attributes in addition to the arguments a
* `arn` - Amazon resource name of resource.
* `last_reported_at` - Date and time that Resource Explorer last queried this resource and updated the index with the latest information about the resource.
* `owning_account_id` - Amazon Web Services account that owns the resource.
* `resource_property` - Structure with additional type-specific details about the resource. See [`resource_property`](#resource_property-attribute-reference) below.
* `properties` - Structure with additional type-specific details about the resource. See [`properties`](#properties-attribute-reference) below.
* `region` - Amazon Web Services Region in which the resource was created and exists.
* `resource_type` - Type of the resource.
* `service` - Amazon Web Service that owns the resource and is responsible for creating and updating it.

### `resource_property` Attribute Reference
### `properties` Attribute Reference

* `data` - Details about this property. The content of this field is a JSON object that varies based on the resource type.
* `last_reported_at` - The date and time that the information about this resource property was last updated.
Expand Down

0 comments on commit 4f5ca45

Please sign in to comment.