code.dwrz.net

Go monorepo.
Log | Files | Refs

resolve.go (7450B)


      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 		Credentials:   aws.AnonymousCredentials{},
     31 		Logger:        logging.NewStandardLogger(os.Stderr),
     32 		ConfigSources: sources,
     33 	}
     34 	return nil
     35 }
     36 
     37 // resolveCustomCABundle extracts the first instance of a custom CA bundle filename
     38 // from the external configurations. It will update the HTTP Client's builder
     39 // to be configured with the custom CA bundle.
     40 //
     41 // Config provider used:
     42 // * customCABundleProvider
     43 func resolveCustomCABundle(ctx context.Context, cfg *aws.Config, cfgs configs) error {
     44 	pemCerts, found, err := getCustomCABundle(ctx, cfgs)
     45 	if err != nil {
     46 		// TODO error handling, What is the best way to handle this?
     47 		// capture previous errors continue. error out if all errors
     48 		return err
     49 	}
     50 	if !found {
     51 		return nil
     52 	}
     53 
     54 	if cfg.HTTPClient == nil {
     55 		cfg.HTTPClient = awshttp.NewBuildableClient()
     56 	}
     57 
     58 	trOpts, ok := cfg.HTTPClient.(*awshttp.BuildableClient)
     59 	if !ok {
     60 		return fmt.Errorf("unable to add custom RootCAs HTTPClient, "+
     61 			"has no WithTransportOptions, %T", cfg.HTTPClient)
     62 	}
     63 
     64 	var appendErr error
     65 	client := trOpts.WithTransportOptions(func(tr *http.Transport) {
     66 		if tr.TLSClientConfig == nil {
     67 			tr.TLSClientConfig = &tls.Config{}
     68 		}
     69 		if tr.TLSClientConfig.RootCAs == nil {
     70 			tr.TLSClientConfig.RootCAs = x509.NewCertPool()
     71 		}
     72 
     73 		b, err := ioutil.ReadAll(pemCerts)
     74 		if err != nil {
     75 			appendErr = fmt.Errorf("failed to read custom CA bundle PEM file")
     76 		}
     77 
     78 		if !tr.TLSClientConfig.RootCAs.AppendCertsFromPEM(b) {
     79 			appendErr = fmt.Errorf("failed to load custom CA bundle PEM file")
     80 		}
     81 	})
     82 	if appendErr != nil {
     83 		return appendErr
     84 	}
     85 
     86 	cfg.HTTPClient = client
     87 	return err
     88 }
     89 
     90 // resolveRegion extracts the first instance of a Region from the configs slice.
     91 //
     92 // Config providers used:
     93 // * regionProvider
     94 func resolveRegion(ctx context.Context, cfg *aws.Config, configs configs) error {
     95 	v, found, err := getRegion(ctx, configs)
     96 	if err != nil {
     97 		// TODO error handling, What is the best way to handle this?
     98 		// capture previous errors continue. error out if all errors
     99 		return err
    100 	}
    101 	if !found {
    102 		return nil
    103 	}
    104 
    105 	cfg.Region = v
    106 	return nil
    107 }
    108 
    109 // resolveDefaultRegion extracts the first instance of a default region and sets `aws.Config.Region` to the default
    110 // region if region had not been resolved from other sources.
    111 func resolveDefaultRegion(ctx context.Context, cfg *aws.Config, configs configs) error {
    112 	if len(cfg.Region) > 0 {
    113 		return nil
    114 	}
    115 
    116 	v, found, err := getDefaultRegion(ctx, configs)
    117 	if err != nil {
    118 		return err
    119 	}
    120 	if !found {
    121 		return nil
    122 	}
    123 
    124 	cfg.Region = v
    125 
    126 	return nil
    127 }
    128 
    129 // resolveHTTPClient extracts the first instance of a HTTPClient and sets `aws.Config.HTTPClient` to the HTTPClient instance
    130 // if one has not been resolved from other sources.
    131 func resolveHTTPClient(ctx context.Context, cfg *aws.Config, configs configs) error {
    132 	c, found, err := getHTTPClient(ctx, configs)
    133 	if err != nil {
    134 		return err
    135 	}
    136 	if !found {
    137 		return nil
    138 	}
    139 
    140 	cfg.HTTPClient = c
    141 	return nil
    142 }
    143 
    144 // resolveAPIOptions extracts the first instance of APIOptions and sets `aws.Config.APIOptions` to the resolved API options
    145 // if one has not been resolved from other sources.
    146 func resolveAPIOptions(ctx context.Context, cfg *aws.Config, configs configs) error {
    147 	o, found, err := getAPIOptions(ctx, configs)
    148 	if err != nil {
    149 		return err
    150 	}
    151 	if !found {
    152 		return nil
    153 	}
    154 
    155 	cfg.APIOptions = o
    156 
    157 	return nil
    158 }
    159 
    160 // resolveEndpointResolver extracts the first instance of a EndpointResolverFunc from the config slice
    161 // and sets the functions result on the aws.Config.EndpointResolver
    162 func resolveEndpointResolver(ctx context.Context, cfg *aws.Config, configs configs) error {
    163 	endpointResolver, found, err := getEndpointResolver(ctx, configs)
    164 	if err != nil {
    165 		return err
    166 	}
    167 	if !found {
    168 		return nil
    169 	}
    170 
    171 	cfg.EndpointResolver = endpointResolver
    172 
    173 	return nil
    174 }
    175 
    176 // resolveEndpointResolver extracts the first instance of a EndpointResolverFunc from the config slice
    177 // and sets the functions result on the aws.Config.EndpointResolver
    178 func resolveEndpointResolverWithOptions(ctx context.Context, cfg *aws.Config, configs configs) error {
    179 	endpointResolver, found, err := getEndpointResolverWithOptions(ctx, configs)
    180 	if err != nil {
    181 		return err
    182 	}
    183 	if !found {
    184 		return nil
    185 	}
    186 
    187 	cfg.EndpointResolverWithOptions = endpointResolver
    188 
    189 	return nil
    190 }
    191 
    192 func resolveLogger(ctx context.Context, cfg *aws.Config, configs configs) error {
    193 	logger, found, err := getLogger(ctx, configs)
    194 	if err != nil {
    195 		return err
    196 	}
    197 	if !found {
    198 		return nil
    199 	}
    200 
    201 	cfg.Logger = logger
    202 
    203 	return nil
    204 }
    205 
    206 func resolveClientLogMode(ctx context.Context, cfg *aws.Config, configs configs) error {
    207 	mode, found, err := getClientLogMode(ctx, configs)
    208 	if err != nil {
    209 		return err
    210 	}
    211 	if !found {
    212 		return nil
    213 	}
    214 
    215 	cfg.ClientLogMode = mode
    216 
    217 	return nil
    218 }
    219 
    220 func resolveRetryer(ctx context.Context, cfg *aws.Config, configs configs) error {
    221 	retryer, found, err := getRetryer(ctx, configs)
    222 	if err != nil {
    223 		return err
    224 	}
    225 
    226 	if found {
    227 		cfg.Retryer = retryer
    228 		return nil
    229 	}
    230 
    231 	// Only load the retry options if a custom retryer has not be specified.
    232 	if err = resolveRetryMaxAttempts(ctx, cfg, configs); err != nil {
    233 		return err
    234 	}
    235 	return resolveRetryMode(ctx, cfg, configs)
    236 }
    237 
    238 func resolveEC2IMDSRegion(ctx context.Context, cfg *aws.Config, configs configs) error {
    239 	if len(cfg.Region) > 0 {
    240 		return nil
    241 	}
    242 
    243 	region, found, err := getEC2IMDSRegion(ctx, configs)
    244 	if err != nil {
    245 		return err
    246 	}
    247 	if !found {
    248 		return nil
    249 	}
    250 
    251 	cfg.Region = region
    252 
    253 	return nil
    254 }
    255 
    256 func resolveDefaultsModeOptions(ctx context.Context, cfg *aws.Config, configs configs) error {
    257 	defaultsMode, found, err := getDefaultsMode(ctx, configs)
    258 	if err != nil {
    259 		return err
    260 	}
    261 	if !found {
    262 		defaultsMode = aws.DefaultsModeLegacy
    263 	}
    264 
    265 	var environment aws.RuntimeEnvironment
    266 	if defaultsMode == aws.DefaultsModeAuto {
    267 		envConfig, _, _ := getAWSConfigSources(configs)
    268 
    269 		client, found, err := getDefaultsModeIMDSClient(ctx, configs)
    270 		if err != nil {
    271 			return err
    272 		}
    273 		if !found {
    274 			client = imds.NewFromConfig(*cfg)
    275 		}
    276 
    277 		environment, err = resolveDefaultsModeRuntimeEnvironment(ctx, envConfig, client)
    278 		if err != nil {
    279 			return err
    280 		}
    281 	}
    282 
    283 	cfg.DefaultsMode = defaultsMode
    284 	cfg.RuntimeEnvironment = environment
    285 
    286 	return nil
    287 }
    288 
    289 func resolveRetryMaxAttempts(ctx context.Context, cfg *aws.Config, configs configs) error {
    290 	maxAttempts, found, err := getRetryMaxAttempts(ctx, configs)
    291 	if err != nil || !found {
    292 		return err
    293 	}
    294 	cfg.RetryMaxAttempts = maxAttempts
    295 
    296 	return nil
    297 }
    298 
    299 func resolveRetryMode(ctx context.Context, cfg *aws.Config, configs configs) error {
    300 	retryMode, found, err := getRetryMode(ctx, configs)
    301 	if err != nil || !found {
    302 		return err
    303 	}
    304 	cfg.RetryMode = retryMode
    305 
    306 	return nil
    307 }