deps: github.com/aws/aws-sdk-go@v1.21.7
Notable changes (from Terraform AWS Provider CHANGELOG): ``` NOTES: * backend/s3: Region validation now automatically supports the new `me-south-1` Middle East (Bahrain) region. For AWS operations to work in the new region, the region must be explicitly enabled as outlined in the [previous new region announcement blog post](https://aws.amazon.com/blogs/aws/now-open-aws-asia-pacific-hong-kong-region/). When the region is not enabled, the Terraform S3 Backend will return errors during credential validation (e.g. `error validating provider credentials: error calling sts:GetCallerIdentity: InvalidClientTokenId: The security token included in the request is invalid`). * backend/s3: After this update, the AWS Go SDK will prefer credentials found via the `AWS_PROFILE` environment variable when both the `AWS_PROFILE` environment variable and the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables are statically defined. Previously the SDK would ignore the `AWS_PROFILE` environment variable, if static environment credentials were also specified. This is listed as a bug fix in the AWS Go SDK release notes. ENHANCEMENTS: * backend/s3: Add support for assuming role via web identity token via the `AWS_WEB_IDENTITY_TOKEN_FILE` and `AWS_ROLE_ARN` environment variables * backend/s3: Support automatic region validation for `me-south-1` BUG FIXES: * backend/s3: Load credentials via the `AWS_PROFILE` environment variable (if available) when `AWS_PROFILE` is defined along with `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` ``` Updated via: ``` go get github.com/aws/aws-sdk-go@v1.21.7 go mod tidy go mod vendor ``` Verification with this update: ```hcl terraform { backend "s3" { bucket = "me-south-1-testing" key = "test" region = "me-south-1" } } output "test" { value = timestamp() } ``` Outputs: ``` $ terraform apply Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: test = 2019-07-30T12:49:19Z ``` If the new region is not properly enabled for the account, errors like the below will be received: ``` $ terraform init Initializing the backend... Error: error validating provider credentials: error calling sts:GetCallerIdentity: InvalidClientTokenId: The security token included in the request is invalid. ``` To use this region before this update: ```hcl terraform { # ... potentially other configuration ... backend "s3" { # ... other configuration ... region = "me-south-1" skip_region_validation = true } } ```
This commit is contained in:
parent
8b2646c2a6
commit
acf794b07f
2
go.mod
2
go.mod
|
@ -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.20.19
|
github.com/aws/aws-sdk-go v1.21.7
|
||||||
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
4
go.sum
|
@ -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.20.19 h1:RQDLGGlcffQzAceEXGdMu+uGGPGhNu+vNG3BrUZAMPI=
|
github.com/aws/aws-sdk-go v1.21.7 h1:ml+k7szyVaq4YD+3LhqOGl9tgMTqgMbpnuUSkB6UJvQ=
|
||||||
github.com/aws/aws-sdk-go v1.20.19/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
github.com/aws/aws-sdk-go v1.21.7/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=
|
||||||
|
|
|
@ -208,7 +208,7 @@ func (e errorList) Error() string {
|
||||||
// How do we want to handle the array size being zero
|
// How do we want to handle the array size being zero
|
||||||
if size := len(e); size > 0 {
|
if size := len(e); size > 0 {
|
||||||
for i := 0; i < size; i++ {
|
for i := 0; i < size; i++ {
|
||||||
msg += fmt.Sprintf("%s", e[i].Error())
|
msg += e[i].Error()
|
||||||
// We check the next index to see if it is within the slice.
|
// We check the next index to see if it is within the slice.
|
||||||
// If it is, then we append a newline. We do this, because unit tests
|
// If it is, then we append a newline. We do this, because unit tests
|
||||||
// could be broken with the additional '\n'
|
// could be broken with the additional '\n'
|
||||||
|
|
|
@ -185,13 +185,12 @@ func ValuesAtPath(i interface{}, path string) ([]interface{}, error) {
|
||||||
// SetValueAtPath sets a value at the case insensitive lexical path inside
|
// SetValueAtPath sets a value at the case insensitive lexical path inside
|
||||||
// of a structure.
|
// of a structure.
|
||||||
func SetValueAtPath(i interface{}, path string, v interface{}) {
|
func SetValueAtPath(i interface{}, path string, v interface{}) {
|
||||||
if rvals := rValuesAtPath(i, path, true, false, v == nil); rvals != nil {
|
rvals := rValuesAtPath(i, path, true, false, v == nil)
|
||||||
for _, rval := range rvals {
|
for _, rval := range rvals {
|
||||||
if rval.Kind() == reflect.Ptr && rval.IsNil() {
|
if rval.Kind() == reflect.Ptr && rval.IsNil() {
|
||||||
continue
|
continue
|
||||||
}
|
|
||||||
setValue(rval, v)
|
|
||||||
}
|
}
|
||||||
|
setValue(rval, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,10 +67,14 @@ func logRequest(r *request.Request) {
|
||||||
if !bodySeekable {
|
if !bodySeekable {
|
||||||
r.SetReaderBody(aws.ReadSeekCloser(r.HTTPRequest.Body))
|
r.SetReaderBody(aws.ReadSeekCloser(r.HTTPRequest.Body))
|
||||||
}
|
}
|
||||||
// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
|
// Reset the request body because dumpRequest will re-wrap the
|
||||||
// Body as a NoOpCloser and will not be reset after read by the HTTP
|
// r.HTTPRequest's Body as a NoOpCloser and will not be reset after
|
||||||
// client reader.
|
// read by the HTTP client reader.
|
||||||
r.ResetBody()
|
if err := r.Error; err != nil {
|
||||||
|
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
|
||||||
|
r.ClientInfo.ServiceName, r.Operation.Name, err))
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
|
r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
|
||||||
|
|
|
@ -84,6 +84,12 @@ type Value struct {
|
||||||
ProviderName string
|
ProviderName string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasKeys returns if the credentials Value has both AccessKeyID and
|
||||||
|
// SecretAccessKey value set.
|
||||||
|
func (v Value) HasKeys() bool {
|
||||||
|
return len(v.AccessKeyID) != 0 && len(v.SecretAccessKey) != 0
|
||||||
|
}
|
||||||
|
|
||||||
// A Provider is the interface for any component which will provide credentials
|
// A Provider is the interface for any component which will provide credentials
|
||||||
// Value. A provider is required to manage its own Expired state, and what to
|
// Value. A provider is required to manage its own Expired state, and what to
|
||||||
// be expired means.
|
// be expired means.
|
||||||
|
|
97
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go
generated
vendored
Normal file
97
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go
generated
vendored
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
package stscreds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/client"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/service/sts"
|
||||||
|
"github.com/aws/aws-sdk-go/service/sts/stsiface"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ErrCodeWebIdentity will be used as an error code when constructing
|
||||||
|
// a new error to be returned during session creation or retrieval.
|
||||||
|
ErrCodeWebIdentity = "WebIdentityErr"
|
||||||
|
|
||||||
|
// WebIdentityProviderName is the web identity provider name
|
||||||
|
WebIdentityProviderName = "WebIdentityCredentials"
|
||||||
|
)
|
||||||
|
|
||||||
|
// now is used to return a time.Time object representing
|
||||||
|
// the current time. This can be used to easily test and
|
||||||
|
// compare test values.
|
||||||
|
var now = time.Now
|
||||||
|
|
||||||
|
// WebIdentityRoleProvider is used to retrieve credentials using
|
||||||
|
// an OIDC token.
|
||||||
|
type WebIdentityRoleProvider struct {
|
||||||
|
credentials.Expiry
|
||||||
|
|
||||||
|
client stsiface.STSAPI
|
||||||
|
ExpiryWindow time.Duration
|
||||||
|
|
||||||
|
tokenFilePath string
|
||||||
|
roleARN string
|
||||||
|
roleSessionName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWebIdentityCredentials will return a new set of credentials with a given
|
||||||
|
// configuration, role arn, and token file path.
|
||||||
|
func NewWebIdentityCredentials(c client.ConfigProvider, roleARN, roleSessionName, path string) *credentials.Credentials {
|
||||||
|
svc := sts.New(c)
|
||||||
|
p := NewWebIdentityRoleProvider(svc, roleARN, roleSessionName, path)
|
||||||
|
return credentials.NewCredentials(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWebIdentityRoleProvider will return a new WebIdentityRoleProvider with the
|
||||||
|
// provided stsiface.STSAPI
|
||||||
|
func NewWebIdentityRoleProvider(svc stsiface.STSAPI, roleARN, roleSessionName, path string) *WebIdentityRoleProvider {
|
||||||
|
return &WebIdentityRoleProvider{
|
||||||
|
client: svc,
|
||||||
|
tokenFilePath: path,
|
||||||
|
roleARN: roleARN,
|
||||||
|
roleSessionName: roleSessionName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve will attempt to assume a role from a token which is located at
|
||||||
|
// 'WebIdentityTokenFilePath' specified destination and if that is empty an
|
||||||
|
// error will be returned.
|
||||||
|
func (p *WebIdentityRoleProvider) Retrieve() (credentials.Value, error) {
|
||||||
|
b, err := ioutil.ReadFile(p.tokenFilePath)
|
||||||
|
if err != nil {
|
||||||
|
errMsg := fmt.Sprintf("unable to read file at %s", p.tokenFilePath)
|
||||||
|
return credentials.Value{}, awserr.New(ErrCodeWebIdentity, errMsg, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionName := p.roleSessionName
|
||||||
|
if len(sessionName) == 0 {
|
||||||
|
// session name is used to uniquely identify a session. This simply
|
||||||
|
// uses unix time in nanoseconds to uniquely identify sessions.
|
||||||
|
sessionName = strconv.FormatInt(now().UnixNano(), 10)
|
||||||
|
}
|
||||||
|
resp, err := p.client.AssumeRoleWithWebIdentity(&sts.AssumeRoleWithWebIdentityInput{
|
||||||
|
RoleArn: &p.roleARN,
|
||||||
|
RoleSessionName: &sessionName,
|
||||||
|
WebIdentityToken: aws.String(string(b)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return credentials.Value{}, awserr.New(ErrCodeWebIdentity, "failed to retrieve credentials", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
p.SetExpiration(aws.TimeValue(resp.Credentials.Expiration), p.ExpiryWindow)
|
||||||
|
|
||||||
|
value := credentials.Value{
|
||||||
|
AccessKeyID: aws.StringValue(resp.Credentials.AccessKeyId),
|
||||||
|
SecretAccessKey: aws.StringValue(resp.Credentials.SecretAccessKey),
|
||||||
|
SessionToken: aws.StringValue(resp.Credentials.SessionToken),
|
||||||
|
ProviderName: WebIdentityProviderName,
|
||||||
|
}
|
||||||
|
return value, nil
|
||||||
|
}
|
|
@ -118,7 +118,7 @@ func (rep *Reporter) sendAPICallMetric(r *request.Request) {
|
||||||
Type: aws.String("ApiCall"),
|
Type: aws.String("ApiCall"),
|
||||||
AttemptCount: aws.Int(r.RetryCount + 1),
|
AttemptCount: aws.Int(r.RetryCount + 1),
|
||||||
Region: r.Config.Region,
|
Region: r.Config.Region,
|
||||||
Latency: aws.Int(int(time.Now().Sub(r.Time) / time.Millisecond)),
|
Latency: aws.Int(int(time.Since(r.Time) / time.Millisecond)),
|
||||||
XAmzRequestID: aws.String(r.RequestID),
|
XAmzRequestID: aws.String(r.RequestID),
|
||||||
MaxRetriesExceeded: aws.Int(boolIntValue(r.RetryCount >= r.MaxRetries())),
|
MaxRetriesExceeded: aws.Int(boolIntValue(r.RetryCount >= r.MaxRetries())),
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ const (
|
||||||
EuWest1RegionID = "eu-west-1" // EU (Ireland).
|
EuWest1RegionID = "eu-west-1" // EU (Ireland).
|
||||||
EuWest2RegionID = "eu-west-2" // EU (London).
|
EuWest2RegionID = "eu-west-2" // EU (London).
|
||||||
EuWest3RegionID = "eu-west-3" // EU (Paris).
|
EuWest3RegionID = "eu-west-3" // EU (Paris).
|
||||||
|
MeSouth1RegionID = "me-south-1" // Middle East (Bahrain).
|
||||||
SaEast1RegionID = "sa-east-1" // South America (Sao Paulo).
|
SaEast1RegionID = "sa-east-1" // South America (Sao Paulo).
|
||||||
UsEast1RegionID = "us-east-1" // US East (N. Virginia).
|
UsEast1RegionID = "us-east-1" // US East (N. Virginia).
|
||||||
UsEast2RegionID = "us-east-2" // US East (Ohio).
|
UsEast2RegionID = "us-east-2" // US East (Ohio).
|
||||||
|
@ -128,6 +129,9 @@ var awsPartition = partition{
|
||||||
"eu-west-3": region{
|
"eu-west-3": region{
|
||||||
Description: "EU (Paris)",
|
Description: "EU (Paris)",
|
||||||
},
|
},
|
||||||
|
"me-south-1": region{
|
||||||
|
Description: "Middle East (Bahrain)",
|
||||||
|
},
|
||||||
"sa-east-1": region{
|
"sa-east-1": region{
|
||||||
Description: "South America (Sao Paulo)",
|
Description: "South America (Sao Paulo)",
|
||||||
},
|
},
|
||||||
|
@ -166,6 +170,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -178,6 +183,7 @@ var awsPartition = partition{
|
||||||
Protocols: []string{"https"},
|
Protocols: []string{"https"},
|
||||||
},
|
},
|
||||||
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{},
|
||||||
|
@ -270,6 +276,12 @@ var awsPartition = partition{
|
||||||
Region: "eu-west-3",
|
Region: "eu-west-3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"me-south-1": endpoint{
|
||||||
|
Hostname: "api.ecr.me-south-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "me-south-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
"sa-east-1": endpoint{
|
"sa-east-1": endpoint{
|
||||||
Hostname: "api.ecr.sa-east-1.amazonaws.com",
|
Hostname: "api.ecr.sa-east-1.amazonaws.com",
|
||||||
CredentialScope: credentialScope{
|
CredentialScope: credentialScope{
|
||||||
|
@ -381,6 +393,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -409,6 +422,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -503,6 +517,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -657,6 +672,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -748,6 +764,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -841,6 +858,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-1-fips": endpoint{
|
"us-east-1-fips": endpoint{
|
||||||
|
@ -1002,6 +1020,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1089,6 +1108,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1117,6 +1137,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1157,6 +1178,12 @@ var awsPartition = partition{
|
||||||
Region: "eu-west-1",
|
Region: "eu-west-1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"eu-west-2": endpoint{
|
||||||
|
Hostname: "rds.eu-west-2.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "eu-west-2",
|
||||||
|
},
|
||||||
|
},
|
||||||
"us-east-1": endpoint{
|
"us-east-1": endpoint{
|
||||||
Hostname: "rds.us-east-1.amazonaws.com",
|
Hostname: "rds.us-east-1.amazonaws.com",
|
||||||
CredentialScope: credentialScope{
|
CredentialScope: credentialScope{
|
||||||
|
@ -1227,8 +1254,9 @@ var awsPartition = partition{
|
||||||
Region: "us-east-1",
|
Region: "us-east-1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sa-east-1": endpoint{},
|
"me-south-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
|
"us-east-1": endpoint{},
|
||||||
"us-east-1-fips": endpoint{
|
"us-east-1-fips": endpoint{
|
||||||
Hostname: "dynamodb-fips.us-east-1.amazonaws.com",
|
Hostname: "dynamodb-fips.us-east-1.amazonaws.com",
|
||||||
CredentialScope: credentialScope{
|
CredentialScope: credentialScope{
|
||||||
|
@ -1275,6 +1303,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1308,6 +1337,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1336,11 +1366,12 @@ var awsPartition = partition{
|
||||||
Region: "us-west-1",
|
Region: "us-west-1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sa-east-1": endpoint{},
|
"me-south-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-west-1": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
"us-west-2": endpoint{},
|
"us-west-1": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"elasticbeanstalk": service{
|
"elasticbeanstalk": service{
|
||||||
|
@ -1358,6 +1389,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1401,6 +1433,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1428,6 +1461,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{
|
"us-east-1": endpoint{
|
||||||
SSLCommonName: "{service}.{region}.{dnsSuffix}",
|
SSLCommonName: "{service}.{region}.{dnsSuffix}",
|
||||||
|
@ -1514,6 +1548,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1568,8 +1603,10 @@ 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-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1609,6 +1646,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1670,6 +1708,7 @@ var awsPartition = partition{
|
||||||
Protocols: []string{"https"},
|
Protocols: []string{"https"},
|
||||||
},
|
},
|
||||||
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{},
|
||||||
|
@ -1775,6 +1814,65 @@ var awsPartition = partition{
|
||||||
"us-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"iotevents": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-southeast-2": endpoint{},
|
||||||
|
"eu-central-1": endpoint{},
|
||||||
|
"eu-west-1": endpoint{},
|
||||||
|
"us-east-1": endpoint{},
|
||||||
|
"us-east-2": endpoint{},
|
||||||
|
"us-west-2": endpoint{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ioteventsdata": service{
|
||||||
|
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"ap-northeast-1": endpoint{
|
||||||
|
Hostname: "data.iotevents.ap-northeast-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "ap-northeast-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"ap-southeast-2": endpoint{
|
||||||
|
Hostname: "data.iotevents.ap-southeast-2.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "ap-southeast-2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"eu-central-1": endpoint{
|
||||||
|
Hostname: "data.iotevents.eu-central-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "eu-central-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"eu-west-1": endpoint{
|
||||||
|
Hostname: "data.iotevents.eu-west-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "eu-west-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"us-east-1": endpoint{
|
||||||
|
Hostname: "data.iotevents.us-east-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-east-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"us-east-2": endpoint{
|
||||||
|
Hostname: "data.iotevents.us-east-2.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-east-2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"us-west-2": endpoint{
|
||||||
|
Hostname: "data.iotevents.us-west-2.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "us-west-2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"iotthingsgraph": service{
|
"iotthingsgraph": service{
|
||||||
Defaults: endpoint{
|
Defaults: endpoint{
|
||||||
CredentialScope: credentialScope{
|
CredentialScope: credentialScope{
|
||||||
|
@ -1796,6 +1894,7 @@ var awsPartition = partition{
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": 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{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
@ -1819,6 +1918,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1867,6 +1967,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1889,6 +1990,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -1951,6 +2053,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -2123,6 +2226,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -2390,6 +2494,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -2429,6 +2534,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -2440,8 +2546,11 @@ var awsPartition = partition{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-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-west-2": endpoint{},
|
"us-west-2": endpoint{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -2572,8 +2681,9 @@ var awsPartition = partition{
|
||||||
Hostname: "s3.eu-west-1.amazonaws.com",
|
Hostname: "s3.eu-west-1.amazonaws.com",
|
||||||
SignatureVersions: []string{"s3", "s3v4"},
|
SignatureVersions: []string{"s3", "s3v4"},
|
||||||
},
|
},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"s3-external-1": endpoint{
|
"s3-external-1": endpoint{
|
||||||
Hostname: "s3-external-1.amazonaws.com",
|
Hostname: "s3-external-1.amazonaws.com",
|
||||||
SignatureVersions: []string{"s3", "s3v4"},
|
SignatureVersions: []string{"s3", "s3v4"},
|
||||||
|
@ -2991,6 +3101,7 @@ var awsPartition = partition{
|
||||||
|
|
||||||
Endpoints: endpoints{
|
Endpoints: endpoints{
|
||||||
"ap-northeast-1": endpoint{},
|
"ap-northeast-1": endpoint{},
|
||||||
|
"ap-northeast-2": endpoint{},
|
||||||
"ap-south-1": endpoint{},
|
"ap-south-1": endpoint{},
|
||||||
"ap-southeast-1": endpoint{},
|
"ap-southeast-1": endpoint{},
|
||||||
"ap-southeast-2": endpoint{},
|
"ap-southeast-2": endpoint{},
|
||||||
|
@ -3023,6 +3134,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -3072,7 +3184,8 @@ var awsPartition = partition{
|
||||||
Region: "us-west-2",
|
Region: "us-west-2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sa-east-1": endpoint{},
|
"me-south-1": endpoint{},
|
||||||
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{
|
"us-east-1": endpoint{
|
||||||
SSLCommonName: "queue.{dnsSuffix}",
|
SSLCommonName: "queue.{dnsSuffix}",
|
||||||
},
|
},
|
||||||
|
@ -3096,6 +3209,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -3118,6 +3232,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -3139,6 +3254,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -3178,8 +3294,9 @@ var awsPartition = partition{
|
||||||
Region: "us-east-1",
|
Region: "us-east-1",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"sa-east-1": endpoint{},
|
"me-south-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
|
"us-east-1": endpoint{},
|
||||||
"us-east-1-fips": endpoint{
|
"us-east-1-fips": endpoint{
|
||||||
Hostname: "dynamodb-fips.us-east-1.amazonaws.com",
|
Hostname: "dynamodb-fips.us-east-1.amazonaws.com",
|
||||||
CredentialScope: credentialScope{
|
CredentialScope: credentialScope{
|
||||||
|
@ -3241,8 +3358,14 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"me-south-1": endpoint{
|
||||||
"us-east-1": endpoint{},
|
Hostname: "sts.me-south-1.amazonaws.com",
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
Region: "me-south-1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"sa-east-1": endpoint{},
|
||||||
|
"us-east-1": endpoint{},
|
||||||
"us-east-1-fips": endpoint{
|
"us-east-1-fips": endpoint{
|
||||||
Hostname: "sts-fips.us-east-1.amazonaws.com",
|
Hostname: "sts-fips.us-east-1.amazonaws.com",
|
||||||
CredentialScope: credentialScope{
|
CredentialScope: credentialScope{
|
||||||
|
@ -3299,6 +3422,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -3321,6 +3445,7 @@ var awsPartition = partition{
|
||||||
"eu-west-1": endpoint{},
|
"eu-west-1": endpoint{},
|
||||||
"eu-west-2": endpoint{},
|
"eu-west-2": endpoint{},
|
||||||
"eu-west-3": endpoint{},
|
"eu-west-3": endpoint{},
|
||||||
|
"me-south-1": endpoint{},
|
||||||
"sa-east-1": endpoint{},
|
"sa-east-1": endpoint{},
|
||||||
"us-east-1": endpoint{},
|
"us-east-1": endpoint{},
|
||||||
"us-east-2": endpoint{},
|
"us-east-2": endpoint{},
|
||||||
|
@ -3400,12 +3525,16 @@ 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-north-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-1": endpoint{},
|
||||||
|
|
|
@ -15,12 +15,15 @@ type offsetReader struct {
|
||||||
closed bool
|
closed bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader {
|
func newOffsetReader(buf io.ReadSeeker, offset int64) (*offsetReader, error) {
|
||||||
reader := &offsetReader{}
|
reader := &offsetReader{}
|
||||||
buf.Seek(offset, sdkio.SeekStart)
|
_, err := buf.Seek(offset, sdkio.SeekStart)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
reader.buf = buf
|
reader.buf = buf
|
||||||
return reader
|
return reader, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close will close the instance of the offset reader's access to
|
// Close will close the instance of the offset reader's access to
|
||||||
|
@ -54,7 +57,9 @@ func (o *offsetReader) Seek(offset int64, whence int) (int64, error) {
|
||||||
|
|
||||||
// CloseAndCopy will return a new offsetReader with a copy of the old buffer
|
// CloseAndCopy will return a new offsetReader with a copy of the old buffer
|
||||||
// and close the old buffer.
|
// and close the old buffer.
|
||||||
func (o *offsetReader) CloseAndCopy(offset int64) *offsetReader {
|
func (o *offsetReader) CloseAndCopy(offset int64) (*offsetReader, error) {
|
||||||
o.Close()
|
if err := o.Close(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
return newOffsetReader(o.buf, offset)
|
return newOffsetReader(o.buf, offset)
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,7 +264,18 @@ func (r *Request) SetStringBody(s string) {
|
||||||
// SetReaderBody will set the request's body reader.
|
// SetReaderBody will set the request's body reader.
|
||||||
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
||||||
r.Body = reader
|
r.Body = reader
|
||||||
r.BodyStart, _ = reader.Seek(0, sdkio.SeekCurrent) // Get the Bodies current offset.
|
|
||||||
|
if aws.IsReaderSeekable(reader) {
|
||||||
|
var err error
|
||||||
|
// Get the Bodies current offset so retries will start from the same
|
||||||
|
// initial position.
|
||||||
|
r.BodyStart, err = reader.Seek(0, sdkio.SeekCurrent)
|
||||||
|
if err != nil {
|
||||||
|
r.Error = awserr.New(ErrCodeSerialization,
|
||||||
|
"failed to determine start of request body", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
r.ResetBody()
|
r.ResetBody()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,9 +347,7 @@ func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, err
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
willRetry = "will retry"
|
|
||||||
notRetrying = "not retrying"
|
notRetrying = "not retrying"
|
||||||
retryCount = "retry %v/%v"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func debugLogReqError(r *Request, stage, retryStr string, err error) {
|
func debugLogReqError(r *Request, stage, retryStr string, err error) {
|
||||||
|
@ -393,12 +402,16 @@ func (r *Request) Sign() error {
|
||||||
return r.Error
|
return r.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
|
func (r *Request) getNextRequestBody() (body io.ReadCloser, err error) {
|
||||||
if r.safeBody != nil {
|
if r.safeBody != nil {
|
||||||
r.safeBody.Close()
|
r.safeBody.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
r.safeBody = newOffsetReader(r.Body, r.BodyStart)
|
r.safeBody, err = newOffsetReader(r.Body, r.BodyStart)
|
||||||
|
if err != nil {
|
||||||
|
return nil, awserr.New(ErrCodeSerialization,
|
||||||
|
"failed to get next request body reader", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Go 1.8 tightened and clarified the rules code needs to use when building
|
// Go 1.8 tightened and clarified the rules code needs to use when building
|
||||||
// requests with the http package. Go 1.8 removed the automatic detection
|
// requests with the http package. Go 1.8 removed the automatic detection
|
||||||
|
@ -415,10 +428,10 @@ func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
|
||||||
// Related golang/go#18257
|
// Related golang/go#18257
|
||||||
l, err := aws.SeekerLen(r.Body)
|
l, err := aws.SeekerLen(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, awserr.New(ErrCodeSerialization, "failed to compute request body size", err)
|
return nil, awserr.New(ErrCodeSerialization,
|
||||||
|
"failed to compute request body size", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var body io.ReadCloser
|
|
||||||
if l == 0 {
|
if l == 0 {
|
||||||
body = NoBody
|
body = NoBody
|
||||||
} else if l > 0 {
|
} else if l > 0 {
|
||||||
|
@ -495,13 +508,16 @@ func (r *Request) Send() error {
|
||||||
return r.Error
|
return r.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
r.prepareRetry()
|
if err := r.prepareRetry(); err != nil {
|
||||||
|
r.Error = err
|
||||||
|
return err
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) prepareRetry() {
|
func (r *Request) prepareRetry() error {
|
||||||
if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
|
if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
|
||||||
r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
|
r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
|
r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
|
||||||
|
@ -512,12 +528,19 @@ func (r *Request) prepareRetry() {
|
||||||
// the request's body even though the Client's Do returned.
|
// the request's body even though the Client's Do returned.
|
||||||
r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil)
|
r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil)
|
||||||
r.ResetBody()
|
r.ResetBody()
|
||||||
|
if err := r.Error; err != nil {
|
||||||
|
return awserr.New(ErrCodeSerialization,
|
||||||
|
"failed to prepare body for retry", err)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Closing response body to ensure that no response body is leaked
|
// Closing response body to ensure that no response body is leaked
|
||||||
// between retry attempts.
|
// between retry attempts.
|
||||||
if r.HTTPResponse != nil && r.HTTPResponse.Body != nil {
|
if r.HTTPResponse != nil && r.HTTPResponse.Body != nil {
|
||||||
r.HTTPResponse.Body.Close()
|
r.HTTPResponse.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Request) sendRequest() (sendErr error) {
|
func (r *Request) sendRequest() (sendErr error) {
|
||||||
|
|
|
@ -4,6 +4,8 @@ package request
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NoBody is a http.NoBody reader instructing Go HTTP client to not include
|
// NoBody is a http.NoBody reader instructing Go HTTP client to not include
|
||||||
|
@ -24,7 +26,8 @@ var NoBody = http.NoBody
|
||||||
func (r *Request) ResetBody() {
|
func (r *Request) ResetBody() {
|
||||||
body, err := r.getNextRequestBody()
|
body, err := r.getNextRequestBody()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Error = err
|
r.Error = awserr.New(ErrCodeSerialization,
|
||||||
|
"failed to reset request body", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,7 @@ func (r *Request) nextPageTokens() []interface{} {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
case bool:
|
case bool:
|
||||||
if v == false {
|
if !v {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,141 @@ import (
|
||||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func resolveCredentials(cfg *aws.Config,
|
||||||
|
envCfg envConfig, sharedCfg sharedConfig,
|
||||||
|
handlers request.Handlers,
|
||||||
|
sessOpts Options,
|
||||||
|
) (*credentials.Credentials, error) {
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(envCfg.Profile) != 0:
|
||||||
|
// User explicitly provided an Profile, so load from shared config
|
||||||
|
// first.
|
||||||
|
return resolveCredsFromProfile(cfg, envCfg, sharedCfg, handlers, sessOpts)
|
||||||
|
|
||||||
|
case envCfg.Creds.HasKeys():
|
||||||
|
// Environment credentials
|
||||||
|
return credentials.NewStaticCredentialsFromCreds(envCfg.Creds), nil
|
||||||
|
|
||||||
|
case len(envCfg.WebIdentityTokenFilePath) != 0:
|
||||||
|
// Web identity token from environment, RoleARN required to also be
|
||||||
|
// set.
|
||||||
|
return assumeWebIdentity(cfg, handlers,
|
||||||
|
envCfg.WebIdentityTokenFilePath,
|
||||||
|
envCfg.RoleARN,
|
||||||
|
envCfg.RoleSessionName,
|
||||||
|
)
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Fallback to the "default" credential resolution chain.
|
||||||
|
return resolveCredsFromProfile(cfg, envCfg, sharedCfg, handlers, sessOpts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WebIdentityEmptyRoleARNErr will occur if 'AWS_WEB_IDENTITY_TOKEN_FILE' was set but
|
||||||
|
// 'AWS_IAM_ROLE_ARN' was not set.
|
||||||
|
var WebIdentityEmptyRoleARNErr = awserr.New(stscreds.ErrCodeWebIdentity, "role ARN is not set", nil)
|
||||||
|
|
||||||
|
// WebIdentityEmptyTokenFilePathErr will occur if 'AWS_IAM_ROLE_ARN' was set but
|
||||||
|
// 'AWS_WEB_IDENTITY_TOKEN_FILE' was not set.
|
||||||
|
var WebIdentityEmptyTokenFilePathErr = awserr.New(stscreds.ErrCodeWebIdentity, "token file path is not set", nil)
|
||||||
|
|
||||||
|
func assumeWebIdentity(cfg *aws.Config, handlers request.Handlers,
|
||||||
|
filepath string,
|
||||||
|
roleARN, sessionName string,
|
||||||
|
) (*credentials.Credentials, error) {
|
||||||
|
|
||||||
|
if len(filepath) == 0 {
|
||||||
|
return nil, WebIdentityEmptyTokenFilePathErr
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(roleARN) == 0 {
|
||||||
|
return nil, WebIdentityEmptyRoleARNErr
|
||||||
|
}
|
||||||
|
|
||||||
|
creds := stscreds.NewWebIdentityCredentials(
|
||||||
|
&Session{
|
||||||
|
Config: cfg,
|
||||||
|
Handlers: handlers.Copy(),
|
||||||
|
},
|
||||||
|
roleARN,
|
||||||
|
sessionName,
|
||||||
|
filepath,
|
||||||
|
)
|
||||||
|
|
||||||
|
return creds, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resolveCredsFromProfile(cfg *aws.Config,
|
||||||
|
envCfg envConfig, sharedCfg sharedConfig,
|
||||||
|
handlers request.Handlers,
|
||||||
|
sessOpts Options,
|
||||||
|
) (creds *credentials.Credentials, err error) {
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case sharedCfg.SourceProfile != nil:
|
||||||
|
// Assume IAM role with credentials source from a different profile.
|
||||||
|
creds, err = resolveCredsFromProfile(cfg, envCfg,
|
||||||
|
*sharedCfg.SourceProfile, handlers, sessOpts,
|
||||||
|
)
|
||||||
|
|
||||||
|
case sharedCfg.Creds.HasKeys():
|
||||||
|
// Static Credentials from Shared Config/Credentials file.
|
||||||
|
creds = credentials.NewStaticCredentialsFromCreds(
|
||||||
|
sharedCfg.Creds,
|
||||||
|
)
|
||||||
|
|
||||||
|
case len(sharedCfg.CredentialProcess) != 0:
|
||||||
|
// Get credentials from CredentialProcess
|
||||||
|
creds = processcreds.NewCredentials(sharedCfg.CredentialProcess)
|
||||||
|
|
||||||
|
case len(sharedCfg.CredentialSource) != 0:
|
||||||
|
creds, err = resolveCredsFromSource(cfg, envCfg,
|
||||||
|
sharedCfg, handlers, sessOpts,
|
||||||
|
)
|
||||||
|
|
||||||
|
case len(sharedCfg.WebIdentityTokenFile) != 0:
|
||||||
|
// Credentials from Assume Web Identity token require an IAM Role, and
|
||||||
|
// that roll will be assumed. May be wrapped with another assume role
|
||||||
|
// via SourceProfile.
|
||||||
|
return assumeWebIdentity(cfg, handlers,
|
||||||
|
sharedCfg.WebIdentityTokenFile,
|
||||||
|
sharedCfg.RoleARN,
|
||||||
|
sharedCfg.RoleSessionName,
|
||||||
|
)
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Fallback to default credentials provider, include mock errors for
|
||||||
|
// the credential chain so user can identify why credentials failed to
|
||||||
|
// be retrieved.
|
||||||
|
creds = 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),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sharedCfg.RoleARN) > 0 {
|
||||||
|
cfgCp := *cfg
|
||||||
|
cfgCp.Credentials = creds
|
||||||
|
return credsFromAssumeRole(cfgCp, handlers, sharedCfg, sessOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
return creds, nil
|
||||||
|
}
|
||||||
|
|
||||||
// valid credential source values
|
// valid credential source values
|
||||||
const (
|
const (
|
||||||
credSourceEc2Metadata = "Ec2InstanceMetadata"
|
credSourceEc2Metadata = "Ec2InstanceMetadata"
|
||||||
|
@ -21,116 +156,33 @@ const (
|
||||||
credSourceECSContainer = "EcsContainer"
|
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 {
|
|
||||||
// Get credentials from CredentialProcess
|
|
||||||
cred := processcreds.NewCredentials(sharedCfg.CredentialProcess)
|
|
||||||
// if RoleARN is provided, so the obtained cred from the Credential Process to assume the role using RoleARN
|
|
||||||
if len(sharedCfg.AssumeRole.RoleARN) > 0 {
|
|
||||||
cfgCp := *cfg
|
|
||||||
cfgCp.Credentials = cred
|
|
||||||
return credsFromAssumeRole(cfgCp, handlers, sharedCfg, sessOpts)
|
|
||||||
}
|
|
||||||
return cred, 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,
|
func resolveCredsFromSource(cfg *aws.Config,
|
||||||
envCfg envConfig, sharedCfg sharedConfig,
|
envCfg envConfig, sharedCfg sharedConfig,
|
||||||
handlers request.Handlers,
|
handlers request.Handlers,
|
||||||
sessOpts Options,
|
sessOpts Options,
|
||||||
) (*credentials.Credentials, error) {
|
) (creds *credentials.Credentials, err 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.CredentialSource {
|
||||||
switch sharedCfg.AssumeRole.CredentialSource {
|
|
||||||
case credSourceEc2Metadata:
|
case credSourceEc2Metadata:
|
||||||
p := defaults.RemoteCredProvider(cfgCp, handlers)
|
p := defaults.RemoteCredProvider(*cfg, handlers)
|
||||||
cfgCp.Credentials = credentials.NewCredentials(p)
|
creds = credentials.NewCredentials(p)
|
||||||
|
|
||||||
case credSourceEnvironment:
|
case credSourceEnvironment:
|
||||||
cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds(envCfg.Creds)
|
creds = credentials.NewStaticCredentialsFromCreds(envCfg.Creds)
|
||||||
|
|
||||||
case credSourceECSContainer:
|
case credSourceECSContainer:
|
||||||
if len(os.Getenv(shareddefaults.ECSCredsProviderEnvVar)) == 0 {
|
if len(os.Getenv(shareddefaults.ECSCredsProviderEnvVar)) == 0 {
|
||||||
return nil, ErrSharedConfigECSContainerEnvVarEmpty
|
return nil, ErrSharedConfigECSContainerEnvVarEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
p := defaults.RemoteCredProvider(cfgCp, handlers)
|
p := defaults.RemoteCredProvider(*cfg, handlers)
|
||||||
cfgCp.Credentials = credentials.NewCredentials(p)
|
creds = credentials.NewCredentials(p)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, ErrSharedConfigInvalidCredSource
|
return nil, ErrSharedConfigInvalidCredSource
|
||||||
}
|
}
|
||||||
|
|
||||||
return credsFromAssumeRole(cfgCp, handlers, sharedCfg, sessOpts)
|
return creds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func credsFromAssumeRole(cfg aws.Config,
|
func credsFromAssumeRole(cfg aws.Config,
|
||||||
|
@ -138,7 +190,8 @@ func credsFromAssumeRole(cfg aws.Config,
|
||||||
sharedCfg sharedConfig,
|
sharedCfg sharedConfig,
|
||||||
sessOpts Options,
|
sessOpts Options,
|
||||||
) (*credentials.Credentials, error) {
|
) (*credentials.Credentials, error) {
|
||||||
if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
|
|
||||||
|
if len(sharedCfg.MFASerial) != 0 && sessOpts.AssumeRoleTokenProvider == nil {
|
||||||
// AssumeRole Token provider is required if doing Assume Role
|
// AssumeRole Token provider is required if doing Assume Role
|
||||||
// with MFA.
|
// with MFA.
|
||||||
return nil, AssumeRoleTokenProviderNotSetError{}
|
return nil, AssumeRoleTokenProviderNotSetError{}
|
||||||
|
@ -149,28 +202,28 @@ func credsFromAssumeRole(cfg aws.Config,
|
||||||
Config: &cfg,
|
Config: &cfg,
|
||||||
Handlers: handlers.Copy(),
|
Handlers: handlers.Copy(),
|
||||||
},
|
},
|
||||||
sharedCfg.AssumeRole.RoleARN,
|
sharedCfg.RoleARN,
|
||||||
func(opt *stscreds.AssumeRoleProvider) {
|
func(opt *stscreds.AssumeRoleProvider) {
|
||||||
opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName
|
opt.RoleSessionName = sharedCfg.RoleSessionName
|
||||||
opt.Duration = sessOpts.AssumeRoleDuration
|
opt.Duration = sessOpts.AssumeRoleDuration
|
||||||
|
|
||||||
// Assume role with external ID
|
// Assume role with external ID
|
||||||
if len(sharedCfg.AssumeRole.ExternalID) > 0 {
|
if len(sharedCfg.ExternalID) > 0 {
|
||||||
opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID)
|
opt.ExternalID = aws.String(sharedCfg.ExternalID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume role with MFA
|
// Assume role with MFA
|
||||||
if len(sharedCfg.AssumeRole.MFASerial) > 0 {
|
if len(sharedCfg.MFASerial) > 0 {
|
||||||
opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial)
|
opt.SerialNumber = aws.String(sharedCfg.MFASerial)
|
||||||
opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
|
opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the
|
// AssumeRoleTokenProviderNotSetError is an error returned when creating a
|
||||||
// MFAToken option is not set when shared config is configured load assume a
|
// session when the MFAToken option is not set when shared config is configured
|
||||||
// role with an MFA token.
|
// load assume a role with an MFA token.
|
||||||
type AssumeRoleTokenProviderNotSetError struct{}
|
type AssumeRoleTokenProviderNotSetError struct{}
|
||||||
|
|
||||||
// Code is the short id of the error.
|
// Code is the short id of the error.
|
||||||
|
@ -197,8 +250,6 @@ type credProviderError struct {
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
var emptyCreds = credentials.Value{}
|
|
||||||
|
|
||||||
func (c credProviderError) Retrieve() (credentials.Value, error) {
|
func (c credProviderError) Retrieve() (credentials.Value, error) {
|
||||||
return credentials.Value{}, c.Err
|
return credentials.Value{}, c.Err
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,11 +104,27 @@ type envConfig struct {
|
||||||
CSMClientID string
|
CSMClientID string
|
||||||
CSMHost string
|
CSMHost string
|
||||||
|
|
||||||
enableEndpointDiscovery string
|
|
||||||
// Enables endpoint discovery via environment variables.
|
// Enables endpoint discovery via environment variables.
|
||||||
//
|
//
|
||||||
// AWS_ENABLE_ENDPOINT_DISCOVERY=true
|
// AWS_ENABLE_ENDPOINT_DISCOVERY=true
|
||||||
EnableEndpointDiscovery *bool
|
EnableEndpointDiscovery *bool
|
||||||
|
enableEndpointDiscovery string
|
||||||
|
|
||||||
|
// Specifies the WebIdentity token the SDK should use to assume a role
|
||||||
|
// with.
|
||||||
|
//
|
||||||
|
// AWS_WEB_IDENTITY_TOKEN_FILE=file_path
|
||||||
|
WebIdentityTokenFilePath string
|
||||||
|
|
||||||
|
// Specifies the IAM role arn to use when assuming an role.
|
||||||
|
//
|
||||||
|
// AWS_ROLE_ARN=role_arn
|
||||||
|
RoleARN string
|
||||||
|
|
||||||
|
// Specifies the IAM role session name to use when assuming a role.
|
||||||
|
//
|
||||||
|
// AWS_ROLE_SESSION_NAME=session_name
|
||||||
|
RoleSessionName string
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -154,6 +170,15 @@ var (
|
||||||
sharedConfigFileEnvKey = []string{
|
sharedConfigFileEnvKey = []string{
|
||||||
"AWS_CONFIG_FILE",
|
"AWS_CONFIG_FILE",
|
||||||
}
|
}
|
||||||
|
webIdentityTokenFilePathEnvKey = []string{
|
||||||
|
"AWS_WEB_IDENTITY_TOKEN_FILE",
|
||||||
|
}
|
||||||
|
roleARNEnvKey = []string{
|
||||||
|
"AWS_ROLE_ARN",
|
||||||
|
}
|
||||||
|
roleSessionNameEnvKey = []string{
|
||||||
|
"AWS_ROLE_SESSION_NAME",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// loadEnvConfig retrieves the SDK's environment configuration.
|
// loadEnvConfig retrieves the SDK's environment configuration.
|
||||||
|
@ -182,9 +207,23 @@ func envConfigLoad(enableSharedConfig bool) envConfig {
|
||||||
|
|
||||||
cfg.EnableSharedConfig = enableSharedConfig
|
cfg.EnableSharedConfig = enableSharedConfig
|
||||||
|
|
||||||
setFromEnvVal(&cfg.Creds.AccessKeyID, credAccessEnvKey)
|
// Static environment credentials
|
||||||
setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey)
|
var creds credentials.Value
|
||||||
setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey)
|
setFromEnvVal(&creds.AccessKeyID, credAccessEnvKey)
|
||||||
|
setFromEnvVal(&creds.SecretAccessKey, credSecretEnvKey)
|
||||||
|
setFromEnvVal(&creds.SessionToken, credSessionEnvKey)
|
||||||
|
if creds.HasKeys() {
|
||||||
|
// Require logical grouping of credentials
|
||||||
|
creds.ProviderName = EnvProviderName
|
||||||
|
cfg.Creds = creds
|
||||||
|
}
|
||||||
|
|
||||||
|
// Role Metadata
|
||||||
|
setFromEnvVal(&cfg.RoleARN, roleARNEnvKey)
|
||||||
|
setFromEnvVal(&cfg.RoleSessionName, roleSessionNameEnvKey)
|
||||||
|
|
||||||
|
// Web identity environment variables
|
||||||
|
setFromEnvVal(&cfg.WebIdentityTokenFilePath, webIdentityTokenFilePathEnvKey)
|
||||||
|
|
||||||
// CSM environment variables
|
// CSM environment variables
|
||||||
setFromEnvVal(&cfg.csmEnabled, csmEnabledEnvKey)
|
setFromEnvVal(&cfg.csmEnabled, csmEnabledEnvKey)
|
||||||
|
@ -193,13 +232,6 @@ func envConfigLoad(enableSharedConfig bool) envConfig {
|
||||||
setFromEnvVal(&cfg.CSMClientID, csmClientIDEnvKey)
|
setFromEnvVal(&cfg.CSMClientID, csmClientIDEnvKey)
|
||||||
cfg.CSMEnabled = len(cfg.csmEnabled) > 0
|
cfg.CSMEnabled = len(cfg.csmEnabled) > 0
|
||||||
|
|
||||||
// Require logical grouping of credentials
|
|
||||||
if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 {
|
|
||||||
cfg.Creds = credentials.Value{}
|
|
||||||
} else {
|
|
||||||
cfg.Creds.ProviderName = EnvProviderName
|
|
||||||
}
|
|
||||||
|
|
||||||
regionKeys := regionEnvKeys
|
regionKeys := regionEnvKeys
|
||||||
profileKeys := profileEnvKeys
|
profileKeys := profileEnvKeys
|
||||||
if !cfg.EnableSharedConfig {
|
if !cfg.EnableSharedConfig {
|
||||||
|
|
|
@ -376,6 +376,7 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
|
||||||
// credentials were.
|
// credentials were.
|
||||||
userCfg := &aws.Config{}
|
userCfg := &aws.Config{}
|
||||||
userCfg.MergeIn(cfgs...)
|
userCfg.MergeIn(cfgs...)
|
||||||
|
cfg.MergeIn(userCfg)
|
||||||
|
|
||||||
// Ordered config files will be loaded in with later files overwriting
|
// Ordered config files will be loaded in with later files overwriting
|
||||||
// previous config file values.
|
// previous config file values.
|
||||||
|
@ -392,9 +393,11 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load additional config from file(s)
|
// Load additional config from file(s)
|
||||||
sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles)
|
sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles, envCfg.EnableSharedConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
if _, ok := err.(SharedConfigProfileNotExistsError); !ok {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil {
|
if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil {
|
||||||
|
@ -478,8 +481,6 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config,
|
||||||
handlers request.Handlers,
|
handlers request.Handlers,
|
||||||
sessOpts Options,
|
sessOpts Options,
|
||||||
) error {
|
) error {
|
||||||
// Merge in user provided configuration
|
|
||||||
cfg.MergeIn(userCfg)
|
|
||||||
|
|
||||||
// Region if not already set by user
|
// Region if not already set by user
|
||||||
if len(aws.StringValue(cfg.Region)) == 0 {
|
if len(aws.StringValue(cfg.Region)) == 0 {
|
||||||
|
|
|
@ -27,8 +27,12 @@ const (
|
||||||
|
|
||||||
// endpoint discovery group
|
// endpoint discovery group
|
||||||
enableEndpointDiscoveryKey = `endpoint_discovery_enabled` // optional
|
enableEndpointDiscoveryKey = `endpoint_discovery_enabled` // optional
|
||||||
|
|
||||||
// External Credential Process
|
// External Credential Process
|
||||||
credentialProcessKey = `credential_process`
|
credentialProcessKey = `credential_process` // optional
|
||||||
|
|
||||||
|
// Web Identity Token File
|
||||||
|
webIdentityTokenFileKey = `web_identity_token_file` // optional
|
||||||
|
|
||||||
// DefaultSharedConfigProfile is the default profile to be used when
|
// DefaultSharedConfigProfile is the default profile to be used when
|
||||||
// loading configuration from the config files if another profile name
|
// loading configuration from the config files if another profile name
|
||||||
|
@ -36,36 +40,33 @@ const (
|
||||||
DefaultSharedConfigProfile = `default`
|
DefaultSharedConfigProfile = `default`
|
||||||
)
|
)
|
||||||
|
|
||||||
type assumeRoleConfig struct {
|
|
||||||
RoleARN string
|
|
||||||
SourceProfile string
|
|
||||||
CredentialSource string
|
|
||||||
ExternalID string
|
|
||||||
MFASerial string
|
|
||||||
RoleSessionName string
|
|
||||||
}
|
|
||||||
|
|
||||||
// sharedConfig represents the configuration fields of the SDK config files.
|
// sharedConfig represents the configuration fields of the SDK config files.
|
||||||
type sharedConfig struct {
|
type sharedConfig struct {
|
||||||
// Credentials values from the config file. Both aws_access_key_id
|
// Credentials values from the config file. Both aws_access_key_id and
|
||||||
// and aws_secret_access_key must be provided together in the same file
|
// aws_secret_access_key must be provided together in the same file to be
|
||||||
// to be considered valid. The values will be ignored if not a complete group.
|
// considered valid. The values will be ignored if not a complete group.
|
||||||
// aws_session_token is an optional field that can be provided if both of the
|
// aws_session_token is an optional field that can be provided if both of
|
||||||
// other two fields are also provided.
|
// the other two fields are also provided.
|
||||||
//
|
//
|
||||||
// aws_access_key_id
|
// aws_access_key_id
|
||||||
// aws_secret_access_key
|
// aws_secret_access_key
|
||||||
// aws_session_token
|
// aws_session_token
|
||||||
Creds credentials.Value
|
Creds credentials.Value
|
||||||
|
|
||||||
AssumeRole assumeRoleConfig
|
CredentialSource string
|
||||||
AssumeRoleSource *sharedConfig
|
CredentialProcess string
|
||||||
|
WebIdentityTokenFile string
|
||||||
|
|
||||||
// An external process to request credentials
|
RoleARN string
|
||||||
CredentialProcess string
|
RoleSessionName string
|
||||||
|
ExternalID string
|
||||||
|
MFASerial string
|
||||||
|
|
||||||
// Region is the region the SDK should use for looking up AWS service endpoints
|
SourceProfileName string
|
||||||
// and signing requests.
|
SourceProfile *sharedConfig
|
||||||
|
|
||||||
|
// Region is the region the SDK should use for looking up AWS service
|
||||||
|
// endpoints and signing requests.
|
||||||
//
|
//
|
||||||
// region
|
// region
|
||||||
Region string
|
Region string
|
||||||
|
@ -82,17 +83,18 @@ type sharedConfigFile struct {
|
||||||
IniData ini.Sections
|
IniData ini.Sections
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadSharedConfig retrieves the configuration from the list of files
|
// loadSharedConfig retrieves the configuration from the list of files using
|
||||||
// using the profile provided. The order the files are listed will determine
|
// the profile provided. The order the files are listed will determine
|
||||||
// precedence. Values in subsequent files will overwrite values defined in
|
// precedence. Values in subsequent files will overwrite values defined in
|
||||||
// earlier files.
|
// earlier files.
|
||||||
//
|
//
|
||||||
// For example, given two files A and B. Both define credentials. If the order
|
// For example, given two files A and B. Both define credentials. If the order
|
||||||
// of the files are A then B, B's credential values will be used instead of A's.
|
// of the files are A then B, B's credential values will be used instead of
|
||||||
|
// A's.
|
||||||
//
|
//
|
||||||
// See sharedConfig.setFromFile for information how the config files
|
// See sharedConfig.setFromFile for information how the config files
|
||||||
// will be loaded.
|
// will be loaded.
|
||||||
func loadSharedConfig(profile string, filenames []string) (sharedConfig, error) {
|
func loadSharedConfig(profile string, filenames []string, exOpts bool) (sharedConfig, error) {
|
||||||
if len(profile) == 0 {
|
if len(profile) == 0 {
|
||||||
profile = DefaultSharedConfigProfile
|
profile = DefaultSharedConfigProfile
|
||||||
}
|
}
|
||||||
|
@ -103,16 +105,11 @@ func loadSharedConfig(profile string, filenames []string) (sharedConfig, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := sharedConfig{}
|
cfg := sharedConfig{}
|
||||||
if err = cfg.setFromIniFiles(profile, files); err != nil {
|
profiles := map[string]struct{}{}
|
||||||
|
if err = cfg.setFromIniFiles(profiles, profile, files, exOpts); err != nil {
|
||||||
return sharedConfig{}, err
|
return sharedConfig{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cfg.AssumeRole.SourceProfile) > 0 {
|
|
||||||
if err := cfg.setAssumeRoleSource(profile, files); err != nil {
|
|
||||||
return sharedConfig{}, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,71 +133,88 @@ func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) {
|
||||||
return files, nil
|
return files, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error {
|
func (cfg *sharedConfig) setFromIniFiles(profiles map[string]struct{}, profile string, files []sharedConfigFile, exOpts bool) error {
|
||||||
var assumeRoleSrc sharedConfig
|
|
||||||
|
|
||||||
if len(cfg.AssumeRole.CredentialSource) > 0 {
|
|
||||||
// setAssumeRoleSource is only called when source_profile is found.
|
|
||||||
// If both source_profile and credential_source are set, then
|
|
||||||
// ErrSharedConfigSourceCollision will be returned
|
|
||||||
return ErrSharedConfigSourceCollision
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiple level assume role chains are not support
|
|
||||||
if cfg.AssumeRole.SourceProfile == origProfile {
|
|
||||||
assumeRoleSrc = *cfg
|
|
||||||
assumeRoleSrc.AssumeRole = assumeRoleConfig{}
|
|
||||||
} else {
|
|
||||||
err := assumeRoleSrc.setFromIniFiles(cfg.AssumeRole.SourceProfile, files)
|
|
||||||
if err != nil {
|
|
||||||
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 cfg.AssumeRole.SourceProfile == origProfile || len(assumeRoleSrc.AssumeRole.SourceProfile) == 0 {
|
|
||||||
//Check if at least either Credential Source, static creds, or credential process is set to retain credentials.
|
|
||||||
if len(assumeRoleSrc.AssumeRole.CredentialSource) == 0 && len(assumeRoleSrc.Creds.AccessKeyID) == 0 && len(assumeRoleSrc.CredentialProcess) == 0 {
|
|
||||||
return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.AssumeRoleSource = &assumeRoleSrc
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *sharedConfig) setFromIniFiles(profile string, files []sharedConfigFile) error {
|
|
||||||
// Trim files from the list that don't exist.
|
// Trim files from the list that don't exist.
|
||||||
|
var skippedFiles int
|
||||||
|
var profileNotFoundErr error
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
if err := cfg.setFromIniFile(profile, f); err != nil {
|
if err := cfg.setFromIniFile(profile, f, exOpts); err != nil {
|
||||||
if _, ok := err.(SharedConfigProfileNotExistsError); ok {
|
if _, ok := err.(SharedConfigProfileNotExistsError); ok {
|
||||||
// Ignore proviles missings
|
// Ignore profiles not defined in individual files.
|
||||||
|
profileNotFoundErr = err
|
||||||
|
skippedFiles++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if skippedFiles == len(files) {
|
||||||
|
// If all files were skipped because the profile is not found, return
|
||||||
|
// the original profile not found error.
|
||||||
|
return profileNotFoundErr
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := profiles[profile]; ok {
|
||||||
|
// if this is the second instance of the profile the Assume Role
|
||||||
|
// options must be cleared because they are only valid for the
|
||||||
|
// first reference of a profile. The self linked instance of the
|
||||||
|
// profile only have credential provider options.
|
||||||
|
cfg.clearAssumeRoleOptions()
|
||||||
|
} else {
|
||||||
|
// First time a profile has been seen, It must either be a assume role
|
||||||
|
// or credentials. Assert if the credential type requires a role ARN,
|
||||||
|
// the ARN is also set.
|
||||||
|
if err := cfg.validateCredentialsRequireARN(profile); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
profiles[profile] = struct{}{}
|
||||||
|
|
||||||
|
if err := cfg.validateCredentialType(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link source profiles for assume roles
|
||||||
|
if len(cfg.SourceProfileName) != 0 {
|
||||||
|
// Linked profile via source_profile ignore credential provider
|
||||||
|
// options, the source profile must provide the credentials.
|
||||||
|
cfg.clearCredentialOptions()
|
||||||
|
|
||||||
|
srcCfg := &sharedConfig{}
|
||||||
|
err := srcCfg.setFromIniFiles(profiles, cfg.SourceProfileName, files, exOpts)
|
||||||
|
if err != nil {
|
||||||
|
// SourceProfile that doesn't exist is an error in configuration.
|
||||||
|
if _, ok := err.(SharedConfigProfileNotExistsError); ok {
|
||||||
|
err = SharedConfigAssumeRoleError{
|
||||||
|
RoleARN: cfg.RoleARN,
|
||||||
|
SourceProfile: cfg.SourceProfileName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !srcCfg.hasCredentials() {
|
||||||
|
return SharedConfigAssumeRoleError{
|
||||||
|
RoleARN: cfg.RoleARN,
|
||||||
|
SourceProfile: cfg.SourceProfileName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg.SourceProfile = srcCfg
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// setFromFile loads the configuration from the file using
|
// setFromFile loads the configuration from the file using the profile
|
||||||
// the profile provided. A sharedConfig pointer type value is used so that
|
// provided. A sharedConfig pointer type value is used so that multiple config
|
||||||
// multiple config file loadings can be chained.
|
// file loadings can be chained.
|
||||||
//
|
//
|
||||||
// Only loads complete logically grouped values, and will not set fields in cfg
|
// Only loads complete logically grouped values, and will not set fields in cfg
|
||||||
// for incomplete grouped values in the config. Such as credentials. For example
|
// for incomplete grouped values in the config. Such as credentials. For
|
||||||
// if a config file only includes aws_access_key_id but no aws_secret_access_key
|
// example if a config file only includes aws_access_key_id but no
|
||||||
// the aws_access_key_id will be ignored.
|
// aws_secret_access_key the aws_access_key_id will be ignored.
|
||||||
func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error {
|
func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, exOpts bool) error {
|
||||||
section, ok := file.IniData.GetSection(profile)
|
section, ok := file.IniData.GetSection(profile)
|
||||||
if !ok {
|
if !ok {
|
||||||
// Fallback to to alternate profile name: profile <name>
|
// Fallback to to alternate profile name: profile <name>
|
||||||
|
@ -210,44 +224,30 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if exOpts {
|
||||||
|
// Assume Role Parameters
|
||||||
|
updateString(&cfg.RoleARN, section, roleArnKey)
|
||||||
|
updateString(&cfg.ExternalID, section, externalIDKey)
|
||||||
|
updateString(&cfg.MFASerial, section, mfaSerialKey)
|
||||||
|
updateString(&cfg.RoleSessionName, section, roleSessionNameKey)
|
||||||
|
updateString(&cfg.SourceProfileName, section, sourceProfileKey)
|
||||||
|
updateString(&cfg.CredentialSource, section, credentialSourceKey)
|
||||||
|
|
||||||
|
updateString(&cfg.Region, section, regionKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateString(&cfg.CredentialProcess, section, credentialProcessKey)
|
||||||
|
updateString(&cfg.WebIdentityTokenFile, section, webIdentityTokenFileKey)
|
||||||
|
|
||||||
// Shared Credentials
|
// Shared Credentials
|
||||||
akid := section.String(accessKeyIDKey)
|
creds := credentials.Value{
|
||||||
secret := section.String(secretAccessKey)
|
AccessKeyID: section.String(accessKeyIDKey),
|
||||||
if len(akid) > 0 && len(secret) > 0 {
|
SecretAccessKey: section.String(secretAccessKey),
|
||||||
cfg.Creds = credentials.Value{
|
SessionToken: section.String(sessionTokenKey),
|
||||||
AccessKeyID: akid,
|
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename),
|
||||||
SecretAccessKey: secret,
|
|
||||||
SessionToken: section.String(sessionTokenKey),
|
|
||||||
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if creds.HasKeys() {
|
||||||
// Assume Role
|
cfg.Creds = creds
|
||||||
roleArn := section.String(roleArnKey)
|
|
||||||
srcProfile := section.String(sourceProfileKey)
|
|
||||||
credentialSource := section.String(credentialSourceKey)
|
|
||||||
credentialProcess := section.String(credentialProcessKey)
|
|
||||||
//Has source to make sure the Assume Role has at least either srcProfile, credential Source, or credential Process.
|
|
||||||
hasSource := len(srcProfile) > 0 || len(credentialSource) > 0 || len(credentialProcess) > 0
|
|
||||||
if len(roleArn) > 0 && hasSource {
|
|
||||||
cfg.AssumeRole = assumeRoleConfig{
|
|
||||||
RoleARN: roleArn,
|
|
||||||
SourceProfile: srcProfile,
|
|
||||||
CredentialSource: credentialSource,
|
|
||||||
ExternalID: section.String(externalIDKey),
|
|
||||||
MFASerial: section.String(mfaSerialKey),
|
|
||||||
RoleSessionName: section.String(roleSessionNameKey),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// `credential_process`
|
|
||||||
if credProc := section.String(credentialProcessKey); len(credProc) > 0 {
|
|
||||||
cfg.CredentialProcess = credProc
|
|
||||||
}
|
|
||||||
|
|
||||||
// Region
|
|
||||||
if v := section.String(regionKey); len(v) > 0 {
|
|
||||||
cfg.Region = v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Endpoint discovery
|
// Endpoint discovery
|
||||||
|
@ -259,6 +259,95 @@ func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) e
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cfg *sharedConfig) validateCredentialsRequireARN(profile string) error {
|
||||||
|
var credSource string
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case len(cfg.SourceProfileName) != 0:
|
||||||
|
credSource = sourceProfileKey
|
||||||
|
case len(cfg.CredentialSource) != 0:
|
||||||
|
credSource = credentialSourceKey
|
||||||
|
case len(cfg.WebIdentityTokenFile) != 0:
|
||||||
|
credSource = webIdentityTokenFileKey
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(credSource) != 0 && len(cfg.RoleARN) == 0 {
|
||||||
|
return CredentialRequiresARNError{
|
||||||
|
Type: credSource,
|
||||||
|
Profile: profile,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *sharedConfig) validateCredentialType() error {
|
||||||
|
// Only one or no credential type can be defined.
|
||||||
|
if !oneOrNone(
|
||||||
|
len(cfg.SourceProfileName) != 0,
|
||||||
|
len(cfg.CredentialSource) != 0,
|
||||||
|
len(cfg.CredentialProcess) != 0,
|
||||||
|
len(cfg.WebIdentityTokenFile) != 0,
|
||||||
|
) {
|
||||||
|
return ErrSharedConfigSourceCollision
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *sharedConfig) hasCredentials() bool {
|
||||||
|
switch {
|
||||||
|
case len(cfg.SourceProfileName) != 0:
|
||||||
|
case len(cfg.CredentialSource) != 0:
|
||||||
|
case len(cfg.CredentialProcess) != 0:
|
||||||
|
case len(cfg.WebIdentityTokenFile) != 0:
|
||||||
|
case cfg.Creds.HasKeys():
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *sharedConfig) clearCredentialOptions() {
|
||||||
|
cfg.CredentialSource = ""
|
||||||
|
cfg.CredentialProcess = ""
|
||||||
|
cfg.WebIdentityTokenFile = ""
|
||||||
|
cfg.Creds = credentials.Value{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *sharedConfig) clearAssumeRoleOptions() {
|
||||||
|
cfg.RoleARN = ""
|
||||||
|
cfg.ExternalID = ""
|
||||||
|
cfg.MFASerial = ""
|
||||||
|
cfg.RoleSessionName = ""
|
||||||
|
cfg.SourceProfileName = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func oneOrNone(bs ...bool) bool {
|
||||||
|
var count int
|
||||||
|
|
||||||
|
for _, b := range bs {
|
||||||
|
if b {
|
||||||
|
count++
|
||||||
|
if count > 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// updateString will only update the dst with the value in the section key, key
|
||||||
|
// is present in the section.
|
||||||
|
func updateString(dst *string, section ini.Section, key string) {
|
||||||
|
if !section.Has(key) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
*dst = section.String(key)
|
||||||
|
}
|
||||||
|
|
||||||
// SharedConfigLoadError is an error for the shared config file failed to load.
|
// SharedConfigLoadError is an error for the shared config file failed to load.
|
||||||
type SharedConfigLoadError struct {
|
type SharedConfigLoadError struct {
|
||||||
Filename string
|
Filename string
|
||||||
|
@ -316,7 +405,8 @@ func (e SharedConfigProfileNotExistsError) Error() string {
|
||||||
// profile contains assume role information, but that information is invalid
|
// profile contains assume role information, but that information is invalid
|
||||||
// or not complete.
|
// or not complete.
|
||||||
type SharedConfigAssumeRoleError struct {
|
type SharedConfigAssumeRoleError struct {
|
||||||
RoleARN string
|
RoleARN string
|
||||||
|
SourceProfile string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code is the short id of the error.
|
// Code is the short id of the error.
|
||||||
|
@ -326,8 +416,10 @@ func (e SharedConfigAssumeRoleError) Code() string {
|
||||||
|
|
||||||
// Message is the description of the error
|
// Message is the description of the error
|
||||||
func (e SharedConfigAssumeRoleError) Message() string {
|
func (e SharedConfigAssumeRoleError) Message() string {
|
||||||
return fmt.Sprintf("failed to load assume role for %s, source profile has no shared credentials",
|
return fmt.Sprintf(
|
||||||
e.RoleARN)
|
"failed to load assume role for %s, source profile %s has no shared credentials",
|
||||||
|
e.RoleARN, e.SourceProfile,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrigErr is the underlying error that caused the failure.
|
// OrigErr is the underlying error that caused the failure.
|
||||||
|
@ -339,3 +431,36 @@ func (e SharedConfigAssumeRoleError) OrigErr() error {
|
||||||
func (e SharedConfigAssumeRoleError) Error() string {
|
func (e SharedConfigAssumeRoleError) Error() string {
|
||||||
return awserr.SprintError(e.Code(), e.Message(), "", nil)
|
return awserr.SprintError(e.Code(), e.Message(), "", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CredentialRequiresARNError provides the error for shared config credentials
|
||||||
|
// that are incorrectly configured in the shared config or credentials file.
|
||||||
|
type CredentialRequiresARNError struct {
|
||||||
|
// type of credentials that were configured.
|
||||||
|
Type string
|
||||||
|
|
||||||
|
// Profile name the credentials were in.
|
||||||
|
Profile string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code is the short id of the error.
|
||||||
|
func (e CredentialRequiresARNError) Code() string {
|
||||||
|
return "CredentialRequiresARNError"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message is the description of the error
|
||||||
|
func (e CredentialRequiresARNError) Message() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"credential type %s requires role_arn, profile %s",
|
||||||
|
e.Type, e.Profile,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrigErr is the underlying error that caused the failure.
|
||||||
|
func (e CredentialRequiresARNError) OrigErr() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error satisfies the error interface.
|
||||||
|
func (e CredentialRequiresARNError) Error() string {
|
||||||
|
return awserr.SprintError(e.Code(), e.Message(), "", nil)
|
||||||
|
}
|
||||||
|
|
|
@ -687,7 +687,11 @@ func (ctx *signingCtx) buildBodyDigest() error {
|
||||||
if !aws.IsReaderSeekable(ctx.Body) {
|
if !aws.IsReaderSeekable(ctx.Body) {
|
||||||
return fmt.Errorf("cannot use unseekable request body %T, for signed request with body", ctx.Body)
|
return fmt.Errorf("cannot use unseekable request body %T, for signed request with body", ctx.Body)
|
||||||
}
|
}
|
||||||
hash = hex.EncodeToString(makeSha256Reader(ctx.Body))
|
hashBytes, err := makeSha256Reader(ctx.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
hash = hex.EncodeToString(hashBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
if includeSHA256Header {
|
if includeSHA256Header {
|
||||||
|
@ -734,10 +738,16 @@ func makeSha256(data []byte) []byte {
|
||||||
return hash.Sum(nil)
|
return hash.Sum(nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeSha256Reader(reader io.ReadSeeker) []byte {
|
func makeSha256Reader(reader io.ReadSeeker) (hashBytes []byte, err error) {
|
||||||
hash := sha256.New()
|
hash := sha256.New()
|
||||||
start, _ := reader.Seek(0, sdkio.SeekCurrent)
|
start, err := reader.Seek(0, sdkio.SeekCurrent)
|
||||||
defer reader.Seek(start, sdkio.SeekStart)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
// ensure error is return if unable to seek back to start of payload.
|
||||||
|
_, err = reader.Seek(start, sdkio.SeekStart)
|
||||||
|
}()
|
||||||
|
|
||||||
// Use CopyN to avoid allocating the 32KB buffer in io.Copy for bodies
|
// Use CopyN to avoid allocating the 32KB buffer in io.Copy for bodies
|
||||||
// smaller than 32KB. Fall back to io.Copy if we fail to determine the size.
|
// smaller than 32KB. Fall back to io.Copy if we fail to determine the size.
|
||||||
|
@ -748,7 +758,7 @@ func makeSha256Reader(reader io.ReadSeeker) []byte {
|
||||||
io.CopyN(hash, reader, size)
|
io.CopyN(hash, reader, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash.Sum(nil)
|
return hash.Sum(nil), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const doubleSpace = " "
|
const doubleSpace = " "
|
||||||
|
|
|
@ -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.20.19"
|
const SDKVersion = "1.21.7"
|
||||||
|
|
|
@ -5420,12 +5420,6 @@ func (c *IAM) GetAccessKeyLastUsedRequest(input *GetAccessKeyLastUsedInput) (req
|
||||||
//
|
//
|
||||||
// See the AWS API reference guide for AWS Identity and Access Management's
|
// See the AWS API reference guide for AWS Identity and Access Management's
|
||||||
// API operation GetAccessKeyLastUsed for usage and error information.
|
// API operation GetAccessKeyLastUsed for usage and error information.
|
||||||
//
|
|
||||||
// Returned Error Codes:
|
|
||||||
// * ErrCodeNoSuchEntityException "NoSuchEntity"
|
|
||||||
// The request was rejected because it referenced a resource entity that does
|
|
||||||
// not exist. The error message describes the resource.
|
|
||||||
//
|
|
||||||
// See also, https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/GetAccessKeyLastUsed
|
// See also, https://docs.aws.amazon.com/goto/WebAPI/iam-2010-05-08/GetAccessKeyLastUsed
|
||||||
func (c *IAM) GetAccessKeyLastUsed(input *GetAccessKeyLastUsedInput) (*GetAccessKeyLastUsedOutput, error) {
|
func (c *IAM) GetAccessKeyLastUsed(input *GetAccessKeyLastUsedInput) (*GetAccessKeyLastUsedOutput, error) {
|
||||||
req, out := c.GetAccessKeyLastUsedRequest(input)
|
req, out := c.GetAccessKeyLastUsedRequest(input)
|
||||||
|
|
|
@ -702,6 +702,102 @@ func (c *STS) DecodeAuthorizationMessageWithContext(ctx aws.Context, input *Deco
|
||||||
return out, req.Send()
|
return out, req.Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const opGetAccessKeyInfo = "GetAccessKeyInfo"
|
||||||
|
|
||||||
|
// GetAccessKeyInfoRequest generates a "aws/request.Request" representing the
|
||||||
|
// client's request for the GetAccessKeyInfo operation. The "output" return
|
||||||
|
// value will be populated with the request's response once the request completes
|
||||||
|
// successfully.
|
||||||
|
//
|
||||||
|
// Use "Send" method on the returned Request to send the API call to the service.
|
||||||
|
// the "output" return value is not valid until after Send returns without error.
|
||||||
|
//
|
||||||
|
// See GetAccessKeyInfo for more information on using the GetAccessKeyInfo
|
||||||
|
// API call, and error handling.
|
||||||
|
//
|
||||||
|
// This method is useful when you want to inject custom logic or configuration
|
||||||
|
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// // Example sending a request using the GetAccessKeyInfoRequest method.
|
||||||
|
// req, resp := client.GetAccessKeyInfoRequest(params)
|
||||||
|
//
|
||||||
|
// err := req.Send()
|
||||||
|
// if err == nil { // resp is now filled
|
||||||
|
// fmt.Println(resp)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetAccessKeyInfo
|
||||||
|
func (c *STS) GetAccessKeyInfoRequest(input *GetAccessKeyInfoInput) (req *request.Request, output *GetAccessKeyInfoOutput) {
|
||||||
|
op := &request.Operation{
|
||||||
|
Name: opGetAccessKeyInfo,
|
||||||
|
HTTPMethod: "POST",
|
||||||
|
HTTPPath: "/",
|
||||||
|
}
|
||||||
|
|
||||||
|
if input == nil {
|
||||||
|
input = &GetAccessKeyInfoInput{}
|
||||||
|
}
|
||||||
|
|
||||||
|
output = &GetAccessKeyInfoOutput{}
|
||||||
|
req = c.newRequest(op, input, output)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAccessKeyInfo API operation for AWS Security Token Service.
|
||||||
|
//
|
||||||
|
// Returns the account identifier for the specified access key ID.
|
||||||
|
//
|
||||||
|
// Access keys consist of two parts: an access key ID (for example, AKIAIOSFODNN7EXAMPLE)
|
||||||
|
// and a secret access key (for example, wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY).
|
||||||
|
// For more information about access keys, see Managing Access Keys for IAM
|
||||||
|
// Users (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)
|
||||||
|
// in the IAM User Guide.
|
||||||
|
//
|
||||||
|
// When you pass an access key ID to this operation, it returns the ID of the
|
||||||
|
// AWS account to which the keys belong. Access key IDs beginning with AKIA
|
||||||
|
// are long-term credentials for an IAM user or the AWS account root user. Access
|
||||||
|
// key IDs beginning with ASIA are temporary credentials that are created using
|
||||||
|
// STS operations. If the account in the response belongs to you, you can sign
|
||||||
|
// in as the root user and review your root user access keys. Then, you can
|
||||||
|
// pull a credentials report (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_getting-report)
|
||||||
|
// to learn which IAM user owns the keys. To learn who requested the temporary
|
||||||
|
// credentials for an ASIA access key, view the STS events in your CloudTrail
|
||||||
|
// logs (https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration).
|
||||||
|
//
|
||||||
|
// This operation does not indicate the state of the access key. The key might
|
||||||
|
// be active, inactive, or deleted. Active keys might not have permissions to
|
||||||
|
// perform an operation. Providing a deleted keys might return an error that
|
||||||
|
// the key doesn't exist.
|
||||||
|
//
|
||||||
|
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
|
||||||
|
// with awserr.Error's Code and Message methods to get detailed information about
|
||||||
|
// the error.
|
||||||
|
//
|
||||||
|
// See the AWS API reference guide for AWS Security Token Service's
|
||||||
|
// API operation GetAccessKeyInfo for usage and error information.
|
||||||
|
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetAccessKeyInfo
|
||||||
|
func (c *STS) GetAccessKeyInfo(input *GetAccessKeyInfoInput) (*GetAccessKeyInfoOutput, error) {
|
||||||
|
req, out := c.GetAccessKeyInfoRequest(input)
|
||||||
|
return out, req.Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAccessKeyInfoWithContext is the same as GetAccessKeyInfo with the addition of
|
||||||
|
// the ability to pass a context and additional request options.
|
||||||
|
//
|
||||||
|
// See GetAccessKeyInfo for details on how to use this API operation.
|
||||||
|
//
|
||||||
|
// 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 *STS) GetAccessKeyInfoWithContext(ctx aws.Context, input *GetAccessKeyInfoInput, opts ...request.Option) (*GetAccessKeyInfoOutput, error) {
|
||||||
|
req, out := c.GetAccessKeyInfoRequest(input)
|
||||||
|
req.SetContext(ctx)
|
||||||
|
req.ApplyOptions(opts...)
|
||||||
|
return out, req.Send()
|
||||||
|
}
|
||||||
|
|
||||||
const opGetCallerIdentity = "GetCallerIdentity"
|
const opGetCallerIdentity = "GetCallerIdentity"
|
||||||
|
|
||||||
// GetCallerIdentityRequest generates a "aws/request.Request" representing the
|
// GetCallerIdentityRequest generates a "aws/request.Request" representing the
|
||||||
|
@ -1129,7 +1225,7 @@ type AssumeRoleInput struct {
|
||||||
// This parameter is optional. You can provide up to 10 managed policy ARNs.
|
// This parameter is optional. You can provide up to 10 managed policy ARNs.
|
||||||
// However, the plain text that you use for both inline and managed session
|
// However, the plain text that you use for both inline and managed session
|
||||||
// policies shouldn't exceed 2048 characters. For more information about ARNs,
|
// policies shouldn't exceed 2048 characters. For more information about ARNs,
|
||||||
// see Amazon Resource Names (ARNs) and AWS Service Namespaces (general/latest/gr/aws-arns-and-namespaces.html)
|
// see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
|
||||||
// in the AWS General Reference.
|
// in the AWS General Reference.
|
||||||
//
|
//
|
||||||
// The characters in this parameter count towards the 2048 character session
|
// The characters in this parameter count towards the 2048 character session
|
||||||
|
@ -1407,7 +1503,7 @@ type AssumeRoleWithSAMLInput struct {
|
||||||
// This parameter is optional. You can provide up to 10 managed policy ARNs.
|
// This parameter is optional. You can provide up to 10 managed policy ARNs.
|
||||||
// However, the plain text that you use for both inline and managed session
|
// However, the plain text that you use for both inline and managed session
|
||||||
// policies shouldn't exceed 2048 characters. For more information about ARNs,
|
// policies shouldn't exceed 2048 characters. For more information about ARNs,
|
||||||
// see Amazon Resource Names (ARNs) and AWS Service Namespaces (general/latest/gr/aws-arns-and-namespaces.html)
|
// see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
|
||||||
// in the AWS General Reference.
|
// in the AWS General Reference.
|
||||||
//
|
//
|
||||||
// The characters in this parameter count towards the 2048 character session
|
// The characters in this parameter count towards the 2048 character session
|
||||||
|
@ -1702,7 +1798,7 @@ type AssumeRoleWithWebIdentityInput struct {
|
||||||
// This parameter is optional. You can provide up to 10 managed policy ARNs.
|
// This parameter is optional. You can provide up to 10 managed policy ARNs.
|
||||||
// However, the plain text that you use for both inline and managed session
|
// However, the plain text that you use for both inline and managed session
|
||||||
// policies shouldn't exceed 2048 characters. For more information about ARNs,
|
// policies shouldn't exceed 2048 characters. For more information about ARNs,
|
||||||
// see Amazon Resource Names (ARNs) and AWS Service Namespaces (general/latest/gr/aws-arns-and-namespaces.html)
|
// see Amazon Resource Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
|
||||||
// in the AWS General Reference.
|
// in the AWS General Reference.
|
||||||
//
|
//
|
||||||
// The characters in this parameter count towards the 2048 character session
|
// The characters in this parameter count towards the 2048 character session
|
||||||
|
@ -2156,6 +2252,73 @@ func (s *FederatedUser) SetFederatedUserId(v string) *FederatedUser {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetAccessKeyInfoInput struct {
|
||||||
|
_ struct{} `type:"structure"`
|
||||||
|
|
||||||
|
// The identifier of an access key.
|
||||||
|
//
|
||||||
|
// This parameter allows (through its regex pattern) a string of characters
|
||||||
|
// that can consist of any upper- or lowercased letter or digit.
|
||||||
|
//
|
||||||
|
// AccessKeyId is a required field
|
||||||
|
AccessKeyId *string `min:"16" type:"string" required:"true"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation
|
||||||
|
func (s GetAccessKeyInfoInput) String() string {
|
||||||
|
return awsutil.Prettify(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GoString returns the string representation
|
||||||
|
func (s GetAccessKeyInfoInput) GoString() string {
|
||||||
|
return s.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate inspects the fields of the type to determine if they are valid.
|
||||||
|
func (s *GetAccessKeyInfoInput) Validate() error {
|
||||||
|
invalidParams := request.ErrInvalidParams{Context: "GetAccessKeyInfoInput"}
|
||||||
|
if s.AccessKeyId == nil {
|
||||||
|
invalidParams.Add(request.NewErrParamRequired("AccessKeyId"))
|
||||||
|
}
|
||||||
|
if s.AccessKeyId != nil && len(*s.AccessKeyId) < 16 {
|
||||||
|
invalidParams.Add(request.NewErrParamMinLen("AccessKeyId", 16))
|
||||||
|
}
|
||||||
|
|
||||||
|
if invalidParams.Len() > 0 {
|
||||||
|
return invalidParams
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAccessKeyId sets the AccessKeyId field's value.
|
||||||
|
func (s *GetAccessKeyInfoInput) SetAccessKeyId(v string) *GetAccessKeyInfoInput {
|
||||||
|
s.AccessKeyId = &v
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetAccessKeyInfoOutput struct {
|
||||||
|
_ struct{} `type:"structure"`
|
||||||
|
|
||||||
|
// The number used to identify the AWS account.
|
||||||
|
Account *string `type:"string"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation
|
||||||
|
func (s GetAccessKeyInfoOutput) String() string {
|
||||||
|
return awsutil.Prettify(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GoString returns the string representation
|
||||||
|
func (s GetAccessKeyInfoOutput) GoString() string {
|
||||||
|
return s.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetAccount sets the Account field's value.
|
||||||
|
func (s *GetAccessKeyInfoOutput) SetAccount(v string) *GetAccessKeyInfoOutput {
|
||||||
|
s.Account = &v
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
type GetCallerIdentityInput struct {
|
type GetCallerIdentityInput struct {
|
||||||
_ struct{} `type:"structure"`
|
_ struct{} `type:"structure"`
|
||||||
}
|
}
|
||||||
|
@ -2545,7 +2708,7 @@ type PolicyDescriptorType struct {
|
||||||
|
|
||||||
// The Amazon Resource Name (ARN) of the IAM managed policy to use as a session
|
// The Amazon Resource Name (ARN) of the IAM managed policy to use as a session
|
||||||
// policy for the role. For more information about ARNs, see Amazon Resource
|
// policy for the role. For more information about ARNs, see Amazon Resource
|
||||||
// Names (ARNs) and AWS Service Namespaces (general/latest/gr/aws-arns-and-namespaces.html)
|
// Names (ARNs) and AWS Service Namespaces (https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
|
||||||
// in the AWS General Reference.
|
// in the AWS General Reference.
|
||||||
Arn *string `locationName:"arn" min:"20" type:"string"`
|
Arn *string `locationName:"arn" min:"20" type:"string"`
|
||||||
}
|
}
|
||||||
|
|
96
vendor/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go
generated
vendored
Normal file
96
vendor/github.com/aws/aws-sdk-go/service/sts/stsiface/interface.go
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Package stsiface provides an interface to enable mocking the AWS Security Token Service service client
|
||||||
|
// for testing your code.
|
||||||
|
//
|
||||||
|
// It is important to note that this interface will have breaking changes
|
||||||
|
// when the service model is updated and adds new API operations, paginators,
|
||||||
|
// and waiters.
|
||||||
|
package stsiface
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/service/sts"
|
||||||
|
)
|
||||||
|
|
||||||
|
// STSAPI provides an interface to enable mocking the
|
||||||
|
// sts.STS service client's API operation,
|
||||||
|
// paginators, and waiters. This make unit testing your code that calls out
|
||||||
|
// to the SDK's service client's calls easier.
|
||||||
|
//
|
||||||
|
// The best way to use this interface is so the SDK's service client's calls
|
||||||
|
// can be stubbed out for unit testing your code with the SDK without needing
|
||||||
|
// to inject custom request handlers into the SDK's request pipeline.
|
||||||
|
//
|
||||||
|
// // myFunc uses an SDK service client to make a request to
|
||||||
|
// // AWS Security Token Service.
|
||||||
|
// func myFunc(svc stsiface.STSAPI) bool {
|
||||||
|
// // Make svc.AssumeRole request
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func main() {
|
||||||
|
// sess := session.New()
|
||||||
|
// svc := sts.New(sess)
|
||||||
|
//
|
||||||
|
// myFunc(svc)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// In your _test.go file:
|
||||||
|
//
|
||||||
|
// // Define a mock struct to be used in your unit tests of myFunc.
|
||||||
|
// type mockSTSClient struct {
|
||||||
|
// stsiface.STSAPI
|
||||||
|
// }
|
||||||
|
// func (m *mockSTSClient) AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) {
|
||||||
|
// // mock response/functionality
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func TestMyFunc(t *testing.T) {
|
||||||
|
// // Setup Test
|
||||||
|
// mockSvc := &mockSTSClient{}
|
||||||
|
//
|
||||||
|
// myfunc(mockSvc)
|
||||||
|
//
|
||||||
|
// // Verify myFunc's functionality
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// It is important to note that this interface will have breaking changes
|
||||||
|
// when the service model is updated and adds new API operations, paginators,
|
||||||
|
// and waiters. Its suggested to use the pattern above for testing, or using
|
||||||
|
// tooling to generate mocks to satisfy the interfaces.
|
||||||
|
type STSAPI interface {
|
||||||
|
AssumeRole(*sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
|
||||||
|
AssumeRoleWithContext(aws.Context, *sts.AssumeRoleInput, ...request.Option) (*sts.AssumeRoleOutput, error)
|
||||||
|
AssumeRoleRequest(*sts.AssumeRoleInput) (*request.Request, *sts.AssumeRoleOutput)
|
||||||
|
|
||||||
|
AssumeRoleWithSAML(*sts.AssumeRoleWithSAMLInput) (*sts.AssumeRoleWithSAMLOutput, error)
|
||||||
|
AssumeRoleWithSAMLWithContext(aws.Context, *sts.AssumeRoleWithSAMLInput, ...request.Option) (*sts.AssumeRoleWithSAMLOutput, error)
|
||||||
|
AssumeRoleWithSAMLRequest(*sts.AssumeRoleWithSAMLInput) (*request.Request, *sts.AssumeRoleWithSAMLOutput)
|
||||||
|
|
||||||
|
AssumeRoleWithWebIdentity(*sts.AssumeRoleWithWebIdentityInput) (*sts.AssumeRoleWithWebIdentityOutput, error)
|
||||||
|
AssumeRoleWithWebIdentityWithContext(aws.Context, *sts.AssumeRoleWithWebIdentityInput, ...request.Option) (*sts.AssumeRoleWithWebIdentityOutput, error)
|
||||||
|
AssumeRoleWithWebIdentityRequest(*sts.AssumeRoleWithWebIdentityInput) (*request.Request, *sts.AssumeRoleWithWebIdentityOutput)
|
||||||
|
|
||||||
|
DecodeAuthorizationMessage(*sts.DecodeAuthorizationMessageInput) (*sts.DecodeAuthorizationMessageOutput, error)
|
||||||
|
DecodeAuthorizationMessageWithContext(aws.Context, *sts.DecodeAuthorizationMessageInput, ...request.Option) (*sts.DecodeAuthorizationMessageOutput, error)
|
||||||
|
DecodeAuthorizationMessageRequest(*sts.DecodeAuthorizationMessageInput) (*request.Request, *sts.DecodeAuthorizationMessageOutput)
|
||||||
|
|
||||||
|
GetAccessKeyInfo(*sts.GetAccessKeyInfoInput) (*sts.GetAccessKeyInfoOutput, error)
|
||||||
|
GetAccessKeyInfoWithContext(aws.Context, *sts.GetAccessKeyInfoInput, ...request.Option) (*sts.GetAccessKeyInfoOutput, error)
|
||||||
|
GetAccessKeyInfoRequest(*sts.GetAccessKeyInfoInput) (*request.Request, *sts.GetAccessKeyInfoOutput)
|
||||||
|
|
||||||
|
GetCallerIdentity(*sts.GetCallerIdentityInput) (*sts.GetCallerIdentityOutput, error)
|
||||||
|
GetCallerIdentityWithContext(aws.Context, *sts.GetCallerIdentityInput, ...request.Option) (*sts.GetCallerIdentityOutput, error)
|
||||||
|
GetCallerIdentityRequest(*sts.GetCallerIdentityInput) (*request.Request, *sts.GetCallerIdentityOutput)
|
||||||
|
|
||||||
|
GetFederationToken(*sts.GetFederationTokenInput) (*sts.GetFederationTokenOutput, error)
|
||||||
|
GetFederationTokenWithContext(aws.Context, *sts.GetFederationTokenInput, ...request.Option) (*sts.GetFederationTokenOutput, error)
|
||||||
|
GetFederationTokenRequest(*sts.GetFederationTokenInput) (*request.Request, *sts.GetFederationTokenOutput)
|
||||||
|
|
||||||
|
GetSessionToken(*sts.GetSessionTokenInput) (*sts.GetSessionTokenOutput, error)
|
||||||
|
GetSessionTokenWithContext(aws.Context, *sts.GetSessionTokenInput, ...request.Option) (*sts.GetSessionTokenOutput, error)
|
||||||
|
GetSessionTokenRequest(*sts.GetSessionTokenInput) (*request.Request, *sts.GetSessionTokenOutput)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ STSAPI = (*sts.STS)(nil)
|
|
@ -59,6 +59,7 @@ func NewConstraint(v string) (Constraints, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
result[i] = c
|
result[i] = c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.20.19
|
# github.com/aws/aws-sdk-go v1.21.7
|
||||||
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
|
||||||
|
@ -115,6 +115,7 @@ 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/internal/sdkuri
|
github.com/aws/aws-sdk-go/internal/sdkuri
|
||||||
|
github.com/aws/aws-sdk-go/service/sts/stsiface
|
||||||
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
|
||||||
github.com/aws/aws-sdk-go/aws/credentials/processcreds
|
github.com/aws/aws-sdk-go/aws/credentials/processcreds
|
||||||
|
|
Loading…
Reference in New Issue