Refactor AWS credential code into a function that returns a static->env->instance chain

This commit is contained in:
Jeff Mitchell 2016-05-03 15:10:35 -04:00
parent 0b44170485
commit 56011c9443
2 changed files with 78 additions and 10 deletions

View file

@ -4,34 +4,40 @@ import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/vault/helper/awsutil"
"github.com/hashicorp/vault/logical"
)
func getRootConfig(s logical.Storage) (*aws.Config, error) {
credConfig := &awsutil.AWSCredentialsConfig{}
entry, err := s.Get("config/root")
if err != nil {
return nil, err
}
if entry == nil {
return nil, fmt.Errorf(
"root credentials haven't been configured. Please configure\n" +
"them at the 'config/root' endpoint")
if entry != nil {
var config rootConfig
if err := entry.DecodeJSON(&config); err != nil {
return nil, fmt.Errorf("error reading root configuration: %s", err)
}
credConfig.AccessKey = config.AccessKey
credConfig.SecretKey = config.SecretKey
credConfig.Region = config.Region
}
var config rootConfig
if err := entry.DecodeJSON(&config); err != nil {
return nil, fmt.Errorf("error reading root configuration: %s", err)
creds, err := awsutil.GenerateCredentialChain(credConfig)
if err != nil {
return nil, err
}
creds := credentials.NewStaticCredentials(config.AccessKey, config.SecretKey, "")
return &aws.Config{
Credentials: creds,
Region: aws.String(config.Region),
Region: aws.String(credConfig.Region),
HTTPClient: cleanhttp.DefaultClient(),
}, nil
}

View file

@ -0,0 +1,62 @@
package awsutil
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/hashicorp/go-cleanhttp"
)
type AWSCredentialsConfig struct {
AccessKey string
SecretKey string
Region string
}
func GenerateCredentialChain(config *AWSCredentialsConfig) (*credentials.Credentials, error) {
if config == nil {
return nil, fmt.Errorf("nil configuration provided")
}
var providers []credentials.Provider
switch {
case config.AccessKey != "" && config.SecretKey != "":
// Add the static credential provider
providers = append(providers, &credentials.StaticProvider{
Value: credentials.Value{
AccessKeyID: config.AccessKey,
SecretAccessKey: config.SecretKey,
}})
case config.AccessKey == "" && config.AccessKey == "":
// Attempt to get credentials from the IAM instance role below
default: // Have one or the other but not both and not neither
return nil, fmt.Errorf(
"static AWS client credentials haven't been properly configured (the access key or secret key were provided but not both)")
}
// Add the environment credential provider
providers = append(providers, &credentials.EnvProvider{})
// Add the instance metadata role provider
// Create the credentials required to access the API.
providers = append(providers, &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(session.New(&aws.Config{
Region: aws.String(config.Region),
HTTPClient: cleanhttp.DefaultClient(),
})),
ExpiryWindow: 15,
})
creds := credentials.NewChainCredentials(providers)
if creds == nil {
return nil, fmt.Errorf("could not compile valid credential providers from static config, environemnt, or instance metadata")
}
return creds, nil
}