From 692ebdb503b4a4a62ae40de35431cf5b78de5f09 Mon Sep 17 00:00:00 2001 From: Tadayuki Onishi Date: Fri, 7 Oct 2022 02:51:45 +0900 Subject: [PATCH 01/20] Add transfer tag resoure impl --- internal/provider/provider.go | 1 + internal/service/transfer/tag_gen.go | 116 ++++++++++++++++++++++ internal/service/transfer/tag_gen_test.go | 71 +++++++++++++ internal/service/transfer/tags_gen.go | 23 +++++ 4 files changed, 211 insertions(+) create mode 100644 internal/service/transfer/tag_gen.go create mode 100644 internal/service/transfer/tag_gen_test.go diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 10dd24663c7a..e3293c3cea07 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -2123,6 +2123,7 @@ func New(_ context.Context) (*schema.Provider, error) { "aws_transfer_ssh_key": transfer.ResourceSSHKey(), "aws_transfer_user": transfer.ResourceUser(), "aws_transfer_workflow": transfer.ResourceWorkflow(), + "aws_transfer_tag": transfer.ResourceTag(), "aws_waf_byte_match_set": waf.ResourceByteMatchSet(), "aws_waf_geo_match_set": waf.ResourceGeoMatchSet(), diff --git a/internal/service/transfer/tag_gen.go b/internal/service/transfer/tag_gen.go new file mode 100644 index 000000000000..00aedac5de97 --- /dev/null +++ b/internal/service/transfer/tag_gen.go @@ -0,0 +1,116 @@ +// Code generated by internal/generate/tagresource/main.go; DO NOT EDIT. + +package transfer + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/service/transfer" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func ResourceTag() *schema.Resource { + return &schema.Resource{ + Create: resourceTagCreate, + Read: resourceTagRead, + Update: resourceTagUpdate, + Delete: resourceTagDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "resource_arn": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "key": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "value": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func resourceTagCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).TransferConn + + identifier := d.Get("resource_arn").(string) + key := d.Get("key").(string) + value := d.Get("value").(string) + + if err := UpdateTags(conn, identifier, nil, map[string]string{key: value}); err != nil { + return fmt.Errorf("error creating %s resource (%s) tag (%s): %w", transfer.ServiceID, identifier, key, err) + } + + d.SetId(tftags.SetResourceID(identifier, key)) + + return resourceTagRead(d, meta) +} + +func resourceTagRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).TransferConn + identifier, key, err := tftags.GetResourceID(d.Id()) + + if err != nil { + return err + } + + value, err := GetTag(conn, identifier, key) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] %s resource (%s) tag (%s) not found, removing from state", transfer.ServiceID, identifier, key) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error reading %s resource (%s) tag (%s): %w", transfer.ServiceID, identifier, key, err) + } + + d.Set("resource_arn", identifier) + d.Set("key", key) + d.Set("value", value) + + return nil +} + +func resourceTagUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).TransferConn + identifier, key, err := tftags.GetResourceID(d.Id()) + + if err != nil { + return err + } + + if err := UpdateTags(conn, identifier, nil, map[string]string{key: d.Get("value").(string)}); err != nil { + return fmt.Errorf("error updating %s resource (%s) tag (%s): %w", transfer.ServiceID, identifier, key, err) + } + + return resourceTagRead(d, meta) +} + +func resourceTagDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*conns.AWSClient).TransferConn + identifier, key, err := tftags.GetResourceID(d.Id()) + + if err != nil { + return err + } + + if err := UpdateTags(conn, identifier, map[string]string{key: d.Get("value").(string)}, nil); err != nil { + return fmt.Errorf("error deleting %s resource (%s) tag (%s): %w", transfer.ServiceID, identifier, key, err) + } + + return nil +} diff --git a/internal/service/transfer/tag_gen_test.go b/internal/service/transfer/tag_gen_test.go new file mode 100644 index 000000000000..9b7c8c7cf39b --- /dev/null +++ b/internal/service/transfer/tag_gen_test.go @@ -0,0 +1,71 @@ +// Code generated by internal/generate/tagresource/main.go; DO NOT EDIT. + +package transfer_test + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/service/transfer" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + tftransfer "github.com/hashicorp/terraform-provider-aws/internal/service/transfer" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" +) + +func testAccCheckTagDestroy(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).TransferConn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_transfer_tag" { + continue + } + + identifier, key, err := tftags.GetResourceID(rs.Primary.ID) + + if err != nil { + return err + } + + _, err = tftransfer.GetTag(conn, identifier, key) + + if tfresource.NotFound(err) { + continue + } + + if err != nil { + return err + } + + return fmt.Errorf("%s resource (%s) tag (%s) still exists", transfer.ServiceID, identifier, key) + } + + return nil +} + +func testAccCheckTagExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("not found: %s", resourceName) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("%s: missing resource ID", resourceName) + } + + identifier, key, err := tftags.GetResourceID(rs.Primary.ID) + + if err != nil { + return err + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).TransferConn + + _, err = tftransfer.GetTag(conn, identifier, key) + + return err + } +} diff --git a/internal/service/transfer/tags_gen.go b/internal/service/transfer/tags_gen.go index 782b5caacd2f..2101d6d69004 100644 --- a/internal/service/transfer/tags_gen.go +++ b/internal/service/transfer/tags_gen.go @@ -9,8 +9,31 @@ import ( "github.com/aws/aws-sdk-go/service/transfer" "github.com/aws/aws-sdk-go/service/transfer/transferiface" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" ) +// GetTag fetches an individual transfer service tag for a resource. +// Returns whether the key value and any errors. A NotFoundError is used to signal that no value was found. +// This function will optimise the handling over ListTags, if possible. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func GetTag(conn transferiface.TransferAPI, identifier string, key string) (*string, error) { + return GetTagWithContext(context.Background(), conn, identifier, key) +} +func GetTagWithContext(ctx context.Context, conn transferiface.TransferAPI, identifier string, key string) (*string, error) { + listTags, err := ListTagsWithContext(ctx, conn, identifier) + + if err != nil { + return nil, err + } + + if !listTags.KeyExists(key) { + return nil, tfresource.NewEmptyResultError(nil) + } + + return listTags.KeyValue(key), nil +} + // ListTags lists transfer service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. From 11406529f856ba03f11e858efe0f8395070d7e6e Mon Sep 17 00:00:00 2001 From: Tadayuki Onishi Date: Fri, 7 Oct 2022 02:53:28 +0900 Subject: [PATCH 02/20] Allow aws prefix tags for transfer tags --- internal/service/transfer/tags_gen.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/transfer/tags_gen.go b/internal/service/transfer/tags_gen.go index 2101d6d69004..94e87ab6c391 100644 --- a/internal/service/transfer/tags_gen.go +++ b/internal/service/transfer/tags_gen.go @@ -97,7 +97,7 @@ func UpdateTagsWithContext(ctx context.Context, conn transferiface.TransferAPI, if removedTags := oldTags.Removed(newTags); len(removedTags) > 0 { input := &transfer.UntagResourceInput{ Arn: aws.String(identifier), - TagKeys: aws.StringSlice(removedTags.IgnoreAWS().Keys()), + TagKeys: aws.StringSlice(removedTags.Keys()), } _, err := conn.UntagResourceWithContext(ctx, input) @@ -110,7 +110,7 @@ func UpdateTagsWithContext(ctx context.Context, conn transferiface.TransferAPI, if updatedTags := oldTags.Updated(newTags); len(updatedTags) > 0 { input := &transfer.TagResourceInput{ Arn: aws.String(identifier), - Tags: Tags(updatedTags.IgnoreAWS()), + Tags: Tags(updatedTags), } _, err := conn.TagResourceWithContext(ctx, input) From a99a5c2696566449cc07f941d064ae28d1cb1a7c Mon Sep 17 00:00:00 2001 From: Tadayuki Onishi Date: Fri, 7 Oct 2022 02:54:10 +0900 Subject: [PATCH 03/20] Add a transfer tag resource doc --- website/docs/r/transfer_tag.html.markdown | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 website/docs/r/transfer_tag.html.markdown diff --git a/website/docs/r/transfer_tag.html.markdown b/website/docs/r/transfer_tag.html.markdown new file mode 100644 index 000000000000..9ad14aaba34f --- /dev/null +++ b/website/docs/r/transfer_tag.html.markdown @@ -0,0 +1,51 @@ +--- +subcategory: "Transfer Family" +layout: "aws" +page_title: "AWS: aws_transfer_tag" +description: |- + Manages an individual Transfer Family resource tag +--- + +# Resource: aws_transfer_tag + +Manages an individual Transfer Family resource tag. This resource should only be used in cases where Transfer Family resources are created outside Terraform (e.g., Servers without AWS Management Console). + +~> **NOTE:** This tagging resource should not be combined with the Terraform resource for managing the parent resource. For example, using `aws_transfer_server` and `aws_transfer_tag` to manage tags of the same ASG will cause a perpetual difference where the `aws_transfer_server` resource will try to remove the tag being added by the `aws_transfer_tag` resource. + +~> **NOTE:** This tagging resource does not use the [provider `ignore_tags` configuration](/docs/providers/aws/index.html#ignore_tags). + +## Example Usage + +```terraform +resource "aws_transfer_server" "example" { + identity_provider_type = "SERVICE_MANAGED" +} + +resource "aws_transfer_tag" "example" { + resource_arn = aws_transfer_server.example.arn + key = "testkey" + value = "testvalue" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `resource_arn` - (Required) Amazon Resource Name (ARN) of the Transfer Family resource to tag. +* `key` - (Required) Tag name. +* `value` - (Required) Tag value. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - Transfer Family resource identifier and key, separated by a comma (`,`) + +## Import + +`aws_transfer_tag` can be imported by using the Transfer Family resource identifier and key, separated by a comma (`,`), e.g., + +``` +$ terraform import aws_transfer_tag.example arn:aws:transfer:us-east-1:123456789012:server/s-1234567890abcdef0,Name +``` From aedf770d95a89621abf4a92b8864f4ea539ad2a4 Mon Sep 17 00:00:00 2001 From: Tadayuki Onishi Date: Fri, 7 Oct 2022 03:33:57 +0900 Subject: [PATCH 04/20] Add a transfer tag resource test --- internal/service/transfer/tag_test.go | 145 ++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 internal/service/transfer/tag_test.go diff --git a/internal/service/transfer/tag_test.go b/internal/service/transfer/tag_test.go new file mode 100644 index 000000000000..1dcc33edc731 --- /dev/null +++ b/internal/service/transfer/tag_test.go @@ -0,0 +1,145 @@ +package transfer_test + +import ( + "fmt" + "github.com/aws/aws-sdk-go/service/transfer" + tftransfer "github.com/hashicorp/terraform-provider-aws/internal/service/transfer" + "testing" + + sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" +) + +func TestAccTransferTag_basic(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_transfer_tag.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, transfer.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckTagDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTagConfig_basic(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTagExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "key", "key1"), + resource.TestCheckResourceAttr(resourceName, "value", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccTransferTag_disappears(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_transfer_tag.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, transfer.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckTagDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTagConfig_basic(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTagExists(resourceName), + acctest.CheckResourceDisappears(acctest.Provider, tftransfer.ResourceTag(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccTransferTag_value(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_transfer_tag.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, transfer.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckTagDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTagConfig_basic(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTagExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "key", "key1"), + resource.TestCheckResourceAttr(resourceName, "value", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccTagConfig_basic(rName, "key1", "value1updated"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTagExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "key", "key1"), + resource.TestCheckResourceAttr(resourceName, "value", "value1updated"), + ), + }, + }, + }) +} + +func TestAccTransferTag_aws(t *testing.T) { + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_transfer_tag.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t) }, + ErrorCheck: acctest.ErrorCheck(t, transfer.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckTagDestroy, + Steps: []resource.TestStep{ + { + Config: testAccTagConfig_basic(rName, "aws:transfer:customHostname", "abc.example.com"), + Check: resource.ComposeTestCheckFunc( + testAccCheckTagExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "key", "aws:transfer:customHostname"), + resource.TestCheckResourceAttr(resourceName, "value", "abc.example.com"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccTagConfig_basic(rName string, key string, value string) string { + return fmt.Sprintf(` +resource "aws_transfer_server" "test" { + identity_provider_type = "SERVICE_MANAGED" + + tags = { + Name = %[1]q + } + + lifecycle { + ignore_changes = [tags] + } +} + +resource "aws_transfer_tag" "test" { + resource_arn = aws_transfer_server.test.arn + key = %[2]q + value = %[3]q +} +`, rName, key, value) +} From 21e8683772adef6c7423dae32432ea9d8384ce6f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 10:57:26 -0400 Subject: [PATCH 05/20] Add CHANGELOG entry. --- .changelog/27131.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/27131.txt diff --git a/.changelog/27131.txt b/.changelog/27131.txt new file mode 100644 index 000000000000..492de35bb2be --- /dev/null +++ b/.changelog/27131.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_transfer_tag +``` From 213facf37fcfdc2a4c0100bb30af7fa17a10ed73 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 10:58:25 -0400 Subject: [PATCH 06/20] Fix importlint 'Imports of different types are not allowed in the same group'. --- internal/service/transfer/tag_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/service/transfer/tag_test.go b/internal/service/transfer/tag_test.go index 1dcc33edc731..99d3418ea554 100644 --- a/internal/service/transfer/tag_test.go +++ b/internal/service/transfer/tag_test.go @@ -2,13 +2,13 @@ package transfer_test import ( "fmt" - "github.com/aws/aws-sdk-go/service/transfer" - tftransfer "github.com/hashicorp/terraform-provider-aws/internal/service/transfer" "testing" + "github.com/aws/aws-sdk-go/service/transfer" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-provider-aws/internal/acctest" + tftransfer "github.com/hashicorp/terraform-provider-aws/internal/service/transfer" ) func TestAccTransferTag_basic(t *testing.T) { From 183d4680c387a82d995091df544f03216758006e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 11:38:45 -0400 Subject: [PATCH 07/20] 'TestAccTransferTag_aws' -> 'TestAccTransferTag_system'. --- internal/service/transfer/tag_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/transfer/tag_test.go b/internal/service/transfer/tag_test.go index 99d3418ea554..5eec3a2f06de 100644 --- a/internal/service/transfer/tag_test.go +++ b/internal/service/transfer/tag_test.go @@ -95,7 +95,7 @@ func TestAccTransferTag_value(t *testing.T) { }) } -func TestAccTransferTag_aws(t *testing.T) { +func TestAccTransferTag_system(t *testing.T) { rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_transfer_tag.test" From 27e009b4cb86e7cfddfbf8f0a6978069c014fca4 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 11:39:22 -0400 Subject: [PATCH 08/20] Cosmetics. --- internal/provider/provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index e3293c3cea07..56a4a2c7773f 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -2121,9 +2121,9 @@ func New(_ context.Context) (*schema.Provider, error) { "aws_transfer_access": transfer.ResourceAccess(), "aws_transfer_server": transfer.ResourceServer(), "aws_transfer_ssh_key": transfer.ResourceSSHKey(), + "aws_transfer_tag": transfer.ResourceTag(), "aws_transfer_user": transfer.ResourceUser(), "aws_transfer_workflow": transfer.ResourceWorkflow(), - "aws_transfer_tag": transfer.ResourceTag(), "aws_waf_byte_match_set": waf.ResourceByteMatchSet(), "aws_waf_geo_match_set": waf.ResourceGeoMatchSet(), From 85d11a26efd0a0d7003e79bbc1c739695536a661 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 11:46:05 -0400 Subject: [PATCH 09/20] Correct tagging code generation. --- internal/service/transfer/generate.go | 3 ++- internal/service/transfer/tags_gen.go | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/internal/service/transfer/generate.go b/internal/service/transfer/generate.go index 4825342ee130..9958b5f160b0 100644 --- a/internal/service/transfer/generate.go +++ b/internal/service/transfer/generate.go @@ -1,4 +1,5 @@ -//go:generate go run ../../generate/tags/main.go -ListTags -ListTagsInIDElem=Arn -ServiceTagsSlice -TagInIDElem=Arn -UpdateTags +//go:generate go run ../../generate/tagresource/main.go -IDAttribName=resource_arn +//go:generate go run ../../generate/tags/main.go -GetTag -ListTags -ListTagsInIDElem=Arn -ServiceTagsSlice -TagInIDElem=Arn -UpdateTags // ONLY generate directives and package declaration! Do not add anything else to this file. package transfer diff --git a/internal/service/transfer/tags_gen.go b/internal/service/transfer/tags_gen.go index 94e87ab6c391..2101d6d69004 100644 --- a/internal/service/transfer/tags_gen.go +++ b/internal/service/transfer/tags_gen.go @@ -97,7 +97,7 @@ func UpdateTagsWithContext(ctx context.Context, conn transferiface.TransferAPI, if removedTags := oldTags.Removed(newTags); len(removedTags) > 0 { input := &transfer.UntagResourceInput{ Arn: aws.String(identifier), - TagKeys: aws.StringSlice(removedTags.Keys()), + TagKeys: aws.StringSlice(removedTags.IgnoreAWS().Keys()), } _, err := conn.UntagResourceWithContext(ctx, input) @@ -110,7 +110,7 @@ func UpdateTagsWithContext(ctx context.Context, conn transferiface.TransferAPI, if updatedTags := oldTags.Updated(newTags); len(updatedTags) > 0 { input := &transfer.TagResourceInput{ Arn: aws.String(identifier), - Tags: Tags(updatedTags), + Tags: Tags(updatedTags.IgnoreAWS()), } _, err := conn.TagResourceWithContext(ctx, input) From 7e1e067b57d2a0fdbb596b2e11ae8db32f6b77f7 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 13:43:08 -0400 Subject: [PATCH 10/20] Regenerate Transfer service tagging code. --- internal/service/transfer/tag_gen.go | 48 ++++++++++++----------- internal/service/transfer/tag_gen_test.go | 5 ++- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/internal/service/transfer/tag_gen.go b/internal/service/transfer/tag_gen.go index 00aedac5de97..105a2e1cb5ac 100644 --- a/internal/service/transfer/tag_gen.go +++ b/internal/service/transfer/tag_gen.go @@ -3,10 +3,11 @@ package transfer import ( - "fmt" + "context" "log" "github.com/aws/aws-sdk-go/service/transfer" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-aws/internal/conns" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" @@ -15,12 +16,13 @@ import ( func ResourceTag() *schema.Resource { return &schema.Resource{ - Create: resourceTagCreate, - Read: resourceTagRead, - Update: resourceTagUpdate, - Delete: resourceTagDelete, + CreateWithoutTimeout: resourceTagCreate, + ReadWithoutTimeout: resourceTagRead, + UpdateWithoutTimeout: resourceTagUpdate, + DeleteWithoutTimeout: resourceTagDelete, + Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + StateContext: schema.ImportStatePassthroughContext, }, Schema: map[string]*schema.Schema{ @@ -42,31 +44,31 @@ func ResourceTag() *schema.Resource { } } -func resourceTagCreate(d *schema.ResourceData, meta interface{}) error { +func resourceTagCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).TransferConn identifier := d.Get("resource_arn").(string) key := d.Get("key").(string) value := d.Get("value").(string) - if err := UpdateTags(conn, identifier, nil, map[string]string{key: value}); err != nil { - return fmt.Errorf("error creating %s resource (%s) tag (%s): %w", transfer.ServiceID, identifier, key, err) + if err := UpdateTagsWithContext(ctx, conn, identifier, nil, map[string]string{key: value}); err != nil { + return diag.Errorf("creating %s resource (%s) tag (%s): %s", transfer.ServiceID, identifier, key, err) } d.SetId(tftags.SetResourceID(identifier, key)) - return resourceTagRead(d, meta) + return resourceTagRead(ctx, d, meta) } -func resourceTagRead(d *schema.ResourceData, meta interface{}) error { +func resourceTagRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).TransferConn identifier, key, err := tftags.GetResourceID(d.Id()) if err != nil { - return err + return diag.FromErr(err) } - value, err := GetTag(conn, identifier, key) + value, err := GetTagWithContext(ctx, conn, identifier, key) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] %s resource (%s) tag (%s) not found, removing from state", transfer.ServiceID, identifier, key) @@ -75,7 +77,7 @@ func resourceTagRead(d *schema.ResourceData, meta interface{}) error { } if err != nil { - return fmt.Errorf("error reading %s resource (%s) tag (%s): %w", transfer.ServiceID, identifier, key, err) + return diag.Errorf("reading %s resource (%s) tag (%s): %s", transfer.ServiceID, identifier, key, err) } d.Set("resource_arn", identifier) @@ -85,31 +87,31 @@ func resourceTagRead(d *schema.ResourceData, meta interface{}) error { return nil } -func resourceTagUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceTagUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).TransferConn identifier, key, err := tftags.GetResourceID(d.Id()) if err != nil { - return err + return diag.FromErr(err) } - if err := UpdateTags(conn, identifier, nil, map[string]string{key: d.Get("value").(string)}); err != nil { - return fmt.Errorf("error updating %s resource (%s) tag (%s): %w", transfer.ServiceID, identifier, key, err) + if err := UpdateTagsWithContext(ctx, conn, identifier, nil, map[string]string{key: d.Get("value").(string)}); err != nil { + return diag.Errorf("updating %s resource (%s) tag (%s): %s", transfer.ServiceID, identifier, key, err) } - return resourceTagRead(d, meta) + return resourceTagRead(ctx, d, meta) } -func resourceTagDelete(d *schema.ResourceData, meta interface{}) error { +func resourceTagDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*conns.AWSClient).TransferConn identifier, key, err := tftags.GetResourceID(d.Id()) if err != nil { - return err + return diag.FromErr(err) } - if err := UpdateTags(conn, identifier, map[string]string{key: d.Get("value").(string)}, nil); err != nil { - return fmt.Errorf("error deleting %s resource (%s) tag (%s): %w", transfer.ServiceID, identifier, key, err) + if err := UpdateTagsWithContext(ctx, conn, identifier, map[string]string{key: d.Get("value").(string)}, nil); err != nil { + return diag.Errorf("deleting %s resource (%s) tag (%s): %s", transfer.ServiceID, identifier, key, err) } return nil diff --git a/internal/service/transfer/tag_gen_test.go b/internal/service/transfer/tag_gen_test.go index 9b7c8c7cf39b..b00d5367e7b6 100644 --- a/internal/service/transfer/tag_gen_test.go +++ b/internal/service/transfer/tag_gen_test.go @@ -3,6 +3,7 @@ package transfer_test import ( + "context" "fmt" "github.com/aws/aws-sdk-go/service/transfer" @@ -29,7 +30,7 @@ func testAccCheckTagDestroy(s *terraform.State) error { return err } - _, err = tftransfer.GetTag(conn, identifier, key) + _, err = tftransfer.GetTagWithContext(context.Background(), conn, identifier, key) if tfresource.NotFound(err) { continue @@ -64,7 +65,7 @@ func testAccCheckTagExists(resourceName string) resource.TestCheckFunc { conn := acctest.Provider.Meta().(*conns.AWSClient).TransferConn - _, err = tftransfer.GetTag(conn, identifier, key) + _, err = tftransfer.GetTagWithContext(context.Background(), conn, identifier, key) return err } From 40600352c3d1634b7ff05d1b9957859442890816 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 14:57:57 -0400 Subject: [PATCH 11/20] generate/tags: Make output file name configurable. --- internal/generate/tags/main.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/internal/generate/tags/main.go b/internal/generate/tags/main.go index 42b11d5a5cf2..82414f2a79e1 100644 --- a/internal/generate/tags/main.go +++ b/internal/generate/tags/main.go @@ -20,8 +20,6 @@ import ( ) const ( - filename = `tags_gen.go` - sdkV1 = 1 sdkV2 = 2 ) @@ -168,6 +166,11 @@ func main() { flag.Usage = usage flag.Parse() + filename := `tags_gen.go` + if args := flag.Args(); len(args) > 0 { + filename = args[0] + } + if *sdkVersion != sdkV1 && *sdkVersion != sdkV2 { log.Fatalf("AWS SDK Go Version %d not supported", *sdkVersion) } @@ -258,31 +261,31 @@ func main() { templateData.AWSService = "" templateData.TagPackage = "" } - writeTemplate(templateBody.header, "header", templateData) + writeTemplate(filename, templateBody.header, "header", templateData) } if *getTag { - writeTemplate(templateBody.getTag, "gettag", templateData) + writeTemplate(filename, templateBody.getTag, "gettag", templateData) } if *listTags { - writeTemplate(templateBody.listTags, "listtags", templateData) + writeTemplate(filename, templateBody.listTags, "listtags", templateData) } if *serviceTagsMap { - writeTemplate(templateBody.serviceTagsMap, "servicetagsmap", templateData) + writeTemplate(filename, templateBody.serviceTagsMap, "servicetagsmap", templateData) } if *serviceTagsSlice { - writeTemplate(templateBody.serviceTagsSlice, "servicetagsslice", templateData) + writeTemplate(filename, templateBody.serviceTagsSlice, "servicetagsslice", templateData) } if *updateTags { - writeTemplate(templateBody.updateTags, "updatetags", templateData) + writeTemplate(filename, templateBody.updateTags, "updatetags", templateData) } } -func writeTemplate(body string, templateName string, td TemplateData) { +func writeTemplate(filename, body, templateName string, td TemplateData) { // If the file doesn't exist, create it, or append to the file f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { From 5a416d088b5b308b87f804eee0696fc8ab1f155b Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 15:15:01 -0400 Subject: [PATCH 12/20] generate/tags: Make UpdateTags function name configurable. --- internal/generate/tags/main.go | 9 ++++++--- .../generate/tags/templates/v1/update_tags_body.tmpl | 10 +++++----- .../generate/tags/templates/v2/update_tags_body.tmpl | 6 +++--- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/internal/generate/tags/main.go b/internal/generate/tags/main.go index 82414f2a79e1..5520572c75b7 100644 --- a/internal/generate/tags/main.go +++ b/internal/generate/tags/main.go @@ -47,7 +47,7 @@ var ( tagResTypeElem = flag.String("TagResTypeElem", "", "tagResTypeElem") tagType = flag.String("TagType", "Tag", "tagType") tagType2 = flag.String("TagType2", "", "tagType") - TagTypeAddBoolElem = flag.String("TagTypeAddBoolElem", "", "TagTypeAddBoolElem") + tagTypeAddBoolElem = flag.String("TagTypeAddBoolElem", "", "TagTypeAddBoolElem") tagTypeIDElem = flag.String("TagTypeIDElem", "", "tagTypeIDElem") tagTypeKeyElem = flag.String("TagTypeKeyElem", "Key", "tagTypeKeyElem") tagTypeValElem = flag.String("TagTypeValElem", "Value", "tagTypeValElem") @@ -55,6 +55,7 @@ var ( untagInNeedTagKeyType = flag.String("UntagInNeedTagKeyType", "", "untagInNeedTagKeyType") untagInTagsElem = flag.String("UntagInTagsElem", "TagKeys", "untagInTagsElem") untagOp = flag.String("UntagOp", "UntagResource", "untagOp") + updateTagsFunc = flag.String("UpdateTagsFunc", "UpdateTags", "updateTagsFunc") parentNotFoundErrCode = flag.String("ParentNotFoundErrCode", "", "Parent 'NotFound' Error Code") parentNotFoundErrMsg = flag.String("ParentNotFoundErrMsg", "", "Parent 'NotFound' Error Message") @@ -150,6 +151,7 @@ type TemplateData struct { UntagInNeedTagType bool UntagInTagsElem string UntagOp string + UpdateTagsFunc string // The following are specific to writing import paths in the `headerBody`; // to include the package, set the corresponding field's value to true @@ -240,8 +242,8 @@ func main() { TagResTypeElem: *tagResTypeElem, TagType: *tagType, TagType2: *tagType2, - TagTypeAddBoolElem: *TagTypeAddBoolElem, - TagTypeAddBoolElemSnake: ToSnakeCase(*TagTypeAddBoolElem), + TagTypeAddBoolElem: *tagTypeAddBoolElem, + TagTypeAddBoolElemSnake: ToSnakeCase(*tagTypeAddBoolElem), TagTypeIDElem: *tagTypeIDElem, TagTypeKeyElem: *tagTypeKeyElem, TagTypeValElem: *tagTypeValElem, @@ -250,6 +252,7 @@ func main() { UntagInNeedTagType: *untagInNeedTagType, UntagInTagsElem: *untagInTagsElem, UntagOp: *untagOp, + UpdateTagsFunc: *updateTagsFunc, } templateBody := NewTemplateBody(*sdkVersion, *kvtValues) diff --git a/internal/generate/tags/templates/v1/update_tags_body.tmpl b/internal/generate/tags/templates/v1/update_tags_body.tmpl index b7ca37a5adf3..56c4a579a6e7 100644 --- a/internal/generate/tags/templates/v1/update_tags_body.tmpl +++ b/internal/generate/tags/templates/v1/update_tags_body.tmpl @@ -1,16 +1,16 @@ -// UpdateTags updates {{ .ServicePackage }} service tags. +// {{ .UpdateTagsFunc }} updates {{ .ServicePackage }} service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. -func UpdateTags(conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, oldTags interface{}, newTags interface{}) error { - return UpdateTagsWithContext(context.Background(), conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}, oldTags, newTags) +func {{ .UpdateTagsFunc }}(conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, oldTags interface{}, newTags interface{}) error { + return {{ .UpdateTagsFunc }}WithContext(context.Background(), conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}, oldTags, newTags) } {{- if .TagTypeAddBoolElem }} -func UpdateTagsWithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, oldTagsSet interface{}, newTagsSet interface{}) error { +func {{ .UpdateTagsFunc }}WithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, oldTagsSet interface{}, newTagsSet interface{}) error { oldTags := KeyValueTags(oldTagsSet, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}) newTags := KeyValueTags(newTagsSet, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}) {{- else }} -func UpdateTagsWithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, oldTagsMap interface{}, newTagsMap interface{}) error { +func {{ .UpdateTagsFunc }}WithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, oldTagsMap interface{}, newTagsMap interface{}) error { oldTags := tftags.New(oldTagsMap) newTags := tftags.New(newTagsMap) {{- end }} diff --git a/internal/generate/tags/templates/v2/update_tags_body.tmpl b/internal/generate/tags/templates/v2/update_tags_body.tmpl index ae511d517178..5b1be0fd5525 100644 --- a/internal/generate/tags/templates/v2/update_tags_body.tmpl +++ b/internal/generate/tags/templates/v2/update_tags_body.tmpl @@ -1,12 +1,12 @@ -// UpdateTags updates {{ .ServicePackage }} service tags. +// {{ .UpdateTagsFunc }} updates {{ .ServicePackage }} service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. {{- if .TagTypeAddBoolElem }} -func UpdateTags(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, oldTagsSet interface{}, newTagsSet interface{}) error { +func {{ .UpdateTagsFunc }}(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, oldTagsSet interface{}, newTagsSet interface{}) error { oldTags := KeyValueTags(oldTagsSet, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}) newTags := KeyValueTags(newTagsSet, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}) {{- else }} -func UpdateTags(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, oldTagsMap interface{}, newTagsMap interface{}) error { +func {{ .UpdateTagsFunc }}(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, oldTagsMap interface{}, newTagsMap interface{}) error { oldTags := tftags.New(oldTagsMap) newTags := tftags.New(newTagsMap) {{- end }} From 420c348b2424c90d90fab3ac002de363a8a5fe6c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 15:21:01 -0400 Subject: [PATCH 13/20] generate/tags: Make ListTags function name configurable. --- internal/generate/tags/main.go | 3 +++ internal/generate/tags/templates/v1/get_tag_body.tmpl | 4 ++-- internal/generate/tags/templates/v1/list_tags_body.tmpl | 8 ++++---- internal/generate/tags/templates/v2/get_tag_body.tmpl | 4 ++-- internal/generate/tags/templates/v2/list_tags_body.tmpl | 4 ++-- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/internal/generate/tags/main.go b/internal/generate/tags/main.go index 5520572c75b7..8ca7f096bb5a 100644 --- a/internal/generate/tags/main.go +++ b/internal/generate/tags/main.go @@ -32,6 +32,7 @@ var ( untagInNeedTagType = flag.Bool("UntagInNeedTagType", false, "whether Untag input needs tag type") updateTags = flag.Bool("UpdateTags", false, "whether to generate UpdateTags") + listTagsFunc = flag.String("ListTagsFunc", "ListTags", "listTagsFunc") listTagsInFiltIDName = flag.String("ListTagsInFiltIDName", "", "listTagsInFiltIDName") listTagsInIDElem = flag.String("ListTagsInIDElem", "ResourceArn", "listTagsInIDElem") listTagsInIDNeedSlice = flag.String("ListTagsInIDNeedSlice", "", "listTagsInIDNeedSlice") @@ -122,6 +123,7 @@ type TemplateData struct { ClientType string ServicePackage string + ListTagsFunc string ListTagsInFiltIDName string ListTagsInIDElem string ListTagsInIDNeedSlice string @@ -224,6 +226,7 @@ func main() { StrConvPkg: awsPkg == "autoscaling", TfResourcePkg: *getTag, + ListTagsFunc: *listTagsFunc, ListTagsInFiltIDName: *listTagsInFiltIDName, ListTagsInIDElem: *listTagsInIDElem, ListTagsInIDNeedSlice: *listTagsInIDNeedSlice, diff --git a/internal/generate/tags/templates/v1/get_tag_body.tmpl b/internal/generate/tags/templates/v1/get_tag_body.tmpl index 51cf212554c0..0c57035a2f3a 100644 --- a/internal/generate/tags/templates/v1/get_tag_body.tmpl +++ b/internal/generate/tags/templates/v1/get_tag_body.tmpl @@ -1,6 +1,6 @@ // GetTag fetches an individual {{ .ServicePackage }} service tag for a resource. // Returns whether the key value and any errors. A NotFoundError is used to signal that no value was found. -// This function will optimise the handling over ListTags, if possible. +// This function will optimise the handling over {{ .ListTagsFunc }}, if possible. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. {{- if or ( .TagTypeIDElem ) ( .TagTypeAddBoolElem ) }} @@ -38,7 +38,7 @@ func GetTagWithContext(ctx context.Context, conn {{ .ClientType }}, identifier s listTags := KeyValueTags(output.{{ .ListTagsOutTagsElem }}{{ if .TagTypeIDElem }}, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}{{ end }}) {{- else }} - listTags, err := ListTagsWithContext(ctx, conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}) + listTags, err := {{ .ListTagsFunc }}WithContext(ctx, conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}) if err != nil { return nil, err diff --git a/internal/generate/tags/templates/v1/list_tags_body.tmpl b/internal/generate/tags/templates/v1/list_tags_body.tmpl index 41f9f75294ba..9dc045621fe0 100644 --- a/internal/generate/tags/templates/v1/list_tags_body.tmpl +++ b/internal/generate/tags/templates/v1/list_tags_body.tmpl @@ -1,11 +1,11 @@ -// ListTags lists {{ .ServicePackage }} service tags. +// {{ .ListTagsFunc }} lists {{ .ServicePackage }} service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. -func ListTags(conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}) (tftags.KeyValueTags, error) { - return ListTagsWithContext(context.Background(), conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}) +func {{ .ListTagsFunc }}(conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}) (tftags.KeyValueTags, error) { + return {{ .ListTagsFunc }}WithContext(context.Background(), conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}) } -func ListTagsWithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}) (tftags.KeyValueTags, error) { +func {{ .ListTagsFunc }}WithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}) (tftags.KeyValueTags, error) { input := &{{ .TagPackage }}.{{ .ListTagsOp }}Input{ {{- if .ListTagsInFiltIDName }} Filters: []*{{ .TagPackage }}.Filter{ diff --git a/internal/generate/tags/templates/v2/get_tag_body.tmpl b/internal/generate/tags/templates/v2/get_tag_body.tmpl index 84a911f8acfe..826c2711650a 100644 --- a/internal/generate/tags/templates/v2/get_tag_body.tmpl +++ b/internal/generate/tags/templates/v2/get_tag_body.tmpl @@ -1,6 +1,6 @@ // GetTag fetches an individual {{ .ServicePackage }} service tag for a resource. // Returns whether the key value and any errors. A NotFoundError is used to signal that no value was found. -// This function will optimise the handling over ListTags, if possible. +// This function will optimise the handling over {{ .ListTagsFunc }}, if possible. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. {{- if or ( .TagTypeIDElem ) ( .TagTypeAddBoolElem ) }} @@ -30,7 +30,7 @@ func GetTag(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if listTags := KeyValueTags(output.{{ .ListTagsOutTagsElem }}{{ if .TagTypeIDElem }}, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}{{ end }}) {{- else }} - listTags, err := ListTags(ctx, conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}) + listTags, err := {{ .ListTagsFunc }}(ctx, conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}) if err != nil { return nil, err diff --git a/internal/generate/tags/templates/v2/list_tags_body.tmpl b/internal/generate/tags/templates/v2/list_tags_body.tmpl index 220da99361bb..2b652053fc05 100644 --- a/internal/generate/tags/templates/v2/list_tags_body.tmpl +++ b/internal/generate/tags/templates/v2/list_tags_body.tmpl @@ -1,7 +1,7 @@ -// ListTags lists {{ .ServicePackage }} service tags. +// {{ .ListTagsFunc }} lists {{ .ServicePackage }} service tags. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. -func ListTags(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}) (tftags.KeyValueTags, error) { +func {{ .ListTagsFunc }}(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}) (tftags.KeyValueTags, error) { input := &{{ .TagPackage }}.{{ .ListTagsOp }}Input{ {{- if .ListTagsInFiltIDName }} Filters: []*{{ .AWSService }}.Filter{ From 547a1b50b39f1be2dd2a7f6c16eb0ab1b0ebd053 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 15:25:42 -0400 Subject: [PATCH 14/20] generate/tags: Make GetTag function name configurable. --- internal/generate/tags/main.go | 3 +++ .../generate/tags/templates/v1/get_tag_body.tmpl | 12 ++++++------ .../generate/tags/templates/v2/get_tag_body.tmpl | 6 +++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/internal/generate/tags/main.go b/internal/generate/tags/main.go index 8ca7f096bb5a..d881761941dd 100644 --- a/internal/generate/tags/main.go +++ b/internal/generate/tags/main.go @@ -32,6 +32,7 @@ var ( untagInNeedTagType = flag.Bool("UntagInNeedTagType", false, "whether Untag input needs tag type") updateTags = flag.Bool("UpdateTags", false, "whether to generate UpdateTags") + getTagFunc = flag.String("GetTagFunc", "GetTag", "getTagFunc") listTagsFunc = flag.String("ListTagsFunc", "ListTags", "listTagsFunc") listTagsInFiltIDName = flag.String("ListTagsInFiltIDName", "", "listTagsInFiltIDName") listTagsInIDElem = flag.String("ListTagsInIDElem", "ResourceArn", "listTagsInIDElem") @@ -123,6 +124,7 @@ type TemplateData struct { ClientType string ServicePackage string + GetTagFunc string ListTagsFunc string ListTagsInFiltIDName string ListTagsInIDElem string @@ -226,6 +228,7 @@ func main() { StrConvPkg: awsPkg == "autoscaling", TfResourcePkg: *getTag, + GetTagFunc: *getTagFunc, ListTagsFunc: *listTagsFunc, ListTagsInFiltIDName: *listTagsInFiltIDName, ListTagsInIDElem: *listTagsInIDElem, diff --git a/internal/generate/tags/templates/v1/get_tag_body.tmpl b/internal/generate/tags/templates/v1/get_tag_body.tmpl index 0c57035a2f3a..7930812ff70c 100644 --- a/internal/generate/tags/templates/v1/get_tag_body.tmpl +++ b/internal/generate/tags/templates/v1/get_tag_body.tmpl @@ -1,20 +1,20 @@ -// GetTag fetches an individual {{ .ServicePackage }} service tag for a resource. +// {{ .GetTagFunc }} fetches an individual {{ .ServicePackage }} service tag for a resource. // Returns whether the key value and any errors. A NotFoundError is used to signal that no value was found. // This function will optimise the handling over {{ .ListTagsFunc }}, if possible. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. {{- if or ( .TagTypeIDElem ) ( .TagTypeAddBoolElem ) }} -func GetTag(conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*tftags.TagData, error) { +func {{ .GetTagFunc }}(conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*tftags.TagData, error) { {{- else }} -func GetTag(conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*string, error) { +func {{ .GetTagFunc }}(conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*string, error) { {{- end }} - return GetTagWithContext(context.Background(), conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}, key) + return {{ .GetTagFunc }}WithContext(context.Background(), conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}, key) } {{- if or ( .TagTypeIDElem ) ( .TagTypeAddBoolElem ) }} -func GetTagWithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*tftags.TagData, error) { +func {{ .GetTagFunc }}WithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*tftags.TagData, error) { {{- else }} -func GetTagWithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*string, error) { +func {{ .GetTagFunc }}WithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*string, error) { {{- end }} {{- if .ListTagsInFiltIDName }} input := &{{ .TagPackage }}.{{ .ListTagsOp }}Input{ diff --git a/internal/generate/tags/templates/v2/get_tag_body.tmpl b/internal/generate/tags/templates/v2/get_tag_body.tmpl index 826c2711650a..3cf9b3f6ffc2 100644 --- a/internal/generate/tags/templates/v2/get_tag_body.tmpl +++ b/internal/generate/tags/templates/v2/get_tag_body.tmpl @@ -1,12 +1,12 @@ -// GetTag fetches an individual {{ .ServicePackage }} service tag for a resource. +// {{ .GetTagFunc }} fetches an individual {{ .ServicePackage }} service tag for a resource. // Returns whether the key value and any errors. A NotFoundError is used to signal that no value was found. // This function will optimise the handling over {{ .ListTagsFunc }}, if possible. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. {{- if or ( .TagTypeIDElem ) ( .TagTypeAddBoolElem ) }} -func GetTag(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*tftags.TagData, error) { +func {{ .GetTagFunc }}(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*tftags.TagData, error) { {{- else }} -func GetTag(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*string, error) { +func {{ .GetTagFunc }}(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, key string) (*string, error) { {{- end }} {{- if .ListTagsInFiltIDName }} input := &{{ .AWSService }}.{{ .ListTagsOp }}Input{ From 4818b4f783d0eda2f50b47248de6de4fd70b4aa3 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 15:36:47 -0400 Subject: [PATCH 15/20] Transfer: Generate 'UpdateTagsNoIgnoreSystem'. --- internal/service/transfer/generate.go | 1 + .../update_tags_no_system_ignore_gen.go | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 internal/service/transfer/update_tags_no_system_ignore_gen.go diff --git a/internal/service/transfer/generate.go b/internal/service/transfer/generate.go index 9958b5f160b0..9f75b9a8cd4d 100644 --- a/internal/service/transfer/generate.go +++ b/internal/service/transfer/generate.go @@ -1,5 +1,6 @@ //go:generate go run ../../generate/tagresource/main.go -IDAttribName=resource_arn //go:generate go run ../../generate/tags/main.go -GetTag -ListTags -ListTagsInIDElem=Arn -ServiceTagsSlice -TagInIDElem=Arn -UpdateTags +//go:generate go run ../../generate/tags/main.go "-TagInCustomVal=Tags(updatedTags)" -TagInIDElem=Arn "-UntagInCustomVal=aws.StringSlice(removedTags.Keys())" -UpdateTags -UpdateTagsFunc=UpdateTagsNoIgnoreSystem -- update_tags_no_system_ignore_gen.go // ONLY generate directives and package declaration! Do not add anything else to this file. package transfer diff --git a/internal/service/transfer/update_tags_no_system_ignore_gen.go b/internal/service/transfer/update_tags_no_system_ignore_gen.go new file mode 100644 index 000000000000..99036c81250f --- /dev/null +++ b/internal/service/transfer/update_tags_no_system_ignore_gen.go @@ -0,0 +1,51 @@ +// Code generated by internal/generate/tags/main.go; DO NOT EDIT. +package transfer + +import ( + "context" + "fmt" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/transfer" + "github.com/aws/aws-sdk-go/service/transfer/transferiface" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" +) + +// UpdateTagsNoIgnoreSystem updates transfer service tags. +// The identifier is typically the Amazon Resource Name (ARN), although +// it may also be a different identifier depending on the service. +func UpdateTagsNoIgnoreSystem(conn transferiface.TransferAPI, identifier string, oldTags interface{}, newTags interface{}) error { + return UpdateTagsNoIgnoreSystemWithContext(context.Background(), conn, identifier, oldTags, newTags) +} +func UpdateTagsNoIgnoreSystemWithContext(ctx context.Context, conn transferiface.TransferAPI, identifier string, oldTagsMap interface{}, newTagsMap interface{}) error { + oldTags := tftags.New(oldTagsMap) + newTags := tftags.New(newTagsMap) + + if removedTags := oldTags.Removed(newTags); len(removedTags) > 0 { + input := &transfer.UntagResourceInput{ + Arn: aws.String(identifier), + TagKeys: aws.StringSlice(removedTags.Keys()), + } + + _, err := conn.UntagResourceWithContext(ctx, input) + + if err != nil { + return fmt.Errorf("untagging resource (%s): %w", identifier, err) + } + } + + if updatedTags := oldTags.Updated(newTags); len(updatedTags) > 0 { + input := &transfer.TagResourceInput{ + Arn: aws.String(identifier), + Tags: Tags(updatedTags), + } + + _, err := conn.TagResourceWithContext(ctx, input) + + if err != nil { + return fmt.Errorf("tagging resource (%s): %w", identifier, err) + } + } + + return nil +} From e95fff876c99d11df789f85481f1b9dab1fae0a0 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 15:50:51 -0400 Subject: [PATCH 16/20] generate/tagresource: Make CreateTags, GetTag and UpdateTags function names configurable. --- internal/generate/tagresource/main.go | 16 +++++++++++++--- internal/generate/tagresource/resource.tmpl | 10 +++++----- internal/generate/tagresource/tests.tmpl | 4 ++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/internal/generate/tagresource/main.go b/internal/generate/tagresource/main.go index b9084ed18309..4a339821da93 100644 --- a/internal/generate/tagresource/main.go +++ b/internal/generate/tagresource/main.go @@ -17,7 +17,10 @@ import ( ) var ( - idAttribName = flag.String("IDAttribName", "resource_arn", "idAttribName") + createTagsFunc = flag.String("CreateTagsFunc", "CreateTags", "createTagsFunc") + getTagFunc = flag.String("GetTagFunc", "GetTag", "getTagFunc") + idAttribName = flag.String("IDAttribName", "resource_arn", "idAttribName") + updateTagsFunc = flag.String("UpdateTagsFunc", "UpdateTags", "updateTagsFunc") ) func usage() { @@ -32,7 +35,10 @@ type TemplateData struct { AWSServiceUpper string ServicePackage string - IDAttribName string + CreateTagsFunc string + GetTagFunc string + IDAttribName string + UpdateTagsFunc string } func main() { @@ -57,7 +63,11 @@ func main() { AWSService: awsService, AWSServiceUpper: u, ServicePackage: servicePackage, - IDAttribName: *idAttribName, + + CreateTagsFunc: *createTagsFunc, + GetTagFunc: *getTagFunc, + IDAttribName: *idAttribName, + UpdateTagsFunc: *updateTagsFunc, } resourceFilename := "tag_gen.go" diff --git a/internal/generate/tagresource/resource.tmpl b/internal/generate/tagresource/resource.tmpl index 838bb37643ff..a174c71a190c 100644 --- a/internal/generate/tagresource/resource.tmpl +++ b/internal/generate/tagresource/resource.tmpl @@ -52,9 +52,9 @@ func resourceTagCreate(ctx context.Context, d *schema.ResourceData, meta interfa value := d.Get("value").(string) {{ if eq .ServicePackage "ec2" }} - if err := CreateTagsWithContext(ctx, conn, identifier, map[string]string{key: value}); err != nil { + if err := {{ .CreateTagsFunc }}WithContext(ctx, conn, identifier, map[string]string{key: value}); err != nil { {{- else }} - if err := UpdateTagsWithContext(ctx, conn, identifier, nil, map[string]string{key: value}); err != nil { + if err := {{ .UpdateTagsFunc }}WithContext(ctx, conn, identifier, nil, map[string]string{key: value}); err != nil { {{- end }} return diag.Errorf("creating %s resource (%s) tag (%s): %s", {{ .ServicePackage }}.ServiceID, identifier, key, err) } @@ -72,7 +72,7 @@ func resourceTagRead(ctx context.Context, d *schema.ResourceData, meta interface return diag.FromErr(err) } - value, err := GetTagWithContext(ctx, conn, identifier, key) + value, err := {{ .GetTagFunc }}WithContext(ctx, conn, identifier, key) if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] %s resource (%s) tag (%s) not found, removing from state", {{ .ServicePackage }}.ServiceID, identifier, key) @@ -99,7 +99,7 @@ func resourceTagUpdate(ctx context.Context, d *schema.ResourceData, meta interfa return diag.FromErr(err) } - if err := UpdateTagsWithContext(ctx, conn, identifier, nil, map[string]string{key: d.Get("value").(string)}); err != nil { + if err := {{ .UpdateTagsFunc }}WithContext(ctx, conn, identifier, nil, map[string]string{key: d.Get("value").(string)}); err != nil { return diag.Errorf("updating %s resource (%s) tag (%s): %s", {{ .ServicePackage }}.ServiceID, identifier, key, err) } @@ -114,7 +114,7 @@ func resourceTagDelete(ctx context.Context, d *schema.ResourceData, meta interfa return diag.FromErr(err) } - if err := UpdateTagsWithContext(ctx, conn, identifier, map[string]string{key: d.Get("value").(string)}, nil); err != nil { + if err := {{ .UpdateTagsFunc }}WithContext(ctx, conn, identifier, map[string]string{key: d.Get("value").(string)}, nil); err != nil { return diag.Errorf("deleting %s resource (%s) tag (%s): %s", {{ .ServicePackage }}.ServiceID, identifier, key, err) } diff --git a/internal/generate/tagresource/tests.tmpl b/internal/generate/tagresource/tests.tmpl index 739ed060b9f7..2c914e61ab5f 100644 --- a/internal/generate/tagresource/tests.tmpl +++ b/internal/generate/tagresource/tests.tmpl @@ -30,7 +30,7 @@ func testAccCheckTagDestroy(s *terraform.State) error { return err } - _, err = tf{{ .ServicePackage }}.GetTagWithContext(context.Background(), conn, identifier, key) + _, err = tf{{ .ServicePackage }}.{{ .GetTagFunc }}WithContext(context.Background(), conn, identifier, key) if tfresource.NotFound(err) { continue @@ -65,7 +65,7 @@ func testAccCheckTagExists(resourceName string) resource.TestCheckFunc { conn := acctest.Provider.Meta().(*conns.AWSClient).{{ .AWSServiceUpper }}Conn - _, err = tf{{ .ServicePackage }}.GetTagWithContext(context.Background(), conn, identifier, key) + _, err = tf{{ .ServicePackage }}.{{ .GetTagFunc }}WithContext(context.Background(), conn, identifier, key) return err } From adb04df3e7f8aa905984499d492060a4a6a1858c Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 15:53:14 -0400 Subject: [PATCH 17/20] r/aws_transfer_tag: Use 'UpdateTagsNoIgnoreSystem'. --- internal/service/transfer/generate.go | 2 +- internal/service/transfer/tag_gen.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/service/transfer/generate.go b/internal/service/transfer/generate.go index 9f75b9a8cd4d..d3a2e63b896c 100644 --- a/internal/service/transfer/generate.go +++ b/internal/service/transfer/generate.go @@ -1,4 +1,4 @@ -//go:generate go run ../../generate/tagresource/main.go -IDAttribName=resource_arn +//go:generate go run ../../generate/tagresource/main.go -IDAttribName=resource_arn -UpdateTagsFunc=UpdateTagsNoIgnoreSystem //go:generate go run ../../generate/tags/main.go -GetTag -ListTags -ListTagsInIDElem=Arn -ServiceTagsSlice -TagInIDElem=Arn -UpdateTags //go:generate go run ../../generate/tags/main.go "-TagInCustomVal=Tags(updatedTags)" -TagInIDElem=Arn "-UntagInCustomVal=aws.StringSlice(removedTags.Keys())" -UpdateTags -UpdateTagsFunc=UpdateTagsNoIgnoreSystem -- update_tags_no_system_ignore_gen.go // ONLY generate directives and package declaration! Do not add anything else to this file. diff --git a/internal/service/transfer/tag_gen.go b/internal/service/transfer/tag_gen.go index 105a2e1cb5ac..79a982e6b9b3 100644 --- a/internal/service/transfer/tag_gen.go +++ b/internal/service/transfer/tag_gen.go @@ -51,7 +51,7 @@ func resourceTagCreate(ctx context.Context, d *schema.ResourceData, meta interfa key := d.Get("key").(string) value := d.Get("value").(string) - if err := UpdateTagsWithContext(ctx, conn, identifier, nil, map[string]string{key: value}); err != nil { + if err := UpdateTagsNoIgnoreSystemWithContext(ctx, conn, identifier, nil, map[string]string{key: value}); err != nil { return diag.Errorf("creating %s resource (%s) tag (%s): %s", transfer.ServiceID, identifier, key, err) } @@ -95,7 +95,7 @@ func resourceTagUpdate(ctx context.Context, d *schema.ResourceData, meta interfa return diag.FromErr(err) } - if err := UpdateTagsWithContext(ctx, conn, identifier, nil, map[string]string{key: d.Get("value").(string)}); err != nil { + if err := UpdateTagsNoIgnoreSystemWithContext(ctx, conn, identifier, nil, map[string]string{key: d.Get("value").(string)}); err != nil { return diag.Errorf("updating %s resource (%s) tag (%s): %s", transfer.ServiceID, identifier, key, err) } @@ -110,7 +110,7 @@ func resourceTagDelete(ctx context.Context, d *schema.ResourceData, meta interfa return diag.FromErr(err) } - if err := UpdateTagsWithContext(ctx, conn, identifier, map[string]string{key: d.Get("value").(string)}, nil); err != nil { + if err := UpdateTagsNoIgnoreSystemWithContext(ctx, conn, identifier, map[string]string{key: d.Get("value").(string)}, nil); err != nil { return diag.Errorf("deleting %s resource (%s) tag (%s): %s", transfer.ServiceID, identifier, key, err) } From 1863fe7158a5d2699ac8763fb6c669b41146deaf Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 16:00:08 -0400 Subject: [PATCH 18/20] ec2/generate/createtags: Make CreateTags function name configurable. --- .../ec2/generate/createtags/functions.tmpl | 8 ++++---- .../service/ec2/generate/createtags/main.go | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/internal/service/ec2/generate/createtags/functions.tmpl b/internal/service/ec2/generate/createtags/functions.tmpl index 76a782c930dd..d35c1c023982 100644 --- a/internal/service/ec2/generate/createtags/functions.tmpl +++ b/internal/service/ec2/generate/createtags/functions.tmpl @@ -17,14 +17,14 @@ import ( const eventualConsistencyTimeout = 5 * time.Minute -// CreateTags creates {{ .ServicePackage }} service tags for new resources. +// {{ .CreateTagsFunc }} creates {{ .ServicePackage }} service tags for new resources. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. -func CreateTags(conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, tagsMap interface{}) error { - return CreateTagsWithContext(context.Background(), conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}, tagsMap) +func {{ .CreateTagsFunc }}(conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, tagsMap interface{}) error { + return {{ .CreateTagsFunc }}WithContext(context.Background(), conn, identifier{{ if .TagResTypeElem }}, resourceType{{ end }}, tagsMap) } -func CreateTagsWithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, tagsMap interface{}) error { +func {{ .CreateTagsFunc }}WithContext(ctx context.Context, conn {{ .ClientType }}, identifier string{{ if .TagResTypeElem }}, resourceType string{{ end }}, tagsMap interface{}) error { tags := tftags.New(tagsMap) {{- if .TagOpBatchSize }} diff --git a/internal/service/ec2/generate/createtags/main.go b/internal/service/ec2/generate/createtags/main.go index 7b1d7748cdf6..78859ad9a128 100644 --- a/internal/service/ec2/generate/createtags/main.go +++ b/internal/service/ec2/generate/createtags/main.go @@ -14,9 +14,8 @@ import ( "text/template" ) -const filename = `create_tags_gen.go` - var ( + createTagsFunc = flag.String("CreateTagsFunc", "CreateTags", "createTagsFunc") retryCreateOnNotFound = flag.Bool("RetryCreateOnNotFound", true, "retry create if resource not found") tagOp = flag.String("TagOp", "CreateTags", "tag function") tagOpBatchSize = flag.String("TagOpBatchSize", "", "tag function batch size") @@ -40,6 +39,7 @@ type TemplateData struct { ClientType string ServicePackage string + CreateTagsFunc string ParentNotFoundError string RetryCreateOnNotFound bool TagInCustomVal string @@ -57,10 +57,17 @@ func main() { flag.Usage = usage flag.Parse() + filename := `create_tags_gen.go` + if args := flag.Args(); len(args) > 0 { + filename = args[0] + } + templateData := TemplateData{ - AWSService: "ec2", - ServicePackage: "ec2", - ClientType: "*ec2.EC2", + AWSService: "ec2", + ServicePackage: "ec2", + ClientType: "*ec2.EC2", + + CreateTagsFunc: *createTagsFunc, RetryCreateOnNotFound: *retryCreateOnNotFound, TagInCustomVal: *tagInCustomVal, TagInIDElem: *tagInIDElem, From 16f419ad7f612ec87346d125627988150845cdbf Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 16:08:08 -0400 Subject: [PATCH 19/20] ec2/generate/createtags: Use 'ec2iface' package. --- internal/service/ec2/create_tags_gen.go | 5 +++-- .../service/ec2/generate/createtags/functions.tmpl | 3 +++ internal/service/ec2/generate/createtags/main.go | 14 ++++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/internal/service/ec2/create_tags_gen.go b/internal/service/ec2/create_tags_gen.go index c1b9981ed130..d1271c5983ee 100644 --- a/internal/service/ec2/create_tags_gen.go +++ b/internal/service/ec2/create_tags_gen.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" + "github.com/aws/aws-sdk-go/service/ec2/ec2iface" "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" @@ -20,11 +21,11 @@ const eventualConsistencyTimeout = 5 * time.Minute // CreateTags creates ec2 service tags for new resources. // The identifier is typically the Amazon Resource Name (ARN), although // it may also be a different identifier depending on the service. -func CreateTags(conn *ec2.EC2, identifier string, tagsMap interface{}) error { +func CreateTags(conn ec2iface.EC2API, identifier string, tagsMap interface{}) error { return CreateTagsWithContext(context.Background(), conn, identifier, tagsMap) } -func CreateTagsWithContext(ctx context.Context, conn *ec2.EC2, identifier string, tagsMap interface{}) error { +func CreateTagsWithContext(ctx context.Context, conn ec2iface.EC2API, identifier string, tagsMap interface{}) error { tags := tftags.New(tagsMap) input := &ec2.CreateTagsInput{ Resources: aws.StringSlice([]string{identifier}), diff --git a/internal/service/ec2/generate/createtags/functions.tmpl b/internal/service/ec2/generate/createtags/functions.tmpl index d35c1c023982..a01e22cbf276 100644 --- a/internal/service/ec2/generate/createtags/functions.tmpl +++ b/internal/service/ec2/generate/createtags/functions.tmpl @@ -9,6 +9,9 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/{{ .AWSService }}" + {{- if .AWSServiceIfacePackage }} + "github.com/aws/aws-sdk-go/service/{{ .AWSServiceIfacePackage }}" + {{- end }} "github.com/hashicorp/aws-sdk-go-base/v2/awsv1shim/v2/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-provider-aws/internal/tfresource" diff --git a/internal/service/ec2/generate/createtags/main.go b/internal/service/ec2/generate/createtags/main.go index 78859ad9a128..ac86b0896e9e 100644 --- a/internal/service/ec2/generate/createtags/main.go +++ b/internal/service/ec2/generate/createtags/main.go @@ -35,9 +35,10 @@ func usage() { } type TemplateData struct { - AWSService string - ClientType string - ServicePackage string + AWSService string + AWSServiceIfacePackage string + ClientType string + ServicePackage string CreateTagsFunc string ParentNotFoundError string @@ -63,9 +64,10 @@ func main() { } templateData := TemplateData{ - AWSService: "ec2", - ServicePackage: "ec2", - ClientType: "*ec2.EC2", + AWSService: "ec2", + AWSServiceIfacePackage: "ec2/ec2iface", + ClientType: "ec2iface.EC2API", + ServicePackage: "ec2", CreateTagsFunc: *createTagsFunc, RetryCreateOnNotFound: *retryCreateOnNotFound, From 8e620514d2203202b2e22c272d6792a9e90e127e Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 7 Oct 2022 16:28:39 -0400 Subject: [PATCH 20/20] r/aws_transfer_tag: Call out usage to manager custom hostname system tags. --- website/docs/r/transfer_server.html.markdown | 2 ++ website/docs/r/transfer_tag.html.markdown | 16 +++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/website/docs/r/transfer_server.html.markdown b/website/docs/r/transfer_server.html.markdown index c5f48849203e..db9baebfa3d3 100644 --- a/website/docs/r/transfer_server.html.markdown +++ b/website/docs/r/transfer_server.html.markdown @@ -12,6 +12,8 @@ Provides a AWS Transfer Server resource. ~> **NOTE on AWS IAM permissions:** If the `endpoint_type` is set to `VPC`, the `ec2:DescribeVpcEndpoints` and `ec2:ModifyVpcEndpoint` [actions](https://docs.aws.amazon.com/service-authorization/latest/reference/list_amazonec2.html#amazonec2-actions-as-permissions) are used. +~> **NOTE:** Use the [`aws_transfer_tag`](transfer_tag.html) resource to manage the system tags used for [custom hostnames](https://docs.aws.amazon.com/transfer/latest/userguide/requirements-dns.html#tag-custom-hostname-cdk). + ## Example Usage ### Basic diff --git a/website/docs/r/transfer_tag.html.markdown b/website/docs/r/transfer_tag.html.markdown index 9ad14aaba34f..b634aa871a8c 100644 --- a/website/docs/r/transfer_tag.html.markdown +++ b/website/docs/r/transfer_tag.html.markdown @@ -8,9 +8,9 @@ description: |- # Resource: aws_transfer_tag -Manages an individual Transfer Family resource tag. This resource should only be used in cases where Transfer Family resources are created outside Terraform (e.g., Servers without AWS Management Console). +Manages an individual Transfer Family resource tag. This resource should only be used in cases where Transfer Family resources are created outside Terraform (e.g., Servers without AWS Management Console) or the tag key has the `aws:` prefix. -~> **NOTE:** This tagging resource should not be combined with the Terraform resource for managing the parent resource. For example, using `aws_transfer_server` and `aws_transfer_tag` to manage tags of the same ASG will cause a perpetual difference where the `aws_transfer_server` resource will try to remove the tag being added by the `aws_transfer_tag` resource. +~> **NOTE:** This tagging resource should not be combined with the Terraform resource for managing the parent resource. For example, using `aws_transfer_server` and `aws_transfer_tag` to manage tags of the same server will cause a perpetual difference where the `aws_transfer_server` resource will try to remove the tag being added by the `aws_transfer_tag` resource. ~> **NOTE:** This tagging resource does not use the [provider `ignore_tags` configuration](/docs/providers/aws/index.html#ignore_tags). @@ -21,10 +21,16 @@ resource "aws_transfer_server" "example" { identity_provider_type = "SERVICE_MANAGED" } -resource "aws_transfer_tag" "example" { +resource "aws_transfer_tag" "zone_id" { resource_arn = aws_transfer_server.example.arn - key = "testkey" - value = "testvalue" + key = "aws:transfer:route53HostedZoneId" + value = "/hostedzone/MyHostedZoneId" +} + +resource "aws_transfer_tag" "hostname" { + resource_arn = aws_transfer_server.example.arn + key = "aws:transfer:customHostname" + value = "example.com" } ```