summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/awslabs/aws-sdk-go/aws/credentials.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/awslabs/aws-sdk-go/aws/credentials.go')
-rw-r--r--Godeps/_workspace/src/github.com/awslabs/aws-sdk-go/aws/credentials.go288
1 files changed, 288 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/awslabs/aws-sdk-go/aws/credentials.go b/Godeps/_workspace/src/github.com/awslabs/aws-sdk-go/aws/credentials.go
new file mode 100644
index 000000000..4490c674a
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/awslabs/aws-sdk-go/aws/credentials.go
@@ -0,0 +1,288 @@
+package aws
+
+import (
+ "bufio"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "os"
+ "path/filepath"
+ "sync"
+ "time"
+
+ "github.com/vaughan0/go-ini"
+)
+
+var currentTime = time.Now
+
+// Credentials are used to authenticate and authorize calls that you make to
+// AWS.
+type Credentials struct {
+ AccessKeyID string
+ SecretAccessKey string
+ SessionToken string
+}
+
+// A CredentialsProvider is a provider of credentials.
+type CredentialsProvider interface {
+ // Credentials returns a set of credentials (or an error if no credentials
+ // could be provided).
+ Credentials() (*Credentials, error)
+}
+
+var (
+ // ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be
+ // found in the process's environment.
+ ErrAccessKeyIDNotFound = fmt.Errorf("AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment")
+ // ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key
+ // can't be found in the process's environment.
+ ErrSecretAccessKeyNotFound = fmt.Errorf("AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment")
+)
+
+type DefaultCredentialsProvider struct {
+}
+
+func (p *DefaultCredentialsProvider) Credentials() (*Credentials, error) {
+ env, err := EnvCreds()
+ if err == nil {
+ return env.Credentials()
+ }
+
+ profile, err := ProfileCreds("", "", 10*time.Minute)
+ if err == nil {
+ profileCreds, err := profile.Credentials()
+ if err == nil {
+ return profileCreds, nil
+ }
+ }
+
+ return IAMCreds().Credentials()
+}
+
+func DefaultCreds() CredentialsProvider {
+ return &DefaultCredentialsProvider{}
+}
+
+// DetectCreds returns a CredentialsProvider based on the available information.
+//
+// If the access key ID and secret access key are provided, it returns a basic
+// provider.
+//
+// If credentials are available via environment variables, it returns an
+// environment provider.
+//
+// If a profile configuration file is available in the default location and has
+// a default profile configured, it returns a profile provider.
+//
+// Otherwise, it returns an IAM instance provider.
+func DetectCreds(accessKeyID, secretAccessKey, sessionToken string) CredentialsProvider {
+ if accessKeyID != "" && secretAccessKey != "" {
+ return Creds(accessKeyID, secretAccessKey, sessionToken)
+ }
+
+ env, err := EnvCreds()
+ if err == nil {
+ return env
+ }
+
+ profile, err := ProfileCreds("", "", 10*time.Minute)
+ if err != nil {
+ return IAMCreds()
+ }
+
+ _, err = profile.Credentials()
+ if err != nil {
+ return IAMCreds()
+ }
+
+ return profile
+}
+
+// EnvCreds returns a static provider of AWS credentials from the process's
+// environment, or an error if none are found.
+func EnvCreds() (CredentialsProvider, error) {
+ id := os.Getenv("AWS_ACCESS_KEY_ID")
+ if id == "" {
+ id = os.Getenv("AWS_ACCESS_KEY")
+ }
+
+ secret := os.Getenv("AWS_SECRET_ACCESS_KEY")
+ if secret == "" {
+ secret = os.Getenv("AWS_SECRET_KEY")
+ }
+
+ if id == "" {
+ return nil, ErrAccessKeyIDNotFound
+ }
+
+ if secret == "" {
+ return nil, ErrSecretAccessKeyNotFound
+ }
+
+ return Creds(id, secret, os.Getenv("AWS_SESSION_TOKEN")), nil
+}
+
+// Creds returns a static provider of credentials.
+func Creds(accessKeyID, secretAccessKey, sessionToken string) CredentialsProvider {
+ return staticCredentialsProvider{
+ creds: Credentials{
+ AccessKeyID: accessKeyID,
+ SecretAccessKey: secretAccessKey,
+ SessionToken: sessionToken,
+ },
+ }
+}
+
+// IAMCreds returns a provider which pulls credentials from the local EC2
+// instance's IAM roles.
+func IAMCreds() CredentialsProvider {
+ return &iamProvider{}
+}
+
+// ProfileCreds returns a provider which pulls credentials from the profile
+// configuration file.
+func ProfileCreds(filename, profile string, expiry time.Duration) (CredentialsProvider, error) {
+ if filename == "" {
+ homeDir := os.Getenv("HOME") // *nix
+ if homeDir == "" { // Windows
+ homeDir = os.Getenv("USERPROFILE")
+ }
+ if homeDir == "" {
+ return nil, errors.New("User home directory not found.")
+ }
+
+ filename = filepath.Join(homeDir, ".aws", "credentials")
+ }
+
+ if profile == "" {
+ profile = "default"
+ }
+
+ return &profileProvider{
+ filename: filename,
+ profile: profile,
+ expiry: expiry,
+ }, nil
+}
+
+type profileProvider struct {
+ filename string
+ profile string
+ expiry time.Duration
+
+ creds Credentials
+ m sync.Mutex
+ expiration time.Time
+}
+
+func (p *profileProvider) Credentials() (*Credentials, error) {
+ p.m.Lock()
+ defer p.m.Unlock()
+
+ if p.expiration.After(currentTime()) {
+ return &p.creds, nil
+ }
+
+ config, err := ini.LoadFile(p.filename)
+ if err != nil {
+ return nil, err
+ }
+ profile := config.Section(p.profile)
+
+ accessKeyID, ok := profile["aws_access_key_id"]
+ if !ok {
+ return nil, fmt.Errorf("profile %s in %s did not contain aws_access_key_id", p.profile, p.filename)
+ }
+
+ secretAccessKey, ok := profile["aws_secret_access_key"]
+ if !ok {
+ return nil, fmt.Errorf("profile %s in %s did not contain aws_secret_access_key", p.profile, p.filename)
+ }
+
+ sessionToken := profile["aws_session_token"]
+
+ p.creds = Credentials{
+ AccessKeyID: accessKeyID,
+ SecretAccessKey: secretAccessKey,
+ SessionToken: sessionToken,
+ }
+ p.expiration = currentTime().Add(p.expiry)
+
+ return &p.creds, nil
+}
+
+type iamProvider struct {
+ creds Credentials
+ m sync.Mutex
+ expiration time.Time
+}
+
+var metadataCredentialsEndpoint = "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
+
+// IAMClient is the HTTP client used to query the metadata endpoint for IAM
+// credentials.
+var IAMClient = http.Client{
+ Timeout: 1 * time.Second,
+}
+
+func (p *iamProvider) Credentials() (*Credentials, error) {
+ p.m.Lock()
+ defer p.m.Unlock()
+
+ if p.expiration.After(currentTime()) {
+ return &p.creds, nil
+ }
+
+ var body struct {
+ Expiration time.Time
+ AccessKeyID string
+ SecretAccessKey string
+ Token string
+ }
+
+ resp, err := IAMClient.Get(metadataCredentialsEndpoint)
+ if err != nil {
+ return nil, fmt.Errorf("listing IAM credentials")
+ }
+ defer func() {
+ _ = resp.Body.Close()
+ }()
+
+ // Take the first line of the body of the metadata endpoint
+ s := bufio.NewScanner(resp.Body)
+ if !s.Scan() {
+ return nil, fmt.Errorf("unable to find default IAM credentials")
+ } else if s.Err() != nil {
+ return nil, fmt.Errorf("%s listing IAM credentials", s.Err())
+ }
+
+ resp, err = IAMClient.Get(metadataCredentialsEndpoint + s.Text())
+ if err != nil {
+ return nil, fmt.Errorf("getting %s IAM credentials", s.Text())
+ }
+ defer func() {
+ _ = resp.Body.Close()
+ }()
+
+ if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
+ return nil, fmt.Errorf("decoding %s IAM credentials", s.Text())
+ }
+
+ p.creds = Credentials{
+ AccessKeyID: body.AccessKeyID,
+ SecretAccessKey: body.SecretAccessKey,
+ SessionToken: body.Token,
+ }
+ p.expiration = body.Expiration
+
+ return &p.creds, nil
+}
+
+type staticCredentialsProvider struct {
+ creds Credentials
+}
+
+func (p staticCredentialsProvider) Credentials() (*Credentials, error) {
+ return &p.creds, nil
+}