resolve.go (9086B)
1 package config 2 3 import ( 4 "context" 5 "crypto/tls" 6 "crypto/x509" 7 "fmt" 8 "io/ioutil" 9 "net/http" 10 "os" 11 12 "github.com/aws/aws-sdk-go-v2/aws" 13 awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" 14 "github.com/aws/aws-sdk-go-v2/feature/ec2/imds" 15 "github.com/aws/smithy-go/logging" 16 ) 17 18 // resolveDefaultAWSConfig will write default configuration values into the cfg 19 // value. It will write the default values, overwriting any previous value. 20 // 21 // This should be used as the first resolver in the slice of resolvers when 22 // resolving external configuration. 23 func resolveDefaultAWSConfig(ctx context.Context, cfg *aws.Config, cfgs configs) error { 24 var sources []interface{} 25 for _, s := range cfgs { 26 sources = append(sources, s) 27 } 28 29 *cfg = aws.Config{ 30 Logger: logging.NewStandardLogger(os.Stderr), 31 ConfigSources: sources, 32 } 33 return nil 34 } 35 36 // resolveCustomCABundle extracts the first instance of a custom CA bundle filename 37 // from the external configurations. It will update the HTTP Client's builder 38 // to be configured with the custom CA bundle. 39 // 40 // Config provider used: 41 // * customCABundleProvider 42 func resolveCustomCABundle(ctx context.Context, cfg *aws.Config, cfgs configs) error { 43 pemCerts, found, err := getCustomCABundle(ctx, cfgs) 44 if err != nil { 45 // TODO error handling, What is the best way to handle this? 46 // capture previous errors continue. error out if all errors 47 return err 48 } 49 if !found { 50 return nil 51 } 52 53 if cfg.HTTPClient == nil { 54 cfg.HTTPClient = awshttp.NewBuildableClient() 55 } 56 57 trOpts, ok := cfg.HTTPClient.(*awshttp.BuildableClient) 58 if !ok { 59 return fmt.Errorf("unable to add custom RootCAs HTTPClient, "+ 60 "has no WithTransportOptions, %T", cfg.HTTPClient) 61 } 62 63 var appendErr error 64 client := trOpts.WithTransportOptions(func(tr *http.Transport) { 65 if tr.TLSClientConfig == nil { 66 tr.TLSClientConfig = &tls.Config{} 67 } 68 if tr.TLSClientConfig.RootCAs == nil { 69 tr.TLSClientConfig.RootCAs = x509.NewCertPool() 70 } 71 72 b, err := ioutil.ReadAll(pemCerts) 73 if err != nil { 74 appendErr = fmt.Errorf("failed to read custom CA bundle PEM file") 75 } 76 77 if !tr.TLSClientConfig.RootCAs.AppendCertsFromPEM(b) { 78 appendErr = fmt.Errorf("failed to load custom CA bundle PEM file") 79 } 80 }) 81 if appendErr != nil { 82 return appendErr 83 } 84 85 cfg.HTTPClient = client 86 return err 87 } 88 89 // resolveRegion extracts the first instance of a Region from the configs slice. 90 // 91 // Config providers used: 92 // * regionProvider 93 func resolveRegion(ctx context.Context, cfg *aws.Config, configs configs) error { 94 v, found, err := getRegion(ctx, configs) 95 if err != nil { 96 // TODO error handling, What is the best way to handle this? 97 // capture previous errors continue. error out if all errors 98 return err 99 } 100 if !found { 101 return nil 102 } 103 104 cfg.Region = v 105 return nil 106 } 107 108 func resolveBaseEndpoint(ctx context.Context, cfg *aws.Config, configs configs) error { 109 var downcastCfgSources []interface{} 110 for _, cs := range configs { 111 downcastCfgSources = append(downcastCfgSources, interface{}(cs)) 112 } 113 114 if val, found, err := GetIgnoreConfiguredEndpoints(ctx, downcastCfgSources); found && val && err == nil { 115 cfg.BaseEndpoint = nil 116 return nil 117 } 118 119 v, found, err := getBaseEndpoint(ctx, configs) 120 if err != nil { 121 return err 122 } 123 124 if !found { 125 return nil 126 } 127 cfg.BaseEndpoint = aws.String(v) 128 return nil 129 } 130 131 // resolveAppID extracts the sdk app ID from the configs slice's SharedConfig or env var 132 func resolveAppID(ctx context.Context, cfg *aws.Config, configs configs) error { 133 ID, _, err := getAppID(ctx, configs) 134 if err != nil { 135 return err 136 } 137 138 cfg.AppID = ID 139 return nil 140 } 141 142 // resolveDisableRequestCompression extracts the DisableRequestCompression from the configs slice's 143 // SharedConfig or EnvConfig 144 func resolveDisableRequestCompression(ctx context.Context, cfg *aws.Config, configs configs) error { 145 disable, _, err := getDisableRequestCompression(ctx, configs) 146 if err != nil { 147 return err 148 } 149 150 cfg.DisableRequestCompression = disable 151 return nil 152 } 153 154 // resolveRequestMinCompressSizeBytes extracts the RequestMinCompressSizeBytes from the configs slice's 155 // SharedConfig or EnvConfig 156 func resolveRequestMinCompressSizeBytes(ctx context.Context, cfg *aws.Config, configs configs) error { 157 minBytes, found, err := getRequestMinCompressSizeBytes(ctx, configs) 158 if err != nil { 159 return err 160 } 161 // must set a default min size 10240 if not configured 162 if !found { 163 minBytes = 10240 164 } 165 cfg.RequestMinCompressSizeBytes = minBytes 166 return nil 167 } 168 169 // resolveDefaultRegion extracts the first instance of a default region and sets `aws.Config.Region` to the default 170 // region if region had not been resolved from other sources. 171 func resolveDefaultRegion(ctx context.Context, cfg *aws.Config, configs configs) error { 172 if len(cfg.Region) > 0 { 173 return nil 174 } 175 176 v, found, err := getDefaultRegion(ctx, configs) 177 if err != nil { 178 return err 179 } 180 if !found { 181 return nil 182 } 183 184 cfg.Region = v 185 186 return nil 187 } 188 189 // resolveHTTPClient extracts the first instance of a HTTPClient and sets `aws.Config.HTTPClient` to the HTTPClient instance 190 // if one has not been resolved from other sources. 191 func resolveHTTPClient(ctx context.Context, cfg *aws.Config, configs configs) error { 192 c, found, err := getHTTPClient(ctx, configs) 193 if err != nil { 194 return err 195 } 196 if !found { 197 return nil 198 } 199 200 cfg.HTTPClient = c 201 return nil 202 } 203 204 // resolveAPIOptions extracts the first instance of APIOptions and sets `aws.Config.APIOptions` to the resolved API options 205 // if one has not been resolved from other sources. 206 func resolveAPIOptions(ctx context.Context, cfg *aws.Config, configs configs) error { 207 o, found, err := getAPIOptions(ctx, configs) 208 if err != nil { 209 return err 210 } 211 if !found { 212 return nil 213 } 214 215 cfg.APIOptions = o 216 217 return nil 218 } 219 220 // resolveEndpointResolver extracts the first instance of a EndpointResolverFunc from the config slice 221 // and sets the functions result on the aws.Config.EndpointResolver 222 func resolveEndpointResolver(ctx context.Context, cfg *aws.Config, configs configs) error { 223 endpointResolver, found, err := getEndpointResolver(ctx, configs) 224 if err != nil { 225 return err 226 } 227 if !found { 228 return nil 229 } 230 231 cfg.EndpointResolver = endpointResolver 232 233 return nil 234 } 235 236 // resolveEndpointResolver extracts the first instance of a EndpointResolverFunc from the config slice 237 // and sets the functions result on the aws.Config.EndpointResolver 238 func resolveEndpointResolverWithOptions(ctx context.Context, cfg *aws.Config, configs configs) error { 239 endpointResolver, found, err := getEndpointResolverWithOptions(ctx, configs) 240 if err != nil { 241 return err 242 } 243 if !found { 244 return nil 245 } 246 247 cfg.EndpointResolverWithOptions = endpointResolver 248 249 return nil 250 } 251 252 func resolveLogger(ctx context.Context, cfg *aws.Config, configs configs) error { 253 logger, found, err := getLogger(ctx, configs) 254 if err != nil { 255 return err 256 } 257 if !found { 258 return nil 259 } 260 261 cfg.Logger = logger 262 263 return nil 264 } 265 266 func resolveClientLogMode(ctx context.Context, cfg *aws.Config, configs configs) error { 267 mode, found, err := getClientLogMode(ctx, configs) 268 if err != nil { 269 return err 270 } 271 if !found { 272 return nil 273 } 274 275 cfg.ClientLogMode = mode 276 277 return nil 278 } 279 280 func resolveRetryer(ctx context.Context, cfg *aws.Config, configs configs) error { 281 retryer, found, err := getRetryer(ctx, configs) 282 if err != nil { 283 return err 284 } 285 286 if found { 287 cfg.Retryer = retryer 288 return nil 289 } 290 291 // Only load the retry options if a custom retryer has not be specified. 292 if err = resolveRetryMaxAttempts(ctx, cfg, configs); err != nil { 293 return err 294 } 295 return resolveRetryMode(ctx, cfg, configs) 296 } 297 298 func resolveEC2IMDSRegion(ctx context.Context, cfg *aws.Config, configs configs) error { 299 if len(cfg.Region) > 0 { 300 return nil 301 } 302 303 region, found, err := getEC2IMDSRegion(ctx, configs) 304 if err != nil { 305 return err 306 } 307 if !found { 308 return nil 309 } 310 311 cfg.Region = region 312 313 return nil 314 } 315 316 func resolveDefaultsModeOptions(ctx context.Context, cfg *aws.Config, configs configs) error { 317 defaultsMode, found, err := getDefaultsMode(ctx, configs) 318 if err != nil { 319 return err 320 } 321 if !found { 322 defaultsMode = aws.DefaultsModeLegacy 323 } 324 325 var environment aws.RuntimeEnvironment 326 if defaultsMode == aws.DefaultsModeAuto { 327 envConfig, _, _ := getAWSConfigSources(configs) 328 329 client, found, err := getDefaultsModeIMDSClient(ctx, configs) 330 if err != nil { 331 return err 332 } 333 if !found { 334 client = imds.NewFromConfig(*cfg) 335 } 336 337 environment, err = resolveDefaultsModeRuntimeEnvironment(ctx, envConfig, client) 338 if err != nil { 339 return err 340 } 341 } 342 343 cfg.DefaultsMode = defaultsMode 344 cfg.RuntimeEnvironment = environment 345 346 return nil 347 } 348 349 func resolveRetryMaxAttempts(ctx context.Context, cfg *aws.Config, configs configs) error { 350 maxAttempts, found, err := getRetryMaxAttempts(ctx, configs) 351 if err != nil || !found { 352 return err 353 } 354 cfg.RetryMaxAttempts = maxAttempts 355 356 return nil 357 } 358 359 func resolveRetryMode(ctx context.Context, cfg *aws.Config, configs configs) error { 360 retryMode, found, err := getRetryMode(ctx, configs) 361 if err != nil || !found { 362 return err 363 } 364 cfg.RetryMode = retryMode 365 366 return nil 367 }