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  }