mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	vendor github.com/aws/aws-sdk-go-v2/config v1.26.6 and related dependencies. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
		
			
				
	
	
		
			1585 lines
		
	
	
		
			47 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			1585 lines
		
	
	
		
			47 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package config
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"context"
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"io/ioutil"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/aws/aws-sdk-go-v2/aws"
 | 
						|
	"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
 | 
						|
	"github.com/aws/aws-sdk-go-v2/internal/ini"
 | 
						|
	"github.com/aws/aws-sdk-go-v2/internal/shareddefaults"
 | 
						|
	"github.com/aws/smithy-go/logging"
 | 
						|
	smithyrequestcompression "github.com/aws/smithy-go/private/requestcompression"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	// Prefix to use for filtering profiles. The profile prefix should only
 | 
						|
	// exist in the shared config file, not the credentials file.
 | 
						|
	profilePrefix = `profile `
 | 
						|
 | 
						|
	// Prefix to be used for SSO sections. These are supposed to only exist in
 | 
						|
	// the shared config file, not the credentials file.
 | 
						|
	ssoSectionPrefix = `sso-session `
 | 
						|
 | 
						|
	// Prefix for services section. It is referenced in profile via the services
 | 
						|
	// parameter to configure clients for service-specific parameters.
 | 
						|
	servicesPrefix = `services `
 | 
						|
 | 
						|
	// string equivalent for boolean
 | 
						|
	endpointDiscoveryDisabled = `false`
 | 
						|
	endpointDiscoveryEnabled  = `true`
 | 
						|
	endpointDiscoveryAuto     = `auto`
 | 
						|
 | 
						|
	// Static Credentials group
 | 
						|
	accessKeyIDKey  = `aws_access_key_id`     // group required
 | 
						|
	secretAccessKey = `aws_secret_access_key` // group required
 | 
						|
	sessionTokenKey = `aws_session_token`     // optional
 | 
						|
 | 
						|
	// Assume Role Credentials group
 | 
						|
	roleArnKey             = `role_arn`          // group required
 | 
						|
	sourceProfileKey       = `source_profile`    // group required
 | 
						|
	credentialSourceKey    = `credential_source` // group required (or source_profile)
 | 
						|
	externalIDKey          = `external_id`       // optional
 | 
						|
	mfaSerialKey           = `mfa_serial`        // optional
 | 
						|
	roleSessionNameKey     = `role_session_name` // optional
 | 
						|
	roleDurationSecondsKey = "duration_seconds"  // optional
 | 
						|
 | 
						|
	// AWS Single Sign-On (AWS SSO) group
 | 
						|
	ssoSessionNameKey = "sso_session"
 | 
						|
 | 
						|
	ssoRegionKey   = "sso_region"
 | 
						|
	ssoStartURLKey = "sso_start_url"
 | 
						|
 | 
						|
	ssoAccountIDKey = "sso_account_id"
 | 
						|
	ssoRoleNameKey  = "sso_role_name"
 | 
						|
 | 
						|
	// Additional Config fields
 | 
						|
	regionKey = `region`
 | 
						|
 | 
						|
	// endpoint discovery group
 | 
						|
	enableEndpointDiscoveryKey = `endpoint_discovery_enabled` // optional
 | 
						|
 | 
						|
	// External Credential process
 | 
						|
	credentialProcessKey = `credential_process` // optional
 | 
						|
 | 
						|
	// Web Identity Token File
 | 
						|
	webIdentityTokenFileKey = `web_identity_token_file` // optional
 | 
						|
 | 
						|
	// S3 ARN Region Usage
 | 
						|
	s3UseARNRegionKey = "s3_use_arn_region"
 | 
						|
 | 
						|
	ec2MetadataServiceEndpointModeKey = "ec2_metadata_service_endpoint_mode"
 | 
						|
 | 
						|
	ec2MetadataServiceEndpointKey = "ec2_metadata_service_endpoint"
 | 
						|
 | 
						|
	ec2MetadataV1DisabledKey = "ec2_metadata_v1_disabled"
 | 
						|
 | 
						|
	// Use DualStack Endpoint Resolution
 | 
						|
	useDualStackEndpoint = "use_dualstack_endpoint"
 | 
						|
 | 
						|
	// DefaultSharedConfigProfile is the default profile to be used when
 | 
						|
	// loading configuration from the config files if another profile name
 | 
						|
	// is not provided.
 | 
						|
	DefaultSharedConfigProfile = `default`
 | 
						|
 | 
						|
	// S3 Disable Multi-Region AccessPoints
 | 
						|
	s3DisableMultiRegionAccessPointsKey = `s3_disable_multiregion_access_points`
 | 
						|
 | 
						|
	useFIPSEndpointKey = "use_fips_endpoint"
 | 
						|
 | 
						|
	defaultsModeKey = "defaults_mode"
 | 
						|
 | 
						|
	// Retry options
 | 
						|
	retryMaxAttemptsKey = "max_attempts"
 | 
						|
	retryModeKey        = "retry_mode"
 | 
						|
 | 
						|
	caBundleKey = "ca_bundle"
 | 
						|
 | 
						|
	sdkAppID = "sdk_ua_app_id"
 | 
						|
 | 
						|
	ignoreConfiguredEndpoints = "ignore_configured_endpoint_urls"
 | 
						|
 | 
						|
	endpointURL = "endpoint_url"
 | 
						|
 | 
						|
	servicesSectionKey = "services"
 | 
						|
 | 
						|
	disableRequestCompression      = "disable_request_compression"
 | 
						|
	requestMinCompressionSizeBytes = "request_min_compression_size_bytes"
 | 
						|
 | 
						|
	s3DisableExpressSessionAuthKey = "s3_disable_express_session_auth"
 | 
						|
)
 | 
						|
 | 
						|
// defaultSharedConfigProfile allows for swapping the default profile for testing
 | 
						|
var defaultSharedConfigProfile = DefaultSharedConfigProfile
 | 
						|
 | 
						|
// DefaultSharedCredentialsFilename returns the SDK's default file path
 | 
						|
// for the shared credentials file.
 | 
						|
//
 | 
						|
// Builds the shared config file path based on the OS's platform.
 | 
						|
//
 | 
						|
//   - Linux/Unix: $HOME/.aws/credentials
 | 
						|
//   - Windows: %USERPROFILE%\.aws\credentials
 | 
						|
func DefaultSharedCredentialsFilename() string {
 | 
						|
	return filepath.Join(shareddefaults.UserHomeDir(), ".aws", "credentials")
 | 
						|
}
 | 
						|
 | 
						|
// DefaultSharedConfigFilename returns the SDK's default file path for
 | 
						|
// the shared config file.
 | 
						|
//
 | 
						|
// Builds the shared config file path based on the OS's platform.
 | 
						|
//
 | 
						|
//   - Linux/Unix: $HOME/.aws/config
 | 
						|
//   - Windows: %USERPROFILE%\.aws\config
 | 
						|
func DefaultSharedConfigFilename() string {
 | 
						|
	return filepath.Join(shareddefaults.UserHomeDir(), ".aws", "config")
 | 
						|
}
 | 
						|
 | 
						|
// DefaultSharedConfigFiles is a slice of the default shared config files that
 | 
						|
// the will be used in order to load the SharedConfig.
 | 
						|
var DefaultSharedConfigFiles = []string{
 | 
						|
	DefaultSharedConfigFilename(),
 | 
						|
}
 | 
						|
 | 
						|
// DefaultSharedCredentialsFiles is a slice of the default shared credentials
 | 
						|
// files that the will be used in order to load the SharedConfig.
 | 
						|
var DefaultSharedCredentialsFiles = []string{
 | 
						|
	DefaultSharedCredentialsFilename(),
 | 
						|
}
 | 
						|
 | 
						|
// SSOSession provides the shared configuration parameters of the sso-session
 | 
						|
// section.
 | 
						|
type SSOSession struct {
 | 
						|
	Name        string
 | 
						|
	SSORegion   string
 | 
						|
	SSOStartURL string
 | 
						|
}
 | 
						|
 | 
						|
func (s *SSOSession) setFromIniSection(section ini.Section) {
 | 
						|
	updateString(&s.Name, section, ssoSessionNameKey)
 | 
						|
	updateString(&s.SSORegion, section, ssoRegionKey)
 | 
						|
	updateString(&s.SSOStartURL, section, ssoStartURLKey)
 | 
						|
}
 | 
						|
 | 
						|
// Services contains values configured in the services section
 | 
						|
// of the AWS configuration file.
 | 
						|
type Services struct {
 | 
						|
	// Services section values
 | 
						|
	// {"serviceId": {"key": "value"}}
 | 
						|
	// e.g. {"s3": {"endpoint_url": "example.com"}}
 | 
						|
	ServiceValues map[string]map[string]string
 | 
						|
}
 | 
						|
 | 
						|
func (s *Services) setFromIniSection(section ini.Section) {
 | 
						|
	if s.ServiceValues == nil {
 | 
						|
		s.ServiceValues = make(map[string]map[string]string)
 | 
						|
	}
 | 
						|
	for _, service := range section.List() {
 | 
						|
		s.ServiceValues[service] = section.Map(service)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// SharedConfig represents the configuration fields of the SDK config files.
 | 
						|
type SharedConfig struct {
 | 
						|
	Profile string
 | 
						|
 | 
						|
	// Credentials values from the config file. Both aws_access_key_id
 | 
						|
	// and aws_secret_access_key must be provided together in the same file
 | 
						|
	// to be considered valid. The values will be ignored if not a complete group.
 | 
						|
	// aws_session_token is an optional field that can be provided if both of the
 | 
						|
	// other two fields are also provided.
 | 
						|
	//
 | 
						|
	//	aws_access_key_id
 | 
						|
	//	aws_secret_access_key
 | 
						|
	//	aws_session_token
 | 
						|
	Credentials aws.Credentials
 | 
						|
 | 
						|
	CredentialSource     string
 | 
						|
	CredentialProcess    string
 | 
						|
	WebIdentityTokenFile string
 | 
						|
 | 
						|
	// SSO session options
 | 
						|
	SSOSessionName string
 | 
						|
	SSOSession     *SSOSession
 | 
						|
 | 
						|
	// Legacy SSO session options
 | 
						|
	SSORegion   string
 | 
						|
	SSOStartURL string
 | 
						|
 | 
						|
	// SSO fields not used
 | 
						|
	SSOAccountID string
 | 
						|
	SSORoleName  string
 | 
						|
 | 
						|
	RoleARN             string
 | 
						|
	ExternalID          string
 | 
						|
	MFASerial           string
 | 
						|
	RoleSessionName     string
 | 
						|
	RoleDurationSeconds *time.Duration
 | 
						|
 | 
						|
	SourceProfileName string
 | 
						|
	Source            *SharedConfig
 | 
						|
 | 
						|
	// Region is the region the SDK should use for looking up AWS service endpoints
 | 
						|
	// and signing requests.
 | 
						|
	//
 | 
						|
	//	region = us-west-2
 | 
						|
	Region string
 | 
						|
 | 
						|
	// EnableEndpointDiscovery can be enabled or disabled in the shared config
 | 
						|
	// by setting endpoint_discovery_enabled to true, or false respectively.
 | 
						|
	//
 | 
						|
	//	endpoint_discovery_enabled = true
 | 
						|
	EnableEndpointDiscovery aws.EndpointDiscoveryEnableState
 | 
						|
 | 
						|
	// Specifies if the S3 service should allow ARNs to direct the region
 | 
						|
	// the client's requests are sent to.
 | 
						|
	//
 | 
						|
	// s3_use_arn_region=true
 | 
						|
	S3UseARNRegion *bool
 | 
						|
 | 
						|
	// Specifies the EC2 Instance Metadata Service default endpoint selection
 | 
						|
	// mode (IPv4 or IPv6)
 | 
						|
	//
 | 
						|
	// ec2_metadata_service_endpoint_mode=IPv6
 | 
						|
	EC2IMDSEndpointMode imds.EndpointModeState
 | 
						|
 | 
						|
	// Specifies the EC2 Instance Metadata Service endpoint to use. If
 | 
						|
	// specified it overrides EC2IMDSEndpointMode.
 | 
						|
	//
 | 
						|
	// ec2_metadata_service_endpoint=http://fd00:ec2::254
 | 
						|
	EC2IMDSEndpoint string
 | 
						|
 | 
						|
	// Specifies that IMDS clients should not fallback to IMDSv1 if token
 | 
						|
	// requests fail.
 | 
						|
	//
 | 
						|
	// ec2_metadata_v1_disabled=true
 | 
						|
	EC2IMDSv1Disabled *bool
 | 
						|
 | 
						|
	// Specifies if the S3 service should disable support for Multi-Region
 | 
						|
	// access-points
 | 
						|
	//
 | 
						|
	// s3_disable_multiregion_access_points=true
 | 
						|
	S3DisableMultiRegionAccessPoints *bool
 | 
						|
 | 
						|
	// Specifies that SDK clients must resolve a dual-stack endpoint for
 | 
						|
	// services.
 | 
						|
	//
 | 
						|
	// use_dualstack_endpoint=true
 | 
						|
	UseDualStackEndpoint aws.DualStackEndpointState
 | 
						|
 | 
						|
	// Specifies that SDK clients must resolve a FIPS endpoint for
 | 
						|
	// services.
 | 
						|
	//
 | 
						|
	// use_fips_endpoint=true
 | 
						|
	UseFIPSEndpoint aws.FIPSEndpointState
 | 
						|
 | 
						|
	// Specifies which defaults mode should be used by services.
 | 
						|
	//
 | 
						|
	// defaults_mode=standard
 | 
						|
	DefaultsMode aws.DefaultsMode
 | 
						|
 | 
						|
	// Specifies the maximum number attempts an API client will call an
 | 
						|
	// operation that fails with a retryable error.
 | 
						|
	//
 | 
						|
	// max_attempts=3
 | 
						|
	RetryMaxAttempts int
 | 
						|
 | 
						|
	// Specifies the retry model the API client will be created with.
 | 
						|
	//
 | 
						|
	// retry_mode=standard
 | 
						|
	RetryMode aws.RetryMode
 | 
						|
 | 
						|
	// Sets the path to a custom Credentials Authority (CA) Bundle PEM file
 | 
						|
	// that the SDK will use instead of the system's root CA bundle. Only use
 | 
						|
	// this if you want to configure the SDK to use a custom set of CAs.
 | 
						|
	//
 | 
						|
	// Enabling this option will attempt to merge the Transport into the SDK's
 | 
						|
	// HTTP client. If the client's Transport is not a http.Transport an error
 | 
						|
	// will be returned. If the Transport's TLS config is set this option will
 | 
						|
	// cause the SDK to overwrite the Transport's TLS config's  RootCAs value.
 | 
						|
	//
 | 
						|
	// Setting a custom HTTPClient in the aws.Config options will override this
 | 
						|
	// setting. To use this option and custom HTTP client, the HTTP client
 | 
						|
	// needs to be provided when creating the config. Not the service client.
 | 
						|
	//
 | 
						|
	//  ca_bundle=$HOME/my_custom_ca_bundle
 | 
						|
	CustomCABundle string
 | 
						|
 | 
						|
	// aws sdk app ID that can be added to user agent header string
 | 
						|
	AppID string
 | 
						|
 | 
						|
	// Flag used to disable configured endpoints.
 | 
						|
	IgnoreConfiguredEndpoints *bool
 | 
						|
 | 
						|
	// Value to contain configured endpoints to be propagated to
 | 
						|
	// corresponding endpoint resolution field.
 | 
						|
	BaseEndpoint string
 | 
						|
 | 
						|
	// Services section config.
 | 
						|
	ServicesSectionName string
 | 
						|
	Services            Services
 | 
						|
 | 
						|
	// determine if request compression is allowed, default to false
 | 
						|
	// retrieved from config file's profile field disable_request_compression
 | 
						|
	DisableRequestCompression *bool
 | 
						|
 | 
						|
	// inclusive threshold request body size to trigger compression,
 | 
						|
	// default to 10240 and must be within 0 and 10485760 bytes inclusive
 | 
						|
	// retrieved from config file's profile field request_min_compression_size_bytes
 | 
						|
	RequestMinCompressSizeBytes *int64
 | 
						|
 | 
						|
	// Whether S3Express auth is disabled.
 | 
						|
	//
 | 
						|
	// This will NOT prevent requests from being made to S3Express buckets, it
 | 
						|
	// will only bypass the modified endpoint routing and signing behaviors
 | 
						|
	// associated with the feature.
 | 
						|
	S3DisableExpressAuth *bool
 | 
						|
}
 | 
						|
 | 
						|
func (c SharedConfig) getDefaultsMode(ctx context.Context) (value aws.DefaultsMode, ok bool, err error) {
 | 
						|
	if len(c.DefaultsMode) == 0 {
 | 
						|
		return "", false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return c.DefaultsMode, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetRetryMaxAttempts returns the maximum number of attempts an API client
 | 
						|
// created Retryer should attempt an operation call before failing.
 | 
						|
func (c SharedConfig) GetRetryMaxAttempts(ctx context.Context) (value int, ok bool, err error) {
 | 
						|
	if c.RetryMaxAttempts == 0 {
 | 
						|
		return 0, false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return c.RetryMaxAttempts, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetRetryMode returns the model the API client should create its Retryer in.
 | 
						|
func (c SharedConfig) GetRetryMode(ctx context.Context) (value aws.RetryMode, ok bool, err error) {
 | 
						|
	if len(c.RetryMode) == 0 {
 | 
						|
		return "", false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return c.RetryMode, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetS3UseARNRegion returns if the S3 service should allow ARNs to direct the region
 | 
						|
// the client's requests are sent to.
 | 
						|
func (c SharedConfig) GetS3UseARNRegion(ctx context.Context) (value, ok bool, err error) {
 | 
						|
	if c.S3UseARNRegion == nil {
 | 
						|
		return false, false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return *c.S3UseARNRegion, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetEnableEndpointDiscovery returns if the enable_endpoint_discovery is set.
 | 
						|
func (c SharedConfig) GetEnableEndpointDiscovery(ctx context.Context) (value aws.EndpointDiscoveryEnableState, ok bool, err error) {
 | 
						|
	if c.EnableEndpointDiscovery == aws.EndpointDiscoveryUnset {
 | 
						|
		return aws.EndpointDiscoveryUnset, false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return c.EnableEndpointDiscovery, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetS3DisableMultiRegionAccessPoints returns if the S3 service should disable support for Multi-Region
 | 
						|
// access-points.
 | 
						|
func (c SharedConfig) GetS3DisableMultiRegionAccessPoints(ctx context.Context) (value, ok bool, err error) {
 | 
						|
	if c.S3DisableMultiRegionAccessPoints == nil {
 | 
						|
		return false, false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return *c.S3DisableMultiRegionAccessPoints, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetRegion returns the region for the profile if a region is set.
 | 
						|
func (c SharedConfig) getRegion(ctx context.Context) (string, bool, error) {
 | 
						|
	if len(c.Region) == 0 {
 | 
						|
		return "", false, nil
 | 
						|
	}
 | 
						|
	return c.Region, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetCredentialsProvider returns the credentials for a profile if they were set.
 | 
						|
func (c SharedConfig) getCredentialsProvider() (aws.Credentials, bool, error) {
 | 
						|
	return c.Credentials, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetEC2IMDSEndpointMode implements a EC2IMDSEndpointMode option resolver interface.
 | 
						|
func (c SharedConfig) GetEC2IMDSEndpointMode() (imds.EndpointModeState, bool, error) {
 | 
						|
	if c.EC2IMDSEndpointMode == imds.EndpointModeStateUnset {
 | 
						|
		return imds.EndpointModeStateUnset, false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return c.EC2IMDSEndpointMode, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetEC2IMDSEndpoint implements a EC2IMDSEndpoint option resolver interface.
 | 
						|
func (c SharedConfig) GetEC2IMDSEndpoint() (string, bool, error) {
 | 
						|
	if len(c.EC2IMDSEndpoint) == 0 {
 | 
						|
		return "", false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return c.EC2IMDSEndpoint, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetEC2IMDSV1FallbackDisabled implements an EC2IMDSV1FallbackDisabled option
 | 
						|
// resolver interface.
 | 
						|
func (c SharedConfig) GetEC2IMDSV1FallbackDisabled() (bool, bool) {
 | 
						|
	if c.EC2IMDSv1Disabled == nil {
 | 
						|
		return false, false
 | 
						|
	}
 | 
						|
 | 
						|
	return *c.EC2IMDSv1Disabled, true
 | 
						|
}
 | 
						|
 | 
						|
// GetUseDualStackEndpoint returns whether the service's dual-stack endpoint should be
 | 
						|
// used for requests.
 | 
						|
func (c SharedConfig) GetUseDualStackEndpoint(ctx context.Context) (value aws.DualStackEndpointState, found bool, err error) {
 | 
						|
	if c.UseDualStackEndpoint == aws.DualStackEndpointStateUnset {
 | 
						|
		return aws.DualStackEndpointStateUnset, false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return c.UseDualStackEndpoint, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetUseFIPSEndpoint returns whether the service's FIPS endpoint should be
 | 
						|
// used for requests.
 | 
						|
func (c SharedConfig) GetUseFIPSEndpoint(ctx context.Context) (value aws.FIPSEndpointState, found bool, err error) {
 | 
						|
	if c.UseFIPSEndpoint == aws.FIPSEndpointStateUnset {
 | 
						|
		return aws.FIPSEndpointStateUnset, false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return c.UseFIPSEndpoint, true, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetS3DisableExpressAuth returns the configured value for
 | 
						|
// [SharedConfig.S3DisableExpressAuth].
 | 
						|
func (c SharedConfig) GetS3DisableExpressAuth() (value, ok bool) {
 | 
						|
	if c.S3DisableExpressAuth == nil {
 | 
						|
		return false, false
 | 
						|
	}
 | 
						|
 | 
						|
	return *c.S3DisableExpressAuth, true
 | 
						|
}
 | 
						|
 | 
						|
// GetCustomCABundle returns the custom CA bundle's PEM bytes if the file was
 | 
						|
func (c SharedConfig) getCustomCABundle(context.Context) (io.Reader, bool, error) {
 | 
						|
	if len(c.CustomCABundle) == 0 {
 | 
						|
		return nil, false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	b, err := ioutil.ReadFile(c.CustomCABundle)
 | 
						|
	if err != nil {
 | 
						|
		return nil, false, err
 | 
						|
	}
 | 
						|
	return bytes.NewReader(b), true, nil
 | 
						|
}
 | 
						|
 | 
						|
// getAppID returns the sdk app ID if set in shared config profile
 | 
						|
func (c SharedConfig) getAppID(context.Context) (string, bool, error) {
 | 
						|
	return c.AppID, len(c.AppID) > 0, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetIgnoreConfiguredEndpoints is used in knowing when to disable configured
 | 
						|
// endpoints feature.
 | 
						|
func (c SharedConfig) GetIgnoreConfiguredEndpoints(context.Context) (bool, bool, error) {
 | 
						|
	if c.IgnoreConfiguredEndpoints == nil {
 | 
						|
		return false, false, nil
 | 
						|
	}
 | 
						|
 | 
						|
	return *c.IgnoreConfiguredEndpoints, true, nil
 | 
						|
}
 | 
						|
 | 
						|
func (c SharedConfig) getBaseEndpoint(context.Context) (string, bool, error) {
 | 
						|
	return c.BaseEndpoint, len(c.BaseEndpoint) > 0, nil
 | 
						|
}
 | 
						|
 | 
						|
// GetServiceBaseEndpoint is used to retrieve a normalized SDK ID for use
 | 
						|
// with configured endpoints.
 | 
						|
func (c SharedConfig) GetServiceBaseEndpoint(ctx context.Context, sdkID string) (string, bool, error) {
 | 
						|
	if service, ok := c.Services.ServiceValues[normalizeShared(sdkID)]; ok {
 | 
						|
		if endpt, ok := service[endpointURL]; ok {
 | 
						|
			return endpt, true, nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return "", false, nil
 | 
						|
}
 | 
						|
 | 
						|
func normalizeShared(sdkID string) string {
 | 
						|
	lower := strings.ToLower(sdkID)
 | 
						|
	return strings.ReplaceAll(lower, " ", "_")
 | 
						|
}
 | 
						|
 | 
						|
func (c SharedConfig) getServicesObject(context.Context) (map[string]map[string]string, bool, error) {
 | 
						|
	return c.Services.ServiceValues, c.Services.ServiceValues != nil, nil
 | 
						|
}
 | 
						|
 | 
						|
// loadSharedConfigIgnoreNotExist is an alias for loadSharedConfig with the
 | 
						|
// addition of ignoring when none of the files exist or when the profile
 | 
						|
// is not found in any of the files.
 | 
						|
func loadSharedConfigIgnoreNotExist(ctx context.Context, configs configs) (Config, error) {
 | 
						|
	cfg, err := loadSharedConfig(ctx, configs)
 | 
						|
	if err != nil {
 | 
						|
		if _, ok := err.(SharedConfigProfileNotExistError); ok {
 | 
						|
			return SharedConfig{}, nil
 | 
						|
		}
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	return cfg, nil
 | 
						|
}
 | 
						|
 | 
						|
// loadSharedConfig uses the configs passed in to load the SharedConfig from file
 | 
						|
// The file names and profile name are sourced from the configs.
 | 
						|
//
 | 
						|
// If profile name is not provided DefaultSharedConfigProfile (default) will
 | 
						|
// be used.
 | 
						|
//
 | 
						|
// If shared config filenames are not provided DefaultSharedConfigFiles will
 | 
						|
// be used.
 | 
						|
//
 | 
						|
// Config providers used:
 | 
						|
// * sharedConfigProfileProvider
 | 
						|
// * sharedConfigFilesProvider
 | 
						|
func loadSharedConfig(ctx context.Context, configs configs) (Config, error) {
 | 
						|
	var profile string
 | 
						|
	var configFiles []string
 | 
						|
	var credentialsFiles []string
 | 
						|
	var ok bool
 | 
						|
	var err error
 | 
						|
 | 
						|
	profile, ok, err = getSharedConfigProfile(ctx, configs)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	if !ok {
 | 
						|
		profile = defaultSharedConfigProfile
 | 
						|
	}
 | 
						|
 | 
						|
	configFiles, ok, err = getSharedConfigFiles(ctx, configs)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	credentialsFiles, ok, err = getSharedCredentialsFiles(ctx, configs)
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	// setup logger if log configuration warning is seti
 | 
						|
	var logger logging.Logger
 | 
						|
	logWarnings, found, err := getLogConfigurationWarnings(ctx, configs)
 | 
						|
	if err != nil {
 | 
						|
		return SharedConfig{}, err
 | 
						|
	}
 | 
						|
	if found && logWarnings {
 | 
						|
		logger, found, err = getLogger(ctx, configs)
 | 
						|
		if err != nil {
 | 
						|
			return SharedConfig{}, err
 | 
						|
		}
 | 
						|
		if !found {
 | 
						|
			logger = logging.NewStandardLogger(os.Stderr)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return LoadSharedConfigProfile(ctx, profile,
 | 
						|
		func(o *LoadSharedConfigOptions) {
 | 
						|
			o.Logger = logger
 | 
						|
			o.ConfigFiles = configFiles
 | 
						|
			o.CredentialsFiles = credentialsFiles
 | 
						|
		},
 | 
						|
	)
 | 
						|
}
 | 
						|
 | 
						|
// LoadSharedConfigOptions struct contains optional values that can be used to load the config.
 | 
						|
type LoadSharedConfigOptions struct {
 | 
						|
 | 
						|
	// CredentialsFiles are the shared credentials files
 | 
						|
	CredentialsFiles []string
 | 
						|
 | 
						|
	// ConfigFiles are the shared config files
 | 
						|
	ConfigFiles []string
 | 
						|
 | 
						|
	// Logger is the logger used to log shared config behavior
 | 
						|
	Logger logging.Logger
 | 
						|
}
 | 
						|
 | 
						|
// LoadSharedConfigProfile retrieves the configuration from the list of files
 | 
						|
// using the profile provided. The order the files are listed will determine
 | 
						|
// precedence. Values in subsequent files will overwrite values defined in
 | 
						|
// earlier files.
 | 
						|
//
 | 
						|
// For example, given two files A and B. Both define credentials. If the order
 | 
						|
// of the files are A then B, B's credential values will be used instead of A's.
 | 
						|
//
 | 
						|
// If config files are not set, SDK will default to using a file at location `.aws/config` if present.
 | 
						|
// If credentials files are not set, SDK will default to using a file at location `.aws/credentials` if present.
 | 
						|
// No default files are set, if files set to an empty slice.
 | 
						|
//
 | 
						|
// You can read more about shared config and credentials file location at
 | 
						|
// https://docs.aws.amazon.com/credref/latest/refdocs/file-location.html#file-location
 | 
						|
func LoadSharedConfigProfile(ctx context.Context, profile string, optFns ...func(*LoadSharedConfigOptions)) (SharedConfig, error) {
 | 
						|
	var option LoadSharedConfigOptions
 | 
						|
	for _, fn := range optFns {
 | 
						|
		fn(&option)
 | 
						|
	}
 | 
						|
 | 
						|
	if option.ConfigFiles == nil {
 | 
						|
		option.ConfigFiles = DefaultSharedConfigFiles
 | 
						|
	}
 | 
						|
 | 
						|
	if option.CredentialsFiles == nil {
 | 
						|
		option.CredentialsFiles = DefaultSharedCredentialsFiles
 | 
						|
	}
 | 
						|
 | 
						|
	// load shared configuration sections from shared configuration INI options
 | 
						|
	configSections, err := loadIniFiles(option.ConfigFiles)
 | 
						|
	if err != nil {
 | 
						|
		return SharedConfig{}, err
 | 
						|
	}
 | 
						|
 | 
						|
	// check for profile prefix and drop duplicates or invalid profiles
 | 
						|
	err = processConfigSections(ctx, &configSections, option.Logger)
 | 
						|
	if err != nil {
 | 
						|
		return SharedConfig{}, err
 | 
						|
	}
 | 
						|
 | 
						|
	// load shared credentials sections from shared credentials INI options
 | 
						|
	credentialsSections, err := loadIniFiles(option.CredentialsFiles)
 | 
						|
	if err != nil {
 | 
						|
		return SharedConfig{}, err
 | 
						|
	}
 | 
						|
 | 
						|
	// check for profile prefix and drop duplicates or invalid profiles
 | 
						|
	err = processCredentialsSections(ctx, &credentialsSections, option.Logger)
 | 
						|
	if err != nil {
 | 
						|
		return SharedConfig{}, err
 | 
						|
	}
 | 
						|
 | 
						|
	err = mergeSections(&configSections, credentialsSections)
 | 
						|
	if err != nil {
 | 
						|
		return SharedConfig{}, err
 | 
						|
	}
 | 
						|
 | 
						|
	cfg := SharedConfig{}
 | 
						|
	profiles := map[string]struct{}{}
 | 
						|
 | 
						|
	if err = cfg.setFromIniSections(profiles, profile, configSections, option.Logger); err != nil {
 | 
						|
		return SharedConfig{}, err
 | 
						|
	}
 | 
						|
 | 
						|
	return cfg, nil
 | 
						|
}
 | 
						|
 | 
						|
func processConfigSections(ctx context.Context, sections *ini.Sections, logger logging.Logger) error {
 | 
						|
	skipSections := map[string]struct{}{}
 | 
						|
 | 
						|
	for _, section := range sections.List() {
 | 
						|
		if _, ok := skipSections[section]; ok {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		// drop sections from config file that do not have expected prefixes.
 | 
						|
		switch {
 | 
						|
		case strings.HasPrefix(section, profilePrefix):
 | 
						|
			// Rename sections to remove "profile " prefixing to match with
 | 
						|
			// credentials file. If default is already present, it will be
 | 
						|
			// dropped.
 | 
						|
			newName, err := renameProfileSection(section, sections, logger)
 | 
						|
			if err != nil {
 | 
						|
				return fmt.Errorf("failed to rename profile section, %w", err)
 | 
						|
			}
 | 
						|
			skipSections[newName] = struct{}{}
 | 
						|
 | 
						|
		case strings.HasPrefix(section, ssoSectionPrefix):
 | 
						|
		case strings.HasPrefix(section, servicesPrefix):
 | 
						|
		case strings.EqualFold(section, "default"):
 | 
						|
		default:
 | 
						|
			// drop this section, as invalid profile name
 | 
						|
			sections.DeleteSection(section)
 | 
						|
 | 
						|
			if logger != nil {
 | 
						|
				logger.Logf(logging.Debug, "A profile defined with name `%v` is ignored. "+
 | 
						|
					"For use within a shared configuration file, "+
 | 
						|
					"a non-default profile must have `profile ` "+
 | 
						|
					"prefixed to the profile name.",
 | 
						|
					section,
 | 
						|
				)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func renameProfileSection(section string, sections *ini.Sections, logger logging.Logger) (string, error) {
 | 
						|
	v, ok := sections.GetSection(section)
 | 
						|
	if !ok {
 | 
						|
		return "", fmt.Errorf("error processing profiles within the shared configuration files")
 | 
						|
	}
 | 
						|
 | 
						|
	// delete section with profile as prefix
 | 
						|
	sections.DeleteSection(section)
 | 
						|
 | 
						|
	// set the value to non-prefixed name in sections.
 | 
						|
	section = strings.TrimPrefix(section, profilePrefix)
 | 
						|
	if sections.HasSection(section) {
 | 
						|
		oldSection, _ := sections.GetSection(section)
 | 
						|
		v.Logs = append(v.Logs,
 | 
						|
			fmt.Sprintf("A non-default profile not prefixed with `profile ` found in %s, "+
 | 
						|
				"overriding non-default profile from %s",
 | 
						|
				v.SourceFile, oldSection.SourceFile))
 | 
						|
		sections.DeleteSection(section)
 | 
						|
	}
 | 
						|
 | 
						|
	// assign non-prefixed name to section
 | 
						|
	v.Name = section
 | 
						|
	sections.SetSection(section, v)
 | 
						|
 | 
						|
	return section, nil
 | 
						|
}
 | 
						|
 | 
						|
func processCredentialsSections(ctx context.Context, sections *ini.Sections, logger logging.Logger) error {
 | 
						|
	for _, section := range sections.List() {
 | 
						|
		// drop profiles with prefix for credential files
 | 
						|
		if strings.HasPrefix(section, profilePrefix) {
 | 
						|
			// drop this section, as invalid profile name
 | 
						|
			sections.DeleteSection(section)
 | 
						|
 | 
						|
			if logger != nil {
 | 
						|
				logger.Logf(logging.Debug,
 | 
						|
					"The profile defined with name `%v` is ignored. A profile with the `profile ` prefix is invalid "+
 | 
						|
						"for the shared credentials file.\n",
 | 
						|
					section,
 | 
						|
				)
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func loadIniFiles(filenames []string) (ini.Sections, error) {
 | 
						|
	mergedSections := ini.NewSections()
 | 
						|
 | 
						|
	for _, filename := range filenames {
 | 
						|
		sections, err := ini.OpenFile(filename)
 | 
						|
		var v *ini.UnableToReadFile
 | 
						|
		if ok := errors.As(err, &v); ok {
 | 
						|
			// Skip files which can't be opened and read for whatever reason.
 | 
						|
			// We treat such files as empty, and do not fall back to other locations.
 | 
						|
			continue
 | 
						|
		} else if err != nil {
 | 
						|
			return ini.Sections{}, SharedConfigLoadError{Filename: filename, Err: err}
 | 
						|
		}
 | 
						|
 | 
						|
		// mergeSections into mergedSections
 | 
						|
		err = mergeSections(&mergedSections, sections)
 | 
						|
		if err != nil {
 | 
						|
			return ini.Sections{}, SharedConfigLoadError{Filename: filename, Err: err}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return mergedSections, nil
 | 
						|
}
 | 
						|
 | 
						|
// mergeSections merges source section properties into destination section properties
 | 
						|
func mergeSections(dst *ini.Sections, src ini.Sections) error {
 | 
						|
	for _, sectionName := range src.List() {
 | 
						|
		srcSection, _ := src.GetSection(sectionName)
 | 
						|
 | 
						|
		if (!srcSection.Has(accessKeyIDKey) && srcSection.Has(secretAccessKey)) ||
 | 
						|
			(srcSection.Has(accessKeyIDKey) && !srcSection.Has(secretAccessKey)) {
 | 
						|
			srcSection.Errors = append(srcSection.Errors,
 | 
						|
				fmt.Errorf("partial credentials found for profile %v", sectionName))
 | 
						|
		}
 | 
						|
 | 
						|
		if !dst.HasSection(sectionName) {
 | 
						|
			dst.SetSection(sectionName, srcSection)
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		// merge with destination srcSection
 | 
						|
		dstSection, _ := dst.GetSection(sectionName)
 | 
						|
 | 
						|
		// errors should be overriden if any
 | 
						|
		dstSection.Errors = srcSection.Errors
 | 
						|
 | 
						|
		// Access key id update
 | 
						|
		if srcSection.Has(accessKeyIDKey) && srcSection.Has(secretAccessKey) {
 | 
						|
			accessKey := srcSection.String(accessKeyIDKey)
 | 
						|
			secretKey := srcSection.String(secretAccessKey)
 | 
						|
 | 
						|
			if dstSection.Has(accessKeyIDKey) {
 | 
						|
				dstSection.Logs = append(dstSection.Logs, newMergeKeyLogMessage(sectionName, accessKeyIDKey,
 | 
						|
					dstSection.SourceFile[accessKeyIDKey], srcSection.SourceFile[accessKeyIDKey]))
 | 
						|
			}
 | 
						|
 | 
						|
			// update access key
 | 
						|
			v, err := ini.NewStringValue(accessKey)
 | 
						|
			if err != nil {
 | 
						|
				return fmt.Errorf("error merging access key, %w", err)
 | 
						|
			}
 | 
						|
			dstSection.UpdateValue(accessKeyIDKey, v)
 | 
						|
 | 
						|
			// update secret key
 | 
						|
			v, err = ini.NewStringValue(secretKey)
 | 
						|
			if err != nil {
 | 
						|
				return fmt.Errorf("error merging secret key, %w", err)
 | 
						|
			}
 | 
						|
			dstSection.UpdateValue(secretAccessKey, v)
 | 
						|
 | 
						|
			// update session token
 | 
						|
			if err = mergeStringKey(&srcSection, &dstSection, sectionName, sessionTokenKey); err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
 | 
						|
			// update source file to reflect where the static creds came from
 | 
						|
			dstSection.UpdateSourceFile(accessKeyIDKey, srcSection.SourceFile[accessKeyIDKey])
 | 
						|
			dstSection.UpdateSourceFile(secretAccessKey, srcSection.SourceFile[secretAccessKey])
 | 
						|
		}
 | 
						|
 | 
						|
		stringKeys := []string{
 | 
						|
			roleArnKey,
 | 
						|
			sourceProfileKey,
 | 
						|
			credentialSourceKey,
 | 
						|
			externalIDKey,
 | 
						|
			mfaSerialKey,
 | 
						|
			roleSessionNameKey,
 | 
						|
			regionKey,
 | 
						|
			enableEndpointDiscoveryKey,
 | 
						|
			credentialProcessKey,
 | 
						|
			webIdentityTokenFileKey,
 | 
						|
			s3UseARNRegionKey,
 | 
						|
			s3DisableMultiRegionAccessPointsKey,
 | 
						|
			ec2MetadataServiceEndpointModeKey,
 | 
						|
			ec2MetadataServiceEndpointKey,
 | 
						|
			ec2MetadataV1DisabledKey,
 | 
						|
			useDualStackEndpoint,
 | 
						|
			useFIPSEndpointKey,
 | 
						|
			defaultsModeKey,
 | 
						|
			retryModeKey,
 | 
						|
			caBundleKey,
 | 
						|
			roleDurationSecondsKey,
 | 
						|
			retryMaxAttemptsKey,
 | 
						|
 | 
						|
			ssoSessionNameKey,
 | 
						|
			ssoAccountIDKey,
 | 
						|
			ssoRegionKey,
 | 
						|
			ssoRoleNameKey,
 | 
						|
			ssoStartURLKey,
 | 
						|
		}
 | 
						|
		for i := range stringKeys {
 | 
						|
			if err := mergeStringKey(&srcSection, &dstSection, sectionName, stringKeys[i]); err != nil {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		// set srcSection on dst srcSection
 | 
						|
		*dst = dst.SetSection(sectionName, dstSection)
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func mergeStringKey(srcSection *ini.Section, dstSection *ini.Section, sectionName, key string) error {
 | 
						|
	if srcSection.Has(key) {
 | 
						|
		srcValue := srcSection.String(key)
 | 
						|
		val, err := ini.NewStringValue(srcValue)
 | 
						|
		if err != nil {
 | 
						|
			return fmt.Errorf("error merging %s, %w", key, err)
 | 
						|
		}
 | 
						|
 | 
						|
		if dstSection.Has(key) {
 | 
						|
			dstSection.Logs = append(dstSection.Logs, newMergeKeyLogMessage(sectionName, key,
 | 
						|
				dstSection.SourceFile[key], srcSection.SourceFile[key]))
 | 
						|
		}
 | 
						|
 | 
						|
		dstSection.UpdateValue(key, val)
 | 
						|
		dstSection.UpdateSourceFile(key, srcSection.SourceFile[key])
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func newMergeKeyLogMessage(sectionName, key, dstSourceFile, srcSourceFile string) string {
 | 
						|
	return fmt.Sprintf("For profile: %v, overriding %v value, defined in %v "+
 | 
						|
		"with a %v value found in a duplicate profile defined at file %v. \n",
 | 
						|
		sectionName, key, dstSourceFile, key, srcSourceFile)
 | 
						|
}
 | 
						|
 | 
						|
// Returns an error if all of the files fail to load. If at least one file is
 | 
						|
// successfully loaded and contains the profile, no error will be returned.
 | 
						|
func (c *SharedConfig) setFromIniSections(profiles map[string]struct{}, profile string,
 | 
						|
	sections ini.Sections, logger logging.Logger) error {
 | 
						|
	c.Profile = profile
 | 
						|
 | 
						|
	section, ok := sections.GetSection(profile)
 | 
						|
	if !ok {
 | 
						|
		return SharedConfigProfileNotExistError{
 | 
						|
			Profile: profile,
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// if logs are appended to the section, log them
 | 
						|
	if section.Logs != nil && logger != nil {
 | 
						|
		for _, log := range section.Logs {
 | 
						|
			logger.Logf(logging.Debug, log)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// set config from the provided INI section
 | 
						|
	err := c.setFromIniSection(profile, section)
 | 
						|
	if err != nil {
 | 
						|
		return fmt.Errorf("error fetching config from profile, %v, %w", profile, err)
 | 
						|
	}
 | 
						|
 | 
						|
	if _, ok := profiles[profile]; ok {
 | 
						|
		// if this is the second instance of the profile the Assume Role
 | 
						|
		// options must be cleared because they are only valid for the
 | 
						|
		// first reference of a profile. The self linked instance of the
 | 
						|
		// profile only have credential provider options.
 | 
						|
		c.clearAssumeRoleOptions()
 | 
						|
	} else {
 | 
						|
		// First time a profile has been seen. Assert if the credential type
 | 
						|
		// requires a role ARN, the ARN is also set
 | 
						|
		if err := c.validateCredentialsConfig(profile); err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	// if not top level profile and has credentials, return with credentials.
 | 
						|
	if len(profiles) != 0 && c.Credentials.HasKeys() {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	profiles[profile] = struct{}{}
 | 
						|
 | 
						|
	// validate no colliding credentials type are present
 | 
						|
	if err := c.validateCredentialType(); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	// Link source profiles for assume roles
 | 
						|
	if len(c.SourceProfileName) != 0 {
 | 
						|
		// Linked profile via source_profile ignore credential provider
 | 
						|
		// options, the source profile must provide the credentials.
 | 
						|
		c.clearCredentialOptions()
 | 
						|
 | 
						|
		srcCfg := &SharedConfig{}
 | 
						|
		err := srcCfg.setFromIniSections(profiles, c.SourceProfileName, sections, logger)
 | 
						|
		if err != nil {
 | 
						|
			// SourceProfileName that doesn't exist is an error in configuration.
 | 
						|
			if _, ok := err.(SharedConfigProfileNotExistError); ok {
 | 
						|
				err = SharedConfigAssumeRoleError{
 | 
						|
					RoleARN: c.RoleARN,
 | 
						|
					Profile: c.SourceProfileName,
 | 
						|
					Err:     err,
 | 
						|
				}
 | 
						|
			}
 | 
						|
			return err
 | 
						|
		}
 | 
						|
 | 
						|
		if !srcCfg.hasCredentials() {
 | 
						|
			return SharedConfigAssumeRoleError{
 | 
						|
				RoleARN: c.RoleARN,
 | 
						|
				Profile: c.SourceProfileName,
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		c.Source = srcCfg
 | 
						|
	}
 | 
						|
 | 
						|
	// If the profile contains an SSO session parameter, the session MUST exist
 | 
						|
	// as a section in the config file. Load the SSO session using the name
 | 
						|
	// provided. If the session section is not found or incomplete an error
 | 
						|
	// will be returned.
 | 
						|
	if c.hasSSOTokenProviderConfiguration() {
 | 
						|
		section, ok := sections.GetSection(ssoSectionPrefix + strings.TrimSpace(c.SSOSessionName))
 | 
						|
		if !ok {
 | 
						|
			return fmt.Errorf("failed to find SSO session section, %v", c.SSOSessionName)
 | 
						|
		}
 | 
						|
		var ssoSession SSOSession
 | 
						|
		ssoSession.setFromIniSection(section)
 | 
						|
		ssoSession.Name = c.SSOSessionName
 | 
						|
		c.SSOSession = &ssoSession
 | 
						|
	}
 | 
						|
 | 
						|
	if len(c.ServicesSectionName) > 0 {
 | 
						|
		if section, ok := sections.GetSection(servicesPrefix + c.ServicesSectionName); ok {
 | 
						|
			var svcs Services
 | 
						|
			svcs.setFromIniSection(section)
 | 
						|
			c.Services = svcs
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// setFromIniSection loads the configuration from the profile section defined in
 | 
						|
// the provided INI file. A SharedConfig pointer type value is used so that
 | 
						|
// multiple config file loadings can be chained.
 | 
						|
//
 | 
						|
// Only loads complete logically grouped values, and will not set fields in cfg
 | 
						|
// for incomplete grouped values in the config. Such as credentials. For example
 | 
						|
// if a config file only includes aws_access_key_id but no aws_secret_access_key
 | 
						|
// the aws_access_key_id will be ignored.
 | 
						|
func (c *SharedConfig) setFromIniSection(profile string, section ini.Section) error {
 | 
						|
	if len(section.Name) == 0 {
 | 
						|
		sources := make([]string, 0)
 | 
						|
		for _, v := range section.SourceFile {
 | 
						|
			sources = append(sources, v)
 | 
						|
		}
 | 
						|
 | 
						|
		return fmt.Errorf("parsing error : could not find profile section name after processing files: %v", sources)
 | 
						|
	}
 | 
						|
 | 
						|
	if len(section.Errors) != 0 {
 | 
						|
		var errStatement string
 | 
						|
		for i, e := range section.Errors {
 | 
						|
			errStatement = fmt.Sprintf("%d, %v\n", i+1, e.Error())
 | 
						|
		}
 | 
						|
		return fmt.Errorf("Error using profile: \n %v", errStatement)
 | 
						|
	}
 | 
						|
 | 
						|
	// Assume Role
 | 
						|
	updateString(&c.RoleARN, section, roleArnKey)
 | 
						|
	updateString(&c.ExternalID, section, externalIDKey)
 | 
						|
	updateString(&c.MFASerial, section, mfaSerialKey)
 | 
						|
	updateString(&c.RoleSessionName, section, roleSessionNameKey)
 | 
						|
	updateString(&c.SourceProfileName, section, sourceProfileKey)
 | 
						|
	updateString(&c.CredentialSource, section, credentialSourceKey)
 | 
						|
	updateString(&c.Region, section, regionKey)
 | 
						|
 | 
						|
	// AWS Single Sign-On (AWS SSO)
 | 
						|
	// SSO session options
 | 
						|
	updateString(&c.SSOSessionName, section, ssoSessionNameKey)
 | 
						|
 | 
						|
	// Legacy SSO session options
 | 
						|
	updateString(&c.SSORegion, section, ssoRegionKey)
 | 
						|
	updateString(&c.SSOStartURL, section, ssoStartURLKey)
 | 
						|
 | 
						|
	// SSO fields not used
 | 
						|
	updateString(&c.SSOAccountID, section, ssoAccountIDKey)
 | 
						|
	updateString(&c.SSORoleName, section, ssoRoleNameKey)
 | 
						|
 | 
						|
	// we're retaining a behavioral quirk with this field that existed before
 | 
						|
	// the removal of literal parsing for #2276:
 | 
						|
	//   - if the key is missing, the config field will not be set
 | 
						|
	//   - if the key is set to a non-numeric, the config field will be set to 0
 | 
						|
	if section.Has(roleDurationSecondsKey) {
 | 
						|
		if v, ok := section.Int(roleDurationSecondsKey); ok {
 | 
						|
			c.RoleDurationSeconds = aws.Duration(time.Duration(v) * time.Second)
 | 
						|
		} else {
 | 
						|
			c.RoleDurationSeconds = aws.Duration(time.Duration(0))
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	updateString(&c.CredentialProcess, section, credentialProcessKey)
 | 
						|
	updateString(&c.WebIdentityTokenFile, section, webIdentityTokenFileKey)
 | 
						|
 | 
						|
	updateEndpointDiscoveryType(&c.EnableEndpointDiscovery, section, enableEndpointDiscoveryKey)
 | 
						|
	updateBoolPtr(&c.S3UseARNRegion, section, s3UseARNRegionKey)
 | 
						|
	updateBoolPtr(&c.S3DisableMultiRegionAccessPoints, section, s3DisableMultiRegionAccessPointsKey)
 | 
						|
	updateBoolPtr(&c.S3DisableExpressAuth, section, s3DisableExpressSessionAuthKey)
 | 
						|
 | 
						|
	if err := updateEC2MetadataServiceEndpointMode(&c.EC2IMDSEndpointMode, section, ec2MetadataServiceEndpointModeKey); err != nil {
 | 
						|
		return fmt.Errorf("failed to load %s from shared config, %v", ec2MetadataServiceEndpointModeKey, err)
 | 
						|
	}
 | 
						|
	updateString(&c.EC2IMDSEndpoint, section, ec2MetadataServiceEndpointKey)
 | 
						|
	updateBoolPtr(&c.EC2IMDSv1Disabled, section, ec2MetadataV1DisabledKey)
 | 
						|
 | 
						|
	updateUseDualStackEndpoint(&c.UseDualStackEndpoint, section, useDualStackEndpoint)
 | 
						|
	updateUseFIPSEndpoint(&c.UseFIPSEndpoint, section, useFIPSEndpointKey)
 | 
						|
 | 
						|
	if err := updateDefaultsMode(&c.DefaultsMode, section, defaultsModeKey); err != nil {
 | 
						|
		return fmt.Errorf("failed to load %s from shared config, %w", defaultsModeKey, err)
 | 
						|
	}
 | 
						|
 | 
						|
	if err := updateInt(&c.RetryMaxAttempts, section, retryMaxAttemptsKey); err != nil {
 | 
						|
		return fmt.Errorf("failed to load %s from shared config, %w", retryMaxAttemptsKey, err)
 | 
						|
	}
 | 
						|
	if err := updateRetryMode(&c.RetryMode, section, retryModeKey); err != nil {
 | 
						|
		return fmt.Errorf("failed to load %s from shared config, %w", retryModeKey, err)
 | 
						|
	}
 | 
						|
 | 
						|
	updateString(&c.CustomCABundle, section, caBundleKey)
 | 
						|
 | 
						|
	// user agent app ID added to request User-Agent header
 | 
						|
	updateString(&c.AppID, section, sdkAppID)
 | 
						|
 | 
						|
	updateBoolPtr(&c.IgnoreConfiguredEndpoints, section, ignoreConfiguredEndpoints)
 | 
						|
 | 
						|
	updateString(&c.BaseEndpoint, section, endpointURL)
 | 
						|
 | 
						|
	if err := updateDisableRequestCompression(&c.DisableRequestCompression, section, disableRequestCompression); err != nil {
 | 
						|
		return fmt.Errorf("failed to load %s from shared config, %w", disableRequestCompression, err)
 | 
						|
	}
 | 
						|
	if err := updateRequestMinCompressSizeBytes(&c.RequestMinCompressSizeBytes, section, requestMinCompressionSizeBytes); err != nil {
 | 
						|
		return fmt.Errorf("failed to load %s from shared config, %w", requestMinCompressionSizeBytes, err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Shared Credentials
 | 
						|
	creds := aws.Credentials{
 | 
						|
		AccessKeyID:     section.String(accessKeyIDKey),
 | 
						|
		SecretAccessKey: section.String(secretAccessKey),
 | 
						|
		SessionToken:    section.String(sessionTokenKey),
 | 
						|
		Source:          fmt.Sprintf("SharedConfigCredentials: %s", section.SourceFile[accessKeyIDKey]),
 | 
						|
	}
 | 
						|
 | 
						|
	if creds.HasKeys() {
 | 
						|
		c.Credentials = creds
 | 
						|
	}
 | 
						|
 | 
						|
	updateString(&c.ServicesSectionName, section, servicesSectionKey)
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func updateRequestMinCompressSizeBytes(bytes **int64, sec ini.Section, key string) error {
 | 
						|
	if !sec.Has(key) {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	v, ok := sec.Int(key)
 | 
						|
	if !ok {
 | 
						|
		return fmt.Errorf("invalid value for min request compression size bytes %s, need int64", sec.String(key))
 | 
						|
	}
 | 
						|
	if v < 0 || v > smithyrequestcompression.MaxRequestMinCompressSizeBytes {
 | 
						|
		return fmt.Errorf("invalid range for min request compression size bytes %d, must be within 0 and 10485760 inclusively", v)
 | 
						|
	}
 | 
						|
	*bytes = new(int64)
 | 
						|
	**bytes = v
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func updateDisableRequestCompression(disable **bool, sec ini.Section, key string) error {
 | 
						|
	if !sec.Has(key) {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	v := sec.String(key)
 | 
						|
	switch {
 | 
						|
	case v == "true":
 | 
						|
		*disable = new(bool)
 | 
						|
		**disable = true
 | 
						|
	case v == "false":
 | 
						|
		*disable = new(bool)
 | 
						|
		**disable = false
 | 
						|
	default:
 | 
						|
		return fmt.Errorf("invalid value for shared config profile field, %s=%s, need true or false", key, v)
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (c SharedConfig) getRequestMinCompressSizeBytes(ctx context.Context) (int64, bool, error) {
 | 
						|
	if c.RequestMinCompressSizeBytes == nil {
 | 
						|
		return 0, false, nil
 | 
						|
	}
 | 
						|
	return *c.RequestMinCompressSizeBytes, true, nil
 | 
						|
}
 | 
						|
 | 
						|
func (c SharedConfig) getDisableRequestCompression(ctx context.Context) (bool, bool, error) {
 | 
						|
	if c.DisableRequestCompression == nil {
 | 
						|
		return false, false, nil
 | 
						|
	}
 | 
						|
	return *c.DisableRequestCompression, true, nil
 | 
						|
}
 | 
						|
 | 
						|
func updateDefaultsMode(mode *aws.DefaultsMode, section ini.Section, key string) error {
 | 
						|
	if !section.Has(key) {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	value := section.String(key)
 | 
						|
	if ok := mode.SetFromString(value); !ok {
 | 
						|
		return fmt.Errorf("invalid value: %s", value)
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func updateRetryMode(mode *aws.RetryMode, section ini.Section, key string) (err error) {
 | 
						|
	if !section.Has(key) {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	value := section.String(key)
 | 
						|
	if *mode, err = aws.ParseRetryMode(value); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func updateEC2MetadataServiceEndpointMode(endpointMode *imds.EndpointModeState, section ini.Section, key string) error {
 | 
						|
	if !section.Has(key) {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	value := section.String(key)
 | 
						|
	return endpointMode.SetFromString(value)
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) validateCredentialsConfig(profile string) error {
 | 
						|
	if err := c.validateCredentialsRequireARN(profile); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) validateCredentialsRequireARN(profile string) error {
 | 
						|
	var credSource string
 | 
						|
 | 
						|
	switch {
 | 
						|
	case len(c.SourceProfileName) != 0:
 | 
						|
		credSource = sourceProfileKey
 | 
						|
	case len(c.CredentialSource) != 0:
 | 
						|
		credSource = credentialSourceKey
 | 
						|
	case len(c.WebIdentityTokenFile) != 0:
 | 
						|
		credSource = webIdentityTokenFileKey
 | 
						|
	}
 | 
						|
 | 
						|
	if len(credSource) != 0 && len(c.RoleARN) == 0 {
 | 
						|
		return CredentialRequiresARNError{
 | 
						|
			Type:    credSource,
 | 
						|
			Profile: profile,
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) validateCredentialType() error {
 | 
						|
	// Only one or no credential type can be defined.
 | 
						|
	if !oneOrNone(
 | 
						|
		len(c.SourceProfileName) != 0,
 | 
						|
		len(c.CredentialSource) != 0,
 | 
						|
		len(c.CredentialProcess) != 0,
 | 
						|
		len(c.WebIdentityTokenFile) != 0,
 | 
						|
	) {
 | 
						|
		return fmt.Errorf("only one credential type may be specified per profile: source profile, credential source, credential process, web identity token")
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) validateSSOConfiguration() error {
 | 
						|
	if c.hasSSOTokenProviderConfiguration() {
 | 
						|
		err := c.validateSSOTokenProviderConfiguration()
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	if c.hasLegacySSOConfiguration() {
 | 
						|
		err := c.validateLegacySSOConfiguration()
 | 
						|
		if err != nil {
 | 
						|
			return err
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) validateSSOTokenProviderConfiguration() error {
 | 
						|
	var missing []string
 | 
						|
 | 
						|
	if len(c.SSOSessionName) == 0 {
 | 
						|
		missing = append(missing, ssoSessionNameKey)
 | 
						|
	}
 | 
						|
 | 
						|
	if c.SSOSession == nil {
 | 
						|
		missing = append(missing, ssoSectionPrefix)
 | 
						|
	} else {
 | 
						|
		if len(c.SSOSession.SSORegion) == 0 {
 | 
						|
			missing = append(missing, ssoRegionKey)
 | 
						|
		}
 | 
						|
 | 
						|
		if len(c.SSOSession.SSOStartURL) == 0 {
 | 
						|
			missing = append(missing, ssoStartURLKey)
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	if len(missing) > 0 {
 | 
						|
		return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s",
 | 
						|
			c.Profile, strings.Join(missing, ", "))
 | 
						|
	}
 | 
						|
 | 
						|
	if len(c.SSORegion) > 0 && c.SSORegion != c.SSOSession.SSORegion {
 | 
						|
		return fmt.Errorf("%s in profile %q must match %s in %s", ssoRegionKey, c.Profile, ssoRegionKey, ssoSectionPrefix)
 | 
						|
	}
 | 
						|
 | 
						|
	if len(c.SSOStartURL) > 0 && c.SSOStartURL != c.SSOSession.SSOStartURL {
 | 
						|
		return fmt.Errorf("%s in profile %q must match %s in %s", ssoStartURLKey, c.Profile, ssoStartURLKey, ssoSectionPrefix)
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) validateLegacySSOConfiguration() error {
 | 
						|
	var missing []string
 | 
						|
 | 
						|
	if len(c.SSORegion) == 0 {
 | 
						|
		missing = append(missing, ssoRegionKey)
 | 
						|
	}
 | 
						|
 | 
						|
	if len(c.SSOStartURL) == 0 {
 | 
						|
		missing = append(missing, ssoStartURLKey)
 | 
						|
	}
 | 
						|
 | 
						|
	if len(c.SSOAccountID) == 0 {
 | 
						|
		missing = append(missing, ssoAccountIDKey)
 | 
						|
	}
 | 
						|
 | 
						|
	if len(c.SSORoleName) == 0 {
 | 
						|
		missing = append(missing, ssoRoleNameKey)
 | 
						|
	}
 | 
						|
 | 
						|
	if len(missing) > 0 {
 | 
						|
		return fmt.Errorf("profile %q is configured to use SSO but is missing required configuration: %s",
 | 
						|
			c.Profile, strings.Join(missing, ", "))
 | 
						|
	}
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) hasCredentials() bool {
 | 
						|
	switch {
 | 
						|
	case len(c.SourceProfileName) != 0:
 | 
						|
	case len(c.CredentialSource) != 0:
 | 
						|
	case len(c.CredentialProcess) != 0:
 | 
						|
	case len(c.WebIdentityTokenFile) != 0:
 | 
						|
	case c.hasSSOConfiguration():
 | 
						|
	case c.Credentials.HasKeys():
 | 
						|
	default:
 | 
						|
		return false
 | 
						|
	}
 | 
						|
 | 
						|
	return true
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) hasSSOConfiguration() bool {
 | 
						|
	return c.hasSSOTokenProviderConfiguration() || c.hasLegacySSOConfiguration()
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) hasSSOTokenProviderConfiguration() bool {
 | 
						|
	return len(c.SSOSessionName) > 0
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) hasLegacySSOConfiguration() bool {
 | 
						|
	return len(c.SSORegion) > 0 || len(c.SSOAccountID) > 0 || len(c.SSOStartURL) > 0 || len(c.SSORoleName) > 0
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) clearAssumeRoleOptions() {
 | 
						|
	c.RoleARN = ""
 | 
						|
	c.ExternalID = ""
 | 
						|
	c.MFASerial = ""
 | 
						|
	c.RoleSessionName = ""
 | 
						|
	c.SourceProfileName = ""
 | 
						|
}
 | 
						|
 | 
						|
func (c *SharedConfig) clearCredentialOptions() {
 | 
						|
	c.CredentialSource = ""
 | 
						|
	c.CredentialProcess = ""
 | 
						|
	c.WebIdentityTokenFile = ""
 | 
						|
	c.Credentials = aws.Credentials{}
 | 
						|
	c.SSOAccountID = ""
 | 
						|
	c.SSORegion = ""
 | 
						|
	c.SSORoleName = ""
 | 
						|
	c.SSOStartURL = ""
 | 
						|
}
 | 
						|
 | 
						|
// SharedConfigLoadError is an error for the shared config file failed to load.
 | 
						|
type SharedConfigLoadError struct {
 | 
						|
	Filename string
 | 
						|
	Err      error
 | 
						|
}
 | 
						|
 | 
						|
// Unwrap returns the underlying error that caused the failure.
 | 
						|
func (e SharedConfigLoadError) Unwrap() error {
 | 
						|
	return e.Err
 | 
						|
}
 | 
						|
 | 
						|
func (e SharedConfigLoadError) Error() string {
 | 
						|
	return fmt.Sprintf("failed to load shared config file, %s, %v", e.Filename, e.Err)
 | 
						|
}
 | 
						|
 | 
						|
// SharedConfigProfileNotExistError is an error for the shared config when
 | 
						|
// the profile was not find in the config file.
 | 
						|
type SharedConfigProfileNotExistError struct {
 | 
						|
	Filename []string
 | 
						|
	Profile  string
 | 
						|
	Err      error
 | 
						|
}
 | 
						|
 | 
						|
// Unwrap returns the underlying error that caused the failure.
 | 
						|
func (e SharedConfigProfileNotExistError) Unwrap() error {
 | 
						|
	return e.Err
 | 
						|
}
 | 
						|
 | 
						|
func (e SharedConfigProfileNotExistError) Error() string {
 | 
						|
	return fmt.Sprintf("failed to get shared config profile, %s", e.Profile)
 | 
						|
}
 | 
						|
 | 
						|
// SharedConfigAssumeRoleError is an error for the shared config when the
 | 
						|
// profile contains assume role information, but that information is invalid
 | 
						|
// or not complete.
 | 
						|
type SharedConfigAssumeRoleError struct {
 | 
						|
	Profile string
 | 
						|
	RoleARN string
 | 
						|
	Err     error
 | 
						|
}
 | 
						|
 | 
						|
// Unwrap returns the underlying error that caused the failure.
 | 
						|
func (e SharedConfigAssumeRoleError) Unwrap() error {
 | 
						|
	return e.Err
 | 
						|
}
 | 
						|
 | 
						|
func (e SharedConfigAssumeRoleError) Error() string {
 | 
						|
	return fmt.Sprintf("failed to load assume role %s, of profile %s, %v",
 | 
						|
		e.RoleARN, e.Profile, e.Err)
 | 
						|
}
 | 
						|
 | 
						|
// CredentialRequiresARNError provides the error for shared config credentials
 | 
						|
// that are incorrectly configured in the shared config or credentials file.
 | 
						|
type CredentialRequiresARNError struct {
 | 
						|
	// type of credentials that were configured.
 | 
						|
	Type string
 | 
						|
 | 
						|
	// Profile name the credentials were in.
 | 
						|
	Profile string
 | 
						|
}
 | 
						|
 | 
						|
// Error satisfies the error interface.
 | 
						|
func (e CredentialRequiresARNError) Error() string {
 | 
						|
	return fmt.Sprintf(
 | 
						|
		"credential type %s requires role_arn, profile %s",
 | 
						|
		e.Type, e.Profile,
 | 
						|
	)
 | 
						|
}
 | 
						|
 | 
						|
func oneOrNone(bs ...bool) bool {
 | 
						|
	var count int
 | 
						|
 | 
						|
	for _, b := range bs {
 | 
						|
		if b {
 | 
						|
			count++
 | 
						|
			if count > 1 {
 | 
						|
				return false
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return true
 | 
						|
}
 | 
						|
 | 
						|
// updateString will only update the dst with the value in the section key, key
 | 
						|
// is present in the section.
 | 
						|
func updateString(dst *string, section ini.Section, key string) {
 | 
						|
	if !section.Has(key) {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	*dst = section.String(key)
 | 
						|
}
 | 
						|
 | 
						|
// updateInt will only update the dst with the value in the section key, key
 | 
						|
// is present in the section.
 | 
						|
//
 | 
						|
// Down casts the INI integer value from a int64 to an int, which could be
 | 
						|
// different bit size depending on platform.
 | 
						|
func updateInt(dst *int, section ini.Section, key string) error {
 | 
						|
	if !section.Has(key) {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	v, ok := section.Int(key)
 | 
						|
	if !ok {
 | 
						|
		return fmt.Errorf("invalid value %s=%s, expect integer", key, section.String(key))
 | 
						|
	}
 | 
						|
 | 
						|
	*dst = int(v)
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// updateBool will only update the dst with the value in the section key, key
 | 
						|
// is present in the section.
 | 
						|
func updateBool(dst *bool, section ini.Section, key string) {
 | 
						|
	if !section.Has(key) {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// retains pre-#2276 behavior where non-bool value would resolve to false
 | 
						|
	v, _ := section.Bool(key)
 | 
						|
	*dst = v
 | 
						|
}
 | 
						|
 | 
						|
// updateBoolPtr will only update the dst with the value in the section key,
 | 
						|
// key is present in the section.
 | 
						|
func updateBoolPtr(dst **bool, section ini.Section, key string) {
 | 
						|
	if !section.Has(key) {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// retains pre-#2276 behavior where non-bool value would resolve to false
 | 
						|
	v, _ := section.Bool(key)
 | 
						|
	*dst = new(bool)
 | 
						|
	**dst = v
 | 
						|
}
 | 
						|
 | 
						|
// updateEndpointDiscoveryType will only update the dst with the value in the section, if
 | 
						|
// a valid key and corresponding EndpointDiscoveryType is found.
 | 
						|
func updateEndpointDiscoveryType(dst *aws.EndpointDiscoveryEnableState, section ini.Section, key string) {
 | 
						|
	if !section.Has(key) {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	value := section.String(key)
 | 
						|
	if len(value) == 0 {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	switch {
 | 
						|
	case strings.EqualFold(value, endpointDiscoveryDisabled):
 | 
						|
		*dst = aws.EndpointDiscoveryDisabled
 | 
						|
	case strings.EqualFold(value, endpointDiscoveryEnabled):
 | 
						|
		*dst = aws.EndpointDiscoveryEnabled
 | 
						|
	case strings.EqualFold(value, endpointDiscoveryAuto):
 | 
						|
		*dst = aws.EndpointDiscoveryAuto
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// updateEndpointDiscoveryType will only update the dst with the value in the section, if
 | 
						|
// a valid key and corresponding EndpointDiscoveryType is found.
 | 
						|
func updateUseDualStackEndpoint(dst *aws.DualStackEndpointState, section ini.Section, key string) {
 | 
						|
	if !section.Has(key) {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// retains pre-#2276 behavior where non-bool value would resolve to false
 | 
						|
	if v, _ := section.Bool(key); v {
 | 
						|
		*dst = aws.DualStackEndpointStateEnabled
 | 
						|
	} else {
 | 
						|
		*dst = aws.DualStackEndpointStateDisabled
 | 
						|
	}
 | 
						|
 | 
						|
	return
 | 
						|
}
 | 
						|
 | 
						|
// updateEndpointDiscoveryType will only update the dst with the value in the section, if
 | 
						|
// a valid key and corresponding EndpointDiscoveryType is found.
 | 
						|
func updateUseFIPSEndpoint(dst *aws.FIPSEndpointState, section ini.Section, key string) {
 | 
						|
	if !section.Has(key) {
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	// retains pre-#2276 behavior where non-bool value would resolve to false
 | 
						|
	if v, _ := section.Bool(key); v {
 | 
						|
		*dst = aws.FIPSEndpointStateEnabled
 | 
						|
	} else {
 | 
						|
		*dst = aws.FIPSEndpointStateDisabled
 | 
						|
	}
 | 
						|
 | 
						|
	return
 | 
						|
}
 |