github.com/sathiyas/terraform@v0.6.9-0.20151210233947-3330da00b997/builtin/providers/aws/s3_tags.go (about) 1 package aws 2 3 import ( 4 "log" 5 6 "github.com/aws/aws-sdk-go/aws" 7 "github.com/aws/aws-sdk-go/aws/awserr" 8 "github.com/aws/aws-sdk-go/service/s3" 9 "github.com/hashicorp/terraform/helper/schema" 10 ) 11 12 // setTags is a helper to set the tags for a resource. It expects the 13 // tags field to be named "tags" 14 func setTagsS3(conn *s3.S3, d *schema.ResourceData) error { 15 if d.HasChange("tags") { 16 oraw, nraw := d.GetChange("tags") 17 o := oraw.(map[string]interface{}) 18 n := nraw.(map[string]interface{}) 19 create, remove := diffTagsS3(tagsFromMapS3(o), tagsFromMapS3(n)) 20 21 // Set tags 22 if len(remove) > 0 { 23 log.Printf("[DEBUG] Removing tags: %#v", remove) 24 _, err := conn.DeleteBucketTagging(&s3.DeleteBucketTaggingInput{ 25 Bucket: aws.String(d.Get("bucket").(string)), 26 }) 27 if err != nil { 28 return err 29 } 30 } 31 if len(create) > 0 { 32 log.Printf("[DEBUG] Creating tags: %#v", create) 33 req := &s3.PutBucketTaggingInput{ 34 Bucket: aws.String(d.Get("bucket").(string)), 35 Tagging: &s3.Tagging{ 36 TagSet: create, 37 }, 38 } 39 40 _, err := conn.PutBucketTagging(req) 41 if err != nil { 42 return err 43 } 44 } 45 } 46 47 return nil 48 } 49 50 // diffTags takes our tags locally and the ones remotely and returns 51 // the set of tags that must be created, and the set of tags that must 52 // be destroyed. 53 func diffTagsS3(oldTags, newTags []*s3.Tag) ([]*s3.Tag, []*s3.Tag) { 54 // First, we're creating everything we have 55 create := make(map[string]interface{}) 56 for _, t := range newTags { 57 create[*t.Key] = *t.Value 58 } 59 60 // Build the list of what to remove 61 var remove []*s3.Tag 62 for _, t := range oldTags { 63 old, ok := create[*t.Key] 64 if !ok || old != *t.Value { 65 // Delete it! 66 remove = append(remove, t) 67 } 68 } 69 70 return tagsFromMapS3(create), remove 71 } 72 73 // tagsFromMap returns the tags for the given map of data. 74 func tagsFromMapS3(m map[string]interface{}) []*s3.Tag { 75 result := make([]*s3.Tag, 0, len(m)) 76 for k, v := range m { 77 result = append(result, &s3.Tag{ 78 Key: aws.String(k), 79 Value: aws.String(v.(string)), 80 }) 81 } 82 83 return result 84 } 85 86 // tagsToMap turns the list of tags into a map. 87 func tagsToMapS3(ts []*s3.Tag) map[string]string { 88 result := make(map[string]string) 89 for _, t := range ts { 90 result[*t.Key] = *t.Value 91 } 92 93 return result 94 } 95 96 // return a slice of s3 tags associated with the given s3 bucket. Essentially 97 // s3.GetBucketTagging, except returns an empty slice instead of an error when 98 // there are no tags. 99 func getTagSetS3(s3conn *s3.S3, bucket string) ([]*s3.Tag, error) { 100 request := &s3.GetBucketTaggingInput{ 101 Bucket: aws.String(bucket), 102 } 103 104 response, err := s3conn.GetBucketTagging(request) 105 if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "NoSuchTagSet" { 106 // There is no tag set associated with the bucket. 107 return []*s3.Tag{}, nil 108 } else if err != nil { 109 return nil, err 110 } 111 112 return response.TagSet, nil 113 }