github.com/emate/packer@v0.8.1-0.20150625195101-fe0fde195dc6/builder/amazon/common/access_config.go (about) 1 package common 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "strings" 8 "unicode" 9 10 "github.com/aws/aws-sdk-go/aws" 11 "github.com/aws/aws-sdk-go/aws/credentials" 12 "github.com/mitchellh/packer/template/interpolate" 13 ) 14 15 // AccessConfig is for common configuration related to AWS access 16 type AccessConfig struct { 17 AccessKey string `mapstructure:"access_key"` 18 SecretKey string `mapstructure:"secret_key"` 19 RawRegion string `mapstructure:"region"` 20 Token string `mapstructure:"token"` 21 } 22 23 // Config returns a valid aws.Config object for access to AWS services, or 24 // an error if the authentication and region couldn't be resolved 25 func (c *AccessConfig) Config() (*aws.Config, error) { 26 creds := credentials.NewChainCredentials([]credentials.Provider{ 27 &credentials.StaticProvider{Value: credentials.Value{ 28 AccessKeyID: c.AccessKey, 29 SecretAccessKey: c.SecretKey, 30 SessionToken: c.Token, 31 }}, 32 &credentials.EnvProvider{}, 33 &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, 34 &credentials.EC2RoleProvider{}, 35 }) 36 37 region, err := c.Region() 38 if err != nil { 39 return nil, err 40 } 41 42 return &aws.Config{ 43 Region: region, 44 Credentials: creds, 45 MaxRetries: 11, 46 }, nil 47 } 48 49 // Region returns the aws.Region object for access to AWS services, requesting 50 // the region from the instance metadata if possible. 51 func (c *AccessConfig) Region() (string, error) { 52 if c.RawRegion != "" { 53 if valid := ValidateRegion(c.RawRegion); valid == false { 54 return "", fmt.Errorf("Not a valid region: %s", c.RawRegion) 55 } 56 return c.RawRegion, nil 57 } 58 59 md, err := GetInstanceMetaData("placement/availability-zone") 60 if err != nil { 61 return "", err 62 } 63 64 region := strings.TrimRightFunc(string(md), unicode.IsLetter) 65 return region, nil 66 } 67 68 func (c *AccessConfig) Prepare(ctx *interpolate.Context) []error { 69 var errs []error 70 if c.RawRegion != "" { 71 if valid := ValidateRegion(c.RawRegion); valid == false { 72 errs = append(errs, fmt.Errorf("Unknown region: %s", c.RawRegion)) 73 } 74 } 75 76 if len(errs) > 0 { 77 return errs 78 } 79 80 return nil 81 } 82 83 func GetInstanceMetaData(path string) (contents []byte, err error) { 84 url := "http://169.254.169.254/latest/meta-data/" + path 85 86 resp, err := http.Get(url) 87 if err != nil { 88 return 89 } 90 defer resp.Body.Close() 91 92 if resp.StatusCode != 200 { 93 err = fmt.Errorf("Code %d returned for url %s", resp.StatusCode, url) 94 return 95 } 96 97 body, err := ioutil.ReadAll(resp.Body) 98 if err != nil { 99 return 100 } 101 return []byte(body), err 102 }