Merge pull request #102 from willglynn/aws_authentication

Add support for additional AWS authentication sources
This commit is contained in:
xenolf 2016-02-07 14:28:57 +01:00
commit e4978657b2
2 changed files with 27 additions and 19 deletions

View file

@ -15,29 +15,29 @@ type DNSProviderRoute53 struct {
}
// NewDNSProviderRoute53 returns a DNSProviderRoute53 instance with a configured route53 client.
// Authentication is either done using the passed credentials or - when empty -
// using the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.
// Authentication is either done using the passed credentials or - when empty - falling back to
// the customary AWS credential mechanisms, including the file refernced by $AWS_CREDENTIAL_FILE
// (defaulting to $HOME/.aws/credentials) optionally scoped to $AWS_PROFILE, credentials
// supplied by the environment variables AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY [ + AWS_SECURITY_TOKEN ],
// and finally credentials available via the EC2 instance metadata service.
func NewDNSProviderRoute53(awsAccessKey, awsSecretKey, awsRegionName string) (*DNSProviderRoute53, error) {
region, ok := aws.Regions[awsRegionName]
if !ok {
return nil, fmt.Errorf("Invalid AWS region name %s", awsRegionName)
}
var auth aws.Auth
// First try passed in credentials
if awsAccessKey != "" && awsSecretKey != "" {
auth = aws.Auth{awsAccessKey, awsSecretKey, ""}
// use aws.GetAuth, which tries really hard to find credentails:
// - uses awsAccessKey and awsSecretKey, if provided
// - uses AWS_PROFILE / AWS_CREDENTIAL_FILE, if provided
// - uses AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY and optionally AWS_SECURITY_TOKEN, if provided
// - uses EC2 instance metadata credentials (http://169.254.169.254/latest/meta-data/…), if available
// ...and otherwise returns an error
if auth, err := aws.GetAuth(awsAccessKey, awsSecretKey); err != nil {
return nil, err
} else {
// try getting credentials from environment
envAuth, err := aws.EnvAuth()
if err != nil {
return nil, fmt.Errorf("AWS credentials missing")
}
auth = envAuth
client := route53.New(auth, region)
return &DNSProviderRoute53{client: client}, nil
}
client := route53.New(auth, region)
return &DNSProviderRoute53{client: client}, nil
}
// Present creates a TXT record using the specified parameters

View file

@ -11,9 +11,11 @@ import (
)
var (
route53Secret string
route53Key string
testServer *testutil.HTTPServer
route53Secret string
route53Key string
awsCredentialFile string
homeDir string
testServer *testutil.HTTPServer
)
var ChangeResourceRecordSetsAnswer = `<?xml version="1.0" encoding="UTF-8"?>
@ -69,6 +71,8 @@ var serverResponseMap = testutil.ResponseMap{
func init() {
route53Key = os.Getenv("AWS_ACCESS_KEY_ID")
route53Secret = os.Getenv("AWS_SECRET_ACCESS_KEY")
awsCredentialFile = os.Getenv("AWS_CREDENTIAL_FILE")
homeDir = os.Getenv("HOME")
testServer = testutil.NewHTTPServer()
testServer.Start()
}
@ -76,6 +80,8 @@ func init() {
func restoreRoute53Env() {
os.Setenv("AWS_ACCESS_KEY_ID", route53Key)
os.Setenv("AWS_SECRET_ACCESS_KEY", route53Secret)
os.Setenv("AWS_CREDENTIAL_FILE", awsCredentialFile)
os.Setenv("HOME", homeDir)
}
func makeRoute53TestServer() *testutil.HTTPServer {
@ -108,8 +114,10 @@ func TestNewDNSProviderRoute53ValidEnv(t *testing.T) {
func TestNewDNSProviderRoute53MissingAuthErr(t *testing.T) {
os.Setenv("AWS_ACCESS_KEY_ID", "")
os.Setenv("AWS_SECRET_ACCESS_KEY", "")
os.Setenv("AWS_CREDENTIAL_FILE", "") // in case test machine has this variable set
os.Setenv("HOME", "/") // in case test machine has ~/.aws/credentials
_, err := NewDNSProviderRoute53("", "", "us-east-1")
assert.EqualError(t, err, "AWS credentials missing")
assert.EqualError(t, err, "No valid AWS authentication found")
restoreRoute53Env()
}