github.com/i0n/terraform@v0.4.3-0.20150506151324-010a39a58ec1/state/remote/s3.go (about) 1 package remote 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "os" 8 9 "github.com/awslabs/aws-sdk-go/aws" 10 "github.com/awslabs/aws-sdk-go/aws/credentials" 11 "github.com/awslabs/aws-sdk-go/service/s3" 12 ) 13 14 func s3Factory(conf map[string]string) (Client, error) { 15 bucketName, ok := conf["bucket"] 16 if !ok { 17 return nil, fmt.Errorf("missing 'bucket' configuration") 18 } 19 20 keyName, ok := conf["key"] 21 if !ok { 22 return nil, fmt.Errorf("missing 'key' configuration") 23 } 24 25 regionName, ok := conf["region"] 26 if !ok { 27 regionName = os.Getenv("AWS_DEFAULT_REGION") 28 if regionName == "" { 29 return nil, fmt.Errorf( 30 "missing 'region' configuration or AWS_DEFAULT_REGION environment variable") 31 } 32 } 33 34 accessKeyId := conf["access_key"] 35 secretAccessKey := conf["secret_key"] 36 37 credentialsProvider := credentials.NewChainCredentials([]credentials.Provider{ 38 &credentials.StaticProvider{Value: credentials.Value{ 39 AccessKeyID: accessKeyId, 40 SecretAccessKey: secretAccessKey, 41 SessionToken: "", 42 }}, 43 &credentials.EnvProvider{}, 44 &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, 45 &credentials.EC2RoleProvider{}, 46 }) 47 48 // Make sure we got some sort of working credentials. 49 _, err := credentialsProvider.Get() 50 if err != nil { 51 return nil, fmt.Errorf("Unable to determine AWS credentials. Set the AWS_ACCESS_KEY_ID and "+ 52 "AWS_SECRET_ACCESS_KEY environment variables.\n(error was: %s)", err) 53 } 54 55 awsConfig := &aws.Config{ 56 Credentials: credentialsProvider, 57 Region: regionName, 58 } 59 nativeClient := s3.New(awsConfig) 60 61 return &S3Client{ 62 nativeClient: nativeClient, 63 bucketName: bucketName, 64 keyName: keyName, 65 }, nil 66 } 67 68 type S3Client struct { 69 nativeClient *s3.S3 70 bucketName string 71 keyName string 72 } 73 74 func (c *S3Client) Get() (*Payload, error) { 75 output, err := c.nativeClient.GetObject(&s3.GetObjectInput{ 76 Bucket: &c.bucketName, 77 Key: &c.keyName, 78 }) 79 80 if err != nil { 81 if awserr := aws.Error(err); awserr != nil { 82 if awserr.Code == "NoSuchKey" { 83 return nil, nil 84 } else { 85 return nil, err 86 } 87 } else { 88 return nil, err 89 } 90 } 91 92 defer output.Body.Close() 93 94 buf := bytes.NewBuffer(nil) 95 if _, err := io.Copy(buf, output.Body); err != nil { 96 return nil, fmt.Errorf("Failed to read remote state: %s", err) 97 } 98 99 payload := &Payload{ 100 Data: buf.Bytes(), 101 } 102 103 // If there was no data, then return nil 104 if len(payload.Data) == 0 { 105 return nil, nil 106 } 107 108 return payload, nil 109 } 110 111 func (c *S3Client) Put(data []byte) error { 112 contentType := "application/octet-stream" 113 contentLength := int64(len(data)) 114 115 _, err := c.nativeClient.PutObject(&s3.PutObjectInput{ 116 ContentType: &contentType, 117 ContentLength: &contentLength, 118 Body: bytes.NewReader(data), 119 Bucket: &c.bucketName, 120 Key: &c.keyName, 121 }) 122 123 if err == nil { 124 return nil 125 } else { 126 return fmt.Errorf("Failed to upload state: %v", err) 127 } 128 } 129 130 func (c *S3Client) Delete() error { 131 _, err := c.nativeClient.DeleteObject(&s3.DeleteObjectInput{ 132 Bucket: &c.bucketName, 133 Key: &c.keyName, 134 }) 135 136 return err 137 }