diff --git a/README.md b/README.md index 6fecbf7bd69..94a333f1197 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AWS SDK for Go v2 -![Build Status](https://codebuild.us-west-2.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoib1lGQ3N6RFJsalI5a3BPcXB3Rytaak9kYVh1ZW1lZExPNjgzaU9Udng3VE5OL1I3czIwcVhkMUlUeG91ajBVaWRYcVVJSEVQcmZwTWVyT1p5MGszbnA4PSIsIml2UGFyYW1ldGVyU3BlYyI6IkhrZ1VMN20zRmtYY1BrR0wiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=master) [![API Reference](https://img.shields.io/badge/api-reference-blue.svg)](https://docs.aws.amazon.com/sdk-for-go/v2/api) [![Join the chat at https://gitter.im/aws/aws-sdk-go](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aws/aws-sdk-go-v2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Apache V2 License](https://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt) +![Build Status](https://codebuild.us-west-2.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoib1lGQ3N6RFJsalI5a3BPcXB3Rytaak9kYVh1ZW1lZExPNjgzaU9Udng3VE5OL1I3czIwcVhkMUlUeG91ajBVaWRYcVVJSEVQcmZwTWVyT1p5MGszbnA4PSIsIml2UGFyYW1ldGVyU3BlYyI6IkhrZ1VMN20zRmtYY1BrR0wiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=master) [![API Reference](https://img.shields.io/badge/api-reference-blue.svg)](https://pkg.go.dev/mod/github.com/aws/aws-sdk-go-v2) [![Apache V2 License](https://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt) `aws-sdk-go-v2` is the **Developer Preview** (aka **beta**) for the v2 AWS SDK for the Go programming language. This Developer Preview is provided to receive feedback from the language community on SDK changes prior to the final release. As such users should expect the SDK to release minor version releases that break backwards compatability. The release notes for the breaking change will include information about the breaking change, and how you can migrate to the latest version. @@ -12,7 +12,6 @@ We'll be expanding out the [Issues] and [Projects] sections with additional chan Jump To: * [Project Status](_#Project-Status_) * [Getting Started](_#Getting-Started_) -* [Quick Examples](_#Quick-Examples_) * [Getting Help](_#Getting-Help_) * [Contributing](_#Feedback-and-contributing_) * [More Resources](_#Resources_) @@ -33,63 +32,73 @@ Users should expect significant changes that could affect the following (non-exh * Minimum Supported Go Release following the [Language Release Policy](https://golang.org/doc/devel/release.html#policy) ## Getting started +To get started working with the SDK setup your project for Go modules, and retrieve the SDK dependencies with `go get`. +This example shows how you can use the v2 SDK to make an API request using the SDK's [Amazon DynamoDB] client. -To get started working with the SDK is to use `go get` to add the SDK to your application dependencies using Go modules. - +###### Initialize Project ```sh -go get github.com/aws/aws-sdk-go-v2 -go get github.com/aws/aws-sdk-go-v2/service/dynamodb +$ mkdir ~/helloaws +$ cd ~/helloaws +$ go mod init helloaws +``` +###### Add SDK Dependencies +```sh +$ go get github.com/aws/aws-sdk-go-v2/aws +$ go get github.com/aws/aws-sdk-go-v2/aws/config +$ go get github.com/aws/aws-sdk-go-v2/service/dynamodb ``` -## Quick Examples - -### Hello AWS - -This example shows how you can use the v2 SDK to make an API request using the SDK's [Amazon DynamoDB] client. +###### Write Code +In your preferred editor add the following content to `main.go` ```go package main import ( - "context" - "fmt" + "context" + "fmt" + "log" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/config" - "github.com/aws/aws-sdk-go-v2/service/dynamodb" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/dynamodb" ) func main() { - // Using the SDK's default configuration, loading additional config - // and credentials values from the environment variables, shared - // credentials, and shared configuration files - cfg, err := config.LoadDefaultConfig() - if err != nil { - panic("unable to load SDK config, " + err.Error()) - } - - // Set the AWS Region that the service clients should use - cfg.Region = "us-west-2" - - // Using the Config value, create the DynamoDB client - svc := dynamodb.NewFromConfig(cfg) - - // Build the request with its input parameters - resp, err := svc.DescribeTable(context.Background(), &dynamodb.DescribeTableInput{ - TableName: aws.String("myTable"), - }) - if err != nil { - panic("failed to describe table, " + err.Error()) - } - - if err != nil { - panic("failed to describe table, " + err.Error()) - } - - fmt.Println("Response", resp) + // Using the SDK's default configuration, loading additional config + // and credentials values from the environment variables, shared + // credentials, and shared configuration files + cfg, err := config.LoadDefaultConfig(config.WithRegion("us-west-2")) + if err != nil { + log.Fatalf("unable to load SDK config, %v", err) + } + + // Using the Config value, create the DynamoDB client + svc := dynamodb.NewFromConfig(cfg) + + // Build the request with its input parameters + resp, err := svc.ListTables(context.Background(), &dynamodb.ListTablesInput{ + Limit: aws.Int32(5), + }) + if err != nil { + log.Fatalf("failed to list tables, %v", err) + } + + fmt.Println("Tables:") + for _, tableName := range resp.TableNames { + fmt.Println(aws.ToString(tableName)) + } } ``` +###### Compile and Execute +```sh +$ go run . +Table: +tableOne +tableTwo +``` + ## Getting Help Please use these community resources for getting help. We use the GitHub issues diff --git a/config/codegen/main.go b/config/codegen/main.go index 5fb06fce782..8c46ec62b9a 100644 --- a/config/codegen/main.go +++ b/config/codegen/main.go @@ -16,13 +16,19 @@ const ( ) var implAsserts = map[string][]string{ - "SharedConfigProfileProvider": {envConfigType, `WithSharedConfigProfile("")`}, - "SharedConfigFilesProvider": {envConfigType, "WithSharedConfigFiles([]string{})"}, - "CustomCABundleProvider": {envConfigType, "WithCustomCABundle([]byte{})"}, - "RegionProvider": {envConfigType, sharedConfigType, `WithRegion("")` /*"&WithEC2MetadataRegion{}"*/}, - "MFATokenFuncProvider": {`WithMFATokenFunc(func() (string, error) { return "", nil })`}, - "CredentialsProviderProvider": {`WithCredentialsProvider{credentials.NewStaticCredentialsProvider("", "", "")}`}, - "DefaultRegionProvider": {`WithDefaultRegion("")`}, + "SharedConfigProfileProvider": {envConfigType, `WithSharedConfigProfile("")`}, + "SharedConfigFilesProvider": {envConfigType, `WithSharedConfigFiles(nil)`}, + "CustomCABundleProvider": {envConfigType, `WithCustomCABundle(nil)`}, + "RegionProvider": {envConfigType, sharedConfigType, `WithRegion("")`, `WithEC2IMDSRegion{}`}, + "CredentialsProviderProvider": {`WithCredentialsProvider(nil)`}, + "DefaultRegionProvider": {`WithDefaultRegion("")`}, + "EC2RoleCredentialOptionsProvider": {`WithEC2RoleCredentialOptions(nil)`}, + "EndpointCredentialOptionsProvider": {`WithEndpointCredentialOptions(nil)`}, + "EndpointResolverProvider": {`WithEndpointResolver(nil)`}, + "APIOptionsProvider": {`WithAPIOptions(nil)`}, + "HTTPClientProvider": {`WithHTTPClient(nil)`}, + "AssumeRoleCredentialOptionsProvider": {`WithAssumeRoleCredentialOptions(nil)`}, + "WebIdentityRoleCredentialOptionsProvider": {`WithWebIdentityRoleCredentialOptions(nil)`}, } var tplProviderTests = template.Must(template.New("tplProviderTests").Funcs(map[string]interface{}{ @@ -41,10 +47,6 @@ var tplProviderTests = template.Must(template.New("tplProviderTests").Funcs(map[ package config -import ( - "github.com/aws/aws-sdk-go-v2/credentials" -) - {{ $sortedKeys := SortKeys . }} {{- range $_, $provider := $sortedKeys }} {{- $implementors := index $ $provider -}} diff --git a/config/config.go b/config/config.go index d2d1b07f49b..c2cfe752977 100644 --- a/config/config.go +++ b/config/config.go @@ -4,30 +4,30 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" ) -// DefaultLoaders are a slice of functions that will read external configuration +// defaultLoaders are a slice of functions that will read external configuration // sources for configuration values. These values are read by the AWSConfigResolvers // using interfaces to extract specific information from the external configuration. -var DefaultLoaders = []Loader{ - LoadEnvConfig, - LoadSharedConfigIgnoreNotExist, +var defaultLoaders = []loader{ + loadEnvConfig, + loadSharedConfigIgnoreNotExist, } -// DefaultAWSConfigResolvers are a slice of functions that will resolve external +// defaultAWSConfigResolvers are a slice of functions that will resolve external // configuration values into AWS configuration values. // // This will setup the AWS configuration's Region, -var DefaultAWSConfigResolvers = []AWSConfigResolver{ - ResolveDefaultAWSConfig, - ResolveCustomCABundle, - ResolveHTTPClient, - ResolveEndpointResolver, - ResolveAPIOptions, - - ResolveRegion, +var defaultAWSConfigResolvers = []awsConfigResolver{ + resolveDefaultAWSConfig, + resolveCustomCABundle, + resolveHTTPClient, + resolveEndpointResolver, + resolveAPIOptions, + + resolveRegion, // TODO: Add back EC2 Region Resolver Support - ResolveDefaultRegion, + resolveDefaultRegion, - ResolveCredentials, + resolveCredentials, } // A Config represents a generic configuration value or set of values. This type @@ -37,22 +37,22 @@ var DefaultAWSConfigResolvers = []AWSConfigResolver{ // to extract specific data from the Config. type Config interface{} -// A Loader is used to load external configuration data and returns it as +// A loader is used to load external configuration data and returns it as // a generic Config type. // // The loader should return an error if it fails to load the external configuration // or the configuration data is malformed, or required components missing. -type Loader func(Configs) (Config, error) +type loader func(configs) (Config, error) -// An AWSConfigResolver will extract configuration data from the Configs slice +// An awsConfigResolver will extract configuration data from the configs slice // using the provider interfaces to extract specific functionality. The extracted // configuration values will be written to the AWS Config value. // // The resolver should return an error if it it fails to extract the data, the // data is malformed, or incomplete. -type AWSConfigResolver func(cfg *aws.Config, configs Configs) error +type awsConfigResolver func(cfg *aws.Config, configs configs) error -// Configs is a slice of Config values. These values will be used by the +// configs is a slice of Config values. These values will be used by the // AWSConfigResolvers to extract external configuration values to populate the // AWS Config type. // @@ -61,15 +61,15 @@ type AWSConfigResolver func(cfg *aws.Config, configs Configs) error // // Use ResolveAWSConfig after external Config values have been added or loaded // to extract the loaded configuration values into the AWS Config. -type Configs []Config +type configs []Config // AppendFromLoaders iterates over the slice of loaders passed in calling each // loader function in order. The external config value returned by the loader -// will be added to the returned Configs slice. +// will be added to the returned configs slice. // // If a loader returns an error this method will stop iterating and return // that error. -func (cs Configs) AppendFromLoaders(loaders []Loader) (Configs, error) { +func (cs configs) AppendFromLoaders(loaders []loader) (configs, error) { for _, fn := range loaders { cfg, err := fn(cs) if err != nil { @@ -88,7 +88,7 @@ func (cs Configs) AppendFromLoaders(loaders []Loader) (Configs, error) { // // If an resolver returns an error this method will return that error, and stop // iterating over the resolvers. -func (cs Configs) ResolveAWSConfig(resolvers []AWSConfigResolver) (aws.Config, error) { +func (cs configs) ResolveAWSConfig(resolvers []awsConfigResolver) (aws.Config, error) { var cfg aws.Config for _, fn := range resolvers { @@ -109,7 +109,7 @@ func (cs Configs) ResolveAWSConfig(resolvers []AWSConfigResolver) (aws.Config, e // ResolveConfig calls the provide function passing slice of configuration sources. // This implements the aws.ConfigResolver interface. -func (cs Configs) ResolveConfig(f func(configs []interface{}) error) error { +func (cs configs) ResolveConfig(f func(configs []interface{}) error) error { var cfgs []interface{} for i := range cs { cfgs = append(cfgs, cs[i]) @@ -121,7 +121,7 @@ func (cs Configs) ResolveConfig(f func(configs []interface{}) error) error { // populates an AWS Config with the values from the external configurations. // // An optional variadic set of additional Config values can be provided as input -// that will be prepended to the Configs slice. Use this to add custom configuration. +// that will be prepended to the configs slice. Use this to add custom configuration. // The custom configurations must satisfy the respective providers for their data // or the custom data will be ignored by the resolvers and config loaders. // @@ -136,14 +136,14 @@ func (cs Configs) ResolveConfig(f func(configs []interface{}) error) error { // The default configuration sources are: // * Environment Variables // * Shared Configuration and Shared Credentials files. -func LoadDefaultConfig(configs ...Config) (aws.Config, error) { - var cfgs Configs - cfgs = append(cfgs, configs...) +func LoadDefaultConfig(cfgs ...Config) (aws.Config, error) { + var cfgCpy configs + cfgCpy = append(cfgCpy, cfgs...) - cfgs, err := cfgs.AppendFromLoaders(DefaultLoaders) + cfgCpy, err := cfgCpy.AppendFromLoaders(defaultLoaders) if err != nil { return aws.Config{}, err } - return cfgs.ResolveAWSConfig(DefaultAWSConfigResolvers) + return cfgCpy.ResolveAWSConfig(defaultAWSConfigResolvers) } diff --git a/config/config_test.go b/config/config_test.go index 50519673f95..3e37cadd890 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -10,11 +10,11 @@ import ( ) func TestConfigs_SharedConfigOptions(t *testing.T) { - _, err := Configs{ + _, err := configs{ WithSharedConfigProfile("profile-name"), WithSharedConfigFiles([]string{"creds-file"}), - }.AppendFromLoaders([]Loader{ - func(configs Configs) (Config, error) { + }.AppendFromLoaders([]loader{ + func(configs configs) (Config, error) { var profile string var files []string var err error @@ -54,8 +54,8 @@ func TestConfigs_SharedConfigOptions(t *testing.T) { func TestConfigs_AppendFromLoaders(t *testing.T) { expectCfg := WithRegion("mock-region") - cfgs, err := Configs{}.AppendFromLoaders([]Loader{ - func(configs Configs) (Config, error) { + cfgs, err := configs{}.AppendFromLoaders([]loader{ + func(configs configs) (Config, error) { if e, a := 0, len(configs); e != a { t.Errorf("expect %v configs, got %v", e, a) } @@ -77,19 +77,19 @@ func TestConfigs_AppendFromLoaders(t *testing.T) { } func TestConfigs_ResolveAWSConfig(t *testing.T) { - configSources := Configs{ + configSources := configs{ WithRegion("mock-region"), - WithCredentialsProvider{credentials.StaticCredentialsProvider{ + WithCredentialsProvider(credentials.StaticCredentialsProvider{ Value: aws.Credentials{ AccessKeyID: "AKID", SecretAccessKey: "SECRET", Source: "provider", }, - }}, + }), } - cfg, err := configSources.ResolveAWSConfig([]AWSConfigResolver{ - ResolveRegion, - ResolveCredentials, + cfg, err := configSources.ResolveAWSConfig([]awsConfigResolver{ + resolveRegion, + resolveCredentials, }) if err != nil { t.Fatalf("expect no error, got %v", err) diff --git a/config/doc.go b/config/doc.go index 76da6eddbc8..eac06645c1a 100644 --- a/config/doc.go +++ b/config/doc.go @@ -8,5 +8,13 @@ // Use the LoadDefaultConfig to load configuration from all the SDK's supported // sources, and resolve credentials using the SDK's default credential chain. // -// * TODO Additional documentation needed. +// LoadDefaultConfig allows for a variadic list of additional Config sources that can +// provide one or more configuration values which can be used to programmatically control the resolution +// of a specific value, or allow for broader range of additional configuration sources not supported by the SDK. +// A Config source implements one or more provider interfaces defined in this package. Config sources passed in will +// 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 +// interface. These helpers should be used for overriding configuration programatically at runtime. package config diff --git a/config/doc_test.go b/config/doc_test.go new file mode 100644 index 00000000000..81360726284 --- /dev/null +++ b/config/doc_test.go @@ -0,0 +1,48 @@ +package config_test + +import ( + "context" + "fmt" + "log" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/sts" +) + +func Example() { + cfg, err := config.LoadDefaultConfig() + if err != nil { + log.Fatal(err) + } + + client := sts.NewFromConfig(cfg) + + identity, err := client.GetCallerIdentity(context.Background(), &sts.GetCallerIdentityInput{}) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Account: %s, Arn: %s", aws.ToString(identity.Account), aws.ToString(identity.Arn)) +} + +func Example_custom_config() { + // Config sources can be passed to LoadDefaultConfig, these sources can implement one or more + // provider interfaces. These sources take priority over the standard environment and shared configuration values. + cfg, err := config.LoadDefaultConfig( + config.WithRegion("us-west-2"), + config.WithSharedConfigProfile("customProfile"), + ) + if err != nil { + log.Fatal(err) + } + + client := sts.NewFromConfig(cfg) + + identity, err := client.GetCallerIdentity(context.Background(), &sts.GetCallerIdentityInput{}) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Account: %s, Arn: %s", aws.ToString(identity.Account), aws.ToString(identity.Arn)) +} diff --git a/config/env_config.go b/config/env_config.go index 0b3352d121a..f942bbe356f 100644 --- a/config/env_config.go +++ b/config/env_config.go @@ -133,7 +133,7 @@ type EnvConfig struct { // AWS_CONFIG_FILE=$HOME/my_shared_config SharedConfigFile string - // Sets the path to a custom Credentials Authroity (CA) Bundle PEM file + // 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. @@ -179,9 +179,9 @@ type EnvConfig struct { S3UseARNRegion *bool } -// LoadEnvConfig reads configuration values from the OS's environment variables. +// loadEnvConfig reads configuration values from the OS's environment variables. // Returning the a Config typed EnvConfig to satisfy the ConfigLoader func type. -func LoadEnvConfig(cfgs Configs) (Config, error) { +func loadEnvConfig(cfgs configs) (Config, error) { return NewEnvConfig() } diff --git a/config/example_test.go b/config/example_test.go index 76f8bbc3373..4f4a359f836 100644 --- a/config/example_test.go +++ b/config/example_test.go @@ -3,12 +3,16 @@ package config_test import ( "context" "fmt" - "os" + "log" + "net/http" "path/filepath" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/credentials/stscreds" + "github.com/awslabs/smithy-go/middleware" + smithyhttp "github.com/awslabs/smithy-go/transport/http" ) func ExampleWithSharedConfigProfile() { @@ -23,8 +27,7 @@ func ExampleWithSharedConfigProfile() { }), ) if err != nil { - fmt.Fprintf(os.Stderr, "failed to load config, %v", err) - os.Exit(1) + log.Fatal(err) } // Region loaded from credentials file. @@ -37,30 +40,98 @@ func ExampleWithSharedConfigProfile() { func ExampleWithCredentialsProvider() { cfg, err := config.LoadDefaultConfig( // Hard coded credentials. - config.WithCredentialsProvider{ - CredentialsProvider: credentials.StaticCredentialsProvider{ - Value: aws.Credentials{ - AccessKeyID: "AKID", SecretAccessKey: "SECRET", SessionToken: "SESSION", - Source: "example hard coded credentials", - }, + config.WithCredentialsProvider(credentials.StaticCredentialsProvider{ + Value: aws.Credentials{ + AccessKeyID: "AKID", SecretAccessKey: "SECRET", SessionToken: "SESSION", + Source: "example hard coded credentials", }, - }, - ) + })) if err != nil { - fmt.Fprintf(os.Stderr, "failed to load config, %v", err) - os.Exit(1) + log.Fatal(err) } // Credentials retrieve will be called automatically internally to the SDK // service clients created with the cfg value. creds, err := cfg.Credentials.Retrieve(context.Background()) if err != nil { - fmt.Fprintf(os.Stderr, "failed to get credentials, %v", err) - os.Exit(1) + log.Fatal(err) } fmt.Println("Credentials Source:", creds.Source) - - // Output: // Credentials Source: example hard coded credentials } + +func ExampleWithAPIOptions() { + // import "github.com/awslabs/smithy-go/middleware" + // import smithyhttp "github.com/awslabs/smithy-go/transport/http" + + cfg, err := config.LoadDefaultConfig(config.WithAPIOptions([]func(stack *middleware.Stack) error{ + smithyhttp.AddHeaderValue("X-Custom-Header", "customHeaderValue"), + })) + if err != nil { + log.Fatal(err) + } + _ = cfg +} + +func ExampleWithEndpointResolver() { + cfg, err := config.LoadDefaultConfig(config.WithEndpointResolver( + aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) { + return aws.Endpoint{URL: "https://mock.amazonaws.com"}, nil + }))) + if err != nil { + log.Fatal(err) + } + _ = cfg +} + +func ExampleWithHTTPClient() { + cfg, err := config.LoadDefaultConfig(config.WithHTTPClient( + aws.NewBuildableHTTPClient().WithTransportOptions(func(tr *http.Transport) { + tr.MaxIdleConns = 60 + }))) + if err != nil { + log.Fatal(err) + } + _ = cfg +} + +func ExampleWithWebIdentityRoleCredentialOptions() { + cfg, err := config.LoadDefaultConfig(config.WithWebIdentityRoleCredentialOptions(func(options *stscreds.WebIdentityRoleOptions) { + options.RoleSessionName = "customSessionName" + })) + if err != nil { + log.Fatal(err) + } + _ = cfg +} + +func ExampleWithRegion() { + cfg, err := config.LoadDefaultConfig(config.WithRegion("us-west-2")) + if err != nil { + log.Fatal(err) + } + _ = cfg +} + +func ExampleWithEC2IMDSRegion() { + cfg, err := config.LoadDefaultConfig(config.WithEC2IMDSRegion{}) + if err != nil { + log.Fatal(err) + } + _ = cfg +} + +func ExampleWithAssumeRoleCredentialOptions() { + // WithAssumeRoleCredentialOptions can be used to configure the AssumeRoleOptions for the STS credential provider. + // For example the TokenProvider can be populated if assuming a role that requires an MFA token. + cfg, err := config.LoadDefaultConfig(config.WithAssumeRoleCredentialOptions(func(options *stscreds.AssumeRoleOptions) { + options.TokenProvider = func() (string, error) { + return "theTokenCode", nil + } + })) + if err != nil { + log.Fatal(err) + } + _ = cfg +} diff --git a/config/local_test.go b/config/local_test.go index ea109895cc3..94fcff65fa8 100644 --- a/config/local_test.go +++ b/config/local_test.go @@ -25,7 +25,6 @@ func TestValidateLocalURL(t *testing.T) { h, ok := m[host] if !ok { - t.Fatalf("unknown host in test, %v", host) return nil, fmt.Errorf("unknown host") } diff --git a/config/provider.go b/config/provider.go index 6cd41140fd7..41f5bb3ac43 100644 --- a/config/provider.go +++ b/config/provider.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "net/http" - "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds" @@ -31,10 +30,10 @@ func (c WithSharedConfigProfile) GetSharedConfigProfile() (string, error) { return string(c), nil } -// GetSharedConfigProfile searches the Configs for a SharedConfigProfileProvider +// getSharedConfigProfile searches the configs for a SharedConfigProfileProvider // and returns the value if found. Returns an error if a provider fails before a // value is found. -func GetSharedConfigProfile(configs Configs) (string, bool, error) { +func getSharedConfigProfile(configs configs) (string, bool, error) { for _, cfg := range configs { if p, ok := cfg.(SharedConfigProfileProvider); ok { v, err := p.GetSharedConfigProfile() @@ -58,18 +57,18 @@ type SharedConfigFilesProvider interface { // WithSharedConfigFiles wraps a slice of strings to satisfy the // SharedConfigFilesProvider interface so a slice of custom shared config files -// ared used when loading the SharedConfig. +// are used when loading the SharedConfig. type WithSharedConfigFiles []string // GetSharedConfigFiles returns the slice of shared config files. func (c WithSharedConfigFiles) GetSharedConfigFiles() ([]string, error) { - return []string(c), nil + return c, nil } -// GetSharedConfigFiles searchds the Configs for a SharedConfigFilesProvider +// getSharedConfigFiles searchds the configs for a SharedConfigFilesProvider // and returns the value if found. Returns an error if a provider fails before a // value is found. -func GetSharedConfigFiles(configs Configs) ([]string, bool, error) { +func getSharedConfigFiles(configs configs) ([]string, bool, error) { for _, cfg := range configs { if p, ok := cfg.(SharedConfigFilesProvider); ok { v, err := p.GetSharedConfigFiles() @@ -96,13 +95,13 @@ type WithCustomCABundle []byte // GetCustomCABundle returns the CA bundle PEM bytes. func (v WithCustomCABundle) GetCustomCABundle() ([]byte, error) { - return []byte(v), nil + return v, nil } -// GetCustomCABundle searchds the Configs for a CustomCABundleProvider +// getCustomCABundle searchds the configs for a CustomCABundleProvider // and returns the value if found. Returns an error if a provider fails before a // value is found. -func GetCustomCABundle(configs Configs) ([]byte, bool, error) { +func getCustomCABundle(configs configs) ([]byte, bool, error) { for _, cfg := range configs { if p, ok := cfg.(CustomCABundleProvider); ok { v, err := p.GetCustomCABundle() @@ -132,9 +131,9 @@ func (v WithRegion) GetRegion() (string, error) { return string(v), nil } -// GetRegion searchds the Configs for a RegionProvider and returns the value +// getRegion searchds the configs for a RegionProvider and returns the value // if found. Returns an error if a provider fails before a value is found. -func GetRegion(configs Configs) (string, bool, error) { +func getRegion(configs configs) (string, bool, error) { for _, cfg := range configs { if p, ok := cfg.(RegionProvider); ok { v, err := p.GetRegion() @@ -190,12 +189,16 @@ type CredentialsProviderProvider interface { // WithCredentialsProvider provides wrapping of a credentials Value to satisfy the // CredentialsProviderProvider interface. -type WithCredentialsProvider struct { +func WithCredentialsProvider(provider aws.CredentialsProvider) CredentialsProviderProvider { + return withCredentialsProvider{CredentialsProvider: provider} +} + +type withCredentialsProvider struct { aws.CredentialsProvider } // GetCredentialsProvider returns the credentials value. -func (v WithCredentialsProvider) GetCredentialsProvider() (aws.CredentialsProvider, bool, error) { +func (v withCredentialsProvider) GetCredentialsProvider() (aws.CredentialsProvider, bool, error) { if v.CredentialsProvider == nil { return nil, false, nil } @@ -203,10 +206,10 @@ func (v WithCredentialsProvider) GetCredentialsProvider() (aws.CredentialsProvid return v.CredentialsProvider, true, nil } -// GetCredentialsProvider searches the Configs for a CredentialsProviderProvider +// getCredentialsProvider searches the configs for a CredentialsProviderProvider // and returns the value if found. Returns an error if a provider fails before a // value is found. -func GetCredentialsProvider(configs Configs) (p aws.CredentialsProvider, found bool, err error) { +func getCredentialsProvider(configs configs) (p aws.CredentialsProvider, found bool, err error) { for _, cfg := range configs { if provider, ok := cfg.(CredentialsProviderProvider); ok { p, found, err = provider.GetCredentialsProvider() @@ -222,49 +225,6 @@ func GetCredentialsProvider(configs Configs) (p aws.CredentialsProvider, found b return p, found, err } -// MFATokenFuncProvider provides access to the MFA token function needed for -// Assume Role with MFA. -type MFATokenFuncProvider interface { - GetMFATokenFunc() (func() (string, error), error) -} - -// WithMFATokenFunc provides wrapping of a string to satisfy the -// MFATokenFuncProvider interface. -type WithMFATokenFunc func() (string, error) - -// GetMFATokenFunc returns the MFA Token function. -func (p WithMFATokenFunc) GetMFATokenFunc() (func() (string, error), error) { - return p, nil -} - -// GetMFATokenFunc searches the Configs for a MFATokenFuncProvider -// and returns the value if found. Returns an error if a provider fails before a -// value is found. -func GetMFATokenFunc(configs Configs) (func() (string, error), bool, error) { - for _, cfg := range configs { - if p, ok := cfg.(MFATokenFuncProvider); ok { - v, err := p.GetMFATokenFunc() - if err != nil { - return nil, false, err - } - if v != nil { - return v, true, nil - } - } - } - - return nil, false, nil -} - -// WithAssumeRoleDuration provides a wrapping type of a time.Duration to satisfy -type WithAssumeRoleDuration time.Duration - -// GetAssumeRoleDuration returns the wrapped time.Duration value to use when setting -// the assume role credentials duration. -func (w WithAssumeRoleDuration) GetAssumeRoleDuration() (time.Duration, bool, error) { - return time.Duration(w), true, nil -} - // ProcessCredentialOptions is an interface for retrieving a function for setting // the processcreds.Options. type ProcessCredentialOptions interface { @@ -280,8 +240,8 @@ func (w WithProcessCredentialOptions) GetProcessCredentialOptions() (func(*proce return w, true, nil } -// GetProcessCredentialOptions searches the slice of configs and returns the first function found -func GetProcessCredentialOptions(configs Configs) (f func(*processcreds.Options), found bool, err error) { +// getProcessCredentialOptions searches the slice of configs and returns the first function found +func getProcessCredentialOptions(configs configs) (f func(*processcreds.Options), found bool, err error) { for _, config := range configs { if p, ok := config.(ProcessCredentialOptions); ok { f, found, err = p.GetProcessCredentialOptions() @@ -296,26 +256,26 @@ func GetProcessCredentialOptions(configs Configs) (f func(*processcreds.Options) return f, found, err } -// EC2RoleCredentialProviderOptions is an interface for retrieving a function +// EC2RoleCredentialOptionsProvider is an interface for retrieving a function // for setting the ec2rolecreds.Provider options. -type EC2RoleCredentialProviderOptions interface { - GetEC2RoleCredentialProviderOptions() (func(*ec2rolecreds.Options), bool, error) +type EC2RoleCredentialOptionsProvider interface { + GetEC2RoleCredentialOptions() (func(*ec2rolecreds.Options), bool, error) } -// WithEC2RoleCredentialProviderOptions wraps a function and satisfies the -// EC2RoleCredentialProviderOptions interface -type WithEC2RoleCredentialProviderOptions func(*ec2rolecreds.Options) +// WithEC2RoleCredentialOptions wraps a function and satisfies the +// EC2RoleCredentialOptionsProvider interface +type WithEC2RoleCredentialOptions func(*ec2rolecreds.Options) -// GetEC2RoleCredentialProviderOptions returns the wrapped function -func (w WithEC2RoleCredentialProviderOptions) GetEC2RoleCredentialProviderOptions() (func(*ec2rolecreds.Options), bool, error) { +// GetEC2RoleCredentialOptions returns the wrapped function +func (w WithEC2RoleCredentialOptions) GetEC2RoleCredentialOptions() (func(*ec2rolecreds.Options), bool, error) { return w, true, nil } -// GetEC2RoleCredentialProviderOptions searches the slice of configs and returns the first function found -func GetEC2RoleCredentialProviderOptions(configs Configs) (f func(*ec2rolecreds.Options), found bool, err error) { +// getEC2RoleCredentialProviderOptions searches the slice of configs and returns the first function found +func getEC2RoleCredentialProviderOptions(configs configs) (f func(*ec2rolecreds.Options), found bool, err error) { for _, config := range configs { - if p, ok := config.(EC2RoleCredentialProviderOptions); ok { - f, found, err = p.GetEC2RoleCredentialProviderOptions() + if p, ok := config.(EC2RoleCredentialOptionsProvider); ok { + f, found, err = p.GetEC2RoleCredentialOptions() if err != nil { return nil, false, err } @@ -340,8 +300,8 @@ func (w WithDefaultRegion) GetDefaultRegion() (string, bool, error) { return string(w), true, nil } -// GetDefaultRegion searches the slice of configs and returns the first fallback region found -func GetDefaultRegion(configs Configs) (value string, found bool, err error) { +// getDefaultRegion searches the slice of configs and returns the first fallback region found +func getDefaultRegion(configs configs) (value string, found bool, err error) { for _, config := range configs { if p, ok := config.(DefaultRegionProvider); ok { value, found, err = p.GetDefaultRegion() @@ -357,25 +317,25 @@ func GetDefaultRegion(configs Configs) (value string, found bool, err error) { return value, found, err } -// EndpointCredentialProviderOptions is an interface for retrieving a function for setting +// EndpointCredentialOptionsProvider is an interface for retrieving a function for setting // the endpointcreds.ProviderOptions. -type EndpointCredentialProviderOptions interface { - GetEndpointCredentialProviderOptions() (func(*endpointcreds.Options), bool, error) +type EndpointCredentialOptionsProvider interface { + GetEndpointCredentialOptions() (func(*endpointcreds.Options), bool, error) } -// WithEndpointCredentialProviderOptions wraps a function and satisfies the EC2RoleCredentialProviderOptions interface -type WithEndpointCredentialProviderOptions func(*endpointcreds.Options) +// WithEndpointCredentialOptions wraps a function and satisfies the EC2RoleCredentialOptionsProvider interface +type WithEndpointCredentialOptions func(*endpointcreds.Options) -// GetEndpointCredentialProviderOptions returns the wrapped function -func (w WithEndpointCredentialProviderOptions) GetEndpointCredentialProviderOptions() (func(*endpointcreds.Options), bool, error) { +// GetEndpointCredentialOptions returns the wrapped function +func (w WithEndpointCredentialOptions) GetEndpointCredentialOptions() (func(*endpointcreds.Options), bool, error) { return w, true, nil } -// GetEndpointCredentialProviderOptions searches the slice of configs and returns the first function found -func GetEndpointCredentialProviderOptions(configs Configs) (f func(*endpointcreds.Options), found bool, err error) { +// getEndpointCredentialProviderOptions searches the slice of configs and returns the first function found +func getEndpointCredentialProviderOptions(configs configs) (f func(*endpointcreds.Options), found bool, err error) { for _, config := range configs { - if p, ok := config.(EndpointCredentialProviderOptions); ok { - f, found, err = p.GetEndpointCredentialProviderOptions() + if p, ok := config.(EndpointCredentialOptionsProvider); ok { + f, found, err = p.GetEndpointCredentialOptions() if err != nil { return nil, false, err } @@ -387,25 +347,25 @@ func GetEndpointCredentialProviderOptions(configs Configs) (f func(*endpointcred return f, found, err } -// WebIdentityCredentialProviderOptions is an interface for retrieving a function for setting -// the stscreds.WebIdentityCredentialProviderOptions. -type WebIdentityCredentialProviderOptions interface { - GetWebIdentityCredentialProviderOptions() (func(*stscreds.WebIdentityRoleOptions), bool, error) +// WebIdentityRoleCredentialOptionsProvider is an interface for retrieving a function for setting +// the stscreds.WebIdentityRoleProvider. +type WebIdentityRoleCredentialOptionsProvider interface { + GetWebIdentityRoleCredentialOptions() (func(*stscreds.WebIdentityRoleOptions), bool, error) } -// WithWebIdentityCredentialProviderOptions wraps a function and satisfies the EC2RoleCredentialProviderOptions interface -type WithWebIdentityCredentialProviderOptions func(*stscreds.WebIdentityRoleOptions) +// WithWebIdentityRoleCredentialOptions wraps a function and satisfies the EC2RoleCredentialOptionsProvider interface +type WithWebIdentityRoleCredentialOptions func(*stscreds.WebIdentityRoleOptions) -// GetWebIdentityCredentialProviderOptions returns the wrapped function -func (w WithWebIdentityCredentialProviderOptions) GetWebIdentityCredentialProviderOptions() (func(*stscreds.WebIdentityRoleOptions), bool, error) { +// GetWebIdentityRoleCredentialOptions returns the wrapped function +func (w WithWebIdentityRoleCredentialOptions) GetWebIdentityRoleCredentialOptions() (func(*stscreds.WebIdentityRoleOptions), bool, error) { return w, true, nil } -// GetWebIdentityCredentialProviderOptions searches the slice of configs and returns the first function found -func GetWebIdentityCredentialProviderOptions(configs Configs) (f func(*stscreds.WebIdentityRoleOptions), found bool, err error) { +// getWebIdentityCredentialProviderOptions searches the slice of configs and returns the first function found +func getWebIdentityCredentialProviderOptions(configs configs) (f func(*stscreds.WebIdentityRoleOptions), found bool, err error) { for _, config := range configs { - if p, ok := config.(WebIdentityCredentialProviderOptions); ok { - f, found, err = p.GetWebIdentityCredentialProviderOptions() + if p, ok := config.(WebIdentityRoleCredentialOptionsProvider); ok { + f, found, err = p.GetWebIdentityRoleCredentialOptions() if err != nil { return nil, false, err } @@ -417,25 +377,25 @@ func GetWebIdentityCredentialProviderOptions(configs Configs) (f func(*stscreds. return f, found, err } -// AssumeRoleCredentialProviderOptions is an interface for retrieving a function for setting -// the stscreds.AssumeRoleProviderOptions. -type AssumeRoleCredentialProviderOptions interface { - GetAssumeRoleCredentialProviderOptions() (func(*stscreds.AssumeRoleOptions), bool, error) +// AssumeRoleCredentialOptionsProvider is an interface for retrieving a function for setting +// the stscreds.AssumeRoleOptions. +type AssumeRoleCredentialOptionsProvider interface { + GetAssumeRoleCredentialOptions() (func(*stscreds.AssumeRoleOptions), bool, error) } -// WithAssumeRoleCredentialProviderOptions wraps a function and satisfies the EC2RoleCredentialProviderOptions interface -type WithAssumeRoleCredentialProviderOptions func(*stscreds.AssumeRoleOptions) +// WithAssumeRoleCredentialOptions wraps a function and satisfies the EC2RoleCredentialOptionsProvider interface +type WithAssumeRoleCredentialOptions func(*stscreds.AssumeRoleOptions) -// GetAssumeRoleCredentialProviderOptions returns the wrapped function -func (w WithAssumeRoleCredentialProviderOptions) GetAssumeRoleCredentialProviderOptions() (func(*stscreds.AssumeRoleOptions), bool, error) { +// GetAssumeRoleCredentialOptions returns the wrapped function +func (w WithAssumeRoleCredentialOptions) GetAssumeRoleCredentialOptions() (func(*stscreds.AssumeRoleOptions), bool, error) { return w, true, nil } -// GetAssumeRoleCredentialProviderOptions searches the slice of configs and returns the first function found -func GetAssumeRoleCredentialProviderOptions(configs Configs) (f func(*stscreds.AssumeRoleOptions), found bool, err error) { +// getAssumeRoleCredentialProviderOptions searches the slice of configs and returns the first function found +func getAssumeRoleCredentialProviderOptions(configs configs) (f func(*stscreds.AssumeRoleOptions), found bool, err error) { for _, config := range configs { - if p, ok := config.(AssumeRoleCredentialProviderOptions); ok { - f, found, err = p.GetAssumeRoleCredentialProviderOptions() + if p, ok := config.(AssumeRoleCredentialOptionsProvider); ok { + f, found, err = p.GetAssumeRoleCredentialOptions() if err != nil { return nil, false, err } @@ -457,21 +417,26 @@ type HTTPClientProvider interface { GetHTTPClient() (HTTPClient, bool, error) } -// WithHTTPClient wraps a HTTPClient and satisfies the HTTPClientProvider interface -type WithHTTPClient struct { +// withHTTPClient wraps a HTTPClient and satisfies the HTTPClientProvider interface +type withHTTPClient struct { HTTPClient } +// WithHTTPClient wraps a HTTPClient and satisfies the HTTPClientProvider interface +func WithHTTPClient(client HTTPClient) HTTPClientProvider { + return withHTTPClient{HTTPClient: client} +} + // GetHTTPClient returns the wrapped HTTPClient. Returns an error if the wrapped client is nil. -func (w WithHTTPClient) GetHTTPClient() (HTTPClient, bool, error) { +func (w withHTTPClient) GetHTTPClient() (HTTPClient, bool, error) { if w.HTTPClient == nil { return nil, false, fmt.Errorf("http client must not be nil") } return w.HTTPClient, true, nil } -// GetHTTPClient searches the slice of configs and returns the first HTTPClient found. -func GetHTTPClient(configs Configs) (c HTTPClient, found bool, err error) { +// getHTTPClient searches the slice of configs and returns the first HTTPClient found. +func getHTTPClient(configs configs) (c HTTPClient, found bool, err error) { for _, config := range configs { if p, ok := config.(HTTPClientProvider); ok { c, found, err = p.GetHTTPClient() @@ -499,8 +464,8 @@ func (w WithAPIOptions) GetAPIOptions() ([]func(*middleware.Stack) error, bool, return w, true, nil } -// GetAPIOptions searches the slice of configs and returns the first APIOptions found. -func GetAPIOptions(configs Configs) (o []func(*middleware.Stack) error, found bool, err error) { +// getAPIOptions searches the slice of configs and returns the first APIOptions found. +func getAPIOptions(configs configs) (o []func(*middleware.Stack) error, found bool, err error) { for _, config := range configs { if p, ok := config.(APIOptionsProvider); ok { o, found, err = p.GetAPIOptions() @@ -515,26 +480,30 @@ func GetAPIOptions(configs Configs) (o []func(*middleware.Stack) error, found bo return o, found, err } -// EndpointResolverFuncProvider is an interface for retrieving an aws.EndpointResolver from a configuration source -type EndpointResolverFuncProvider interface { +// EndpointResolverProvider is an interface for retrieving an aws.EndpointResolver from a configuration source +type EndpointResolverProvider interface { GetEndpointResolver() (aws.EndpointResolver, bool, error) } -// WithEndpointResolver wraps a aws.EndpointResolver value to satisfy the EndpointResolverFuncProvider interface -type WithEndpointResolver struct { +type withEndpointResolver struct { aws.EndpointResolver } +// WithEndpointResolver wraps a aws.EndpointResolver value to satisfy the EndpointResolverProvider interface +func WithEndpointResolver(resolver aws.EndpointResolver) EndpointResolverProvider { + return withEndpointResolver{EndpointResolver: resolver} +} + // GetEndpointResolver returns the wrapped EndpointResolver -func (w WithEndpointResolver) GetEndpointResolver() (aws.EndpointResolver, bool, error) { +func (w withEndpointResolver) GetEndpointResolver() (aws.EndpointResolver, bool, error) { return w.EndpointResolver, true, nil } -// GetEndpointResolver searches the provided config sources for a EndpointResolverFunc that can be used +// getEndpointResolver searches the provided config sources for a EndpointResolverFunc that can be used // to configure the aws.Config.EndpointResolver value. -func GetEndpointResolver(configs Configs) (f aws.EndpointResolver, found bool, err error) { +func getEndpointResolver(configs configs) (f aws.EndpointResolver, found bool, err error) { for _, c := range configs { - if p, ok := c.(EndpointResolverFuncProvider); ok { + if p, ok := c.(EndpointResolverProvider); ok { f, found, err = p.GetEndpointResolver() if err != nil { return nil, false, err diff --git a/config/provider_assert_test.go b/config/provider_assert_test.go index 0a781ef9807..f32f0ebae20 100644 --- a/config/provider_assert_test.go +++ b/config/provider_assert_test.go @@ -2,19 +2,25 @@ package config -import ( - "github.com/aws/aws-sdk-go-v2/credentials" +// APIOptionsProvider implementor assertions +var ( + _ APIOptionsProvider = WithAPIOptions(nil) +) + +// AssumeRoleCredentialOptionsProvider implementor assertions +var ( + _ AssumeRoleCredentialOptionsProvider = WithAssumeRoleCredentialOptions(nil) ) // CredentialsProviderProvider implementor assertions var ( - _ CredentialsProviderProvider = WithCredentialsProvider{credentials.NewStaticCredentialsProvider("", "", "")} + _ CredentialsProviderProvider = WithCredentialsProvider(nil) ) // CustomCABundleProvider implementor assertions var ( _ CustomCABundleProvider = &EnvConfig{} - _ CustomCABundleProvider = WithCustomCABundle([]byte{}) + _ CustomCABundleProvider = WithCustomCABundle(nil) ) // DefaultRegionProvider implementor assertions @@ -22,9 +28,24 @@ var ( _ DefaultRegionProvider = WithDefaultRegion("") ) -// MFATokenFuncProvider implementor assertions +// EC2RoleCredentialOptionsProvider implementor assertions +var ( + _ EC2RoleCredentialOptionsProvider = WithEC2RoleCredentialOptions(nil) +) + +// EndpointCredentialOptionsProvider implementor assertions +var ( + _ EndpointCredentialOptionsProvider = WithEndpointCredentialOptions(nil) +) + +// EndpointResolverProvider implementor assertions +var ( + _ EndpointResolverProvider = WithEndpointResolver(nil) +) + +// HTTPClientProvider implementor assertions var ( - _ MFATokenFuncProvider = WithMFATokenFunc(func() (string, error) { return "", nil }) + _ HTTPClientProvider = WithHTTPClient(nil) ) // RegionProvider implementor assertions @@ -32,12 +53,13 @@ var ( _ RegionProvider = &EnvConfig{} _ RegionProvider = &SharedConfig{} _ RegionProvider = WithRegion("") + _ RegionProvider = WithEC2IMDSRegion{} ) // SharedConfigFilesProvider implementor assertions var ( _ SharedConfigFilesProvider = &EnvConfig{} - _ SharedConfigFilesProvider = WithSharedConfigFiles([]string{}) + _ SharedConfigFilesProvider = WithSharedConfigFiles(nil) ) // SharedConfigProfileProvider implementor assertions @@ -45,3 +67,8 @@ var ( _ SharedConfigProfileProvider = &EnvConfig{} _ SharedConfigProfileProvider = WithSharedConfigProfile("") ) + +// WebIdentityRoleCredentialOptionsProvider implementor assertions +var ( + _ WebIdentityRoleCredentialOptionsProvider = WithWebIdentityRoleCredentialOptions(nil) +) diff --git a/config/resolve.go b/config/resolve.go index 6608d0d61a2..919eeea8772 100644 --- a/config/resolve.go +++ b/config/resolve.go @@ -9,26 +9,26 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" ) -// ResolveDefaultAWSConfig will write default configuration values into the cfg +// resolveDefaultAWSConfig will write default configuration values into the cfg // value. It will write the default values, overwriting any previous value. // // This should be used as the first resolver in the slice of resolvers when // resolving external configuration. -func ResolveDefaultAWSConfig(cfg *aws.Config, configs Configs) error { +func resolveDefaultAWSConfig(cfg *aws.Config, cfgs configs) error { *cfg = aws.Config{ Credentials: aws.AnonymousCredentials{}, } return nil } -// ResolveCustomCABundle extracts the first instance of a custom CA bundle filename +// resolveCustomCABundle extracts the first instance of a custom CA bundle filename // from the external configurations. It will update the HTTP Client's builder // to be configured with the custom CA bundle. // // Config provider used: // * CustomCABundleProvider -func ResolveCustomCABundle(cfg *aws.Config, configs Configs) error { - pemCerts, found, err := GetCustomCABundle(configs) +func resolveCustomCABundle(cfg *aws.Config, cfgs configs) error { + pemCerts, found, err := getCustomCABundle(cfgs) if err != nil { // TODO error handling, What is the best way to handle this? // capture previous errors continue. error out if all errors @@ -68,12 +68,12 @@ func ResolveCustomCABundle(cfg *aws.Config, configs Configs) error { return err } -// ResolveRegion extracts the first instance of a Region from the Configs slice. +// resolveRegion extracts the first instance of a Region from the configs slice. // // Config providers used: // * RegionProvider -func ResolveRegion(cfg *aws.Config, configs Configs) error { - v, found, err := GetRegion(configs) +func resolveRegion(cfg *aws.Config, configs configs) error { + v, found, err := getRegion(configs) if err != nil { // TODO error handling, What is the best way to handle this? // capture previous errors continue. error out if all errors @@ -87,14 +87,14 @@ func ResolveRegion(cfg *aws.Config, configs Configs) error { return nil } -// ResolveDefaultRegion extracts the first instance of a default region and sets `aws.Config.Region` to the default +// resolveDefaultRegion extracts the first instance of a default region and sets `aws.Config.Region` to the default // region if region had not been resolved from other sources. -func ResolveDefaultRegion(cfg *aws.Config, configs Configs) error { +func resolveDefaultRegion(cfg *aws.Config, configs configs) error { if len(cfg.Region) > 0 { return nil } - region, found, err := GetDefaultRegion(configs) + region, found, err := getDefaultRegion(configs) if err != nil { return err } @@ -107,10 +107,10 @@ func ResolveDefaultRegion(cfg *aws.Config, configs Configs) error { return nil } -// ResolveHTTPClient extracts the first instance of a HTTPClient and sets `aws.Config.HTTPClient` to the HTTPClient instance +// resolveHTTPClient extracts the first instance of a HTTPClient and sets `aws.Config.HTTPClient` to the HTTPClient instance // if one has not been resolved from other sources. -func ResolveHTTPClient(cfg *aws.Config, configs Configs) error { - c, found, err := GetHTTPClient(configs) +func resolveHTTPClient(cfg *aws.Config, configs configs) error { + c, found, err := getHTTPClient(configs) if err != nil { return err } @@ -122,10 +122,10 @@ func ResolveHTTPClient(cfg *aws.Config, configs Configs) error { return nil } -// ResolveAPIOptions extracts the first instance of APIOptions and sets `aws.Config.APIOptions` to the resolved API options +// resolveAPIOptions extracts the first instance of APIOptions and sets `aws.Config.APIOptions` to the resolved API options // if one has not been resolved from other sources. -func ResolveAPIOptions(cfg *aws.Config, configs Configs) error { - o, found, err := GetAPIOptions(configs) +func resolveAPIOptions(cfg *aws.Config, configs configs) error { + o, found, err := getAPIOptions(configs) if err != nil { return err } @@ -138,10 +138,10 @@ func ResolveAPIOptions(cfg *aws.Config, configs Configs) error { return nil } -// ResolveEndpointResolver extracts the first instance of a EndpointResolverFunc from the config slice +// resolveEndpointResolver extracts the first instance of a EndpointResolverFunc from the config slice // and sets the functions result on the aws.Config.EndpointResolver -func ResolveEndpointResolver(cfg *aws.Config, configs Configs) error { - endpointResolver, found, err := GetEndpointResolver(configs) +func resolveEndpointResolver(cfg *aws.Config, configs configs) error { + endpointResolver, found, err := getEndpointResolver(configs) if err != nil { return err } diff --git a/config/resolve_assume_role_test.go b/config/resolve_assume_role_test.go index ea9fecdf761..b2b5b6b2c0a 100644 --- a/config/resolve_assume_role_test.go +++ b/config/resolve_assume_role_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + "github.com/aws/aws-sdk-go-v2/credentials/stscreds" "github.com/aws/aws-sdk-go-v2/internal/awstesting" ) @@ -30,7 +31,7 @@ func TestAssumeRole(t *testing.T) { }, nil }) - config, err := LoadDefaultConfig(WithHTTPClient{client}) + config, err := LoadDefaultConfig(WithHTTPClient(client)) if err != nil { t.Fatalf("expect no error, got %v", err) } @@ -85,12 +86,14 @@ func TestAssumeRole_WithMFA(t *testing.T) { config, err := LoadDefaultConfig( WithRegion("us-east-1"), WithSharedConfigProfile("assume_role_w_mfa"), - WithMFATokenFunc(func() (string, error) { - customProviderCalled = true + WithAssumeRoleCredentialOptions(func(options *stscreds.AssumeRoleOptions) { + options.TokenProvider = func() (string, error) { + customProviderCalled = true - return "tokencode", nil + return "tokencode", nil + } }), - WithHTTPClient{client}, + WithHTTPClient(client), ) if err != nil { t.Fatalf("expect no error, got %v", err) @@ -175,7 +178,7 @@ func TestAssumeRole_ExtendedDuration(t *testing.T) { }, nil }) - config, err := LoadDefaultConfig(WithHTTPClient{client}) + config, err := LoadDefaultConfig(WithHTTPClient(client)) if err != nil { t.Fatalf("expect no error, got %v", err) } diff --git a/config/resolve_credentials.go b/config/resolve_credentials.go index 5d796b6dfee..98705d3e035 100644 --- a/config/resolve_credentials.go +++ b/config/resolve_credentials.go @@ -27,12 +27,12 @@ var ( ) -// 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. -func ResolveCredentials(cfg *aws.Config, configs Configs) error { - found, err := ResolveCredentialProvider(cfg, configs) +func resolveCredentials(cfg *aws.Config, configs configs) error { + found, err := resolveCredentialProvider(cfg, configs) if err != nil { return err } @@ -40,7 +40,7 @@ func ResolveCredentials(cfg *aws.Config, configs Configs) error { return nil } - err = ResolveCredentialChain(cfg, configs) + err = resolveCredentialChain(cfg, configs) if err != nil { return err } @@ -48,7 +48,7 @@ func ResolveCredentials(cfg *aws.Config, configs Configs) error { return nil } -// ResolveCredentialProvider extracts the first instance of Credentials from the +// resolveCredentialProvider extracts the first instance of Credentials from the // config slices. // // The resolved CredentialProvider will be wrapped in a cache to ensure the @@ -57,8 +57,8 @@ func ResolveCredentials(cfg *aws.Config, configs Configs) error { // // Config providers used: // * CredentialsProviderProvider -func ResolveCredentialProvider(cfg *aws.Config, configs Configs) (bool, error) { - credentials, found, err := GetCredentialsProvider(configs) +func resolveCredentialProvider(cfg *aws.Config, cfgs configs) (bool, error) { + credProvider, found, err := getCredentialsProvider(cfgs) if err != nil { return false, err } @@ -66,19 +66,19 @@ func ResolveCredentialProvider(cfg *aws.Config, configs Configs) (bool, error) { return false, nil } - cfg.Credentials = &aws.CredentialsCache{Provider: credentials} + cfg.Credentials = &aws.CredentialsCache{Provider: credProvider} return true, nil } -// ResolveCredentialChain resolves a credential provider chain using EnvConfig +// resolveCredentialChain resolves a credential provider chain using EnvConfig // and SharedConfig if present in the slice of provided configs. // // The resolved CredentialProvider will be wrapped in a cache to ensure the // credentials are only refreshed when needed. This also protects the // credential provider to be used concurrently. -func ResolveCredentialChain(cfg *aws.Config, configs Configs) (err error) { - _, sharedProfileSet, err := GetSharedConfigProfile(configs) +func resolveCredentialChain(cfg *aws.Config, configs configs) (err error) { + _, sharedProfileSet, err := getSharedConfigProfile(configs) if err != nil { return err } @@ -105,7 +105,7 @@ func ResolveCredentialChain(cfg *aws.Config, configs Configs) (err error) { return nil } -func resolveCredsFromProfile(cfg *aws.Config, envConfig *EnvConfig, sharedConfig *SharedConfig, configs Configs) (err error) { +func resolveCredsFromProfile(cfg *aws.Config, envConfig *EnvConfig, sharedConfig *SharedConfig, configs configs) (err error) { switch { case sharedConfig.Source != nil: @@ -155,10 +155,10 @@ func ecsContainerURI(path string) string { return fmt.Sprintf("%s%s", ecsContainerEndpoint, path) } -func processCredentials(cfg *aws.Config, sharedConfig *SharedConfig, configs Configs) error { +func processCredentials(cfg *aws.Config, sharedConfig *SharedConfig, configs configs) error { var opts []func(*processcreds.Options) - options, found, err := GetProcessCredentialOptions(configs) + options, found, err := getProcessCredentialOptions(configs) if err != nil { return err } @@ -171,7 +171,7 @@ func processCredentials(cfg *aws.Config, sharedConfig *SharedConfig, configs Con return nil } -func resolveLocalHTTPCredProvider(cfg *aws.Config, endpointURL, authToken string, configs Configs) error { +func resolveLocalHTTPCredProvider(cfg *aws.Config, endpointURL, authToken string, configs configs) error { var resolveErr error parsed, err := url.Parse(endpointURL) @@ -195,7 +195,7 @@ func resolveLocalHTTPCredProvider(cfg *aws.Config, endpointURL, authToken string return resolveHTTPCredProvider(cfg, endpointURL, authToken, configs) } -func resolveHTTPCredProvider(cfg *aws.Config, url, authToken string, configs Configs) error { +func resolveHTTPCredProvider(cfg *aws.Config, url, authToken string, configs configs) error { optFns := []func(*endpointcreds.Options){ func(options *endpointcreds.Options) { options.ExpiryWindow = 5 * time.Minute @@ -207,7 +207,7 @@ func resolveHTTPCredProvider(cfg *aws.Config, url, authToken string, configs Con }, } - optFn, found, err := GetEndpointCredentialProviderOptions(configs) + optFn, found, err := getEndpointCredentialProviderOptions(configs) if err != nil { return err } @@ -222,7 +222,7 @@ func resolveHTTPCredProvider(cfg *aws.Config, url, authToken string, configs Con return nil } -func resolveCredsFromSource(cfg *aws.Config, envConfig *EnvConfig, sharedCfg *SharedConfig, configs Configs) (err error) { +func resolveCredsFromSource(cfg *aws.Config, envConfig *EnvConfig, sharedCfg *SharedConfig, configs configs) (err error) { switch sharedCfg.CredentialSource { case credSourceEc2Metadata: return resolveEC2RoleCredentials(cfg, configs) @@ -243,10 +243,10 @@ func resolveCredsFromSource(cfg *aws.Config, envConfig *EnvConfig, sharedCfg *Sh return nil } -func resolveEC2RoleCredentials(cfg *aws.Config, configs Configs) error { +func resolveEC2RoleCredentials(cfg *aws.Config, configs configs) error { optFns := make([]func(*ec2rolecreds.Options), 0, 2) - optFn, found, err := GetEC2RoleCredentialProviderOptions(configs) + optFn, found, err := getEC2RoleCredentialProviderOptions(configs) if err != nil { return err } @@ -273,15 +273,15 @@ func resolveEC2RoleCredentials(cfg *aws.Config, configs Configs) error { return nil } -func getAWSConfigSources(configs Configs) (*EnvConfig, *SharedConfig, Configs) { +func getAWSConfigSources(cfgs configs) (*EnvConfig, *SharedConfig, configs) { var ( envConfig *EnvConfig sharedConfig *SharedConfig - other Configs + other configs ) - for i := range configs { - switch c := configs[i].(type) { + for i := range cfgs { + switch c := cfgs[i].(type) { case EnvConfig: if envConfig == nil { envConfig = &c @@ -324,7 +324,7 @@ func (e AssumeRoleTokenProviderNotSetError) Error() string { return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.") } -func assumeWebIdentity(cfg *aws.Config, filepath string, roleARN, sessionName string, configs Configs) error { +func assumeWebIdentity(cfg *aws.Config, filepath string, roleARN, sessionName string, configs configs) error { if len(filepath) == 0 { return fmt.Errorf("token file path is not set") } @@ -339,7 +339,7 @@ func assumeWebIdentity(cfg *aws.Config, filepath string, roleARN, sessionName st }, } - optFn, found, err := GetWebIdentityCredentialProviderOptions(configs) + optFn, found, err := getWebIdentityCredentialProviderOptions(configs) if err != nil { return err } @@ -354,22 +354,7 @@ func assumeWebIdentity(cfg *aws.Config, filepath string, roleARN, sessionName st return nil } -func credsFromAssumeRole(cfg *aws.Config, sharedCfg *SharedConfig, configs Configs) (err error) { - var tokenFunc func() (string, error) - if len(sharedCfg.MFASerial) != 0 { - var found bool - tokenFunc, found, err = GetMFATokenFunc(configs) - if err != nil { - return err - } - - if !found { - // AssumeRole Token provider is required if doing Assume Role - // with MFA. - return AssumeRoleTokenProviderNotSetError{} - } - } - +func credsFromAssumeRole(cfg *aws.Config, sharedCfg *SharedConfig, configs configs) (err error) { optFns := []func(*stscreds.AssumeRoleOptions){ func(options *stscreds.AssumeRoleOptions) { options.RoleSessionName = sharedCfg.RoleSessionName @@ -386,12 +371,11 @@ func credsFromAssumeRole(cfg *aws.Config, sharedCfg *SharedConfig, configs Confi // Assume role with MFA if len(sharedCfg.MFASerial) != 0 { options.SerialNumber = aws.String(sharedCfg.MFASerial) - options.TokenProvider = tokenFunc } }, } - optFn, found, err := GetAssumeRoleCredentialProviderOptions(configs) + optFn, found, err := getAssumeRoleCredentialProviderOptions(configs) if err != nil { return err } @@ -399,6 +383,18 @@ func credsFromAssumeRole(cfg *aws.Config, sharedCfg *SharedConfig, configs Confi optFns = append(optFns, optFn) } + { + // Synthesize options early to validate configuration errors sooner to ensure a token provider + // is present if the SerialNumber was set. + var o stscreds.AssumeRoleOptions + for _, fn := range optFns { + fn(&o) + } + if o.TokenProvider == nil && o.SerialNumber != nil { + return AssumeRoleTokenProviderNotSetError{} + } + } + cfg.Credentials = stscreds.NewAssumeRoleProvider(sts.NewFromConfig(cfg.Copy()), sharedCfg.RoleARN, optFns...) return nil diff --git a/config/resolve_credentials_test.go b/config/resolve_credentials_test.go index 93637c05f3f..377540d53ce 100644 --- a/config/resolve_credentials_test.go +++ b/config/resolve_credentials_test.go @@ -202,7 +202,7 @@ func TestSharedConfigCredentialSource(t *testing.T) { var credChain []string configSources := []Config{ - WithEndpointResolver{endpointResolver}, + WithEndpointResolver(endpointResolver), WithAPIOptions(append([]func(*middleware.Stack) error{}, func(stack *middleware.Stack) error { return stack.Initialize.Add(middleware.InitializeMiddlewareFunc("GetRoleArns", func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler, ) ( diff --git a/config/resolve_test.go b/config/resolve_test.go index 659ca658a8b..74c4db4ee50 100644 --- a/config/resolve_test.go +++ b/config/resolve_test.go @@ -13,14 +13,14 @@ import ( ) func TestResolveCustomCABundle(t *testing.T) { - configs := Configs{ + configs := configs{ WithCustomCABundle(awstesting.TLSBundleCA), } cfg := aws.Config{ HTTPClient: aws.NewBuildableHTTPClient(), } - if err := ResolveCustomCABundle(&cfg, configs); err != nil { + if err := resolveCustomCABundle(&cfg, configs); err != nil { t.Fatalf("expect no error, got %v", err) } @@ -54,14 +54,14 @@ func TestResolveCustomCABundle_ValidCA(t *testing.T) { t.Fatalf("failed to read CA file, %v", err) } - configs := Configs{ + configs := configs{ WithCustomCABundle(caPEM), } cfg := aws.Config{ HTTPClient: aws.NewBuildableHTTPClient(), } - if err := ResolveCustomCABundle(&cfg, configs); err != nil { + if err := resolveCustomCABundle(&cfg, configs); err != nil { t.Fatalf("expect no error, got %v", err) } @@ -78,20 +78,20 @@ func TestResolveCustomCABundle_ValidCA(t *testing.T) { } func TestResolveCustomCABundle_ErrorCustomClient(t *testing.T) { - configs := Configs{ + configs := configs{ WithCustomCABundle(awstesting.TLSBundleCA), } cfg := aws.Config{ HTTPClient: &http.Client{}, } - if err := ResolveCustomCABundle(&cfg, configs); err == nil { + if err := resolveCustomCABundle(&cfg, configs); err == nil { t.Fatalf("expect error, got none") } } func TestResolveRegion(t *testing.T) { - configs := Configs{ + configs := configs{ WithRegion("mock-region"), WithRegion("ignored-region"), } @@ -99,7 +99,7 @@ func TestResolveRegion(t *testing.T) { cfg := aws.Config{} cfg.Credentials = nil - if err := ResolveRegion(&cfg, configs); err != nil { + if err := resolveRegion(&cfg, configs); err != nil { t.Fatalf("expect no error, got %v", err) } @@ -109,20 +109,20 @@ func TestResolveRegion(t *testing.T) { } func TestResolveCredentialsProvider(t *testing.T) { - configs := Configs{ - WithCredentialsProvider{credentials.StaticCredentialsProvider{ + configs := configs{ + WithCredentialsProvider(credentials.StaticCredentialsProvider{ Value: aws.Credentials{ AccessKeyID: "AKID", SecretAccessKey: "SECRET", Source: "valid", }}, - }, + ), } cfg := aws.Config{} cfg.Credentials = nil - if found, err := ResolveCredentialProvider(&cfg, configs); err != nil { + if found, err := resolveCredentialProvider(&cfg, configs); err != nil { t.Fatalf("expect no error, got %v", err) } else if e, a := true, found; e != a { t.Fatalf("expected %v, got %v", e, a) @@ -154,13 +154,13 @@ func TestResolveCredentialsProvider(t *testing.T) { } func TestDefaultRegion(t *testing.T) { - configs := Configs{ + configs := configs{ WithDefaultRegion("foo-region"), } cfg := unit.Config() - err := ResolveDefaultRegion(&cfg, configs) + err := resolveDefaultRegion(&cfg, configs) if err != nil { t.Fatalf("expected no error, got %v", err) } @@ -171,7 +171,7 @@ func TestDefaultRegion(t *testing.T) { cfg.Region = "" - err = ResolveDefaultRegion(&cfg, configs) + err = resolveDefaultRegion(&cfg, configs) if err != nil { t.Fatalf("expected no error, got %v", err) } diff --git a/config/shared_config.go b/config/shared_config.go index 54fcc63ac40..6bdc1518afe 100644 --- a/config/shared_config.go +++ b/config/shared_config.go @@ -42,9 +42,6 @@ const ( // S3 ARN Region Usage s3UseARNRegionKey = "s3_use_arn_region" - // ErrCodeSharedConfig AWS SDK Error Code for Shared Configuration Errors - ErrCodeSharedConfig = "SharedConfigErr" - // DefaultSharedConfigProfile is the default profile to be used when // loading configuration from the config files if another profile name // is not provided. @@ -139,7 +136,7 @@ func (c *SharedConfig) GetEnableEndpointDiscovery() (value, ok bool, err error) return *c.EnableEndpointDiscovery, true, nil } -// GetS3UseARNRegion retions if the S3 service should allow ARNs to direct the region +// GetS3UseARNRegion returns if the S3 service should allow ARNs to direct the region // the client's requests are sent to. func (c *SharedConfig) GetS3UseARNRegion() (value, ok bool, err error) { if c.S3UseARNRegion == nil { @@ -159,11 +156,11 @@ func (c SharedConfig) GetCredentialsProvider() (aws.Credentials, error) { return c.Credentials, nil } -// LoadSharedConfigIgnoreNotExist is an alias for LoadSharedConfig with the +// 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(configs Configs) (Config, error) { - cfg, err := LoadSharedConfig(configs) +func loadSharedConfigIgnoreNotExist(configs configs) (Config, error) { + cfg, err := loadSharedConfig(configs) if err != nil { if _, ok := err.(SharedConfigNotExistErrors); ok { return SharedConfig{}, nil @@ -174,8 +171,8 @@ func LoadSharedConfigIgnoreNotExist(configs Configs) (Config, error) { 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. +// 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. @@ -186,13 +183,13 @@ func LoadSharedConfigIgnoreNotExist(configs Configs) (Config, error) { // Config providers used: // * SharedConfigProfileProvider // * SharedConfigFilesProvider -func LoadSharedConfig(configs Configs) (Config, error) { +func loadSharedConfig(configs configs) (Config, error) { var profile string var files []string var ok bool var err error - profile, ok, err = GetSharedConfigProfile(configs) + profile, ok, err = getSharedConfigProfile(configs) if err != nil { return nil, err } @@ -200,7 +197,7 @@ func LoadSharedConfig(configs Configs) (Config, error) { profile = defaultSharedConfigProfile } - files, ok, err = GetSharedConfigFiles(configs) + files, ok, err = getSharedConfigFiles(configs) if err != nil { return nil, err } @@ -485,7 +482,7 @@ type SharedConfigLoadError struct { Err error } -// Unwrap retunrs the underlying error that caused the failure. +// Unwrap returns the underlying error that caused the failure. func (e SharedConfigLoadError) Unwrap() error { return e.Err } diff --git a/config/shared_config_test.go b/config/shared_config_test.go index 8f135e4bcd6..ab8e112026e 100644 --- a/config/shared_config_test.go +++ b/config/shared_config_test.go @@ -424,86 +424,86 @@ func TestLoadSharedConfig(t *testing.T) { }() cases := []struct { - Configs Configs + Configs configs Files []string Profile string - LoadFn func(Configs) (Config, error) + LoadFn func(configs) (Config, error) Expect SharedConfig Err string }{ { - Configs: Configs{ + Configs: configs{ WithSharedConfigProfile("alt_profile_name"), }, Files: []string{ filepath.Join("testdata", "shared_config"), }, - LoadFn: LoadSharedConfig, + LoadFn: loadSharedConfig, Expect: SharedConfig{ Profile: "alt_profile_name", Region: "alt_profile_name_region", }, }, { - Configs: Configs{ + Configs: configs{ WithSharedConfigFiles([]string{ filepath.Join("testdata", "shared_config"), }), }, Profile: "alt_profile_name", - LoadFn: LoadSharedConfig, + LoadFn: loadSharedConfig, Expect: SharedConfig{ Profile: "alt_profile_name", Region: "alt_profile_name_region", }, }, { - Configs: Configs{ + Configs: configs{ WithSharedConfigProfile("default"), }, Files: []string{ filepath.Join("file_not_exist"), }, - LoadFn: LoadSharedConfig, + LoadFn: loadSharedConfig, Err: "failed to open shared config file, file_not_exist", }, { - Configs: Configs{ + Configs: configs{ WithSharedConfigProfile("profile_not_exist"), }, Files: []string{ filepath.Join("testdata", "shared_config"), }, - LoadFn: LoadSharedConfig, + LoadFn: loadSharedConfig, Err: "failed to get shared config profile, profile_not_exist", }, { - Configs: Configs{ + Configs: configs{ WithSharedConfigProfile("default"), }, Files: []string{ filepath.Join("file_not_exist"), }, - LoadFn: LoadSharedConfigIgnoreNotExist, + LoadFn: loadSharedConfigIgnoreNotExist, }, { - Configs: Configs{ + Configs: configs{ WithSharedConfigProfile("assume_role_invalid_source_profile"), }, Files: []string{ testConfigOtherFilename, testConfigFilename, }, - LoadFn: LoadSharedConfig, + LoadFn: loadSharedConfig, Err: "failed to get shared config profile", }, { - Configs: Configs{ + Configs: configs{ WithSharedConfigProfile("assume_role_invalid_source_profile"), }, Files: []string{ testConfigOtherFilename, testConfigFilename, }, - LoadFn: LoadSharedConfigIgnoreNotExist, + LoadFn: loadSharedConfigIgnoreNotExist, Err: "failed to get shared config profile", }, } diff --git a/doc.go b/doc.go index 5ff491bfaf2..48063e3da15 100644 --- a/doc.go +++ b/doc.go @@ -7,56 +7,52 @@ // Getting started // // The best way to get started working with the SDK is to use `go get` to add the -// SDK to your Go Workspace manually. +// SDK and desired service clients to your Go dependencies explicitly. // // go get github.com/aws/aws-sdk-go-v2 -// -// You could also use [Dep] to add the SDK to your application's dependencies. -// Using [Dep] will simplify your update story and help your application keep -// pinned to specific version of the SDK -// -// dep ensure --add github.com/aws/aws-sdk-go-v2 +// go get github.com/aws/aws-sdk-go-v2/config +// go get github.com/aws/aws-sdk-go-v2/service/dynamodb // // Hello AWS // // This example shows how you can use the v2 SDK to make an API request using the // SDK's Amazon DynamoDB client. // -// package main -// -// import ( -// "context" -// "fmt" -// "log" -// -// "github.com/aws/aws-sdk-go-v2/aws" -// "github.com/aws/aws-sdk-go-v2/config" -// "github.com/aws/aws-sdk-go-v2/service/dynamodb" -// ) -// -// func main() { -// // Using the SDK's default configuration, loading additional config -// // and credentials values from the environment variables, shared -// // credentials, and shared configuration files -// cfg, err := config.LoadDefaultConfig() -// if err != nil { -// log.Fatalf("unable to load SDK config, %v", err) -// } -// -// // Set the AWS Region that the service clients should use -// cfg.Region = "us-west-2" -// -// // Using the Config value, create the DynamoDB client -// svc := dynamodb.NewFromConfig(cfg) -// -// // Send the request, and get the response or error back -// resp, err := svc.DescribeTable(&dynamodb.DescribeTableInput{ -// TableName: aws.String("myTable"), -// }) -// if err != nil { -// log.Fatalf("failed to describe table, %v", err) -// } -// -// fmt.Println("Response", resp) -// } +// package main +// +// import ( +// "context" +// "fmt" +// "log" +// +// "github.com/aws/aws-sdk-go-v2/aws" +// "github.com/aws/aws-sdk-go-v2/config" +// "github.com/aws/aws-sdk-go-v2/service/dynamodb" +// ) +// +// func main() { +// // Using the SDK's default configuration, loading additional config +// // and credentials values from the environment variables, shared +// // credentials, and shared configuration files +// cfg, err := config.LoadDefaultConfig(config.WithRegion("us-west-2")) +// if err != nil { +// log.Fatalf("unable to load SDK config, %v", err) +// } +// +// // Using the Config value, create the DynamoDB client +// svc := dynamodb.NewFromConfig(cfg) +// +// // Build the request with its input parameters +// resp, err := svc.ListTables(context.Background(), &dynamodb.ListTablesInput{ +// Limit: aws.Int32(5), +// }) +// if err != nil { +// log.Fatalf("failed to list tables, %v", err) +// } +// +// fmt.Println("Tables:") +// for _, tableName := range resp.TableNames { +// fmt.Println(aws.ToString(tableName)) +// } +// } package sdk diff --git a/service/internal/integrationtest/config.go b/service/internal/integrationtest/config.go index 66e16d4b64e..1a3d231537e 100644 --- a/service/internal/integrationtest/config.go +++ b/service/internal/integrationtest/config.go @@ -16,16 +16,12 @@ func LoadConfigWithDefaultRegion(defaultRegion string) (cfg aws.Config, err erro var opts []config.Config if strings.EqualFold(os.Getenv("AWS_DEBUG_REQUEST"), "true") { - opts = append(opts, config.WithHTTPClient{ - HTTPClient: smithyhttp.WrapLogClient( - logger{}, aws.NewBuildableHTTPClient(), false), - }) + opts = append(opts, config.WithHTTPClient(smithyhttp.WrapLogClient( + logger{}, aws.NewBuildableHTTPClient(), false))) } else if strings.EqualFold(os.Getenv("AWS_DEBUG_REQUEST_BODY"), "true") { - opts = append(opts, config.WithHTTPClient{ - HTTPClient: smithyhttp.WrapLogClient( - logger{}, aws.NewBuildableHTTPClient(), true), - }) + opts = append(opts, config.WithHTTPClient(smithyhttp.WrapLogClient( + logger{}, aws.NewBuildableHTTPClient(), true))) } cfg, err = config.LoadDefaultConfig(opts...) diff --git a/service/internal/integrationtest/go.mod b/service/internal/integrationtest/go.mod index fa216277f00..57757fcf6b3 100644 --- a/service/internal/integrationtest/go.mod +++ b/service/internal/integrationtest/go.mod @@ -85,7 +85,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/wafregional v0.26.0 github.com/aws/aws-sdk-go-v2/service/wafv2 v0.26.0 github.com/aws/aws-sdk-go-v2/service/workspaces v0.26.0 - github.com/awslabs/smithy-go v0.1.1 + github.com/awslabs/smithy-go v0.1.2-0.20201012175301-b4d8737f29d1 ) go 1.15 diff --git a/service/internal/integrationtest/go.sum b/service/internal/integrationtest/go.sum index d7d483eeff8..f941895374a 100644 --- a/service/internal/integrationtest/go.sum +++ b/service/internal/integrationtest/go.sum @@ -4,6 +4,8 @@ github.com/awslabs/smithy-go v0.1.0 h1:yltioxA96yA1Fv+fE+5FFXnbFgw3ngpeEV++TUUkt github.com/awslabs/smithy-go v0.1.0/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= github.com/awslabs/smithy-go v0.1.1 h1:v1hUSAYf3w2ClKr58C+AtwoyPVoBjWyWT8thf7/VRtU= github.com/awslabs/smithy-go v0.1.1/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= +github.com/awslabs/smithy-go v0.1.2-0.20201012175301-b4d8737f29d1 h1:5eAoxqWUc2VMuT3ob/pUYCLliBYEk3dccw6P/reTuRY= +github.com/awslabs/smithy-go v0.1.2-0.20201012175301-b4d8737f29d1/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= diff --git a/service/s3/go.sum b/service/s3/go.sum index dc351771daf..8e9d6217b05 100644 --- a/service/s3/go.sum +++ b/service/s3/go.sum @@ -1,3 +1,4 @@ +github.com/awslabs/smithy-go v0.0.0-20200930175536-2cd7f70a8c2f/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= github.com/awslabs/smithy-go v0.1.0 h1:yltioxA96yA1Fv+fE+5FFXnbFgw3ngpeEV++TUUktiM= github.com/awslabs/smithy-go v0.1.0/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= github.com/awslabs/smithy-go v0.1.2-0.20201012175301-b4d8737f29d1 h1:5eAoxqWUc2VMuT3ob/pUYCLliBYEk3dccw6P/reTuRY= diff --git a/service/s3/internal/configtesting/go.sum b/service/s3/internal/configtesting/go.sum index dc351771daf..402a4581695 100644 --- a/service/s3/internal/configtesting/go.sum +++ b/service/s3/internal/configtesting/go.sum @@ -1,5 +1,8 @@ +github.com/awslabs/smithy-go v0.0.0-20200930175536-2cd7f70a8c2f/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= +github.com/awslabs/smithy-go v0.0.0-20201009221937-21015eb9ec4b/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= github.com/awslabs/smithy-go v0.1.0 h1:yltioxA96yA1Fv+fE+5FFXnbFgw3ngpeEV++TUUktiM= github.com/awslabs/smithy-go v0.1.0/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= +github.com/awslabs/smithy-go v0.1.1/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= github.com/awslabs/smithy-go v0.1.2-0.20201012175301-b4d8737f29d1 h1:5eAoxqWUc2VMuT3ob/pUYCLliBYEk3dccw6P/reTuRY= github.com/awslabs/smithy-go v0.1.2-0.20201012175301-b4d8737f29d1/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/service/s3control/go.sum b/service/s3control/go.sum index 03ae053aa4b..7be7f695b04 100644 --- a/service/s3control/go.sum +++ b/service/s3control/go.sum @@ -1,3 +1,5 @@ +github.com/awslabs/smithy-go v0.0.0-20200930175536-2cd7f70a8c2f/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= +github.com/awslabs/smithy-go v0.1.0/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= github.com/awslabs/smithy-go v0.1.2-0.20201012175301-b4d8737f29d1 h1:5eAoxqWUc2VMuT3ob/pUYCLliBYEk3dccw6P/reTuRY= github.com/awslabs/smithy-go v0.1.2-0.20201012175301-b4d8737f29d1/go.mod h1:hPOQwnmBLHsUphH13tVSjQhTAFma0/0XoZGbBcOuABI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=