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  }