src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

resolve.go (11205B)


      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 // resolveAccountIDEndpointMode extracts the AccountIDEndpointMode from the configs slice's
    170 // SharedConfig or EnvConfig
    171 func resolveAccountIDEndpointMode(ctx context.Context, cfg *aws.Config, configs configs) error {
    172 	m, found, err := getAccountIDEndpointMode(ctx, configs)
    173 	if err != nil {
    174 		return err
    175 	}
    176 
    177 	if !found {
    178 		m = aws.AccountIDEndpointModePreferred
    179 	}
    180 
    181 	cfg.AccountIDEndpointMode = m
    182 	return nil
    183 }
    184 
    185 // resolveRequestChecksumCalculation extracts the RequestChecksumCalculation from the configs slice's
    186 // SharedConfig or EnvConfig
    187 func resolveRequestChecksumCalculation(ctx context.Context, cfg *aws.Config, configs configs) error {
    188 	c, found, err := getRequestChecksumCalculation(ctx, configs)
    189 	if err != nil {
    190 		return err
    191 	}
    192 
    193 	if !found {
    194 		c = aws.RequestChecksumCalculationWhenSupported
    195 	}
    196 	cfg.RequestChecksumCalculation = c
    197 	return nil
    198 }
    199 
    200 // resolveResponseValidation extracts the ResponseChecksumValidation from the configs slice's
    201 // SharedConfig or EnvConfig
    202 func resolveResponseChecksumValidation(ctx context.Context, cfg *aws.Config, configs configs) error {
    203 	c, found, err := getResponseChecksumValidation(ctx, configs)
    204 	if err != nil {
    205 		return err
    206 	}
    207 
    208 	if !found {
    209 		c = aws.ResponseChecksumValidationWhenSupported
    210 	}
    211 	cfg.ResponseChecksumValidation = c
    212 	return nil
    213 }
    214 
    215 // resolveDefaultRegion extracts the first instance of a default region and sets `aws.Config.Region` to the default
    216 // region if region had not been resolved from other sources.
    217 func resolveDefaultRegion(ctx context.Context, cfg *aws.Config, configs configs) error {
    218 	if len(cfg.Region) > 0 {
    219 		return nil
    220 	}
    221 
    222 	v, found, err := getDefaultRegion(ctx, configs)
    223 	if err != nil {
    224 		return err
    225 	}
    226 	if !found {
    227 		return nil
    228 	}
    229 
    230 	cfg.Region = v
    231 
    232 	return nil
    233 }
    234 
    235 // resolveHTTPClient extracts the first instance of a HTTPClient and sets `aws.Config.HTTPClient` to the HTTPClient instance
    236 // if one has not been resolved from other sources.
    237 func resolveHTTPClient(ctx context.Context, cfg *aws.Config, configs configs) error {
    238 	c, found, err := getHTTPClient(ctx, configs)
    239 	if err != nil {
    240 		return err
    241 	}
    242 	if !found {
    243 		return nil
    244 	}
    245 
    246 	cfg.HTTPClient = c
    247 	return nil
    248 }
    249 
    250 // resolveAPIOptions extracts the first instance of APIOptions and sets `aws.Config.APIOptions` to the resolved API options
    251 // if one has not been resolved from other sources.
    252 func resolveAPIOptions(ctx context.Context, cfg *aws.Config, configs configs) error {
    253 	o, found, err := getAPIOptions(ctx, configs)
    254 	if err != nil {
    255 		return err
    256 	}
    257 	if !found {
    258 		return nil
    259 	}
    260 
    261 	cfg.APIOptions = o
    262 
    263 	return nil
    264 }
    265 
    266 // resolveEndpointResolver extracts the first instance of a EndpointResolverFunc from the config slice
    267 // and sets the functions result on the aws.Config.EndpointResolver
    268 func resolveEndpointResolver(ctx context.Context, cfg *aws.Config, configs configs) error {
    269 	endpointResolver, found, err := getEndpointResolver(ctx, configs)
    270 	if err != nil {
    271 		return err
    272 	}
    273 	if !found {
    274 		return nil
    275 	}
    276 
    277 	cfg.EndpointResolver = endpointResolver
    278 
    279 	return nil
    280 }
    281 
    282 // resolveEndpointResolver extracts the first instance of a EndpointResolverFunc from the config slice
    283 // and sets the functions result on the aws.Config.EndpointResolver
    284 func resolveEndpointResolverWithOptions(ctx context.Context, cfg *aws.Config, configs configs) error {
    285 	endpointResolver, found, err := getEndpointResolverWithOptions(ctx, configs)
    286 	if err != nil {
    287 		return err
    288 	}
    289 	if !found {
    290 		return nil
    291 	}
    292 
    293 	cfg.EndpointResolverWithOptions = endpointResolver
    294 
    295 	return nil
    296 }
    297 
    298 func resolveLogger(ctx context.Context, cfg *aws.Config, configs configs) error {
    299 	logger, found, err := getLogger(ctx, configs)
    300 	if err != nil {
    301 		return err
    302 	}
    303 	if !found {
    304 		return nil
    305 	}
    306 
    307 	cfg.Logger = logger
    308 
    309 	return nil
    310 }
    311 
    312 func resolveClientLogMode(ctx context.Context, cfg *aws.Config, configs configs) error {
    313 	mode, found, err := getClientLogMode(ctx, configs)
    314 	if err != nil {
    315 		return err
    316 	}
    317 	if !found {
    318 		return nil
    319 	}
    320 
    321 	cfg.ClientLogMode = mode
    322 
    323 	return nil
    324 }
    325 
    326 func resolveRetryer(ctx context.Context, cfg *aws.Config, configs configs) error {
    327 	retryer, found, err := getRetryer(ctx, configs)
    328 	if err != nil {
    329 		return err
    330 	}
    331 
    332 	if found {
    333 		cfg.Retryer = retryer
    334 		return nil
    335 	}
    336 
    337 	// Only load the retry options if a custom retryer has not be specified.
    338 	if err = resolveRetryMaxAttempts(ctx, cfg, configs); err != nil {
    339 		return err
    340 	}
    341 	return resolveRetryMode(ctx, cfg, configs)
    342 }
    343 
    344 func resolveEC2IMDSRegion(ctx context.Context, cfg *aws.Config, configs configs) error {
    345 	if len(cfg.Region) > 0 {
    346 		return nil
    347 	}
    348 
    349 	region, found, err := getEC2IMDSRegion(ctx, configs)
    350 	if err != nil {
    351 		return err
    352 	}
    353 	if !found {
    354 		return nil
    355 	}
    356 
    357 	cfg.Region = region
    358 
    359 	return nil
    360 }
    361 
    362 func resolveDefaultsModeOptions(ctx context.Context, cfg *aws.Config, configs configs) error {
    363 	defaultsMode, found, err := getDefaultsMode(ctx, configs)
    364 	if err != nil {
    365 		return err
    366 	}
    367 	if !found {
    368 		defaultsMode = aws.DefaultsModeLegacy
    369 	}
    370 
    371 	var environment aws.RuntimeEnvironment
    372 	if defaultsMode == aws.DefaultsModeAuto {
    373 		envConfig, _, _ := getAWSConfigSources(configs)
    374 
    375 		client, found, err := getDefaultsModeIMDSClient(ctx, configs)
    376 		if err != nil {
    377 			return err
    378 		}
    379 		if !found {
    380 			client = imds.NewFromConfig(*cfg)
    381 		}
    382 
    383 		environment, err = resolveDefaultsModeRuntimeEnvironment(ctx, envConfig, client)
    384 		if err != nil {
    385 			return err
    386 		}
    387 	}
    388 
    389 	cfg.DefaultsMode = defaultsMode
    390 	cfg.RuntimeEnvironment = environment
    391 
    392 	return nil
    393 }
    394 
    395 func resolveRetryMaxAttempts(ctx context.Context, cfg *aws.Config, configs configs) error {
    396 	maxAttempts, found, err := getRetryMaxAttempts(ctx, configs)
    397 	if err != nil || !found {
    398 		return err
    399 	}
    400 	cfg.RetryMaxAttempts = maxAttempts
    401 
    402 	return nil
    403 }
    404 
    405 func resolveRetryMode(ctx context.Context, cfg *aws.Config, configs configs) error {
    406 	retryMode, found, err := getRetryMode(ctx, configs)
    407 	if err != nil || !found {
    408 		return err
    409 	}
    410 	cfg.RetryMode = retryMode
    411 
    412 	return nil
    413 }
    414 
    415 func resolveInterceptors(ctx context.Context, cfg *aws.Config, configs configs) error {
    416 	// LoadOptions is the only thing that you can really configure interceptors
    417 	// on so just check that directly.
    418 	for _, c := range configs {
    419 		if loadopts, ok := c.(LoadOptions); ok {
    420 			cfg.Interceptors = loadopts.Interceptors.Copy()
    421 		}
    422 	}
    423 	return nil
    424 }
    425 
    426 func resolveAuthSchemePreference(ctx context.Context, cfg *aws.Config, configs configs) error {
    427 	if pref, ok := getAuthSchemePreference(ctx, configs); ok {
    428 		cfg.AuthSchemePreference = pref
    429 	}
    430 	return nil
    431 }
    432 
    433 func resolveServiceOptions(ctx context.Context, cfg *aws.Config, configs configs) error {
    434 	serviceOptions, found, err := getServiceOptions(ctx, configs)
    435 	if err != nil {
    436 		return err
    437 	}
    438 	if !found {
    439 		return nil
    440 	}
    441 
    442 	cfg.ServiceOptions = serviceOptions
    443 	return nil
    444 }