github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/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/aws/aws-sdk-go/service/elbv2" 9 "github.com/hashicorp/terraform/helper/schema" 10 ) 11 12 // tagsSchema returns the schema to use for tags. 13 // 14 func tagsSchema() *schema.Schema { 15 return &schema.Schema{ 16 Type: schema.TypeMap, 17 Optional: true, 18 } 19 } 20 21 func setElbV2Tags(conn *elbv2.ELBV2, d *schema.ResourceData) error { 22 if d.HasChange("tags") { 23 oraw, nraw := d.GetChange("tags") 24 o := oraw.(map[string]interface{}) 25 n := nraw.(map[string]interface{}) 26 create, remove := diffElbV2Tags(tagsFromMapELBv2(o), tagsFromMapELBv2(n)) 27 28 // Set tags 29 if len(remove) > 0 { 30 var tagKeys []*string 31 for _, tag := range remove { 32 tagKeys = append(tagKeys, tag.Key) 33 } 34 log.Printf("[DEBUG] Removing tags: %#v from %s", remove, d.Id()) 35 _, err := conn.RemoveTags(&elbv2.RemoveTagsInput{ 36 ResourceArns: []*string{aws.String(d.Id())}, 37 TagKeys: tagKeys, 38 }) 39 if err != nil { 40 return err 41 } 42 } 43 if len(create) > 0 { 44 log.Printf("[DEBUG] Creating tags: %s for %s", create, d.Id()) 45 _, err := conn.AddTags(&elbv2.AddTagsInput{ 46 ResourceArns: []*string{aws.String(d.Id())}, 47 Tags: create, 48 }) 49 if err != nil { 50 return err 51 } 52 } 53 } 54 55 return nil 56 } 57 58 // setTags is a helper to set the tags for a resource. It expects the 59 // tags field to be named "tags" 60 func setTags(conn *ec2.EC2, d *schema.ResourceData) error { 61 if d.HasChange("tags") { 62 oraw, nraw := d.GetChange("tags") 63 o := oraw.(map[string]interface{}) 64 n := nraw.(map[string]interface{}) 65 create, remove := diffTags(tagsFromMap(o), tagsFromMap(n)) 66 67 // Set tags 68 if len(remove) > 0 { 69 log.Printf("[DEBUG] Removing tags: %#v from %s", remove, d.Id()) 70 _, err := conn.DeleteTags(&ec2.DeleteTagsInput{ 71 Resources: []*string{aws.String(d.Id())}, 72 Tags: remove, 73 }) 74 if err != nil { 75 return err 76 } 77 } 78 if len(create) > 0 { 79 log.Printf("[DEBUG] Creating tags: %s for %s", create, d.Id()) 80 _, err := conn.CreateTags(&ec2.CreateTagsInput{ 81 Resources: []*string{aws.String(d.Id())}, 82 Tags: create, 83 }) 84 if err != nil { 85 return err 86 } 87 } 88 } 89 90 return nil 91 } 92 93 // diffTags takes our tags locally and the ones remotely and returns 94 // the set of tags that must be created, and the set of tags that must 95 // be destroyed. 96 func diffTags(oldTags, newTags []*ec2.Tag) ([]*ec2.Tag, []*ec2.Tag) { 97 // First, we're creating everything we have 98 create := make(map[string]interface{}) 99 for _, t := range newTags { 100 create[*t.Key] = *t.Value 101 } 102 103 // Build the list of what to remove 104 var remove []*ec2.Tag 105 for _, t := range oldTags { 106 old, ok := create[*t.Key] 107 if !ok || old != *t.Value { 108 // Delete it! 109 remove = append(remove, t) 110 } 111 } 112 113 return tagsFromMap(create), remove 114 } 115 116 // tagsFromMap returns the tags for the given map of data. 117 func tagsFromMap(m map[string]interface{}) []*ec2.Tag { 118 result := make([]*ec2.Tag, 0, len(m)) 119 for k, v := range m { 120 result = append(result, &ec2.Tag{ 121 Key: aws.String(k), 122 Value: aws.String(v.(string)), 123 }) 124 } 125 126 return result 127 } 128 129 // tagsToMap turns the list of tags into a map. 130 func tagsToMap(ts []*ec2.Tag) map[string]string { 131 result := make(map[string]string) 132 for _, t := range ts { 133 result[*t.Key] = *t.Value 134 } 135 136 return result 137 } 138 139 func diffElbV2Tags(oldTags, newTags []*elbv2.Tag) ([]*elbv2.Tag, []*elbv2.Tag) { 140 // First, we're creating everything we have 141 create := make(map[string]interface{}) 142 for _, t := range newTags { 143 create[*t.Key] = *t.Value 144 } 145 146 // Build the list of what to remove 147 var remove []*elbv2.Tag 148 for _, t := range oldTags { 149 old, ok := create[*t.Key] 150 if !ok || old != *t.Value { 151 // Delete it! 152 remove = append(remove, t) 153 } 154 } 155 156 return tagsFromMapELBv2(create), remove 157 } 158 159 // tagsToMapELBv2 turns the list of tags into a map. 160 func tagsToMapELBv2(ts []*elbv2.Tag) map[string]string { 161 result := make(map[string]string) 162 for _, t := range ts { 163 result[*t.Key] = *t.Value 164 } 165 166 return result 167 } 168 169 // tagsFromMapELBv2 returns the tags for the given map of data. 170 func tagsFromMapELBv2(m map[string]interface{}) []*elbv2.Tag { 171 var result []*elbv2.Tag 172 for k, v := range m { 173 result = append(result, &elbv2.Tag{ 174 Key: aws.String(k), 175 Value: aws.String(v.(string)), 176 }) 177 } 178 179 return result 180 }