diff --git a/builtin/credential/aws/client.go b/builtin/credential/aws/client.go index 761ddeb55acf..13bc17ba7b24 100644 --- a/builtin/credential/aws/client.go +++ b/builtin/credential/aws/client.go @@ -34,6 +34,7 @@ func (b *backend) getRawClientConfig(ctx context.Context, s logical.Storage, reg } endpoint := aws.String("") + var maxRetries int = aws.UseServiceDefaultRetries if config != nil { // Override the default endpoint with the configured endpoint. switch { @@ -47,6 +48,7 @@ func (b *backend) getRawClientConfig(ctx context.Context, s logical.Storage, reg credsConfig.AccessKey = config.AccessKey credsConfig.SecretKey = config.SecretKey + maxRetries = config.MaxRetries } credsConfig.HTTPClient = cleanhttp.DefaultClient() @@ -65,6 +67,7 @@ func (b *backend) getRawClientConfig(ctx context.Context, s logical.Storage, reg Region: aws.String(region), HTTPClient: cleanhttp.DefaultClient(), Endpoint: endpoint, + MaxRetries: aws.Int(maxRetries), }, nil } diff --git a/builtin/credential/aws/path_config_client.go b/builtin/credential/aws/path_config_client.go index 0d7532ce4b00..05e080af5b78 100644 --- a/builtin/credential/aws/path_config_client.go +++ b/builtin/credential/aws/path_config_client.go @@ -3,6 +3,7 @@ package awsauth import ( "context" + "github.com/aws/aws-sdk-go/aws" "github.com/fatih/structs" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" @@ -47,6 +48,11 @@ func pathConfigClient(b *backend) *framework.Path { Default: "", Description: "Value to require in the X-Vault-AWS-IAM-Server-ID request header", }, + "max_retries": &framework.FieldSchema{ + Type: framework.TypeInt, + Default: aws.UseServiceDefaultRetries, + Description: "Maximum number of retries for recoverable exceptions of AWS APIs", + }, }, ExistenceCheck: b.pathConfigClientExistenceCheck, @@ -220,6 +226,13 @@ func (b *backend) pathConfigClientCreateUpdate(ctx context.Context, req *logical configEntry.IAMServerIdHeaderValue = data.Get("iam_server_id_header_value").(string) } + maxRetriesInt, ok := data.GetOk("max_retries") + if ok { + configEntry.MaxRetries = maxRetriesInt.(int) + } else if req.Operation == logical.CreateOperation { + configEntry.MaxRetries = data.Get("max_retries").(int) + } + // Since this endpoint supports both create operation and update operation, // the error checks for access_key and secret_key not being set are not present. // This allows calling this endpoint multiple times to provide the values. @@ -254,6 +267,7 @@ type clientConfig struct { IAMEndpoint string `json:"iam_endpoint" structs:"iam_endpoint" mapstructure:"iam_endpoint"` STSEndpoint string `json:"sts_endpoint" structs:"sts_endpoint" mapstructure:"sts_endpoint"` IAMServerIdHeaderValue string `json:"iam_server_id_header_value" structs:"iam_server_id_header_value" mapstructure:"iam_server_id_header_value"` + MaxRetries int `json:"max_retries"` } const pathConfigClientHelpSyn = ` diff --git a/builtin/logical/aws/client.go b/builtin/logical/aws/client.go index 91309ad28aae..7787cfa679d2 100644 --- a/builtin/logical/aws/client.go +++ b/builtin/logical/aws/client.go @@ -17,6 +17,7 @@ import ( func getRootConfig(ctx context.Context, s logical.Storage, clientType string) (*aws.Config, error) { credsConfig := &awsutil.CredentialsConfig{} var endpoint string + var maxRetries int = aws.UseServiceDefaultRetries entry, err := s.Get(ctx, "config/root") if err != nil { @@ -31,6 +32,7 @@ func getRootConfig(ctx context.Context, s logical.Storage, clientType string) (* credsConfig.AccessKey = config.AccessKey credsConfig.SecretKey = config.SecretKey credsConfig.Region = config.Region + maxRetries = config.MaxRetries switch { case clientType == "iam" && config.IAMEndpoint != "": endpoint = *aws.String(config.IAMEndpoint) @@ -61,6 +63,7 @@ func getRootConfig(ctx context.Context, s logical.Storage, clientType string) (* Region: aws.String(credsConfig.Region), Endpoint: &endpoint, HTTPClient: cleanhttp.DefaultClient(), + MaxRetries: aws.Int(maxRetries), }, nil } diff --git a/builtin/logical/aws/path_config_root.go b/builtin/logical/aws/path_config_root.go index d420c1ef10f0..12d8142928ca 100644 --- a/builtin/logical/aws/path_config_root.go +++ b/builtin/logical/aws/path_config_root.go @@ -3,6 +3,7 @@ package aws import ( "context" + "github.com/aws/aws-sdk-go/aws" "github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical/framework" ) @@ -33,6 +34,11 @@ func pathConfigRoot() *framework.Path { Type: framework.TypeString, Description: "Endpoint to custom STS server URL", }, + "max_retries": &framework.FieldSchema{ + Type: framework.TypeInt, + Default: aws.UseServiceDefaultRetries, + Description: "Maximum number of retries for recoverable exceptions of AWS APIs", + }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ @@ -48,6 +54,7 @@ func pathConfigRootWrite(ctx context.Context, req *logical.Request, data *framew region := data.Get("region").(string) iamendpoint := data.Get("iam_endpoint").(string) stsendpoint := data.Get("sts_endpoint").(string) + maxretries := data.Get("max_retries").(int) entry, err := logical.StorageEntryJSON("config/root", rootConfig{ AccessKey: data.Get("access_key").(string), @@ -55,6 +62,7 @@ func pathConfigRootWrite(ctx context.Context, req *logical.Request, data *framew IAMEndpoint: iamendpoint, STSEndpoint: stsendpoint, Region: region, + MaxRetries: maxretries, }) if err != nil { return nil, err @@ -73,6 +81,7 @@ type rootConfig struct { IAMEndpoint string `json:"iam_endpoint"` STSEndpoint string `json:"sts_endpoint"` Region string `json:"region"` + MaxRetries int `json:"max_retries"` } const pathConfigRootHelpSyn = `