github.com/aavshr/aws-sdk-go@v1.41.3/aws/defaults/defaults.go (about) 1 // Package defaults is a collection of helpers to retrieve the SDK's default 2 // configuration and handlers. 3 // 4 // Generally this package shouldn't be used directly, but session.Session 5 // instead. This package is useful when you need to reset the defaults 6 // of a session or service client to the SDK defaults before setting 7 // additional parameters. 8 package defaults 9 10 import ( 11 "fmt" 12 "net" 13 "net/http" 14 "net/url" 15 "os" 16 "time" 17 18 "github.com/aavshr/aws-sdk-go/aws" 19 "github.com/aavshr/aws-sdk-go/aws/awserr" 20 "github.com/aavshr/aws-sdk-go/aws/corehandlers" 21 "github.com/aavshr/aws-sdk-go/aws/credentials" 22 "github.com/aavshr/aws-sdk-go/aws/credentials/ec2rolecreds" 23 "github.com/aavshr/aws-sdk-go/aws/credentials/endpointcreds" 24 "github.com/aavshr/aws-sdk-go/aws/ec2metadata" 25 "github.com/aavshr/aws-sdk-go/aws/endpoints" 26 "github.com/aavshr/aws-sdk-go/aws/request" 27 "github.com/aavshr/aws-sdk-go/internal/shareddefaults" 28 ) 29 30 // A Defaults provides a collection of default values for SDK clients. 31 type Defaults struct { 32 Config *aws.Config 33 Handlers request.Handlers 34 } 35 36 // Get returns the SDK's default values with Config and handlers pre-configured. 37 func Get() Defaults { 38 cfg := Config() 39 handlers := Handlers() 40 cfg.Credentials = CredChain(cfg, handlers) 41 42 return Defaults{ 43 Config: cfg, 44 Handlers: handlers, 45 } 46 } 47 48 // Config returns the default configuration without credentials. 49 // To retrieve a config with credentials also included use 50 // `defaults.Get().Config` instead. 51 // 52 // Generally you shouldn't need to use this method directly, but 53 // is available if you need to reset the configuration of an 54 // existing service client or session. 55 func Config() *aws.Config { 56 return aws.NewConfig(). 57 WithCredentials(credentials.AnonymousCredentials). 58 WithRegion(os.Getenv("AWS_REGION")). 59 WithHTTPClient(http.DefaultClient). 60 WithMaxRetries(aws.UseServiceDefaultRetries). 61 WithLogger(aws.NewDefaultLogger()). 62 WithLogLevel(aws.LogOff). 63 WithEndpointResolver(endpoints.DefaultResolver()) 64 } 65 66 // Handlers returns the default request handlers. 67 // 68 // Generally you shouldn't need to use this method directly, but 69 // is available if you need to reset the request handlers of an 70 // existing service client or session. 71 func Handlers() request.Handlers { 72 var handlers request.Handlers 73 74 handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler) 75 handlers.Validate.AfterEachFn = request.HandlerListStopOnError 76 handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler) 77 handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHander) 78 handlers.Build.AfterEachFn = request.HandlerListStopOnError 79 handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler) 80 handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler) 81 handlers.Send.PushBackNamed(corehandlers.SendHandler) 82 handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) 83 handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler) 84 85 return handlers 86 } 87 88 // CredChain returns the default credential chain. 89 // 90 // Generally you shouldn't need to use this method directly, but 91 // is available if you need to reset the credentials of an 92 // existing service client or session's Config. 93 func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials { 94 return credentials.NewCredentials(&credentials.ChainProvider{ 95 VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), 96 Providers: CredProviders(cfg, handlers), 97 }) 98 } 99 100 // CredProviders returns the slice of providers used in 101 // the default credential chain. 102 // 103 // For applications that need to use some other provider (for example use 104 // different environment variables for legacy reasons) but still fall back 105 // on the default chain of providers. This allows that default chaint to be 106 // automatically updated 107 func CredProviders(cfg *aws.Config, handlers request.Handlers) []credentials.Provider { 108 return []credentials.Provider{ 109 &credentials.EnvProvider{}, 110 &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, 111 RemoteCredProvider(*cfg, handlers), 112 } 113 } 114 115 const ( 116 httpProviderAuthorizationEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN" 117 httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI" 118 ) 119 120 // RemoteCredProvider returns a credentials provider for the default remote 121 // endpoints such as EC2 or ECS Roles. 122 func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { 123 if u := os.Getenv(httpProviderEnvVar); len(u) > 0 { 124 return localHTTPCredProvider(cfg, handlers, u) 125 } 126 127 if uri := os.Getenv(shareddefaults.ECSCredsProviderEnvVar); len(uri) > 0 { 128 u := fmt.Sprintf("%s%s", shareddefaults.ECSContainerCredentialsURI, uri) 129 return httpCredProvider(cfg, handlers, u) 130 } 131 132 return ec2RoleProvider(cfg, handlers) 133 } 134 135 var lookupHostFn = net.LookupHost 136 137 func isLoopbackHost(host string) (bool, error) { 138 ip := net.ParseIP(host) 139 if ip != nil { 140 return ip.IsLoopback(), nil 141 } 142 143 // Host is not an ip, perform lookup 144 addrs, err := lookupHostFn(host) 145 if err != nil { 146 return false, err 147 } 148 for _, addr := range addrs { 149 if !net.ParseIP(addr).IsLoopback() { 150 return false, nil 151 } 152 } 153 154 return true, nil 155 } 156 157 func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { 158 var errMsg string 159 160 parsed, err := url.Parse(u) 161 if err != nil { 162 errMsg = fmt.Sprintf("invalid URL, %v", err) 163 } else { 164 host := aws.URLHostname(parsed) 165 if len(host) == 0 { 166 errMsg = "unable to parse host from local HTTP cred provider URL" 167 } else if isLoopback, loopbackErr := isLoopbackHost(host); loopbackErr != nil { 168 errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, loopbackErr) 169 } else if !isLoopback { 170 errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback hosts are allowed.", host) 171 } 172 } 173 174 if len(errMsg) > 0 { 175 if cfg.Logger != nil { 176 cfg.Logger.Log("Ignoring, HTTP credential provider", errMsg, err) 177 } 178 return credentials.ErrorProvider{ 179 Err: awserr.New("CredentialsEndpointError", errMsg, err), 180 ProviderName: endpointcreds.ProviderName, 181 } 182 } 183 184 return httpCredProvider(cfg, handlers, u) 185 } 186 187 func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { 188 return endpointcreds.NewProviderClient(cfg, handlers, u, 189 func(p *endpointcreds.Provider) { 190 p.ExpiryWindow = 5 * time.Minute 191 p.AuthorizationToken = os.Getenv(httpProviderAuthorizationEnvVar) 192 }, 193 ) 194 } 195 196 func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { 197 resolver := cfg.EndpointResolver 198 if resolver == nil { 199 resolver = endpoints.DefaultResolver() 200 } 201 202 e, _ := resolver.EndpointFor(endpoints.Ec2metadataServiceID, "") 203 return &ec2rolecreds.EC2RoleProvider{ 204 Client: ec2metadata.NewClient(cfg, handlers, e.URL, e.SigningRegion), 205 ExpiryWindow: 5 * time.Minute, 206 } 207 }