Skip to content

Commit

Permalink
Merge pull request #37433 from hashicorp/b-lakeformation_data_cells_f…
Browse files Browse the repository at this point in the history
…ilter_rows

r/lakeformation_data_cells_filter: fix error when using `row_filter.all_rows_wildcard`
  • Loading branch information
johnsonaj authored May 10, 2024
2 parents 18ca4ad + 7576d54 commit b52d7b4
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 19 deletions.
3 changes: 3 additions & 0 deletions .changelog/37433.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
resource/aws_lakeformation_data_cells_filter: Fix inconsistent `state` error when using `row_filter.all_rows_wildcard`
```
51 changes: 32 additions & 19 deletions internal/service/lakeformation/data_cells_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package lakeformation

import (
"context"
"strings"
"time"

"github.com/YakDriver/regexache"
Expand Down Expand Up @@ -109,9 +108,6 @@ func (r *resourceDataCellsFilter) Schema(ctx context.Context, _ resource.SchemaR
Validators: []validator.String{
stringvalidator.RegexMatches(regexache.MustCompile(`^[0-9]+$`), "must be a number"),
},
PlanModifiers: []planmodifier.String{
stringplanmodifier.UseStateForUnknown(),
},
},
},
Blocks: map[string]schema.Block{
Expand All @@ -132,12 +128,14 @@ func (r *resourceDataCellsFilter) Schema(ctx context.Context, _ resource.SchemaR
"row_filter": schema.ListNestedBlock{
CustomType: fwtypes.NewListNestedObjectTypeOf[rowFilter](ctx),
Validators: []validator.List{
listvalidator.IsRequired(),
listvalidator.SizeAtMost(1),
},
NestedObject: schema.NestedBlockObject{
Attributes: map[string]schema.Attribute{
"filter_expression": schema.StringAttribute{
Optional: true,
Computed: true,
},
},
Blocks: map[string]schema.Block{
Expand All @@ -160,6 +158,10 @@ func (r *resourceDataCellsFilter) Schema(ctx context.Context, _ resource.SchemaR
}
}

const (
dataCellsFilterIDPartCount = 4
)

func (r *resourceDataCellsFilter) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
conn := r.Meta().LakeFormationClient(ctx)

Expand Down Expand Up @@ -198,7 +200,7 @@ func (r *resourceDataCellsFilter) Create(ctx context.Context, req resource.Creat
planTD.TableCatalogID.ValueString(),
planTD.TableName.ValueString(),
}
id, err := intflex.FlattenResourceId(idParts, len(idParts), false)
id, err := intflex.FlattenResourceId(idParts, dataCellsFilterIDPartCount, false)

if err != nil {
resp.Diagnostics.AddError(
Expand Down Expand Up @@ -299,6 +301,25 @@ func (r *resourceDataCellsFilter) Update(ctx context.Context, req resource.Updat
)
return
}

output, err := findDataCellsFilterByID(ctx, conn, state.ID.ValueString())

if err != nil {
resp.Diagnostics.AddError(
create.ProblemStandardMessage(names.LakeFormation, create.ErrActionUpdating, ResNameDataCellsFilter, plan.ID.String(), err),
err.Error(),
)
return
}

td := tableData{}
resp.Diagnostics.Append(fwflex.Flatten(ctx, output, &td)...)

if resp.Diagnostics.HasError() {
return
}

plan.TableData = fwtypes.NewListNestedObjectValueOfPtrMust(ctx, &td)
}

resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
Expand All @@ -319,8 +340,7 @@ func (r *resourceDataCellsFilter) Delete(ctx context.Context, req resource.Delet
return
}

id := identifier(state.ID.ValueString())
idParts, err := intflex.ExpandResourceId(id.String(), id.Len(), false)
idParts, err := intflex.ExpandResourceId(state.ID.ValueString(), dataCellsFilterIDPartCount, false)

if err != nil {
resp.Diagnostics.AddError(
Expand Down Expand Up @@ -358,22 +378,15 @@ func (r *resourceDataCellsFilter) ConfigValidators(_ context.Context) []resource
path.MatchRoot("table_data").AtListIndex(0).AtName("column_names"),
path.MatchRoot("table_data").AtListIndex(0).AtName("column_wildcard"),
),
resourcevalidator.ExactlyOneOf(
path.MatchRoot("table_data").AtListIndex(0).AtName("row_filter").AtListIndex(0).AtName("filter_expression"),
path.MatchRoot("table_data").AtListIndex(0).AtName("row_filter").AtListIndex(0).AtName("all_rows_wildcard"),
),
}
}

type identifier string

func (i *identifier) String() string {
return string(*i)
}

func (i *identifier) Len() int {
return len(strings.Split(string(*i), intflex.ResourceIdSeparator))
}

func findDataCellsFilterByID(ctx context.Context, conn *lakeformation.Client, id string) (*awstypes.DataCellsFilter, error) {
identity := identifier(id)
idParts, err := intflex.ExpandResourceId(identity.String(), identity.Len(), false)
idParts, err := intflex.ExpandResourceId(id, dataCellsFilterIDPartCount, false)

if err != nil {
return nil, err
Expand Down
74 changes: 74 additions & 0 deletions internal/service/lakeformation/data_cells_filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,57 @@ func testAccDataCellsFilter_disappears(t *testing.T) {
})
}

func testAccDataCellsFilter_rowFilter(t *testing.T) {
ctx := acctest.Context(t)

var datacellsfilter awstypes.DataCellsFilter
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_lakeformation_data_cells_filter.test"

filterExpression := `
filter_expression = "my_column_23='testing'"
`
allRowsildcard := `
all_rows_wildcard {}
`
resource.Test(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
acctest.PreCheckPartitionHasService(t, names.LakeFormation)
testAccDataCellsFilterPreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, names.LakeFormationServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckDataCellsFilterDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccDataCellsFilterConfig_rowFilter(rName, filterExpression),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataCellsFilterExists(ctx, resourceName, &datacellsfilter),
resource.TestCheckResourceAttr(resourceName, "table_data.0.database_name", rName),
resource.TestCheckResourceAttr(resourceName, "table_data.0.name", rName),
resource.TestCheckResourceAttr(resourceName, "table_data.0.table_name", rName),
resource.TestCheckResourceAttrSet(resourceName, "table_data.0.version_id"),
resource.TestCheckResourceAttr(resourceName, "table_data.0.column_names.#", "1"),
resource.TestCheckResourceAttr(resourceName, "table_data.0.row_filter.0.filter_expression", "my_column_23='testing'"),
),
},
{
Config: testAccDataCellsFilterConfig_rowFilter(rName, allRowsildcard),
Check: resource.ComposeTestCheckFunc(
testAccCheckDataCellsFilterExists(ctx, resourceName, &datacellsfilter),
resource.TestCheckResourceAttr(resourceName, "table_data.0.database_name", rName),
resource.TestCheckResourceAttr(resourceName, "table_data.0.name", rName),
resource.TestCheckResourceAttr(resourceName, "table_data.0.table_name", rName),
resource.TestCheckResourceAttrSet(resourceName, "table_data.0.version_id"),
resource.TestCheckResourceAttr(resourceName, "table_data.0.column_names.#", "1"),
resource.TestCheckResourceAttr(resourceName, "table_data.0.row_filter.0.all_rows_wildcard.#", "1"),
),
},
},
})
}

func testAccCheckDataCellsFilterDestroy(ctx context.Context) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).LakeFormationClient(ctx)
Expand Down Expand Up @@ -292,3 +343,26 @@ resource "aws_lakeformation_data_cells_filter" "test" {
}
`, rName, column))
}

func testAccDataCellsFilterConfig_rowFilter(rName, rowFilter string) string {
return acctest.ConfigCompose(
testAccDataCellsFilterConfigBase(rName),
fmt.Sprintf(`
resource "aws_lakeformation_data_cells_filter" "test" {
table_data {
database_name = aws_glue_catalog_database.test.name
name = %[1]q
table_catalog_id = data.aws_caller_identity.current.account_id
table_name = aws_glue_catalog_table.test.name
column_names = ["my_column_22"]
row_filter {
%[2]s
}
}
depends_on = [aws_lakeformation_data_lake_settings.test]
}
`, rName, rowFilter))
}
1 change: 1 addition & 0 deletions internal/service/lakeformation/lakeformation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func TestAccLakeFormation_serial(t *testing.T) {
"basic": testAccDataCellsFilter_basic,
"columnWildcard": testAccDataCellsFilter_columnWildcard,
"disappears": testAccDataCellsFilter_disappears,
"rowFilter": testAccDataCellsFilter_rowFilter,
},
"DataLakeSettingsDataSource": {
"basic": testAccDataLakeSettingsDataSource_basic,
Expand Down

0 comments on commit b52d7b4

Please sign in to comment.