github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/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  }