github.com/sathiyas/terraform@v0.6.9-0.20151210233947-3330da00b997/builtin/providers/aws/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/service/ec2" 8 "github.com/hashicorp/terraform/helper/schema" 9 ) 10 11 // tagsSchema returns the schema to use for tags. 12 // 13 func tagsSchema() *schema.Schema { 14 return &schema.Schema{ 15 Type: schema.TypeMap, 16 Optional: true, 17 } 18 } 19 20 // setTags is a helper to set the tags for a resource. It expects the 21 // tags field to be named "tags" 22 func setTags(conn *ec2.EC2, d *schema.ResourceData) error { 23 if d.HasChange("tags") { 24 oraw, nraw := d.GetChange("tags") 25 o := oraw.(map[string]interface{}) 26 n := nraw.(map[string]interface{}) 27 create, remove := diffTags(tagsFromMap(o), tagsFromMap(n)) 28 29 // Set tags 30 if len(remove) > 0 { 31 log.Printf("[DEBUG] Removing tags: %#v from %s", remove, d.Id()) 32 _, err := conn.DeleteTags(&ec2.DeleteTagsInput{ 33 Resources: []*string{aws.String(d.Id())}, 34 Tags: remove, 35 }) 36 if err != nil { 37 return err 38 } 39 } 40 if len(create) > 0 { 41 log.Printf("[DEBUG] Creating tags: %s for %s", create, d.Id()) 42 _, err := conn.CreateTags(&ec2.CreateTagsInput{ 43 Resources: []*string{aws.String(d.Id())}, 44 Tags: create, 45 }) 46 if err != nil { 47 return err 48 } 49 } 50 } 51 52 return nil 53 } 54 55 // diffTags takes our tags locally and the ones remotely and returns 56 // the set of tags that must be created, and the set of tags that must 57 // be destroyed. 58 func diffTags(oldTags, newTags []*ec2.Tag) ([]*ec2.Tag, []*ec2.Tag) { 59 // First, we're creating everything we have 60 create := make(map[string]interface{}) 61 for _, t := range newTags { 62 create[*t.Key] = *t.Value 63 } 64 65 // Build the list of what to remove 66 var remove []*ec2.Tag 67 for _, t := range oldTags { 68 old, ok := create[*t.Key] 69 if !ok || old != *t.Value { 70 // Delete it! 71 remove = append(remove, t) 72 } 73 } 74 75 return tagsFromMap(create), remove 76 } 77 78 // tagsFromMap returns the tags for the given map of data. 79 func tagsFromMap(m map[string]interface{}) []*ec2.Tag { 80 result := make([]*ec2.Tag, 0, len(m)) 81 for k, v := range m { 82 result = append(result, &ec2.Tag{ 83 Key: aws.String(k), 84 Value: aws.String(v.(string)), 85 }) 86 } 87 88 return result 89 } 90 91 // tagsToMap turns the list of tags into a map. 92 func tagsToMap(ts []*ec2.Tag) map[string]string { 93 result := make(map[string]string) 94 for _, t := range ts { 95 result[*t.Key] = *t.Value 96 } 97 98 return result 99 }