1package awsutil 2 3import ( 4 "fmt" 5 "net/http" 6 7 "github.com/aws/aws-sdk-go/aws" 8 "github.com/aws/aws-sdk-go/aws/credentials" 9 "github.com/aws/aws-sdk-go/aws/defaults" 10) 11 12type CredentialsConfig struct { 13 // The access key if static credentials are being used 14 AccessKey string 15 16 // The secret key if static credentials are being used 17 SecretKey string 18 19 // The session token if it is being used 20 SessionToken string 21 22 // If specified, the region will be provided to the config of the 23 // EC2RoleProvider's client. This may be useful if you want to e.g. reuse 24 // the client elsewhere. 25 Region string 26 27 // The filename for the shared credentials provider, if being used 28 Filename string 29 30 // The profile for the shared credentials provider, if being used 31 Profile string 32 33 // The http.Client to use, or nil for the client to use its default 34 HTTPClient *http.Client 35} 36 37func (c *CredentialsConfig) GenerateCredentialChain() (*credentials.Credentials, error) { 38 var providers []credentials.Provider 39 40 switch { 41 case c.AccessKey != "" && c.SecretKey != "": 42 // Add the static credential provider 43 providers = append(providers, &credentials.StaticProvider{ 44 Value: credentials.Value{ 45 AccessKeyID: c.AccessKey, 46 SecretAccessKey: c.SecretKey, 47 SessionToken: c.SessionToken, 48 }}) 49 case c.AccessKey == "" && c.SecretKey == "": 50 // Attempt to get credentials from the IAM instance role below 51 52 default: // Have one or the other but not both and not neither 53 return nil, fmt.Errorf( 54 "static AWS client credentials haven't been properly configured (the access key or secret key were provided but not both)") 55 } 56 57 // Add the environment credential provider 58 providers = append(providers, &credentials.EnvProvider{}) 59 60 // Add the shared credentials provider 61 providers = append(providers, &credentials.SharedCredentialsProvider{ 62 Filename: c.Filename, 63 Profile: c.Profile, 64 }) 65 66 // Add the remote provider 67 def := defaults.Get() 68 if c.Region != "" { 69 def.Config.Region = aws.String(c.Region) 70 } 71 if c.HTTPClient != nil { 72 def.Config.HTTPClient = c.HTTPClient 73 } 74 75 providers = append(providers, defaults.RemoteCredProvider(*def.Config, def.Handlers)) 76 77 // Create the credentials required to access the API. 78 creds := credentials.NewChainCredentials(providers) 79 if creds == nil { 80 return nil, fmt.Errorf("could not compile valid credential providers from static config, environment, shared, or instance metadata") 81 } 82 83 return creds, nil 84} 85