...

Source file src/github.com/aws/aws-sdk-go-v2/config/env_config.go

Documentation: github.com/aws/aws-sdk-go-v2/config

     1  package config
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  	"os"
    10  	"strconv"
    11  	"strings"
    12  
    13  	"github.com/aws/aws-sdk-go-v2/aws"
    14  	"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
    15  	smithyrequestcompression "github.com/aws/smithy-go/private/requestcompression"
    16  )
    17  
    18  // CredentialsSourceName provides a name of the provider when config is
    19  // loaded from environment.
    20  const CredentialsSourceName = "EnvConfigCredentials"
    21  
    22  // Environment variables that will be read for configuration values.
    23  const (
    24  	awsAccessKeyIDEnvVar = "AWS_ACCESS_KEY_ID"
    25  	awsAccessKeyEnvVar   = "AWS_ACCESS_KEY"
    26  
    27  	awsSecretAccessKeyEnvVar = "AWS_SECRET_ACCESS_KEY"
    28  	awsSecretKeyEnvVar       = "AWS_SECRET_KEY"
    29  
    30  	awsSessionTokenEnvVar = "AWS_SESSION_TOKEN"
    31  
    32  	awsContainerCredentialsEndpointEnvVar     = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
    33  	awsContainerCredentialsRelativePathEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
    34  	awsContainerPProviderAuthorizationEnvVar  = "AWS_CONTAINER_AUTHORIZATION_TOKEN"
    35  
    36  	awsRegionEnvVar        = "AWS_REGION"
    37  	awsDefaultRegionEnvVar = "AWS_DEFAULT_REGION"
    38  
    39  	awsProfileEnvVar        = "AWS_PROFILE"
    40  	awsDefaultProfileEnvVar = "AWS_DEFAULT_PROFILE"
    41  
    42  	awsSharedCredentialsFileEnvVar = "AWS_SHARED_CREDENTIALS_FILE"
    43  
    44  	awsConfigFileEnvVar = "AWS_CONFIG_FILE"
    45  
    46  	awsCustomCABundleEnvVar = "AWS_CA_BUNDLE"
    47  
    48  	awsWebIdentityTokenFilePathEnvVar = "AWS_WEB_IDENTITY_TOKEN_FILE"
    49  
    50  	awsRoleARNEnvVar         = "AWS_ROLE_ARN"
    51  	awsRoleSessionNameEnvVar = "AWS_ROLE_SESSION_NAME"
    52  
    53  	awsEnableEndpointDiscoveryEnvVar = "AWS_ENABLE_ENDPOINT_DISCOVERY"
    54  
    55  	awsS3UseARNRegionEnvVar = "AWS_S3_USE_ARN_REGION"
    56  
    57  	awsEc2MetadataServiceEndpointModeEnvVar = "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE"
    58  
    59  	awsEc2MetadataServiceEndpointEnvVar = "AWS_EC2_METADATA_SERVICE_ENDPOINT"
    60  
    61  	awsEc2MetadataDisabled         = "AWS_EC2_METADATA_DISABLED"
    62  	awsEc2MetadataV1DisabledEnvVar = "AWS_EC2_METADATA_V1_DISABLED"
    63  
    64  	awsS3DisableMultiRegionAccessPointEnvVar = "AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS"
    65  
    66  	awsUseDualStackEndpoint = "AWS_USE_DUALSTACK_ENDPOINT"
    67  
    68  	awsUseFIPSEndpoint = "AWS_USE_FIPS_ENDPOINT"
    69  
    70  	awsDefaultMode = "AWS_DEFAULTS_MODE"
    71  
    72  	awsRetryMaxAttempts = "AWS_MAX_ATTEMPTS"
    73  	awsRetryMode        = "AWS_RETRY_MODE"
    74  	awsSdkAppID         = "AWS_SDK_UA_APP_ID"
    75  
    76  	awsIgnoreConfiguredEndpoints = "AWS_IGNORE_CONFIGURED_ENDPOINT_URLS"
    77  	awsEndpointURL               = "AWS_ENDPOINT_URL"
    78  
    79  	awsDisableRequestCompression      = "AWS_DISABLE_REQUEST_COMPRESSION"
    80  	awsRequestMinCompressionSizeBytes = "AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES"
    81  
    82  	awsS3DisableExpressSessionAuthEnv = "AWS_S3_DISABLE_EXPRESS_SESSION_AUTH"
    83  )
    84  
    85  var (
    86  	credAccessEnvKeys = []string{
    87  		awsAccessKeyIDEnvVar,
    88  		awsAccessKeyEnvVar,
    89  	}
    90  	credSecretEnvKeys = []string{
    91  		awsSecretAccessKeyEnvVar,
    92  		awsSecretKeyEnvVar,
    93  	}
    94  	regionEnvKeys = []string{
    95  		awsRegionEnvVar,
    96  		awsDefaultRegionEnvVar,
    97  	}
    98  	profileEnvKeys = []string{
    99  		awsProfileEnvVar,
   100  		awsDefaultProfileEnvVar,
   101  	}
   102  )
   103  
   104  // EnvConfig is a collection of environment values the SDK will read
   105  // setup config from. All environment values are optional. But some values
   106  // such as credentials require multiple values to be complete or the values
   107  // will be ignored.
   108  type EnvConfig struct {
   109  	// Environment configuration values. If set both Access Key ID and Secret Access
   110  	// Key must be provided. Session Token and optionally also be provided, but is
   111  	// not required.
   112  	//
   113  	//	# Access Key ID
   114  	//	AWS_ACCESS_KEY_ID=AKID
   115  	//	AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set.
   116  	//
   117  	//	# Secret Access Key
   118  	//	AWS_SECRET_ACCESS_KEY=SECRET
   119  	//	AWS_SECRET_KEY=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set.
   120  	//
   121  	//	# Session Token
   122  	//	AWS_SESSION_TOKEN=TOKEN
   123  	Credentials aws.Credentials
   124  
   125  	// ContainerCredentialsEndpoint value is the HTTP enabled endpoint to retrieve credentials
   126  	// using the endpointcreds.Provider
   127  	ContainerCredentialsEndpoint string
   128  
   129  	// ContainerCredentialsRelativePath is the relative URI path that will be used when attempting to retrieve
   130  	// credentials from the container endpoint.
   131  	ContainerCredentialsRelativePath string
   132  
   133  	// ContainerAuthorizationToken is the authorization token that will be included in the HTTP Authorization
   134  	// header when attempting to retrieve credentials from the container credentials endpoint.
   135  	ContainerAuthorizationToken string
   136  
   137  	// Region value will instruct the SDK where to make service API requests to. If is
   138  	// not provided in the environment the region must be provided before a service
   139  	// client request is made.
   140  	//
   141  	//	AWS_REGION=us-west-2
   142  	//	AWS_DEFAULT_REGION=us-west-2
   143  	Region string
   144  
   145  	// Profile name the SDK should load use when loading shared configuration from the
   146  	// shared configuration files. If not provided "default" will be used as the
   147  	// profile name.
   148  	//
   149  	//	AWS_PROFILE=my_profile
   150  	//	AWS_DEFAULT_PROFILE=my_profile
   151  	SharedConfigProfile string
   152  
   153  	// Shared credentials file path can be set to instruct the SDK to use an alternate
   154  	// file for the shared credentials. If not set the file will be loaded from
   155  	// $HOME/.aws/credentials on Linux/Unix based systems, and
   156  	// %USERPROFILE%\.aws\credentials on Windows.
   157  	//
   158  	//	AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials
   159  	SharedCredentialsFile string
   160  
   161  	// Shared config file path can be set to instruct the SDK to use an alternate
   162  	// file for the shared config. If not set the file will be loaded from
   163  	// $HOME/.aws/config on Linux/Unix based systems, and
   164  	// %USERPROFILE%\.aws\config on Windows.
   165  	//
   166  	//	AWS_CONFIG_FILE=$HOME/my_shared_config
   167  	SharedConfigFile string
   168  
   169  	// Sets the path to a custom Credentials Authority (CA) Bundle PEM file
   170  	// that the SDK will use instead of the system's root CA bundle.
   171  	// Only use this if you want to configure the SDK to use a custom set
   172  	// of CAs.
   173  	//
   174  	// Enabling this option will attempt to merge the Transport
   175  	// into the SDK's HTTP client. If the client's Transport is
   176  	// not a http.Transport an error will be returned. If the
   177  	// Transport's TLS config is set this option will cause the
   178  	// SDK to overwrite the Transport's TLS config's  RootCAs value.
   179  	//
   180  	// Setting a custom HTTPClient in the aws.Config options will override this setting.
   181  	// To use this option and custom HTTP client, the HTTP client needs to be provided
   182  	// when creating the config. Not the service client.
   183  	//
   184  	//  AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle
   185  	CustomCABundle string
   186  
   187  	// Enables endpoint discovery via environment variables.
   188  	//
   189  	//	AWS_ENABLE_ENDPOINT_DISCOVERY=true
   190  	EnableEndpointDiscovery aws.EndpointDiscoveryEnableState
   191  
   192  	// Specifies the WebIdentity token the SDK should use to assume a role
   193  	// with.
   194  	//
   195  	//  AWS_WEB_IDENTITY_TOKEN_FILE=file_path
   196  	WebIdentityTokenFilePath string
   197  
   198  	// Specifies the IAM role arn to use when assuming an role.
   199  	//
   200  	//  AWS_ROLE_ARN=role_arn
   201  	RoleARN string
   202  
   203  	// Specifies the IAM role session name to use when assuming a role.
   204  	//
   205  	//  AWS_ROLE_SESSION_NAME=session_name
   206  	RoleSessionName string
   207  
   208  	// Specifies if the S3 service should allow ARNs to direct the region
   209  	// the client's requests are sent to.
   210  	//
   211  	// AWS_S3_USE_ARN_REGION=true
   212  	S3UseARNRegion *bool
   213  
   214  	// Specifies if the EC2 IMDS service client is enabled.
   215  	//
   216  	// AWS_EC2_METADATA_DISABLED=true
   217  	EC2IMDSClientEnableState imds.ClientEnableState
   218  
   219  	// Specifies if EC2 IMDSv1 fallback is disabled.
   220  	//
   221  	// AWS_EC2_METADATA_V1_DISABLED=true
   222  	EC2IMDSv1Disabled *bool
   223  
   224  	// Specifies the EC2 Instance Metadata Service default endpoint selection mode (IPv4 or IPv6)
   225  	//
   226  	// AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE=IPv6
   227  	EC2IMDSEndpointMode imds.EndpointModeState
   228  
   229  	// Specifies the EC2 Instance Metadata Service endpoint to use. If specified it overrides EC2IMDSEndpointMode.
   230  	//
   231  	// AWS_EC2_METADATA_SERVICE_ENDPOINT=http://fd00:ec2::254
   232  	EC2IMDSEndpoint string
   233  
   234  	// Specifies if the S3 service should disable multi-region access points
   235  	// support.
   236  	//
   237  	// AWS_S3_DISABLE_MULTIREGION_ACCESS_POINTS=true
   238  	S3DisableMultiRegionAccessPoints *bool
   239  
   240  	// Specifies that SDK clients must resolve a dual-stack endpoint for
   241  	// services.
   242  	//
   243  	// AWS_USE_DUALSTACK_ENDPOINT=true
   244  	UseDualStackEndpoint aws.DualStackEndpointState
   245  
   246  	// Specifies that SDK clients must resolve a FIPS endpoint for
   247  	// services.
   248  	//
   249  	// AWS_USE_FIPS_ENDPOINT=true
   250  	UseFIPSEndpoint aws.FIPSEndpointState
   251  
   252  	// Specifies the SDK Defaults Mode used by services.
   253  	//
   254  	// AWS_DEFAULTS_MODE=standard
   255  	DefaultsMode aws.DefaultsMode
   256  
   257  	// Specifies the maximum number attempts an API client will call an
   258  	// operation that fails with a retryable error.
   259  	//
   260  	// AWS_MAX_ATTEMPTS=3
   261  	RetryMaxAttempts int
   262  
   263  	// Specifies the retry model the API client will be created with.
   264  	//
   265  	// aws_retry_mode=standard
   266  	RetryMode aws.RetryMode
   267  
   268  	// aws sdk app ID that can be added to user agent header string
   269  	AppID string
   270  
   271  	// Flag used to disable configured endpoints.
   272  	IgnoreConfiguredEndpoints *bool
   273  
   274  	// Value to contain configured endpoints to be propagated to
   275  	// corresponding endpoint resolution field.
   276  	BaseEndpoint string
   277  
   278  	// determine if request compression is allowed, default to false
   279  	// retrieved from env var AWS_DISABLE_REQUEST_COMPRESSION
   280  	DisableRequestCompression *bool
   281  
   282  	// inclusive threshold request body size to trigger compression,
   283  	// default to 10240 and must be within 0 and 10485760 bytes inclusive
   284  	// retrieved from env var AWS_REQUEST_MIN_COMPRESSION_SIZE_BYTES
   285  	RequestMinCompressSizeBytes *int64
   286  
   287  	// Whether S3Express auth is disabled.
   288  	//
   289  	// This will NOT prevent requests from being made to S3Express buckets, it
   290  	// will only bypass the modified endpoint routing and signing behaviors
   291  	// associated with the feature.
   292  	S3DisableExpressAuth *bool
   293  }
   294  
   295  // loadEnvConfig reads configuration values from the OS's environment variables.
   296  // Returning the a Config typed EnvConfig to satisfy the ConfigLoader func type.
   297  func loadEnvConfig(ctx context.Context, cfgs configs) (Config, error) {
   298  	return NewEnvConfig()
   299  }
   300  
   301  // NewEnvConfig retrieves the SDK's environment configuration.
   302  // See `EnvConfig` for the values that will be retrieved.
   303  func NewEnvConfig() (EnvConfig, error) {
   304  	var cfg EnvConfig
   305  
   306  	creds := aws.Credentials{
   307  		Source: CredentialsSourceName,
   308  	}
   309  	setStringFromEnvVal(&creds.AccessKeyID, credAccessEnvKeys)
   310  	setStringFromEnvVal(&creds.SecretAccessKey, credSecretEnvKeys)
   311  	if creds.HasKeys() {
   312  		creds.SessionToken = os.Getenv(awsSessionTokenEnvVar)
   313  		cfg.Credentials = creds
   314  	}
   315  
   316  	cfg.ContainerCredentialsEndpoint = os.Getenv(awsContainerCredentialsEndpointEnvVar)
   317  	cfg.ContainerCredentialsRelativePath = os.Getenv(awsContainerCredentialsRelativePathEnvVar)
   318  	cfg.ContainerAuthorizationToken = os.Getenv(awsContainerPProviderAuthorizationEnvVar)
   319  
   320  	setStringFromEnvVal(&cfg.Region, regionEnvKeys)
   321  	setStringFromEnvVal(&cfg.SharedConfigProfile, profileEnvKeys)
   322  
   323  	cfg.SharedCredentialsFile = os.Getenv(awsSharedCredentialsFileEnvVar)
   324  	cfg.SharedConfigFile = os.Getenv(awsConfigFileEnvVar)
   325  
   326  	cfg.CustomCABundle = os.Getenv(awsCustomCABundleEnvVar)
   327  
   328  	cfg.WebIdentityTokenFilePath = os.Getenv(awsWebIdentityTokenFilePathEnvVar)
   329  
   330  	cfg.RoleARN = os.Getenv(awsRoleARNEnvVar)
   331  	cfg.RoleSessionName = os.Getenv(awsRoleSessionNameEnvVar)
   332  
   333  	cfg.AppID = os.Getenv(awsSdkAppID)
   334  
   335  	if err := setBoolPtrFromEnvVal(&cfg.DisableRequestCompression, []string{awsDisableRequestCompression}); err != nil {
   336  		return cfg, err
   337  	}
   338  	if err := setInt64PtrFromEnvVal(&cfg.RequestMinCompressSizeBytes, []string{awsRequestMinCompressionSizeBytes}, smithyrequestcompression.MaxRequestMinCompressSizeBytes); err != nil {
   339  		return cfg, err
   340  	}
   341  
   342  	if err := setEndpointDiscoveryTypeFromEnvVal(&cfg.EnableEndpointDiscovery, []string{awsEnableEndpointDiscoveryEnvVar}); err != nil {
   343  		return cfg, err
   344  	}
   345  
   346  	if err := setBoolPtrFromEnvVal(&cfg.S3UseARNRegion, []string{awsS3UseARNRegionEnvVar}); err != nil {
   347  		return cfg, err
   348  	}
   349  
   350  	setEC2IMDSClientEnableState(&cfg.EC2IMDSClientEnableState, []string{awsEc2MetadataDisabled})
   351  	if err := setEC2IMDSEndpointMode(&cfg.EC2IMDSEndpointMode, []string{awsEc2MetadataServiceEndpointModeEnvVar}); err != nil {
   352  		return cfg, err
   353  	}
   354  	cfg.EC2IMDSEndpoint = os.Getenv(awsEc2MetadataServiceEndpointEnvVar)
   355  	if err := setBoolPtrFromEnvVal(&cfg.EC2IMDSv1Disabled, []string{awsEc2MetadataV1DisabledEnvVar}); err != nil {
   356  		return cfg, err
   357  	}
   358  
   359  	if err := setBoolPtrFromEnvVal(&cfg.S3DisableMultiRegionAccessPoints, []string{awsS3DisableMultiRegionAccessPointEnvVar}); err != nil {
   360  		return cfg, err
   361  	}
   362  
   363  	if err := setUseDualStackEndpointFromEnvVal(&cfg.UseDualStackEndpoint, []string{awsUseDualStackEndpoint}); err != nil {
   364  		return cfg, err
   365  	}
   366  
   367  	if err := setUseFIPSEndpointFromEnvVal(&cfg.UseFIPSEndpoint, []string{awsUseFIPSEndpoint}); err != nil {
   368  		return cfg, err
   369  	}
   370  
   371  	if err := setDefaultsModeFromEnvVal(&cfg.DefaultsMode, []string{awsDefaultMode}); err != nil {
   372  		return cfg, err
   373  	}
   374  
   375  	if err := setIntFromEnvVal(&cfg.RetryMaxAttempts, []string{awsRetryMaxAttempts}); err != nil {
   376  		return cfg, err
   377  	}
   378  	if err := setRetryModeFromEnvVal(&cfg.RetryMode, []string{awsRetryMode}); err != nil {
   379  		return cfg, err
   380  	}
   381  
   382  	setStringFromEnvVal(&cfg.BaseEndpoint, []string{awsEndpointURL})
   383  
   384  	if err := setBoolPtrFromEnvVal(&cfg.IgnoreConfiguredEndpoints, []string{awsIgnoreConfiguredEndpoints}); err != nil {
   385  		return cfg, err
   386  	}
   387  
   388  	if err := setBoolPtrFromEnvVal(&cfg.S3DisableExpressAuth, []string{awsS3DisableExpressSessionAuthEnv}); err != nil {
   389  		return cfg, err
   390  	}
   391  
   392  	return cfg, nil
   393  }
   394  
   395  func (c EnvConfig) getDefaultsMode(ctx context.Context) (aws.DefaultsMode, bool, error) {
   396  	if len(c.DefaultsMode) == 0 {
   397  		return "", false, nil
   398  	}
   399  	return c.DefaultsMode, true, nil
   400  }
   401  
   402  func (c EnvConfig) getAppID(context.Context) (string, bool, error) {
   403  	return c.AppID, len(c.AppID) > 0, nil
   404  }
   405  
   406  func (c EnvConfig) getDisableRequestCompression(context.Context) (bool, bool, error) {
   407  	if c.DisableRequestCompression == nil {
   408  		return false, false, nil
   409  	}
   410  	return *c.DisableRequestCompression, true, nil
   411  }
   412  
   413  func (c EnvConfig) getRequestMinCompressSizeBytes(context.Context) (int64, bool, error) {
   414  	if c.RequestMinCompressSizeBytes == nil {
   415  		return 0, false, nil
   416  	}
   417  	return *c.RequestMinCompressSizeBytes, true, nil
   418  }
   419  
   420  // GetRetryMaxAttempts returns the value of AWS_MAX_ATTEMPTS if was specified,
   421  // and not 0.
   422  func (c EnvConfig) GetRetryMaxAttempts(ctx context.Context) (int, bool, error) {
   423  	if c.RetryMaxAttempts == 0 {
   424  		return 0, false, nil
   425  	}
   426  	return c.RetryMaxAttempts, true, nil
   427  }
   428  
   429  // GetRetryMode returns the RetryMode of AWS_RETRY_MODE if was specified, and a
   430  // valid value.
   431  func (c EnvConfig) GetRetryMode(ctx context.Context) (aws.RetryMode, bool, error) {
   432  	if len(c.RetryMode) == 0 {
   433  		return "", false, nil
   434  	}
   435  	return c.RetryMode, true, nil
   436  }
   437  
   438  func setEC2IMDSClientEnableState(state *imds.ClientEnableState, keys []string) {
   439  	for _, k := range keys {
   440  		value := os.Getenv(k)
   441  		if len(value) == 0 {
   442  			continue
   443  		}
   444  		switch {
   445  		case strings.EqualFold(value, "true"):
   446  			*state = imds.ClientDisabled
   447  		case strings.EqualFold(value, "false"):
   448  			*state = imds.ClientEnabled
   449  		default:
   450  			continue
   451  		}
   452  		break
   453  	}
   454  }
   455  
   456  func setDefaultsModeFromEnvVal(mode *aws.DefaultsMode, keys []string) error {
   457  	for _, k := range keys {
   458  		if value := os.Getenv(k); len(value) > 0 {
   459  			if ok := mode.SetFromString(value); !ok {
   460  				return fmt.Errorf("invalid %s value: %s", k, value)
   461  			}
   462  			break
   463  		}
   464  	}
   465  	return nil
   466  }
   467  
   468  func setRetryModeFromEnvVal(mode *aws.RetryMode, keys []string) (err error) {
   469  	for _, k := range keys {
   470  		if value := os.Getenv(k); len(value) > 0 {
   471  			*mode, err = aws.ParseRetryMode(value)
   472  			if err != nil {
   473  				return fmt.Errorf("invalid %s value, %w", k, err)
   474  			}
   475  			break
   476  		}
   477  	}
   478  	return nil
   479  }
   480  
   481  func setEC2IMDSEndpointMode(mode *imds.EndpointModeState, keys []string) error {
   482  	for _, k := range keys {
   483  		value := os.Getenv(k)
   484  		if len(value) == 0 {
   485  			continue
   486  		}
   487  		if err := mode.SetFromString(value); err != nil {
   488  			return fmt.Errorf("invalid value for environment variable, %s=%s, %v", k, value, err)
   489  		}
   490  	}
   491  	return nil
   492  }
   493  
   494  // GetRegion returns the AWS Region if set in the environment. Returns an empty
   495  // string if not set.
   496  func (c EnvConfig) getRegion(ctx context.Context) (string, bool, error) {
   497  	if len(c.Region) == 0 {
   498  		return "", false, nil
   499  	}
   500  	return c.Region, true, nil
   501  }
   502  
   503  // GetSharedConfigProfile returns the shared config profile if set in the
   504  // environment. Returns an empty string if not set.
   505  func (c EnvConfig) getSharedConfigProfile(ctx context.Context) (string, bool, error) {
   506  	if len(c.SharedConfigProfile) == 0 {
   507  		return "", false, nil
   508  	}
   509  
   510  	return c.SharedConfigProfile, true, nil
   511  }
   512  
   513  // getSharedConfigFiles returns a slice of filenames set in the environment.
   514  //
   515  // Will return the filenames in the order of:
   516  // * Shared Config
   517  func (c EnvConfig) getSharedConfigFiles(context.Context) ([]string, bool, error) {
   518  	var files []string
   519  	if v := c.SharedConfigFile; len(v) > 0 {
   520  		files = append(files, v)
   521  	}
   522  
   523  	if len(files) == 0 {
   524  		return nil, false, nil
   525  	}
   526  	return files, true, nil
   527  }
   528  
   529  // getSharedCredentialsFiles returns a slice of filenames set in the environment.
   530  //
   531  // Will return the filenames in the order of:
   532  // * Shared Credentials
   533  func (c EnvConfig) getSharedCredentialsFiles(context.Context) ([]string, bool, error) {
   534  	var files []string
   535  	if v := c.SharedCredentialsFile; len(v) > 0 {
   536  		files = append(files, v)
   537  	}
   538  	if len(files) == 0 {
   539  		return nil, false, nil
   540  	}
   541  	return files, true, nil
   542  }
   543  
   544  // GetCustomCABundle returns the custom CA bundle's PEM bytes if the file was
   545  func (c EnvConfig) getCustomCABundle(context.Context) (io.Reader, bool, error) {
   546  	if len(c.CustomCABundle) == 0 {
   547  		return nil, false, nil
   548  	}
   549  
   550  	b, err := ioutil.ReadFile(c.CustomCABundle)
   551  	if err != nil {
   552  		return nil, false, err
   553  	}
   554  	return bytes.NewReader(b), true, nil
   555  }
   556  
   557  // GetIgnoreConfiguredEndpoints is used in knowing when to disable configured
   558  // endpoints feature.
   559  func (c EnvConfig) GetIgnoreConfiguredEndpoints(context.Context) (bool, bool, error) {
   560  	if c.IgnoreConfiguredEndpoints == nil {
   561  		return false, false, nil
   562  	}
   563  
   564  	return *c.IgnoreConfiguredEndpoints, true, nil
   565  }
   566  
   567  func (c EnvConfig) getBaseEndpoint(context.Context) (string, bool, error) {
   568  	return c.BaseEndpoint, len(c.BaseEndpoint) > 0, nil
   569  }
   570  
   571  // GetServiceBaseEndpoint is used to retrieve a normalized SDK ID for use
   572  // with configured endpoints.
   573  func (c EnvConfig) GetServiceBaseEndpoint(ctx context.Context, sdkID string) (string, bool, error) {
   574  	if endpt := os.Getenv(fmt.Sprintf("%s_%s", awsEndpointURL, normalizeEnv(sdkID))); endpt != "" {
   575  		return endpt, true, nil
   576  	}
   577  	return "", false, nil
   578  }
   579  
   580  func normalizeEnv(sdkID string) string {
   581  	upper := strings.ToUpper(sdkID)
   582  	return strings.ReplaceAll(upper, " ", "_")
   583  }
   584  
   585  // GetS3UseARNRegion returns whether to allow ARNs to direct the region
   586  // the S3 client's requests are sent to.
   587  func (c EnvConfig) GetS3UseARNRegion(ctx context.Context) (value, ok bool, err error) {
   588  	if c.S3UseARNRegion == nil {
   589  		return false, false, nil
   590  	}
   591  
   592  	return *c.S3UseARNRegion, true, nil
   593  }
   594  
   595  // GetS3DisableMultiRegionAccessPoints returns whether to disable multi-region access point
   596  // support for the S3 client.
   597  func (c EnvConfig) GetS3DisableMultiRegionAccessPoints(ctx context.Context) (value, ok bool, err error) {
   598  	if c.S3DisableMultiRegionAccessPoints == nil {
   599  		return false, false, nil
   600  	}
   601  
   602  	return *c.S3DisableMultiRegionAccessPoints, true, nil
   603  }
   604  
   605  // GetUseDualStackEndpoint returns whether the service's dual-stack endpoint should be
   606  // used for requests.
   607  func (c EnvConfig) GetUseDualStackEndpoint(ctx context.Context) (value aws.DualStackEndpointState, found bool, err error) {
   608  	if c.UseDualStackEndpoint == aws.DualStackEndpointStateUnset {
   609  		return aws.DualStackEndpointStateUnset, false, nil
   610  	}
   611  
   612  	return c.UseDualStackEndpoint, true, nil
   613  }
   614  
   615  // GetUseFIPSEndpoint returns whether the service's FIPS endpoint should be
   616  // used for requests.
   617  func (c EnvConfig) GetUseFIPSEndpoint(ctx context.Context) (value aws.FIPSEndpointState, found bool, err error) {
   618  	if c.UseFIPSEndpoint == aws.FIPSEndpointStateUnset {
   619  		return aws.FIPSEndpointStateUnset, false, nil
   620  	}
   621  
   622  	return c.UseFIPSEndpoint, true, nil
   623  }
   624  
   625  func setStringFromEnvVal(dst *string, keys []string) {
   626  	for _, k := range keys {
   627  		if v := os.Getenv(k); len(v) > 0 {
   628  			*dst = v
   629  			break
   630  		}
   631  	}
   632  }
   633  
   634  func setIntFromEnvVal(dst *int, keys []string) error {
   635  	for _, k := range keys {
   636  		if v := os.Getenv(k); len(v) > 0 {
   637  			i, err := strconv.ParseInt(v, 10, 64)
   638  			if err != nil {
   639  				return fmt.Errorf("invalid value %s=%s, %w", k, v, err)
   640  			}
   641  			*dst = int(i)
   642  			break
   643  		}
   644  	}
   645  
   646  	return nil
   647  }
   648  
   649  func setBoolPtrFromEnvVal(dst **bool, keys []string) error {
   650  	for _, k := range keys {
   651  		value := os.Getenv(k)
   652  		if len(value) == 0 {
   653  			continue
   654  		}
   655  
   656  		if *dst == nil {
   657  			*dst = new(bool)
   658  		}
   659  
   660  		switch {
   661  		case strings.EqualFold(value, "false"):
   662  			**dst = false
   663  		case strings.EqualFold(value, "true"):
   664  			**dst = true
   665  		default:
   666  			return fmt.Errorf(
   667  				"invalid value for environment variable, %s=%s, need true or false",
   668  				k, value)
   669  		}
   670  		break
   671  	}
   672  
   673  	return nil
   674  }
   675  
   676  func setInt64PtrFromEnvVal(dst **int64, keys []string, max int64) error {
   677  	for _, k := range keys {
   678  		value := os.Getenv(k)
   679  		if len(value) == 0 {
   680  			continue
   681  		}
   682  
   683  		v, err := strconv.ParseInt(value, 10, 64)
   684  		if err != nil {
   685  			return fmt.Errorf("invalid value for env var, %s=%s, need int64", k, value)
   686  		} else if v < 0 || v > max {
   687  			return fmt.Errorf("invalid range for env var min request compression size bytes %q, must be within 0 and 10485760 inclusively", v)
   688  		}
   689  		if *dst == nil {
   690  			*dst = new(int64)
   691  		}
   692  
   693  		**dst = v
   694  		break
   695  	}
   696  
   697  	return nil
   698  }
   699  
   700  func setEndpointDiscoveryTypeFromEnvVal(dst *aws.EndpointDiscoveryEnableState, keys []string) error {
   701  	for _, k := range keys {
   702  		value := os.Getenv(k)
   703  		if len(value) == 0 {
   704  			continue // skip if empty
   705  		}
   706  
   707  		switch {
   708  		case strings.EqualFold(value, endpointDiscoveryDisabled):
   709  			*dst = aws.EndpointDiscoveryDisabled
   710  		case strings.EqualFold(value, endpointDiscoveryEnabled):
   711  			*dst = aws.EndpointDiscoveryEnabled
   712  		case strings.EqualFold(value, endpointDiscoveryAuto):
   713  			*dst = aws.EndpointDiscoveryAuto
   714  		default:
   715  			return fmt.Errorf(
   716  				"invalid value for environment variable, %s=%s, need true, false or auto",
   717  				k, value)
   718  		}
   719  	}
   720  	return nil
   721  }
   722  
   723  func setUseDualStackEndpointFromEnvVal(dst *aws.DualStackEndpointState, keys []string) error {
   724  	for _, k := range keys {
   725  		value := os.Getenv(k)
   726  		if len(value) == 0 {
   727  			continue // skip if empty
   728  		}
   729  
   730  		switch {
   731  		case strings.EqualFold(value, "true"):
   732  			*dst = aws.DualStackEndpointStateEnabled
   733  		case strings.EqualFold(value, "false"):
   734  			*dst = aws.DualStackEndpointStateDisabled
   735  		default:
   736  			return fmt.Errorf(
   737  				"invalid value for environment variable, %s=%s, need true, false",
   738  				k, value)
   739  		}
   740  	}
   741  	return nil
   742  }
   743  
   744  func setUseFIPSEndpointFromEnvVal(dst *aws.FIPSEndpointState, keys []string) error {
   745  	for _, k := range keys {
   746  		value := os.Getenv(k)
   747  		if len(value) == 0 {
   748  			continue // skip if empty
   749  		}
   750  
   751  		switch {
   752  		case strings.EqualFold(value, "true"):
   753  			*dst = aws.FIPSEndpointStateEnabled
   754  		case strings.EqualFold(value, "false"):
   755  			*dst = aws.FIPSEndpointStateDisabled
   756  		default:
   757  			return fmt.Errorf(
   758  				"invalid value for environment variable, %s=%s, need true, false",
   759  				k, value)
   760  		}
   761  	}
   762  	return nil
   763  }
   764  
   765  // GetEnableEndpointDiscovery returns resolved value for EnableEndpointDiscovery env variable setting.
   766  func (c EnvConfig) GetEnableEndpointDiscovery(ctx context.Context) (value aws.EndpointDiscoveryEnableState, found bool, err error) {
   767  	if c.EnableEndpointDiscovery == aws.EndpointDiscoveryUnset {
   768  		return aws.EndpointDiscoveryUnset, false, nil
   769  	}
   770  
   771  	return c.EnableEndpointDiscovery, true, nil
   772  }
   773  
   774  // GetEC2IMDSClientEnableState implements a EC2IMDSClientEnableState options resolver interface.
   775  func (c EnvConfig) GetEC2IMDSClientEnableState() (imds.ClientEnableState, bool, error) {
   776  	if c.EC2IMDSClientEnableState == imds.ClientDefaultEnableState {
   777  		return imds.ClientDefaultEnableState, false, nil
   778  	}
   779  
   780  	return c.EC2IMDSClientEnableState, true, nil
   781  }
   782  
   783  // GetEC2IMDSEndpointMode implements a EC2IMDSEndpointMode option resolver interface.
   784  func (c EnvConfig) GetEC2IMDSEndpointMode() (imds.EndpointModeState, bool, error) {
   785  	if c.EC2IMDSEndpointMode == imds.EndpointModeStateUnset {
   786  		return imds.EndpointModeStateUnset, false, nil
   787  	}
   788  
   789  	return c.EC2IMDSEndpointMode, true, nil
   790  }
   791  
   792  // GetEC2IMDSEndpoint implements a EC2IMDSEndpoint option resolver interface.
   793  func (c EnvConfig) GetEC2IMDSEndpoint() (string, bool, error) {
   794  	if len(c.EC2IMDSEndpoint) == 0 {
   795  		return "", false, nil
   796  	}
   797  
   798  	return c.EC2IMDSEndpoint, true, nil
   799  }
   800  
   801  // GetEC2IMDSV1FallbackDisabled implements an EC2IMDSV1FallbackDisabled option
   802  // resolver interface.
   803  func (c EnvConfig) GetEC2IMDSV1FallbackDisabled() (bool, bool) {
   804  	if c.EC2IMDSv1Disabled == nil {
   805  		return false, false
   806  	}
   807  
   808  	return *c.EC2IMDSv1Disabled, true
   809  }
   810  
   811  // GetS3DisableExpressAuth returns the configured value for
   812  // [EnvConfig.S3DisableExpressAuth].
   813  func (c EnvConfig) GetS3DisableExpressAuth() (value, ok bool) {
   814  	if c.S3DisableExpressAuth == nil {
   815  		return false, false
   816  	}
   817  
   818  	return *c.S3DisableExpressAuth, true
   819  }
   820  

View as plain text