src

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

config.go (8072B)


      1 package config
      2 
      3 import (
      4 	"context"
      5 	"os"
      6 
      7 	"github.com/aws/aws-sdk-go-v2/aws"
      8 )
      9 
     10 // defaultAWSConfigResolvers are a slice of functions that will resolve external
     11 // configuration values into AWS configuration values.
     12 //
     13 // This will setup the AWS configuration's Region,
     14 var defaultAWSConfigResolvers = []awsConfigResolver{
     15 	// Resolves the default configuration the SDK's aws.Config will be
     16 	// initialized with.
     17 	resolveDefaultAWSConfig,
     18 
     19 	// Sets the logger to be used. Could be user provided logger, and client
     20 	// logging mode.
     21 	resolveLogger,
     22 	resolveClientLogMode,
     23 
     24 	// Sets the HTTP client and configuration to use for making requests using
     25 	// the HTTP transport.
     26 	resolveHTTPClient,
     27 	resolveCustomCABundle,
     28 
     29 	// Sets the endpoint resolving behavior the API Clients will use for making
     30 	// requests to. Clients default to their own clients this allows overrides
     31 	// to be specified. The resolveEndpointResolver option is deprecated, but
     32 	// we still need to set it for backwards compatibility on config
     33 	// construction.
     34 	resolveEndpointResolver,
     35 	resolveEndpointResolverWithOptions,
     36 
     37 	// Sets the retry behavior API clients will use within their retry attempt
     38 	// middleware. Defaults to unset, allowing API clients to define their own
     39 	// retry behavior.
     40 	resolveRetryer,
     41 
     42 	// Sets the region the API Clients should use for making requests to.
     43 	resolveRegion,
     44 	resolveEC2IMDSRegion,
     45 	resolveDefaultRegion,
     46 
     47 	// Sets the additional set of middleware stack mutators that will custom
     48 	// API client request pipeline middleware.
     49 	resolveAPIOptions,
     50 
     51 	// Resolves the DefaultsMode that should be used by SDK clients. If this
     52 	// mode is set to DefaultsModeAuto.
     53 	//
     54 	// Comes after HTTPClient and CustomCABundle to ensure the HTTP client is
     55 	// configured if provided before invoking IMDS if mode is auto. Comes
     56 	// before resolving credentials so that those subsequent clients use the
     57 	// configured auto mode.
     58 	resolveDefaultsModeOptions,
     59 
     60 	// Sets the resolved credentials the API clients will use for
     61 	// authentication. Provides the SDK's default credential chain.
     62 	//
     63 	// Should probably be the last step in the resolve chain to ensure that all
     64 	// other configurations are resolved first in case downstream credentials
     65 	// implementations depend on or can be configured with earlier resolved
     66 	// configuration options.
     67 	resolveCredentials,
     68 
     69 	// Sets the resolved bearer authentication token API clients will use for
     70 	// httpBearerAuth authentication scheme.
     71 	resolveBearerAuthToken,
     72 
     73 	// Sets the sdk app ID if present in env var or shared config profile
     74 	resolveAppID,
     75 
     76 	resolveBaseEndpoint,
     77 
     78 	// Sets the DisableRequestCompression if present in env var or shared config profile
     79 	resolveDisableRequestCompression,
     80 
     81 	// Sets the RequestMinCompressSizeBytes if present in env var or shared config profile
     82 	resolveRequestMinCompressSizeBytes,
     83 
     84 	// Sets the AccountIDEndpointMode if present in env var or shared config profile
     85 	resolveAccountIDEndpointMode,
     86 
     87 	// Sets the RequestChecksumCalculation if present in env var or shared config profile
     88 	resolveRequestChecksumCalculation,
     89 
     90 	// Sets the ResponseChecksumValidation if present in env var or shared config profile
     91 	resolveResponseChecksumValidation,
     92 
     93 	resolveInterceptors,
     94 
     95 	resolveAuthSchemePreference,
     96 
     97 	// Sets the ServiceOptions if present in LoadOptions
     98 	resolveServiceOptions,
     99 }
    100 
    101 // A Config represents a generic configuration value or set of values. This type
    102 // will be used by the AWSConfigResolvers to extract
    103 //
    104 // General the Config type will use type assertion against the Provider interfaces
    105 // to extract specific data from the Config.
    106 type Config interface{}
    107 
    108 // A loader is used to load external configuration data and returns it as
    109 // a generic Config type.
    110 //
    111 // The loader should return an error if it fails to load the external configuration
    112 // or the configuration data is malformed, or required components missing.
    113 type loader func(context.Context, configs) (Config, error)
    114 
    115 // An awsConfigResolver will extract configuration data from the configs slice
    116 // using the provider interfaces to extract specific functionality. The extracted
    117 // configuration values will be written to the AWS Config value.
    118 //
    119 // The resolver should return an error if it it fails to extract the data, the
    120 // data is malformed, or incomplete.
    121 type awsConfigResolver func(ctx context.Context, cfg *aws.Config, configs configs) error
    122 
    123 // configs is a slice of Config values. These values will be used by the
    124 // AWSConfigResolvers to extract external configuration values to populate the
    125 // AWS Config type.
    126 //
    127 // Use AppendFromLoaders to add additional external Config values that are
    128 // loaded from external sources.
    129 //
    130 // Use ResolveAWSConfig after external Config values have been added or loaded
    131 // to extract the loaded configuration values into the AWS Config.
    132 type configs []Config
    133 
    134 // AppendFromLoaders iterates over the slice of loaders passed in calling each
    135 // loader function in order. The external config value returned by the loader
    136 // will be added to the returned configs slice.
    137 //
    138 // If a loader returns an error this method will stop iterating and return
    139 // that error.
    140 func (cs configs) AppendFromLoaders(ctx context.Context, loaders []loader) (configs, error) {
    141 	for _, fn := range loaders {
    142 		cfg, err := fn(ctx, cs)
    143 		if err != nil {
    144 			return nil, err
    145 		}
    146 
    147 		cs = append(cs, cfg)
    148 	}
    149 
    150 	return cs, nil
    151 }
    152 
    153 // ResolveAWSConfig returns a AWS configuration populated with values by calling
    154 // the resolvers slice passed in. Each resolver is called in order. Any resolver
    155 // may overwrite the AWS Configuration value of a previous resolver.
    156 //
    157 // If an resolver returns an error this method will return that error, and stop
    158 // iterating over the resolvers.
    159 func (cs configs) ResolveAWSConfig(ctx context.Context, resolvers []awsConfigResolver) (aws.Config, error) {
    160 	var cfg aws.Config
    161 
    162 	for _, fn := range resolvers {
    163 		if err := fn(ctx, &cfg, cs); err != nil {
    164 			return aws.Config{}, err
    165 		}
    166 	}
    167 
    168 	return cfg, nil
    169 }
    170 
    171 // ResolveConfig calls the provide function passing slice of configuration sources.
    172 // This implements the aws.ConfigResolver interface.
    173 func (cs configs) ResolveConfig(f func(configs []interface{}) error) error {
    174 	var cfgs []interface{}
    175 	for i := range cs {
    176 		cfgs = append(cfgs, cs[i])
    177 	}
    178 	return f(cfgs)
    179 }
    180 
    181 // LoadDefaultConfig reads the SDK's default external configurations, and
    182 // populates an AWS Config with the values from the external configurations.
    183 //
    184 // An optional variadic set of additional Config values can be provided as input
    185 // that will be prepended to the configs slice. Use this to add custom configuration.
    186 // The custom configurations must satisfy the respective providers for their data
    187 // or the custom data will be ignored by the resolvers and config loaders.
    188 //
    189 //	cfg, err := config.LoadDefaultConfig( context.TODO(),
    190 //	   config.WithSharedConfigProfile("test-profile"),
    191 //	)
    192 //	if err != nil {
    193 //	   panic(fmt.Sprintf("failed loading config, %v", err))
    194 //	}
    195 //
    196 // The default configuration sources are:
    197 // * Environment Variables
    198 // * Shared Configuration and Shared Credentials files.
    199 func LoadDefaultConfig(ctx context.Context, optFns ...func(*LoadOptions) error) (cfg aws.Config, err error) {
    200 	var options LoadOptions
    201 	for _, optFn := range optFns {
    202 		if err := optFn(&options); err != nil {
    203 			return aws.Config{}, err
    204 		}
    205 	}
    206 
    207 	// assign Load Options to configs
    208 	var cfgCpy = configs{options}
    209 
    210 	cfgCpy, err = cfgCpy.AppendFromLoaders(ctx, resolveConfigLoaders(&options))
    211 	if err != nil {
    212 		return aws.Config{}, err
    213 	}
    214 
    215 	cfg, err = cfgCpy.ResolveAWSConfig(ctx, defaultAWSConfigResolvers)
    216 	if err != nil {
    217 		return aws.Config{}, err
    218 	}
    219 
    220 	return cfg, nil
    221 }
    222 
    223 func resolveConfigLoaders(options *LoadOptions) []loader {
    224 	loaders := make([]loader, 2)
    225 	loaders[0] = loadEnvConfig
    226 
    227 	// specification of a profile should cause a load failure if it doesn't exist
    228 	if os.Getenv(awsProfileEnv) != "" || options.SharedConfigProfile != "" {
    229 		loaders[1] = loadSharedConfig
    230 	} else {
    231 		loaders[1] = loadSharedConfigIgnoreNotExist
    232 	}
    233 
    234 	return loaders
    235 }