src

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

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 }