From 5e32c144d5fcc2ff437e3b6dc9e919bbbb93e91f Mon Sep 17 00:00:00 2001 From: Andreas Skarmutsos Lindh Date: Tue, 21 Jun 2016 17:33:12 +0200 Subject: [PATCH] Ignore AWS specific tags Allows us to adopt resources created with CloudFormation. Extend AWS specific tag ignoring to all tags* Ignore AWS specific tags for autoscaling --- builtin/providers/aws/autoscaling_tags.go | 22 +++++++- .../providers/aws/autoscaling_tags_test.go | 18 +++++++ builtin/providers/aws/s3_tags.go | 26 ++++++++-- builtin/providers/aws/s3_tags_test.go | 18 +++++++ builtin/providers/aws/tags.go | 51 ++++++++++++++++--- builtin/providers/aws/tagsBeanstalk.go | 28 ++++++++-- builtin/providers/aws/tagsBeanstalk_test.go | 18 +++++++ builtin/providers/aws/tagsCloudtrail.go | 26 ++++++++-- builtin/providers/aws/tagsCloudtrail_test.go | 18 +++++++ builtin/providers/aws/tagsEC.go | 26 ++++++++-- builtin/providers/aws/tagsEC_test.go | 18 +++++++ builtin/providers/aws/tagsEFS.go | 26 ++++++++-- builtin/providers/aws/tagsEFS_test.go | 18 +++++++ builtin/providers/aws/tagsELB.go | 26 ++++++++-- builtin/providers/aws/tagsELB_test.go | 18 +++++++ builtin/providers/aws/tagsRDS.go | 26 ++++++++-- builtin/providers/aws/tagsRDS_test.go | 18 +++++++ builtin/providers/aws/tagsRedshift.go | 26 ++++++++-- builtin/providers/aws/tagsRedshift_test.go | 20 ++++++++ .../aws/tags_elasticsearchservice.go | 26 ++++++++-- .../aws/tags_elasticsearchservice_test.go | 18 +++++++ builtin/providers/aws/tags_kinesis.go | 26 ++++++++-- builtin/providers/aws/tags_kinesis_test.go | 18 +++++++ builtin/providers/aws/tags_route53.go | 26 ++++++++-- builtin/providers/aws/tags_route53_test.go | 18 +++++++ builtin/providers/aws/tags_test.go | 19 +++++++ 26 files changed, 556 insertions(+), 42 deletions(-) diff --git a/builtin/providers/aws/autoscaling_tags.go b/builtin/providers/aws/autoscaling_tags.go index e6eef8ec6..e9ca8531a 100644 --- a/builtin/providers/aws/autoscaling_tags.go +++ b/builtin/providers/aws/autoscaling_tags.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/autoscaling" @@ -119,13 +120,16 @@ func autoscalingTagsFromMap(m map[string]interface{}, resourceID string) []*auto result := make([]*autoscaling.Tag, 0, len(m)) for k, v := range m { attr := v.(map[string]interface{}) - result = append(result, &autoscaling.Tag{ + t := &autoscaling.Tag{ Key: aws.String(k), Value: aws.String(attr["value"].(string)), PropagateAtLaunch: aws.Bool(attr["propagate_at_launch"].(bool)), ResourceId: aws.String(resourceID), ResourceType: aws.String("auto-scaling-group"), - }) + } + if !tagIgnoredAutoscaling(t) { + result = append(result, t) + } } return result @@ -182,3 +186,17 @@ func setToMapByKey(s *schema.Set, key string) map[string]interface{} { return result } + +// compare a tag against a list of strings and checks if it should +// be ignored or not +func tagIgnoredAutoscaling(t *autoscaling.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/autoscaling_tags_test.go b/builtin/providers/aws/autoscaling_tags_test.go index b401fa2e4..04d8c15cb 100644 --- a/builtin/providers/aws/autoscaling_tags_test.go +++ b/builtin/providers/aws/autoscaling_tags_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -120,3 +121,20 @@ func testAccCheckAutoscalingTagNotExists(ts *[]*autoscaling.TagDescription, key return nil } } + +func TestIgnoringTagsAutoscaling(t *testing.T) { + var ignoredTags []*autoscaling.Tag + ignoredTags = append(ignoredTags, &autoscaling.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &autoscaling.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredAutoscaling(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} diff --git a/builtin/providers/aws/s3_tags.go b/builtin/providers/aws/s3_tags.go index 5d620b132..696821b79 100644 --- a/builtin/providers/aws/s3_tags.go +++ b/builtin/providers/aws/s3_tags.go @@ -2,6 +2,7 @@ package aws import ( "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -74,10 +75,13 @@ func diffTagsS3(oldTags, newTags []*s3.Tag) ([]*s3.Tag, []*s3.Tag) { func tagsFromMapS3(m map[string]interface{}) []*s3.Tag { result := make([]*s3.Tag, 0, len(m)) for k, v := range m { - result = append(result, &s3.Tag{ + t := &s3.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredS3(t) { + result = append(result, t) + } } return result @@ -87,7 +91,9 @@ func tagsFromMapS3(m map[string]interface{}) []*s3.Tag { func tagsToMapS3(ts []*s3.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredS3(t) { + result[*t.Key] = *t.Value + } } return result @@ -111,3 +117,17 @@ func getTagSetS3(s3conn *s3.S3, bucket string) ([]*s3.Tag, error) { return response.TagSet, nil } + +// compare a tag against a list of strings and checks if it should +// be ignored or not +func tagIgnoredS3(t *s3.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/s3_tags_test.go b/builtin/providers/aws/s3_tags_test.go index 3d4188c5f..48d38b715 100644 --- a/builtin/providers/aws/s3_tags_test.go +++ b/builtin/providers/aws/s3_tags_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/s3" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,23 @@ func TestDiffTagsS3(t *testing.T) { } } +func TestIgnoringTagsS3(t *testing.T) { + var ignoredTags []*s3.Tag + ignoredTags = append(ignoredTags, &s3.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &s3.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredS3(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckTags can be used to check the tags on a resource. func testAccCheckTagsS3( ts *[]*s3.Tag, key string, value string) resource.TestCheckFunc { diff --git a/builtin/providers/aws/tags.go b/builtin/providers/aws/tags.go index 7df71b5dc..758ea6238 100644 --- a/builtin/providers/aws/tags.go +++ b/builtin/providers/aws/tags.go @@ -2,6 +2,7 @@ package aws import ( "log" + "regexp" "strings" "time" @@ -137,7 +138,6 @@ func diffTags(oldTags, newTags []*ec2.Tag) ([]*ec2.Tag, []*ec2.Tag) { for _, t := range oldTags { old, ok := create[*t.Key] if !ok || old != *t.Value { - // Delete it! remove = append(remove, t) } } @@ -149,10 +149,13 @@ func diffTags(oldTags, newTags []*ec2.Tag) ([]*ec2.Tag, []*ec2.Tag) { func tagsFromMap(m map[string]interface{}) []*ec2.Tag { result := make([]*ec2.Tag, 0, len(m)) for k, v := range m { - result = append(result, &ec2.Tag{ + t := &ec2.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnored(t) { + result = append(result, t) + } } return result @@ -162,7 +165,9 @@ func tagsFromMap(m map[string]interface{}) []*ec2.Tag { func tagsToMap(ts []*ec2.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnored(t) { + result[*t.Key] = *t.Value + } } return result @@ -192,7 +197,9 @@ func diffElbV2Tags(oldTags, newTags []*elbv2.Tag) ([]*elbv2.Tag, []*elbv2.Tag) { func tagsToMapELBv2(ts []*elbv2.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredELBv2(t) { + result[*t.Key] = *t.Value + } } return result @@ -202,11 +209,41 @@ func tagsToMapELBv2(ts []*elbv2.Tag) map[string]string { func tagsFromMapELBv2(m map[string]interface{}) []*elbv2.Tag { var result []*elbv2.Tag for k, v := range m { - result = append(result, &elbv2.Tag{ + t := &elbv2.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredELBv2(t) { + result = append(result, t) + } } return result } + +// tagIgnored compares a tag against a list of strings and checks if it should +// be ignored or not +func tagIgnored(t *ec2.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} + +// and for ELBv2 as well +func tagIgnoredELBv2(t *elbv2.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tagsBeanstalk.go b/builtin/providers/aws/tagsBeanstalk.go index b54b77ee9..c3b7b95da 100644 --- a/builtin/providers/aws/tagsBeanstalk.go +++ b/builtin/providers/aws/tagsBeanstalk.go @@ -1,6 +1,9 @@ package aws import ( + "log" + "regexp" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/elasticbeanstalk" ) @@ -32,10 +35,13 @@ func diffTagsBeanstalk(oldTags, newTags []*elasticbeanstalk.Tag) ([]*elasticbean func tagsFromMapBeanstalk(m map[string]interface{}) []*elasticbeanstalk.Tag { var result []*elasticbeanstalk.Tag for k, v := range m { - result = append(result, &elasticbeanstalk.Tag{ + t := &elasticbeanstalk.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredBeanstalk(t) { + result = append(result, t) + } } return result @@ -45,8 +51,24 @@ func tagsFromMapBeanstalk(m map[string]interface{}) []*elasticbeanstalk.Tag { func tagsToMapBeanstalk(ts []*elasticbeanstalk.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredBeanstalk(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 tagIgnoredBeanstalk(t *elasticbeanstalk.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tagsBeanstalk_test.go b/builtin/providers/aws/tagsBeanstalk_test.go index 0a6613de6..0c9233863 100644 --- a/builtin/providers/aws/tagsBeanstalk_test.go +++ b/builtin/providers/aws/tagsBeanstalk_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/elasticbeanstalk" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,23 @@ func TestDiffBeanstalkTags(t *testing.T) { } } +func TestIgnoringTagsBeanstalk(t *testing.T) { + var ignoredTags []*elasticbeanstalk.Tag + ignoredTags = append(ignoredTags, &elasticbeanstalk.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &elasticbeanstalk.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredBeanstalk(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckTags can be used to check the tags on a resource. func testAccCheckBeanstalkTags( ts *[]*elasticbeanstalk.Tag, key string, value string) resource.TestCheckFunc { diff --git a/builtin/providers/aws/tagsCloudtrail.go b/builtin/providers/aws/tagsCloudtrail.go index 3599d4fe1..020a6ea92 100644 --- a/builtin/providers/aws/tagsCloudtrail.go +++ b/builtin/providers/aws/tagsCloudtrail.go @@ -2,6 +2,7 @@ package aws import ( "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cloudtrail" @@ -72,10 +73,13 @@ func diffTagsCloudtrail(oldTags, newTags []*cloudtrail.Tag) ([]*cloudtrail.Tag, func tagsFromMapCloudtrail(m map[string]interface{}) []*cloudtrail.Tag { var result []*cloudtrail.Tag for k, v := range m { - result = append(result, &cloudtrail.Tag{ + t := &cloudtrail.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredCloudtrail(t) { + result = append(result, t) + } } return result @@ -85,8 +89,24 @@ func tagsFromMapCloudtrail(m map[string]interface{}) []*cloudtrail.Tag { func tagsToMapCloudtrail(ts []*cloudtrail.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredCloudtrail(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 tagIgnoredCloudtrail(t *cloudtrail.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tagsCloudtrail_test.go b/builtin/providers/aws/tagsCloudtrail_test.go index 860a9bd3d..a1d7b0463 100644 --- a/builtin/providers/aws/tagsCloudtrail_test.go +++ b/builtin/providers/aws/tagsCloudtrail_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cloudtrail" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,23 @@ func TestDiffCloudtrailTags(t *testing.T) { } } +func TestIgnoringTagsCloudtrail(t *testing.T) { + var ignoredTags []*cloudtrail.Tag + ignoredTags = append(ignoredTags, &cloudtrail.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &cloudtrail.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredCloudtrail(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckCloudTrailCheckTags can be used to check the tags on a trail func testAccCheckCloudTrailCheckTags(tags *[]*cloudtrail.Tag, expectedTags map[string]string) resource.TestCheckFunc { return func(s *terraform.State) error { diff --git a/builtin/providers/aws/tagsEC.go b/builtin/providers/aws/tagsEC.go index 3a5ba1acf..6b29057ad 100644 --- a/builtin/providers/aws/tagsEC.go +++ b/builtin/providers/aws/tagsEC.go @@ -2,6 +2,7 @@ package aws import ( "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/elasticache" @@ -75,10 +76,13 @@ func diffTagsEC(oldTags, newTags []*elasticache.Tag) ([]*elasticache.Tag, []*ela func tagsFromMapEC(m map[string]interface{}) []*elasticache.Tag { result := make([]*elasticache.Tag, 0, len(m)) for k, v := range m { - result = append(result, &elasticache.Tag{ + t := &elasticache.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredEC(t) { + result = append(result, t) + } } return result @@ -88,8 +92,24 @@ func tagsFromMapEC(m map[string]interface{}) []*elasticache.Tag { func tagsToMapEC(ts []*elasticache.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredEC(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 tagIgnoredEC(t *elasticache.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tagsEC_test.go b/builtin/providers/aws/tagsEC_test.go index 11737ecea..3ea3a8d70 100644 --- a/builtin/providers/aws/tagsEC_test.go +++ b/builtin/providers/aws/tagsEC_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/elasticache" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,23 @@ func TestDiffelasticacheTags(t *testing.T) { } } +func TestIgnoringTagsEC(t *testing.T) { + var ignoredTags []*elasticache.Tag + ignoredTags = append(ignoredTags, &elasticache.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &elasticache.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredEC(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckTags can be used to check the tags on a resource. func testAccCheckelasticacheTags( ts []*elasticache.Tag, key string, value string) resource.TestCheckFunc { diff --git a/builtin/providers/aws/tagsEFS.go b/builtin/providers/aws/tagsEFS.go index 8303d6888..2dc6189cc 100644 --- a/builtin/providers/aws/tagsEFS.go +++ b/builtin/providers/aws/tagsEFS.go @@ -2,6 +2,7 @@ package aws import ( "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/efs" @@ -74,10 +75,13 @@ func diffTagsEFS(oldTags, newTags []*efs.Tag) ([]*efs.Tag, []*efs.Tag) { func tagsFromMapEFS(m map[string]interface{}) []*efs.Tag { var result []*efs.Tag for k, v := range m { - result = append(result, &efs.Tag{ + t := &efs.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredEFS(t) { + result = append(result, t) + } } return result @@ -87,8 +91,24 @@ func tagsFromMapEFS(m map[string]interface{}) []*efs.Tag { func tagsToMapEFS(ts []*efs.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredEFS(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 tagIgnoredEFS(t *efs.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tagsEFS_test.go b/builtin/providers/aws/tagsEFS_test.go index ca2ae8843..58ed72da1 100644 --- a/builtin/providers/aws/tagsEFS_test.go +++ b/builtin/providers/aws/tagsEFS_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/efs" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,23 @@ func TestDiffEFSTags(t *testing.T) { } } +func TestIgnoringTagsEFS(t *testing.T) { + var ignoredTags []*efs.Tag + ignoredTags = append(ignoredTags, &efs.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &efs.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredEFS(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckTags can be used to check the tags on a resource. func testAccCheckEFSTags( ts *[]*efs.Tag, key string, value string) resource.TestCheckFunc { diff --git a/builtin/providers/aws/tagsELB.go b/builtin/providers/aws/tagsELB.go index 1b1a93488..4c177b878 100644 --- a/builtin/providers/aws/tagsELB.go +++ b/builtin/providers/aws/tagsELB.go @@ -2,6 +2,7 @@ package aws import ( "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/elb" @@ -74,10 +75,13 @@ func diffTagsELB(oldTags, newTags []*elb.Tag) ([]*elb.Tag, []*elb.Tag) { func tagsFromMapELB(m map[string]interface{}) []*elb.Tag { var result []*elb.Tag for k, v := range m { - result = append(result, &elb.Tag{ + t := &elb.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredELB(t) { + result = append(result, t) + } } return result @@ -87,8 +91,24 @@ func tagsFromMapELB(m map[string]interface{}) []*elb.Tag { func tagsToMapELB(ts []*elb.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredELB(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 tagIgnoredELB(t *elb.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tagsELB_test.go b/builtin/providers/aws/tagsELB_test.go index 9ec6dd8db..3fc97d661 100644 --- a/builtin/providers/aws/tagsELB_test.go +++ b/builtin/providers/aws/tagsELB_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/elb" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,23 @@ func TestDiffELBTags(t *testing.T) { } } +func TestIgnoringTagsELB(t *testing.T) { + var ignoredTags []*elb.Tag + ignoredTags = append(ignoredTags, &elb.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &elb.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredELB(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckTags can be used to check the tags on a resource. func testAccCheckELBTags( ts *[]*elb.Tag, key string, value string) resource.TestCheckFunc { diff --git a/builtin/providers/aws/tagsRDS.go b/builtin/providers/aws/tagsRDS.go index bcc3eb9ea..1a5b0c1c7 100644 --- a/builtin/providers/aws/tagsRDS.go +++ b/builtin/providers/aws/tagsRDS.go @@ -3,6 +3,7 @@ package aws import ( "fmt" "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/rds" @@ -76,10 +77,13 @@ func diffTagsRDS(oldTags, newTags []*rds.Tag) ([]*rds.Tag, []*rds.Tag) { func tagsFromMapRDS(m map[string]interface{}) []*rds.Tag { result := make([]*rds.Tag, 0, len(m)) for k, v := range m { - result = append(result, &rds.Tag{ + t := &rds.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredRDS(t) { + result = append(result, t) + } } return result @@ -89,7 +93,9 @@ func tagsFromMapRDS(m map[string]interface{}) []*rds.Tag { func tagsToMapRDS(ts []*rds.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredRDS(t) { + result[*t.Key] = *t.Value + } } return result @@ -111,3 +117,17 @@ func saveTagsRDS(conn *rds.RDS, d *schema.ResourceData, arn string) error { return d.Set("tags", tagsToMapRDS(dt)) } + +// compare a tag against a list of strings and checks if it should +// be ignored or not +func tagIgnoredRDS(t *rds.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tagsRDS_test.go b/builtin/providers/aws/tagsRDS_test.go index 2aa0a05b3..cc2887daa 100644 --- a/builtin/providers/aws/tagsRDS_test.go +++ b/builtin/providers/aws/tagsRDS_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/rds" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,23 @@ func TestDiffRDSTags(t *testing.T) { } } +func TestIgnoringTagsRDS(t *testing.T) { + var ignoredTags []*rds.Tag + ignoredTags = append(ignoredTags, &rds.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &rds.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredRDS(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckTags can be used to check the tags on a resource. func testAccCheckRDSTags( ts []*rds.Tag, key string, value string) resource.TestCheckFunc { diff --git a/builtin/providers/aws/tagsRedshift.go b/builtin/providers/aws/tagsRedshift.go index d43149d7a..0a87f7114 100644 --- a/builtin/providers/aws/tagsRedshift.go +++ b/builtin/providers/aws/tagsRedshift.go @@ -2,6 +2,7 @@ package aws import ( "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/redshift" @@ -69,10 +70,13 @@ func diffTagsRedshift(oldTags, newTags []*redshift.Tag) ([]*redshift.Tag, []*red func tagsFromMapRedshift(m map[string]interface{}) []*redshift.Tag { result := make([]*redshift.Tag, 0, len(m)) for k, v := range m { - result = append(result, &redshift.Tag{ + t := &redshift.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredRedshift(t) { + result = append(result, t) + } } return result @@ -81,8 +85,24 @@ func tagsFromMapRedshift(m map[string]interface{}) []*redshift.Tag { func tagsToMapRedshift(ts []*redshift.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredRedshift(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 tagIgnoredRedshift(t *redshift.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tagsRedshift_test.go b/builtin/providers/aws/tagsRedshift_test.go index f2507f306..ec269e540 100644 --- a/builtin/providers/aws/tagsRedshift_test.go +++ b/builtin/providers/aws/tagsRedshift_test.go @@ -3,6 +3,9 @@ package aws import ( "reflect" "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/redshift" ) func TestDiffRedshiftTags(t *testing.T) { @@ -52,3 +55,20 @@ func TestDiffRedshiftTags(t *testing.T) { } } } + +func TestIgnoringTagsRedshift(t *testing.T) { + var ignoredTags []*redshift.Tag + ignoredTags = append(ignoredTags, &redshift.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &redshift.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredRedshift(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} diff --git a/builtin/providers/aws/tags_elasticsearchservice.go b/builtin/providers/aws/tags_elasticsearchservice.go index 9fc664343..f048e4681 100644 --- a/builtin/providers/aws/tags_elasticsearchservice.go +++ b/builtin/providers/aws/tags_elasticsearchservice.go @@ -2,6 +2,7 @@ package aws import ( "log" + "regexp" "github.com/aws/aws-sdk-go/aws" elasticsearch "github.com/aws/aws-sdk-go/service/elasticsearchservice" @@ -74,10 +75,13 @@ func diffTagsElasticsearchService(oldTags, newTags []*elasticsearch.Tag) ([]*ela func tagsFromMapElasticsearchService(m map[string]interface{}) []*elasticsearch.Tag { var result []*elasticsearch.Tag for k, v := range m { - result = append(result, &elasticsearch.Tag{ + t := &elasticsearch.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredElasticsearchService(t) { + result = append(result, t) + } } return result @@ -87,8 +91,24 @@ func tagsFromMapElasticsearchService(m map[string]interface{}) []*elasticsearch. func tagsToMapElasticsearchService(ts []*elasticsearch.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredElasticsearchService(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 tagIgnoredElasticsearchService(t *elasticsearch.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tags_elasticsearchservice_test.go b/builtin/providers/aws/tags_elasticsearchservice_test.go index 3d367ed9a..11c211d3c 100644 --- a/builtin/providers/aws/tags_elasticsearchservice_test.go +++ b/builtin/providers/aws/tags_elasticsearchservice_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" elasticsearch "github.com/aws/aws-sdk-go/service/elasticsearchservice" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,23 @@ func TestDiffElasticsearchServiceTags(t *testing.T) { } } +func TestIgnoringTagsElasticsearchService(t *testing.T) { + var ignoredTags []*elasticsearch.Tag + ignoredTags = append(ignoredTags, &elasticsearch.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &elasticsearch.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredElasticsearchService(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckTags can be used to check the tags on a resource. func testAccCheckElasticsearchServiceTags( ts *[]*elasticsearch.Tag, key string, value string) resource.TestCheckFunc { diff --git a/builtin/providers/aws/tags_kinesis.go b/builtin/providers/aws/tags_kinesis.go index c9562644d..5c5935988 100644 --- a/builtin/providers/aws/tags_kinesis.go +++ b/builtin/providers/aws/tags_kinesis.go @@ -2,6 +2,7 @@ package aws import ( "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/kinesis" @@ -85,10 +86,13 @@ func diffTagsKinesis(oldTags, newTags []*kinesis.Tag) ([]*kinesis.Tag, []*kinesi func tagsFromMapKinesis(m map[string]interface{}) []*kinesis.Tag { var result []*kinesis.Tag for k, v := range m { - result = append(result, &kinesis.Tag{ + t := &kinesis.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredKinesis(t) { + result = append(result, t) + } } return result @@ -98,8 +102,24 @@ func tagsFromMapKinesis(m map[string]interface{}) []*kinesis.Tag { func tagsToMapKinesis(ts []*kinesis.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredKinesis(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 tagIgnoredKinesis(t *kinesis.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tags_kinesis_test.go b/builtin/providers/aws/tags_kinesis_test.go index d97365ad8..63504b10b 100644 --- a/builtin/providers/aws/tags_kinesis_test.go +++ b/builtin/providers/aws/tags_kinesis_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/kinesis" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,23 @@ func TestDiffTagsKinesis(t *testing.T) { } } +func TestIgnoringTagsKinesis(t *testing.T) { + var ignoredTags []*kinesis.Tag + ignoredTags = append(ignoredTags, &kinesis.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &kinesis.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredKinesis(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckTags can be used to check the tags on a resource. func testAccCheckKinesisTags(ts []*kinesis.Tag, key string, value string) resource.TestCheckFunc { return func(s *terraform.State) error { diff --git a/builtin/providers/aws/tags_route53.go b/builtin/providers/aws/tags_route53.go index 7482146a8..d675f42e0 100644 --- a/builtin/providers/aws/tags_route53.go +++ b/builtin/providers/aws/tags_route53.go @@ -2,6 +2,7 @@ package aws import ( "log" + "regexp" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" @@ -71,10 +72,13 @@ func diffTagsR53(oldTags, newTags []*route53.Tag) ([]*route53.Tag, []*route53.Ta func tagsFromMapR53(m map[string]interface{}) []*route53.Tag { result := make([]*route53.Tag, 0, len(m)) for k, v := range m { - result = append(result, &route53.Tag{ + t := &route53.Tag{ Key: aws.String(k), Value: aws.String(v.(string)), - }) + } + if !tagIgnoredRoute53(t) { + result = append(result, t) + } } return result @@ -84,8 +88,24 @@ func tagsFromMapR53(m map[string]interface{}) []*route53.Tag { func tagsToMapR53(ts []*route53.Tag) map[string]string { result := make(map[string]string) for _, t := range ts { - result[*t.Key] = *t.Value + if !tagIgnoredRoute53(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 tagIgnoredRoute53(t *route53.Tag) bool { + filter := []string{"^aws:*"} + for _, v := range filter { + log.Printf("[DEBUG] Matching %v with %v\n", v, *t.Key) + if r, _ := regexp.MatchString(v, *t.Key); r == true { + log.Printf("[DEBUG] Found AWS specific tag %s (val: %s), ignoring.\n", *t.Key, *t.Value) + return true + } + } + return false +} diff --git a/builtin/providers/aws/tags_route53_test.go b/builtin/providers/aws/tags_route53_test.go index a0b2c6410..4703dbf39 100644 --- a/builtin/providers/aws/tags_route53_test.go +++ b/builtin/providers/aws/tags_route53_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,23 @@ func TestDiffTagsR53(t *testing.T) { } } +func TestIgnoringTagsRoute53(t *testing.T) { + var ignoredTags []*route53.Tag + ignoredTags = append(ignoredTags, &route53.Tag{ + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &route53.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnoredRoute53(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckTags can be used to check the tags on a resource. func testAccCheckTagsR53( ts *[]*route53.Tag, key string, value string) resource.TestCheckFunc { diff --git a/builtin/providers/aws/tags_test.go b/builtin/providers/aws/tags_test.go index 8aac147fc..1777c3764 100644 --- a/builtin/providers/aws/tags_test.go +++ b/builtin/providers/aws/tags_test.go @@ -5,6 +5,7 @@ import ( "reflect" "testing" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -61,6 +62,24 @@ func TestDiffTags(t *testing.T) { } } +func TestIgnoringTags(t *testing.T) { + var ignoredTags []*ec2.Tag + ignoredTags = append(ignoredTags, &ec2.Tag{ + + Key: aws.String("aws:cloudformation:logical-id"), + Value: aws.String("foo"), + }) + ignoredTags = append(ignoredTags, &ec2.Tag{ + Key: aws.String("aws:foo:bar"), + Value: aws.String("baz"), + }) + for _, tag := range ignoredTags { + if !tagIgnored(tag) { + t.Fatalf("Tag %v with value %v not ignored, but should be!", *tag.Key, *tag.Value) + } + } +} + // testAccCheckTags can be used to check the tags on a resource. func testAccCheckTags( ts *[]*ec2.Tag, key string, value string) resource.TestCheckFunc {