github.com/gabrielperezs/terraform@v0.7.0-rc2.0.20160715084931-f7da2612946f/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  }