summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/aws/aws-sdk-go/aws/session/session.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go/aws/session/session.go')
-rw-r--r--vendor/github.com/aws/aws-sdk-go/aws/session/session.go363
1 files changed, 217 insertions, 146 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go
index 51f305563..15fa64769 100644
--- a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go
+++ b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go
@@ -8,19 +8,36 @@ import (
"io/ioutil"
"net/http"
"os"
+ "time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/credentials"
- "github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/csm"
"github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request"
)
+const (
+ // ErrCodeSharedConfig represents an error that occurs in the shared
+ // configuration logic
+ ErrCodeSharedConfig = "SharedConfigErr"
+)
+
+// ErrSharedConfigSourceCollision will be returned if a section contains both
+// source_profile and credential_source
+var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only source profile or credential source can be specified, not both", nil)
+
+// ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment
+// variables are empty and Environment was set as the credential source
+var ErrSharedConfigECSContainerEnvVarEmpty = awserr.New(ErrCodeSharedConfig, "EcsContainer was specified as the credential_source, but 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' was not set", nil)
+
+// ErrSharedConfigInvalidCredSource will be returned if an invalid credential source was provided
+var ErrSharedConfigInvalidCredSource = awserr.New(ErrCodeSharedConfig, "credential source values must be EcsContainer, Ec2InstanceMetadata, or Environment", nil)
+
// A Session provides a central location to create service clients from and
// store configurations and request handlers for those services.
//
@@ -56,7 +73,7 @@ type Session struct {
// func is called instead of waiting to receive an error until a request is made.
func New(cfgs ...*aws.Config) *Session {
// load initial config from environment
- envCfg := loadEnvConfig()
+ envCfg, envErr := loadEnvConfig()
if envCfg.EnableSharedConfig {
var cfg aws.Config
@@ -76,19 +93,28 @@ func New(cfgs ...*aws.Config) *Session {
// Session creation failed, need to report the error and prevent
// any requests from succeeding.
s = &Session{Config: defaults.Config()}
- s.Config.MergeIn(cfgs...)
- s.Config.Logger.Log("ERROR:", msg, "Error:", err)
- s.Handlers.Validate.PushBack(func(r *request.Request) {
- r.Error = err
- })
+ s.logDeprecatedNewSessionError(msg, err, cfgs)
}
return s
}
s := deprecatedNewSession(cfgs...)
- if envCfg.CSMEnabled {
- enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger)
+ if envErr != nil {
+ msg := "failed to load env config"
+ s.logDeprecatedNewSessionError(msg, envErr, cfgs)
+ }
+
+ if csmCfg, err := loadCSMConfig(envCfg, []string{}); err != nil {
+ if l := s.Config.Logger; l != nil {
+ l.Log(fmt.Sprintf("ERROR: failed to load CSM configuration, %v", err))
+ }
+ } else if csmCfg.Enabled {
+ err := enableCSM(&s.Handlers, csmCfg, s.Config.Logger)
+ if err != nil {
+ msg := "failed to enable CSM"
+ s.logDeprecatedNewSessionError(msg, err, cfgs)
+ }
}
return s
@@ -107,7 +133,7 @@ func New(cfgs ...*aws.Config) *Session {
// to be built with retrieving credentials with AssumeRole set in the config.
//
// See the NewSessionWithOptions func for information on how to override or
-// control through code how the Session will be created. Such as specifying the
+// control through code how the Session will be created, such as specifying the
// config profile, and controlling if shared config is enabled or not.
func NewSession(cfgs ...*aws.Config) (*Session, error) {
opts := Options{}
@@ -191,6 +217,12 @@ type Options struct {
// the config enables assume role wit MFA via the mfa_serial field.
AssumeRoleTokenProvider func() (string, error)
+ // When the SDK's shared config is configured to assume a role this option
+ // may be provided to set the expiry duration of the STS credentials.
+ // Defaults to 15 minutes if not set as documented in the
+ // stscreds.AssumeRoleProvider.
+ AssumeRoleDuration time.Duration
+
// Reader for a custom Credentials Authority (CA) bundle in PEM format that
// the SDK will use instead of the default system's root CA bundle. Use this
// only if you want to replace the CA bundle the SDK uses for TLS requests.
@@ -205,6 +237,12 @@ type Options struct {
// to also enable this feature. CustomCABundle session option field has priority
// over the AWS_CA_BUNDLE environment variable, and will be used if both are set.
CustomCABundle io.Reader
+
+ // The handlers that the session and all API clients will be created with.
+ // This must be a complete set of handlers. Use the defaults.Handlers()
+ // function to initialize this value before changing the handlers to be
+ // used by the SDK.
+ Handlers request.Handlers
}
// NewSessionWithOptions returns a new Session created from SDK defaults, config files,
@@ -238,13 +276,20 @@ type Options struct {
// }))
func NewSessionWithOptions(opts Options) (*Session, error) {
var envCfg envConfig
+ var err error
if opts.SharedConfigState == SharedConfigEnable {
- envCfg = loadSharedEnvConfig()
+ envCfg, err = loadSharedEnvConfig()
+ if err != nil {
+ return nil, fmt.Errorf("failed to load shared config, %v", err)
+ }
} else {
- envCfg = loadEnvConfig()
+ envCfg, err = loadEnvConfig()
+ if err != nil {
+ return nil, fmt.Errorf("failed to load environment config, %v", err)
+ }
}
- if len(opts.Profile) > 0 {
+ if len(opts.Profile) != 0 {
envCfg.Profile = opts.Profile
}
@@ -310,27 +355,33 @@ func deprecatedNewSession(cfgs ...*aws.Config) *Session {
return s
}
-func enableCSM(handlers *request.Handlers, clientID string, port string, logger aws.Logger) {
- logger.Log("Enabling CSM")
- if len(port) == 0 {
- port = csm.DefaultPort
+func enableCSM(handlers *request.Handlers, cfg csmConfig, logger aws.Logger) error {
+ if logger != nil {
+ logger.Log("Enabling CSM")
}
- r, err := csm.Start(clientID, "127.0.0.1:"+port)
+ r, err := csm.Start(cfg.ClientID, csm.AddressWithDefaults(cfg.Host, cfg.Port))
if err != nil {
- return
+ return err
}
r.InjectHandlers(handlers)
+
+ return nil
}
func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) {
cfg := defaults.Config()
- handlers := defaults.Handlers()
+
+ handlers := opts.Handlers
+ if handlers.IsEmpty() {
+ handlers = defaults.Handlers()
+ }
// Get a merged version of the user provided config to determine if
// credentials were.
userCfg := &aws.Config{}
userCfg.MergeIn(cfgs...)
+ cfg.MergeIn(userCfg)
// Ordered config files will be loaded in with later files overwriting
// previous config file values.
@@ -347,9 +398,17 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
}
// Load additional config from file(s)
- sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles)
+ sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles, envCfg.EnableSharedConfig)
if err != nil {
- return nil, err
+ if len(envCfg.Profile) == 0 && !envCfg.EnableSharedConfig && (envCfg.Creds.HasKeys() || userCfg.Credentials != nil) {
+ // Special case where the user has not explicitly specified an AWS_PROFILE,
+ // or session.Options.profile, shared config is not enabled, and the
+ // environment has credentials, allow the shared config file to fail to
+ // load since the user has already provided credentials, and nothing else
+ // is required to be read file. Github(aws/aws-sdk-go#2455)
+ } else if _, ok := err.(SharedConfigProfileNotExistsError); !ok {
+ return nil, err
+ }
}
if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil {
@@ -362,8 +421,16 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
}
initHandlers(s)
- if envCfg.CSMEnabled {
- enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger)
+
+ if csmCfg, err := loadCSMConfig(envCfg, cfgFiles); err != nil {
+ if l := s.Config.Logger; l != nil {
+ l.Log(fmt.Sprintf("ERROR: failed to load CSM configuration, %v", err))
+ }
+ } else if csmCfg.Enabled {
+ err = enableCSM(&s.Handlers, csmCfg, s.Config.Logger)
+ if err != nil {
+ return nil, err
+ }
}
// Setup HTTP client with custom cert bundle if enabled
@@ -376,6 +443,46 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
return s, nil
}
+type csmConfig struct {
+ Enabled bool
+ Host string
+ Port string
+ ClientID string
+}
+
+var csmProfileName = "aws_csm"
+
+func loadCSMConfig(envCfg envConfig, cfgFiles []string) (csmConfig, error) {
+ if envCfg.CSMEnabled != nil {
+ if *envCfg.CSMEnabled {
+ return csmConfig{
+ Enabled: true,
+ ClientID: envCfg.CSMClientID,
+ Host: envCfg.CSMHost,
+ Port: envCfg.CSMPort,
+ }, nil
+ }
+ return csmConfig{}, nil
+ }
+
+ sharedCfg, err := loadSharedConfig(csmProfileName, cfgFiles, false)
+ if err != nil {
+ if _, ok := err.(SharedConfigProfileNotExistsError); !ok {
+ return csmConfig{}, err
+ }
+ }
+ if sharedCfg.CSMEnabled != nil && *sharedCfg.CSMEnabled == true {
+ return csmConfig{
+ Enabled: true,
+ ClientID: sharedCfg.CSMClientID,
+ Host: sharedCfg.CSMHost,
+ Port: sharedCfg.CSMPort,
+ }, nil
+ }
+
+ return csmConfig{}, nil
+}
+
func loadCustomCABundle(s *Session, bundle io.Reader) error {
var t *http.Transport
switch v := s.Config.HTTPClient.Transport.(type) {
@@ -388,7 +495,10 @@ func loadCustomCABundle(s *Session, bundle io.Reader) error {
}
}
if t == nil {
- t = &http.Transport{}
+ // Nil transport implies `http.DefaultTransport` should be used. Since
+ // the SDK cannot modify, nor copy the `DefaultTransport` specifying
+ // the values the next closest behavior.
+ t = getCABundleTransport()
}
p, err := loadCertPool(bundle)
@@ -421,9 +531,11 @@ func loadCertPool(r io.Reader) (*x509.CertPool, error) {
return p, nil
}
-func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers, sessOpts Options) error {
- // Merge in user provided configuration
- cfg.MergeIn(userCfg)
+func mergeConfigSrcs(cfg, userCfg *aws.Config,
+ envCfg envConfig, sharedCfg sharedConfig,
+ handlers request.Handlers,
+ sessOpts Options,
+) error {
// Region if not already set by user
if len(aws.StringValue(cfg.Region)) == 0 {
@@ -434,101 +546,44 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg share
}
}
- // Configure credentials if not already set
- if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
- if len(envCfg.Creds.AccessKeyID) > 0 {
- cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
- envCfg.Creds,
- )
- } else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil {
- cfgCp := *cfg
- cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds(
- sharedCfg.AssumeRoleSource.Creds,
- )
- if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
- // AssumeRole Token provider is required if doing Assume Role
- // with MFA.
- return AssumeRoleTokenProviderNotSetError{}
- }
- cfg.Credentials = stscreds.NewCredentials(
- &Session{
- Config: &cfgCp,
- Handlers: handlers.Copy(),
- },
- sharedCfg.AssumeRole.RoleARN,
- func(opt *stscreds.AssumeRoleProvider) {
- opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName
-
- // Assume role with external ID
- if len(sharedCfg.AssumeRole.ExternalID) > 0 {
- opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID)
- }
-
- // Assume role with MFA
- if len(sharedCfg.AssumeRole.MFASerial) > 0 {
- opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial)
- opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
- }
- },
- )
- } else if len(sharedCfg.Creds.AccessKeyID) > 0 {
- cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
- sharedCfg.Creds,
- )
- } else {
- // Fallback to default credentials provider, include mock errors
- // for the credential chain so user can identify why credentials
- // failed to be retrieved.
- cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{
- VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
- Providers: []credentials.Provider{
- &credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)},
- &credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)},
- defaults.RemoteCredProvider(*cfg, handlers),
- },
- })
+ if cfg.EnableEndpointDiscovery == nil {
+ if envCfg.EnableEndpointDiscovery != nil {
+ cfg.WithEndpointDiscovery(*envCfg.EnableEndpointDiscovery)
+ } else if envCfg.EnableSharedConfig && sharedCfg.EnableEndpointDiscovery != nil {
+ cfg.WithEndpointDiscovery(*sharedCfg.EnableEndpointDiscovery)
}
}
- return nil
-}
+ // Regional Endpoint flag for STS endpoint resolving
+ mergeSTSRegionalEndpointConfig(cfg, envCfg, sharedCfg)
-// AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the
-// MFAToken option is not set when shared config is configured load assume a
-// role with an MFA token.
-type AssumeRoleTokenProviderNotSetError struct{}
-
-// Code is the short id of the error.
-func (e AssumeRoleTokenProviderNotSetError) Code() string {
- return "AssumeRoleTokenProviderNotSetError"
-}
-
-// Message is the description of the error
-func (e AssumeRoleTokenProviderNotSetError) Message() string {
- return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.")
-}
+ // Configure credentials if not already set by the user when creating the
+ // Session.
+ if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
+ creds, err := resolveCredentials(cfg, envCfg, sharedCfg, handlers, sessOpts)
+ if err != nil {
+ return err
+ }
+ cfg.Credentials = creds
+ }
-// OrigErr is the underlying error that caused the failure.
-func (e AssumeRoleTokenProviderNotSetError) OrigErr() error {
return nil
}
-// Error satisfies the error interface.
-func (e AssumeRoleTokenProviderNotSetError) Error() string {
- return awserr.SprintError(e.Code(), e.Message(), "", nil)
-}
+// mergeSTSRegionalEndpointConfig function merges the STSRegionalEndpoint into cfg from
+// envConfig and SharedConfig with envConfig being given precedence over SharedConfig
+func mergeSTSRegionalEndpointConfig(cfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig) error {
-type credProviderError struct {
- Err error
-}
+ cfg.STSRegionalEndpoint = envCfg.STSRegionalEndpoint
-var emptyCreds = credentials.Value{}
+ if cfg.STSRegionalEndpoint == endpoints.UnsetSTSEndpoint {
+ cfg.STSRegionalEndpoint = sharedCfg.STSRegionalEndpoint
+ }
-func (c credProviderError) Retrieve() (credentials.Value, error) {
- return credentials.Value{}, c.Err
-}
-func (c credProviderError) IsExpired() bool {
- return true
+ if cfg.STSRegionalEndpoint == endpoints.UnsetSTSEndpoint {
+ cfg.STSRegionalEndpoint = endpoints.LegacySTSEndpoint
+ }
+ return nil
}
func initHandlers(s *Session) {
@@ -539,7 +594,7 @@ func initHandlers(s *Session) {
}
}
-// Copy creates and returns a copy of the current Session, coping the config
+// Copy creates and returns a copy of the current Session, copying the config
// and handlers. If any additional configs are provided they will be merged
// on top of the Session's copied config.
//
@@ -559,37 +614,15 @@ func (s *Session) Copy(cfgs ...*aws.Config) *Session {
// ClientConfig satisfies the client.ConfigProvider interface and is used to
// configure the service client instances. Passing the Session to the service
// client's constructor (New) will use this method to configure the client.
-func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
- // Backwards compatibility, the error will be eaten if user calls ClientConfig
- // directly. All SDK services will use ClientconfigWithError.
- cfg, _ := s.clientConfigWithErr(serviceName, cfgs...)
-
- return cfg
-}
-
-func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (client.Config, error) {
+func (s *Session) ClientConfig(service string, cfgs ...*aws.Config) client.Config {
s = s.Copy(cfgs...)
- var resolved endpoints.ResolvedEndpoint
- var err error
-
region := aws.StringValue(s.Config.Region)
-
- if endpoint := aws.StringValue(s.Config.Endpoint); len(endpoint) != 0 {
- resolved.URL = endpoints.AddScheme(endpoint, aws.BoolValue(s.Config.DisableSSL))
- resolved.SigningRegion = region
- } else {
- resolved, err = s.Config.EndpointResolver.EndpointFor(
- serviceName, region,
- func(opt *endpoints.Options) {
- opt.DisableSSL = aws.BoolValue(s.Config.DisableSSL)
- opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack)
-
- // Support the condition where the service is modeled but its
- // endpoint metadata is not available.
- opt.ResolveUnknownService = true
- },
- )
+ resolved, err := s.resolveEndpoint(service, region, s.Config)
+ if err != nil && s.Config.Logger != nil {
+ s.Config.Logger.Log(fmt.Sprintf(
+ "ERROR: unable to resolve endpoint for service %q, region %q, err: %v",
+ service, region, err))
}
return client.Config{
@@ -599,7 +632,37 @@ func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (
SigningRegion: resolved.SigningRegion,
SigningNameDerived: resolved.SigningNameDerived,
SigningName: resolved.SigningName,
- }, err
+ }
+}
+
+func (s *Session) resolveEndpoint(service, region string, cfg *aws.Config) (endpoints.ResolvedEndpoint, error) {
+
+ if ep := aws.StringValue(cfg.Endpoint); len(ep) != 0 {
+ return endpoints.ResolvedEndpoint{
+ URL: endpoints.AddScheme(ep, aws.BoolValue(cfg.DisableSSL)),
+ SigningRegion: region,
+ }, nil
+ }
+
+ resolved, err := cfg.EndpointResolver.EndpointFor(service, region,
+ func(opt *endpoints.Options) {
+ opt.DisableSSL = aws.BoolValue(cfg.DisableSSL)
+ opt.UseDualStack = aws.BoolValue(cfg.UseDualStack)
+ // Support for STSRegionalEndpoint where the STSRegionalEndpoint is
+ // provided in envConfig or sharedConfig with envConfig getting
+ // precedence.
+ opt.STSRegionalEndpoint = cfg.STSRegionalEndpoint
+
+ // Support the condition where the service is modeled but its
+ // endpoint metadata is not available.
+ opt.ResolveUnknownService = true
+ },
+ )
+ if err != nil {
+ return endpoints.ResolvedEndpoint{}, err
+ }
+
+ return resolved, nil
}
// ClientConfigNoResolveEndpoint is the same as ClientConfig with the exception
@@ -609,12 +672,9 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf
s = s.Copy(cfgs...)
var resolved endpoints.ResolvedEndpoint
-
- region := aws.StringValue(s.Config.Region)
-
if ep := aws.StringValue(s.Config.Endpoint); len(ep) > 0 {
resolved.URL = endpoints.AddScheme(ep, aws.BoolValue(s.Config.DisableSSL))
- resolved.SigningRegion = region
+ resolved.SigningRegion = aws.StringValue(s.Config.Region)
}
return client.Config{
@@ -626,3 +686,14 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf
SigningName: resolved.SigningName,
}
}
+
+// logDeprecatedNewSessionError function enables error handling for session
+func (s *Session) logDeprecatedNewSessionError(msg string, err error, cfgs []*aws.Config) {
+ // Session creation failed, need to report the error and prevent
+ // any requests from succeeding.
+ s.Config.MergeIn(cfgs...)
+ s.Config.Logger.Log("ERROR:", msg, "Error:", err)
+ s.Handlers.Validate.PushBack(func(r *request.Request) {
+ r.Error = err
+ })
+}