From f42bdeebc84755328dbcf579509f8b263f802930 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Mon, 4 Nov 2019 18:20:05 -0500 Subject: [PATCH] service/secretsmanager: Refactor tagging logic to keyvaluetags package Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/10688 Output from acceptance testing: ``` --- PASS: TestAccDataSourceAwsSecretsManagerSecret_Basic (5.99s) --- PASS: TestAccAwsSecretsManagerSecret_Basic (13.99s) --- PASS: TestAccAwsSecretsManagerSecret_withNamePrefix (14.02s) --- PASS: TestAccDataSourceAwsSecretsManagerSecret_ARN (15.28s) --- PASS: TestAccDataSourceAwsSecretsManagerSecret_Policy (16.05s) --- PASS: TestAccDataSourceAwsSecretsManagerSecret_Name (16.35s) --- PASS: TestAccAwsSecretsManagerSecret_policy (17.75s) --- PASS: TestAccAwsSecretsManagerSecret_Description (21.89s) --- PASS: TestAccAwsSecretsManagerSecret_Tags (38.69s) --- PASS: TestAccAwsSecretsManagerSecret_RecoveryWindowInDays_Recreate (39.41s) --- PASS: TestAccAwsSecretsManagerSecret_RotationRules (50.42s) --- PASS: TestAccAwsSecretsManagerSecret_RotationLambdaARN (50.55s) --- PASS: TestAccAwsSecretsManagerSecret_KmsKeyID (53.23s) ``` --- aws/data_source_aws_secretsmanager_secret.go | 3 +- aws/resource_aws_secretsmanager_secret.go | 38 ++-------- aws/tagsSecretsManager.go | 75 ------------------- aws/tagsSecretsManager_test.go | 79 -------------------- 4 files changed, 8 insertions(+), 187 deletions(-) delete mode 100644 aws/tagsSecretsManager.go delete mode 100644 aws/tagsSecretsManager_test.go diff --git a/aws/data_source_aws_secretsmanager_secret.go b/aws/data_source_aws_secretsmanager_secret.go index 2aa573be3a74..898191a9d8be 100644 --- a/aws/data_source_aws_secretsmanager_secret.go +++ b/aws/data_source_aws_secretsmanager_secret.go @@ -9,6 +9,7 @@ import ( "github.com/aws/aws-sdk-go/service/secretsmanager" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/structure" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) func dataSourceAwsSecretsManagerSecret() *schema.Resource { @@ -131,7 +132,7 @@ func dataSourceAwsSecretsManagerSecretRead(d *schema.ResourceData, meta interfac return fmt.Errorf("error setting rotation_rules: %s", err) } - if err := d.Set("tags", tagsToMapSecretsManager(output.Tags)); err != nil { + if err := d.Set("tags", keyvaluetags.SecretsmanagerKeyValueTags(output.Tags).IgnoreAws().Map()); err != nil { return fmt.Errorf("error setting tags: %s", err) } diff --git a/aws/resource_aws_secretsmanager_secret.go b/aws/resource_aws_secretsmanager_secret.go index d6ce9b179cd5..7395059f16e6 100644 --- a/aws/resource_aws_secretsmanager_secret.go +++ b/aws/resource_aws_secretsmanager_secret.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/structure" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) func resourceAwsSecretsManagerSecret() *schema.Resource { @@ -118,8 +119,7 @@ func resourceAwsSecretsManagerSecretCreate(d *schema.ResourceData, meta interfac } if v, ok := d.GetOk("tags"); ok { - input.Tags = tagsFromMapSecretsManager(v.(map[string]interface{})) - log.Printf("[DEBUG] Tagging Secrets Manager Secret: %s", input.Tags) + input.Tags = keyvaluetags.New(v.(map[string]interface{})).IgnoreAws().SecretsmanagerTags() } if v, ok := d.GetOk("kms_key_id"); ok && v.(string) != "" { @@ -248,7 +248,7 @@ func resourceAwsSecretsManagerSecretRead(d *schema.ResourceData, meta interface{ d.Set("rotation_rules", []interface{}{}) } - if err := d.Set("tags", tagsToMapSecretsManager(output.Tags)); err != nil { + if err := d.Set("tags", keyvaluetags.SecretsmanagerKeyValueTags(output.Tags).IgnoreAws().Map()); err != nil { return fmt.Errorf("error setting tags: %s", err) } @@ -344,35 +344,9 @@ func resourceAwsSecretsManagerSecretUpdate(d *schema.ResourceData, meta interfac } if d.HasChange("tags") { - oraw, nraw := d.GetChange("tags") - o := oraw.(map[string]interface{}) - n := nraw.(map[string]interface{}) - create, remove := diffTagsSecretsManager(tagsFromMapSecretsManager(o), tagsFromMapSecretsManager(n)) - - if len(remove) > 0 { - log.Printf("[DEBUG] Removing Secrets Manager Secret %q tags: %#v", d.Id(), remove) - k := make([]*string, len(remove)) - for i, t := range remove { - k[i] = t.Key - } - - _, err := conn.UntagResource(&secretsmanager.UntagResourceInput{ - SecretId: aws.String(d.Id()), - TagKeys: k, - }) - if err != nil { - return fmt.Errorf("error updating Secrets Manager Secrets %q tags: %s", d.Id(), err) - } - } - if len(create) > 0 { - log.Printf("[DEBUG] Creating Secrets Manager Secret %q tags: %#v", d.Id(), create) - _, err := conn.TagResource(&secretsmanager.TagResourceInput{ - SecretId: aws.String(d.Id()), - Tags: create, - }) - if err != nil { - return fmt.Errorf("error updating Secrets Manager Secrets %q tags: %s", d.Id(), err) - } + o, n := d.GetChange("tags") + if err := keyvaluetags.SecretsmanagerUpdateTags(conn, d.Id(), o, n); err != nil { + return fmt.Errorf("error updating tags: %s", err) } } diff --git a/aws/tagsSecretsManager.go b/aws/tagsSecretsManager.go deleted file mode 100644 index e7547ad7fe66..000000000000 --- a/aws/tagsSecretsManager.go +++ /dev/null @@ -1,75 +0,0 @@ -package aws - -import ( - "log" - "regexp" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/secretsmanager" -) - -// diffTags takes our tags locally and the ones remotely and returns -// the set of tags that must be created, and the set of tags that must -// be destroyed. -func diffTagsSecretsManager(oldTags, newTags []*secretsmanager.Tag) ([]*secretsmanager.Tag, []*secretsmanager.Tag) { - // First, we're creating everything we have - create := make(map[string]interface{}) - for _, t := range newTags { - create[*t.Key] = *t.Value - } - - // Build the list of what to remove - var remove []*secretsmanager.Tag - for _, t := range oldTags { - old, ok := create[*t.Key] - if !ok || old != *t.Value { - // Delete it! - remove = append(remove, t) - } - } - - return tagsFromMapSecretsManager(create), remove -} - -// tagsFromMap returns the tags for the given map of data. -func tagsFromMapSecretsManager(m map[string]interface{}) []*secretsmanager.Tag { - result := make([]*secretsmanager.Tag, 0, len(m)) - for k, v := range m { - t := &secretsmanager.Tag{ - Key: aws.String(k), - Value: aws.String(v.(string)), - } - if !tagIgnoredSecretsManager(t) { - result = append(result, t) - } - } - - return result -} - -// tagsToMap turns the list of tags into a map. -func tagsToMapSecretsManager(ts []*secretsmanager.Tag) map[string]string { - result := make(map[string]string) - for _, t := range ts { - if !tagIgnoredSecretsManager(t) { - result[*t.Key] = *t.Value - } - } - - return result -} - -// compare a tag against a list of strings and checks if it should -// be ignored or not -func tagIgnoredSecretsManager(t *secretsmanager.Tag) bool { - filter := []string{"^aws:"} - for _, v := range filter { - log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) - r, _ := regexp.MatchString(v, *t.Key) - if r { - log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) - return true - } - } - return false -} diff --git a/aws/tagsSecretsManager_test.go b/aws/tagsSecretsManager_test.go deleted file mode 100644 index d6eebe5343c9..000000000000 --- a/aws/tagsSecretsManager_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package aws - -import ( - "reflect" - "testing" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/secretsmanager" -) - -// go test -v -run="TestDiffSecretsManagerTags" -func TestDiffSecretsManagerTags(t *testing.T) { - cases := []struct { - Old, New map[string]interface{} - Create, Remove map[string]string - }{ - // Basic add/remove - { - Old: map[string]interface{}{ - "foo": "bar", - }, - New: map[string]interface{}{ - "bar": "baz", - }, - Create: map[string]string{ - "bar": "baz", - }, - Remove: map[string]string{ - "foo": "bar", - }, - }, - - // Modify - { - Old: map[string]interface{}{ - "foo": "bar", - }, - New: map[string]interface{}{ - "foo": "baz", - }, - Create: map[string]string{ - "foo": "baz", - }, - Remove: map[string]string{ - "foo": "bar", - }, - }, - } - - for i, tc := range cases { - c, r := diffTagsSecretsManager(tagsFromMapSecretsManager(tc.Old), tagsFromMapSecretsManager(tc.New)) - cm := tagsToMapSecretsManager(c) - rm := tagsToMapSecretsManager(r) - if !reflect.DeepEqual(cm, tc.Create) { - t.Fatalf("%d: bad create: %#v", i, cm) - } - if !reflect.DeepEqual(rm, tc.Remove) { - t.Fatalf("%d: bad remove: %#v", i, rm) - } - } -} - -// go test -v -run="TestIgnoringTagsSecretsManager" -func TestIgnoringTagsSecretsManager(t *testing.T) { - var ignoredTags []*secretsmanager.Tag - ignoredTags = append(ignoredTags, &secretsmanager.Tag{ - Key: aws.String("aws:cloudformation:logical-id"), - Value: aws.String("foo"), - }) - ignoredTags = append(ignoredTags, &secretsmanager.Tag{ - Key: aws.String("aws:foo:bar"), - Value: aws.String("baz"), - }) - for _, tag := range ignoredTags { - if !tagIgnoredSecretsManager(tag) { - t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) - } - } -}