github.com/jefferai/terraform@v0.3.7-0.20150310153852-f7512ca29fcf/builtin/providers/aws/config.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "strings" 7 "unicode" 8 9 "github.com/hashicorp/terraform/helper/multierror" 10 "github.com/mitchellh/goamz/aws" 11 "github.com/mitchellh/goamz/ec2" 12 13 awsGo "github.com/hashicorp/aws-sdk-go/aws" 14 "github.com/hashicorp/aws-sdk-go/gen/autoscaling" 15 "github.com/hashicorp/aws-sdk-go/gen/elb" 16 "github.com/hashicorp/aws-sdk-go/gen/rds" 17 "github.com/hashicorp/aws-sdk-go/gen/route53" 18 "github.com/hashicorp/aws-sdk-go/gen/s3" 19 20 awsEC2 "github.com/hashicorp/aws-sdk-go/gen/ec2" 21 ) 22 23 type Config struct { 24 AccessKey string 25 SecretKey string 26 Token string 27 Region string 28 } 29 30 type AWSClient struct { 31 ec2conn *ec2.EC2 32 awsEC2conn *awsEC2.EC2 33 elbconn *elb.ELB 34 autoscalingconn *autoscaling.AutoScaling 35 s3conn *s3.S3 36 r53conn *route53.Route53 37 region string 38 rdsconn *rds.RDS 39 } 40 41 // Client configures and returns a fully initailized AWSClient 42 func (c *Config) Client() (interface{}, error) { 43 var client AWSClient 44 45 // Get the auth and region. This can fail if keys/regions were not 46 // specified and we're attempting to use the environment. 47 var errs []error 48 log.Println("[INFO] Building AWS auth structure") 49 auth, err := c.AWSAuth() 50 if err != nil { 51 errs = append(errs, err) 52 } 53 54 log.Println("[INFO] Building AWS region structure") 55 region, err := c.AWSRegion() 56 if err != nil { 57 errs = append(errs, err) 58 } 59 60 if len(errs) == 0 { 61 // store AWS region in client struct, for region specific operations such as 62 // bucket storage in S3 63 client.region = c.Region 64 65 creds := awsGo.Creds(c.AccessKey, c.SecretKey, c.Token) 66 67 log.Println("[INFO] Initializing EC2 connection") 68 client.ec2conn = ec2.New(auth, region) 69 log.Println("[INFO] Initializing ELB connection") 70 client.elbconn = elb.New(creds, c.Region, nil) 71 log.Println("[INFO] Initializing AutoScaling connection") 72 client.autoscalingconn = autoscaling.New(creds, c.Region, nil) 73 log.Println("[INFO] Initializing S3 connection") 74 client.s3conn = s3.New(creds, c.Region, nil) 75 log.Println("[INFO] Initializing RDS connection") 76 client.rdsconn = rds.New(creds, c.Region, nil) 77 78 // aws-sdk-go uses v4 for signing requests, which requires all global 79 // endpoints to use 'us-east-1'. 80 // See http://docs.aws.amazon.com/general/latest/gr/sigv4_changes.html 81 log.Println("[INFO] Initializing Route53 connection") 82 client.r53conn = route53.New(creds, "us-east-1", nil) 83 log.Println("[INFO] Initializing AWS-GO EC2 Connection") 84 client.awsEC2conn = awsEC2.New(creds, c.Region, nil) 85 } 86 87 if len(errs) > 0 { 88 return nil, &multierror.Error{Errors: errs} 89 } 90 91 return &client, nil 92 } 93 94 // AWSAuth returns a valid aws.Auth object for access to AWS services, or 95 // an error if the authentication couldn't be resolved. 96 // 97 // TODO(mitchellh): Test in some way. 98 func (c *Config) AWSAuth() (aws.Auth, error) { 99 auth, err := aws.GetAuth(c.AccessKey, c.SecretKey) 100 if err == nil { 101 // Store the accesskey and secret that we got... 102 c.AccessKey = auth.AccessKey 103 c.SecretKey = auth.SecretKey 104 c.Token = auth.Token 105 } 106 107 return auth, err 108 } 109 110 // IsValidRegion returns true if the configured region is a valid AWS 111 // region and false if it's not 112 func (c *Config) IsValidRegion() bool { 113 var regions = [11]string{"us-east-1", "us-west-2", "us-west-1", "eu-west-1", 114 "eu-central-1", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1", 115 "sa-east-1", "cn-north-1", "us-gov-west-1"} 116 117 for _, valid := range regions { 118 if c.Region == valid { 119 return true 120 } 121 } 122 return false 123 } 124 125 // AWSRegion returns the configured region. 126 // 127 // TODO(mitchellh): Test in some way. 128 func (c *Config) AWSRegion() (aws.Region, error) { 129 if c.Region != "" { 130 if c.IsValidRegion() { 131 return aws.Regions[c.Region], nil 132 } else { 133 return aws.Region{}, fmt.Errorf("Not a valid region: %s", c.Region) 134 } 135 } 136 137 md, err := aws.GetMetaData("placement/availability-zone") 138 if err != nil { 139 return aws.Region{}, err 140 } 141 142 region := strings.TrimRightFunc(string(md), unicode.IsLetter) 143 return aws.Regions[region], nil 144 }