vendor: update buildkit to master@31c870e82a48

Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
Justin Chadwell
2023-05-15 18:32:31 +01:00
parent 167cd16acb
commit e61a8cf637
269 changed files with 25798 additions and 3371 deletions

View File

@ -1,3 +1,178 @@
# v1.18.16 (2023-03-10)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.15 (2023-02-22)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.14 (2023-02-20)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.13 (2023-02-15)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.12 (2023-02-03)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.11 (2023-02-01)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.10 (2023-01-25)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.9 (2023-01-23)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.8 (2023-01-05)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.7 (2022-12-20)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.6 (2022-12-19)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.5 (2022-12-15)
* **Bug Fix**: Unify logic between shared config and in finding home directory
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.4 (2022-12-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.3 (2022-11-22)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.2 (2022-11-17)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.1 (2022-11-16)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.18.0 (2022-11-11)
* **Announcement**: When using the SSOTokenProvider, a previous implementation incorrectly compensated for invalid SSOTokenProvider configurations in the shared profile. This has been fixed via PR #1903 and tracked in issue #1846
* **Feature**: Adds token refresh support (via SSOTokenProvider) when using the SSOCredentialProvider
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.11 (2022-11-10)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.10 (2022-10-24)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.9 (2022-10-21)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.8 (2022-09-30)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.7 (2022-09-20)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.6 (2022-09-14)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.5 (2022-09-02)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.4 (2022-08-31)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.3 (2022-08-30)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.2 (2022-08-29)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.1 (2022-08-15)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.17.0 (2022-08-14)
* **Feature**: Add alternative mechanism for determning the users `$HOME` or `%USERPROFILE%` location when the environment variables are not present.
# v1.16.1 (2022-08-11)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.16.0 (2022-08-10)
* **Feature**: Adds support for the following settings in the `~/.aws/credentials` file: `sso_account_id`, `sso_region`, `sso_role_name`, `sso_start_url`, and `ca_bundle`.
# v1.15.17 (2022-08-09)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.16 (2022-08-08)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.15 (2022-08-01)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.14 (2022-07-11)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.13 (2022-07-05)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.12 (2022-06-29)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.11 (2022-06-16)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.10 (2022-06-07)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.9 (2022-05-26)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.8 (2022-05-25)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.7 (2022-05-17)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.6 (2022-05-16)
* **Dependency Update**: Updated to the latest SDK module versions
# v1.15.5 (2022-05-09)
* **Bug Fix**: Fixes a bug in LoadDefaultConfig to correctly assign ConfigSources so all config resolvers have access to the config sources. This fixes the feature/ec2/imds client not having configuration applied via config.LoadOptions such as EC2IMDSClientEnableState. PR [#1682](https://github.com/aws/aws-sdk-go-v2/pull/1682)

View File

@ -72,6 +72,10 @@ var defaultAWSConfigResolvers = []awsConfigResolver{
// implementations depend on or can be configured with earlier resolved
// configuration options.
resolveCredentials,
// Sets the resolved bearer authentication token API clients will use for
// httpBearerAuth authentication scheme.
resolveBearerAuthToken,
}
// A Config represents a generic configuration value or set of values. This type
@ -162,13 +166,12 @@ func (cs configs) ResolveConfig(f func(configs []interface{}) error) error {
// The custom configurations must satisfy the respective providers for their data
// or the custom data will be ignored by the resolvers and config loaders.
//
// cfg, err := config.LoadDefaultConfig( context.TODO(),
// WithSharedConfigProfile("test-profile"),
// )
// if err != nil {
// panic(fmt.Sprintf("failed loading config, %v", err))
// }
//
// cfg, err := config.LoadDefaultConfig( context.TODO(),
// WithSharedConfigProfile("test-profile"),
// )
// if err != nil {
// panic(fmt.Sprintf("failed loading config, %v", err))
// }
//
// The default configuration sources are:
// * Environment Variables

View File

@ -15,6 +15,6 @@
// take precedence over the default environment and shared config sources used by the SDK. If one or more Config sources
// implement the same provider interface, priority will be handled by the order in which the sources were passed in.
//
// A number of helpers (prefixed by ``With``) are provided in this package that implement their respective provider
// A number of helpers (prefixed by With) are provided in this package that implement their respective provider
// interface. These helpers should be used for overriding configuration programmatically at runtime.
package config

View File

@ -3,4 +3,4 @@
package config
// goModuleVersion is the tagged release for this module
const goModuleVersion = "1.15.5"
const goModuleVersion = "1.18.16"

View File

@ -11,6 +11,7 @@ import (
"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
smithybearer "github.com/aws/smithy-go/auth/bearer"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/middleware"
)
@ -28,6 +29,9 @@ type LoadOptions struct {
// Credentials object to use when signing requests.
Credentials aws.CredentialsProvider
// Token provider for authentication operations with bearer authentication.
BearerAuthTokenProvider smithybearer.TokenProvider
// HTTPClient the SDK's API clients will use to invoke HTTP requests.
HTTPClient HTTPClient
@ -128,6 +132,14 @@ type LoadOptions struct {
// aws.CredentialsCacheOptions
CredentialsCacheOptions func(*aws.CredentialsCacheOptions)
// BearerAuthTokenCacheOptions is a function for setting the smithy-go
// auth/bearer#TokenCacheOptions
BearerAuthTokenCacheOptions func(*smithybearer.TokenCacheOptions)
// SSOTokenProviderOptions is a function for setting the
// credentials/ssocreds.SSOTokenProviderOptions
SSOTokenProviderOptions func(*ssocreds.SSOTokenProviderOptions)
// ProcessCredentialOptions is a function for setting
// the processcreds.Options
ProcessCredentialOptions func(*processcreds.Options)
@ -451,6 +463,73 @@ func WithCredentialsCacheOptions(v func(*aws.CredentialsCacheOptions)) LoadOptio
}
}
// getBearerAuthTokenProvider returns the credentials value
func (o LoadOptions) getBearerAuthTokenProvider(ctx context.Context) (smithybearer.TokenProvider, bool, error) {
if o.BearerAuthTokenProvider == nil {
return nil, false, nil
}
return o.BearerAuthTokenProvider, true, nil
}
// WithBearerAuthTokenProvider is a helper function to construct functional options
// that sets Credential provider value on config's LoadOptions. If credentials
// provider is set to nil, the credentials provider value will be ignored.
// If multiple WithBearerAuthTokenProvider calls are made, the last call overrides
// the previous call values.
func WithBearerAuthTokenProvider(v smithybearer.TokenProvider) LoadOptionsFunc {
return func(o *LoadOptions) error {
o.BearerAuthTokenProvider = v
return nil
}
}
// getBearerAuthTokenCacheOptionsProvider returns the wrapped function to set smithybearer.TokenCacheOptions
func (o LoadOptions) getBearerAuthTokenCacheOptions(ctx context.Context) (func(*smithybearer.TokenCacheOptions), bool, error) {
if o.BearerAuthTokenCacheOptions == nil {
return nil, false, nil
}
return o.BearerAuthTokenCacheOptions, true, nil
}
// WithBearerAuthTokenCacheOptions is a helper function to construct functional options
// that sets a function to modify the TokenCacheOptions the smithy-go
// auth/bearer#TokenCache will be configured with, if the TokenCache is used by
// the configuration loader.
//
// If multiple WithBearerAuthTokenCacheOptions calls are made, the last call overrides
// the previous call values.
func WithBearerAuthTokenCacheOptions(v func(*smithybearer.TokenCacheOptions)) LoadOptionsFunc {
return func(o *LoadOptions) error {
o.BearerAuthTokenCacheOptions = v
return nil
}
}
// getSSOTokenProviderOptionsProvider returns the wrapped function to set smithybearer.TokenCacheOptions
func (o LoadOptions) getSSOTokenProviderOptions(ctx context.Context) (func(*ssocreds.SSOTokenProviderOptions), bool, error) {
if o.SSOTokenProviderOptions == nil {
return nil, false, nil
}
return o.SSOTokenProviderOptions, true, nil
}
// WithSSOTokenProviderOptions is a helper function to construct functional
// options that sets a function to modify the SSOtokenProviderOptions the SDK's
// credentials/ssocreds#SSOProvider will be configured with, if the
// SSOTokenProvider is used by the configuration loader.
//
// If multiple WithSSOTokenProviderOptions calls are made, the last call overrides
// the previous call values.
func WithSSOTokenProviderOptions(v func(*ssocreds.SSOTokenProviderOptions)) LoadOptionsFunc {
return func(o *LoadOptions) error {
o.SSOTokenProviderOptions = v
return nil
}
}
// getProcessCredentialOptions returns the wrapped function to set processcreds.Options
func (o LoadOptions) getProcessCredentialOptions(ctx context.Context) (func(*processcreds.Options), bool, error) {
if o.ProcessCredentialOptions == nil {

View File

@ -12,6 +12,7 @@ import (
"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
smithybearer "github.com/aws/smithy-go/auth/bearer"
"github.com/aws/smithy-go/logging"
"github.com/aws/smithy-go/middleware"
)
@ -185,6 +186,73 @@ func getCredentialsCacheOptionsProvider(ctx context.Context, configs configs) (
return
}
// bearerAuthTokenProviderProvider provides access to the bearer authentication
// token external configuration value.
type bearerAuthTokenProviderProvider interface {
getBearerAuthTokenProvider(context.Context) (smithybearer.TokenProvider, bool, error)
}
// getBearerAuthTokenProvider searches the config sources for a
// bearerAuthTokenProviderProvider and returns the value if found. Returns an
// error if a provider fails before a value is found.
func getBearerAuthTokenProvider(ctx context.Context, configs configs) (p smithybearer.TokenProvider, found bool, err error) {
for _, cfg := range configs {
if provider, ok := cfg.(bearerAuthTokenProviderProvider); ok {
p, found, err = provider.getBearerAuthTokenProvider(ctx)
if err != nil || found {
break
}
}
}
return
}
// bearerAuthTokenCacheOptionsProvider is an interface for retrieving a function for
// setting the smithy-go auth/bearer#TokenCacheOptions.
type bearerAuthTokenCacheOptionsProvider interface {
getBearerAuthTokenCacheOptions(context.Context) (func(*smithybearer.TokenCacheOptions), bool, error)
}
// getBearerAuthTokenCacheOptionsProvider is an interface for retrieving a function for
// setting the smithy-go auth/bearer#TokenCacheOptions.
func getBearerAuthTokenCacheOptions(ctx context.Context, configs configs) (
f func(*smithybearer.TokenCacheOptions), found bool, err error,
) {
for _, config := range configs {
if p, ok := config.(bearerAuthTokenCacheOptionsProvider); ok {
f, found, err = p.getBearerAuthTokenCacheOptions(ctx)
if err != nil || found {
break
}
}
}
return
}
// ssoTokenProviderOptionsProvider is an interface for retrieving a function for
// setting the SDK's credentials/ssocreds#SSOTokenProviderOptions.
type ssoTokenProviderOptionsProvider interface {
getSSOTokenProviderOptions(context.Context) (func(*ssocreds.SSOTokenProviderOptions), bool, error)
}
// getSSOTokenProviderOptions is an interface for retrieving a function for
// setting the SDK's credentials/ssocreds#SSOTokenProviderOptions.
func getSSOTokenProviderOptions(ctx context.Context, configs configs) (
f func(*ssocreds.SSOTokenProviderOptions), found bool, err error,
) {
for _, config := range configs {
if p, ok := config.(ssoTokenProviderOptionsProvider); ok {
f, found, err = p.getSSOTokenProviderOptions(ctx)
if err != nil || found {
break
}
}
}
return
}
// ssoTokenProviderOptionsProvider
// processCredentialOptions is an interface for retrieving a function for setting
// the processcreds.Options.
type processCredentialOptions interface {

View File

@ -0,0 +1,122 @@
package config
import (
"context"
"fmt"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials/ssocreds"
"github.com/aws/aws-sdk-go-v2/service/ssooidc"
smithybearer "github.com/aws/smithy-go/auth/bearer"
)
// resolveBearerAuthToken extracts a token provider from the config sources.
//
// If an explicit bearer authentication token provider is not found the
// resolver will fallback to resolving token provider via other config sources
// such as SharedConfig.
func resolveBearerAuthToken(ctx context.Context, cfg *aws.Config, configs configs) error {
found, err := resolveBearerAuthTokenProvider(ctx, cfg, configs)
if found || err != nil {
return err
}
return resolveBearerAuthTokenProviderChain(ctx, cfg, configs)
}
// resolveBearerAuthTokenProvider extracts the first instance of
// BearerAuthTokenProvider from the config sources.
//
// The resolved BearerAuthTokenProvider will be wrapped in a cache to ensure
// the Token is only refreshed when needed. This also protects the
// TokenProvider so it can be used concurrently.
//
// Config providers used:
// * bearerAuthTokenProviderProvider
func resolveBearerAuthTokenProvider(ctx context.Context, cfg *aws.Config, configs configs) (bool, error) {
tokenProvider, found, err := getBearerAuthTokenProvider(ctx, configs)
if !found || err != nil {
return false, err
}
cfg.BearerAuthTokenProvider, err = wrapWithBearerAuthTokenCache(
ctx, configs, tokenProvider)
if err != nil {
return false, err
}
return true, nil
}
func resolveBearerAuthTokenProviderChain(ctx context.Context, cfg *aws.Config, configs configs) (err error) {
_, sharedConfig, _ := getAWSConfigSources(configs)
var provider smithybearer.TokenProvider
if sharedConfig.SSOSession != nil {
provider, err = resolveBearerAuthSSOTokenProvider(
ctx, cfg, sharedConfig.SSOSession, configs)
}
if err == nil && provider != nil {
cfg.BearerAuthTokenProvider, err = wrapWithBearerAuthTokenCache(
ctx, configs, provider)
}
return err
}
func resolveBearerAuthSSOTokenProvider(ctx context.Context, cfg *aws.Config, session *SSOSession, configs configs) (*ssocreds.SSOTokenProvider, error) {
ssoTokenProviderOptionsFn, found, err := getSSOTokenProviderOptions(ctx, configs)
if err != nil {
return nil, fmt.Errorf("failed to get SSOTokenProviderOptions from config sources, %w", err)
}
var optFns []func(*ssocreds.SSOTokenProviderOptions)
if found {
optFns = append(optFns, ssoTokenProviderOptionsFn)
}
cachePath, err := ssocreds.StandardCachedTokenFilepath(session.Name)
if err != nil {
return nil, fmt.Errorf("failed to get SSOTokenProvider's cache path, %w", err)
}
client := ssooidc.NewFromConfig(*cfg)
provider := ssocreds.NewSSOTokenProvider(client, cachePath, optFns...)
return provider, nil
}
// wrapWithBearerAuthTokenCache will wrap provider with an smithy-go
// bearer/auth#TokenCache with the provided options if the provider is not
// already a TokenCache.
func wrapWithBearerAuthTokenCache(
ctx context.Context,
cfgs configs,
provider smithybearer.TokenProvider,
optFns ...func(*smithybearer.TokenCacheOptions),
) (smithybearer.TokenProvider, error) {
_, ok := provider.(*smithybearer.TokenCache)
if ok {
return provider, nil
}
tokenCacheConfigOptions, optionsFound, err := getBearerAuthTokenCacheOptions(ctx, cfgs)
if err != nil {
return nil, err
}
opts := make([]func(*smithybearer.TokenCacheOptions), 0, 2+len(optFns))
opts = append(opts, func(o *smithybearer.TokenCacheOptions) {
o.RefreshBeforeExpires = 5 * time.Minute
o.RetrieveBearerTokenTimeout = 30 * time.Second
})
opts = append(opts, optFns...)
if optionsFound {
opts = append(opts, tokenCacheConfigOptions)
}
return smithybearer.NewTokenCache(provider, opts...), nil
}

View File

@ -15,6 +15,7 @@ import (
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
"github.com/aws/aws-sdk-go-v2/service/sso"
"github.com/aws/aws-sdk-go-v2/service/ssooidc"
"github.com/aws/aws-sdk-go-v2/service/sts"
)
@ -29,25 +30,19 @@ var (
ecsContainerEndpoint = "http://169.254.170.2" // not constant to allow for swapping during unit-testing
)
// resolveCredentials extracts a credential provider from slice of config sources.
// resolveCredentials extracts a credential provider from slice of config
// sources.
//
// If an explict credential provider is not found the resolver will fallback to resolving
// credentials by extracting a credential provider from EnvConfig and SharedConfig.
// If an explicit credential provider is not found the resolver will fallback
// to resolving credentials by extracting a credential provider from EnvConfig
// and SharedConfig.
func resolveCredentials(ctx context.Context, cfg *aws.Config, configs configs) error {
found, err := resolveCredentialProvider(ctx, cfg, configs)
if err != nil {
return err
}
if found {
return nil
}
err = resolveCredentialChain(ctx, cfg, configs)
if err != nil {
if found || err != nil {
return err
}
return nil
return resolveCredentialChain(ctx, cfg, configs)
}
// resolveCredentialProvider extracts the first instance of Credentials from the
@ -61,12 +56,9 @@ func resolveCredentials(ctx context.Context, cfg *aws.Config, configs configs) e
// * credentialsProviderProvider
func resolveCredentialProvider(ctx context.Context, cfg *aws.Config, configs configs) (bool, error) {
credProvider, found, err := getCredentialsProvider(ctx, configs)
if err != nil {
if !found || err != nil {
return false, err
}
if !found {
return false, nil
}
cfg.Credentials, err = wrapWithCredentialsCache(ctx, configs, credProvider)
if err != nil {
@ -180,7 +172,30 @@ func resolveSSOCredentials(ctx context.Context, cfg *aws.Config, sharedConfig *S
}
cfgCopy := cfg.Copy()
cfgCopy.Region = sharedConfig.SSORegion
if sharedConfig.SSOSession != nil {
ssoTokenProviderOptionsFn, found, err := getSSOTokenProviderOptions(ctx, configs)
if err != nil {
return fmt.Errorf("failed to get SSOTokenProviderOptions from config sources, %w", err)
}
var optFns []func(*ssocreds.SSOTokenProviderOptions)
if found {
optFns = append(optFns, ssoTokenProviderOptionsFn)
}
cfgCopy.Region = sharedConfig.SSOSession.SSORegion
cachedPath, err := ssocreds.StandardCachedTokenFilepath(sharedConfig.SSOSession.Name)
if err != nil {
return err
}
oidcClient := ssooidc.NewFromConfig(cfgCopy)
tokenProvider := ssocreds.NewSSOTokenProvider(oidcClient, cachedPath, optFns...)
options = append(options, func(o *ssocreds.Options) {
o.SSOTokenProvider = tokenProvider
o.CachedTokenFilepath = cachedPath
})
} else {
cfgCopy.Region = sharedConfig.SSORegion
}
cfg.Credentials = ssocreds.New(sso.NewFromConfig(cfgCopy), sharedConfig.SSOAccountID, sharedConfig.SSORoleName, sharedConfig.SSOStartURL, options...)
@ -454,7 +469,7 @@ func wrapWithCredentialsCache(
return provider, nil
}
credCacheOptions, found, err := getCredentialsCacheOptionsProvider(ctx, cfgs)
credCacheOptions, optionsFound, err := getCredentialsCacheOptionsProvider(ctx, cfgs)
if err != nil {
return nil, err
}
@ -462,7 +477,7 @@ func wrapWithCredentialsCache(
// force allocation of a new slice if the additional options are
// needed, to prevent overwriting the passed in slice of options.
optFns = optFns[:len(optFns):len(optFns)]
if found {
if optionsFound {
optFns = append(optFns, credCacheOptions)
}

View File

@ -15,13 +15,19 @@ import (
"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"
)
const (
// Prefix to use for filtering profiles
// 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 `
// string equivalent for boolean
endpointDiscoveryDisabled = `false`
endpointDiscoveryEnabled = `true`
@ -42,10 +48,13 @@ const (
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"
ssoRegionKey = "sso_region"
ssoRoleNameKey = "sso_role_name"
ssoStartURL = "sso_start_url"
// Additional Config fields
regionKey = `region`
@ -99,7 +108,7 @@ var defaultSharedConfigProfile = DefaultSharedConfigProfile
// - Linux/Unix: $HOME/.aws/credentials
// - Windows: %USERPROFILE%\.aws\credentials
func DefaultSharedCredentialsFilename() string {
return filepath.Join(userHomeDir(), ".aws", "credentials")
return filepath.Join(shareddefaults.UserHomeDir(), ".aws", "credentials")
}
// DefaultSharedConfigFilename returns the SDK's default file path for
@ -110,7 +119,7 @@ func DefaultSharedCredentialsFilename() string {
// - Linux/Unix: $HOME/.aws/config
// - Windows: %USERPROFILE%\.aws\config
func DefaultSharedConfigFilename() string {
return filepath.Join(userHomeDir(), ".aws", "config")
return filepath.Join(shareddefaults.UserHomeDir(), ".aws", "config")
}
// DefaultSharedConfigFiles is a slice of the default shared config files that
@ -119,12 +128,26 @@ 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.
// 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)
}
// SharedConfig represents the configuration fields of the SDK config files.
type SharedConfig struct {
Profile string
@ -144,10 +167,17 @@ type SharedConfig struct {
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
SSORegion string
SSORoleName string
SSOStartURL string
RoleARN string
ExternalID string
@ -463,7 +493,6 @@ type LoadSharedConfigOptions struct {
//
// 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 {
@ -485,7 +514,7 @@ func LoadSharedConfigProfile(ctx context.Context, profile string, optFns ...func
}
// check for profile prefix and drop duplicates or invalid profiles
err = processConfigSections(ctx, configSections, option.Logger)
err = processConfigSections(ctx, &configSections, option.Logger)
if err != nil {
return SharedConfig{}, err
}
@ -497,12 +526,12 @@ func LoadSharedConfigProfile(ctx context.Context, profile string, optFns ...func
}
// check for profile prefix and drop duplicates or invalid profiles
err = processCredentialsSections(ctx, credentialsSections, option.Logger)
err = processCredentialsSections(ctx, &credentialsSections, option.Logger)
if err != nil {
return SharedConfig{}, err
}
err = mergeSections(configSections, credentialsSections)
err = mergeSections(&configSections, credentialsSections)
if err != nil {
return SharedConfig{}, err
}
@ -516,53 +545,73 @@ func LoadSharedConfigProfile(ctx context.Context, profile string, optFns ...func
return cfg, nil
}
func processConfigSections(ctx context.Context, sections ini.Sections, logger logging.Logger) error {
func processConfigSections(ctx context.Context, sections *ini.Sections, logger logging.Logger) error {
skipSections := map[string]struct{}{}
for _, section := range sections.List() {
// drop profiles without prefix for config files
if !strings.HasPrefix(section, profilePrefix) && !strings.EqualFold(section, "default") {
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.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.\n",
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,
)
}
}
}
// rename sections to remove `profile ` prefixing to match with credentials file.
// if default is already present, it will be dropped.
for _, section := range sections.List() {
if strings.HasPrefix(section, profilePrefix) {
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 default profile prefixed with `profile ` found in %s, "+
"overrided non-prefixed default profile from %s", v.SourceFile, oldSection.SourceFile))
}
// assign non-prefixed name to section
v.Name = section
sections.SetSection(section, v)
}
}
return nil
}
func processCredentialsSections(ctx context.Context, sections ini.Sections, logger logging.Logger) error {
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) {
@ -596,7 +645,7 @@ func loadIniFiles(filenames []string) (ini.Sections, error) {
}
// mergeSections into mergedSections
err = mergeSections(mergedSections, sections)
err = mergeSections(&mergedSections, sections)
if err != nil {
return ini.Sections{}, SharedConfigLoadError{Filename: filename, Err: err}
}
@ -606,7 +655,7 @@ func loadIniFiles(filenames []string) (ini.Sections, error) {
}
// mergeSections merges source section properties into destination section properties
func mergeSections(dst, src ini.Sections) error {
func mergeSections(dst *ini.Sections, src ini.Sections) error {
for _, sectionName := range src.List() {
srcSection, _ := src.GetSection(sectionName)
@ -680,6 +729,13 @@ func mergeSections(dst, src ini.Sections) error {
useFIPSEndpointKey,
defaultsModeKey,
retryModeKey,
caBundleKey,
ssoSessionNameKey,
ssoAccountIDKey,
ssoRegionKey,
ssoRoleNameKey,
ssoStartURLKey,
}
for i := range stringKeys {
if err := mergeStringKey(&srcSection, &dstSection, sectionName, stringKeys[i]); err != nil {
@ -698,7 +754,7 @@ func mergeSections(dst, src ini.Sections) error {
}
// set srcSection on dst srcSection
dst = dst.SetSection(sectionName, dstSection)
*dst = dst.SetSection(sectionName, dstSection)
}
return nil
@ -769,7 +825,7 @@ func (c *SharedConfig) setFromIniSections(profiles map[string]struct{}, profile
}
}
// set config from the provided ini section
// 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)
@ -782,9 +838,8 @@ func (c *SharedConfig) setFromIniSections(profiles map[string]struct{}, profile
// profile only have credential provider options.
c.clearAssumeRoleOptions()
} else {
// First time a profile has been seen, It must either be a assume role
// credentials, or SSO. Assert if the credential type requires a role ARN,
// the ARN is also set, or validate that the SSO configuration is complete.
// 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
}
@ -832,11 +887,26 @@ func (c *SharedConfig) setFromIniSections(profiles map[string]struct{}, profile
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
}
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
// 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
@ -871,10 +941,16 @@ func (c *SharedConfig) setFromIniSection(profile string, section ini.Section) er
updateString(&c.Region, section, regionKey)
// AWS Single Sign-On (AWS SSO)
updateString(&c.SSOAccountID, section, ssoAccountIDKey)
// 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)
updateString(&c.SSOStartURL, section, ssoStartURL)
if section.Has(roleDurationSecondsKey) {
d := time.Duration(section.Int(roleDurationSecondsKey)) * time.Second
@ -992,32 +1068,47 @@ func (c *SharedConfig) validateCredentialType() error {
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, or sso")
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.hasSSOConfiguration() {
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.SSOAccountID) == 0 {
missing = append(missing, ssoAccountIDKey)
if len(c.SSOSessionName) == 0 {
missing = append(missing, ssoSessionNameKey)
}
if len(c.SSORegion) == 0 {
missing = append(missing, ssoRegionKey)
}
if c.SSOSession == nil {
missing = append(missing, ssoSectionPrefix)
} else {
if len(c.SSOSession.SSORegion) == 0 {
missing = append(missing, ssoRegionKey)
}
if len(c.SSORoleName) == 0 {
missing = append(missing, ssoRoleNameKey)
}
if len(c.SSOStartURL) == 0 {
missing = append(missing, ssoStartURL)
if len(c.SSOSession.SSOStartURL) == 0 {
missing = append(missing, ssoStartURLKey)
}
}
if len(missing) > 0 {
@ -1025,6 +1116,40 @@ func (c *SharedConfig) validateSSOConfiguration() error {
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
}
@ -1044,15 +1169,15 @@ func (c *SharedConfig) hasCredentials() bool {
}
func (c *SharedConfig) hasSSOConfiguration() bool {
switch {
case len(c.SSOAccountID) != 0:
case len(c.SSORegion) != 0:
case len(c.SSORoleName) != 0:
case len(c.SSOStartURL) != 0:
default:
return false
}
return true
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() {
@ -1143,12 +1268,6 @@ func (e CredentialRequiresARNError) Error() string {
)
}
func userHomeDir() string {
// Ignore errors since we only care about Windows and *nix.
homedir, _ := os.UserHomeDir()
return homedir
}
func oneOrNone(bs ...bool) bool {
var count int