Merge pull request #21815 from hashicorp/v-aws-sdk-go-v1.20.4

deps: github.com/aws/aws-sdk-go@v1.20.4
This commit is contained in:
Brian Flad 2019-06-20 18:19:49 -04:00 committed by GitHub
commit 5d05349fb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 3162 additions and 1713 deletions

2
go.mod
View File

@ -16,7 +16,7 @@ require (
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da // indirect
github.com/armon/go-radix v1.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect
github.com/aws/aws-sdk-go v1.19.18 github.com/aws/aws-sdk-go v1.20.4
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
github.com/blang/semver v3.5.1+incompatible github.com/blang/semver v3.5.1+incompatible
github.com/boltdb/bolt v1.3.1 // indirect github.com/boltdb/bolt v1.3.1 // indirect

4
go.sum
View File

@ -57,8 +57,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
github.com/aws/aws-sdk-go v1.16.36 h1:POeH34ZME++pr7GBGh+ZO6Y5kOwSMQpqp5BGUgooJ6k= github.com/aws/aws-sdk-go v1.16.36 h1:POeH34ZME++pr7GBGh+ZO6Y5kOwSMQpqp5BGUgooJ6k=
github.com/aws/aws-sdk-go v1.16.36/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.16.36/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.19.18 h1:Hb3+b9HCqrOrbAtFstUWg7H5TQ+/EcklJtE8VShVs8o= github.com/aws/aws-sdk-go v1.20.4 h1:czX3oqFyqz/AELrK/tneNuyZgNIrWnyqP+iQXsQ32E0=
github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.20.4/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=

View File

@ -138,8 +138,27 @@ type RequestFailure interface {
RequestID() string RequestID() string
} }
// NewRequestFailure returns a new request error wrapper for the given Error // NewRequestFailure returns a wrapped error with additional information for
// provided. // request status code, and service requestID.
//
// Should be used to wrap all request which involve service requests. Even if
// the request failed without a service response, but had an HTTP status code
// that may be meaningful.
func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure { func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure {
return newRequestError(err, statusCode, reqID) return newRequestError(err, statusCode, reqID)
} }
// UnmarshalError provides the interface for the SDK failing to unmarshal data.
type UnmarshalError interface {
awsError
Bytes() []byte
}
// NewUnmarshalError returns an initialized UnmarshalError error wrapper adding
// the bytes that fail to unmarshal to the error.
func NewUnmarshalError(err error, msg string, bytes []byte) UnmarshalError {
return &unmarshalError{
awsError: New("UnmarshalError", msg, err),
bytes: bytes,
}
}

View File

@ -1,6 +1,9 @@
package awserr package awserr
import "fmt" import (
"encoding/hex"
"fmt"
)
// SprintError returns a string of the formatted error code. // SprintError returns a string of the formatted error code.
// //
@ -119,6 +122,7 @@ type requestError struct {
awsError awsError
statusCode int statusCode int
requestID string requestID string
bytes []byte
} }
// newRequestError returns a wrapped error with additional information for // newRequestError returns a wrapped error with additional information for
@ -170,6 +174,29 @@ func (r requestError) OrigErrs() []error {
return []error{r.OrigErr()} return []error{r.OrigErr()}
} }
type unmarshalError struct {
awsError
bytes []byte
}
// Error returns the string representation of the error.
// Satisfies the error interface.
func (e unmarshalError) Error() string {
extra := hex.Dump(e.bytes)
return SprintError(e.Code(), e.Message(), extra, e.OrigErr())
}
// String returns the string representation of the error.
// Alias for Error to satisfy the stringer interface.
func (e unmarshalError) String() string {
return e.Error()
}
// Bytes returns the bytes that failed to unmarshal.
func (e unmarshalError) Bytes() []byte {
return e.bytes
}
// An error list that satisfies the golang interface // An error list that satisfies the golang interface
type errorList []error type errorList []error

View File

@ -50,9 +50,10 @@ package credentials
import ( import (
"fmt" "fmt"
"github.com/aws/aws-sdk-go/aws/awserr"
"sync" "sync"
"time" "time"
"github.com/aws/aws-sdk-go/aws/awserr"
) )
// AnonymousCredentials is an empty Credential object that can be used as // AnonymousCredentials is an empty Credential object that can be used as

View File

@ -11,6 +11,7 @@ import (
"github.com/aws/aws-sdk-go/aws/client" "github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/sdkuri" "github.com/aws/aws-sdk-go/internal/sdkuri"
) )
@ -142,7 +143,8 @@ func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) {
} }
if err := s.Err(); err != nil { if err := s.Err(); err != nil {
return nil, awserr.New("SerializationError", "failed to read EC2 instance role from metadata service", err) return nil, awserr.New(request.ErrCodeSerialization,
"failed to read EC2 instance role from metadata service", err)
} }
return credsList, nil return credsList, nil
@ -164,7 +166,7 @@ func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCred
respCreds := ec2RoleCredRespBody{} respCreds := ec2RoleCredRespBody{}
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil { if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil {
return ec2RoleCredRespBody{}, return ec2RoleCredRespBody{},
awserr.New("SerializationError", awserr.New(request.ErrCodeSerialization,
fmt.Sprintf("failed to decode %s EC2 instance role credentials", credsName), fmt.Sprintf("failed to decode %s EC2 instance role credentials", credsName),
err) err)
} }

View File

@ -39,6 +39,7 @@ import (
"github.com/aws/aws-sdk-go/aws/client/metadata" "github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
) )
// ProviderName is the name of the credentials provider. // ProviderName is the name of the credentials provider.
@ -174,7 +175,7 @@ func unmarshalHandler(r *request.Request) {
out := r.Data.(*getCredentialsOutput) out := r.Data.(*getCredentialsOutput)
if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil { if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil {
r.Error = awserr.New("SerializationError", r.Error = awserr.New(request.ErrCodeSerialization,
"failed to decode endpoint credentials", "failed to decode endpoint credentials",
err, err,
) )
@ -185,11 +186,15 @@ func unmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
var errOut errorOutput var errOut errorOutput
if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&errOut); err != nil { err := jsonutil.UnmarshalJSONError(&errOut, r.HTTPResponse.Body)
r.Error = awserr.New("SerializationError", if err != nil {
"failed to decode endpoint credentials", r.Error = awserr.NewRequestFailure(
err, awserr.New(request.ErrCodeSerialization,
"failed to decode error message", err),
r.HTTPResponse.StatusCode,
r.RequestID,
) )
return
} }
// Response body format is not consistent between metadata endpoints. // Response body format is not consistent between metadata endpoints.

View File

@ -258,7 +258,6 @@ func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*
// Retrieve generates a new set of temporary credentials using STS. // Retrieve generates a new set of temporary credentials using STS.
func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) { func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
// Apply defaults where parameters are not set. // Apply defaults where parameters are not set.
if p.RoleSessionName == "" { if p.RoleSessionName == "" {
// Try to work out a role name that will hopefully end up unique. // Try to work out a role name that will hopefully end up unique.

View File

@ -96,7 +96,7 @@ func getMetricException(err awserr.Error) metricException {
switch code { switch code {
case "RequestError", case "RequestError",
"SerializationError", request.ErrCodeSerialization,
request.CanceledErrorCode: request.CanceledErrorCode:
return sdkException{ return sdkException{
requestException{exception: code, message: msg}, requestException{exception: code, message: msg},

View File

@ -82,7 +82,7 @@ func (c *EC2Metadata) GetInstanceIdentityDocument() (EC2InstanceIdentityDocument
doc := EC2InstanceIdentityDocument{} doc := EC2InstanceIdentityDocument{}
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&doc); err != nil { if err := json.NewDecoder(strings.NewReader(resp)).Decode(&doc); err != nil {
return EC2InstanceIdentityDocument{}, return EC2InstanceIdentityDocument{},
awserr.New("SerializationError", awserr.New(request.ErrCodeSerialization,
"failed to decode EC2 instance identity document", err) "failed to decode EC2 instance identity document", err)
} }
@ -101,7 +101,7 @@ func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) {
info := EC2IAMInfo{} info := EC2IAMInfo{}
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&info); err != nil { if err := json.NewDecoder(strings.NewReader(resp)).Decode(&info); err != nil {
return EC2IAMInfo{}, return EC2IAMInfo{},
awserr.New("SerializationError", awserr.New(request.ErrCodeSerialization,
"failed to decode EC2 IAM info", err) "failed to decode EC2 IAM info", err)
} }

View File

@ -123,7 +123,7 @@ func unmarshalHandler(r *request.Request) {
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
b := &bytes.Buffer{} b := &bytes.Buffer{}
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err) r.Error = awserr.New(request.ErrCodeSerialization, "unable to unmarshal EC2 metadata respose", err)
return return
} }
@ -136,7 +136,7 @@ func unmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
b := &bytes.Buffer{} b := &bytes.Buffer{}
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil { if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err) r.Error = awserr.New(request.ErrCodeSerialization, "unable to unmarshal EC2 metadata error respose", err)
return return
} }

View File

@ -416,6 +416,24 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"appmesh": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
},
},
"appstream2": service{ "appstream2": service{
Defaults: endpoint{ Defaults: endpoint{
Protocols: []string{"https"}, Protocols: []string{"https"},
@ -515,6 +533,17 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"backup": service{
Endpoints: endpoints{
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
"batch": service{ "batch": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -584,6 +613,7 @@ var awsPartition = partition{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
@ -662,6 +692,7 @@ var awsPartition = partition{
}, },
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -726,6 +757,7 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
@ -789,6 +821,7 @@ var awsPartition = partition{
"codedeploy": service{ "codedeploy": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -937,7 +970,10 @@ var awsPartition = partition{
"comprehendmedical": service{ "comprehendmedical": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
@ -971,6 +1007,19 @@ var awsPartition = partition{
"us-east-1": endpoint{}, "us-east-1": endpoint{},
}, },
}, },
"data.mediastore": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-west-2": endpoint{},
},
},
"datapipeline": service{ "datapipeline": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -1070,6 +1119,24 @@ var awsPartition = partition{
"docdb": service{ "docdb": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{
Hostname: "rds.ap-northeast-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "ap-northeast-1",
},
},
"ap-northeast-2": endpoint{
Hostname: "rds.ap-northeast-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "ap-northeast-2",
},
},
"ap-southeast-2": endpoint{
Hostname: "rds.ap-southeast-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "ap-southeast-2",
},
},
"eu-central-1": endpoint{ "eu-central-1": endpoint{
Hostname: "rds.eu-central-1.amazonaws.com", Hostname: "rds.eu-central-1.amazonaws.com",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -1133,6 +1200,12 @@ var awsPartition = partition{
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"ca-central-1-fips": endpoint{
Hostname: "dynamodb-fips.ca-central-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "ca-central-1",
},
},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{}, "eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
@ -1147,9 +1220,33 @@ var awsPartition = partition{
}, },
"sa-east-1": endpoint{}, "sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-1-fips": endpoint{
Hostname: "dynamodb-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-east-2-fips": endpoint{
Hostname: "dynamodb-fips.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-2",
},
},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
"us-west-1-fips": endpoint{
Hostname: "dynamodb-fips.us-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-1",
},
},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
"us-west-2-fips": endpoint{
Hostname: "dynamodb-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
}, },
}, },
"ec2": service{ "ec2": service{
@ -1240,6 +1337,7 @@ var awsPartition = partition{
"elasticbeanstalk": service{ "elasticbeanstalk": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -1263,11 +1361,14 @@ var awsPartition = partition{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
@ -1343,6 +1444,8 @@ var awsPartition = partition{
"email": service{ "email": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-south-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
@ -1419,6 +1522,7 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
@ -1435,11 +1539,15 @@ var awsPartition = partition{
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
@ -1500,6 +1608,7 @@ var awsPartition = partition{
"glue": service{ "glue": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-east-1": endpoint{},
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
@ -1530,6 +1639,13 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"groundstation": service{
Endpoints: endpoints{
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
"guardduty": service{ "guardduty": service{
IsRegionalized: boxedTrue, IsRegionalized: boxedTrue,
Defaults: endpoint{ Defaults: endpoint{
@ -1543,6 +1659,7 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
@ -1596,6 +1713,7 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
@ -1633,6 +1751,35 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"iotthingsgraph": service{
Defaults: endpoint{
CredentialScope: credentialScope{
Service: "iotthingsgraph",
},
},
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-west-2": endpoint{},
},
},
"kafka": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
"kinesis": service{ "kinesis": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -1658,8 +1805,13 @@ var awsPartition = partition{
"kinesisanalytics": service{ "kinesisanalytics": service{
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
@ -1734,11 +1886,16 @@ var awsPartition = partition{
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
@ -1873,6 +2030,7 @@ var awsPartition = partition{
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
@ -1959,6 +2117,7 @@ var awsPartition = partition{
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
@ -1987,6 +2146,12 @@ var awsPartition = partition{
Region: "ap-northeast-1", Region: "ap-northeast-1",
}, },
}, },
"ap-northeast-2": endpoint{
Hostname: "rds.ap-northeast-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "ap-northeast-2",
},
},
"ap-south-1": endpoint{ "ap-south-1": endpoint{
Hostname: "rds.ap-south-1.amazonaws.com", Hostname: "rds.ap-south-1.amazonaws.com",
CredentialScope: credentialScope{ CredentialScope: credentialScope{
@ -2126,6 +2291,37 @@ var awsPartition = partition{
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
"projects.iot1click": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
"ram": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
},
},
"rds": service{ "rds": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -2178,10 +2374,14 @@ var awsPartition = partition{
"ap-northeast-1": endpoint{}, "ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{}, "ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
}, },
}, },
@ -2281,9 +2481,33 @@ var awsPartition = partition{
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-1-fips": endpoint{
Hostname: "runtime-fips.sagemaker.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-east-2-fips": endpoint{
Hostname: "runtime-fips.sagemaker.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-2",
},
},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
"us-west-1-fips": endpoint{
Hostname: "runtime-fips.sagemaker.us-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-1",
},
},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
"us-west-2-fips": endpoint{
Hostname: "runtime-fips.sagemaker.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
}, },
}, },
"s3": service{ "s3": service{
@ -2571,6 +2795,7 @@ var awsPartition = partition{
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"eu-west-2": endpoint{}, "eu-west-2": endpoint{},
"eu-west-3": endpoint{}, "eu-west-3": endpoint{},
@ -2905,6 +3130,12 @@ var awsPartition = partition{
"ap-southeast-1": endpoint{}, "ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{}, "ap-southeast-2": endpoint{},
"ca-central-1": endpoint{}, "ca-central-1": endpoint{},
"ca-central-1-fips": endpoint{
Hostname: "dynamodb-fips.ca-central-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "ca-central-1",
},
},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-north-1": endpoint{}, "eu-north-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
@ -2919,9 +3150,33 @@ var awsPartition = partition{
}, },
"sa-east-1": endpoint{}, "sa-east-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
"us-east-1-fips": endpoint{
Hostname: "dynamodb-fips.us-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-1",
},
},
"us-east-2": endpoint{}, "us-east-2": endpoint{},
"us-east-2-fips": endpoint{
Hostname: "dynamodb-fips.us-east-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-east-2",
},
},
"us-west-1": endpoint{}, "us-west-1": endpoint{},
"us-west-1-fips": endpoint{
Hostname: "dynamodb-fips.us-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-1",
},
},
"us-west-2": endpoint{}, "us-west-2": endpoint{},
"us-west-2-fips": endpoint{
Hostname: "dynamodb-fips.us-west-2.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-west-2",
},
},
}, },
}, },
"sts": service{ "sts": service{
@ -2990,7 +3245,7 @@ var awsPartition = partition{
"support": service{ "support": service{
Endpoints: endpoints{ Endpoints: endpoints{
"us-east-1": endpoint{}, "aws-global": endpoint{},
}, },
}, },
"swf": service{ "swf": service{
@ -3061,7 +3316,11 @@ var awsPartition = partition{
Protocols: []string{"https"}, Protocols: []string{"https"},
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{}, "ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{}, "eu-central-1": endpoint{},
"eu-west-1": endpoint{}, "eu-west-1": endpoint{},
"us-east-1": endpoint{}, "us-east-1": endpoint{},
@ -3463,6 +3722,13 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{},
}, },
}, },
"kms": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
"cn-northwest-1": endpoint{},
},
},
"lambda": service{ "lambda": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -3480,7 +3746,12 @@ var awscnPartition = partition{
"mediaconvert": service{ "mediaconvert": service{
Endpoints: endpoints{ Endpoints: endpoints{
"cn-northwest-1": endpoint{}, "cn-northwest-1": endpoint{
Hostname: "subscribe.mediaconvert.cn-northwest-1.amazonaws.com.cn",
CredentialScope: credentialScope{
Region: "cn-northwest-1",
},
},
}, },
}, },
"monitoring": service{ "monitoring": service{
@ -3668,6 +3939,15 @@ var awsusgovPartition = partition{
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
"acm-pca": service{
Defaults: endpoint{
Protocols: []string{"https"},
},
Endpoints: endpoints{
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{},
},
},
"api.ecr": service{ "api.ecr": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -3713,6 +3993,7 @@ var awsusgovPartition = partition{
"athena": service{ "athena": service{
Endpoints: endpoints{ Endpoints: endpoints{
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
@ -3762,9 +4043,16 @@ var awsusgovPartition = partition{
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
"codebuild": service{
Endpoints: endpoints{
"us-gov-west-1": endpoint{},
},
},
"codecommit": service{ "codecommit": service{
Endpoints: endpoints{ Endpoints: endpoints{
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
@ -3819,6 +4107,7 @@ var awsusgovPartition = partition{
"ds": service{ "ds": service{
Endpoints: endpoints{ Endpoints: endpoints{
"us-gov-east-1": endpoint{},
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
@ -3826,6 +4115,12 @@ var awsusgovPartition = partition{
Endpoints: endpoints{ Endpoints: endpoints{
"us-gov-east-1": endpoint{}, "us-gov-east-1": endpoint{},
"us-gov-east-1-fips": endpoint{
Hostname: "dynamodb.us-gov-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-east-1",
},
},
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
"us-gov-west-1-fips": endpoint{ "us-gov-west-1-fips": endpoint{
Hostname: "dynamodb.us-gov-west-1.amazonaws.com", Hostname: "dynamodb.us-gov-west-1.amazonaws.com",
@ -4048,6 +4343,19 @@ var awsusgovPartition = partition{
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
}, },
}, },
"organizations": service{
PartitionEndpoint: "aws-us-gov-global",
IsRegionalized: boxedFalse,
Endpoints: endpoints{
"aws-us-gov-global": endpoint{
Hostname: "organizations.us-gov-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-west-1",
},
},
},
},
"polly": service{ "polly": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -4137,6 +4445,28 @@ var awsusgovPartition = partition{
}, },
}, },
}, },
"secretsmanager": service{
Endpoints: endpoints{
"us-gov-west-1": endpoint{},
"us-gov-west-1-fips": endpoint{
Hostname: "secretsmanager-fips.us-gov-west-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-west-1",
},
},
},
},
"serverlessrepo": service{
Defaults: endpoint{
Protocols: []string{"https"},
},
Endpoints: endpoints{
"us-gov-west-1": endpoint{
Protocols: []string{"https"},
},
},
},
"sms": service{ "sms": service{
Endpoints: endpoints{ Endpoints: endpoints{
@ -4198,6 +4528,12 @@ var awsusgovPartition = partition{
}, },
Endpoints: endpoints{ Endpoints: endpoints{
"us-gov-east-1": endpoint{}, "us-gov-east-1": endpoint{},
"us-gov-east-1-fips": endpoint{
Hostname: "dynamodb.us-gov-east-1.amazonaws.com",
CredentialScope: credentialScope{
Region: "us-gov-east-1",
},
},
"us-gov-west-1": endpoint{}, "us-gov-west-1": endpoint{},
"us-gov-west-1-fips": endpoint{ "us-gov-west-1-fips": endpoint{
Hostname: "dynamodb.us-gov-west-1.amazonaws.com", Hostname: "dynamodb.us-gov-west-1.amazonaws.com",

View File

@ -2,7 +2,7 @@ package endpoints
// Service identifiers // Service identifiers
// //
// Deprecated: Use client package's EndpointID value instead of these // Deprecated: Use client package's EndpointsID value instead of these
// ServiceIDs. These IDs are not maintained, and are out of date. // ServiceIDs. These IDs are not maintained, and are out of date.
const ( const (
A4bServiceID = "a4b" // A4b. A4bServiceID = "a4b" // A4b.

View File

@ -1,18 +1,17 @@
// +build !appengine,!plan9
package request package request
import ( import (
"net" "strings"
"os"
"syscall"
) )
func isErrConnectionReset(err error) bool { func isErrConnectionReset(err error) bool {
if opErr, ok := err.(*net.OpError); ok { if strings.Contains(err.Error(), "read: connection reset") {
if sysErr, ok := opErr.Err.(*os.SyscallError); ok { return false
return sysErr.Err == syscall.ECONNRESET
} }
if strings.Contains(err.Error(), "connection reset") ||
strings.Contains(err.Error(), "broken pipe") {
return true
} }
return false return false

View File

@ -1,11 +0,0 @@
// +build appengine plan9
package request
import (
"strings"
)
func isErrConnectionReset(err error) bool {
return strings.Contains(err.Error(), "connection reset")
}

View File

@ -59,6 +59,51 @@ func (h *Handlers) Clear() {
h.Complete.Clear() h.Complete.Clear()
} }
// IsEmpty returns if there are no handlers in any of the handlerlists.
func (h *Handlers) IsEmpty() bool {
if h.Validate.Len() != 0 {
return false
}
if h.Build.Len() != 0 {
return false
}
if h.Send.Len() != 0 {
return false
}
if h.Sign.Len() != 0 {
return false
}
if h.Unmarshal.Len() != 0 {
return false
}
if h.UnmarshalStream.Len() != 0 {
return false
}
if h.UnmarshalMeta.Len() != 0 {
return false
}
if h.UnmarshalError.Len() != 0 {
return false
}
if h.ValidateResponse.Len() != 0 {
return false
}
if h.Retry.Len() != 0 {
return false
}
if h.AfterRetry.Len() != 0 {
return false
}
if h.CompleteAttempt.Len() != 0 {
return false
}
if h.Complete.Len() != 0 {
return false
}
return true
}
// A HandlerListRunItem represents an entry in the HandlerList which // A HandlerListRunItem represents an entry in the HandlerList which
// is being run. // is being run.
type HandlerListRunItem struct { type HandlerListRunItem struct {

View File

@ -231,6 +231,10 @@ func (r *Request) WillRetry() bool {
return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries() return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries()
} }
func fmtAttemptCount(retryCount, maxRetries int) string {
return fmt.Sprintf("attempt %v/%v", retryCount, maxRetries)
}
// ParamsFilled returns if the request's parameters have been populated // ParamsFilled returns if the request's parameters have been populated
// and the parameters are valid. False is returned if no parameters are // and the parameters are valid. False is returned if no parameters are
// provided or invalid. // provided or invalid.
@ -330,16 +334,17 @@ func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, err
return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil
} }
func debugLogReqError(r *Request, stage string, retrying bool, err error) { const (
willRetry = "will retry"
notRetrying = "not retrying"
retryCount = "retry %v/%v"
)
func debugLogReqError(r *Request, stage, retryStr string, err error) {
if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) { if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) {
return return
} }
retryStr := "not retrying"
if retrying {
retryStr = "will retry"
}
r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v", r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v",
stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err)) stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err))
} }
@ -358,12 +363,12 @@ func (r *Request) Build() error {
if !r.built { if !r.built {
r.Handlers.Validate.Run(r) r.Handlers.Validate.Run(r)
if r.Error != nil { if r.Error != nil {
debugLogReqError(r, "Validate Request", false, r.Error) debugLogReqError(r, "Validate Request", notRetrying, r.Error)
return r.Error return r.Error
} }
r.Handlers.Build.Run(r) r.Handlers.Build.Run(r)
if r.Error != nil { if r.Error != nil {
debugLogReqError(r, "Build Request", false, r.Error) debugLogReqError(r, "Build Request", notRetrying, r.Error)
return r.Error return r.Error
} }
r.built = true r.built = true
@ -379,7 +384,7 @@ func (r *Request) Build() error {
func (r *Request) Sign() error { func (r *Request) Sign() error {
r.Build() r.Build()
if r.Error != nil { if r.Error != nil {
debugLogReqError(r, "Build Request", false, r.Error) debugLogReqError(r, "Build Request", notRetrying, r.Error)
return r.Error return r.Error
} }
@ -473,7 +478,7 @@ func (r *Request) Send() error {
r.AttemptTime = time.Now() r.AttemptTime = time.Now()
if err := r.Sign(); err != nil { if err := r.Sign(); err != nil {
debugLogReqError(r, "Sign Request", false, err) debugLogReqError(r, "Sign Request", notRetrying, err)
return err return err
} }
@ -520,7 +525,9 @@ func (r *Request) sendRequest() (sendErr error) {
r.Retryable = nil r.Retryable = nil
r.Handlers.Send.Run(r) r.Handlers.Send.Run(r)
if r.Error != nil { if r.Error != nil {
debugLogReqError(r, "Send Request", r.WillRetry(), r.Error) debugLogReqError(r, "Send Request",
fmtAttemptCount(r.RetryCount, r.MaxRetries()),
r.Error)
return r.Error return r.Error
} }
@ -528,13 +535,17 @@ func (r *Request) sendRequest() (sendErr error) {
r.Handlers.ValidateResponse.Run(r) r.Handlers.ValidateResponse.Run(r)
if r.Error != nil { if r.Error != nil {
r.Handlers.UnmarshalError.Run(r) r.Handlers.UnmarshalError.Run(r)
debugLogReqError(r, "Validate Response", r.WillRetry(), r.Error) debugLogReqError(r, "Validate Response",
fmtAttemptCount(r.RetryCount, r.MaxRetries()),
r.Error)
return r.Error return r.Error
} }
r.Handlers.Unmarshal.Run(r) r.Handlers.Unmarshal.Run(r)
if r.Error != nil { if r.Error != nil {
debugLogReqError(r, "Unmarshal Response", r.WillRetry(), r.Error) debugLogReqError(r, "Unmarshal Response",
fmtAttemptCount(r.RetryCount, r.MaxRetries()),
r.Error)
return r.Error return r.Error
} }
@ -565,8 +576,8 @@ type temporary interface {
Temporary() bool Temporary() bool
} }
func shouldRetryCancel(err error) bool { func shouldRetryCancel(origErr error) bool {
switch err := err.(type) { switch err := origErr.(type) {
case awserr.Error: case awserr.Error:
if err.Code() == CanceledErrorCode { if err.Code() == CanceledErrorCode {
return false return false
@ -585,10 +596,10 @@ func shouldRetryCancel(err error) bool {
case temporary: case temporary:
// If the error is temporary, we want to allow continuation of the // If the error is temporary, we want to allow continuation of the
// retry process // retry process
return err.Temporary() return err.Temporary() || isErrConnectionReset(origErr)
case nil: case nil:
// `awserr.Error.OrigErr()` can be nil, meaning there was an error but // `awserr.Error.OrigErr()` can be nil, meaning there was an error but
// because we don't know the cause, it is marked as retriable. See // because we don't know the cause, it is marked as retryable. See
// TestRequest4xxUnretryable for an example. // TestRequest4xxUnretryable for an example.
return true return true
default: default:

View File

@ -0,0 +1,203 @@
package session
import (
"fmt"
"os"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/processcreds"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/shareddefaults"
)
// valid credential source values
const (
credSourceEc2Metadata = "Ec2InstanceMetadata"
credSourceEnvironment = "Environment"
credSourceECSContainer = "EcsContainer"
)
func resolveCredentials(cfg *aws.Config,
envCfg envConfig, sharedCfg sharedConfig,
handlers request.Handlers,
sessOpts Options,
) (*credentials.Credentials, error) {
// Credentials from Assume Role with specific credentials source.
if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.CredentialSource) > 0 {
return resolveCredsFromSource(cfg, envCfg, sharedCfg, handlers, sessOpts)
}
// Credentials from environment variables
if len(envCfg.Creds.AccessKeyID) > 0 {
return credentials.NewStaticCredentialsFromCreds(envCfg.Creds), nil
}
// Fallback to the "default" credential resolution chain.
return resolveCredsFromProfile(cfg, envCfg, sharedCfg, handlers, sessOpts)
}
func resolveCredsFromProfile(cfg *aws.Config,
envCfg envConfig, sharedCfg sharedConfig,
handlers request.Handlers,
sessOpts Options,
) (*credentials.Credentials, error) {
if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil {
// Assume IAM role with credentials source from a different profile.
cred, err := resolveCredsFromProfile(cfg, envCfg, *sharedCfg.AssumeRoleSource, handlers, sessOpts)
if err != nil {
return nil, err
}
cfgCp := *cfg
cfgCp.Credentials = cred
return credsFromAssumeRole(cfgCp, handlers, sharedCfg, sessOpts)
} else if len(sharedCfg.Creds.AccessKeyID) > 0 {
// Static Credentials from Shared Config/Credentials file.
return credentials.NewStaticCredentialsFromCreds(
sharedCfg.Creds,
), nil
} else if len(sharedCfg.CredentialProcess) > 0 {
// Credential Process credentials from Shared Config/Credentials file.
return processcreds.NewCredentials(
sharedCfg.CredentialProcess,
), nil
} else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.CredentialSource) > 0 {
// Assume IAM Role with specific credential source.
return resolveCredsFromSource(cfg, envCfg, sharedCfg, handlers, sessOpts)
}
// Fallback to default credentials provider, include mock errors
// for the credential chain so user can identify why credentials
// failed to be retrieved.
return credentials.NewCredentials(&credentials.ChainProvider{
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
Providers: []credentials.Provider{
&credProviderError{
Err: awserr.New("EnvAccessKeyNotFound",
"failed to find credentials in the environment.", nil),
},
&credProviderError{
Err: awserr.New("SharedCredsLoad",
fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil),
},
defaults.RemoteCredProvider(*cfg, handlers),
},
}), nil
}
func resolveCredsFromSource(cfg *aws.Config,
envCfg envConfig, sharedCfg sharedConfig,
handlers request.Handlers,
sessOpts Options,
) (*credentials.Credentials, error) {
// if both credential_source and source_profile have been set, return an
// error as this is undefined behavior. Only one can be used at a time
// within a profile.
if len(sharedCfg.AssumeRole.SourceProfile) > 0 {
return nil, ErrSharedConfigSourceCollision
}
cfgCp := *cfg
switch sharedCfg.AssumeRole.CredentialSource {
case credSourceEc2Metadata:
p := defaults.RemoteCredProvider(cfgCp, handlers)
cfgCp.Credentials = credentials.NewCredentials(p)
case credSourceEnvironment:
cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds(envCfg.Creds)
case credSourceECSContainer:
if len(os.Getenv(shareddefaults.ECSCredsProviderEnvVar)) == 0 {
return nil, ErrSharedConfigECSContainerEnvVarEmpty
}
p := defaults.RemoteCredProvider(cfgCp, handlers)
cfgCp.Credentials = credentials.NewCredentials(p)
default:
return nil, ErrSharedConfigInvalidCredSource
}
return credsFromAssumeRole(cfgCp, handlers, sharedCfg, sessOpts)
}
func credsFromAssumeRole(cfg aws.Config,
handlers request.Handlers,
sharedCfg sharedConfig,
sessOpts Options,
) (*credentials.Credentials, error) {
if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
// AssumeRole Token provider is required if doing Assume Role
// with MFA.
return nil, AssumeRoleTokenProviderNotSetError{}
}
return stscreds.NewCredentials(
&Session{
Config: &cfg,
Handlers: handlers.Copy(),
},
sharedCfg.AssumeRole.RoleARN,
func(opt *stscreds.AssumeRoleProvider) {
opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName
opt.Duration = sessOpts.AssumeRoleDuration
// Assume role with external ID
if len(sharedCfg.AssumeRole.ExternalID) > 0 {
opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID)
}
// Assume role with MFA
if len(sharedCfg.AssumeRole.MFASerial) > 0 {
opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial)
opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
}
},
), nil
}
// AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the
// MFAToken option is not set when shared config is configured load assume a
// role with an MFA token.
type AssumeRoleTokenProviderNotSetError struct{}
// Code is the short id of the error.
func (e AssumeRoleTokenProviderNotSetError) Code() string {
return "AssumeRoleTokenProviderNotSetError"
}
// Message is the description of the error
func (e AssumeRoleTokenProviderNotSetError) Message() string {
return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.")
}
// OrigErr is the underlying error that caused the failure.
func (e AssumeRoleTokenProviderNotSetError) OrigErr() error {
return nil
}
// Error satisfies the error interface.
func (e AssumeRoleTokenProviderNotSetError) Error() string {
return awserr.SprintError(e.Code(), e.Message(), "", nil)
}
type credProviderError struct {
Err error
}
var emptyCreds = credentials.Value{}
func (c credProviderError) Retrieve() (credentials.Value, error) {
return credentials.Value{}, c.Err
}
func (c credProviderError) IsExpired() bool {
return true
}

View File

@ -3,24 +3,21 @@ package session
import ( import (
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
"time"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/client" "github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/corehandlers" "github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/credentials/processcreds"
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/csm" "github.com/aws/aws-sdk-go/aws/csm"
"github.com/aws/aws-sdk-go/aws/defaults" "github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/shareddefaults"
) )
const ( const (
@ -210,6 +207,12 @@ type Options struct {
// the config enables assume role wit MFA via the mfa_serial field. // the config enables assume role wit MFA via the mfa_serial field.
AssumeRoleTokenProvider func() (string, error) AssumeRoleTokenProvider func() (string, error)
// When the SDK's shared config is configured to assume a role this option
// may be provided to set the expiry duration of the STS credentials.
// Defaults to 15 minutes if not set as documented in the
// stscreds.AssumeRoleProvider.
AssumeRoleDuration time.Duration
// Reader for a custom Credentials Authority (CA) bundle in PEM format that // Reader for a custom Credentials Authority (CA) bundle in PEM format that
// the SDK will use instead of the default system's root CA bundle. Use this // the SDK will use instead of the default system's root CA bundle. Use this
// only if you want to replace the CA bundle the SDK uses for TLS requests. // only if you want to replace the CA bundle the SDK uses for TLS requests.
@ -224,6 +227,12 @@ type Options struct {
// to also enable this feature. CustomCABundle session option field has priority // to also enable this feature. CustomCABundle session option field has priority
// over the AWS_CA_BUNDLE environment variable, and will be used if both are set. // over the AWS_CA_BUNDLE environment variable, and will be used if both are set.
CustomCABundle io.Reader CustomCABundle io.Reader
// The handlers that the session and all API clients will be created with.
// This must be a complete set of handlers. Use the defaults.Handlers()
// function to initialize this value before changing the handlers to be
// used by the SDK.
Handlers request.Handlers
} }
// NewSessionWithOptions returns a new Session created from SDK defaults, config files, // NewSessionWithOptions returns a new Session created from SDK defaults, config files,
@ -344,7 +353,11 @@ func enableCSM(handlers *request.Handlers, clientID string, port string, logger
func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) { func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) {
cfg := defaults.Config() cfg := defaults.Config()
handlers := defaults.Handlers()
handlers := opts.Handlers
if handlers.IsEmpty() {
handlers = defaults.Handlers()
}
// Get a merged version of the user provided config to determine if // Get a merged version of the user provided config to determine if
// credentials were. // credentials were.
@ -443,7 +456,11 @@ func loadCertPool(r io.Reader) (*x509.CertPool, error) {
return p, nil return p, nil
} }
func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers, sessOpts Options) error { func mergeConfigSrcs(cfg, userCfg *aws.Config,
envCfg envConfig, sharedCfg sharedConfig,
handlers request.Handlers,
sessOpts Options,
) error {
// Merge in user provided configuration // Merge in user provided configuration
cfg.MergeIn(userCfg) cfg.MergeIn(userCfg)
@ -464,164 +481,19 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg share
} }
} }
// Configure credentials if not already set // Configure credentials if not already set by the user when creating the
// Session.
if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil { if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
creds, err := resolveCredentials(cfg, envCfg, sharedCfg, handlers, sessOpts)
// inspect the profile to see if a credential source has been specified. if err != nil {
if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.CredentialSource) > 0 { return err
// if both credential_source and source_profile have been set, return an error
// as this is undefined behavior.
if len(sharedCfg.AssumeRole.SourceProfile) > 0 {
return ErrSharedConfigSourceCollision
} }
// valid credential source values
const (
credSourceEc2Metadata = "Ec2InstanceMetadata"
credSourceEnvironment = "Environment"
credSourceECSContainer = "EcsContainer"
)
switch sharedCfg.AssumeRole.CredentialSource {
case credSourceEc2Metadata:
cfgCp := *cfg
p := defaults.RemoteCredProvider(cfgCp, handlers)
cfgCp.Credentials = credentials.NewCredentials(p)
if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
// AssumeRole Token provider is required if doing Assume Role
// with MFA.
return AssumeRoleTokenProviderNotSetError{}
}
cfg.Credentials = assumeRoleCredentials(cfgCp, handlers, sharedCfg, sessOpts)
case credSourceEnvironment:
cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
envCfg.Creds,
)
case credSourceECSContainer:
if len(os.Getenv(shareddefaults.ECSCredsProviderEnvVar)) == 0 {
return ErrSharedConfigECSContainerEnvVarEmpty
}
cfgCp := *cfg
p := defaults.RemoteCredProvider(cfgCp, handlers)
creds := credentials.NewCredentials(p)
cfg.Credentials = creds cfg.Credentials = creds
default:
return ErrSharedConfigInvalidCredSource
} }
return nil return nil
} }
if len(envCfg.Creds.AccessKeyID) > 0 {
cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
envCfg.Creds,
)
} else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil {
cfgCp := *cfg
cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds(
sharedCfg.AssumeRoleSource.Creds,
)
if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
// AssumeRole Token provider is required if doing Assume Role
// with MFA.
return AssumeRoleTokenProviderNotSetError{}
}
cfg.Credentials = assumeRoleCredentials(cfgCp, handlers, sharedCfg, sessOpts)
} else if len(sharedCfg.Creds.AccessKeyID) > 0 {
cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
sharedCfg.Creds,
)
} else if len(sharedCfg.CredentialProcess) > 0 {
cfg.Credentials = processcreds.NewCredentials(
sharedCfg.CredentialProcess,
)
} else {
// Fallback to default credentials provider, include mock errors
// for the credential chain so user can identify why credentials
// failed to be retrieved.
cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
Providers: []credentials.Provider{
&credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)},
&credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)},
defaults.RemoteCredProvider(*cfg, handlers),
},
})
}
}
return nil
}
func assumeRoleCredentials(cfg aws.Config, handlers request.Handlers, sharedCfg sharedConfig, sessOpts Options) *credentials.Credentials {
return stscreds.NewCredentials(
&Session{
Config: &cfg,
Handlers: handlers.Copy(),
},
sharedCfg.AssumeRole.RoleARN,
func(opt *stscreds.AssumeRoleProvider) {
opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName
// Assume role with external ID
if len(sharedCfg.AssumeRole.ExternalID) > 0 {
opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID)
}
// Assume role with MFA
if len(sharedCfg.AssumeRole.MFASerial) > 0 {
opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial)
opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
}
},
)
}
// AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the
// MFAToken option is not set when shared config is configured load assume a
// role with an MFA token.
type AssumeRoleTokenProviderNotSetError struct{}
// Code is the short id of the error.
func (e AssumeRoleTokenProviderNotSetError) Code() string {
return "AssumeRoleTokenProviderNotSetError"
}
// Message is the description of the error
func (e AssumeRoleTokenProviderNotSetError) Message() string {
return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.")
}
// OrigErr is the underlying error that caused the failure.
func (e AssumeRoleTokenProviderNotSetError) OrigErr() error {
return nil
}
// Error satisfies the error interface.
func (e AssumeRoleTokenProviderNotSetError) Error() string {
return awserr.SprintError(e.Code(), e.Message(), "", nil)
}
type credProviderError struct {
Err error
}
var emptyCreds = credentials.Value{}
func (c credProviderError) Retrieve() (credentials.Value, error) {
return credentials.Value{}, c.Err
}
func (c credProviderError) IsExpired() bool {
return true
}
func initHandlers(s *Session) { func initHandlers(s *Session) {
// Add the Validate parameter handler if it is not disabled. // Add the Validate parameter handler if it is not disabled.
s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler) s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)

View File

@ -156,11 +156,21 @@ func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedC
if err != nil { if err != nil {
return err return err
} }
// Chain if profile depends of other profiles
if len(assumeRoleSrc.AssumeRole.SourceProfile) > 0 {
err := assumeRoleSrc.setAssumeRoleSource(cfg.AssumeRole.SourceProfile, files)
if err != nil {
return err
}
}
} }
if len(assumeRoleSrc.Creds.AccessKeyID) == 0 { if cfg.AssumeRole.SourceProfile == origProfile || len(assumeRoleSrc.AssumeRole.SourceProfile) == 0 {
if len(assumeRoleSrc.AssumeRole.CredentialSource) == 0 && len(assumeRoleSrc.Creds.AccessKeyID) == 0 {
return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN} return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN}
} }
}
cfg.AssumeRoleSource = &assumeRoleSrc cfg.AssumeRoleSource = &assumeRoleSrc

View File

@ -7,13 +7,18 @@ import (
"github.com/aws/aws-sdk-go/internal/sdkio" "github.com/aws/aws-sdk-go/internal/sdkio"
) )
// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Should // ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Allows the
// only be used with an io.Reader that is also an io.Seeker. Doing so may // SDK to accept an io.Reader that is not also an io.Seeker for unsigned
// cause request signature errors, or request body's not sent for GET, HEAD // streaming payload API operations.
// and DELETE HTTP methods.
// //
// Deprecated: Should only be used with io.ReadSeeker. If using for // A ReadSeekCloser wrapping an nonseekable io.Reader used in an API
// S3 PutObject to stream content use s3manager.Uploader instead. // operation's input will prevent that operation being retried in the case of
// network errors, and cause operation requests to fail if the operation
// requires payload signing.
//
// Note: If using With S3 PutObject to stream an object upload The SDK's S3
// Upload manager (s3manager.Uploader) provides support for streaming with the
// ability to retry network errors.
func ReadSeekCloser(r io.Reader) ReaderSeekerCloser { func ReadSeekCloser(r io.Reader) ReaderSeekerCloser {
return ReaderSeekerCloser{r} return ReaderSeekerCloser{r}
} }
@ -43,7 +48,8 @@ func IsReaderSeekable(r io.Reader) bool {
// Read reads from the reader up to size of p. The number of bytes read, and // Read reads from the reader up to size of p. The number of bytes read, and
// error if it occurred will be returned. // error if it occurred will be returned.
// //
// If the reader is not an io.Reader zero bytes read, and nil error will be returned. // If the reader is not an io.Reader zero bytes read, and nil error will be
// returned.
// //
// Performs the same functionality as io.Reader Read // Performs the same functionality as io.Reader Read
func (r ReaderSeekerCloser) Read(p []byte) (int, error) { func (r ReaderSeekerCloser) Read(p []byte) (int, error) {

View File

@ -5,4 +5,4 @@ package aws
const SDKName = "aws-sdk-go" const SDKName = "aws-sdk-go"
// SDKVersion is the version of this SDK // SDKVersion is the version of this SDK
const SDKVersion = "1.19.18" const SDKVersion = "1.20.4"

View File

@ -304,7 +304,9 @@ loop:
stmt := newCommentStatement(tok) stmt := newCommentStatement(tok)
stack.Push(stmt) stack.Push(stmt)
default: default:
return nil, NewParseError(fmt.Sprintf("invalid state with ASTKind %v and TokenType %v", k, tok)) return nil, NewParseError(
fmt.Sprintf("invalid state with ASTKind %v and TokenType %v",
k, tok.Type()))
} }
if len(tokens) > 0 { if len(tokens) > 0 {
@ -314,7 +316,7 @@ loop:
// this occurs when a statement has not been completed // this occurs when a statement has not been completed
if stack.top > 1 { if stack.top > 1 {
return nil, NewParseError(fmt.Sprintf("incomplete expression: %v", stack.container)) return nil, NewParseError(fmt.Sprintf("incomplete ini expression"))
} }
// returns a sublist which excludes the start symbol // returns a sublist which excludes the start symbol

View File

@ -1,6 +1,7 @@
package jsonutil package jsonutil
import ( import (
"bytes"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -9,9 +10,30 @@ import (
"time" "time"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/private/protocol" "github.com/aws/aws-sdk-go/private/protocol"
) )
// UnmarshalJSONError unmarshal's the reader's JSON document into the passed in
// type. The value to unmarshal the json document into must be a pointer to the
// type.
func UnmarshalJSONError(v interface{}, stream io.Reader) error {
var errBuf bytes.Buffer
body := io.TeeReader(stream, &errBuf)
err := json.NewDecoder(body).Decode(v)
if err != nil {
msg := "failed decoding error message"
if err == io.EOF {
msg = "error message missing"
err = nil
}
return awserr.NewUnmarshalError(err, msg, errBuf.Bytes())
}
return nil
}
// UnmarshalJSON reads a stream and unmarshals the results in object v. // UnmarshalJSON reads a stream and unmarshals the results in object v.
func UnmarshalJSON(v interface{}, stream io.Reader) error { func UnmarshalJSON(v interface{}, stream io.Reader) error {
var out interface{} var out interface{}

View File

@ -6,8 +6,6 @@ package jsonrpc
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go //go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go
import ( import (
"encoding/json"
"io"
"strings" "strings"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
@ -37,7 +35,7 @@ func Build(req *request.Request) {
if req.ParamsFilled() { if req.ParamsFilled() {
buf, err = jsonutil.BuildJSON(req.Params) buf, err = jsonutil.BuildJSON(req.Params)
if err != nil { if err != nil {
req.Error = awserr.New("SerializationError", "failed encoding JSON RPC request", err) req.Error = awserr.New(request.ErrCodeSerialization, "failed encoding JSON RPC request", err)
return return
} }
} else { } else {
@ -68,7 +66,7 @@ func Unmarshal(req *request.Request) {
err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body) err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body)
if err != nil { if err != nil {
req.Error = awserr.NewRequestFailure( req.Error = awserr.NewRequestFailure(
awserr.New("SerializationError", "failed decoding JSON RPC response", err), awserr.New(request.ErrCodeSerialization, "failed decoding JSON RPC response", err),
req.HTTPResponse.StatusCode, req.HTTPResponse.StatusCode,
req.RequestID, req.RequestID,
) )
@ -87,17 +85,11 @@ func UnmarshalError(req *request.Request) {
defer req.HTTPResponse.Body.Close() defer req.HTTPResponse.Body.Close()
var jsonErr jsonErrorResponse var jsonErr jsonErrorResponse
err := json.NewDecoder(req.HTTPResponse.Body).Decode(&jsonErr) err := jsonutil.UnmarshalJSONError(&jsonErr, req.HTTPResponse.Body)
if err == io.EOF { if err != nil {
req.Error = awserr.NewRequestFailure( req.Error = awserr.NewRequestFailure(
awserr.New("SerializationError", req.HTTPResponse.Status, nil), awserr.New(request.ErrCodeSerialization,
req.HTTPResponse.StatusCode, "failed to unmarshal error message", err),
req.RequestID,
)
return
} else if err != nil {
req.Error = awserr.NewRequestFailure(
awserr.New("SerializationError", "failed decoding JSON RPC error response", err),
req.HTTPResponse.StatusCode, req.HTTPResponse.StatusCode,
req.RequestID, req.RequestID,
) )

View File

@ -21,7 +21,7 @@ func Build(r *request.Request) {
"Version": {r.ClientInfo.APIVersion}, "Version": {r.ClientInfo.APIVersion},
} }
if err := queryutil.Parse(body, r.Params, false); err != nil { if err := queryutil.Parse(body, r.Params, false); err != nil {
r.Error = awserr.New("SerializationError", "failed encoding Query request", err) r.Error = awserr.New(request.ErrCodeSerialization, "failed encoding Query request", err)
return return
} }

View File

@ -24,7 +24,7 @@ func Unmarshal(r *request.Request) {
err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result") err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result")
if err != nil { if err != nil {
r.Error = awserr.NewRequestFailure( r.Error = awserr.NewRequestFailure(
awserr.New("SerializationError", "failed decoding Query response", err), awserr.New(request.ErrCodeSerialization, "failed decoding Query response", err),
r.HTTPResponse.StatusCode, r.HTTPResponse.StatusCode,
r.RequestID, r.RequestID,
) )

View File

@ -2,73 +2,68 @@ package query
import ( import (
"encoding/xml" "encoding/xml"
"io/ioutil" "fmt"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil"
) )
// UnmarshalErrorHandler is a name request handler to unmarshal request errors
var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError}
type xmlErrorResponse struct { type xmlErrorResponse struct {
XMLName xml.Name `xml:"ErrorResponse"`
Code string `xml:"Error>Code"` Code string `xml:"Error>Code"`
Message string `xml:"Error>Message"` Message string `xml:"Error>Message"`
RequestID string `xml:"RequestId"` RequestID string `xml:"RequestId"`
} }
type xmlServiceUnavailableResponse struct { type xmlResponseError struct {
XMLName xml.Name `xml:"ServiceUnavailableException"` xmlErrorResponse
} }
// UnmarshalErrorHandler is a name request handler to unmarshal request errors func (e *xmlResponseError) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError} const svcUnavailableTagName = "ServiceUnavailableException"
const errorResponseTagName = "ErrorResponse"
switch start.Name.Local {
case svcUnavailableTagName:
e.Code = svcUnavailableTagName
e.Message = "service is unavailable"
return d.Skip()
case errorResponseTagName:
return d.DecodeElement(&e.xmlErrorResponse, &start)
default:
return fmt.Errorf("unknown error response tag, %v", start)
}
}
// UnmarshalError unmarshals an error response for an AWS Query service. // UnmarshalError unmarshals an error response for an AWS Query service.
func UnmarshalError(r *request.Request) { func UnmarshalError(r *request.Request) {
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body) var respErr xmlResponseError
err := xmlutil.UnmarshalXMLError(&respErr, r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.NewRequestFailure( r.Error = awserr.NewRequestFailure(
awserr.New("SerializationError", "failed to read from query HTTP response body", err), awserr.New(request.ErrCodeSerialization,
"failed to unmarshal error message", err),
r.HTTPResponse.StatusCode, r.HTTPResponse.StatusCode,
r.RequestID, r.RequestID,
) )
return return
} }
// First check for specific error reqID := respErr.RequestID
resp := xmlErrorResponse{} if len(reqID) == 0 {
decodeErr := xml.Unmarshal(bodyBytes, &resp)
if decodeErr == nil {
reqID := resp.RequestID
if reqID == "" {
reqID = r.RequestID reqID = r.RequestID
} }
r.Error = awserr.NewRequestFailure( r.Error = awserr.NewRequestFailure(
awserr.New(resp.Code, resp.Message, nil), awserr.New(respErr.Code, respErr.Message, nil),
r.HTTPResponse.StatusCode, r.HTTPResponse.StatusCode,
reqID, reqID,
) )
return
}
// Check for unhandled error
servUnavailResp := xmlServiceUnavailableResponse{}
unavailErr := xml.Unmarshal(bodyBytes, &servUnavailResp)
if unavailErr == nil {
r.Error = awserr.NewRequestFailure(
awserr.New("ServiceUnavailableException", "service is unavailable", nil),
r.HTTPResponse.StatusCode,
r.RequestID,
)
return
}
// Failed to retrieve any error message from the response body
r.Error = awserr.NewRequestFailure(
awserr.New("SerializationError",
"failed to decode query XML error response", decodeErr),
r.HTTPResponse.StatusCode,
r.RequestID,
)
} }

View File

@ -25,6 +25,8 @@ var noEscape [256]bool
var errValueNotSet = fmt.Errorf("value not set") var errValueNotSet = fmt.Errorf("value not set")
var byteSliceType = reflect.TypeOf([]byte{})
func init() { func init() {
for i := 0; i < len(noEscape); i++ { for i := 0; i < len(noEscape); i++ {
// AWS expects every character except these to be escaped // AWS expects every character except these to be escaped
@ -94,6 +96,14 @@ func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bo
continue continue
} }
// Support the ability to customize values to be marshaled as a
// blob even though they were modeled as a string. Required for S3
// API operations like SSECustomerKey is modeled as stirng but
// required to be base64 encoded in request.
if field.Tag.Get("marshal-as") == "blob" {
m = m.Convert(byteSliceType)
}
var err error var err error
switch field.Tag.Get("location") { switch field.Tag.Get("location") {
case "headers": // header maps case "headers": // header maps
@ -137,7 +147,7 @@ func buildBody(r *request.Request, v reflect.Value) {
case string: case string:
r.SetStringBody(reader) r.SetStringBody(reader)
default: default:
r.Error = awserr.New("SerializationError", r.Error = awserr.New(request.ErrCodeSerialization,
"failed to encode REST request", "failed to encode REST request",
fmt.Errorf("unknown payload type %s", payload.Type())) fmt.Errorf("unknown payload type %s", payload.Type()))
} }
@ -152,7 +162,7 @@ func buildHeader(header *http.Header, v reflect.Value, name string, tag reflect.
if err == errValueNotSet { if err == errValueNotSet {
return nil return nil
} else if err != nil { } else if err != nil {
return awserr.New("SerializationError", "failed to encode REST request", err) return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err)
} }
name = strings.TrimSpace(name) name = strings.TrimSpace(name)
@ -170,7 +180,7 @@ func buildHeaderMap(header *http.Header, v reflect.Value, tag reflect.StructTag)
if err == errValueNotSet { if err == errValueNotSet {
continue continue
} else if err != nil { } else if err != nil {
return awserr.New("SerializationError", "failed to encode REST request", err) return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err)
} }
keyStr := strings.TrimSpace(key.String()) keyStr := strings.TrimSpace(key.String())
@ -186,7 +196,7 @@ func buildURI(u *url.URL, v reflect.Value, name string, tag reflect.StructTag) e
if err == errValueNotSet { if err == errValueNotSet {
return nil return nil
} else if err != nil { } else if err != nil {
return awserr.New("SerializationError", "failed to encode REST request", err) return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err)
} }
u.Path = strings.Replace(u.Path, "{"+name+"}", value, -1) u.Path = strings.Replace(u.Path, "{"+name+"}", value, -1)
@ -219,7 +229,7 @@ func buildQueryString(query url.Values, v reflect.Value, name string, tag reflec
if err == errValueNotSet { if err == errValueNotSet {
return nil return nil
} else if err != nil { } else if err != nil {
return awserr.New("SerializationError", "failed to encode REST request", err) return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err)
} }
query.Set(name, str) query.Set(name, str)
} }

View File

@ -57,7 +57,7 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
b, err := ioutil.ReadAll(r.HTTPResponse.Body) b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.New("SerializationError", "failed to decode REST response", err) r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
} else { } else {
payload.Set(reflect.ValueOf(b)) payload.Set(reflect.ValueOf(b))
} }
@ -65,7 +65,7 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
b, err := ioutil.ReadAll(r.HTTPResponse.Body) b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.New("SerializationError", "failed to decode REST response", err) r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
} else { } else {
str := string(b) str := string(b)
payload.Set(reflect.ValueOf(&str)) payload.Set(reflect.ValueOf(&str))
@ -77,7 +77,7 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
case "io.ReadSeeker": case "io.ReadSeeker":
b, err := ioutil.ReadAll(r.HTTPResponse.Body) b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.New("SerializationError", r.Error = awserr.New(request.ErrCodeSerialization,
"failed to read response body", err) "failed to read response body", err)
return return
} }
@ -85,7 +85,7 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
default: default:
io.Copy(ioutil.Discard, r.HTTPResponse.Body) io.Copy(ioutil.Discard, r.HTTPResponse.Body)
defer r.HTTPResponse.Body.Close() defer r.HTTPResponse.Body.Close()
r.Error = awserr.New("SerializationError", r.Error = awserr.New(request.ErrCodeSerialization,
"failed to decode REST response", "failed to decode REST response",
fmt.Errorf("unknown payload type %s", payload.Type())) fmt.Errorf("unknown payload type %s", payload.Type()))
} }
@ -115,14 +115,14 @@ func unmarshalLocationElements(r *request.Request, v reflect.Value) {
case "header": case "header":
err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name), field.Tag) err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name), field.Tag)
if err != nil { if err != nil {
r.Error = awserr.New("SerializationError", "failed to decode REST response", err) r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
break break
} }
case "headers": case "headers":
prefix := field.Tag.Get("locationName") prefix := field.Tag.Get("locationName")
err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix) err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix)
if err != nil { if err != nil {
r.Error = awserr.New("SerializationError", "failed to decode REST response", err) r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err)
break break
} }
} }

View File

@ -37,7 +37,8 @@ func Build(r *request.Request) {
err := xmlutil.BuildXML(r.Params, xml.NewEncoder(&buf)) err := xmlutil.BuildXML(r.Params, xml.NewEncoder(&buf))
if err != nil { if err != nil {
r.Error = awserr.NewRequestFailure( r.Error = awserr.NewRequestFailure(
awserr.New("SerializationError", "failed to encode rest XML request", err), awserr.New(request.ErrCodeSerialization,
"failed to encode rest XML request", err),
r.HTTPResponse.StatusCode, r.HTTPResponse.StatusCode,
r.RequestID, r.RequestID,
) )
@ -55,7 +56,8 @@ func Unmarshal(r *request.Request) {
err := xmlutil.UnmarshalXML(r.Data, decoder, "") err := xmlutil.UnmarshalXML(r.Data, decoder, "")
if err != nil { if err != nil {
r.Error = awserr.NewRequestFailure( r.Error = awserr.NewRequestFailure(
awserr.New("SerializationError", "failed to decode REST XML response", err), awserr.New(request.ErrCodeSerialization,
"failed to decode REST XML response", err),
r.HTTPResponse.StatusCode, r.HTTPResponse.StatusCode,
r.RequestID, r.RequestID,
) )

View File

@ -1,6 +1,7 @@
package xmlutil package xmlutil
import ( import (
"bytes"
"encoding/base64" "encoding/base64"
"encoding/xml" "encoding/xml"
"fmt" "fmt"
@ -10,9 +11,27 @@ import (
"strings" "strings"
"time" "time"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/private/protocol" "github.com/aws/aws-sdk-go/private/protocol"
) )
// UnmarshalXMLError unmarshals the XML error from the stream into the value
// type specified. The value must be a pointer. If the message fails to
// unmarshal, the message content will be included in the returned error as a
// awserr.UnmarshalError.
func UnmarshalXMLError(v interface{}, stream io.Reader) error {
var errBuf bytes.Buffer
body := io.TeeReader(stream, &errBuf)
err := xml.NewDecoder(body).Decode(v)
if err != nil && err != io.EOF {
return awserr.NewUnmarshalError(err,
"failed to unmarshal error message", errBuf.Bytes())
}
return nil
}
// UnmarshalXML deserializes an xml.Decoder into the container v. V // UnmarshalXML deserializes an xml.Decoder into the container v. V
// needs to match the shape of the XML expected to be decoded. // needs to match the shape of the XML expected to be decoded.
// If the shape doesn't match unmarshaling will fail. // If the shape doesn't match unmarshaling will fail.

File diff suppressed because it is too large Load Diff

View File

@ -124,8 +124,8 @@ const (
// "RequestLimitExceeded". // "RequestLimitExceeded".
// //
// Throughput exceeds the current throughput limit for your account. Please // Throughput exceeds the current throughput limit for your account. Please
// contact AWS Support at AWS Support (https://docs.aws.amazon.com/https:/aws.amazon.com/support) // contact AWS Support at AWS Support (https://aws.amazon.com/support) to request
// to request a limit increase. // a limit increase.
ErrCodeRequestLimitExceeded = "RequestLimitExceeded" ErrCodeRequestLimitExceeded = "RequestLimitExceeded"
// ErrCodeResourceInUseException for service response error code // ErrCodeResourceInUseException for service response error code
@ -165,9 +165,9 @@ const (
// ErrCodeTransactionCanceledException for service response error code // ErrCodeTransactionCanceledException for service response error code
// "TransactionCanceledException". // "TransactionCanceledException".
// //
// The entire transaction request was rejected. // The entire transaction request was canceled.
// //
// DynamoDB rejects a TransactWriteItems request under the following circumstances: // DynamoDB cancels a TransactWriteItems request under the following circumstances:
// //
// * A condition in one of the condition expressions is not met. // * A condition in one of the condition expressions is not met.
// //
@ -186,7 +186,7 @@ const (
// //
// * There is a user error, such as an invalid data format. // * There is a user error, such as an invalid data format.
// //
// DynamoDB rejects a TransactGetItems request under the following circumstances: // DynamoDB cancels a TransactGetItems request under the following circumstances:
// //
// * There is an ongoing TransactGetItems operation that conflicts with a // * There is an ongoing TransactGetItems operation that conflicts with a
// concurrent PutItem, UpdateItem, DeleteItem or TransactWriteItems request. // concurrent PutItem, UpdateItem, DeleteItem or TransactWriteItems request.
@ -199,6 +199,57 @@ const (
// completed. // completed.
// //
// * There is a user error, such as an invalid data format. // * There is a user error, such as an invalid data format.
//
// If using Java, DynamoDB lists the cancellation reasons on the CancellationReasons
// property. This property is not set for other languages. Transaction cancellation
// reasons are ordered in the order of requested items, if an item has no error
// it will have NONE code and Null message.
//
// Cancellation reason codes and possible error messages:
//
// * No Errors: Code: NONE Message: null
//
// * Conditional Check Failed: Code: ConditionalCheckFailed Message: The
// conditional request failed.
//
// * Item Collection Size Limit Exceeded: Code: ItemCollectionSizeLimitExceeded
// Message: Collection size exceeded.
//
// * Transaction Conflict: Code: TransactionConflict Message: Transaction
// is ongoing for the item.
//
// * Provisioned Throughput Exceeded: Code: ProvisionedThroughputExceeded
// Messages: The level of configured provisioned throughput for the table
// was exceeded. Consider increasing your provisioning level with the UpdateTable
// API. This Message is received when provisioned throughput is exceeded
// is on a provisioned DynamoDB table. The level of configured provisioned
// throughput for one or more global secondary indexes of the table was exceeded.
// Consider increasing your provisioning level for the under-provisioned
// global secondary indexes with the UpdateTable API. This message is returned
// when provisioned throughput is exceeded is on a provisioned GSI.
//
// * Throttling Error: Code: ThrottlingError Messages: Throughput exceeds
// the current capacity of your table or index. DynamoDB is automatically
// scaling your table or index so please try again shortly. If exceptions
// persist, check if you have a hot key: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-partition-key-design.html.
// This message is returned when writes get throttled on an On-Demand table
// as DynamoDB is automatically scaling the table. Throughput exceeds the
// current capacity for one or more global secondary indexes. DynamoDB is
// automatically scaling your index so please try again shortly. This message
// is returned when when writes get throttled on an On-Demand GSI as DynamoDB
// is automatically scaling the GSI.
//
// * Validation Error: Code: ValidationError Messages: One or more parameter
// values were invalid. The update expression attempted to update the secondary
// index key beyond allowed size limits. The update expression attempted
// to update the secondary index key to unsupported type. An operand in the
// update expression has an incorrect data type. Item size to update has
// exceeded the maximum allowed size. Number overflow. Attempting to store
// a number with magnitude larger than supported range. Type mismatch for
// attribute to update. Nesting Levels have exceeded supported limits. The
// document path provided in the update expression is invalid for update.
// The provided expression refers to an attribute that does not exist in
// the item.
ErrCodeTransactionCanceledException = "TransactionCanceledException" ErrCodeTransactionCanceledException = "TransactionCanceledException"
// ErrCodeTransactionConflictException for service response error code // ErrCodeTransactionConflictException for service response error code

File diff suppressed because it is too large Load Diff

View File

@ -60,6 +60,108 @@ func (c *IAM) WaitUntilInstanceProfileExistsWithContext(ctx aws.Context, input *
return w.WaitWithContext(ctx) return w.WaitWithContext(ctx)
} }
// WaitUntilPolicyExists uses the IAM API operation
// GetPolicy to wait for a condition to be met before returning.
// If the condition is not met within the max attempt window, an error will
// be returned.
func (c *IAM) WaitUntilPolicyExists(input *GetPolicyInput) error {
return c.WaitUntilPolicyExistsWithContext(aws.BackgroundContext(), input)
}
// WaitUntilPolicyExistsWithContext is an extended version of WaitUntilPolicyExists.
// With the support for passing in a context and options to configure the
// Waiter and the underlying request options.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *IAM) WaitUntilPolicyExistsWithContext(ctx aws.Context, input *GetPolicyInput, opts ...request.WaiterOption) error {
w := request.Waiter{
Name: "WaitUntilPolicyExists",
MaxAttempts: 20,
Delay: request.ConstantWaiterDelay(1 * time.Second),
Acceptors: []request.WaiterAcceptor{
{
State: request.SuccessWaiterState,
Matcher: request.StatusWaiterMatch,
Expected: 200,
},
{
State: request.RetryWaiterState,
Matcher: request.ErrorWaiterMatch,
Expected: "NoSuchEntity",
},
},
Logger: c.Config.Logger,
NewRequest: func(opts []request.Option) (*request.Request, error) {
var inCpy *GetPolicyInput
if input != nil {
tmp := *input
inCpy = &tmp
}
req, _ := c.GetPolicyRequest(inCpy)
req.SetContext(ctx)
req.ApplyOptions(opts...)
return req, nil
},
}
w.ApplyOptions(opts...)
return w.WaitWithContext(ctx)
}
// WaitUntilRoleExists uses the IAM API operation
// GetRole to wait for a condition to be met before returning.
// If the condition is not met within the max attempt window, an error will
// be returned.
func (c *IAM) WaitUntilRoleExists(input *GetRoleInput) error {
return c.WaitUntilRoleExistsWithContext(aws.BackgroundContext(), input)
}
// WaitUntilRoleExistsWithContext is an extended version of WaitUntilRoleExists.
// With the support for passing in a context and options to configure the
// Waiter and the underlying request options.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *IAM) WaitUntilRoleExistsWithContext(ctx aws.Context, input *GetRoleInput, opts ...request.WaiterOption) error {
w := request.Waiter{
Name: "WaitUntilRoleExists",
MaxAttempts: 20,
Delay: request.ConstantWaiterDelay(1 * time.Second),
Acceptors: []request.WaiterAcceptor{
{
State: request.SuccessWaiterState,
Matcher: request.StatusWaiterMatch,
Expected: 200,
},
{
State: request.RetryWaiterState,
Matcher: request.ErrorWaiterMatch,
Expected: "NoSuchEntity",
},
},
Logger: c.Config.Logger,
NewRequest: func(opts []request.Option) (*request.Request, error) {
var inCpy *GetRoleInput
if input != nil {
tmp := *input
inCpy = &tmp
}
req, _ := c.GetRoleRequest(inCpy)
req.SetContext(ctx)
req.ApplyOptions(opts...)
return req, nil
},
}
w.ApplyOptions(opts...)
return w.WaitWithContext(ctx)
}
// WaitUntilUserExists uses the IAM API operation // WaitUntilUserExists uses the IAM API operation
// GetUser to wait for a condition to be met before returning. // GetUser to wait for a condition to be met before returning.
// If the condition is not met within the max attempt window, an error will // If the condition is not met within the max attempt window, an error will

File diff suppressed because it is too large Load Diff

View File

@ -80,7 +80,8 @@ func buildGetBucketLocation(r *request.Request) {
out := r.Data.(*GetBucketLocationOutput) out := r.Data.(*GetBucketLocationOutput)
b, err := ioutil.ReadAll(r.HTTPResponse.Body) b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.New("SerializationError", "failed reading response body", err) r.Error = awserr.New(request.ErrCodeSerialization,
"failed reading response body", err)
return return
} }

View File

@ -17,7 +17,8 @@ func defaultInitClientFn(c *client.Client) {
// Require SSL when using SSE keys // Require SSL when using SSE keys
c.Handlers.Validate.PushBack(validateSSERequiresSSL) c.Handlers.Validate.PushBack(validateSSERequiresSSL)
c.Handlers.Build.PushBack(computeSSEKeys) c.Handlers.Build.PushBack(computeSSEKeyMD5)
c.Handlers.Build.PushBack(computeCopySourceSSEKeyMD5)
// S3 uses custom error unmarshaling logic // S3 uses custom error unmarshaling logic
c.Handlers.UnmarshalError.Clear() c.Handlers.UnmarshalError.Clear()

View File

@ -3,6 +3,7 @@ package s3
import ( import (
"crypto/md5" "crypto/md5"
"encoding/base64" "encoding/base64"
"net/http"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
@ -30,25 +31,54 @@ func validateSSERequiresSSL(r *request.Request) {
} }
} }
func computeSSEKeys(r *request.Request) { const (
headers := []string{ sseKeyHeader = "x-amz-server-side-encryption-customer-key"
"x-amz-server-side-encryption-customer-key", sseKeyMD5Header = sseKeyHeader + "-md5"
"x-amz-copy-source-server-side-encryption-customer-key", )
func computeSSEKeyMD5(r *request.Request) {
var key string
if g, ok := r.Params.(sseCustomerKeyGetter); ok {
key = g.getSSECustomerKey()
} }
for _, h := range headers { computeKeyMD5(sseKeyHeader, sseKeyMD5Header, key, r.HTTPRequest)
md5h := h + "-md5" }
if key := r.HTTPRequest.Header.Get(h); key != "" {
// Base64-encode the value
b64v := base64.StdEncoding.EncodeToString([]byte(key))
r.HTTPRequest.Header.Set(h, b64v)
// Add MD5 if it wasn't computed const (
if r.HTTPRequest.Header.Get(md5h) == "" { copySrcSSEKeyHeader = "x-amz-copy-source-server-side-encryption-customer-key"
copySrcSSEKeyMD5Header = copySrcSSEKeyHeader + "-md5"
)
func computeCopySourceSSEKeyMD5(r *request.Request) {
var key string
if g, ok := r.Params.(copySourceSSECustomerKeyGetter); ok {
key = g.getCopySourceSSECustomerKey()
}
computeKeyMD5(copySrcSSEKeyHeader, copySrcSSEKeyMD5Header, key, r.HTTPRequest)
}
func computeKeyMD5(keyHeader, keyMD5Header, key string, r *http.Request) {
if len(key) == 0 {
// Backwards compatiablity where user just set the header value instead
// of using the API parameter, or setting the header value for an
// operation without the parameters modeled.
key = r.Header.Get(keyHeader)
if len(key) == 0 {
return
}
// In backwards compatiable, the header's value is not base64 encoded,
// and needs to be encoded and updated by the SDK's customizations.
b64Key := base64.StdEncoding.EncodeToString([]byte(key))
r.Header.Set(keyHeader, b64Key)
}
// Only update Key's MD5 if not already set.
if len(r.Header.Get(keyMD5Header)) == 0 {
sum := md5.Sum([]byte(key)) sum := md5.Sum([]byte(key))
b64sum := base64.StdEncoding.EncodeToString(sum[:]) keyMD5 := base64.StdEncoding.EncodeToString(sum[:])
r.HTTPRequest.Header.Set(md5h, b64sum) r.Header.Set(keyMD5Header, keyMD5)
}
}
} }
} }

View File

@ -14,7 +14,7 @@ func copyMultipartStatusOKUnmarhsalError(r *request.Request) {
b, err := ioutil.ReadAll(r.HTTPResponse.Body) b, err := ioutil.ReadAll(r.HTTPResponse.Body)
if err != nil { if err != nil {
r.Error = awserr.NewRequestFailure( r.Error = awserr.NewRequestFailure(
awserr.New("SerializationError", "unable to read response body", err), awserr.New(request.ErrCodeSerialization, "unable to read response body", err),
r.HTTPResponse.StatusCode, r.HTTPResponse.StatusCode,
r.RequestID, r.RequestID,
) )
@ -31,7 +31,7 @@ func copyMultipartStatusOKUnmarhsalError(r *request.Request) {
unmarshalError(r) unmarshalError(r)
if err, ok := r.Error.(awserr.Error); ok && err != nil { if err, ok := r.Error.(awserr.Error); ok && err != nil {
if err.Code() == "SerializationError" { if err.Code() == request.ErrCodeSerialization {
r.Error = nil r.Error = nil
return return
} }

View File

@ -11,6 +11,7 @@ import (
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil"
) )
type xmlErrorResponse struct { type xmlErrorResponse struct {
@ -42,29 +43,34 @@ func unmarshalError(r *request.Request) {
return return
} }
var errCode, errMsg string
// Attempt to parse error from body if it is known // Attempt to parse error from body if it is known
resp := &xmlErrorResponse{} var errResp xmlErrorResponse
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp) err := xmlutil.UnmarshalXMLError(&errResp, r.HTTPResponse.Body)
if err != nil && err != io.EOF { if err == io.EOF {
errCode = "SerializationError" // Only capture the error if an unmarshal error occurs that is not EOF,
errMsg = "failed to decode S3 XML error response" // because S3 might send an error without a error message which causes
} else { // the XML unmarshal to fail with EOF.
errCode = resp.Code
errMsg = resp.Message
err = nil err = nil
} }
if err != nil {
r.Error = awserr.NewRequestFailure(
awserr.New(request.ErrCodeSerialization,
"failed to unmarshal error message", err),
r.HTTPResponse.StatusCode,
r.RequestID,
)
return
}
// Fallback to status code converted to message if still no error code // Fallback to status code converted to message if still no error code
if len(errCode) == 0 { if len(errResp.Code) == 0 {
statusText := http.StatusText(r.HTTPResponse.StatusCode) statusText := http.StatusText(r.HTTPResponse.StatusCode)
errCode = strings.Replace(statusText, " ", "", -1) errResp.Code = strings.Replace(statusText, " ", "", -1)
errMsg = statusText errResp.Message = statusText
} }
r.Error = awserr.NewRequestFailure( r.Error = awserr.NewRequestFailure(
awserr.New(errCode, errMsg, err), awserr.New(errResp.Code, errResp.Message, err),
r.HTTPResponse.StatusCode, r.HTTPResponse.StatusCode,
r.RequestID, r.RequestID,
) )

File diff suppressed because it is too large Load Diff

View File

@ -7,22 +7,14 @@
// request temporary, limited-privilege credentials for AWS Identity and Access // request temporary, limited-privilege credentials for AWS Identity and Access
// Management (IAM) users or for users that you authenticate (federated users). // Management (IAM) users or for users that you authenticate (federated users).
// This guide provides descriptions of the STS API. For more detailed information // This guide provides descriptions of the STS API. For more detailed information
// about using this service, go to Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html). // about using this service, go to Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html).
//
// As an alternative to using the API, you can use one of the AWS SDKs, which
// consist of libraries and sample code for various programming languages and
// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient
// way to create programmatic access to STS. For example, the SDKs take care
// of cryptographically signing requests, managing errors, and retrying requests
// automatically. For information about the AWS SDKs, including how to download
// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/).
// //
// For information about setting up signatures and authorization through the // For information about setting up signatures and authorization through the
// API, go to Signing AWS API Requests (http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) // API, go to Signing AWS API Requests (https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)
// in the AWS General Reference. For general information about the Query API, // in the AWS General Reference. For general information about the Query API,
// go to Making Query Requests (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html) // go to Making Query Requests (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html)
// in Using IAM. For information about using security tokens with other AWS // in Using IAM. For information about using security tokens with other AWS
// products, go to AWS Services That Work with IAM (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) // products, go to AWS Services That Work with IAM (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html)
// in the IAM User Guide. // in the IAM User Guide.
// //
// If you're new to AWS and need additional technical information about a specific // If you're new to AWS and need additional technical information about a specific
@ -31,14 +23,38 @@
// //
// Endpoints // Endpoints
// //
// The AWS Security Token Service (STS) has a default endpoint of https://sts.amazonaws.com // By default, AWS Security Token Service (STS) is available as a global service,
// that maps to the US East (N. Virginia) region. Additional regions are available // and all AWS STS requests go to a single endpoint at https://sts.amazonaws.com.
// and are activated by default. For more information, see Activating and Deactivating // Global requests map to the US East (N. Virginia) region. AWS recommends using
// AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) // Regional AWS STS endpoints instead of the global endpoint to reduce latency,
// build in redundancy, and increase session token validity. For more information,
// see Managing AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
// in the IAM User Guide. // in the IAM User Guide.
// //
// For information about STS endpoints, see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region) // Most AWS Regions are enabled for operations in all AWS services by default.
// in the AWS General Reference. // Those Regions are automatically activated for use with AWS STS. Some Regions,
// such as Asia Pacific (Hong Kong), must be manually enabled. To learn more
// about enabling and disabling AWS Regions, see Managing AWS Regions (https://docs.aws.amazon.com/general/latest/gr/rande-manage.html)
// in the AWS General Reference. When you enable these AWS Regions, they are
// automatically activated for use with AWS STS. You cannot activate the STS
// endpoint for a Region that is disabled. Tokens that are valid in all AWS
// Regions are longer than tokens that are valid in Regions that are enabled
// by default. Changing this setting might affect existing systems where you
// temporarily store tokens. For more information, see Managing Global Endpoint
// Session Tokens (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-manage-tokens)
// in the IAM User Guide.
//
// After you activate a Region for use with AWS STS, you can direct AWS STS
// API calls to that Region. AWS STS recommends that you provide both the Region
// and endpoint when you make calls to a Regional endpoint. You can provide
// the Region alone for manually enabled Regions, such as Asia Pacific (Hong
// Kong). In this case, the calls are directed to the STS Regional endpoint.
// However, if you provide the Region alone for Regions enabled by default,
// the calls are directed to the global endpoint of https://sts.amazonaws.com.
//
// To view the list of AWS STS endpoints and whether they are active by default,
// see Writing Code to Use AWS STS Regions (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#id_credentials_temp_enable-regions_writing_code)
// in the IAM User Guide.
// //
// Recording API requests // Recording API requests
// //
@ -46,8 +62,28 @@
// your AWS account and delivers log files to an Amazon S3 bucket. By using // your AWS account and delivers log files to an Amazon S3 bucket. By using
// information collected by CloudTrail, you can determine what requests were // information collected by CloudTrail, you can determine what requests were
// successfully made to STS, who made the request, when it was made, and so // successfully made to STS, who made the request, when it was made, and so
// on. To learn more about CloudTrail, including how to turn it on and find // on.
// your log files, see the AWS CloudTrail User Guide (http://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html). //
// If you activate AWS STS endpoints in Regions other than the default global
// endpoint, then you must also turn on CloudTrail logging in those Regions.
// This is necessary to record any AWS STS API calls that are made in those
// Regions. For more information, see Turning On CloudTrail in Additional Regions
// (https://docs.aws.amazon.com/awscloudtrail/latest/userguide/aggregating_logs_regions_turn_on_ct.html)
// in the AWS CloudTrail User Guide.
//
// AWS Security Token Service (STS) is a global service with a single endpoint
// at https://sts.amazonaws.com. Calls to this endpoint are logged as calls
// to a global service. However, because this endpoint is physically located
// in the US East (N. Virginia) Region, your logs list us-east-1 as the event
// Region. CloudTrail does not write these logs to the US East (Ohio) Region
// unless you choose to include global service logs in that Region. CloudTrail
// writes calls to all Regional endpoints to their respective Regions. For example,
// calls to sts.us-east-2.amazonaws.com are published to the US East (Ohio)
// Region and calls to sts.eu-central-1.amazonaws.com are published to the EU
// (Frankfurt) Region.
//
// To learn more about CloudTrail, including how to turn it on and find your
// log files, see the AWS CloudTrail User Guide (https://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html).
// //
// See https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service. // See https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service.
// //

View File

@ -67,7 +67,7 @@ const (
// STS is not activated in the requested region for the account that is being // STS is not activated in the requested region for the account that is being
// asked to generate credentials. The account administrator must use the IAM // asked to generate credentials. The account administrator must use the IAM
// console to activate STS in that region. For more information, see Activating // console to activate STS in that region. For more information, see Activating
// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) // and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
// in the IAM User Guide. // in the IAM User Guide.
ErrCodeRegionDisabledException = "RegionDisabledException" ErrCodeRegionDisabledException = "RegionDisabledException"
) )

4
vendor/modules.txt vendored
View File

@ -79,7 +79,7 @@ github.com/apparentlymart/go-textseg/textseg
github.com/armon/circbuf github.com/armon/circbuf
# github.com/armon/go-radix v1.0.0 # github.com/armon/go-radix v1.0.0
github.com/armon/go-radix github.com/armon/go-radix
# github.com/aws/aws-sdk-go v1.19.18 # github.com/aws/aws-sdk-go v1.20.4
github.com/aws/aws-sdk-go/aws github.com/aws/aws-sdk-go/aws
github.com/aws/aws-sdk-go/aws/awserr github.com/aws/aws-sdk-go/aws/awserr
github.com/aws/aws-sdk-go/service/dynamodb github.com/aws/aws-sdk-go/service/dynamodb
@ -100,6 +100,7 @@ github.com/aws/aws-sdk-go/private/protocol/eventstream
github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi github.com/aws/aws-sdk-go/private/protocol/eventstream/eventstreamapi
github.com/aws/aws-sdk-go/private/protocol/rest github.com/aws/aws-sdk-go/private/protocol/rest
github.com/aws/aws-sdk-go/private/protocol/restxml github.com/aws/aws-sdk-go/private/protocol/restxml
github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil
github.com/aws/aws-sdk-go/aws/arn github.com/aws/aws-sdk-go/aws/arn
github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds
github.com/aws/aws-sdk-go/aws/credentials/stscreds github.com/aws/aws-sdk-go/aws/credentials/stscreds
@ -113,7 +114,6 @@ github.com/aws/aws-sdk-go/internal/shareddefaults
github.com/aws/aws-sdk-go/internal/sdkrand github.com/aws/aws-sdk-go/internal/sdkrand
github.com/aws/aws-sdk-go/private/protocol/json/jsonutil github.com/aws/aws-sdk-go/private/protocol/json/jsonutil
github.com/aws/aws-sdk-go/private/protocol/query github.com/aws/aws-sdk-go/private/protocol/query
github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil
github.com/aws/aws-sdk-go/internal/sdkuri github.com/aws/aws-sdk-go/internal/sdkuri
github.com/aws/aws-sdk-go/aws/corehandlers github.com/aws/aws-sdk-go/aws/corehandlers
github.com/aws/aws-sdk-go/aws/credentials/endpointcreds github.com/aws/aws-sdk-go/aws/credentials/endpointcreds