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