github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/aws/resource_aws_s3_bucket_object.go (about)

     1  package aws
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  	"os"
     9  
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  	"github.com/mitchellh/go-homedir"
    12  
    13  	"github.com/aws/aws-sdk-go/aws"
    14  	"github.com/aws/aws-sdk-go/aws/awserr"
    15  	"github.com/aws/aws-sdk-go/service/s3"
    16  )
    17  
    18  func resourceAwsS3BucketObject() *schema.Resource {
    19  	return &schema.Resource{
    20  		Create: resourceAwsS3BucketObjectPut,
    21  		Read:   resourceAwsS3BucketObjectRead,
    22  		Delete: resourceAwsS3BucketObjectDelete,
    23  
    24  		Schema: map[string]*schema.Schema{
    25  			"bucket": &schema.Schema{
    26  				Type:     schema.TypeString,
    27  				Required: true,
    28  				ForceNew: true,
    29  			},
    30  
    31  			"cache_control": &schema.Schema{
    32  				Type:     schema.TypeString,
    33  				Optional: true,
    34  				ForceNew: true,
    35  			},
    36  
    37  			"content_disposition": &schema.Schema{
    38  				Type:     schema.TypeString,
    39  				Optional: true,
    40  				ForceNew: true,
    41  			},
    42  
    43  			"content_encoding": &schema.Schema{
    44  				Type:     schema.TypeString,
    45  				Optional: true,
    46  				ForceNew: true,
    47  			},
    48  
    49  			"content_language": &schema.Schema{
    50  				Type:     schema.TypeString,
    51  				Optional: true,
    52  				ForceNew: true,
    53  			},
    54  
    55  			"content_type": &schema.Schema{
    56  				Type:     schema.TypeString,
    57  				Optional: true,
    58  				ForceNew: true,
    59  				Computed: true,
    60  			},
    61  
    62  			"key": &schema.Schema{
    63  				Type:     schema.TypeString,
    64  				Required: true,
    65  				ForceNew: true,
    66  			},
    67  
    68  			"source": &schema.Schema{
    69  				Type:          schema.TypeString,
    70  				Optional:      true,
    71  				ForceNew:      true,
    72  				ConflictsWith: []string{"content"},
    73  			},
    74  
    75  			"content": &schema.Schema{
    76  				Type:          schema.TypeString,
    77  				Optional:      true,
    78  				ForceNew:      true,
    79  				ConflictsWith: []string{"source"},
    80  			},
    81  
    82  			"etag": &schema.Schema{
    83  				Type:     schema.TypeString,
    84  				Computed: true,
    85  			},
    86  		},
    87  	}
    88  }
    89  
    90  func resourceAwsS3BucketObjectPut(d *schema.ResourceData, meta interface{}) error {
    91  	s3conn := meta.(*AWSClient).s3conn
    92  
    93  	bucket := d.Get("bucket").(string)
    94  	key := d.Get("key").(string)
    95  	var body io.ReadSeeker
    96  
    97  	if v, ok := d.GetOk("source"); ok {
    98  		source := v.(string)
    99  		path, err := homedir.Expand(source)
   100  		if err != nil {
   101  			return fmt.Errorf("Error expanding homedir in source (%s): %s", source, err)
   102  		}
   103  		file, err := os.Open(path)
   104  		if err != nil {
   105  			return fmt.Errorf("Error opening S3 bucket object source (%s): %s", source, err)
   106  		}
   107  
   108  		body = file
   109  	} else if v, ok := d.GetOk("content"); ok {
   110  		content := v.(string)
   111  		body = bytes.NewReader([]byte(content))
   112  	} else {
   113  
   114  		return fmt.Errorf("Must specify \"source\" or \"content\" field")
   115  	}
   116  	putInput := &s3.PutObjectInput{
   117  		Bucket: aws.String(bucket),
   118  		Key:    aws.String(key),
   119  		Body:   body,
   120  	}
   121  
   122  	if v, ok := d.GetOk("cache_control"); ok {
   123  		putInput.CacheControl = aws.String(v.(string))
   124  	}
   125  
   126  	if v, ok := d.GetOk("content_type"); ok {
   127  		putInput.ContentType = aws.String(v.(string))
   128  	}
   129  
   130  	if v, ok := d.GetOk("content_encoding"); ok {
   131  		putInput.ContentEncoding = aws.String(v.(string))
   132  	}
   133  
   134  	if v, ok := d.GetOk("content_language"); ok {
   135  		putInput.ContentLanguage = aws.String(v.(string))
   136  	}
   137  
   138  	if v, ok := d.GetOk("content_disposition"); ok {
   139  		putInput.ContentDisposition = aws.String(v.(string))
   140  	}
   141  
   142  	resp, err := s3conn.PutObject(putInput)
   143  	if err != nil {
   144  		return fmt.Errorf("Error putting object in S3 bucket (%s): %s", bucket, err)
   145  	}
   146  
   147  	d.Set("etag", resp.ETag)
   148  	d.SetId(key)
   149  	return nil
   150  }
   151  
   152  func resourceAwsS3BucketObjectRead(d *schema.ResourceData, meta interface{}) error {
   153  	s3conn := meta.(*AWSClient).s3conn
   154  
   155  	bucket := d.Get("bucket").(string)
   156  	key := d.Get("key").(string)
   157  	etag := d.Get("etag").(string)
   158  
   159  	resp, err := s3conn.HeadObject(
   160  		&s3.HeadObjectInput{
   161  			Bucket:  aws.String(bucket),
   162  			Key:     aws.String(key),
   163  			IfMatch: aws.String(etag),
   164  		})
   165  
   166  	if err != nil {
   167  		// If S3 returns a 404 Request Failure, mark the object as destroyed
   168  		if awsErr, ok := err.(awserr.RequestFailure); ok && awsErr.StatusCode() == 404 {
   169  			d.SetId("")
   170  			log.Printf("[WARN] Error Reading Object (%s), object not found (HTTP status 404)", key)
   171  			return nil
   172  		}
   173  		return err
   174  	}
   175  
   176  	d.Set("cache_control", resp.CacheControl)
   177  	d.Set("content_disposition", resp.ContentDisposition)
   178  	d.Set("content_encoding", resp.ContentEncoding)
   179  	d.Set("content_language", resp.ContentLanguage)
   180  	d.Set("content_type", resp.ContentType)
   181  
   182  	log.Printf("[DEBUG] Reading S3 Bucket Object meta: %s", resp)
   183  	return nil
   184  }
   185  
   186  func resourceAwsS3BucketObjectDelete(d *schema.ResourceData, meta interface{}) error {
   187  	s3conn := meta.(*AWSClient).s3conn
   188  
   189  	bucket := d.Get("bucket").(string)
   190  	key := d.Get("key").(string)
   191  
   192  	_, err := s3conn.DeleteObject(
   193  		&s3.DeleteObjectInput{
   194  			Bucket: aws.String(bucket),
   195  			Key:    aws.String(key),
   196  		})
   197  	if err != nil {
   198  		return fmt.Errorf("Error deleting S3 bucket object: %s", err)
   199  	}
   200  	return nil
   201  }