src

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

config.go (8205B)


      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 	// Sets the DisableClockSkewCorrection if present in env var or shared config profile
     81 	resolveDisableClockSkewCorrection,
     82 
     83 	// Sets the RequestMinCompressSizeBytes if present in env var or shared config profile
     84 	resolveRequestMinCompressSizeBytes,
     85 
     86 	// Sets the AccountIDEndpointMode if present in env var or shared config profile
     87 	resolveAccountIDEndpointMode,
     88 
     89 	// Sets the RequestChecksumCalculation if present in env var or shared config profile
     90 	resolveRequestChecksumCalculation,
     91 
     92 	// Sets the ResponseChecksumValidation if present in env var or shared config profile
     93 	resolveResponseChecksumValidation,
     94 
     95 	resolveInterceptors,
     96 
     97 	resolveAuthSchemePreference,
     98 
     99 	// Sets the ServiceOptions if present in LoadOptions
    100 	resolveServiceOptions,
    101 
    102 	resolveRestrictFilePermissions,
    103 }
    104 
    105 // A Config represents a generic configuration value or set of values. This type
    106 // will be used by the AWSConfigResolvers to extract
    107 //
    108 // General the Config type will use type assertion against the Provider interfaces
    109 // to extract specific data from the Config.
    110 type Config any
    111 
    112 // A loader is used to load external configuration data and returns it as
    113 // a generic Config type.
    114 //
    115 // The loader should return an error if it fails to load the external configuration
    116 // or the configuration data is malformed, or required components missing.
    117 type loader func(context.Context, configs) (Config, error)
    118 
    119 // An awsConfigResolver will extract configuration data from the configs slice
    120 // using the provider interfaces to extract specific functionality. The extracted
    121 // configuration values will be written to the AWS Config value.
    122 //
    123 // The resolver should return an error if it it fails to extract the data, the
    124 // data is malformed, or incomplete.
    125 type awsConfigResolver func(ctx context.Context, cfg *aws.Config, configs configs) error
    126 
    127 // configs is a slice of Config values. These values will be used by the
    128 // AWSConfigResolvers to extract external configuration values to populate the
    129 // AWS Config type.
    130 //
    131 // Use AppendFromLoaders to add additional external Config values that are
    132 // loaded from external sources.
    133 //
    134 // Use ResolveAWSConfig after external Config values have been added or loaded
    135 // to extract the loaded configuration values into the AWS Config.
    136 type configs []Config
    137 
    138 // AppendFromLoaders iterates over the slice of loaders passed in calling each
    139 // loader function in order. The external config value returned by the loader
    140 // will be added to the returned configs slice.
    141 //
    142 // If a loader returns an error this method will stop iterating and return
    143 // that error.
    144 func (cs configs) AppendFromLoaders(ctx context.Context, loaders []loader) (configs, error) {
    145 	for _, fn := range loaders {
    146 		cfg, err := fn(ctx, cs)
    147 		if err != nil {
    148 			return nil, err
    149 		}
    150 
    151 		cs = append(cs, cfg)
    152 	}
    153 
    154 	return cs, nil
    155 }
    156 
    157 // ResolveAWSConfig returns a AWS configuration populated with values by calling
    158 // the resolvers slice passed in. Each resolver is called in order. Any resolver
    159 // may overwrite the AWS Configuration value of a previous resolver.
    160 //
    161 // If an resolver returns an error this method will return that error, and stop
    162 // iterating over the resolvers.
    163 func (cs configs) ResolveAWSConfig(ctx context.Context, resolvers []awsConfigResolver) (aws.Config, error) {
    164 	var cfg aws.Config
    165 
    166 	for _, fn := range resolvers {
    167 		if err := fn(ctx, &cfg, cs); err != nil {
    168 			return aws.Config{}, err
    169 		}
    170 	}
    171 
    172 	return cfg, nil
    173 }
    174 
    175 // ResolveConfig calls the provide function passing slice of configuration sources.
    176 // This implements the aws.ConfigResolver interface.
    177 func (cs configs) ResolveConfig(f func(configs []any) error) error {
    178 	var cfgs []any
    179 	for i := range cs {
    180 		cfgs = append(cfgs, cs[i])
    181 	}
    182 	return f(cfgs)
    183 }
    184 
    185 // LoadDefaultConfig reads the SDK's default external configurations, and
    186 // populates an AWS Config with the values from the external configurations.
    187 //
    188 // An optional variadic set of additional Config values can be provided as input
    189 // that will be prepended to the configs slice. Use this to add custom configuration.
    190 // The custom configurations must satisfy the respective providers for their data
    191 // or the custom data will be ignored by the resolvers and config loaders.
    192 //
    193 //	cfg, err := config.LoadDefaultConfig( context.TODO(),
    194 //	   config.WithSharedConfigProfile("test-profile"),
    195 //	)
    196 //	if err != nil {
    197 //	   panic(fmt.Sprintf("failed loading config, %v", err))
    198 //	}
    199 //
    200 // The default configuration sources are:
    201 // * Environment Variables
    202 // * Shared Configuration and Shared Credentials files.
    203 func LoadDefaultConfig(ctx context.Context, optFns ...func(*LoadOptions) error) (cfg aws.Config, err error) {
    204 	var options LoadOptions
    205 	for _, optFn := range optFns {
    206 		if err := optFn(&options); err != nil {
    207 			return aws.Config{}, err
    208 		}
    209 	}
    210 
    211 	// assign Load Options to configs
    212 	var cfgCpy = configs{options}
    213 
    214 	cfgCpy, err = cfgCpy.AppendFromLoaders(ctx, resolveConfigLoaders(&options))
    215 	if err != nil {
    216 		return aws.Config{}, err
    217 	}
    218 
    219 	cfg, err = cfgCpy.ResolveAWSConfig(ctx, defaultAWSConfigResolvers)
    220 	if err != nil {
    221 		return aws.Config{}, err
    222 	}
    223 
    224 	return cfg, nil
    225 }
    226 
    227 func resolveConfigLoaders(options *LoadOptions) []loader {
    228 	loaders := make([]loader, 2)
    229 	loaders[0] = loadEnvConfig
    230 
    231 	// specification of a profile should cause a load failure if it doesn't exist
    232 	if os.Getenv(awsProfileEnv) != "" || options.SharedConfigProfile != "" {
    233 		loaders[1] = loadSharedConfig
    234 	} else {
    235 		loaders[1] = loadSharedConfigIgnoreNotExist
    236 	}
    237 
    238 	return loaders
    239 }