diff --git a/.changelog/28258.txt b/.changelog/28258.txt new file mode 100644 index 00000000000..568e42ad81b --- /dev/null +++ b/.changelog/28258.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_lakeformation_lf_tag: Fix support for lf-tag keys with colons in the name +``` \ No newline at end of file diff --git a/internal/service/lakeformation/lakeformation_test.go b/internal/service/lakeformation/lakeformation_test.go index 8ee1b689dc0..dfe53801259 100644 --- a/internal/service/lakeformation/lakeformation_test.go +++ b/internal/service/lakeformation/lakeformation_test.go @@ -54,9 +54,10 @@ func TestAccLakeFormation_serial(t *testing.T) { "wildcardSelectPlus": testAccPermissions_twcWildcardSelectPlus, }, "LFTags": { - "basic": testAccLFTag_basic, - "disappears": testAccLFTag_disappears, - "values": testAccLFTag_values, + "basic": testAccLFTag_basic, + "disappears": testAccLFTag_disappears, + "tagKeyComplex": testAccLFTag_TagKey_complex, + "values": testAccLFTag_values, }, "ResourceLFTags": { "basic": testAccResourceLFTags_basic, diff --git a/internal/service/lakeformation/lf_tag.go b/internal/service/lakeformation/lf_tag.go index 4352da7ffd6..f5d27697e9c 100644 --- a/internal/service/lakeformation/lf_tag.go +++ b/internal/service/lakeformation/lf_tag.go @@ -179,12 +179,14 @@ func resourceLFTagDelete(ctx context.Context, d *schema.ResourceData, meta inter return diags } -func ReadLFTagID(id string) (catalogID string, tagKey string, err error) { - idParts := strings.Split(id, ":") - if len(idParts) != 2 { +func ReadLFTagID(id string) (string, string, error) { + catalogID, tagKey, found := strings.Cut(id, ":") + + if !found { return "", "", fmt.Errorf("unexpected format of ID (%q), expected CATALOG-ID:TAG-KEY", id) } - return idParts[0], idParts[1], nil + + return catalogID, tagKey, nil } func validateLFTagValues() schema.SchemaValidateFunc { diff --git a/internal/service/lakeformation/lf_tag_test.go b/internal/service/lakeformation/lf_tag_test.go index f574f9fa1cc..f1ac49dc40e 100644 --- a/internal/service/lakeformation/lf_tag_test.go +++ b/internal/service/lakeformation/lf_tag_test.go @@ -18,6 +18,58 @@ import ( tflakeformation "github.com/hashicorp/terraform-provider-aws/internal/service/lakeformation" ) +func TestReadLFTagID(t *testing.T) { + t.Parallel() + + type testCase struct { + val string + catalogID string + tagKey string + expectError bool + } + + tests := map[string]testCase{ + "empty_string": { + expectError: true, + }, + "invalid_id": { + val: "test", + expectError: true, + }, + "valid_key_simple": { + val: "123344556:tagKey", + catalogID: "123344556", + tagKey: "tagKey", + }, + "valid_key_complex": { + val: "123344556:keyPrefix:tagKey", + catalogID: "123344556", + tagKey: "keyPrefix:tagKey", + }, + } + + for name, test := range tests { + name, test := name, test + t.Run(name, func(t *testing.T) { + t.Parallel() + + catalogID, tagKey, err := tflakeformation.ReadLFTagID(test.val) + + if err == nil && test.expectError { + t.Fatal("expected error") + } + + if err != nil && !test.expectError { + t.Fatalf("got unexpected error: %s", err) + } + + if test.catalogID != catalogID || test.tagKey != tagKey { + t.Fatalf("expected catalogID (%s), tagKey (%s), got catalogID (%s), tagKey (%s)", test.catalogID, test.tagKey, catalogID, tagKey) + } + }) + } +} + func testAccLFTag_basic(t *testing.T) { ctx := acctest.Context(t) resourceName := "aws_lakeformation_lf_tag.test" @@ -47,6 +99,30 @@ func testAccLFTag_basic(t *testing.T) { }) } +func testAccLFTag_TagKey_complex(t *testing.T) { + ctx := acctest.Context(t) + resourceName := "aws_lakeformation_lf_tag.test" + rName := fmt.Sprintf("%s:%s", sdkacctest.RandomWithPrefix(acctest.ResourcePrefix), "subKey") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, lakeformation.EndpointsID) }, + ErrorCheck: acctest.ErrorCheck(t, lakeformation.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckLFTagsDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: testAccLFTagConfig_basic(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckLFTagExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, "key", rName), + resource.TestCheckResourceAttr(resourceName, "values.0", "value"), + acctest.CheckResourceAttrAccountID(resourceName, "catalog_id"), + ), + }, + }, + }) +} + func testAccLFTag_disappears(t *testing.T) { ctx := acctest.Context(t) resourceName := "aws_lakeformation_lf_tag.test"