awslogs: Update aws-sdk-go to support IMDSv2
AWS recently launched a new version of the EC2 Instance Metadata
Service, which is used to provide credentials to the awslogs driver when
running on Amazon EC2. This new version of the IMDS adds
defense-in-depth mechanisms against open firewalls, reverse proxies, and
SSRF vulnerabilities and is generally an improvement over the previous
version. An updated version of the AWS SDK is able to handle the both
the previous version and the new version of the IMDS and functions when
either is enabled.
More information about IMDSv2 is available at the following links:
* https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/
* https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html
Closes https://github.com/moby/moby/issues/40422
Signed-off-by: Samuel Karp <skarp@amazon.com>
(cherry picked from commit 44a8e10bfc
)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
bd33bbf049
commit
5f32bd9ced
150 changed files with 16548 additions and 6537 deletions
|
@ -101,9 +101,8 @@ github.com/tinylib/msgp af6442a0fcf6e2a1b824f70dd0c7
|
|||
github.com/fsnotify/fsnotify 1485a34d5d5723fea214f5710708e19a831720e4 # v1.4.7-11-g1485a34
|
||||
|
||||
# awslogs deps
|
||||
github.com/aws/aws-sdk-go 9ed0c8de252f04ac45a65358377103d5a1aa2d92 # v1.12.66
|
||||
github.com/go-ini/ini 300e940a926eb277d3901b20bdfcc54928ad3642 # v1.25.4
|
||||
github.com/jmespath/go-jmespath 0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74
|
||||
github.com/aws/aws-sdk-go 2590bc875c54c9fda225d8e4e56a9d28d90c6a47 # v1.28.11
|
||||
github.com/jmespath/go-jmespath c2b33e8439af944379acbdd9c3a5fe0bc44bd8a5 # see https://github.com/aws/aws-sdk-go/blob/2590bc875c54c9fda225d8e4e56a9d28d90c6a47/Gopkg.toml#L42
|
||||
|
||||
# logentries
|
||||
github.com/bsphere/le_go 7a984a84b5492ae539b79b62fb4a10afc63c7bcf
|
||||
|
|
2
vendor/github.com/aws/aws-sdk-go/NOTICE.txt
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/NOTICE.txt
generated
vendored
|
@ -1,3 +1,3 @@
|
|||
AWS SDK for Go
|
||||
Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
Copyright 2014-2015 Stripe, Inc.
|
||||
|
|
95
vendor/github.com/aws/aws-sdk-go/README.md
generated
vendored
95
vendor/github.com/aws/aws-sdk-go/README.md
generated
vendored
|
@ -1,35 +1,61 @@
|
|||
[![API Reference](http://img.shields.io/badge/api-reference-blue.svg)](http://docs.aws.amazon.com/sdk-for-go/api) [![Join the chat at https://gitter.im/aws/aws-sdk-go](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aws/aws-sdk-go?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://img.shields.io/travis/aws/aws-sdk-go.svg)](https://travis-ci.org/aws/aws-sdk-go) [![Apache V2 License](http://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt)
|
||||
[![API Reference](https://img.shields.io/badge/api-reference-blue.svg)](https://docs.aws.amazon.com/sdk-for-go/api) [![Join the chat at https://gitter.im/aws/aws-sdk-go](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aws/aws-sdk-go?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://img.shields.io/travis/aws/aws-sdk-go.svg)](https://travis-ci.org/aws/aws-sdk-go) [![Apache V2 License](https://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt)
|
||||
|
||||
# AWS SDK for Go
|
||||
|
||||
aws-sdk-go is the official AWS SDK for the Go programming language.
|
||||
|
||||
Checkout our [release notes](https://github.com/aws/aws-sdk-go/releases) for information about the latest bug fixes, updates, and features added to the SDK.
|
||||
Checkout our [release notes](https://github.com/aws/aws-sdk-go/releases) for
|
||||
information about the latest bug fixes, updates, and features added to the SDK.
|
||||
|
||||
We [announced](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-2-0-developer-preview/) the Developer Preview for the [v2 AWS SDK for Go](). The v2 SDK is available at https://github.com/aws/aws-sdk-go-v2, and `go get github.com/aws/aws-sdk-go-v2` via `go get`. Check out the v2 SDK's [changes and updates](https://github.com/aws/aws-sdk-go-v2/blob/master/CHANGELOG.md), and let us know what you think. We want your feedback.
|
||||
We [announced](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-2-0-developer-preview/) the Developer Preview for the [v2 AWS SDK for Go](https://github.com/aws/aws-sdk-go-v2). The v2 SDK source is available at https://github.com/aws/aws-sdk-go-v2, and add it to your project with `go get github.com/aws/aws-sdk-go-v2`. Check out the v2 SDK's [changes and updates](https://github.com/aws/aws-sdk-go-v2/blob/master/CHANGELOG.md), and let us know what you think. We want your feedback.
|
||||
|
||||
We have a pilot redesign of the [AWS SDK for Go API reference documentation](https://docs.aws.amazon.com/sdk-for-go/v1/api/gosdk-apiref.html). Let us know what you think.
|
||||
|
||||
## Installing
|
||||
|
||||
If you are using Go 1.5 with the `GO15VENDOREXPERIMENT=1` vendoring flag, or 1.6 and higher you can use the following command to retrieve the SDK. The SDK's non-testing dependencies will be included and are vendored in the `vendor` folder.
|
||||
Use `go get` to retrieve the SDK to add it to your `GOPATH` workspace, or
|
||||
project's Go module dependencies.
|
||||
|
||||
go get -u github.com/aws/aws-sdk-go
|
||||
go get github.com/aws/aws-sdk-go
|
||||
|
||||
Otherwise if your Go environment does not have vendoring support enabled, or you do not want to include the vendored SDK's dependencies you can use the following command to retrieve the SDK and its non-testing dependencies using `go get`.
|
||||
To update the SDK use `go get -u` to retrieve the latest version of the SDK.
|
||||
|
||||
go get -u github.com/aws/aws-sdk-go/aws/...
|
||||
go get -u github.com/aws/aws-sdk-go/service/...
|
||||
go get -u github.com/aws/aws-sdk-go
|
||||
|
||||
If you're looking to retrieve just the SDK without any dependencies use the following command.
|
||||
### Dependencies
|
||||
|
||||
go get -d github.com/aws/aws-sdk-go/
|
||||
The SDK includes a `vendor` folder containing the runtime dependencies of the
|
||||
SDK. The metadata of the SDK's dependencies can be found in the Go module file
|
||||
`go.mod` or Dep file `Gopkg.toml`.
|
||||
|
||||
These two processes will still include the `vendor` folder and it should be deleted if its not going to be used by your environment.
|
||||
### Go Modules
|
||||
|
||||
If you are using Go modules, your `go get` will default to the latest tagged
|
||||
release version of the SDK. To get a specific release version of the SDK use
|
||||
`@<tag>` in your `go get` command.
|
||||
|
||||
go get github.com/aws/aws-sdk-go@v1.15.77
|
||||
|
||||
To get the latest SDK repository change use `@latest`.
|
||||
|
||||
go get github.com/aws/aws-sdk-go@latest
|
||||
|
||||
### Go 1.5
|
||||
|
||||
If you are using Go 1.5 without vendoring enabled, (`GO15VENDOREXPERIMENT=1`),
|
||||
you will need to use `...` when retrieving the SDK to get its dependencies.
|
||||
|
||||
go get github.com/aws/aws-sdk-go/...
|
||||
|
||||
This will still include the `vendor` folder. The `vendor` folder can be deleted
|
||||
if not used by your environment.
|
||||
|
||||
rm -rf $GOPATH/src/github.com/aws/aws-sdk-go/vendor
|
||||
|
||||
## Getting Help
|
||||
|
||||
Please use these community resources for getting help. We use the GitHub issues for tracking bugs and feature requests.
|
||||
Please use these community resources for getting help. We use the GitHub issues
|
||||
for tracking bugs and feature requests.
|
||||
|
||||
* Ask a question on [StackOverflow](http://stackoverflow.com/) and tag it with the [`aws-sdk-go`](http://stackoverflow.com/questions/tagged/aws-sdk-go) tag.
|
||||
* Come join the AWS SDK for Go community chat on [gitter](https://gitter.im/aws/aws-sdk-go).
|
||||
|
@ -38,19 +64,43 @@ Please use these community resources for getting help. We use the GitHub issues
|
|||
|
||||
## Opening Issues
|
||||
|
||||
If you encounter a bug with the AWS SDK for Go we would like to hear about it. Search the [existing issues](https://github.com/aws/aws-sdk-go/issues) and see if others are also experiencing the issue before opening a new issue. Please include the version of AWS SDK for Go, Go language, and OS you’re using. Please also include repro case when appropriate.
|
||||
If you encounter a bug with the AWS SDK for Go we would like to hear about it.
|
||||
Search the [existing issues](https://github.com/aws/aws-sdk-go/issues) and see
|
||||
if others are also experiencing the issue before opening a new issue. Please
|
||||
include the version of AWS SDK for Go, Go language, and OS you’re using. Please
|
||||
also include reproduction case when appropriate.
|
||||
|
||||
The GitHub issues are intended for bug reports and feature requests. For help and questions with using AWS SDK for GO please make use of the resources listed in the [Getting Help](https://github.com/aws/aws-sdk-go#getting-help) section. Keeping the list of open issues lean will help us respond in a timely manner.
|
||||
The GitHub issues are intended for bug reports and feature requests. For help
|
||||
and questions with using AWS SDK for GO please make use of the resources listed
|
||||
in the [Getting Help](https://github.com/aws/aws-sdk-go#getting-help) section.
|
||||
Keeping the list of open issues lean will help us respond in a timely manner.
|
||||
|
||||
## Reference Documentation
|
||||
|
||||
[`Getting Started Guide`](https://aws.amazon.com/sdk-for-go/) - This document is a general introduction how to configure and make requests with the SDK. If this is your first time using the SDK, this documentation and the API documentation will help you get started. This document focuses on the syntax and behavior of the SDK. The [Service Developer Guide](https://aws.amazon.com/documentation/) will help you get started using specific AWS services.
|
||||
[`Getting Started Guide`](https://aws.amazon.com/sdk-for-go/) - This document
|
||||
is a general introduction on how to configure and make requests with the SDK.
|
||||
If this is your first time using the SDK, this documentation and the API
|
||||
documentation will help you get started. This document focuses on the syntax
|
||||
and behavior of the SDK. The [Service Developer
|
||||
Guide](https://aws.amazon.com/documentation/) will help you get started using
|
||||
specific AWS services.
|
||||
|
||||
[`SDK API Reference Documentation`](https://docs.aws.amazon.com/sdk-for-go/api/) - Use this document to look up all API operation input and output parameters for AWS services supported by the SDK. The API reference also includes documentation of the SDK, and examples how to using the SDK, service client API operations, and API operation require parameters.
|
||||
[`SDK API Reference
|
||||
Documentation`](https://docs.aws.amazon.com/sdk-for-go/api/) - Use this
|
||||
document to look up all API operation input and output parameters for AWS
|
||||
services supported by the SDK. The API reference also includes documentation of
|
||||
the SDK, and examples how to using the SDK, service client API operations, and
|
||||
API operation require parameters.
|
||||
|
||||
[`Service Developer Guide`](https://aws.amazon.com/documentation/) - Use this documentation to learn how to interface with an AWS service. These are great guides both, if you're getting started with a service, or looking for more information on a service. You should not need this document for coding, though in some cases, services may supply helpful samples that you might want to look out for.
|
||||
[`Service Developer Guide`](https://aws.amazon.com/documentation/) - Use this
|
||||
documentation to learn how to interface with AWS services. These guides are
|
||||
great for getting started with a service, or when looking for more
|
||||
information about a service. While this document is not required for coding,
|
||||
services may supply helpful samples to look out for.
|
||||
|
||||
[`SDK Examples`](https://github.com/aws/aws-sdk-go/tree/master/example) - Included in the SDK's repo are a several hand crafted examples using the SDK features and AWS services.
|
||||
[`SDK Examples`](https://github.com/aws/aws-sdk-go/tree/master/example) -
|
||||
Included in the SDK's repo are several hand crafted examples using the SDK
|
||||
features and AWS services.
|
||||
|
||||
## Overview of SDK's Packages
|
||||
|
||||
|
@ -94,8 +144,7 @@ package under the service folder at the root of the SDK.
|
|||
|
||||
The SDK includes the Go types and utilities you can use to make requests to
|
||||
AWS service APIs. Within the service folder at the root of the SDK you'll find
|
||||
a package for each AWS service the SDK supports. All service clients follows
|
||||
a common pattern of creation and usage.
|
||||
a package for each AWS service the SDK supports. All service clients follow common pattern of creation and usage.
|
||||
|
||||
When creating a client for an AWS service you'll first need to have a Session
|
||||
value constructed. The Session provides shared configuration that can be shared
|
||||
|
@ -334,7 +383,7 @@ take a callback function that will be called for each page of the API's response
|
|||
```
|
||||
|
||||
Waiter helper methods provide the functionality to wait for an AWS resource
|
||||
state. These methods abstract the logic needed to to check the state of an
|
||||
state. These methods abstract the logic needed to check the state of an
|
||||
AWS resource, and wait until that resource is in a desired state. The waiter
|
||||
will block until the resource is in the state that is desired, an error occurs,
|
||||
or the waiter times out. If a resource times out the error code returned will
|
||||
|
@ -420,7 +469,9 @@ response.
|
|||
}
|
||||
// Ensure the context is canceled to prevent leaking.
|
||||
// See context package for more information, https://golang.org/pkg/context/
|
||||
defer cancelFn()
|
||||
if cancelFn != nil {
|
||||
defer cancelFn()
|
||||
}
|
||||
|
||||
// Uploads the object to S3. The Context will interrupt the request if the
|
||||
// timeout expires.
|
||||
|
|
23
vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go
generated
vendored
23
vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go
generated
vendored
|
@ -138,8 +138,27 @@ type RequestFailure interface {
|
|||
RequestID() string
|
||||
}
|
||||
|
||||
// NewRequestFailure returns a new request error wrapper for the given Error
|
||||
// provided.
|
||||
// NewRequestFailure returns a wrapped error with additional information for
|
||||
// request status code, and service requestID.
|
||||
//
|
||||
// Should be used to wrap all request which involve service requests. Even if
|
||||
// the request failed without a service response, but had an HTTP status code
|
||||
// that may be meaningful.
|
||||
func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure {
|
||||
return newRequestError(err, statusCode, reqID)
|
||||
}
|
||||
|
||||
// UnmarshalError provides the interface for the SDK failing to unmarshal data.
|
||||
type UnmarshalError interface {
|
||||
awsError
|
||||
Bytes() []byte
|
||||
}
|
||||
|
||||
// NewUnmarshalError returns an initialized UnmarshalError error wrapper adding
|
||||
// the bytes that fail to unmarshal to the error.
|
||||
func NewUnmarshalError(err error, msg string, bytes []byte) UnmarshalError {
|
||||
return &unmarshalError{
|
||||
awsError: New("UnmarshalError", msg, err),
|
||||
bytes: bytes,
|
||||
}
|
||||
}
|
||||
|
|
31
vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go
generated
vendored
31
vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go
generated
vendored
|
@ -1,6 +1,9 @@
|
|||
package awserr
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// SprintError returns a string of the formatted error code.
|
||||
//
|
||||
|
@ -119,6 +122,7 @@ type requestError struct {
|
|||
awsError
|
||||
statusCode int
|
||||
requestID string
|
||||
bytes []byte
|
||||
}
|
||||
|
||||
// newRequestError returns a wrapped error with additional information for
|
||||
|
@ -170,6 +174,29 @@ func (r requestError) OrigErrs() []error {
|
|||
return []error{r.OrigErr()}
|
||||
}
|
||||
|
||||
type unmarshalError struct {
|
||||
awsError
|
||||
bytes []byte
|
||||
}
|
||||
|
||||
// Error returns the string representation of the error.
|
||||
// Satisfies the error interface.
|
||||
func (e unmarshalError) Error() string {
|
||||
extra := hex.Dump(e.bytes)
|
||||
return SprintError(e.Code(), e.Message(), extra, e.OrigErr())
|
||||
}
|
||||
|
||||
// String returns the string representation of the error.
|
||||
// Alias for Error to satisfy the stringer interface.
|
||||
func (e unmarshalError) String() string {
|
||||
return e.Error()
|
||||
}
|
||||
|
||||
// Bytes returns the bytes that failed to unmarshal.
|
||||
func (e unmarshalError) Bytes() []byte {
|
||||
return e.bytes
|
||||
}
|
||||
|
||||
// An error list that satisfies the golang interface
|
||||
type errorList []error
|
||||
|
||||
|
@ -181,7 +208,7 @@ func (e errorList) Error() string {
|
|||
// How do we want to handle the array size being zero
|
||||
if size := len(e); size > 0 {
|
||||
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.
|
||||
// If it is, then we append a newline. We do this, because unit tests
|
||||
// could be broken with the additional '\n'
|
||||
|
|
2
vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
generated
vendored
|
@ -15,7 +15,7 @@ func DeepEqual(a, b interface{}) bool {
|
|||
rb := reflect.Indirect(reflect.ValueOf(b))
|
||||
|
||||
if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid {
|
||||
// If the elements are both nil, and of the same type the are equal
|
||||
// If the elements are both nil, and of the same type they are equal
|
||||
// If they are of different types they are not equal
|
||||
return reflect.TypeOf(a) == reflect.TypeOf(b)
|
||||
} else if raValid != rbValid {
|
||||
|
|
13
vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
13
vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
|
@ -70,7 +70,7 @@ func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTer
|
|||
value = value.FieldByNameFunc(func(name string) bool {
|
||||
if c == name {
|
||||
return true
|
||||
} else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) {
|
||||
} else if !caseSensitive && strings.EqualFold(name, c) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -185,13 +185,12 @@ func ValuesAtPath(i interface{}, path string) ([]interface{}, error) {
|
|||
// SetValueAtPath sets a value at the case insensitive lexical path inside
|
||||
// of a structure.
|
||||
func SetValueAtPath(i interface{}, path string, v interface{}) {
|
||||
if rvals := rValuesAtPath(i, path, true, false, v == nil); rvals != nil {
|
||||
for _, rval := range rvals {
|
||||
if rval.Kind() == reflect.Ptr && rval.IsNil() {
|
||||
continue
|
||||
}
|
||||
setValue(rval, v)
|
||||
rvals := rValuesAtPath(i, path, true, false, v == nil)
|
||||
for _, rval := range rvals {
|
||||
if rval.Kind() == reflect.Ptr && rval.IsNil() {
|
||||
continue
|
||||
}
|
||||
setValue(rval, v)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
25
vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
generated
vendored
25
vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
generated
vendored
|
@ -23,28 +23,27 @@ func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) {
|
|||
case reflect.Struct:
|
||||
buf.WriteString("{\n")
|
||||
|
||||
names := []string{}
|
||||
for i := 0; i < v.Type().NumField(); i++ {
|
||||
name := v.Type().Field(i).Name
|
||||
f := v.Field(i)
|
||||
if name[0:1] == strings.ToLower(name[0:1]) {
|
||||
ft := v.Type().Field(i)
|
||||
fv := v.Field(i)
|
||||
|
||||
if ft.Name[0:1] == strings.ToLower(ft.Name[0:1]) {
|
||||
continue // ignore unexported fields
|
||||
}
|
||||
if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice) && f.IsNil() {
|
||||
if (fv.Kind() == reflect.Ptr || fv.Kind() == reflect.Slice) && fv.IsNil() {
|
||||
continue // ignore unset fields
|
||||
}
|
||||
names = append(names, name)
|
||||
}
|
||||
|
||||
for i, n := range names {
|
||||
val := v.FieldByName(n)
|
||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
||||
buf.WriteString(n + ": ")
|
||||
stringValue(val, indent+2, buf)
|
||||
buf.WriteString(ft.Name + ": ")
|
||||
|
||||
if i < len(names)-1 {
|
||||
buf.WriteString(",\n")
|
||||
if tag := ft.Tag.Get("sensitive"); tag == "true" {
|
||||
buf.WriteString("<sensitive>")
|
||||
} else {
|
||||
stringValue(fv, indent+2, buf)
|
||||
}
|
||||
|
||||
buf.WriteString(",\n")
|
||||
}
|
||||
|
||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
||||
|
|
13
vendor/github.com/aws/aws-sdk-go/aws/client/client.go
generated
vendored
13
vendor/github.com/aws/aws-sdk-go/aws/client/client.go
generated
vendored
|
@ -12,9 +12,16 @@ import (
|
|||
type Config struct {
|
||||
Config *aws.Config
|
||||
Handlers request.Handlers
|
||||
PartitionID string
|
||||
Endpoint string
|
||||
SigningRegion string
|
||||
SigningName string
|
||||
|
||||
// States that the signing name did not come from a modeled source but
|
||||
// was derived based on other data. Used by service client constructors
|
||||
// to determine if the signin name can be overridden based on metadata the
|
||||
// service has.
|
||||
SigningNameDerived bool
|
||||
}
|
||||
|
||||
// ConfigProvider provides a generic way for a service client to receive
|
||||
|
@ -58,7 +65,7 @@ func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, op
|
|||
default:
|
||||
maxRetries := aws.IntValue(cfg.MaxRetries)
|
||||
if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries {
|
||||
maxRetries = 3
|
||||
maxRetries = DefaultRetryerMaxNumRetries
|
||||
}
|
||||
svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries}
|
||||
}
|
||||
|
@ -85,6 +92,6 @@ func (c *Client) AddDebugHandlers() {
|
|||
return
|
||||
}
|
||||
|
||||
c.Handlers.Send.PushFrontNamed(request.NamedHandler{Name: "awssdk.client.LogRequest", Fn: logRequest})
|
||||
c.Handlers.Send.PushBackNamed(request.NamedHandler{Name: "awssdk.client.LogResponse", Fn: logResponse})
|
||||
c.Handlers.Send.PushFrontNamed(LogHTTPRequestHandler)
|
||||
c.Handlers.Send.PushBackNamed(LogHTTPResponseHandler)
|
||||
}
|
||||
|
|
171
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
171
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
|
@ -1,93 +1,151 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"math"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/internal/sdkrand"
|
||||
)
|
||||
|
||||
// DefaultRetryer implements basic retry logic using exponential backoff for
|
||||
// most services. If you want to implement custom retry logic, implement the
|
||||
// request.Retryer interface or create a structure type that composes this
|
||||
// struct and override the specific methods. For example, to override only
|
||||
// the MaxRetries method:
|
||||
// most services. If you want to implement custom retry logic, you can implement the
|
||||
// request.Retryer interface.
|
||||
//
|
||||
// type retryer struct {
|
||||
// client.DefaultRetryer
|
||||
// }
|
||||
//
|
||||
// // This implementation always has 100 max retries
|
||||
// func (d retryer) MaxRetries() int { return 100 }
|
||||
type DefaultRetryer struct {
|
||||
// Num max Retries is the number of max retries that will be performed.
|
||||
// By default, this is zero.
|
||||
NumMaxRetries int
|
||||
|
||||
// MinRetryDelay is the minimum retry delay after which retry will be performed.
|
||||
// If not set, the value is 0ns.
|
||||
MinRetryDelay time.Duration
|
||||
|
||||
// MinThrottleRetryDelay is the minimum retry delay when throttled.
|
||||
// If not set, the value is 0ns.
|
||||
MinThrottleDelay time.Duration
|
||||
|
||||
// MaxRetryDelay is the maximum retry delay before which retry must be performed.
|
||||
// If not set, the value is 0ns.
|
||||
MaxRetryDelay time.Duration
|
||||
|
||||
// MaxThrottleDelay is the maximum retry delay when throttled.
|
||||
// If not set, the value is 0ns.
|
||||
MaxThrottleDelay time.Duration
|
||||
}
|
||||
|
||||
const (
|
||||
// DefaultRetryerMaxNumRetries sets maximum number of retries
|
||||
DefaultRetryerMaxNumRetries = 3
|
||||
|
||||
// DefaultRetryerMinRetryDelay sets minimum retry delay
|
||||
DefaultRetryerMinRetryDelay = 30 * time.Millisecond
|
||||
|
||||
// DefaultRetryerMinThrottleDelay sets minimum delay when throttled
|
||||
DefaultRetryerMinThrottleDelay = 500 * time.Millisecond
|
||||
|
||||
// DefaultRetryerMaxRetryDelay sets maximum retry delay
|
||||
DefaultRetryerMaxRetryDelay = 300 * time.Second
|
||||
|
||||
// DefaultRetryerMaxThrottleDelay sets maximum delay when throttled
|
||||
DefaultRetryerMaxThrottleDelay = 300 * time.Second
|
||||
)
|
||||
|
||||
// MaxRetries returns the number of maximum returns the service will use to make
|
||||
// an individual API request.
|
||||
func (d DefaultRetryer) MaxRetries() int {
|
||||
return d.NumMaxRetries
|
||||
}
|
||||
|
||||
var seededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())})
|
||||
// setRetryerDefaults sets the default values of the retryer if not set
|
||||
func (d *DefaultRetryer) setRetryerDefaults() {
|
||||
if d.MinRetryDelay == 0 {
|
||||
d.MinRetryDelay = DefaultRetryerMinRetryDelay
|
||||
}
|
||||
if d.MaxRetryDelay == 0 {
|
||||
d.MaxRetryDelay = DefaultRetryerMaxRetryDelay
|
||||
}
|
||||
if d.MinThrottleDelay == 0 {
|
||||
d.MinThrottleDelay = DefaultRetryerMinThrottleDelay
|
||||
}
|
||||
if d.MaxThrottleDelay == 0 {
|
||||
d.MaxThrottleDelay = DefaultRetryerMaxThrottleDelay
|
||||
}
|
||||
}
|
||||
|
||||
// RetryRules returns the delay duration before retrying this request again
|
||||
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
|
||||
// Set the upper limit of delay in retrying at ~five minutes
|
||||
minTime := 30
|
||||
throttle := d.shouldThrottle(r)
|
||||
if throttle {
|
||||
if delay, ok := getRetryDelay(r); ok {
|
||||
return delay
|
||||
}
|
||||
|
||||
minTime = 500
|
||||
// if number of max retries is zero, no retries will be performed.
|
||||
if d.NumMaxRetries == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Sets default value for retryer members
|
||||
d.setRetryerDefaults()
|
||||
|
||||
// minDelay is the minimum retryer delay
|
||||
minDelay := d.MinRetryDelay
|
||||
|
||||
var initialDelay time.Duration
|
||||
|
||||
isThrottle := r.IsErrorThrottle()
|
||||
if isThrottle {
|
||||
if delay, ok := getRetryAfterDelay(r); ok {
|
||||
initialDelay = delay
|
||||
}
|
||||
minDelay = d.MinThrottleDelay
|
||||
}
|
||||
|
||||
retryCount := r.RetryCount
|
||||
if throttle && retryCount > 8 {
|
||||
retryCount = 8
|
||||
} else if retryCount > 13 {
|
||||
retryCount = 13
|
||||
|
||||
// maxDelay the maximum retryer delay
|
||||
maxDelay := d.MaxRetryDelay
|
||||
|
||||
if isThrottle {
|
||||
maxDelay = d.MaxThrottleDelay
|
||||
}
|
||||
|
||||
delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime)
|
||||
return time.Duration(delay) * time.Millisecond
|
||||
var delay time.Duration
|
||||
|
||||
// Logic to cap the retry count based on the minDelay provided
|
||||
actualRetryCount := int(math.Log2(float64(minDelay))) + 1
|
||||
if actualRetryCount < 63-retryCount {
|
||||
delay = time.Duration(1<<uint64(retryCount)) * getJitterDelay(minDelay)
|
||||
if delay > maxDelay {
|
||||
delay = getJitterDelay(maxDelay / 2)
|
||||
}
|
||||
} else {
|
||||
delay = getJitterDelay(maxDelay / 2)
|
||||
}
|
||||
return delay + initialDelay
|
||||
}
|
||||
|
||||
// getJitterDelay returns a jittered delay for retry
|
||||
func getJitterDelay(duration time.Duration) time.Duration {
|
||||
return time.Duration(sdkrand.SeededRand.Int63n(int64(duration)) + int64(duration))
|
||||
}
|
||||
|
||||
// ShouldRetry returns true if the request should be retried.
|
||||
func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
|
||||
|
||||
// ShouldRetry returns false if number of max retries is 0.
|
||||
if d.NumMaxRetries == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
// If one of the other handlers already set the retry state
|
||||
// we don't want to override it based on the service's state
|
||||
if r.Retryable != nil {
|
||||
return *r.Retryable
|
||||
}
|
||||
|
||||
if r.HTTPResponse.StatusCode >= 500 {
|
||||
return true
|
||||
}
|
||||
return r.IsErrorRetryable() || d.shouldThrottle(r)
|
||||
}
|
||||
|
||||
// ShouldThrottle returns true if the request should be throttled.
|
||||
func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
|
||||
switch r.HTTPResponse.StatusCode {
|
||||
case 429:
|
||||
case 502:
|
||||
case 503:
|
||||
case 504:
|
||||
default:
|
||||
return r.IsErrorThrottle()
|
||||
}
|
||||
|
||||
return true
|
||||
return r.IsErrorRetryable() || r.IsErrorThrottle()
|
||||
}
|
||||
|
||||
// This will look in the Retry-After header, RFC 7231, for how long
|
||||
// it will wait before attempting another request
|
||||
func getRetryDelay(r *request.Request) (time.Duration, bool) {
|
||||
func getRetryAfterDelay(r *request.Request) (time.Duration, bool) {
|
||||
if !canUseRetryAfterHeader(r) {
|
||||
return 0, false
|
||||
}
|
||||
|
@ -117,22 +175,3 @@ func canUseRetryAfterHeader(r *request.Request) bool {
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
// lockedSource is a thread-safe implementation of rand.Source
|
||||
type lockedSource struct {
|
||||
lk sync.Mutex
|
||||
src rand.Source
|
||||
}
|
||||
|
||||
func (r *lockedSource) Int63() (n int64) {
|
||||
r.lk.Lock()
|
||||
n = r.src.Int63()
|
||||
r.lk.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
func (r *lockedSource) Seed(seed int64) {
|
||||
r.lk.Lock()
|
||||
r.src.Seed(seed)
|
||||
r.lk.Unlock()
|
||||
}
|
||||
|
|
124
vendor/github.com/aws/aws-sdk-go/aws/client/logger.go
generated
vendored
124
vendor/github.com/aws/aws-sdk-go/aws/client/logger.go
generated
vendored
|
@ -44,22 +44,61 @@ func (reader *teeReaderCloser) Close() error {
|
|||
return reader.Source.Close()
|
||||
}
|
||||
|
||||
// LogHTTPRequestHandler is a SDK request handler to log the HTTP request sent
|
||||
// to a service. Will include the HTTP request body if the LogLevel of the
|
||||
// request matches LogDebugWithHTTPBody.
|
||||
var LogHTTPRequestHandler = request.NamedHandler{
|
||||
Name: "awssdk.client.LogRequest",
|
||||
Fn: logRequest,
|
||||
}
|
||||
|
||||
func logRequest(r *request.Request) {
|
||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
||||
dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody)
|
||||
bodySeekable := aws.IsReaderSeekable(r.Body)
|
||||
|
||||
b, err := httputil.DumpRequestOut(r.HTTPRequest, logBody)
|
||||
if err != nil {
|
||||
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err))
|
||||
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
|
||||
r.ClientInfo.ServiceName, r.Operation.Name, err))
|
||||
return
|
||||
}
|
||||
|
||||
if logBody {
|
||||
// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
|
||||
// Body as a NoOpCloser and will not be reset after read by the HTTP
|
||||
// client reader.
|
||||
r.ResetBody()
|
||||
if !bodySeekable {
|
||||
r.SetReaderBody(aws.ReadSeekCloser(r.HTTPRequest.Body))
|
||||
}
|
||||
// Reset the request body because dumpRequest will re-wrap the
|
||||
// r.HTTPRequest's Body as a NoOpCloser and will not be reset after
|
||||
// read by the HTTP client reader.
|
||||
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.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody)))
|
||||
r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
|
||||
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
|
||||
}
|
||||
|
||||
// LogHTTPRequestHeaderHandler is a SDK request handler to log the HTTP request sent
|
||||
// to a service. Will only log the HTTP request's headers. The request payload
|
||||
// will not be read.
|
||||
var LogHTTPRequestHeaderHandler = request.NamedHandler{
|
||||
Name: "awssdk.client.LogRequestHeader",
|
||||
Fn: logRequestHeader,
|
||||
}
|
||||
|
||||
func logRequestHeader(r *request.Request) {
|
||||
b, err := httputil.DumpRequestOut(r.HTTPRequest, false)
|
||||
if 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.ClientInfo.ServiceName, r.Operation.Name, string(b)))
|
||||
}
|
||||
|
||||
const logRespMsg = `DEBUG: Response %s/%s Details:
|
||||
|
@ -72,27 +111,50 @@ const logRespErrMsg = `DEBUG ERROR: Response %s/%s:
|
|||
%s
|
||||
-----------------------------------------------------`
|
||||
|
||||
// LogHTTPResponseHandler is a SDK request handler to log the HTTP response
|
||||
// received from a service. Will include the HTTP response body if the LogLevel
|
||||
// of the request matches LogDebugWithHTTPBody.
|
||||
var LogHTTPResponseHandler = request.NamedHandler{
|
||||
Name: "awssdk.client.LogResponse",
|
||||
Fn: logResponse,
|
||||
}
|
||||
|
||||
func logResponse(r *request.Request) {
|
||||
lw := &logWriter{r.Config.Logger, bytes.NewBuffer(nil)}
|
||||
r.HTTPResponse.Body = &teeReaderCloser{
|
||||
Reader: io.TeeReader(r.HTTPResponse.Body, lw),
|
||||
Source: r.HTTPResponse.Body,
|
||||
|
||||
if r.HTTPResponse == nil {
|
||||
lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
||||
r.ClientInfo.ServiceName, r.Operation.Name, "request's HTTPResponse is nil"))
|
||||
return
|
||||
}
|
||||
|
||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
||||
if logBody {
|
||||
r.HTTPResponse.Body = &teeReaderCloser{
|
||||
Reader: io.TeeReader(r.HTTPResponse.Body, lw),
|
||||
Source: r.HTTPResponse.Body,
|
||||
}
|
||||
}
|
||||
|
||||
handlerFn := func(req *request.Request) {
|
||||
body, err := httputil.DumpResponse(req.HTTPResponse, false)
|
||||
b, err := httputil.DumpResponse(req.HTTPResponse, false)
|
||||
if err != nil {
|
||||
lw.Logger.Log(fmt.Sprintf(logRespErrMsg, req.ClientInfo.ServiceName, req.Operation.Name, err))
|
||||
lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
||||
req.ClientInfo.ServiceName, req.Operation.Name, err))
|
||||
return
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadAll(lw.buf)
|
||||
if err != nil {
|
||||
lw.Logger.Log(fmt.Sprintf(logRespErrMsg, req.ClientInfo.ServiceName, req.Operation.Name, err))
|
||||
return
|
||||
}
|
||||
lw.Logger.Log(fmt.Sprintf(logRespMsg, req.ClientInfo.ServiceName, req.Operation.Name, string(body)))
|
||||
if req.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) {
|
||||
lw.Logger.Log(fmt.Sprintf(logRespMsg,
|
||||
req.ClientInfo.ServiceName, req.Operation.Name, string(b)))
|
||||
|
||||
if logBody {
|
||||
b, err := ioutil.ReadAll(lw.buf)
|
||||
if err != nil {
|
||||
lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
||||
req.ClientInfo.ServiceName, req.Operation.Name, err))
|
||||
return
|
||||
}
|
||||
|
||||
lw.Logger.Log(string(b))
|
||||
}
|
||||
}
|
||||
|
@ -106,3 +168,27 @@ func logResponse(r *request.Request) {
|
|||
Name: handlerName, Fn: handlerFn,
|
||||
})
|
||||
}
|
||||
|
||||
// LogHTTPResponseHeaderHandler is a SDK request handler to log the HTTP
|
||||
// response received from a service. Will only log the HTTP response's headers.
|
||||
// The response payload will not be read.
|
||||
var LogHTTPResponseHeaderHandler = request.NamedHandler{
|
||||
Name: "awssdk.client.LogResponseHeader",
|
||||
Fn: logResponseHeader,
|
||||
}
|
||||
|
||||
func logResponseHeader(r *request.Request) {
|
||||
if r.Config.Logger == nil {
|
||||
return
|
||||
}
|
||||
|
||||
b, err := httputil.DumpResponse(r.HTTPResponse, false)
|
||||
if err != nil {
|
||||
r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
||||
r.ClientInfo.ServiceName, r.Operation.Name, err))
|
||||
return
|
||||
}
|
||||
|
||||
r.Config.Logger.Log(fmt.Sprintf(logRespMsg,
|
||||
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
|
||||
}
|
||||
|
|
2
vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
generated
vendored
|
@ -3,7 +3,9 @@ package metadata
|
|||
// ClientInfo wraps immutable data from the client.Client structure.
|
||||
type ClientInfo struct {
|
||||
ServiceName string
|
||||
ServiceID string
|
||||
APIVersion string
|
||||
PartitionID string
|
||||
Endpoint string
|
||||
SigningName string
|
||||
SigningRegion string
|
||||
|
|
28
vendor/github.com/aws/aws-sdk-go/aws/client/no_op_retryer.go
generated
vendored
Normal file
28
vendor/github.com/aws/aws-sdk-go/aws/client/no_op_retryer.go
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// NoOpRetryer provides a retryer that performs no retries.
|
||||
// It should be used when we do not want retries to be performed.
|
||||
type NoOpRetryer struct{}
|
||||
|
||||
// MaxRetries returns the number of maximum returns the service will use to make
|
||||
// an individual API; For NoOpRetryer the MaxRetries will always be zero.
|
||||
func (d NoOpRetryer) MaxRetries() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// ShouldRetry will always return false for NoOpRetryer, as it should never retry.
|
||||
func (d NoOpRetryer) ShouldRetry(_ *request.Request) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// RetryRules returns the delay duration before retrying this request again;
|
||||
// since NoOpRetryer does not retry, RetryRules always returns 0.
|
||||
func (d NoOpRetryer) RetryRules(_ *request.Request) time.Duration {
|
||||
return 0
|
||||
}
|
136
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
136
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
|
@ -18,9 +18,9 @@ const UseServiceDefaultRetries = -1
|
|||
type RequestRetryer interface{}
|
||||
|
||||
// A Config provides service configuration for service clients. By default,
|
||||
// all clients will use the defaults.DefaultConfig tructure.
|
||||
// all clients will use the defaults.DefaultConfig structure.
|
||||
//
|
||||
// // Create Session with MaxRetry configuration to be shared by multiple
|
||||
// // Create Session with MaxRetries configuration to be shared by multiple
|
||||
// // service clients.
|
||||
// sess := session.Must(session.NewSession(&aws.Config{
|
||||
// MaxRetries: aws.Int(3),
|
||||
|
@ -45,8 +45,8 @@ type Config struct {
|
|||
// that overrides the default generated endpoint for a client. Set this
|
||||
// to `""` to use the default generated endpoint.
|
||||
//
|
||||
// @note You must still provide a `Region` value when specifying an
|
||||
// endpoint for a client.
|
||||
// Note: You must still provide a `Region` value when specifying an
|
||||
// endpoint for a client.
|
||||
Endpoint *string
|
||||
|
||||
// The resolver to use for looking up endpoints for AWS service clients
|
||||
|
@ -65,8 +65,8 @@ type Config struct {
|
|||
// noted. A full list of regions is found in the "Regions and Endpoints"
|
||||
// document.
|
||||
//
|
||||
// @see http://docs.aws.amazon.com/general/latest/gr/rande.html
|
||||
// AWS Regions and Endpoints
|
||||
// See http://docs.aws.amazon.com/general/latest/gr/rande.html for AWS
|
||||
// Regions and Endpoints.
|
||||
Region *string
|
||||
|
||||
// Set this to `true` to disable SSL when sending requests. Defaults
|
||||
|
@ -120,9 +120,10 @@ type Config struct {
|
|||
// will use virtual hosted bucket addressing when possible
|
||||
// (`http://BUCKET.s3.amazonaws.com/KEY`).
|
||||
//
|
||||
// @note This configuration option is specific to the Amazon S3 service.
|
||||
// @see http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html
|
||||
// Amazon S3: Virtual Hosting of Buckets
|
||||
// Note: This configuration option is specific to the Amazon S3 service.
|
||||
//
|
||||
// See http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html
|
||||
// for Amazon S3: Virtual Hosting of Buckets
|
||||
S3ForcePathStyle *bool
|
||||
|
||||
// Set this to `true` to disable the SDK adding the `Expect: 100-Continue`
|
||||
|
@ -151,6 +152,26 @@ type Config struct {
|
|||
// with accelerate.
|
||||
S3UseAccelerate *bool
|
||||
|
||||
// S3DisableContentMD5Validation config option is temporarily disabled,
|
||||
// For S3 GetObject API calls, #1837.
|
||||
//
|
||||
// Set this to `true` to disable the S3 service client from automatically
|
||||
// adding the ContentMD5 to S3 Object Put and Upload API calls. This option
|
||||
// will also disable the SDK from performing object ContentMD5 validation
|
||||
// on GetObject API calls.
|
||||
S3DisableContentMD5Validation *bool
|
||||
|
||||
// Set this to `true` to have the S3 service client to use the region specified
|
||||
// in the ARN, when an ARN is provided as an argument to a bucket parameter.
|
||||
S3UseARNRegion *bool
|
||||
|
||||
// Set this to `true` to enable the SDK to unmarshal API response header maps to
|
||||
// normalized lower case map keys.
|
||||
//
|
||||
// For example S3's X-Amz-Meta prefixed header will be unmarshaled to lower case
|
||||
// Metadata member's map keys. The value of the header in the map is unaffected.
|
||||
LowerCaseHeaderMaps *bool
|
||||
|
||||
// Set this to `true` to disable the EC2Metadata client from overriding the
|
||||
// default http.Client's Timeout. This is helpful if you do not want the
|
||||
// EC2Metadata client to create a new http.Client. This options is only
|
||||
|
@ -214,12 +235,40 @@ type Config struct {
|
|||
// Key: aws.String("//foo//bar//moo"),
|
||||
// })
|
||||
DisableRestProtocolURICleaning *bool
|
||||
|
||||
// EnableEndpointDiscovery will allow for endpoint discovery on operations that
|
||||
// have the definition in its model. By default, endpoint discovery is off.
|
||||
//
|
||||
// Example:
|
||||
// sess := session.Must(session.NewSession(&aws.Config{
|
||||
// EnableEndpointDiscovery: aws.Bool(true),
|
||||
// }))
|
||||
//
|
||||
// svc := s3.New(sess)
|
||||
// out, err := svc.GetObject(&s3.GetObjectInput {
|
||||
// Bucket: aws.String("bucketname"),
|
||||
// Key: aws.String("/foo/bar/moo"),
|
||||
// })
|
||||
EnableEndpointDiscovery *bool
|
||||
|
||||
// DisableEndpointHostPrefix will disable the SDK's behavior of prefixing
|
||||
// request endpoint hosts with modeled information.
|
||||
//
|
||||
// Disabling this feature is useful when you want to use local endpoints
|
||||
// for testing that do not support the modeled host prefix pattern.
|
||||
DisableEndpointHostPrefix *bool
|
||||
|
||||
// STSRegionalEndpoint will enable regional or legacy endpoint resolving
|
||||
STSRegionalEndpoint endpoints.STSRegionalEndpoint
|
||||
|
||||
// S3UsEast1RegionalEndpoint will enable regional or legacy endpoint resolving
|
||||
S3UsEast1RegionalEndpoint endpoints.S3UsEast1RegionalEndpoint
|
||||
}
|
||||
|
||||
// NewConfig returns a new Config pointer that can be chained with builder
|
||||
// methods to set multiple configuration values inline without using pointers.
|
||||
//
|
||||
// // Create Session with MaxRetry configuration to be shared by multiple
|
||||
// // Create Session with MaxRetries configuration to be shared by multiple
|
||||
// // service clients.
|
||||
// sess := session.Must(session.NewSession(aws.NewConfig().
|
||||
// WithMaxRetries(3),
|
||||
|
@ -336,6 +385,22 @@ func (c *Config) WithS3Disable100Continue(disable bool) *Config {
|
|||
func (c *Config) WithS3UseAccelerate(enable bool) *Config {
|
||||
c.S3UseAccelerate = &enable
|
||||
return c
|
||||
|
||||
}
|
||||
|
||||
// WithS3DisableContentMD5Validation sets a config
|
||||
// S3DisableContentMD5Validation value returning a Config pointer for chaining.
|
||||
func (c *Config) WithS3DisableContentMD5Validation(enable bool) *Config {
|
||||
c.S3DisableContentMD5Validation = &enable
|
||||
return c
|
||||
|
||||
}
|
||||
|
||||
// WithS3UseARNRegion sets a config S3UseARNRegion value and
|
||||
// returning a Config pointer for chaining
|
||||
func (c *Config) WithS3UseARNRegion(enable bool) *Config {
|
||||
c.S3UseARNRegion = &enable
|
||||
return c
|
||||
}
|
||||
|
||||
// WithUseDualStack sets a config UseDualStack value returning a Config
|
||||
|
@ -359,6 +424,19 @@ func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config {
|
|||
return c
|
||||
}
|
||||
|
||||
// WithEndpointDiscovery will set whether or not to use endpoint discovery.
|
||||
func (c *Config) WithEndpointDiscovery(t bool) *Config {
|
||||
c.EnableEndpointDiscovery = &t
|
||||
return c
|
||||
}
|
||||
|
||||
// WithDisableEndpointHostPrefix will set whether or not to use modeled host prefix
|
||||
// when making requests.
|
||||
func (c *Config) WithDisableEndpointHostPrefix(t bool) *Config {
|
||||
c.DisableEndpointHostPrefix = &t
|
||||
return c
|
||||
}
|
||||
|
||||
// MergeIn merges the passed in configs into the existing config object.
|
||||
func (c *Config) MergeIn(cfgs ...*Config) {
|
||||
for _, other := range cfgs {
|
||||
|
@ -366,6 +444,20 @@ func (c *Config) MergeIn(cfgs ...*Config) {
|
|||
}
|
||||
}
|
||||
|
||||
// WithSTSRegionalEndpoint will set whether or not to use regional endpoint flag
|
||||
// when resolving the endpoint for a service
|
||||
func (c *Config) WithSTSRegionalEndpoint(sre endpoints.STSRegionalEndpoint) *Config {
|
||||
c.STSRegionalEndpoint = sre
|
||||
return c
|
||||
}
|
||||
|
||||
// WithS3UsEast1RegionalEndpoint will set whether or not to use regional endpoint flag
|
||||
// when resolving the endpoint for a service
|
||||
func (c *Config) WithS3UsEast1RegionalEndpoint(sre endpoints.S3UsEast1RegionalEndpoint) *Config {
|
||||
c.S3UsEast1RegionalEndpoint = sre
|
||||
return c
|
||||
}
|
||||
|
||||
func mergeInConfig(dst *Config, other *Config) {
|
||||
if other == nil {
|
||||
return
|
||||
|
@ -435,6 +527,14 @@ func mergeInConfig(dst *Config, other *Config) {
|
|||
dst.S3UseAccelerate = other.S3UseAccelerate
|
||||
}
|
||||
|
||||
if other.S3DisableContentMD5Validation != nil {
|
||||
dst.S3DisableContentMD5Validation = other.S3DisableContentMD5Validation
|
||||
}
|
||||
|
||||
if other.S3UseARNRegion != nil {
|
||||
dst.S3UseARNRegion = other.S3UseARNRegion
|
||||
}
|
||||
|
||||
if other.UseDualStack != nil {
|
||||
dst.UseDualStack = other.UseDualStack
|
||||
}
|
||||
|
@ -454,6 +554,22 @@ func mergeInConfig(dst *Config, other *Config) {
|
|||
if other.EnforceShouldRetryCheck != nil {
|
||||
dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck
|
||||
}
|
||||
|
||||
if other.EnableEndpointDiscovery != nil {
|
||||
dst.EnableEndpointDiscovery = other.EnableEndpointDiscovery
|
||||
}
|
||||
|
||||
if other.DisableEndpointHostPrefix != nil {
|
||||
dst.DisableEndpointHostPrefix = other.DisableEndpointHostPrefix
|
||||
}
|
||||
|
||||
if other.STSRegionalEndpoint != endpoints.UnsetSTSEndpoint {
|
||||
dst.STSRegionalEndpoint = other.STSRegionalEndpoint
|
||||
}
|
||||
|
||||
if other.S3UsEast1RegionalEndpoint != endpoints.UnsetS3UsEast1Endpoint {
|
||||
dst.S3UsEast1RegionalEndpoint = other.S3UsEast1RegionalEndpoint
|
||||
}
|
||||
}
|
||||
|
||||
// Copy will return a shallow copy of the Config object. If any additional
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// +build !go1.9
|
||||
|
||||
package aws
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
import "time"
|
||||
|
||||
// Context is an copy of the Go v1.7 stdlib's context.Context interface.
|
||||
// It is represented as a SDK interface to enable you to use the "WithContext"
|
||||
|
@ -35,37 +35,3 @@ type Context interface {
|
|||
// functions.
|
||||
Value(key interface{}) interface{}
|
||||
}
|
||||
|
||||
// BackgroundContext returns a context that will never be canceled, has no
|
||||
// values, and no deadline. This context is used by the SDK to provide
|
||||
// backwards compatibility with non-context API operations and functionality.
|
||||
//
|
||||
// Go 1.6 and before:
|
||||
// This context function is equivalent to context.Background in the Go stdlib.
|
||||
//
|
||||
// Go 1.7 and later:
|
||||
// The context returned will be the value returned by context.Background()
|
||||
//
|
||||
// See https://golang.org/pkg/context for more information on Contexts.
|
||||
func BackgroundContext() Context {
|
||||
return backgroundCtx
|
||||
}
|
||||
|
||||
// SleepWithContext will wait for the timer duration to expire, or the context
|
||||
// is canceled. Which ever happens first. If the context is canceled the Context's
|
||||
// error will be returned.
|
||||
//
|
||||
// Expects Context to always return a non-nil error if the Done channel is closed.
|
||||
func SleepWithContext(ctx Context, dur time.Duration) error {
|
||||
t := time.NewTimer(dur)
|
||||
defer t.Stop()
|
||||
|
||||
select {
|
||||
case <-t.C:
|
||||
break
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
9
vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go
generated
vendored
9
vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go
generated
vendored
|
@ -1,9 +0,0 @@
|
|||
// +build go1.7
|
||||
|
||||
package aws
|
||||
|
||||
import "context"
|
||||
|
||||
var (
|
||||
backgroundCtx = context.Background()
|
||||
)
|
11
vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go
generated
vendored
Normal file
11
vendor/github.com/aws/aws-sdk-go/aws/context_1_9.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
// +build go1.9
|
||||
|
||||
package aws
|
||||
|
||||
import "context"
|
||||
|
||||
// Context is an alias of the Go stdlib's context.Context interface.
|
||||
// It can be used within the SDK's API operation "WithContext" methods.
|
||||
//
|
||||
// See https://golang.org/pkg/context on how to use contexts.
|
||||
type Context = context.Context
|
|
@ -39,3 +39,18 @@ func (e *emptyCtx) String() string {
|
|||
var (
|
||||
backgroundCtx = new(emptyCtx)
|
||||
)
|
||||
|
||||
// BackgroundContext returns a context that will never be canceled, has no
|
||||
// values, and no deadline. This context is used by the SDK to provide
|
||||
// backwards compatibility with non-context API operations and functionality.
|
||||
//
|
||||
// Go 1.6 and before:
|
||||
// This context function is equivalent to context.Background in the Go stdlib.
|
||||
//
|
||||
// Go 1.7 and later:
|
||||
// The context returned will be the value returned by context.Background()
|
||||
//
|
||||
// See https://golang.org/pkg/context for more information on Contexts.
|
||||
func BackgroundContext() Context {
|
||||
return backgroundCtx
|
||||
}
|
20
vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go
generated
vendored
Normal file
20
vendor/github.com/aws/aws-sdk-go/aws/context_background_1_7.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
// +build go1.7
|
||||
|
||||
package aws
|
||||
|
||||
import "context"
|
||||
|
||||
// BackgroundContext returns a context that will never be canceled, has no
|
||||
// values, and no deadline. This context is used by the SDK to provide
|
||||
// backwards compatibility with non-context API operations and functionality.
|
||||
//
|
||||
// Go 1.6 and before:
|
||||
// This context function is equivalent to context.Background in the Go stdlib.
|
||||
//
|
||||
// Go 1.7 and later:
|
||||
// The context returned will be the value returned by context.Background()
|
||||
//
|
||||
// See https://golang.org/pkg/context for more information on Contexts.
|
||||
func BackgroundContext() Context {
|
||||
return context.Background()
|
||||
}
|
24
vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go
generated
vendored
Normal file
24
vendor/github.com/aws/aws-sdk-go/aws/context_sleep.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// SleepWithContext will wait for the timer duration to expire, or the context
|
||||
// is canceled. Which ever happens first. If the context is canceled the Context's
|
||||
// error will be returned.
|
||||
//
|
||||
// Expects Context to always return a non-nil error if the Done channel is closed.
|
||||
func SleepWithContext(ctx Context, dur time.Duration) error {
|
||||
t := time.NewTimer(dur)
|
||||
defer t.Stop()
|
||||
|
||||
select {
|
||||
case <-t.C:
|
||||
break
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
531
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
531
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
|
@ -179,6 +179,242 @@ func IntValueMap(src map[string]*int) map[string]int {
|
|||
return dst
|
||||
}
|
||||
|
||||
// Uint returns a pointer to the uint value passed in.
|
||||
func Uint(v uint) *uint {
|
||||
return &v
|
||||
}
|
||||
|
||||
// UintValue returns the value of the uint pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func UintValue(v *uint) uint {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// UintSlice converts a slice of uint values uinto a slice of
|
||||
// uint pointers
|
||||
func UintSlice(src []uint) []*uint {
|
||||
dst := make([]*uint, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UintValueSlice converts a slice of uint pointers uinto a slice of
|
||||
// uint values
|
||||
func UintValueSlice(src []*uint) []uint {
|
||||
dst := make([]uint, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UintMap converts a string map of uint values uinto a string
|
||||
// map of uint pointers
|
||||
func UintMap(src map[string]uint) map[string]*uint {
|
||||
dst := make(map[string]*uint)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// UintValueMap converts a string map of uint pointers uinto a string
|
||||
// map of uint values
|
||||
func UintValueMap(src map[string]*uint) map[string]uint {
|
||||
dst := make(map[string]uint)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int8 returns a pointer to the int8 value passed in.
|
||||
func Int8(v int8) *int8 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int8Value returns the value of the int8 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Int8Value(v *int8) int8 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Int8Slice converts a slice of int8 values into a slice of
|
||||
// int8 pointers
|
||||
func Int8Slice(src []int8) []*int8 {
|
||||
dst := make([]*int8, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int8ValueSlice converts a slice of int8 pointers into a slice of
|
||||
// int8 values
|
||||
func Int8ValueSlice(src []*int8) []int8 {
|
||||
dst := make([]int8, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int8Map converts a string map of int8 values into a string
|
||||
// map of int8 pointers
|
||||
func Int8Map(src map[string]int8) map[string]*int8 {
|
||||
dst := make(map[string]*int8)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int8ValueMap converts a string map of int8 pointers into a string
|
||||
// map of int8 values
|
||||
func Int8ValueMap(src map[string]*int8) map[string]int8 {
|
||||
dst := make(map[string]int8)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int16 returns a pointer to the int16 value passed in.
|
||||
func Int16(v int16) *int16 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int16Value returns the value of the int16 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Int16Value(v *int16) int16 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Int16Slice converts a slice of int16 values into a slice of
|
||||
// int16 pointers
|
||||
func Int16Slice(src []int16) []*int16 {
|
||||
dst := make([]*int16, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int16ValueSlice converts a slice of int16 pointers into a slice of
|
||||
// int16 values
|
||||
func Int16ValueSlice(src []*int16) []int16 {
|
||||
dst := make([]int16, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int16Map converts a string map of int16 values into a string
|
||||
// map of int16 pointers
|
||||
func Int16Map(src map[string]int16) map[string]*int16 {
|
||||
dst := make(map[string]*int16)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int16ValueMap converts a string map of int16 pointers into a string
|
||||
// map of int16 values
|
||||
func Int16ValueMap(src map[string]*int16) map[string]int16 {
|
||||
dst := make(map[string]int16)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int32 returns a pointer to the int32 value passed in.
|
||||
func Int32(v int32) *int32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Int32Value returns the value of the int32 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Int32Value(v *int32) int32 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Int32Slice converts a slice of int32 values into a slice of
|
||||
// int32 pointers
|
||||
func Int32Slice(src []int32) []*int32 {
|
||||
dst := make([]*int32, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int32ValueSlice converts a slice of int32 pointers into a slice of
|
||||
// int32 values
|
||||
func Int32ValueSlice(src []*int32) []int32 {
|
||||
dst := make([]int32, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int32Map converts a string map of int32 values into a string
|
||||
// map of int32 pointers
|
||||
func Int32Map(src map[string]int32) map[string]*int32 {
|
||||
dst := make(map[string]*int32)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int32ValueMap converts a string map of int32 pointers into a string
|
||||
// map of int32 values
|
||||
func Int32ValueMap(src map[string]*int32) map[string]int32 {
|
||||
dst := make(map[string]int32)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Int64 returns a pointer to the int64 value passed in.
|
||||
func Int64(v int64) *int64 {
|
||||
return &v
|
||||
|
@ -238,6 +474,301 @@ func Int64ValueMap(src map[string]*int64) map[string]int64 {
|
|||
return dst
|
||||
}
|
||||
|
||||
// Uint8 returns a pointer to the uint8 value passed in.
|
||||
func Uint8(v uint8) *uint8 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint8Value returns the value of the uint8 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Uint8Value(v *uint8) uint8 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Uint8Slice converts a slice of uint8 values into a slice of
|
||||
// uint8 pointers
|
||||
func Uint8Slice(src []uint8) []*uint8 {
|
||||
dst := make([]*uint8, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint8ValueSlice converts a slice of uint8 pointers into a slice of
|
||||
// uint8 values
|
||||
func Uint8ValueSlice(src []*uint8) []uint8 {
|
||||
dst := make([]uint8, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint8Map converts a string map of uint8 values into a string
|
||||
// map of uint8 pointers
|
||||
func Uint8Map(src map[string]uint8) map[string]*uint8 {
|
||||
dst := make(map[string]*uint8)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint8ValueMap converts a string map of uint8 pointers into a string
|
||||
// map of uint8 values
|
||||
func Uint8ValueMap(src map[string]*uint8) map[string]uint8 {
|
||||
dst := make(map[string]uint8)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint16 returns a pointer to the uint16 value passed in.
|
||||
func Uint16(v uint16) *uint16 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint16Value returns the value of the uint16 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Uint16Value(v *uint16) uint16 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Uint16Slice converts a slice of uint16 values into a slice of
|
||||
// uint16 pointers
|
||||
func Uint16Slice(src []uint16) []*uint16 {
|
||||
dst := make([]*uint16, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint16ValueSlice converts a slice of uint16 pointers into a slice of
|
||||
// uint16 values
|
||||
func Uint16ValueSlice(src []*uint16) []uint16 {
|
||||
dst := make([]uint16, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint16Map converts a string map of uint16 values into a string
|
||||
// map of uint16 pointers
|
||||
func Uint16Map(src map[string]uint16) map[string]*uint16 {
|
||||
dst := make(map[string]*uint16)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint16ValueMap converts a string map of uint16 pointers into a string
|
||||
// map of uint16 values
|
||||
func Uint16ValueMap(src map[string]*uint16) map[string]uint16 {
|
||||
dst := make(map[string]uint16)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint32 returns a pointer to the uint32 value passed in.
|
||||
func Uint32(v uint32) *uint32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint32Value returns the value of the uint32 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Uint32Value(v *uint32) uint32 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Uint32Slice converts a slice of uint32 values into a slice of
|
||||
// uint32 pointers
|
||||
func Uint32Slice(src []uint32) []*uint32 {
|
||||
dst := make([]*uint32, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint32ValueSlice converts a slice of uint32 pointers into a slice of
|
||||
// uint32 values
|
||||
func Uint32ValueSlice(src []*uint32) []uint32 {
|
||||
dst := make([]uint32, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint32Map converts a string map of uint32 values into a string
|
||||
// map of uint32 pointers
|
||||
func Uint32Map(src map[string]uint32) map[string]*uint32 {
|
||||
dst := make(map[string]*uint32)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint32ValueMap converts a string map of uint32 pointers into a string
|
||||
// map of uint32 values
|
||||
func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
|
||||
dst := make(map[string]uint32)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint64 returns a pointer to the uint64 value passed in.
|
||||
func Uint64(v uint64) *uint64 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Uint64Value returns the value of the uint64 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Uint64Value(v *uint64) uint64 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Uint64Slice converts a slice of uint64 values into a slice of
|
||||
// uint64 pointers
|
||||
func Uint64Slice(src []uint64) []*uint64 {
|
||||
dst := make([]*uint64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint64ValueSlice converts a slice of uint64 pointers into a slice of
|
||||
// uint64 values
|
||||
func Uint64ValueSlice(src []*uint64) []uint64 {
|
||||
dst := make([]uint64, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint64Map converts a string map of uint64 values into a string
|
||||
// map of uint64 pointers
|
||||
func Uint64Map(src map[string]uint64) map[string]*uint64 {
|
||||
dst := make(map[string]*uint64)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Uint64ValueMap converts a string map of uint64 pointers into a string
|
||||
// map of uint64 values
|
||||
func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
|
||||
dst := make(map[string]uint64)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float32 returns a pointer to the float32 value passed in.
|
||||
func Float32(v float32) *float32 {
|
||||
return &v
|
||||
}
|
||||
|
||||
// Float32Value returns the value of the float32 pointer passed in or
|
||||
// 0 if the pointer is nil.
|
||||
func Float32Value(v *float32) float32 {
|
||||
if v != nil {
|
||||
return *v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Float32Slice converts a slice of float32 values into a slice of
|
||||
// float32 pointers
|
||||
func Float32Slice(src []float32) []*float32 {
|
||||
dst := make([]*float32, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i] = &(src[i])
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float32ValueSlice converts a slice of float32 pointers into a slice of
|
||||
// float32 values
|
||||
func Float32ValueSlice(src []*float32) []float32 {
|
||||
dst := make([]float32, len(src))
|
||||
for i := 0; i < len(src); i++ {
|
||||
if src[i] != nil {
|
||||
dst[i] = *(src[i])
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float32Map converts a string map of float32 values into a string
|
||||
// map of float32 pointers
|
||||
func Float32Map(src map[string]float32) map[string]*float32 {
|
||||
dst := make(map[string]*float32)
|
||||
for k, val := range src {
|
||||
v := val
|
||||
dst[k] = &v
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float32ValueMap converts a string map of float32 pointers into a string
|
||||
// map of float32 values
|
||||
func Float32ValueMap(src map[string]*float32) map[string]float32 {
|
||||
dst := make(map[string]float32)
|
||||
for k, val := range src {
|
||||
if val != nil {
|
||||
dst[k] = *val
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
// Float64 returns a pointer to the float64 value passed in.
|
||||
func Float64(v float64) *float64 {
|
||||
return &v
|
||||
|
|
96
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
generated
vendored
96
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
generated
vendored
|
@ -3,12 +3,10 @@ package corehandlers
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
|
@ -36,18 +34,13 @@ var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLen
|
|||
if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
|
||||
length, _ = strconv.ParseInt(slength, 10, 64)
|
||||
} else {
|
||||
switch body := r.Body.(type) {
|
||||
case nil:
|
||||
length = 0
|
||||
case lener:
|
||||
length = int64(body.Len())
|
||||
case io.Seeker:
|
||||
r.BodyStart, _ = body.Seek(0, 1)
|
||||
end, _ := body.Seek(0, 2)
|
||||
body.Seek(r.BodyStart, 0) // make sure to seek back to original location
|
||||
length = end - r.BodyStart
|
||||
default:
|
||||
panic("Cannot get length of body, must provide `ContentLength`")
|
||||
if r.Body != nil {
|
||||
var err error
|
||||
length, err = aws.SeekerLen(r.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.New(request.ErrCodeSerialization, "failed to get request body's length", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,13 +53,6 @@ var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLen
|
|||
}
|
||||
}}
|
||||
|
||||
// SDKVersionUserAgentHandler is a request handler for adding the SDK Version to the user agent.
|
||||
var SDKVersionUserAgentHandler = request.NamedHandler{
|
||||
Name: "core.SDKVersionUserAgentHandler",
|
||||
Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion,
|
||||
runtime.Version(), runtime.GOOS, runtime.GOARCH),
|
||||
}
|
||||
|
||||
var reStatusCode = regexp.MustCompile(`^(\d{3})`)
|
||||
|
||||
// ValidateReqSigHandler is a request handler to ensure that the request's
|
||||
|
@ -86,9 +72,9 @@ var ValidateReqSigHandler = request.NamedHandler{
|
|||
signedTime = r.LastSignedAt
|
||||
}
|
||||
|
||||
// 10 minutes to allow for some clock skew/delays in transmission.
|
||||
// 5 minutes to allow for some clock skew/delays in transmission.
|
||||
// Would be improved with aws/aws-sdk-go#423
|
||||
if signedTime.Add(10 * time.Minute).After(time.Now()) {
|
||||
if signedTime.Add(5 * time.Minute).After(time.Now()) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -173,9 +159,9 @@ func handleSendError(r *request.Request, err error) {
|
|||
Body: ioutil.NopCloser(bytes.NewReader([]byte{})),
|
||||
}
|
||||
}
|
||||
// Catch all other request errors.
|
||||
r.Error = awserr.New("RequestError", "send request failed", err)
|
||||
r.Retryable = aws.Bool(true) // network errors are retryable
|
||||
// Catch all request errors, and let the default retrier determine
|
||||
// if the error is retryable.
|
||||
r.Error = awserr.New(request.ErrCodeRequestError, "send request failed", err)
|
||||
|
||||
// Override the error with a context canceled error, if that was canceled.
|
||||
ctx := r.Context()
|
||||
|
@ -198,37 +184,39 @@ var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseH
|
|||
|
||||
// AfterRetryHandler performs final checks to determine if the request should
|
||||
// be retried and how long to delay.
|
||||
var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) {
|
||||
// If one of the other handlers already set the retry state
|
||||
// we don't want to override it based on the service's state
|
||||
if r.Retryable == nil || aws.BoolValue(r.Config.EnforceShouldRetryCheck) {
|
||||
r.Retryable = aws.Bool(r.ShouldRetry(r))
|
||||
}
|
||||
|
||||
if r.WillRetry() {
|
||||
r.RetryDelay = r.RetryRules(r)
|
||||
|
||||
if sleepFn := r.Config.SleepDelay; sleepFn != nil {
|
||||
// Support SleepDelay for backwards compatibility and testing
|
||||
sleepFn(r.RetryDelay)
|
||||
} else if err := aws.SleepWithContext(r.Context(), r.RetryDelay); err != nil {
|
||||
r.Error = awserr.New(request.CanceledErrorCode,
|
||||
"request context canceled", err)
|
||||
r.Retryable = aws.Bool(false)
|
||||
return
|
||||
var AfterRetryHandler = request.NamedHandler{
|
||||
Name: "core.AfterRetryHandler",
|
||||
Fn: func(r *request.Request) {
|
||||
// If one of the other handlers already set the retry state
|
||||
// we don't want to override it based on the service's state
|
||||
if r.Retryable == nil || aws.BoolValue(r.Config.EnforceShouldRetryCheck) {
|
||||
r.Retryable = aws.Bool(r.ShouldRetry(r))
|
||||
}
|
||||
|
||||
// when the expired token exception occurs the credentials
|
||||
// need to be expired locally so that the next request to
|
||||
// get credentials will trigger a credentials refresh.
|
||||
if r.IsErrorExpired() {
|
||||
r.Config.Credentials.Expire()
|
||||
}
|
||||
if r.WillRetry() {
|
||||
r.RetryDelay = r.RetryRules(r)
|
||||
|
||||
r.RetryCount++
|
||||
r.Error = nil
|
||||
}
|
||||
}}
|
||||
if sleepFn := r.Config.SleepDelay; sleepFn != nil {
|
||||
// Support SleepDelay for backwards compatibility and testing
|
||||
sleepFn(r.RetryDelay)
|
||||
} else if err := aws.SleepWithContext(r.Context(), r.RetryDelay); err != nil {
|
||||
r.Error = awserr.New(request.CanceledErrorCode,
|
||||
"request context canceled", err)
|
||||
r.Retryable = aws.Bool(false)
|
||||
return
|
||||
}
|
||||
|
||||
// when the expired token exception occurs the credentials
|
||||
// need to be expired locally so that the next request to
|
||||
// get credentials will trigger a credentials refresh.
|
||||
if r.IsErrorExpired() {
|
||||
r.Config.Credentials.Expire()
|
||||
}
|
||||
|
||||
r.RetryCount++
|
||||
r.Error = nil
|
||||
}
|
||||
}}
|
||||
|
||||
// ValidateEndpointHandler is a request handler to validate a request had the
|
||||
// appropriate Region and Endpoint set. Will set r.Error if the endpoint or
|
||||
|
|
37
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go
generated
vendored
Normal file
37
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
package corehandlers
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// SDKVersionUserAgentHandler is a request handler for adding the SDK Version
|
||||
// to the user agent.
|
||||
var SDKVersionUserAgentHandler = request.NamedHandler{
|
||||
Name: "core.SDKVersionUserAgentHandler",
|
||||
Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion,
|
||||
runtime.Version(), runtime.GOOS, runtime.GOARCH),
|
||||
}
|
||||
|
||||
const execEnvVar = `AWS_EXECUTION_ENV`
|
||||
const execEnvUAKey = `exec-env`
|
||||
|
||||
// AddHostExecEnvUserAgentHander is a request handler appending the SDK's
|
||||
// execution environment to the user agent.
|
||||
//
|
||||
// If the environment variable AWS_EXECUTION_ENV is set, its value will be
|
||||
// appended to the user agent string.
|
||||
var AddHostExecEnvUserAgentHander = request.NamedHandler{
|
||||
Name: "core.AddHostExecEnvUserAgentHander",
|
||||
Fn: func(r *request.Request) {
|
||||
v := os.Getenv(execEnvVar)
|
||||
if len(v) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
request.AddToUserAgent(r, execEnvUAKey+"/"+v)
|
||||
},
|
||||
}
|
4
vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
|
@ -9,9 +9,7 @@ var (
|
|||
// providers in the ChainProvider.
|
||||
//
|
||||
// This has been deprecated. For verbose error messaging set
|
||||
// aws.Config.CredentialsChainVerboseErrors to true
|
||||
//
|
||||
// @readonly
|
||||
// aws.Config.CredentialsChainVerboseErrors to true.
|
||||
ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders",
|
||||
`no valid providers in chain. Deprecated.
|
||||
For verbose messaging see aws.Config.CredentialsChainVerboseErrors`,
|
||||
|
|
71
vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
71
vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
|
@ -49,8 +49,11 @@
|
|||
package credentials
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
// AnonymousCredentials is an empty Credential object that can be used as
|
||||
|
@ -64,8 +67,6 @@ import (
|
|||
// Credentials: credentials.AnonymousCredentials,
|
||||
// })))
|
||||
// // Access public S3 buckets.
|
||||
//
|
||||
// @readonly
|
||||
var AnonymousCredentials = NewStaticCredentials("", "", "")
|
||||
|
||||
// A Value is the AWS credentials value for individual credential fields.
|
||||
|
@ -83,6 +84,12 @@ type Value struct {
|
|||
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
|
||||
// Value. A provider is required to manage its own Expired state, and what to
|
||||
// be expired means.
|
||||
|
@ -99,6 +106,14 @@ type Provider interface {
|
|||
IsExpired() bool
|
||||
}
|
||||
|
||||
// An Expirer is an interface that Providers can implement to expose the expiration
|
||||
// time, if known. If the Provider cannot accurately provide this info,
|
||||
// it should not implement this interface.
|
||||
type Expirer interface {
|
||||
// The time at which the credentials are no longer valid
|
||||
ExpiresAt() time.Time
|
||||
}
|
||||
|
||||
// An ErrorProvider is a stub credentials provider that always returns an error
|
||||
// this is used by the SDK when construction a known provider is not possible
|
||||
// due to an error.
|
||||
|
@ -158,13 +173,19 @@ func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) {
|
|||
|
||||
// IsExpired returns if the credentials are expired.
|
||||
func (e *Expiry) IsExpired() bool {
|
||||
if e.CurrentTime == nil {
|
||||
e.CurrentTime = time.Now
|
||||
curTime := e.CurrentTime
|
||||
if curTime == nil {
|
||||
curTime = time.Now
|
||||
}
|
||||
return e.expiration.Before(e.CurrentTime())
|
||||
return e.expiration.Before(curTime())
|
||||
}
|
||||
|
||||
// A Credentials provides synchronous safe retrieval of AWS credentials Value.
|
||||
// ExpiresAt returns the expiration time of the credential
|
||||
func (e *Expiry) ExpiresAt() time.Time {
|
||||
return e.expiration
|
||||
}
|
||||
|
||||
// A Credentials provides concurrency safe retrieval of AWS credentials Value.
|
||||
// Credentials will cache the credentials value until they expire. Once the value
|
||||
// expires the next Get will attempt to retrieve valid credentials.
|
||||
//
|
||||
|
@ -178,7 +199,8 @@ func (e *Expiry) IsExpired() bool {
|
|||
type Credentials struct {
|
||||
creds Value
|
||||
forceRefresh bool
|
||||
m sync.Mutex
|
||||
|
||||
m sync.RWMutex
|
||||
|
||||
provider Provider
|
||||
}
|
||||
|
@ -201,6 +223,17 @@ func NewCredentials(provider Provider) *Credentials {
|
|||
// If Credentials.Expire() was called the credentials Value will be force
|
||||
// expired, and the next call to Get() will cause them to be refreshed.
|
||||
func (c *Credentials) Get() (Value, error) {
|
||||
// Check the cached credentials first with just the read lock.
|
||||
c.m.RLock()
|
||||
if !c.isExpired() {
|
||||
creds := c.creds
|
||||
c.m.RUnlock()
|
||||
return creds, nil
|
||||
}
|
||||
c.m.RUnlock()
|
||||
|
||||
// Credentials are expired need to retrieve the credentials taking the full
|
||||
// lock.
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
|
||||
|
@ -234,8 +267,8 @@ func (c *Credentials) Expire() {
|
|||
// If the Credentials were forced to be expired with Expire() this will
|
||||
// reflect that override.
|
||||
func (c *Credentials) IsExpired() bool {
|
||||
c.m.Lock()
|
||||
defer c.m.Unlock()
|
||||
c.m.RLock()
|
||||
defer c.m.RUnlock()
|
||||
|
||||
return c.isExpired()
|
||||
}
|
||||
|
@ -244,3 +277,23 @@ func (c *Credentials) IsExpired() bool {
|
|||
func (c *Credentials) isExpired() bool {
|
||||
return c.forceRefresh || c.provider.IsExpired()
|
||||
}
|
||||
|
||||
// ExpiresAt provides access to the functionality of the Expirer interface of
|
||||
// the underlying Provider, if it supports that interface. Otherwise, it returns
|
||||
// an error.
|
||||
func (c *Credentials) ExpiresAt() (time.Time, error) {
|
||||
c.m.RLock()
|
||||
defer c.m.RUnlock()
|
||||
|
||||
expirer, ok := c.provider.(Expirer)
|
||||
if !ok {
|
||||
return time.Time{}, awserr.New("ProviderNotExpirer",
|
||||
fmt.Sprintf("provider %s does not support ExpiresAt()", c.creds.ProviderName),
|
||||
nil)
|
||||
}
|
||||
if c.forceRefresh {
|
||||
// set expiration time to the distant past
|
||||
return time.Time{}, nil
|
||||
}
|
||||
return expirer.ExpiresAt(), nil
|
||||
}
|
||||
|
|
12
vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
generated
vendored
12
vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
generated
vendored
|
@ -4,7 +4,6 @@ import (
|
|||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -12,6 +11,8 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/internal/sdkuri"
|
||||
)
|
||||
|
||||
// ProviderName provides a name of EC2Role provider
|
||||
|
@ -125,7 +126,7 @@ type ec2RoleCredRespBody struct {
|
|||
Message string
|
||||
}
|
||||
|
||||
const iamSecurityCredsPath = "/iam/security-credentials"
|
||||
const iamSecurityCredsPath = "iam/security-credentials/"
|
||||
|
||||
// requestCredList requests a list of credentials from the EC2 service.
|
||||
// If there are no credentials, or there is an error making or receiving the request
|
||||
|
@ -142,7 +143,8 @@ func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) {
|
|||
}
|
||||
|
||||
if err := s.Err(); err != nil {
|
||||
return nil, awserr.New("SerializationError", "failed to read EC2 instance role from metadata service", err)
|
||||
return nil, awserr.New(request.ErrCodeSerialization,
|
||||
"failed to read EC2 instance role from metadata service", err)
|
||||
}
|
||||
|
||||
return credsList, nil
|
||||
|
@ -153,7 +155,7 @@ func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) {
|
|||
// If the credentials cannot be found, or there is an error reading the response
|
||||
// and error will be returned.
|
||||
func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) {
|
||||
resp, err := client.GetMetadata(path.Join(iamSecurityCredsPath, credsName))
|
||||
resp, err := client.GetMetadata(sdkuri.PathJoin(iamSecurityCredsPath, credsName))
|
||||
if err != nil {
|
||||
return ec2RoleCredRespBody{},
|
||||
awserr.New("EC2RoleRequestError",
|
||||
|
@ -164,7 +166,7 @@ func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCred
|
|||
respCreds := ec2RoleCredRespBody{}
|
||||
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil {
|
||||
return ec2RoleCredRespBody{},
|
||||
awserr.New("SerializationError",
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
fmt.Sprintf("failed to decode %s EC2 instance role credentials", credsName),
|
||||
err)
|
||||
}
|
||||
|
|
26
vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go
generated
vendored
26
vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go
generated
vendored
|
@ -39,6 +39,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/json/jsonutil"
|
||||
)
|
||||
|
||||
// ProviderName is the name of the credentials provider.
|
||||
|
@ -65,6 +66,10 @@ type Provider struct {
|
|||
//
|
||||
// If ExpiryWindow is 0 or less it will be ignored.
|
||||
ExpiryWindow time.Duration
|
||||
|
||||
// Optional authorization token value if set will be used as the value of
|
||||
// the Authorization header of the endpoint credential request.
|
||||
AuthorizationToken string
|
||||
}
|
||||
|
||||
// NewProviderClient returns a credentials Provider for retrieving AWS credentials
|
||||
|
@ -93,8 +98,8 @@ func NewProviderClient(cfg aws.Config, handlers request.Handlers, endpoint strin
|
|||
return p
|
||||
}
|
||||
|
||||
// NewCredentialsClient returns a Credentials wrapper for retrieving credentials
|
||||
// from an arbitrary endpoint concurrently. The client will request the
|
||||
// NewCredentialsClient returns a pointer to a new Credentials object
|
||||
// wrapping the endpoint credentials Provider.
|
||||
func NewCredentialsClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) *credentials.Credentials {
|
||||
return credentials.NewCredentials(NewProviderClient(cfg, handlers, endpoint, options...))
|
||||
}
|
||||
|
@ -152,6 +157,9 @@ func (p *Provider) getCredentials() (*getCredentialsOutput, error) {
|
|||
out := &getCredentialsOutput{}
|
||||
req := p.Client.NewRequest(op, nil, out)
|
||||
req.HTTPRequest.Header.Set("Accept", "application/json")
|
||||
if authToken := p.AuthorizationToken; len(authToken) != 0 {
|
||||
req.HTTPRequest.Header.Set("Authorization", authToken)
|
||||
}
|
||||
|
||||
return out, req.Send()
|
||||
}
|
||||
|
@ -167,7 +175,7 @@ func unmarshalHandler(r *request.Request) {
|
|||
|
||||
out := r.Data.(*getCredentialsOutput)
|
||||
if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil {
|
||||
r.Error = awserr.New("SerializationError",
|
||||
r.Error = awserr.New(request.ErrCodeSerialization,
|
||||
"failed to decode endpoint credentials",
|
||||
err,
|
||||
)
|
||||
|
@ -178,11 +186,15 @@ func unmarshalError(r *request.Request) {
|
|||
defer r.HTTPResponse.Body.Close()
|
||||
|
||||
var errOut errorOutput
|
||||
if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&errOut); err != nil {
|
||||
r.Error = awserr.New("SerializationError",
|
||||
"failed to decode endpoint credentials",
|
||||
err,
|
||||
err := jsonutil.UnmarshalJSONError(&errOut, r.HTTPResponse.Body)
|
||||
if err != nil {
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to decode error message", err),
|
||||
r.HTTPResponse.StatusCode,
|
||||
r.RequestID,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// Response body format is not consistent between metadata endpoints.
|
||||
|
|
4
vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
|
@ -12,14 +12,10 @@ const EnvProviderName = "EnvProvider"
|
|||
var (
|
||||
// ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be
|
||||
// found in the process's environment.
|
||||
//
|
||||
// @readonly
|
||||
ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil)
|
||||
|
||||
// ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key
|
||||
// can't be found in the process's environment.
|
||||
//
|
||||
// @readonly
|
||||
ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil)
|
||||
)
|
||||
|
||||
|
|
426
vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go
generated
vendored
Normal file
426
vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go
generated
vendored
Normal file
|
@ -0,0 +1,426 @@
|
|||
/*
|
||||
Package processcreds is a credential Provider to retrieve `credential_process`
|
||||
credentials.
|
||||
|
||||
WARNING: The following describes a method of sourcing credentials from an external
|
||||
process. This can potentially be dangerous, so proceed with caution. Other
|
||||
credential providers should be preferred if at all possible. If using this
|
||||
option, you should make sure that the config file is as locked down as possible
|
||||
using security best practices for your operating system.
|
||||
|
||||
You can use credentials from a `credential_process` in a variety of ways.
|
||||
|
||||
One way is to setup your shared config file, located in the default
|
||||
location, with the `credential_process` key and the command you want to be
|
||||
called. You also need to set the AWS_SDK_LOAD_CONFIG environment variable
|
||||
(e.g., `export AWS_SDK_LOAD_CONFIG=1`) to use the shared config file.
|
||||
|
||||
[default]
|
||||
credential_process = /command/to/call
|
||||
|
||||
Creating a new session will use the credential process to retrieve credentials.
|
||||
NOTE: If there are credentials in the profile you are using, the credential
|
||||
process will not be used.
|
||||
|
||||
// Initialize a session to load credentials.
|
||||
sess, _ := session.NewSession(&aws.Config{
|
||||
Region: aws.String("us-east-1")},
|
||||
)
|
||||
|
||||
// Create S3 service client to use the credentials.
|
||||
svc := s3.New(sess)
|
||||
|
||||
Another way to use the `credential_process` method is by using
|
||||
`credentials.NewCredentials()` and providing a command to be executed to
|
||||
retrieve credentials:
|
||||
|
||||
// Create credentials using the ProcessProvider.
|
||||
creds := processcreds.NewCredentials("/path/to/command")
|
||||
|
||||
// Create service client value configured for credentials.
|
||||
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
||||
|
||||
You can set a non-default timeout for the `credential_process` with another
|
||||
constructor, `credentials.NewCredentialsTimeout()`, providing the timeout. To
|
||||
set a one minute timeout:
|
||||
|
||||
// Create credentials using the ProcessProvider.
|
||||
creds := processcreds.NewCredentialsTimeout(
|
||||
"/path/to/command",
|
||||
time.Duration(500) * time.Millisecond)
|
||||
|
||||
If you need more control, you can set any configurable options in the
|
||||
credentials using one or more option functions. For example, you can set a two
|
||||
minute timeout, a credential duration of 60 minutes, and a maximum stdout
|
||||
buffer size of 2k.
|
||||
|
||||
creds := processcreds.NewCredentials(
|
||||
"/path/to/command",
|
||||
func(opt *ProcessProvider) {
|
||||
opt.Timeout = time.Duration(2) * time.Minute
|
||||
opt.Duration = time.Duration(60) * time.Minute
|
||||
opt.MaxBufSize = 2048
|
||||
})
|
||||
|
||||
You can also use your own `exec.Cmd`:
|
||||
|
||||
// Create an exec.Cmd
|
||||
myCommand := exec.Command("/path/to/command")
|
||||
|
||||
// Create credentials using your exec.Cmd and custom timeout
|
||||
creds := processcreds.NewCredentialsCommand(
|
||||
myCommand,
|
||||
func(opt *processcreds.ProcessProvider) {
|
||||
opt.Timeout = time.Duration(1) * time.Second
|
||||
})
|
||||
*/
|
||||
package processcreds
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/internal/sdkio"
|
||||
)
|
||||
|
||||
const (
|
||||
// ProviderName is the name this credentials provider will label any
|
||||
// returned credentials Value with.
|
||||
ProviderName = `ProcessProvider`
|
||||
|
||||
// ErrCodeProcessProviderParse error parsing process output
|
||||
ErrCodeProcessProviderParse = "ProcessProviderParseError"
|
||||
|
||||
// ErrCodeProcessProviderVersion version error in output
|
||||
ErrCodeProcessProviderVersion = "ProcessProviderVersionError"
|
||||
|
||||
// ErrCodeProcessProviderRequired required attribute missing in output
|
||||
ErrCodeProcessProviderRequired = "ProcessProviderRequiredError"
|
||||
|
||||
// ErrCodeProcessProviderExecution execution of command failed
|
||||
ErrCodeProcessProviderExecution = "ProcessProviderExecutionError"
|
||||
|
||||
// errMsgProcessProviderTimeout process took longer than allowed
|
||||
errMsgProcessProviderTimeout = "credential process timed out"
|
||||
|
||||
// errMsgProcessProviderProcess process error
|
||||
errMsgProcessProviderProcess = "error in credential_process"
|
||||
|
||||
// errMsgProcessProviderParse problem parsing output
|
||||
errMsgProcessProviderParse = "parse failed of credential_process output"
|
||||
|
||||
// errMsgProcessProviderVersion version error in output
|
||||
errMsgProcessProviderVersion = "wrong version in process output (not 1)"
|
||||
|
||||
// errMsgProcessProviderMissKey missing access key id in output
|
||||
errMsgProcessProviderMissKey = "missing AccessKeyId in process output"
|
||||
|
||||
// errMsgProcessProviderMissSecret missing secret acess key in output
|
||||
errMsgProcessProviderMissSecret = "missing SecretAccessKey in process output"
|
||||
|
||||
// errMsgProcessProviderPrepareCmd prepare of command failed
|
||||
errMsgProcessProviderPrepareCmd = "failed to prepare command"
|
||||
|
||||
// errMsgProcessProviderEmptyCmd command must not be empty
|
||||
errMsgProcessProviderEmptyCmd = "command must not be empty"
|
||||
|
||||
// errMsgProcessProviderPipe failed to initialize pipe
|
||||
errMsgProcessProviderPipe = "failed to initialize pipe"
|
||||
|
||||
// DefaultDuration is the default amount of time in minutes that the
|
||||
// credentials will be valid for.
|
||||
DefaultDuration = time.Duration(15) * time.Minute
|
||||
|
||||
// DefaultBufSize limits buffer size from growing to an enormous
|
||||
// amount due to a faulty process.
|
||||
DefaultBufSize = int(8 * sdkio.KibiByte)
|
||||
|
||||
// DefaultTimeout default limit on time a process can run.
|
||||
DefaultTimeout = time.Duration(1) * time.Minute
|
||||
)
|
||||
|
||||
// ProcessProvider satisfies the credentials.Provider interface, and is a
|
||||
// client to retrieve credentials from a process.
|
||||
type ProcessProvider struct {
|
||||
staticCreds bool
|
||||
credentials.Expiry
|
||||
originalCommand []string
|
||||
|
||||
// Expiry duration of the credentials. Defaults to 15 minutes if not set.
|
||||
Duration time.Duration
|
||||
|
||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
||||
// the credentials actually expiring. This is beneficial so race conditions
|
||||
// with expiring credentials do not cause request to fail unexpectedly
|
||||
// due to ExpiredTokenException exceptions.
|
||||
//
|
||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
||||
// 10 seconds before the credentials are actually expired.
|
||||
//
|
||||
// If ExpiryWindow is 0 or less it will be ignored.
|
||||
ExpiryWindow time.Duration
|
||||
|
||||
// A string representing an os command that should return a JSON with
|
||||
// credential information.
|
||||
command *exec.Cmd
|
||||
|
||||
// MaxBufSize limits memory usage from growing to an enormous
|
||||
// amount due to a faulty process.
|
||||
MaxBufSize int
|
||||
|
||||
// Timeout limits the time a process can run.
|
||||
Timeout time.Duration
|
||||
}
|
||||
|
||||
// NewCredentials returns a pointer to a new Credentials object wrapping the
|
||||
// ProcessProvider. The credentials will expire every 15 minutes by default.
|
||||
func NewCredentials(command string, options ...func(*ProcessProvider)) *credentials.Credentials {
|
||||
p := &ProcessProvider{
|
||||
command: exec.Command(command),
|
||||
Duration: DefaultDuration,
|
||||
Timeout: DefaultTimeout,
|
||||
MaxBufSize: DefaultBufSize,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(p)
|
||||
}
|
||||
|
||||
return credentials.NewCredentials(p)
|
||||
}
|
||||
|
||||
// NewCredentialsTimeout returns a pointer to a new Credentials object with
|
||||
// the specified command and timeout, and default duration and max buffer size.
|
||||
func NewCredentialsTimeout(command string, timeout time.Duration) *credentials.Credentials {
|
||||
p := NewCredentials(command, func(opt *ProcessProvider) {
|
||||
opt.Timeout = timeout
|
||||
})
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
// NewCredentialsCommand returns a pointer to a new Credentials object with
|
||||
// the specified command, and default timeout, duration and max buffer size.
|
||||
func NewCredentialsCommand(command *exec.Cmd, options ...func(*ProcessProvider)) *credentials.Credentials {
|
||||
p := &ProcessProvider{
|
||||
command: command,
|
||||
Duration: DefaultDuration,
|
||||
Timeout: DefaultTimeout,
|
||||
MaxBufSize: DefaultBufSize,
|
||||
}
|
||||
|
||||
for _, option := range options {
|
||||
option(p)
|
||||
}
|
||||
|
||||
return credentials.NewCredentials(p)
|
||||
}
|
||||
|
||||
type credentialProcessResponse struct {
|
||||
Version int
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SecretAccessKey string
|
||||
SessionToken string
|
||||
Expiration *time.Time
|
||||
}
|
||||
|
||||
// Retrieve executes the 'credential_process' and returns the credentials.
|
||||
func (p *ProcessProvider) Retrieve() (credentials.Value, error) {
|
||||
out, err := p.executeCredentialProcess()
|
||||
if err != nil {
|
||||
return credentials.Value{ProviderName: ProviderName}, err
|
||||
}
|
||||
|
||||
// Serialize and validate response
|
||||
resp := &credentialProcessResponse{}
|
||||
if err = json.Unmarshal(out, resp); err != nil {
|
||||
return credentials.Value{ProviderName: ProviderName}, awserr.New(
|
||||
ErrCodeProcessProviderParse,
|
||||
fmt.Sprintf("%s: %s", errMsgProcessProviderParse, string(out)),
|
||||
err)
|
||||
}
|
||||
|
||||
if resp.Version != 1 {
|
||||
return credentials.Value{ProviderName: ProviderName}, awserr.New(
|
||||
ErrCodeProcessProviderVersion,
|
||||
errMsgProcessProviderVersion,
|
||||
nil)
|
||||
}
|
||||
|
||||
if len(resp.AccessKeyID) == 0 {
|
||||
return credentials.Value{ProviderName: ProviderName}, awserr.New(
|
||||
ErrCodeProcessProviderRequired,
|
||||
errMsgProcessProviderMissKey,
|
||||
nil)
|
||||
}
|
||||
|
||||
if len(resp.SecretAccessKey) == 0 {
|
||||
return credentials.Value{ProviderName: ProviderName}, awserr.New(
|
||||
ErrCodeProcessProviderRequired,
|
||||
errMsgProcessProviderMissSecret,
|
||||
nil)
|
||||
}
|
||||
|
||||
// Handle expiration
|
||||
p.staticCreds = resp.Expiration == nil
|
||||
if resp.Expiration != nil {
|
||||
p.SetExpiration(*resp.Expiration, p.ExpiryWindow)
|
||||
}
|
||||
|
||||
return credentials.Value{
|
||||
ProviderName: ProviderName,
|
||||
AccessKeyID: resp.AccessKeyID,
|
||||
SecretAccessKey: resp.SecretAccessKey,
|
||||
SessionToken: resp.SessionToken,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// IsExpired returns true if the credentials retrieved are expired, or not yet
|
||||
// retrieved.
|
||||
func (p *ProcessProvider) IsExpired() bool {
|
||||
if p.staticCreds {
|
||||
return false
|
||||
}
|
||||
return p.Expiry.IsExpired()
|
||||
}
|
||||
|
||||
// prepareCommand prepares the command to be executed.
|
||||
func (p *ProcessProvider) prepareCommand() error {
|
||||
|
||||
var cmdArgs []string
|
||||
if runtime.GOOS == "windows" {
|
||||
cmdArgs = []string{"cmd.exe", "/C"}
|
||||
} else {
|
||||
cmdArgs = []string{"sh", "-c"}
|
||||
}
|
||||
|
||||
if len(p.originalCommand) == 0 {
|
||||
p.originalCommand = make([]string, len(p.command.Args))
|
||||
copy(p.originalCommand, p.command.Args)
|
||||
|
||||
// check for empty command because it succeeds
|
||||
if len(strings.TrimSpace(p.originalCommand[0])) < 1 {
|
||||
return awserr.New(
|
||||
ErrCodeProcessProviderExecution,
|
||||
fmt.Sprintf(
|
||||
"%s: %s",
|
||||
errMsgProcessProviderPrepareCmd,
|
||||
errMsgProcessProviderEmptyCmd),
|
||||
nil)
|
||||
}
|
||||
}
|
||||
|
||||
cmdArgs = append(cmdArgs, p.originalCommand...)
|
||||
p.command = exec.Command(cmdArgs[0], cmdArgs[1:]...)
|
||||
p.command.Env = os.Environ()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// executeCredentialProcess starts the credential process on the OS and
|
||||
// returns the results or an error.
|
||||
func (p *ProcessProvider) executeCredentialProcess() ([]byte, error) {
|
||||
|
||||
if err := p.prepareCommand(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Setup the pipes
|
||||
outReadPipe, outWritePipe, err := os.Pipe()
|
||||
if err != nil {
|
||||
return nil, awserr.New(
|
||||
ErrCodeProcessProviderExecution,
|
||||
errMsgProcessProviderPipe,
|
||||
err)
|
||||
}
|
||||
|
||||
p.command.Stderr = os.Stderr // display stderr on console for MFA
|
||||
p.command.Stdout = outWritePipe // get creds json on process's stdout
|
||||
p.command.Stdin = os.Stdin // enable stdin for MFA
|
||||
|
||||
output := bytes.NewBuffer(make([]byte, 0, p.MaxBufSize))
|
||||
|
||||
stdoutCh := make(chan error, 1)
|
||||
go readInput(
|
||||
io.LimitReader(outReadPipe, int64(p.MaxBufSize)),
|
||||
output,
|
||||
stdoutCh)
|
||||
|
||||
execCh := make(chan error, 1)
|
||||
go executeCommand(*p.command, execCh)
|
||||
|
||||
finished := false
|
||||
var errors []error
|
||||
for !finished {
|
||||
select {
|
||||
case readError := <-stdoutCh:
|
||||
errors = appendError(errors, readError)
|
||||
finished = true
|
||||
case execError := <-execCh:
|
||||
err := outWritePipe.Close()
|
||||
errors = appendError(errors, err)
|
||||
errors = appendError(errors, execError)
|
||||
if errors != nil {
|
||||
return output.Bytes(), awserr.NewBatchError(
|
||||
ErrCodeProcessProviderExecution,
|
||||
errMsgProcessProviderProcess,
|
||||
errors)
|
||||
}
|
||||
case <-time.After(p.Timeout):
|
||||
finished = true
|
||||
return output.Bytes(), awserr.NewBatchError(
|
||||
ErrCodeProcessProviderExecution,
|
||||
errMsgProcessProviderTimeout,
|
||||
errors) // errors can be nil
|
||||
}
|
||||
}
|
||||
|
||||
out := output.Bytes()
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
// windows adds slashes to quotes
|
||||
out = []byte(strings.Replace(string(out), `\"`, `"`, -1))
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// appendError conveniently checks for nil before appending slice
|
||||
func appendError(errors []error, err error) []error {
|
||||
if err != nil {
|
||||
return append(errors, err)
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
func executeCommand(cmd exec.Cmd, exec chan error) {
|
||||
// Start the command
|
||||
err := cmd.Start()
|
||||
if err == nil {
|
||||
err = cmd.Wait()
|
||||
}
|
||||
|
||||
exec <- err
|
||||
}
|
||||
|
||||
func readInput(r io.Reader, w io.Writer, read chan error) {
|
||||
tee := io.TeeReader(r, w)
|
||||
|
||||
_, err := ioutil.ReadAll(tee)
|
||||
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
}
|
||||
|
||||
read <- err // will only arrive here when write end of pipe is closed
|
||||
}
|
30
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
30
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
|
@ -4,9 +4,8 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/go-ini/ini"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/internal/ini"
|
||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||
)
|
||||
|
||||
|
@ -77,36 +76,37 @@ func (p *SharedCredentialsProvider) IsExpired() bool {
|
|||
// The credentials retrieved from the profile will be returned or error. Error will be
|
||||
// returned if it fails to read from the file, or the data is invalid.
|
||||
func loadProfile(filename, profile string) (Value, error) {
|
||||
config, err := ini.Load(filename)
|
||||
config, err := ini.OpenFile(filename)
|
||||
if err != nil {
|
||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err)
|
||||
}
|
||||
iniProfile, err := config.GetSection(profile)
|
||||
if err != nil {
|
||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", err)
|
||||
|
||||
iniProfile, ok := config.GetSection(profile)
|
||||
if !ok {
|
||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", nil)
|
||||
}
|
||||
|
||||
id, err := iniProfile.GetKey("aws_access_key_id")
|
||||
if err != nil {
|
||||
id := iniProfile.String("aws_access_key_id")
|
||||
if len(id) == 0 {
|
||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey",
|
||||
fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
|
||||
err)
|
||||
nil)
|
||||
}
|
||||
|
||||
secret, err := iniProfile.GetKey("aws_secret_access_key")
|
||||
if err != nil {
|
||||
secret := iniProfile.String("aws_secret_access_key")
|
||||
if len(secret) == 0 {
|
||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret",
|
||||
fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename),
|
||||
nil)
|
||||
}
|
||||
|
||||
// Default to empty string if not found
|
||||
token := iniProfile.Key("aws_session_token")
|
||||
token := iniProfile.String("aws_session_token")
|
||||
|
||||
return Value{
|
||||
AccessKeyID: id.String(),
|
||||
SecretAccessKey: secret.String(),
|
||||
SessionToken: token.String(),
|
||||
AccessKeyID: id,
|
||||
SecretAccessKey: secret,
|
||||
SessionToken: token,
|
||||
ProviderName: SharedCredsProviderName,
|
||||
}, nil
|
||||
}
|
||||
|
|
2
vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
|
@ -9,8 +9,6 @@ const StaticProviderName = "StaticProvider"
|
|||
|
||||
var (
|
||||
// ErrStaticCredentialsEmpty is emitted when static credentials are empty.
|
||||
//
|
||||
// @readonly
|
||||
ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil)
|
||||
)
|
||||
|
||||
|
|
37
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
37
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
|
@ -80,16 +80,18 @@ package stscreds
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"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/internal/sdkrand"
|
||||
"github.com/aws/aws-sdk-go/service/sts"
|
||||
)
|
||||
|
||||
// StdinTokenProvider will prompt on stdout and read from stdin for a string value.
|
||||
// StdinTokenProvider will prompt on stderr and read from stdin for a string value.
|
||||
// An error is returned if reading from stdin fails.
|
||||
//
|
||||
// Use this function go read MFA tokens from stdin. The function makes no attempt
|
||||
|
@ -102,7 +104,7 @@ import (
|
|||
// Will wait forever until something is provided on the stdin.
|
||||
func StdinTokenProvider() (string, error) {
|
||||
var v string
|
||||
fmt.Printf("Assume Role MFA token code: ")
|
||||
fmt.Fprintf(os.Stderr, "Assume Role MFA token code: ")
|
||||
_, err := fmt.Scanln(&v)
|
||||
|
||||
return v, err
|
||||
|
@ -142,6 +144,13 @@ type AssumeRoleProvider struct {
|
|||
// Session name, if you wish to reuse the credentials elsewhere.
|
||||
RoleSessionName string
|
||||
|
||||
// Optional, you can pass tag key-value pairs to your session. These tags are called session tags.
|
||||
Tags []*sts.Tag
|
||||
|
||||
// A list of keys for session tags that you want to set as transitive.
|
||||
// If you set a tag key as transitive, the corresponding key and value passes to subsequent sessions in a role chain.
|
||||
TransitiveTagKeys []*string
|
||||
|
||||
// Expiry duration of the STS credentials. Defaults to 15 minutes if not set.
|
||||
Duration time.Duration
|
||||
|
||||
|
@ -193,6 +202,18 @@ type AssumeRoleProvider struct {
|
|||
//
|
||||
// If ExpiryWindow is 0 or less it will be ignored.
|
||||
ExpiryWindow time.Duration
|
||||
|
||||
// MaxJitterFrac reduces the effective Duration of each credential requested
|
||||
// by a random percentage between 0 and MaxJitterFraction. MaxJitterFrac must
|
||||
// have a value between 0 and 1. Any other value may lead to expected behavior.
|
||||
// With a MaxJitterFrac value of 0, default) will no jitter will be used.
|
||||
//
|
||||
// For example, with a Duration of 30m and a MaxJitterFrac of 0.1, the
|
||||
// AssumeRole call will be made with an arbitrary Duration between 27m and
|
||||
// 30m.
|
||||
//
|
||||
// MaxJitterFrac should not be negative.
|
||||
MaxJitterFrac float64
|
||||
}
|
||||
|
||||
// NewCredentials returns a pointer to a new Credentials object wrapping the
|
||||
|
@ -244,7 +265,6 @@ func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*
|
|||
|
||||
// Retrieve generates a new set of temporary credentials using STS.
|
||||
func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
|
||||
|
||||
// Apply defaults where parameters are not set.
|
||||
if p.RoleSessionName == "" {
|
||||
// Try to work out a role name that will hopefully end up unique.
|
||||
|
@ -254,11 +274,14 @@ func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
|
|||
// Expire as often as AWS permits.
|
||||
p.Duration = DefaultDuration
|
||||
}
|
||||
jitter := time.Duration(sdkrand.SeededRand.Float64() * p.MaxJitterFrac * float64(p.Duration))
|
||||
input := &sts.AssumeRoleInput{
|
||||
DurationSeconds: aws.Int64(int64(p.Duration / time.Second)),
|
||||
RoleArn: aws.String(p.RoleARN),
|
||||
RoleSessionName: aws.String(p.RoleSessionName),
|
||||
ExternalId: p.ExternalID,
|
||||
DurationSeconds: aws.Int64(int64((p.Duration - jitter) / time.Second)),
|
||||
RoleArn: aws.String(p.RoleARN),
|
||||
RoleSessionName: aws.String(p.RoleSessionName),
|
||||
ExternalId: p.ExternalID,
|
||||
Tags: p.Tags,
|
||||
TransitiveTagKeys: p.TransitiveTagKeys,
|
||||
}
|
||||
if p.Policy != nil {
|
||||
input.Policy = p.Policy
|
||||
|
|
100
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go
generated
vendored
Normal file
100
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/web_identity_provider.go
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
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)
|
||||
}
|
||||
req, resp := p.client.AssumeRoleWithWebIdentityRequest(&sts.AssumeRoleWithWebIdentityInput{
|
||||
RoleArn: &p.roleARN,
|
||||
RoleSessionName: &sessionName,
|
||||
WebIdentityToken: aws.String(string(b)),
|
||||
})
|
||||
// InvalidIdentityToken error is a temporary error that can occur
|
||||
// when assuming an Role with a JWT web identity token.
|
||||
req.RetryErrorCodes = append(req.RetryErrorCodes, sts.ErrCodeInvalidIdentityTokenException)
|
||||
if err := req.Send(); 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
|
||||
}
|
69
vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go
generated
vendored
Normal file
69
vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
// Package csm provides the Client Side Monitoring (CSM) client which enables
|
||||
// sending metrics via UDP connection to the CSM agent. This package provides
|
||||
// control options, and configuration for the CSM client. The client can be
|
||||
// controlled manually, or automatically via the SDK's Session configuration.
|
||||
//
|
||||
// Enabling CSM client via SDK's Session configuration
|
||||
//
|
||||
// The CSM client can be enabled automatically via SDK's Session configuration.
|
||||
// The SDK's session configuration enables the CSM client if the AWS_CSM_PORT
|
||||
// environment variable is set to a non-empty value.
|
||||
//
|
||||
// The configuration options for the CSM client via the SDK's session
|
||||
// configuration are:
|
||||
//
|
||||
// * AWS_CSM_PORT=<port number>
|
||||
// The port number the CSM agent will receive metrics on.
|
||||
//
|
||||
// * AWS_CSM_HOST=<hostname or ip>
|
||||
// The hostname, or IP address the CSM agent will receive metrics on.
|
||||
// Without port number.
|
||||
//
|
||||
// Manually enabling the CSM client
|
||||
//
|
||||
// The CSM client can be started, paused, and resumed manually. The Start
|
||||
// function will enable the CSM client to publish metrics to the CSM agent. It
|
||||
// is safe to call Start concurrently, but if Start is called additional times
|
||||
// with different ClientID or address it will panic.
|
||||
//
|
||||
// r, err := csm.Start("clientID", ":31000")
|
||||
// if err != nil {
|
||||
// panic(fmt.Errorf("failed starting CSM: %v", err))
|
||||
// }
|
||||
//
|
||||
// When controlling the CSM client manually, you must also inject its request
|
||||
// handlers into the SDK's Session configuration for the SDK's API clients to
|
||||
// publish metrics.
|
||||
//
|
||||
// sess, err := session.NewSession(&aws.Config{})
|
||||
// if err != nil {
|
||||
// panic(fmt.Errorf("failed loading session: %v", err))
|
||||
// }
|
||||
//
|
||||
// // Add CSM client's metric publishing request handlers to the SDK's
|
||||
// // Session Configuration.
|
||||
// r.InjectHandlers(&sess.Handlers)
|
||||
//
|
||||
// Controlling CSM client
|
||||
//
|
||||
// Once the CSM client has been enabled the Get function will return a Reporter
|
||||
// value that you can use to pause and resume the metrics published to the CSM
|
||||
// agent. If Get function is called before the reporter is enabled with the
|
||||
// Start function or via SDK's Session configuration nil will be returned.
|
||||
//
|
||||
// The Pause method can be called to stop the CSM client publishing metrics to
|
||||
// the CSM agent. The Continue method will resume metric publishing.
|
||||
//
|
||||
// // Get the CSM client Reporter.
|
||||
// r := csm.Get()
|
||||
//
|
||||
// // Will pause monitoring
|
||||
// r.Pause()
|
||||
// resp, err = client.GetObject(&s3.GetObjectInput{
|
||||
// Bucket: aws.String("bucket"),
|
||||
// Key: aws.String("key"),
|
||||
// })
|
||||
//
|
||||
// // Resume monitoring
|
||||
// r.Continue()
|
||||
package csm
|
89
vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go
generated
vendored
Normal file
89
vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go
generated
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
package csm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
lock sync.Mutex
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultPort is used when no port is specified.
|
||||
DefaultPort = "31000"
|
||||
|
||||
// DefaultHost is the host that will be used when none is specified.
|
||||
DefaultHost = "127.0.0.1"
|
||||
)
|
||||
|
||||
// AddressWithDefaults returns a CSM address built from the host and port
|
||||
// values. If the host or port is not set, default values will be used
|
||||
// instead. If host is "localhost" it will be replaced with "127.0.0.1".
|
||||
func AddressWithDefaults(host, port string) string {
|
||||
if len(host) == 0 || strings.EqualFold(host, "localhost") {
|
||||
host = DefaultHost
|
||||
}
|
||||
|
||||
if len(port) == 0 {
|
||||
port = DefaultPort
|
||||
}
|
||||
|
||||
// Only IP6 host can contain a colon
|
||||
if strings.Contains(host, ":") {
|
||||
return "[" + host + "]:" + port
|
||||
}
|
||||
|
||||
return host + ":" + port
|
||||
}
|
||||
|
||||
// Start will start a long running go routine to capture
|
||||
// client side metrics. Calling start multiple time will only
|
||||
// start the metric listener once and will panic if a different
|
||||
// client ID or port is passed in.
|
||||
//
|
||||
// r, err := csm.Start("clientID", "127.0.0.1:31000")
|
||||
// if err != nil {
|
||||
// panic(fmt.Errorf("expected no error, but received %v", err))
|
||||
// }
|
||||
// sess := session.NewSession()
|
||||
// r.InjectHandlers(sess.Handlers)
|
||||
//
|
||||
// svc := s3.New(sess)
|
||||
// out, err := svc.GetObject(&s3.GetObjectInput{
|
||||
// Bucket: aws.String("bucket"),
|
||||
// Key: aws.String("key"),
|
||||
// })
|
||||
func Start(clientID string, url string) (*Reporter, error) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
if sender == nil {
|
||||
sender = newReporter(clientID, url)
|
||||
} else {
|
||||
if sender.clientID != clientID {
|
||||
panic(fmt.Errorf("inconsistent client IDs. %q was expected, but received %q", sender.clientID, clientID))
|
||||
}
|
||||
|
||||
if sender.url != url {
|
||||
panic(fmt.Errorf("inconsistent URLs. %q was expected, but received %q", sender.url, url))
|
||||
}
|
||||
}
|
||||
|
||||
if err := connect(url); err != nil {
|
||||
sender = nil
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return sender, nil
|
||||
}
|
||||
|
||||
// Get will return a reporter if one exists, if one does not exist, nil will
|
||||
// be returned.
|
||||
func Get() *Reporter {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
return sender
|
||||
}
|
109
vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go
generated
vendored
Normal file
109
vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
|||
package csm
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
)
|
||||
|
||||
type metricTime time.Time
|
||||
|
||||
func (t metricTime) MarshalJSON() ([]byte, error) {
|
||||
ns := time.Duration(time.Time(t).UnixNano())
|
||||
return []byte(strconv.FormatInt(int64(ns/time.Millisecond), 10)), nil
|
||||
}
|
||||
|
||||
type metric struct {
|
||||
ClientID *string `json:"ClientId,omitempty"`
|
||||
API *string `json:"Api,omitempty"`
|
||||
Service *string `json:"Service,omitempty"`
|
||||
Timestamp *metricTime `json:"Timestamp,omitempty"`
|
||||
Type *string `json:"Type,omitempty"`
|
||||
Version *int `json:"Version,omitempty"`
|
||||
|
||||
AttemptCount *int `json:"AttemptCount,omitempty"`
|
||||
Latency *int `json:"Latency,omitempty"`
|
||||
|
||||
Fqdn *string `json:"Fqdn,omitempty"`
|
||||
UserAgent *string `json:"UserAgent,omitempty"`
|
||||
AttemptLatency *int `json:"AttemptLatency,omitempty"`
|
||||
|
||||
SessionToken *string `json:"SessionToken,omitempty"`
|
||||
Region *string `json:"Region,omitempty"`
|
||||
AccessKey *string `json:"AccessKey,omitempty"`
|
||||
HTTPStatusCode *int `json:"HttpStatusCode,omitempty"`
|
||||
XAmzID2 *string `json:"XAmzId2,omitempty"`
|
||||
XAmzRequestID *string `json:"XAmznRequestId,omitempty"`
|
||||
|
||||
AWSException *string `json:"AwsException,omitempty"`
|
||||
AWSExceptionMessage *string `json:"AwsExceptionMessage,omitempty"`
|
||||
SDKException *string `json:"SdkException,omitempty"`
|
||||
SDKExceptionMessage *string `json:"SdkExceptionMessage,omitempty"`
|
||||
|
||||
FinalHTTPStatusCode *int `json:"FinalHttpStatusCode,omitempty"`
|
||||
FinalAWSException *string `json:"FinalAwsException,omitempty"`
|
||||
FinalAWSExceptionMessage *string `json:"FinalAwsExceptionMessage,omitempty"`
|
||||
FinalSDKException *string `json:"FinalSdkException,omitempty"`
|
||||
FinalSDKExceptionMessage *string `json:"FinalSdkExceptionMessage,omitempty"`
|
||||
|
||||
DestinationIP *string `json:"DestinationIp,omitempty"`
|
||||
ConnectionReused *int `json:"ConnectionReused,omitempty"`
|
||||
|
||||
AcquireConnectionLatency *int `json:"AcquireConnectionLatency,omitempty"`
|
||||
ConnectLatency *int `json:"ConnectLatency,omitempty"`
|
||||
RequestLatency *int `json:"RequestLatency,omitempty"`
|
||||
DNSLatency *int `json:"DnsLatency,omitempty"`
|
||||
TCPLatency *int `json:"TcpLatency,omitempty"`
|
||||
SSLLatency *int `json:"SslLatency,omitempty"`
|
||||
|
||||
MaxRetriesExceeded *int `json:"MaxRetriesExceeded,omitempty"`
|
||||
}
|
||||
|
||||
func (m *metric) TruncateFields() {
|
||||
m.ClientID = truncateString(m.ClientID, 255)
|
||||
m.UserAgent = truncateString(m.UserAgent, 256)
|
||||
|
||||
m.AWSException = truncateString(m.AWSException, 128)
|
||||
m.AWSExceptionMessage = truncateString(m.AWSExceptionMessage, 512)
|
||||
|
||||
m.SDKException = truncateString(m.SDKException, 128)
|
||||
m.SDKExceptionMessage = truncateString(m.SDKExceptionMessage, 512)
|
||||
|
||||
m.FinalAWSException = truncateString(m.FinalAWSException, 128)
|
||||
m.FinalAWSExceptionMessage = truncateString(m.FinalAWSExceptionMessage, 512)
|
||||
|
||||
m.FinalSDKException = truncateString(m.FinalSDKException, 128)
|
||||
m.FinalSDKExceptionMessage = truncateString(m.FinalSDKExceptionMessage, 512)
|
||||
}
|
||||
|
||||
func truncateString(v *string, l int) *string {
|
||||
if v != nil && len(*v) > l {
|
||||
nv := (*v)[:l]
|
||||
return &nv
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (m *metric) SetException(e metricException) {
|
||||
switch te := e.(type) {
|
||||
case awsException:
|
||||
m.AWSException = aws.String(te.exception)
|
||||
m.AWSExceptionMessage = aws.String(te.message)
|
||||
case sdkException:
|
||||
m.SDKException = aws.String(te.exception)
|
||||
m.SDKExceptionMessage = aws.String(te.message)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *metric) SetFinalException(e metricException) {
|
||||
switch te := e.(type) {
|
||||
case awsException:
|
||||
m.FinalAWSException = aws.String(te.exception)
|
||||
m.FinalAWSExceptionMessage = aws.String(te.message)
|
||||
case sdkException:
|
||||
m.FinalSDKException = aws.String(te.exception)
|
||||
m.FinalSDKExceptionMessage = aws.String(te.message)
|
||||
}
|
||||
}
|
55
vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go
generated
vendored
Normal file
55
vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
package csm
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
const (
|
||||
runningEnum = iota
|
||||
pausedEnum
|
||||
)
|
||||
|
||||
var (
|
||||
// MetricsChannelSize of metrics to hold in the channel
|
||||
MetricsChannelSize = 100
|
||||
)
|
||||
|
||||
type metricChan struct {
|
||||
ch chan metric
|
||||
paused *int64
|
||||
}
|
||||
|
||||
func newMetricChan(size int) metricChan {
|
||||
return metricChan{
|
||||
ch: make(chan metric, size),
|
||||
paused: new(int64),
|
||||
}
|
||||
}
|
||||
|
||||
func (ch *metricChan) Pause() {
|
||||
atomic.StoreInt64(ch.paused, pausedEnum)
|
||||
}
|
||||
|
||||
func (ch *metricChan) Continue() {
|
||||
atomic.StoreInt64(ch.paused, runningEnum)
|
||||
}
|
||||
|
||||
func (ch *metricChan) IsPaused() bool {
|
||||
v := atomic.LoadInt64(ch.paused)
|
||||
return v == pausedEnum
|
||||
}
|
||||
|
||||
// Push will push metrics to the metric channel if the channel
|
||||
// is not paused
|
||||
func (ch *metricChan) Push(m metric) bool {
|
||||
if ch.IsPaused() {
|
||||
return false
|
||||
}
|
||||
|
||||
select {
|
||||
case ch.ch <- m:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
26
vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go
generated
vendored
Normal file
26
vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
package csm
|
||||
|
||||
type metricException interface {
|
||||
Exception() string
|
||||
Message() string
|
||||
}
|
||||
|
||||
type requestException struct {
|
||||
exception string
|
||||
message string
|
||||
}
|
||||
|
||||
func (e requestException) Exception() string {
|
||||
return e.exception
|
||||
}
|
||||
func (e requestException) Message() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
type awsException struct {
|
||||
requestException
|
||||
}
|
||||
|
||||
type sdkException struct {
|
||||
requestException
|
||||
}
|
264
vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go
generated
vendored
Normal file
264
vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go
generated
vendored
Normal file
|
@ -0,0 +1,264 @@
|
|||
package csm
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// Reporter will gather metrics of API requests made and
|
||||
// send those metrics to the CSM endpoint.
|
||||
type Reporter struct {
|
||||
clientID string
|
||||
url string
|
||||
conn net.Conn
|
||||
metricsCh metricChan
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
var (
|
||||
sender *Reporter
|
||||
)
|
||||
|
||||
func connect(url string) error {
|
||||
const network = "udp"
|
||||
if err := sender.connect(network, url); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if sender.done == nil {
|
||||
sender.done = make(chan struct{})
|
||||
go sender.start()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func newReporter(clientID, url string) *Reporter {
|
||||
return &Reporter{
|
||||
clientID: clientID,
|
||||
url: url,
|
||||
metricsCh: newMetricChan(MetricsChannelSize),
|
||||
}
|
||||
}
|
||||
|
||||
func (rep *Reporter) sendAPICallAttemptMetric(r *request.Request) {
|
||||
if rep == nil {
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
creds, _ := r.Config.Credentials.Get()
|
||||
|
||||
m := metric{
|
||||
ClientID: aws.String(rep.clientID),
|
||||
API: aws.String(r.Operation.Name),
|
||||
Service: aws.String(r.ClientInfo.ServiceID),
|
||||
Timestamp: (*metricTime)(&now),
|
||||
UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")),
|
||||
Region: r.Config.Region,
|
||||
Type: aws.String("ApiCallAttempt"),
|
||||
Version: aws.Int(1),
|
||||
|
||||
XAmzRequestID: aws.String(r.RequestID),
|
||||
|
||||
AttemptLatency: aws.Int(int(now.Sub(r.AttemptTime).Nanoseconds() / int64(time.Millisecond))),
|
||||
AccessKey: aws.String(creds.AccessKeyID),
|
||||
}
|
||||
|
||||
if r.HTTPResponse != nil {
|
||||
m.HTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode)
|
||||
}
|
||||
|
||||
if r.Error != nil {
|
||||
if awserr, ok := r.Error.(awserr.Error); ok {
|
||||
m.SetException(getMetricException(awserr))
|
||||
}
|
||||
}
|
||||
|
||||
m.TruncateFields()
|
||||
rep.metricsCh.Push(m)
|
||||
}
|
||||
|
||||
func getMetricException(err awserr.Error) metricException {
|
||||
msg := err.Error()
|
||||
code := err.Code()
|
||||
|
||||
switch code {
|
||||
case request.ErrCodeRequestError,
|
||||
request.ErrCodeSerialization,
|
||||
request.CanceledErrorCode:
|
||||
return sdkException{
|
||||
requestException{exception: code, message: msg},
|
||||
}
|
||||
default:
|
||||
return awsException{
|
||||
requestException{exception: code, message: msg},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (rep *Reporter) sendAPICallMetric(r *request.Request) {
|
||||
if rep == nil {
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
m := metric{
|
||||
ClientID: aws.String(rep.clientID),
|
||||
API: aws.String(r.Operation.Name),
|
||||
Service: aws.String(r.ClientInfo.ServiceID),
|
||||
Timestamp: (*metricTime)(&now),
|
||||
UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")),
|
||||
Type: aws.String("ApiCall"),
|
||||
AttemptCount: aws.Int(r.RetryCount + 1),
|
||||
Region: r.Config.Region,
|
||||
Latency: aws.Int(int(time.Since(r.Time) / time.Millisecond)),
|
||||
XAmzRequestID: aws.String(r.RequestID),
|
||||
MaxRetriesExceeded: aws.Int(boolIntValue(r.RetryCount >= r.MaxRetries())),
|
||||
}
|
||||
|
||||
if r.HTTPResponse != nil {
|
||||
m.FinalHTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode)
|
||||
}
|
||||
|
||||
if r.Error != nil {
|
||||
if awserr, ok := r.Error.(awserr.Error); ok {
|
||||
m.SetFinalException(getMetricException(awserr))
|
||||
}
|
||||
}
|
||||
|
||||
m.TruncateFields()
|
||||
|
||||
// TODO: Probably want to figure something out for logging dropped
|
||||
// metrics
|
||||
rep.metricsCh.Push(m)
|
||||
}
|
||||
|
||||
func (rep *Reporter) connect(network, url string) error {
|
||||
if rep.conn != nil {
|
||||
rep.conn.Close()
|
||||
}
|
||||
|
||||
conn, err := net.Dial(network, url)
|
||||
if err != nil {
|
||||
return awserr.New("UDPError", "Could not connect", err)
|
||||
}
|
||||
|
||||
rep.conn = conn
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rep *Reporter) close() {
|
||||
if rep.done != nil {
|
||||
close(rep.done)
|
||||
}
|
||||
|
||||
rep.metricsCh.Pause()
|
||||
}
|
||||
|
||||
func (rep *Reporter) start() {
|
||||
defer func() {
|
||||
rep.metricsCh.Pause()
|
||||
}()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-rep.done:
|
||||
rep.done = nil
|
||||
return
|
||||
case m := <-rep.metricsCh.ch:
|
||||
// TODO: What to do with this error? Probably should just log
|
||||
b, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
rep.conn.Write(b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pause will pause the metric channel preventing any new metrics from being
|
||||
// added. It is safe to call concurrently with other calls to Pause, but if
|
||||
// called concurently with Continue can lead to unexpected state.
|
||||
func (rep *Reporter) Pause() {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
if rep == nil {
|
||||
return
|
||||
}
|
||||
|
||||
rep.close()
|
||||
}
|
||||
|
||||
// Continue will reopen the metric channel and allow for monitoring to be
|
||||
// resumed. It is safe to call concurrently with other calls to Continue, but
|
||||
// if called concurently with Pause can lead to unexpected state.
|
||||
func (rep *Reporter) Continue() {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
if rep == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !rep.metricsCh.IsPaused() {
|
||||
return
|
||||
}
|
||||
|
||||
rep.metricsCh.Continue()
|
||||
}
|
||||
|
||||
// Client side metric handler names
|
||||
const (
|
||||
APICallMetricHandlerName = "awscsm.SendAPICallMetric"
|
||||
APICallAttemptMetricHandlerName = "awscsm.SendAPICallAttemptMetric"
|
||||
)
|
||||
|
||||
// InjectHandlers will will enable client side metrics and inject the proper
|
||||
// handlers to handle how metrics are sent.
|
||||
//
|
||||
// InjectHandlers is NOT safe to call concurrently. Calling InjectHandlers
|
||||
// multiple times may lead to unexpected behavior, (e.g. duplicate metrics).
|
||||
//
|
||||
// // Start must be called in order to inject the correct handlers
|
||||
// r, err := csm.Start("clientID", "127.0.0.1:8094")
|
||||
// if err != nil {
|
||||
// panic(fmt.Errorf("expected no error, but received %v", err))
|
||||
// }
|
||||
//
|
||||
// sess := session.NewSession()
|
||||
// r.InjectHandlers(&sess.Handlers)
|
||||
//
|
||||
// // create a new service client with our client side metric session
|
||||
// svc := s3.New(sess)
|
||||
func (rep *Reporter) InjectHandlers(handlers *request.Handlers) {
|
||||
if rep == nil {
|
||||
return
|
||||
}
|
||||
|
||||
handlers.Complete.PushFrontNamed(request.NamedHandler{
|
||||
Name: APICallMetricHandlerName,
|
||||
Fn: rep.sendAPICallMetric,
|
||||
})
|
||||
|
||||
handlers.CompleteAttempt.PushFrontNamed(request.NamedHandler{
|
||||
Name: APICallAttemptMetricHandlerName,
|
||||
Fn: rep.sendAPICallAttemptMetric,
|
||||
})
|
||||
}
|
||||
|
||||
// boolIntValue return 1 for true and 0 for false.
|
||||
func boolIntValue(b bool) int {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
32
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
32
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||
)
|
||||
|
||||
// A Defaults provides a collection of default values for SDK clients.
|
||||
|
@ -73,6 +74,7 @@ func Handlers() request.Handlers {
|
|||
handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
||||
handlers.Validate.AfterEachFn = request.HandlerListStopOnError
|
||||
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
|
||||
handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHander)
|
||||
handlers.Build.AfterEachFn = request.HandlerListStopOnError
|
||||
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
||||
handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler)
|
||||
|
@ -91,17 +93,28 @@ func Handlers() request.Handlers {
|
|||
func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
|
||||
return credentials.NewCredentials(&credentials.ChainProvider{
|
||||
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
|
||||
Providers: []credentials.Provider{
|
||||
&credentials.EnvProvider{},
|
||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
|
||||
RemoteCredProvider(*cfg, handlers),
|
||||
},
|
||||
Providers: CredProviders(cfg, handlers),
|
||||
})
|
||||
}
|
||||
|
||||
// CredProviders returns the slice of providers used in
|
||||
// the default credential chain.
|
||||
//
|
||||
// For applications that need to use some other provider (for example use
|
||||
// different environment variables for legacy reasons) but still fall back
|
||||
// on the default chain of providers. This allows that default chaint to be
|
||||
// automatically updated
|
||||
func CredProviders(cfg *aws.Config, handlers request.Handlers) []credentials.Provider {
|
||||
return []credentials.Provider{
|
||||
&credentials.EnvProvider{},
|
||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
|
||||
RemoteCredProvider(*cfg, handlers),
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
|
||||
ecsCredsProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
||||
httpProviderAuthorizationEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN"
|
||||
httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
|
||||
)
|
||||
|
||||
// RemoteCredProvider returns a credentials provider for the default remote
|
||||
|
@ -111,8 +124,8 @@ func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.P
|
|||
return localHTTPCredProvider(cfg, handlers, u)
|
||||
}
|
||||
|
||||
if uri := os.Getenv(ecsCredsProviderEnvVar); len(uri) > 0 {
|
||||
u := fmt.Sprintf("http://169.254.170.2%s", uri)
|
||||
if uri := os.Getenv(shareddefaults.ECSCredsProviderEnvVar); len(uri) > 0 {
|
||||
u := fmt.Sprintf("%s%s", shareddefaults.ECSContainerCredentialsURI, uri)
|
||||
return httpCredProvider(cfg, handlers, u)
|
||||
}
|
||||
|
||||
|
@ -175,6 +188,7 @@ func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) crede
|
|||
return endpointcreds.NewProviderClient(cfg, handlers, u,
|
||||
func(p *endpointcreds.Provider) {
|
||||
p.ExpiryWindow = 5 * time.Minute
|
||||
p.AuthorizationToken = os.Getenv(httpProviderAuthorizationEnvVar)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
105
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
generated
vendored
105
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
generated
vendored
|
@ -4,28 +4,63 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/internal/sdkuri"
|
||||
)
|
||||
|
||||
// getToken uses the duration to return a token for EC2 metadata service,
|
||||
// or an error if the request failed.
|
||||
func (c *EC2Metadata) getToken(duration time.Duration) (tokenOutput, error) {
|
||||
op := &request.Operation{
|
||||
Name: "GetToken",
|
||||
HTTPMethod: "PUT",
|
||||
HTTPPath: "/api/token",
|
||||
}
|
||||
|
||||
var output tokenOutput
|
||||
req := c.NewRequest(op, nil, &output)
|
||||
|
||||
// remove the fetch token handler from the request handlers to avoid infinite recursion
|
||||
req.Handlers.Sign.RemoveByName(fetchTokenHandlerName)
|
||||
|
||||
// Swap the unmarshalMetadataHandler with unmarshalTokenHandler on this request.
|
||||
req.Handlers.Unmarshal.Swap(unmarshalMetadataHandlerName, unmarshalTokenHandler)
|
||||
|
||||
ttl := strconv.FormatInt(int64(duration/time.Second), 10)
|
||||
req.HTTPRequest.Header.Set(ttlHeader, ttl)
|
||||
|
||||
err := req.Send()
|
||||
|
||||
// Errors with bad request status should be returned.
|
||||
if err != nil {
|
||||
err = awserr.NewRequestFailure(
|
||||
awserr.New(req.HTTPResponse.Status, http.StatusText(req.HTTPResponse.StatusCode), err),
|
||||
req.HTTPResponse.StatusCode, req.RequestID)
|
||||
}
|
||||
|
||||
return output, err
|
||||
}
|
||||
|
||||
// GetMetadata uses the path provided to request information from the EC2
|
||||
// instance metdata service. The content will be returned as a string, or
|
||||
// instance metadata service. The content will be returned as a string, or
|
||||
// error if the request failed.
|
||||
func (c *EC2Metadata) GetMetadata(p string) (string, error) {
|
||||
op := &request.Operation{
|
||||
Name: "GetMetadata",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: path.Join("/", "meta-data", p),
|
||||
HTTPPath: sdkuri.PathJoin("/meta-data", p),
|
||||
}
|
||||
|
||||
output := &metadataOutput{}
|
||||
|
||||
req := c.NewRequest(op, nil, output)
|
||||
|
||||
return output.Content, req.Send()
|
||||
err := req.Send()
|
||||
return output.Content, err
|
||||
}
|
||||
|
||||
// GetUserData returns the userdata that was configured for the service. If
|
||||
|
@ -35,18 +70,14 @@ func (c *EC2Metadata) GetUserData() (string, error) {
|
|||
op := &request.Operation{
|
||||
Name: "GetUserData",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: path.Join("/", "user-data"),
|
||||
HTTPPath: "/user-data",
|
||||
}
|
||||
|
||||
output := &metadataOutput{}
|
||||
req := c.NewRequest(op, nil, output)
|
||||
req.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
|
||||
if r.HTTPResponse.StatusCode == http.StatusNotFound {
|
||||
r.Error = awserr.New("NotFoundError", "user-data not found", r.Error)
|
||||
}
|
||||
})
|
||||
|
||||
return output.Content, req.Send()
|
||||
err := req.Send()
|
||||
return output.Content, err
|
||||
}
|
||||
|
||||
// GetDynamicData uses the path provided to request information from the EC2
|
||||
|
@ -56,13 +87,14 @@ func (c *EC2Metadata) GetDynamicData(p string) (string, error) {
|
|||
op := &request.Operation{
|
||||
Name: "GetDynamicData",
|
||||
HTTPMethod: "GET",
|
||||
HTTPPath: path.Join("/", "dynamic", p),
|
||||
HTTPPath: sdkuri.PathJoin("/dynamic", p),
|
||||
}
|
||||
|
||||
output := &metadataOutput{}
|
||||
req := c.NewRequest(op, nil, output)
|
||||
|
||||
return output.Content, req.Send()
|
||||
err := req.Send()
|
||||
return output.Content, err
|
||||
}
|
||||
|
||||
// GetInstanceIdentityDocument retrieves an identity document describing an
|
||||
|
@ -79,7 +111,7 @@ func (c *EC2Metadata) GetInstanceIdentityDocument() (EC2InstanceIdentityDocument
|
|||
doc := EC2InstanceIdentityDocument{}
|
||||
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&doc); err != nil {
|
||||
return EC2InstanceIdentityDocument{},
|
||||
awserr.New("SerializationError",
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to decode EC2 instance identity document", err)
|
||||
}
|
||||
|
||||
|
@ -98,7 +130,7 @@ func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) {
|
|||
info := EC2IAMInfo{}
|
||||
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&info); err != nil {
|
||||
return EC2IAMInfo{},
|
||||
awserr.New("SerializationError",
|
||||
awserr.New(request.ErrCodeSerialization,
|
||||
"failed to decode EC2 IAM info", err)
|
||||
}
|
||||
|
||||
|
@ -113,13 +145,17 @@ func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) {
|
|||
|
||||
// Region returns the region the instance is running in.
|
||||
func (c *EC2Metadata) Region() (string, error) {
|
||||
resp, err := c.GetMetadata("placement/availability-zone")
|
||||
ec2InstanceIdentityDocument, err := c.GetInstanceIdentityDocument()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// returns region without the suffix. Eg: us-west-2a becomes us-west-2
|
||||
return resp[:len(resp)-1], nil
|
||||
// extract region from the ec2InstanceIdentityDocument
|
||||
region := ec2InstanceIdentityDocument.Region
|
||||
if len(region) == 0 {
|
||||
return "", awserr.New("EC2MetadataError", "invalid region received for ec2metadata instance", nil)
|
||||
}
|
||||
// returns region
|
||||
return region, nil
|
||||
}
|
||||
|
||||
// Available returns if the application has access to the EC2 Metadata service.
|
||||
|
@ -145,18 +181,19 @@ type EC2IAMInfo struct {
|
|||
// An EC2InstanceIdentityDocument provides the shape for unmarshaling
|
||||
// an instance identity document
|
||||
type EC2InstanceIdentityDocument struct {
|
||||
DevpayProductCodes []string `json:"devpayProductCodes"`
|
||||
AvailabilityZone string `json:"availabilityZone"`
|
||||
PrivateIP string `json:"privateIp"`
|
||||
Version string `json:"version"`
|
||||
Region string `json:"region"`
|
||||
InstanceID string `json:"instanceId"`
|
||||
BillingProducts []string `json:"billingProducts"`
|
||||
InstanceType string `json:"instanceType"`
|
||||
AccountID string `json:"accountId"`
|
||||
PendingTime time.Time `json:"pendingTime"`
|
||||
ImageID string `json:"imageId"`
|
||||
KernelID string `json:"kernelId"`
|
||||
RamdiskID string `json:"ramdiskId"`
|
||||
Architecture string `json:"architecture"`
|
||||
DevpayProductCodes []string `json:"devpayProductCodes"`
|
||||
MarketplaceProductCodes []string `json:"marketplaceProductCodes"`
|
||||
AvailabilityZone string `json:"availabilityZone"`
|
||||
PrivateIP string `json:"privateIp"`
|
||||
Version string `json:"version"`
|
||||
Region string `json:"region"`
|
||||
InstanceID string `json:"instanceId"`
|
||||
BillingProducts []string `json:"billingProducts"`
|
||||
InstanceType string `json:"instanceType"`
|
||||
AccountID string `json:"accountId"`
|
||||
PendingTime time.Time `json:"pendingTime"`
|
||||
ImageID string `json:"imageId"`
|
||||
KernelID string `json:"kernelId"`
|
||||
RamdiskID string `json:"ramdiskId"`
|
||||
Architecture string `json:"architecture"`
|
||||
}
|
||||
|
|
142
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
generated
vendored
142
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
generated
vendored
|
@ -1,5 +1,10 @@
|
|||
// Package ec2metadata provides the client for making API calls to the
|
||||
// EC2 Metadata service.
|
||||
//
|
||||
// This package's client can be disabled completely by setting the environment
|
||||
// variable "AWS_EC2_METADATA_DISABLED=true". This environment variable set to
|
||||
// true instructs the SDK to disable the EC2 Metadata client. The client cannot
|
||||
// be used while the environment variable is set to true, (case insensitive).
|
||||
package ec2metadata
|
||||
|
||||
import (
|
||||
|
@ -7,17 +12,38 @@ import (
|
|||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"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/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// ServiceName is the name of the service.
|
||||
const ServiceName = "ec2metadata"
|
||||
const (
|
||||
// ServiceName is the name of the service.
|
||||
ServiceName = "ec2metadata"
|
||||
disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED"
|
||||
|
||||
// Headers for Token and TTL
|
||||
ttlHeader = "x-aws-ec2-metadata-token-ttl-seconds"
|
||||
tokenHeader = "x-aws-ec2-metadata-token"
|
||||
|
||||
// Named Handler constants
|
||||
fetchTokenHandlerName = "FetchTokenHandler"
|
||||
unmarshalMetadataHandlerName = "unmarshalMetadataHandler"
|
||||
unmarshalTokenHandlerName = "unmarshalTokenHandler"
|
||||
enableTokenProviderHandlerName = "enableTokenProviderHandler"
|
||||
|
||||
// TTL constants
|
||||
defaultTTL = 21600 * time.Second
|
||||
ttlExpirationWindow = 30 * time.Second
|
||||
)
|
||||
|
||||
// A EC2Metadata is an EC2 Metadata service Client.
|
||||
type EC2Metadata struct {
|
||||
|
@ -54,8 +80,10 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
|
|||
// use a shorter timeout than default because the metadata
|
||||
// service is local if it is running, and to fail faster
|
||||
// if not running on an ec2 instance.
|
||||
Timeout: 5 * time.Second,
|
||||
Timeout: 1 * time.Second,
|
||||
}
|
||||
// max number of retries on the client operation
|
||||
cfg.MaxRetries = aws.Int(2)
|
||||
}
|
||||
|
||||
svc := &EC2Metadata{
|
||||
|
@ -63,6 +91,7 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
|
|||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceName,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "latest",
|
||||
},
|
||||
|
@ -70,16 +99,47 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
|
|||
),
|
||||
}
|
||||
|
||||
svc.Handlers.Unmarshal.PushBack(unmarshalHandler)
|
||||
// token provider instance
|
||||
tp := newTokenProvider(svc, defaultTTL)
|
||||
|
||||
// NamedHandler for fetching token
|
||||
svc.Handlers.Sign.PushBackNamed(request.NamedHandler{
|
||||
Name: fetchTokenHandlerName,
|
||||
Fn: tp.fetchTokenHandler,
|
||||
})
|
||||
// NamedHandler for enabling token provider
|
||||
svc.Handlers.Complete.PushBackNamed(request.NamedHandler{
|
||||
Name: enableTokenProviderHandlerName,
|
||||
Fn: tp.enableTokenProviderHandler,
|
||||
})
|
||||
|
||||
svc.Handlers.Unmarshal.PushBackNamed(unmarshalHandler)
|
||||
svc.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||
svc.Handlers.Validate.Clear()
|
||||
svc.Handlers.Validate.PushBack(validateEndpointHandler)
|
||||
|
||||
// Disable the EC2 Metadata service if the environment variable is set.
|
||||
// This short-circuits the service's functionality to always fail to send
|
||||
// requests.
|
||||
if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" {
|
||||
svc.Handlers.Send.SwapNamed(request.NamedHandler{
|
||||
Name: corehandlers.SendHandler.Name,
|
||||
Fn: func(r *request.Request) {
|
||||
r.HTTPResponse = &http.Response{
|
||||
Header: http.Header{},
|
||||
}
|
||||
r.Error = awserr.New(
|
||||
request.CanceledErrorCode,
|
||||
"EC2 IMDS access disabled via "+disableServiceEnvVar+" env var",
|
||||
nil)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Add additional options to the service config
|
||||
for _, option := range opts {
|
||||
option(svc.Client)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
|
@ -91,30 +151,74 @@ type metadataOutput struct {
|
|||
Content string
|
||||
}
|
||||
|
||||
func unmarshalHandler(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
b := &bytes.Buffer{}
|
||||
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
|
||||
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err)
|
||||
return
|
||||
}
|
||||
type tokenOutput struct {
|
||||
Token string
|
||||
TTL time.Duration
|
||||
}
|
||||
|
||||
if data, ok := r.Data.(*metadataOutput); ok {
|
||||
data.Content = b.String()
|
||||
}
|
||||
// unmarshal token handler is used to parse the response of a getToken operation
|
||||
var unmarshalTokenHandler = request.NamedHandler{
|
||||
Name: unmarshalTokenHandlerName,
|
||||
Fn: func(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
var b bytes.Buffer
|
||||
if _, err := io.Copy(&b, r.HTTPResponse.Body); err != nil {
|
||||
r.Error = awserr.NewRequestFailure(awserr.New(request.ErrCodeSerialization,
|
||||
"unable to unmarshal EC2 metadata response", err), r.HTTPResponse.StatusCode, r.RequestID)
|
||||
return
|
||||
}
|
||||
|
||||
v := r.HTTPResponse.Header.Get(ttlHeader)
|
||||
data, ok := r.Data.(*tokenOutput)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
data.Token = b.String()
|
||||
// TTL is in seconds
|
||||
i, err := strconv.ParseInt(v, 10, 64)
|
||||
if err != nil {
|
||||
r.Error = awserr.NewRequestFailure(awserr.New(request.ParamFormatErrCode,
|
||||
"unable to parse EC2 token TTL response", err), r.HTTPResponse.StatusCode, r.RequestID)
|
||||
return
|
||||
}
|
||||
t := time.Duration(i) * time.Second
|
||||
data.TTL = t
|
||||
},
|
||||
}
|
||||
|
||||
var unmarshalHandler = request.NamedHandler{
|
||||
Name: unmarshalMetadataHandlerName,
|
||||
Fn: func(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
var b bytes.Buffer
|
||||
if _, err := io.Copy(&b, r.HTTPResponse.Body); err != nil {
|
||||
r.Error = awserr.NewRequestFailure(awserr.New(request.ErrCodeSerialization,
|
||||
"unable to unmarshal EC2 metadata response", err), r.HTTPResponse.StatusCode, r.RequestID)
|
||||
return
|
||||
}
|
||||
|
||||
if data, ok := r.Data.(*metadataOutput); ok {
|
||||
data.Content = b.String()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func unmarshalError(r *request.Request) {
|
||||
defer r.HTTPResponse.Body.Close()
|
||||
b := &bytes.Buffer{}
|
||||
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
|
||||
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err)
|
||||
var b bytes.Buffer
|
||||
|
||||
if _, err := io.Copy(&b, r.HTTPResponse.Body); err != nil {
|
||||
r.Error = awserr.NewRequestFailure(
|
||||
awserr.New(request.ErrCodeSerialization, "unable to unmarshal EC2 metadata error response", err),
|
||||
r.HTTPResponse.StatusCode, r.RequestID)
|
||||
return
|
||||
}
|
||||
|
||||
// Response body format is not consistent between metadata endpoints.
|
||||
// Grab the error message as a string and include that as the source error
|
||||
r.Error = awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String()))
|
||||
r.Error = awserr.NewRequestFailure(awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String())),
|
||||
r.HTTPResponse.StatusCode, r.RequestID)
|
||||
}
|
||||
|
||||
func validateEndpointHandler(r *request.Request) {
|
||||
|
|
92
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/token_provider.go
generated
vendored
Normal file
92
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/token_provider.go
generated
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
package ec2metadata
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
// A tokenProvider struct provides access to EC2Metadata client
|
||||
// and atomic instance of a token, along with configuredTTL for it.
|
||||
// tokenProvider also provides an atomic flag to disable the
|
||||
// fetch token operation.
|
||||
// The disabled member will use 0 as false, and 1 as true.
|
||||
type tokenProvider struct {
|
||||
client *EC2Metadata
|
||||
token atomic.Value
|
||||
configuredTTL time.Duration
|
||||
disabled uint32
|
||||
}
|
||||
|
||||
// A ec2Token struct helps use of token in EC2 Metadata service ops
|
||||
type ec2Token struct {
|
||||
token string
|
||||
credentials.Expiry
|
||||
}
|
||||
|
||||
// newTokenProvider provides a pointer to a tokenProvider instance
|
||||
func newTokenProvider(c *EC2Metadata, duration time.Duration) *tokenProvider {
|
||||
return &tokenProvider{client: c, configuredTTL: duration}
|
||||
}
|
||||
|
||||
// fetchTokenHandler fetches token for EC2Metadata service client by default.
|
||||
func (t *tokenProvider) fetchTokenHandler(r *request.Request) {
|
||||
|
||||
// short-circuits to insecure data flow if tokenProvider is disabled.
|
||||
if v := atomic.LoadUint32(&t.disabled); v == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
if ec2Token, ok := t.token.Load().(ec2Token); ok && !ec2Token.IsExpired() {
|
||||
r.HTTPRequest.Header.Set(tokenHeader, ec2Token.token)
|
||||
return
|
||||
}
|
||||
|
||||
output, err := t.client.getToken(t.configuredTTL)
|
||||
|
||||
if err != nil {
|
||||
|
||||
// change the disabled flag on token provider to true,
|
||||
// when error is request timeout error.
|
||||
if requestFailureError, ok := err.(awserr.RequestFailure); ok {
|
||||
switch requestFailureError.StatusCode() {
|
||||
case http.StatusForbidden, http.StatusNotFound, http.StatusMethodNotAllowed:
|
||||
atomic.StoreUint32(&t.disabled, 1)
|
||||
case http.StatusBadRequest:
|
||||
r.Error = requestFailureError
|
||||
}
|
||||
|
||||
// Check if request timed out while waiting for response
|
||||
if e, ok := requestFailureError.OrigErr().(awserr.Error); ok {
|
||||
if e.Code() == request.ErrCodeRequestError {
|
||||
atomic.StoreUint32(&t.disabled, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
newToken := ec2Token{
|
||||
token: output.Token,
|
||||
}
|
||||
newToken.SetExpiration(time.Now().Add(output.TTL), ttlExpirationWindow)
|
||||
t.token.Store(newToken)
|
||||
|
||||
// Inject token header to the request.
|
||||
if ec2Token, ok := t.token.Load().(ec2Token); ok {
|
||||
r.HTTPRequest.Header.Set(tokenHeader, ec2Token.token)
|
||||
}
|
||||
}
|
||||
|
||||
// enableTokenProviderHandler enables the token provider
|
||||
func (t *tokenProvider) enableTokenProviderHandler(r *request.Request) {
|
||||
// If the error code status is 401, we enable the token provider
|
||||
if e, ok := r.Error.(awserr.RequestFailure); ok && e != nil &&
|
||||
e.StatusCode() == http.StatusUnauthorized {
|
||||
atomic.StoreUint32(&t.disabled, 0)
|
||||
}
|
||||
}
|
87
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
generated
vendored
87
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
generated
vendored
|
@ -83,7 +83,10 @@ func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resol
|
|||
p := &ps[i]
|
||||
custAddEC2Metadata(p)
|
||||
custAddS3DualStack(p)
|
||||
custRegionalS3(p)
|
||||
custRmIotDataService(p)
|
||||
custFixAppAutoscalingChina(p)
|
||||
custFixAppAutoscalingUsGov(p)
|
||||
}
|
||||
|
||||
return ps, nil
|
||||
|
@ -94,7 +97,39 @@ func custAddS3DualStack(p *partition) {
|
|||
return
|
||||
}
|
||||
|
||||
s, ok := p.Services["s3"]
|
||||
custAddDualstack(p, "s3")
|
||||
custAddDualstack(p, "s3-control")
|
||||
}
|
||||
|
||||
func custRegionalS3(p *partition) {
|
||||
if p.ID != "aws" {
|
||||
return
|
||||
}
|
||||
|
||||
service, ok := p.Services["s3"]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
// If global endpoint already exists no customization needed.
|
||||
if _, ok := service.Endpoints["aws-global"]; ok {
|
||||
return
|
||||
}
|
||||
|
||||
service.PartitionEndpoint = "aws-global"
|
||||
service.Endpoints["us-east-1"] = endpoint{}
|
||||
service.Endpoints["aws-global"] = endpoint{
|
||||
Hostname: "s3.amazonaws.com",
|
||||
CredentialScope: credentialScope{
|
||||
Region: "us-east-1",
|
||||
},
|
||||
}
|
||||
|
||||
p.Services["s3"] = service
|
||||
}
|
||||
|
||||
func custAddDualstack(p *partition, svcName string) {
|
||||
s, ok := p.Services[svcName]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
@ -102,7 +137,7 @@ func custAddS3DualStack(p *partition) {
|
|||
s.Defaults.HasDualStack = boxedTrue
|
||||
s.Defaults.DualStackHostname = "{service}.dualstack.{region}.{dnsSuffix}"
|
||||
|
||||
p.Services["s3"] = s
|
||||
p.Services[svcName] = s
|
||||
}
|
||||
|
||||
func custAddEC2Metadata(p *partition) {
|
||||
|
@ -122,6 +157,54 @@ func custRmIotDataService(p *partition) {
|
|||
delete(p.Services, "data.iot")
|
||||
}
|
||||
|
||||
func custFixAppAutoscalingChina(p *partition) {
|
||||
if p.ID != "aws-cn" {
|
||||
return
|
||||
}
|
||||
|
||||
const serviceName = "application-autoscaling"
|
||||
s, ok := p.Services[serviceName]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
const expectHostname = `autoscaling.{region}.amazonaws.com`
|
||||
if e, a := s.Defaults.Hostname, expectHostname; e != a {
|
||||
fmt.Printf("custFixAppAutoscalingChina: ignoring customization, expected %s, got %s\n", e, a)
|
||||
return
|
||||
}
|
||||
|
||||
s.Defaults.Hostname = expectHostname + ".cn"
|
||||
p.Services[serviceName] = s
|
||||
}
|
||||
|
||||
func custFixAppAutoscalingUsGov(p *partition) {
|
||||
if p.ID != "aws-us-gov" {
|
||||
return
|
||||
}
|
||||
|
||||
const serviceName = "application-autoscaling"
|
||||
s, ok := p.Services[serviceName]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if a := s.Defaults.CredentialScope.Service; a != "" {
|
||||
fmt.Printf("custFixAppAutoscalingUsGov: ignoring customization, expected empty credential scope service, got %s\n", a)
|
||||
return
|
||||
}
|
||||
|
||||
if a := s.Defaults.Hostname; a != "" {
|
||||
fmt.Printf("custFixAppAutoscalingUsGov: ignoring customization, expected empty hostname, got %s\n", a)
|
||||
return
|
||||
}
|
||||
|
||||
s.Defaults.CredentialScope.Service = "application-autoscaling"
|
||||
s.Defaults.Hostname = "autoscaling.{region}.amazonaws.com"
|
||||
|
||||
p.Services[serviceName] = s
|
||||
}
|
||||
|
||||
type decodeModelError struct {
|
||||
awsError
|
||||
}
|
||||
|
|
4425
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
4425
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
File diff suppressed because it is too large
Load diff
141
vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go
generated
vendored
Normal file
141
vendor/github.com/aws/aws-sdk-go/aws/endpoints/dep_service_ids.go
generated
vendored
Normal file
|
@ -0,0 +1,141 @@
|
|||
package endpoints
|
||||
|
||||
// Service identifiers
|
||||
//
|
||||
// Deprecated: Use client package's EndpointsID value instead of these
|
||||
// ServiceIDs. These IDs are not maintained, and are out of date.
|
||||
const (
|
||||
A4bServiceID = "a4b" // A4b.
|
||||
AcmServiceID = "acm" // Acm.
|
||||
AcmPcaServiceID = "acm-pca" // AcmPca.
|
||||
ApiMediatailorServiceID = "api.mediatailor" // ApiMediatailor.
|
||||
ApiPricingServiceID = "api.pricing" // ApiPricing.
|
||||
ApiSagemakerServiceID = "api.sagemaker" // ApiSagemaker.
|
||||
ApigatewayServiceID = "apigateway" // Apigateway.
|
||||
ApplicationAutoscalingServiceID = "application-autoscaling" // ApplicationAutoscaling.
|
||||
Appstream2ServiceID = "appstream2" // Appstream2.
|
||||
AppsyncServiceID = "appsync" // Appsync.
|
||||
AthenaServiceID = "athena" // Athena.
|
||||
AutoscalingServiceID = "autoscaling" // Autoscaling.
|
||||
AutoscalingPlansServiceID = "autoscaling-plans" // AutoscalingPlans.
|
||||
BatchServiceID = "batch" // Batch.
|
||||
BudgetsServiceID = "budgets" // Budgets.
|
||||
CeServiceID = "ce" // Ce.
|
||||
ChimeServiceID = "chime" // Chime.
|
||||
Cloud9ServiceID = "cloud9" // Cloud9.
|
||||
ClouddirectoryServiceID = "clouddirectory" // Clouddirectory.
|
||||
CloudformationServiceID = "cloudformation" // Cloudformation.
|
||||
CloudfrontServiceID = "cloudfront" // Cloudfront.
|
||||
CloudhsmServiceID = "cloudhsm" // Cloudhsm.
|
||||
Cloudhsmv2ServiceID = "cloudhsmv2" // Cloudhsmv2.
|
||||
CloudsearchServiceID = "cloudsearch" // Cloudsearch.
|
||||
CloudtrailServiceID = "cloudtrail" // Cloudtrail.
|
||||
CodebuildServiceID = "codebuild" // Codebuild.
|
||||
CodecommitServiceID = "codecommit" // Codecommit.
|
||||
CodedeployServiceID = "codedeploy" // Codedeploy.
|
||||
CodepipelineServiceID = "codepipeline" // Codepipeline.
|
||||
CodestarServiceID = "codestar" // Codestar.
|
||||
CognitoIdentityServiceID = "cognito-identity" // CognitoIdentity.
|
||||
CognitoIdpServiceID = "cognito-idp" // CognitoIdp.
|
||||
CognitoSyncServiceID = "cognito-sync" // CognitoSync.
|
||||
ComprehendServiceID = "comprehend" // Comprehend.
|
||||
ConfigServiceID = "config" // Config.
|
||||
CurServiceID = "cur" // Cur.
|
||||
DatapipelineServiceID = "datapipeline" // Datapipeline.
|
||||
DaxServiceID = "dax" // Dax.
|
||||
DevicefarmServiceID = "devicefarm" // Devicefarm.
|
||||
DirectconnectServiceID = "directconnect" // Directconnect.
|
||||
DiscoveryServiceID = "discovery" // Discovery.
|
||||
DmsServiceID = "dms" // Dms.
|
||||
DsServiceID = "ds" // Ds.
|
||||
DynamodbServiceID = "dynamodb" // Dynamodb.
|
||||
Ec2ServiceID = "ec2" // Ec2.
|
||||
Ec2metadataServiceID = "ec2metadata" // Ec2metadata.
|
||||
EcrServiceID = "ecr" // Ecr.
|
||||
EcsServiceID = "ecs" // Ecs.
|
||||
ElasticacheServiceID = "elasticache" // Elasticache.
|
||||
ElasticbeanstalkServiceID = "elasticbeanstalk" // Elasticbeanstalk.
|
||||
ElasticfilesystemServiceID = "elasticfilesystem" // Elasticfilesystem.
|
||||
ElasticloadbalancingServiceID = "elasticloadbalancing" // Elasticloadbalancing.
|
||||
ElasticmapreduceServiceID = "elasticmapreduce" // Elasticmapreduce.
|
||||
ElastictranscoderServiceID = "elastictranscoder" // Elastictranscoder.
|
||||
EmailServiceID = "email" // Email.
|
||||
EntitlementMarketplaceServiceID = "entitlement.marketplace" // EntitlementMarketplace.
|
||||
EsServiceID = "es" // Es.
|
||||
EventsServiceID = "events" // Events.
|
||||
FirehoseServiceID = "firehose" // Firehose.
|
||||
FmsServiceID = "fms" // Fms.
|
||||
GameliftServiceID = "gamelift" // Gamelift.
|
||||
GlacierServiceID = "glacier" // Glacier.
|
||||
GlueServiceID = "glue" // Glue.
|
||||
GreengrassServiceID = "greengrass" // Greengrass.
|
||||
GuarddutyServiceID = "guardduty" // Guardduty.
|
||||
HealthServiceID = "health" // Health.
|
||||
IamServiceID = "iam" // Iam.
|
||||
ImportexportServiceID = "importexport" // Importexport.
|
||||
InspectorServiceID = "inspector" // Inspector.
|
||||
IotServiceID = "iot" // Iot.
|
||||
IotanalyticsServiceID = "iotanalytics" // Iotanalytics.
|
||||
KinesisServiceID = "kinesis" // Kinesis.
|
||||
KinesisanalyticsServiceID = "kinesisanalytics" // Kinesisanalytics.
|
||||
KinesisvideoServiceID = "kinesisvideo" // Kinesisvideo.
|
||||
KmsServiceID = "kms" // Kms.
|
||||
LambdaServiceID = "lambda" // Lambda.
|
||||
LightsailServiceID = "lightsail" // Lightsail.
|
||||
LogsServiceID = "logs" // Logs.
|
||||
MachinelearningServiceID = "machinelearning" // Machinelearning.
|
||||
MarketplacecommerceanalyticsServiceID = "marketplacecommerceanalytics" // Marketplacecommerceanalytics.
|
||||
MediaconvertServiceID = "mediaconvert" // Mediaconvert.
|
||||
MedialiveServiceID = "medialive" // Medialive.
|
||||
MediapackageServiceID = "mediapackage" // Mediapackage.
|
||||
MediastoreServiceID = "mediastore" // Mediastore.
|
||||
MeteringMarketplaceServiceID = "metering.marketplace" // MeteringMarketplace.
|
||||
MghServiceID = "mgh" // Mgh.
|
||||
MobileanalyticsServiceID = "mobileanalytics" // Mobileanalytics.
|
||||
ModelsLexServiceID = "models.lex" // ModelsLex.
|
||||
MonitoringServiceID = "monitoring" // Monitoring.
|
||||
MturkRequesterServiceID = "mturk-requester" // MturkRequester.
|
||||
NeptuneServiceID = "neptune" // Neptune.
|
||||
OpsworksServiceID = "opsworks" // Opsworks.
|
||||
OpsworksCmServiceID = "opsworks-cm" // OpsworksCm.
|
||||
OrganizationsServiceID = "organizations" // Organizations.
|
||||
PinpointServiceID = "pinpoint" // Pinpoint.
|
||||
PollyServiceID = "polly" // Polly.
|
||||
RdsServiceID = "rds" // Rds.
|
||||
RedshiftServiceID = "redshift" // Redshift.
|
||||
RekognitionServiceID = "rekognition" // Rekognition.
|
||||
ResourceGroupsServiceID = "resource-groups" // ResourceGroups.
|
||||
Route53ServiceID = "route53" // Route53.
|
||||
Route53domainsServiceID = "route53domains" // Route53domains.
|
||||
RuntimeLexServiceID = "runtime.lex" // RuntimeLex.
|
||||
RuntimeSagemakerServiceID = "runtime.sagemaker" // RuntimeSagemaker.
|
||||
S3ServiceID = "s3" // S3.
|
||||
S3ControlServiceID = "s3-control" // S3Control.
|
||||
SagemakerServiceID = "api.sagemaker" // Sagemaker.
|
||||
SdbServiceID = "sdb" // Sdb.
|
||||
SecretsmanagerServiceID = "secretsmanager" // Secretsmanager.
|
||||
ServerlessrepoServiceID = "serverlessrepo" // Serverlessrepo.
|
||||
ServicecatalogServiceID = "servicecatalog" // Servicecatalog.
|
||||
ServicediscoveryServiceID = "servicediscovery" // Servicediscovery.
|
||||
ShieldServiceID = "shield" // Shield.
|
||||
SmsServiceID = "sms" // Sms.
|
||||
SnowballServiceID = "snowball" // Snowball.
|
||||
SnsServiceID = "sns" // Sns.
|
||||
SqsServiceID = "sqs" // Sqs.
|
||||
SsmServiceID = "ssm" // Ssm.
|
||||
StatesServiceID = "states" // States.
|
||||
StoragegatewayServiceID = "storagegateway" // Storagegateway.
|
||||
StreamsDynamodbServiceID = "streams.dynamodb" // StreamsDynamodb.
|
||||
StsServiceID = "sts" // Sts.
|
||||
SupportServiceID = "support" // Support.
|
||||
SwfServiceID = "swf" // Swf.
|
||||
TaggingServiceID = "tagging" // Tagging.
|
||||
TransferServiceID = "transfer" // Transfer.
|
||||
TranslateServiceID = "translate" // Translate.
|
||||
WafServiceID = "waf" // Waf.
|
||||
WafRegionalServiceID = "waf-regional" // WafRegional.
|
||||
WorkdocsServiceID = "workdocs" // Workdocs.
|
||||
WorkmailServiceID = "workmail" // Workmail.
|
||||
WorkspacesServiceID = "workspaces" // Workspaces.
|
||||
XrayServiceID = "xray" // Xray.
|
||||
)
|
151
vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
generated
vendored
151
vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
generated
vendored
|
@ -3,6 +3,7 @@ package endpoints
|
|||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
@ -35,7 +36,7 @@ type Options struct {
|
|||
//
|
||||
// If resolving an endpoint on the partition list the provided region will
|
||||
// be used to determine which partition's domain name pattern to the service
|
||||
// endpoint ID with. If both the service and region are unkonwn and resolving
|
||||
// endpoint ID with. If both the service and region are unknown and resolving
|
||||
// the endpoint on partition list an UnknownEndpointError error will be returned.
|
||||
//
|
||||
// If resolving and endpoint on a partition specific resolver that partition's
|
||||
|
@ -46,6 +47,108 @@ type Options struct {
|
|||
//
|
||||
// This option is ignored if StrictMatching is enabled.
|
||||
ResolveUnknownService bool
|
||||
|
||||
// STS Regional Endpoint flag helps with resolving the STS endpoint
|
||||
STSRegionalEndpoint STSRegionalEndpoint
|
||||
|
||||
// S3 Regional Endpoint flag helps with resolving the S3 endpoint
|
||||
S3UsEast1RegionalEndpoint S3UsEast1RegionalEndpoint
|
||||
}
|
||||
|
||||
// STSRegionalEndpoint is an enum for the states of the STS Regional Endpoint
|
||||
// options.
|
||||
type STSRegionalEndpoint int
|
||||
|
||||
func (e STSRegionalEndpoint) String() string {
|
||||
switch e {
|
||||
case LegacySTSEndpoint:
|
||||
return "legacy"
|
||||
case RegionalSTSEndpoint:
|
||||
return "regional"
|
||||
case UnsetSTSEndpoint:
|
||||
return ""
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// UnsetSTSEndpoint represents that STS Regional Endpoint flag is not specified.
|
||||
UnsetSTSEndpoint STSRegionalEndpoint = iota
|
||||
|
||||
// LegacySTSEndpoint represents when STS Regional Endpoint flag is specified
|
||||
// to use legacy endpoints.
|
||||
LegacySTSEndpoint
|
||||
|
||||
// RegionalSTSEndpoint represents when STS Regional Endpoint flag is specified
|
||||
// to use regional endpoints.
|
||||
RegionalSTSEndpoint
|
||||
)
|
||||
|
||||
// GetSTSRegionalEndpoint function returns the STSRegionalEndpointFlag based
|
||||
// on the input string provided in env config or shared config by the user.
|
||||
//
|
||||
// `legacy`, `regional` are the only case-insensitive valid strings for
|
||||
// resolving the STS regional Endpoint flag.
|
||||
func GetSTSRegionalEndpoint(s string) (STSRegionalEndpoint, error) {
|
||||
switch {
|
||||
case strings.EqualFold(s, "legacy"):
|
||||
return LegacySTSEndpoint, nil
|
||||
case strings.EqualFold(s, "regional"):
|
||||
return RegionalSTSEndpoint, nil
|
||||
default:
|
||||
return UnsetSTSEndpoint, fmt.Errorf("unable to resolve the value of STSRegionalEndpoint for %v", s)
|
||||
}
|
||||
}
|
||||
|
||||
// S3UsEast1RegionalEndpoint is an enum for the states of the S3 us-east-1
|
||||
// Regional Endpoint options.
|
||||
type S3UsEast1RegionalEndpoint int
|
||||
|
||||
func (e S3UsEast1RegionalEndpoint) String() string {
|
||||
switch e {
|
||||
case LegacyS3UsEast1Endpoint:
|
||||
return "legacy"
|
||||
case RegionalS3UsEast1Endpoint:
|
||||
return "regional"
|
||||
case UnsetS3UsEast1Endpoint:
|
||||
return ""
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// UnsetS3UsEast1Endpoint represents that S3 Regional Endpoint flag is not
|
||||
// specified.
|
||||
UnsetS3UsEast1Endpoint S3UsEast1RegionalEndpoint = iota
|
||||
|
||||
// LegacyS3UsEast1Endpoint represents when S3 Regional Endpoint flag is
|
||||
// specified to use legacy endpoints.
|
||||
LegacyS3UsEast1Endpoint
|
||||
|
||||
// RegionalS3UsEast1Endpoint represents when S3 Regional Endpoint flag is
|
||||
// specified to use regional endpoints.
|
||||
RegionalS3UsEast1Endpoint
|
||||
)
|
||||
|
||||
// GetS3UsEast1RegionalEndpoint function returns the S3UsEast1RegionalEndpointFlag based
|
||||
// on the input string provided in env config or shared config by the user.
|
||||
//
|
||||
// `legacy`, `regional` are the only case-insensitive valid strings for
|
||||
// resolving the S3 regional Endpoint flag.
|
||||
func GetS3UsEast1RegionalEndpoint(s string) (S3UsEast1RegionalEndpoint, error) {
|
||||
switch {
|
||||
case strings.EqualFold(s, "legacy"):
|
||||
return LegacyS3UsEast1Endpoint, nil
|
||||
case strings.EqualFold(s, "regional"):
|
||||
return RegionalS3UsEast1Endpoint, nil
|
||||
default:
|
||||
return UnsetS3UsEast1Endpoint,
|
||||
fmt.Errorf("unable to resolve the value of S3UsEast1RegionalEndpoint for %v", s)
|
||||
}
|
||||
}
|
||||
|
||||
// Set combines all of the option functions together.
|
||||
|
@ -79,6 +182,12 @@ func ResolveUnknownServiceOption(o *Options) {
|
|||
o.ResolveUnknownService = true
|
||||
}
|
||||
|
||||
// STSRegionalEndpointOption enables the STS endpoint resolver behavior to resolve
|
||||
// STS endpoint to their regional endpoint, instead of the global endpoint.
|
||||
func STSRegionalEndpointOption(o *Options) {
|
||||
o.STSRegionalEndpoint = RegionalSTSEndpoint
|
||||
}
|
||||
|
||||
// A Resolver provides the interface for functionality to resolve endpoints.
|
||||
// The build in Partition and DefaultResolver return value satisfy this interface.
|
||||
type Resolver interface {
|
||||
|
@ -170,10 +279,13 @@ func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) {
|
|||
// A Partition provides the ability to enumerate the partition's regions
|
||||
// and services.
|
||||
type Partition struct {
|
||||
id string
|
||||
p *partition
|
||||
id, dnsSuffix string
|
||||
p *partition
|
||||
}
|
||||
|
||||
// DNSSuffix returns the base domain name of the partition.
|
||||
func (p Partition) DNSSuffix() string { return p.dnsSuffix }
|
||||
|
||||
// ID returns the identifier of the partition.
|
||||
func (p Partition) ID() string { return p.id }
|
||||
|
||||
|
@ -191,7 +303,7 @@ func (p Partition) ID() string { return p.id }
|
|||
// require the provided service and region to be known by the partition.
|
||||
// If the endpoint cannot be strictly resolved an error will be returned. This
|
||||
// mode is useful to ensure the endpoint resolved is valid. Without
|
||||
// StrictMatching enabled the endpoint returned my look valid but may not work.
|
||||
// StrictMatching enabled the endpoint returned may look valid but may not work.
|
||||
// StrictMatching requires the SDK to be updated if you want to take advantage
|
||||
// of new regions and services expansions.
|
||||
//
|
||||
|
@ -205,11 +317,12 @@ func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (
|
|||
// Regions returns a map of Regions indexed by their ID. This is useful for
|
||||
// enumerating over the regions in a partition.
|
||||
func (p Partition) Regions() map[string]Region {
|
||||
rs := map[string]Region{}
|
||||
for id := range p.p.Regions {
|
||||
rs := make(map[string]Region, len(p.p.Regions))
|
||||
for id, r := range p.p.Regions {
|
||||
rs[id] = Region{
|
||||
id: id,
|
||||
p: p.p,
|
||||
id: id,
|
||||
desc: r.Description,
|
||||
p: p.p,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,7 +332,7 @@ func (p Partition) Regions() map[string]Region {
|
|||
// Services returns a map of Service indexed by their ID. This is useful for
|
||||
// enumerating over the services in a partition.
|
||||
func (p Partition) Services() map[string]Service {
|
||||
ss := map[string]Service{}
|
||||
ss := make(map[string]Service, len(p.p.Services))
|
||||
for id := range p.p.Services {
|
||||
ss[id] = Service{
|
||||
id: id,
|
||||
|
@ -240,6 +353,10 @@ type Region struct {
|
|||
// ID returns the region's identifier.
|
||||
func (r Region) ID() string { return r.id }
|
||||
|
||||
// Description returns the region's description. The region description
|
||||
// is free text, it can be empty, and it may change between SDK releases.
|
||||
func (r Region) Description() string { return r.desc }
|
||||
|
||||
// ResolveEndpoint resolves an endpoint from the context of the region given
|
||||
// a service. See Partition.EndpointFor for usage and errors that can be returned.
|
||||
func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
||||
|
@ -284,10 +401,11 @@ func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (Resolve
|
|||
func (s Service) Regions() map[string]Region {
|
||||
rs := map[string]Region{}
|
||||
for id := range s.p.Services[s.id].Endpoints {
|
||||
if _, ok := s.p.Regions[id]; ok {
|
||||
if r, ok := s.p.Regions[id]; ok {
|
||||
rs[id] = Region{
|
||||
id: id,
|
||||
p: s.p,
|
||||
id: id,
|
||||
desc: r.Description,
|
||||
p: s.p,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -301,7 +419,7 @@ func (s Service) Regions() map[string]Region {
|
|||
// A region is the AWS region the service exists in. Whereas a Endpoint is
|
||||
// an URL that can be resolved to a instance of a service.
|
||||
func (s Service) Endpoints() map[string]Endpoint {
|
||||
es := map[string]Endpoint{}
|
||||
es := make(map[string]Endpoint, len(s.p.Services[s.id].Endpoints))
|
||||
for id := range s.p.Services[s.id].Endpoints {
|
||||
es[id] = Endpoint{
|
||||
id: id,
|
||||
|
@ -341,12 +459,19 @@ type ResolvedEndpoint struct {
|
|||
// The endpoint URL
|
||||
URL string
|
||||
|
||||
// The endpoint partition
|
||||
PartitionID string
|
||||
|
||||
// The region that should be used for signing requests.
|
||||
SigningRegion string
|
||||
|
||||
// The service name that should be used for signing requests.
|
||||
SigningName string
|
||||
|
||||
// States that the signing name for this endpoint was derived from metadata
|
||||
// passed in, but was not explicitly modeled.
|
||||
SigningNameDerived bool
|
||||
|
||||
// The signing method that should be used for signing requests.
|
||||
SigningMethod string
|
||||
}
|
||||
|
|
24
vendor/github.com/aws/aws-sdk-go/aws/endpoints/legacy_regions.go
generated
vendored
Normal file
24
vendor/github.com/aws/aws-sdk-go/aws/endpoints/legacy_regions.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
package endpoints
|
||||
|
||||
var legacyGlobalRegions = map[string]map[string]struct{}{
|
||||
"sts": {
|
||||
"ap-northeast-1": {},
|
||||
"ap-south-1": {},
|
||||
"ap-southeast-1": {},
|
||||
"ap-southeast-2": {},
|
||||
"ca-central-1": {},
|
||||
"eu-central-1": {},
|
||||
"eu-north-1": {},
|
||||
"eu-west-1": {},
|
||||
"eu-west-2": {},
|
||||
"eu-west-3": {},
|
||||
"sa-east-1": {},
|
||||
"us-east-1": {},
|
||||
"us-east-2": {},
|
||||
"us-west-1": {},
|
||||
"us-west-2": {},
|
||||
},
|
||||
"s3": {
|
||||
"us-east-1": {},
|
||||
},
|
||||
}
|
78
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go
generated
vendored
78
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go
generated
vendored
|
@ -54,8 +54,9 @@ type partition struct {
|
|||
|
||||
func (p partition) Partition() Partition {
|
||||
return Partition{
|
||||
id: p.ID,
|
||||
p: &p,
|
||||
dnsSuffix: p.DNSSuffix,
|
||||
id: p.ID,
|
||||
p: &p,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,24 +75,56 @@ func (p partition) canResolveEndpoint(service, region string, strictMatch bool)
|
|||
return p.RegionRegex.MatchString(region)
|
||||
}
|
||||
|
||||
func allowLegacyEmptyRegion(service string) bool {
|
||||
legacy := map[string]struct{}{
|
||||
"budgets": {},
|
||||
"ce": {},
|
||||
"chime": {},
|
||||
"cloudfront": {},
|
||||
"ec2metadata": {},
|
||||
"iam": {},
|
||||
"importexport": {},
|
||||
"organizations": {},
|
||||
"route53": {},
|
||||
"sts": {},
|
||||
"support": {},
|
||||
"waf": {},
|
||||
}
|
||||
|
||||
_, allowed := legacy[service]
|
||||
return allowed
|
||||
}
|
||||
|
||||
func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (resolved ResolvedEndpoint, err error) {
|
||||
var opt Options
|
||||
opt.Set(opts...)
|
||||
|
||||
s, hasService := p.Services[service]
|
||||
if !(hasService || opt.ResolveUnknownService) {
|
||||
if len(service) == 0 || !(hasService || opt.ResolveUnknownService) {
|
||||
// Only return error if the resolver will not fallback to creating
|
||||
// endpoint based on service endpoint ID passed in.
|
||||
return resolved, NewUnknownServiceError(p.ID, service, serviceList(p.Services))
|
||||
}
|
||||
|
||||
if len(region) == 0 && allowLegacyEmptyRegion(service) && len(s.PartitionEndpoint) != 0 {
|
||||
region = s.PartitionEndpoint
|
||||
}
|
||||
|
||||
if (service == "sts" && opt.STSRegionalEndpoint != RegionalSTSEndpoint) ||
|
||||
(service == "s3" && opt.S3UsEast1RegionalEndpoint != RegionalS3UsEast1Endpoint) {
|
||||
if _, ok := legacyGlobalRegions[service][region]; ok {
|
||||
region = "aws-global"
|
||||
}
|
||||
}
|
||||
|
||||
e, hasEndpoint := s.endpointForRegion(region)
|
||||
if !hasEndpoint && opt.StrictMatching {
|
||||
if len(region) == 0 || (!hasEndpoint && opt.StrictMatching) {
|
||||
return resolved, NewUnknownEndpointError(p.ID, service, region, endpointList(s.Endpoints))
|
||||
}
|
||||
|
||||
defs := []endpoint{p.Defaults, s.Defaults}
|
||||
return e.resolve(service, region, p.DNSSuffix, defs, opt), nil
|
||||
|
||||
return e.resolve(service, p.ID, region, p.DNSSuffix, defs, opt), nil
|
||||
}
|
||||
|
||||
func serviceList(ss services) []string {
|
||||
|
@ -200,7 +233,7 @@ func getByPriority(s []string, p []string, def string) string {
|
|||
return s[0]
|
||||
}
|
||||
|
||||
func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, opts Options) ResolvedEndpoint {
|
||||
func (e endpoint) resolve(service, partitionID, region, dnsSuffix string, defs []endpoint, opts Options) ResolvedEndpoint {
|
||||
var merged endpoint
|
||||
for _, def := range defs {
|
||||
merged.mergeIn(def)
|
||||
|
@ -208,11 +241,23 @@ func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, op
|
|||
merged.mergeIn(e)
|
||||
e = merged
|
||||
|
||||
hostname := e.Hostname
|
||||
signingRegion := e.CredentialScope.Region
|
||||
if len(signingRegion) == 0 {
|
||||
signingRegion = region
|
||||
}
|
||||
|
||||
signingName := e.CredentialScope.Service
|
||||
var signingNameDerived bool
|
||||
if len(signingName) == 0 {
|
||||
signingName = service
|
||||
signingNameDerived = true
|
||||
}
|
||||
|
||||
hostname := e.Hostname
|
||||
// Offset the hostname for dualstack if enabled
|
||||
if opts.UseDualStack && e.HasDualStack == boxedTrue {
|
||||
hostname = e.DualStackHostname
|
||||
region = signingRegion
|
||||
}
|
||||
|
||||
u := strings.Replace(hostname, "{service}", service, 1)
|
||||
|
@ -222,20 +267,13 @@ func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, op
|
|||
scheme := getEndpointScheme(e.Protocols, opts.DisableSSL)
|
||||
u = fmt.Sprintf("%s://%s", scheme, u)
|
||||
|
||||
signingRegion := e.CredentialScope.Region
|
||||
if len(signingRegion) == 0 {
|
||||
signingRegion = region
|
||||
}
|
||||
signingName := e.CredentialScope.Service
|
||||
if len(signingName) == 0 {
|
||||
signingName = service
|
||||
}
|
||||
|
||||
return ResolvedEndpoint{
|
||||
URL: u,
|
||||
SigningRegion: signingRegion,
|
||||
SigningName: signingName,
|
||||
SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner),
|
||||
URL: u,
|
||||
PartitionID: partitionID,
|
||||
SigningRegion: signingRegion,
|
||||
SigningName: signingName,
|
||||
SigningNameDerived: signingNameDerived,
|
||||
SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
24
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go
generated
vendored
24
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go
generated
vendored
|
@ -16,6 +16,10 @@ import (
|
|||
type CodeGenOptions struct {
|
||||
// Options for how the model will be decoded.
|
||||
DecodeModelOptions DecodeModelOptions
|
||||
|
||||
// Disables code generation of the service endpoint prefix IDs defined in
|
||||
// the model.
|
||||
DisableGenerateServiceIDs bool
|
||||
}
|
||||
|
||||
// Set combines all of the option functions together
|
||||
|
@ -39,8 +43,16 @@ func CodeGenModel(modelFile io.Reader, outFile io.Writer, optFns ...func(*CodeGe
|
|||
return err
|
||||
}
|
||||
|
||||
v := struct {
|
||||
Resolver
|
||||
CodeGenOptions
|
||||
}{
|
||||
Resolver: resolver,
|
||||
CodeGenOptions: opts,
|
||||
}
|
||||
|
||||
tmpl := template.Must(template.New("tmpl").Funcs(funcMap).Parse(v3Tmpl))
|
||||
if err := tmpl.ExecuteTemplate(outFile, "defaults", resolver); err != nil {
|
||||
if err := tmpl.ExecuteTemplate(outFile, "defaults", v); err != nil {
|
||||
return fmt.Errorf("failed to execute template, %v", err)
|
||||
}
|
||||
|
||||
|
@ -166,15 +178,17 @@ import (
|
|||
"regexp"
|
||||
)
|
||||
|
||||
{{ template "partition consts" . }}
|
||||
{{ template "partition consts" $.Resolver }}
|
||||
|
||||
{{ range $_, $partition := . }}
|
||||
{{ range $_, $partition := $.Resolver }}
|
||||
{{ template "partition region consts" $partition }}
|
||||
{{ end }}
|
||||
|
||||
{{ template "service consts" . }}
|
||||
{{ if not $.DisableGenerateServiceIDs -}}
|
||||
{{ template "service consts" $.Resolver }}
|
||||
{{- end }}
|
||||
|
||||
{{ template "endpoint resolvers" . }}
|
||||
{{ template "endpoint resolvers" $.Resolver }}
|
||||
{{- end }}
|
||||
|
||||
{{ define "partition consts" }}
|
||||
|
|
4
vendor/github.com/aws/aws-sdk-go/aws/errors.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/aws/errors.go
generated
vendored
|
@ -5,13 +5,9 @@ import "github.com/aws/aws-sdk-go/aws/awserr"
|
|||
var (
|
||||
// ErrMissingRegion is an error that is returned if region configuration is
|
||||
// not found.
|
||||
//
|
||||
// @readonly
|
||||
ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil)
|
||||
|
||||
// ErrMissingEndpoint is an error that is returned if an endpoint cannot be
|
||||
// resolved for a service.
|
||||
//
|
||||
// @readonly
|
||||
ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil)
|
||||
)
|
||||
|
|
6
vendor/github.com/aws/aws-sdk-go/aws/logger.go
generated
vendored
6
vendor/github.com/aws/aws-sdk-go/aws/logger.go
generated
vendored
|
@ -71,6 +71,12 @@ const (
|
|||
// LogDebugWithRequestErrors states the SDK should log when service requests fail
|
||||
// to build, send, validate, or unmarshal.
|
||||
LogDebugWithRequestErrors
|
||||
|
||||
// LogDebugWithEventStreamBody states the SDK should log EventStream
|
||||
// request and response bodys. This should be used to log the EventStream
|
||||
// wire unmarshaled message content of requests and responses made while
|
||||
// using the SDK Will also enable LogDebug.
|
||||
LogDebugWithEventStreamBody
|
||||
)
|
||||
|
||||
// A Logger is a minimalistic interface for the SDK to log messages to. Should
|
||||
|
|
17
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go
generated
vendored
17
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go
generated
vendored
|
@ -1,18 +1,17 @@
|
|||
// +build !appengine,!plan9
|
||||
|
||||
package request
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func isErrConnectionReset(err error) bool {
|
||||
if opErr, ok := err.(*net.OpError); ok {
|
||||
if sysErr, ok := opErr.Err.(*os.SyscallError); ok {
|
||||
return sysErr.Err == syscall.ECONNRESET
|
||||
}
|
||||
if strings.Contains(err.Error(), "read: connection reset") {
|
||||
return false
|
||||
}
|
||||
|
||||
if strings.Contains(err.Error(), "connection reset") ||
|
||||
strings.Contains(err.Error(), "broken pipe") {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
|
|
11
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other.go
generated
vendored
11
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other.go
generated
vendored
|
@ -1,11 +0,0 @@
|
|||
// +build appengine plan9
|
||||
|
||||
package request
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func isErrConnectionReset(err error) bool {
|
||||
return strings.Contains(err.Error(), "connection reset")
|
||||
}
|
91
vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go
generated
vendored
91
vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go
generated
vendored
|
@ -10,49 +10,106 @@ import (
|
|||
type Handlers struct {
|
||||
Validate HandlerList
|
||||
Build HandlerList
|
||||
BuildStream HandlerList
|
||||
Sign HandlerList
|
||||
Send HandlerList
|
||||
ValidateResponse HandlerList
|
||||
Unmarshal HandlerList
|
||||
UnmarshalStream HandlerList
|
||||
UnmarshalMeta HandlerList
|
||||
UnmarshalError HandlerList
|
||||
Retry HandlerList
|
||||
AfterRetry HandlerList
|
||||
CompleteAttempt HandlerList
|
||||
Complete HandlerList
|
||||
}
|
||||
|
||||
// Copy returns of this handler's lists.
|
||||
// Copy returns a copy of this handler's lists.
|
||||
func (h *Handlers) Copy() Handlers {
|
||||
return Handlers{
|
||||
Validate: h.Validate.copy(),
|
||||
Build: h.Build.copy(),
|
||||
BuildStream: h.BuildStream.copy(),
|
||||
Sign: h.Sign.copy(),
|
||||
Send: h.Send.copy(),
|
||||
ValidateResponse: h.ValidateResponse.copy(),
|
||||
Unmarshal: h.Unmarshal.copy(),
|
||||
UnmarshalStream: h.UnmarshalStream.copy(),
|
||||
UnmarshalError: h.UnmarshalError.copy(),
|
||||
UnmarshalMeta: h.UnmarshalMeta.copy(),
|
||||
Retry: h.Retry.copy(),
|
||||
AfterRetry: h.AfterRetry.copy(),
|
||||
CompleteAttempt: h.CompleteAttempt.copy(),
|
||||
Complete: h.Complete.copy(),
|
||||
}
|
||||
}
|
||||
|
||||
// Clear removes callback functions for all handlers
|
||||
// Clear removes callback functions for all handlers.
|
||||
func (h *Handlers) Clear() {
|
||||
h.Validate.Clear()
|
||||
h.Build.Clear()
|
||||
h.BuildStream.Clear()
|
||||
h.Send.Clear()
|
||||
h.Sign.Clear()
|
||||
h.Unmarshal.Clear()
|
||||
h.UnmarshalStream.Clear()
|
||||
h.UnmarshalMeta.Clear()
|
||||
h.UnmarshalError.Clear()
|
||||
h.ValidateResponse.Clear()
|
||||
h.Retry.Clear()
|
||||
h.AfterRetry.Clear()
|
||||
h.CompleteAttempt.Clear()
|
||||
h.Complete.Clear()
|
||||
}
|
||||
|
||||
// IsEmpty returns if there are no handlers in any of the handlerlists.
|
||||
func (h *Handlers) IsEmpty() bool {
|
||||
if h.Validate.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.Build.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.BuildStream.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.Send.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.Sign.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.Unmarshal.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.UnmarshalStream.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.UnmarshalMeta.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.UnmarshalError.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.ValidateResponse.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.Retry.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.AfterRetry.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.CompleteAttempt.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
if h.Complete.Len() != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// A HandlerListRunItem represents an entry in the HandlerList which
|
||||
// is being run.
|
||||
type HandlerListRunItem struct {
|
||||
|
@ -172,6 +229,21 @@ func (l *HandlerList) SwapNamed(n NamedHandler) (swapped bool) {
|
|||
return swapped
|
||||
}
|
||||
|
||||
// Swap will swap out all handlers matching the name passed in. The matched
|
||||
// handlers will be swapped in. True is returned if the handlers were swapped.
|
||||
func (l *HandlerList) Swap(name string, replace NamedHandler) bool {
|
||||
var swapped bool
|
||||
|
||||
for i := 0; i < len(l.list); i++ {
|
||||
if l.list[i].Name == name {
|
||||
l.list[i] = replace
|
||||
swapped = true
|
||||
}
|
||||
}
|
||||
|
||||
return swapped
|
||||
}
|
||||
|
||||
// SetBackNamed will replace the named handler if it exists in the handler list.
|
||||
// If the handler does not exist the handler will be added to the end of the list.
|
||||
func (l *HandlerList) SetBackNamed(n NamedHandler) {
|
||||
|
@ -254,3 +326,18 @@ func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) {
|
|||
AddToUserAgent(r, s)
|
||||
}
|
||||
}
|
||||
|
||||
// WithSetRequestHeaders updates the operation request's HTTP header to contain
|
||||
// the header key value pairs provided. If the header key already exists in the
|
||||
// request's HTTP header set, the existing value(s) will be replaced.
|
||||
func WithSetRequestHeaders(h map[string]string) Option {
|
||||
return withRequestHeader(h).SetRequestHeaders
|
||||
}
|
||||
|
||||
type withRequestHeader map[string]string
|
||||
|
||||
func (h withRequestHeader) SetRequestHeaders(r *Request) {
|
||||
for k, v := range h {
|
||||
r.HTTPRequest.Header[k] = []string{v}
|
||||
}
|
||||
}
|
||||
|
|
17
vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go
generated
vendored
17
vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go
generated
vendored
|
@ -3,6 +3,8 @@ package request
|
|||
import (
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/aws/aws-sdk-go/internal/sdkio"
|
||||
)
|
||||
|
||||
// offsetReader is a thread-safe io.ReadCloser to prevent racing
|
||||
|
@ -13,12 +15,15 @@ type offsetReader struct {
|
|||
closed bool
|
||||
}
|
||||
|
||||
func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader {
|
||||
func newOffsetReader(buf io.ReadSeeker, offset int64) (*offsetReader, error) {
|
||||
reader := &offsetReader{}
|
||||
buf.Seek(offset, 0)
|
||||
_, err := buf.Seek(offset, sdkio.SeekStart)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reader.buf = buf
|
||||
return reader
|
||||
return reader, nil
|
||||
}
|
||||
|
||||
// Close will close the instance of the offset reader's access to
|
||||
|
@ -52,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
|
||||
// and close the old buffer.
|
||||
func (o *offsetReader) CloseAndCopy(offset int64) *offsetReader {
|
||||
o.Close()
|
||||
func (o *offsetReader) CloseAndCopy(offset int64) (*offsetReader, error) {
|
||||
if err := o.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newOffsetReader(o.buf, offset)
|
||||
}
|
||||
|
|
315
vendor/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
315
vendor/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
|
@ -4,7 +4,6 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
|
@ -14,6 +13,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/internal/sdkio"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -36,6 +36,10 @@ const (
|
|||
// API request that was canceled. Requests given a aws.Context may
|
||||
// return this error when canceled.
|
||||
CanceledErrorCode = "RequestCanceled"
|
||||
|
||||
// ErrCodeRequestError is an error preventing the SDK from continuing to
|
||||
// process the request.
|
||||
ErrCodeRequestError = "RequestError"
|
||||
)
|
||||
|
||||
// A Request is the service request to be made.
|
||||
|
@ -45,11 +49,13 @@ type Request struct {
|
|||
Handlers Handlers
|
||||
|
||||
Retryer
|
||||
AttemptTime time.Time
|
||||
Time time.Time
|
||||
Operation *Operation
|
||||
HTTPRequest *http.Request
|
||||
HTTPResponse *http.Response
|
||||
Body io.ReadSeeker
|
||||
streamingBody io.ReadCloser
|
||||
BodyStart int64 // offset from beginning of Body that the request body starts
|
||||
Params interface{}
|
||||
Error error
|
||||
|
@ -63,6 +69,15 @@ type Request struct {
|
|||
LastSignedAt time.Time
|
||||
DisableFollowRedirects bool
|
||||
|
||||
// Additional API error codes that should be retried. IsErrorRetryable
|
||||
// will consider these codes in addition to its built in cases.
|
||||
RetryErrorCodes []string
|
||||
|
||||
// Additional API error codes that should be retried with throttle backoff
|
||||
// delay. IsErrorThrottle will consider these codes in addition to its
|
||||
// built in cases.
|
||||
ThrottleErrorCodes []string
|
||||
|
||||
// A value greater than 0 instructs the request to be signed as Presigned URL
|
||||
// You should not set this field directly. Instead use Request's
|
||||
// Presign or PresignRequest methods.
|
||||
|
@ -89,8 +104,12 @@ type Operation struct {
|
|||
BeforePresignFn func(r *Request) error
|
||||
}
|
||||
|
||||
// New returns a new Request pointer for the service API
|
||||
// operation and parameters.
|
||||
// New returns a new Request pointer for the service API operation and
|
||||
// parameters.
|
||||
//
|
||||
// A Retryer should be provided to direct how the request is retried. If
|
||||
// Retryer is nil, a default no retry value will be used. You can use
|
||||
// NoOpRetryer in the Client package to disable retry behavior directly.
|
||||
//
|
||||
// Params is any value of input parameters to be the request payload.
|
||||
// Data is pointer value to an object which the request's response
|
||||
|
@ -98,6 +117,10 @@ type Operation struct {
|
|||
func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
|
||||
retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request {
|
||||
|
||||
if retryer == nil {
|
||||
retryer = noOpRetryer{}
|
||||
}
|
||||
|
||||
method := operation.HTTPMethod
|
||||
if method == "" {
|
||||
method = "POST"
|
||||
|
@ -112,8 +135,6 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
|
|||
err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err)
|
||||
}
|
||||
|
||||
SanitizeHostForHeader(httpReq)
|
||||
|
||||
r := &Request{
|
||||
Config: cfg,
|
||||
ClientInfo: clientInfo,
|
||||
|
@ -224,9 +245,16 @@ func (r *Request) SetContext(ctx aws.Context) {
|
|||
|
||||
// WillRetry returns if the request's can be retried.
|
||||
func (r *Request) WillRetry() bool {
|
||||
if !aws.IsReaderSeekable(r.Body) && r.HTTPRequest.Body != NoBody {
|
||||
return false
|
||||
}
|
||||
return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries()
|
||||
}
|
||||
|
||||
func fmtAttemptCount(retryCount, maxRetries int) string {
|
||||
return fmt.Sprintf("attempt %v/%v", retryCount, maxRetries)
|
||||
}
|
||||
|
||||
// ParamsFilled returns if the request's parameters have been populated
|
||||
// and the parameters are valid. False is returned if no parameters are
|
||||
// provided or invalid.
|
||||
|
@ -255,11 +283,32 @@ func (r *Request) SetStringBody(s string) {
|
|||
// SetReaderBody will set the request's body reader.
|
||||
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
||||
r.Body = reader
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
// SetStreamingBody set the reader to be used for the request that will stream
|
||||
// bytes to the server. Request's Body must not be set to any reader.
|
||||
func (r *Request) SetStreamingBody(reader io.ReadCloser) {
|
||||
r.streamingBody = reader
|
||||
r.SetReaderBody(aws.ReadSeekCloser(reader))
|
||||
}
|
||||
|
||||
// Presign returns the request's signed URL. Error will be returned
|
||||
// if the signing fails.
|
||||
// if the signing fails. The expire parameter is only used for presigned Amazon
|
||||
// S3 API requests. All other AWS services will use a fixed expiration
|
||||
// time of 15 minutes.
|
||||
//
|
||||
// It is invalid to create a presigned URL with a expire duration 0 or less. An
|
||||
// error is returned if expire duration is 0 or less.
|
||||
|
@ -276,7 +325,9 @@ func (r *Request) Presign(expire time.Duration) (string, error) {
|
|||
}
|
||||
|
||||
// PresignRequest behaves just like presign, with the addition of returning a
|
||||
// set of headers that were signed.
|
||||
// set of headers that were signed. The expire parameter is only used for
|
||||
// presigned Amazon S3 API requests. All other AWS services will use a fixed
|
||||
// expiration time of 15 minutes.
|
||||
//
|
||||
// It is invalid to create a presigned URL with a expire duration 0 or less. An
|
||||
// error is returned if expire duration is 0 or less.
|
||||
|
@ -292,6 +343,11 @@ func (r *Request) PresignRequest(expire time.Duration) (string, http.Header, err
|
|||
return getPresignedURL(r, expire)
|
||||
}
|
||||
|
||||
// IsPresigned returns true if the request represents a presigned API url.
|
||||
func (r *Request) IsPresigned() bool {
|
||||
return r.ExpireTime != 0
|
||||
}
|
||||
|
||||
func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, error) {
|
||||
if expire <= 0 {
|
||||
return "", nil, awserr.New(
|
||||
|
@ -316,23 +372,22 @@ func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, err
|
|||
return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil
|
||||
}
|
||||
|
||||
func debugLogReqError(r *Request, stage string, retrying bool, err error) {
|
||||
const (
|
||||
notRetrying = "not retrying"
|
||||
)
|
||||
|
||||
func debugLogReqError(r *Request, stage, retryStr string, err error) {
|
||||
if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) {
|
||||
return
|
||||
}
|
||||
|
||||
retryStr := "not retrying"
|
||||
if retrying {
|
||||
retryStr = "will retry"
|
||||
}
|
||||
|
||||
r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v",
|
||||
stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err))
|
||||
}
|
||||
|
||||
// Build will build the request's object so it can be signed and sent
|
||||
// to the service. Build will also validate all the request's parameters.
|
||||
// Anny additional build Handlers set on this request will be run
|
||||
// Any additional build Handlers set on this request will be run
|
||||
// in the order they were set.
|
||||
//
|
||||
// The request will only be built once. Multiple calls to build will have
|
||||
|
@ -344,12 +399,12 @@ func (r *Request) Build() error {
|
|||
if !r.built {
|
||||
r.Handlers.Validate.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Validate Request", false, r.Error)
|
||||
debugLogReqError(r, "Validate Request", notRetrying, r.Error)
|
||||
return r.Error
|
||||
}
|
||||
r.Handlers.Build.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Build Request", false, r.Error)
|
||||
debugLogReqError(r, "Build Request", notRetrying, r.Error)
|
||||
return r.Error
|
||||
}
|
||||
r.built = true
|
||||
|
@ -358,27 +413,37 @@ func (r *Request) Build() error {
|
|||
return r.Error
|
||||
}
|
||||
|
||||
// Sign will sign the request returning error if errors are encountered.
|
||||
// Sign will sign the request, returning error if errors are encountered.
|
||||
//
|
||||
// Send will build the request prior to signing. All Sign Handlers will
|
||||
// Sign will build the request prior to signing. All Sign Handlers will
|
||||
// be executed in the order they were set.
|
||||
func (r *Request) Sign() error {
|
||||
r.Build()
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Build Request", false, r.Error)
|
||||
debugLogReqError(r, "Build Request", notRetrying, r.Error)
|
||||
return r.Error
|
||||
}
|
||||
|
||||
SanitizeHostForHeader(r.HTTPRequest)
|
||||
|
||||
r.Handlers.Sign.Run(r)
|
||||
return r.Error
|
||||
}
|
||||
|
||||
func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
|
||||
func (r *Request) getNextRequestBody() (body io.ReadCloser, err error) {
|
||||
if r.streamingBody != nil {
|
||||
return r.streamingBody, nil
|
||||
}
|
||||
|
||||
if r.safeBody != nil {
|
||||
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
|
||||
// requests with the http package. Go 1.8 removed the automatic detection
|
||||
|
@ -393,12 +458,12 @@ func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
|
|||
// of the SDK if they used that field.
|
||||
//
|
||||
// Related golang/go#18257
|
||||
l, err := computeBodyLength(r.Body)
|
||||
l, err := aws.SeekerLen(r.Body)
|
||||
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 {
|
||||
body = NoBody
|
||||
} else if l > 0 {
|
||||
|
@ -411,7 +476,8 @@ func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
|
|||
// Transfer-Encoding: chunked bodies for these methods.
|
||||
//
|
||||
// This would only happen if a aws.ReaderSeekerCloser was used with
|
||||
// a io.Reader that was not also an io.Seeker.
|
||||
// a io.Reader that was not also an io.Seeker, or did not implement
|
||||
// Len() method.
|
||||
switch r.Operation.HTTPMethod {
|
||||
case "GET", "HEAD", "DELETE":
|
||||
body = NoBody
|
||||
|
@ -423,49 +489,13 @@ func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
|
|||
return body, nil
|
||||
}
|
||||
|
||||
// Attempts to compute the length of the body of the reader using the
|
||||
// io.Seeker interface. If the value is not seekable because of being
|
||||
// a ReaderSeekerCloser without an unerlying Seeker -1 will be returned.
|
||||
// If no error occurs the length of the body will be returned.
|
||||
func computeBodyLength(r io.ReadSeeker) (int64, error) {
|
||||
seekable := true
|
||||
// Determine if the seeker is actually seekable. ReaderSeekerCloser
|
||||
// hides the fact that a io.Readers might not actually be seekable.
|
||||
switch v := r.(type) {
|
||||
case aws.ReaderSeekerCloser:
|
||||
seekable = v.IsSeeker()
|
||||
case *aws.ReaderSeekerCloser:
|
||||
seekable = v.IsSeeker()
|
||||
}
|
||||
if !seekable {
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
curOffset, err := r.Seek(0, 1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
endOffset, err := r.Seek(0, 2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
_, err = r.Seek(curOffset, 0)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return endOffset - curOffset, nil
|
||||
}
|
||||
|
||||
// GetBody will return an io.ReadSeeker of the Request's underlying
|
||||
// input body with a concurrency safe wrapper.
|
||||
func (r *Request) GetBody() io.ReadSeeker {
|
||||
return r.safeBody
|
||||
}
|
||||
|
||||
// Send will send the request returning error if errors are encountered.
|
||||
// Send will send the request, returning error if errors are encountered.
|
||||
//
|
||||
// Send will sign the request prior to sending. All Send Handlers will
|
||||
// be executed in the order they were set.
|
||||
|
@ -485,79 +515,90 @@ func (r *Request) Send() error {
|
|||
r.Handlers.Complete.Run(r)
|
||||
}()
|
||||
|
||||
if err := r.Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
if aws.BoolValue(r.Retryable) {
|
||||
if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
|
||||
r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
|
||||
r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
|
||||
}
|
||||
r.Error = nil
|
||||
r.AttemptTime = time.Now()
|
||||
|
||||
// The previous http.Request will have a reference to the r.Body
|
||||
// and the HTTP Client's Transport may still be reading from
|
||||
// the request's body even though the Client's Do returned.
|
||||
r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil)
|
||||
r.ResetBody()
|
||||
|
||||
// Closing response body to ensure that no response body is leaked
|
||||
// between retry attempts.
|
||||
if r.HTTPResponse != nil && r.HTTPResponse.Body != nil {
|
||||
r.HTTPResponse.Body.Close()
|
||||
}
|
||||
if err := r.Sign(); err != nil {
|
||||
debugLogReqError(r, "Sign Request", notRetrying, err)
|
||||
return err
|
||||
}
|
||||
|
||||
r.Sign()
|
||||
if r.Error != nil {
|
||||
if err := r.sendRequest(); err == nil {
|
||||
return nil
|
||||
}
|
||||
r.Handlers.Retry.Run(r)
|
||||
r.Handlers.AfterRetry.Run(r)
|
||||
|
||||
if r.Error != nil || !aws.BoolValue(r.Retryable) {
|
||||
return r.Error
|
||||
}
|
||||
|
||||
r.Retryable = nil
|
||||
|
||||
r.Handlers.Send.Run(r)
|
||||
if r.Error != nil {
|
||||
if !shouldRetryCancel(r) {
|
||||
return r.Error
|
||||
}
|
||||
|
||||
err := r.Error
|
||||
r.Handlers.Retry.Run(r)
|
||||
r.Handlers.AfterRetry.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Send Request", false, err)
|
||||
return r.Error
|
||||
}
|
||||
debugLogReqError(r, "Send Request", true, err)
|
||||
continue
|
||||
if err := r.prepareRetry(); err != nil {
|
||||
r.Error = err
|
||||
return err
|
||||
}
|
||||
r.Handlers.UnmarshalMeta.Run(r)
|
||||
r.Handlers.ValidateResponse.Run(r)
|
||||
if r.Error != nil {
|
||||
r.Handlers.UnmarshalError.Run(r)
|
||||
err := r.Error
|
||||
}
|
||||
}
|
||||
|
||||
r.Handlers.Retry.Run(r)
|
||||
r.Handlers.AfterRetry.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Validate Response", false, err)
|
||||
return r.Error
|
||||
}
|
||||
debugLogReqError(r, "Validate Response", true, err)
|
||||
continue
|
||||
}
|
||||
func (r *Request) prepareRetry() error {
|
||||
if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
|
||||
r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
|
||||
r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
|
||||
}
|
||||
|
||||
r.Handlers.Unmarshal.Run(r)
|
||||
if r.Error != nil {
|
||||
err := r.Error
|
||||
r.Handlers.Retry.Run(r)
|
||||
r.Handlers.AfterRetry.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Unmarshal Response", false, err)
|
||||
return r.Error
|
||||
}
|
||||
debugLogReqError(r, "Unmarshal Response", true, err)
|
||||
continue
|
||||
}
|
||||
// The previous http.Request will have a reference to the r.Body
|
||||
// and the HTTP Client's Transport may still be reading from
|
||||
// the request's body even though the Client's Do returned.
|
||||
r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil)
|
||||
r.ResetBody()
|
||||
if err := r.Error; err != nil {
|
||||
return awserr.New(ErrCodeSerialization,
|
||||
"failed to prepare body for retry", err)
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
// Closing response body to ensure that no response body is leaked
|
||||
// between retry attempts.
|
||||
if r.HTTPResponse != nil && r.HTTPResponse.Body != nil {
|
||||
r.HTTPResponse.Body.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Request) sendRequest() (sendErr error) {
|
||||
defer r.Handlers.CompleteAttempt.Run(r)
|
||||
|
||||
r.Retryable = nil
|
||||
r.Handlers.Send.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Send Request",
|
||||
fmtAttemptCount(r.RetryCount, r.MaxRetries()),
|
||||
r.Error)
|
||||
return r.Error
|
||||
}
|
||||
|
||||
r.Handlers.UnmarshalMeta.Run(r)
|
||||
r.Handlers.ValidateResponse.Run(r)
|
||||
if r.Error != nil {
|
||||
r.Handlers.UnmarshalError.Run(r)
|
||||
debugLogReqError(r, "Validate Response",
|
||||
fmtAttemptCount(r.RetryCount, r.MaxRetries()),
|
||||
r.Error)
|
||||
return r.Error
|
||||
}
|
||||
|
||||
r.Handlers.Unmarshal.Run(r)
|
||||
if r.Error != nil {
|
||||
debugLogReqError(r, "Unmarshal Response",
|
||||
fmtAttemptCount(r.RetryCount, r.MaxRetries()),
|
||||
r.Error)
|
||||
return r.Error
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -583,32 +624,6 @@ func AddToUserAgent(r *Request, s string) {
|
|||
r.HTTPRequest.Header.Set("User-Agent", s)
|
||||
}
|
||||
|
||||
func shouldRetryCancel(r *Request) bool {
|
||||
awsErr, ok := r.Error.(awserr.Error)
|
||||
timeoutErr := false
|
||||
errStr := r.Error.Error()
|
||||
if ok {
|
||||
if awsErr.Code() == CanceledErrorCode {
|
||||
return false
|
||||
}
|
||||
err := awsErr.OrigErr()
|
||||
netErr, netOK := err.(net.Error)
|
||||
timeoutErr = netOK && netErr.Temporary()
|
||||
if urlErr, ok := err.(*url.Error); !timeoutErr && ok {
|
||||
errStr = urlErr.Err.Error()
|
||||
}
|
||||
}
|
||||
|
||||
// There can be two types of canceled errors here.
|
||||
// The first being a net.Error and the other being an error.
|
||||
// If the request was timed out, we want to continue the retry
|
||||
// process. Otherwise, return the canceled error.
|
||||
return timeoutErr ||
|
||||
(errStr != "net/http: request canceled" &&
|
||||
errStr != "net/http: request canceled while waiting for connection")
|
||||
|
||||
}
|
||||
|
||||
// SanitizeHostForHeader removes default port from host and updates request.Host
|
||||
func SanitizeHostForHeader(r *http.Request) {
|
||||
host := getHost(r)
|
||||
|
|
2
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go
generated
vendored
|
@ -21,7 +21,7 @@ func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil }
|
|||
var NoBody = noBody{}
|
||||
|
||||
// ResetBody rewinds the request body back to its starting position, and
|
||||
// set's the HTTP Request body reference. When the body is read prior
|
||||
// sets the HTTP Request body reference. When the body is read prior
|
||||
// to being sent in the HTTP request it will need to be rewound.
|
||||
//
|
||||
// ResetBody will automatically be called by the SDK's build handler, but if
|
||||
|
|
7
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go
generated
vendored
7
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go
generated
vendored
|
@ -4,6 +4,8 @@ package request
|
|||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
// NoBody is a http.NoBody reader instructing Go HTTP client to not include
|
||||
|
@ -11,7 +13,7 @@ import (
|
|||
var NoBody = http.NoBody
|
||||
|
||||
// ResetBody rewinds the request body back to its starting position, and
|
||||
// set's the HTTP Request body reference. When the body is read prior
|
||||
// sets the HTTP Request body reference. When the body is read prior
|
||||
// to being sent in the HTTP request it will need to be rewound.
|
||||
//
|
||||
// ResetBody will automatically be called by the SDK's build handler, but if
|
||||
|
@ -24,7 +26,8 @@ var NoBody = http.NoBody
|
|||
func (r *Request) ResetBody() {
|
||||
body, err := r.getNextRequestBody()
|
||||
if err != nil {
|
||||
r.Error = err
|
||||
r.Error = awserr.New(ErrCodeSerialization,
|
||||
"failed to reset request body", err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
48
vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
generated
vendored
48
vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
generated
vendored
|
@ -17,11 +17,13 @@ import (
|
|||
// does the pagination between API operations, and Paginator defines the
|
||||
// configuration that will be used per page request.
|
||||
//
|
||||
// cont := true
|
||||
// for p.Next() && cont {
|
||||
// for p.Next() {
|
||||
// data := p.Page().(*s3.ListObjectsOutput)
|
||||
// // process the page's data
|
||||
// // ...
|
||||
// // break out of loop to stop fetching additional pages
|
||||
// }
|
||||
//
|
||||
// return p.Err()
|
||||
//
|
||||
// See service client API operation Pages methods for examples how the SDK will
|
||||
|
@ -35,8 +37,12 @@ type Pagination struct {
|
|||
// NewRequest should always be built from the same API operations. It is
|
||||
// undefined if different API operations are returned on subsequent calls.
|
||||
NewRequest func() (*Request, error)
|
||||
// EndPageOnSameToken, when enabled, will allow the paginator to stop on
|
||||
// token that are the same as its previous tokens.
|
||||
EndPageOnSameToken bool
|
||||
|
||||
started bool
|
||||
prevTokens []interface{}
|
||||
nextTokens []interface{}
|
||||
|
||||
err error
|
||||
|
@ -49,7 +55,15 @@ type Pagination struct {
|
|||
//
|
||||
// Will always return true if Next has not been called yet.
|
||||
func (p *Pagination) HasNextPage() bool {
|
||||
return !(p.started && len(p.nextTokens) == 0)
|
||||
if !p.started {
|
||||
return true
|
||||
}
|
||||
|
||||
hasNextPage := len(p.nextTokens) != 0
|
||||
if p.EndPageOnSameToken {
|
||||
return hasNextPage && !awsutil.DeepEqual(p.nextTokens, p.prevTokens)
|
||||
}
|
||||
return hasNextPage
|
||||
}
|
||||
|
||||
// Err returns the error Pagination encountered when retrieving the next page.
|
||||
|
@ -96,6 +110,7 @@ func (p *Pagination) Next() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
p.prevTokens = p.nextTokens
|
||||
p.nextTokens = req.nextPageTokens()
|
||||
p.curPage = req.Data
|
||||
|
||||
|
@ -133,7 +148,7 @@ func (r *Request) nextPageTokens() []interface{} {
|
|||
return nil
|
||||
}
|
||||
case bool:
|
||||
if v == false {
|
||||
if !v {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -142,13 +157,28 @@ func (r *Request) nextPageTokens() []interface{} {
|
|||
tokens := []interface{}{}
|
||||
tokenAdded := false
|
||||
for _, outToken := range r.Operation.OutputTokens {
|
||||
v, _ := awsutil.ValuesAtPath(r.Data, outToken)
|
||||
if len(v) > 0 {
|
||||
tokens = append(tokens, v[0])
|
||||
tokenAdded = true
|
||||
} else {
|
||||
vs, _ := awsutil.ValuesAtPath(r.Data, outToken)
|
||||
if len(vs) == 0 {
|
||||
tokens = append(tokens, nil)
|
||||
continue
|
||||
}
|
||||
v := vs[0]
|
||||
|
||||
switch tv := v.(type) {
|
||||
case *string:
|
||||
if len(aws.StringValue(tv)) == 0 {
|
||||
tokens = append(tokens, nil)
|
||||
continue
|
||||
}
|
||||
case string:
|
||||
if len(tv) == 0 {
|
||||
tokens = append(tokens, nil)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
tokenAdded = true
|
||||
tokens = append(tokens, v)
|
||||
}
|
||||
if !tokenAdded {
|
||||
return nil
|
||||
|
|
206
vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
generated
vendored
206
vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
generated
vendored
|
@ -1,32 +1,81 @@
|
|||
package request
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
// Retryer is an interface to control retry logic for a given service.
|
||||
// The default implementation used by most services is the client.DefaultRetryer
|
||||
// structure, which contains basic retry logic using exponential backoff.
|
||||
// Retryer provides the interface drive the SDK's request retry behavior. The
|
||||
// Retryer implementation is responsible for implementing exponential backoff,
|
||||
// and determine if a request API error should be retried.
|
||||
//
|
||||
// client.DefaultRetryer is the SDK's default implementation of the Retryer. It
|
||||
// uses the which uses the Request.IsErrorRetryable and Request.IsErrorThrottle
|
||||
// methods to determine if the request is retried.
|
||||
type Retryer interface {
|
||||
// RetryRules return the retry delay that should be used by the SDK before
|
||||
// making another request attempt for the failed request.
|
||||
RetryRules(*Request) time.Duration
|
||||
|
||||
// ShouldRetry returns if the failed request is retryable.
|
||||
//
|
||||
// Implementations may consider request attempt count when determining if a
|
||||
// request is retryable, but the SDK will use MaxRetries to limit the
|
||||
// number of attempts a request are made.
|
||||
ShouldRetry(*Request) bool
|
||||
|
||||
// MaxRetries is the number of times a request may be retried before
|
||||
// failing.
|
||||
MaxRetries() int
|
||||
}
|
||||
|
||||
// WithRetryer sets a config Retryer value to the given Config returning it
|
||||
// for chaining.
|
||||
// WithRetryer sets a Retryer value to the given Config returning the Config
|
||||
// value for chaining. The value must not be nil.
|
||||
func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config {
|
||||
if retryer == nil {
|
||||
if cfg.Logger != nil {
|
||||
cfg.Logger.Log("ERROR: Request.WithRetryer called with nil retryer. Replacing with retry disabled Retryer.")
|
||||
}
|
||||
retryer = noOpRetryer{}
|
||||
}
|
||||
cfg.Retryer = retryer
|
||||
return cfg
|
||||
|
||||
}
|
||||
|
||||
// noOpRetryer is a internal no op retryer used when a request is created
|
||||
// without a retryer.
|
||||
//
|
||||
// Provides a retryer that performs no retries.
|
||||
// It should be used when we do not want retries to be performed.
|
||||
type noOpRetryer struct{}
|
||||
|
||||
// MaxRetries returns the number of maximum returns the service will use to make
|
||||
// an individual API; For NoOpRetryer the MaxRetries will always be zero.
|
||||
func (d noOpRetryer) MaxRetries() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// ShouldRetry will always return false for NoOpRetryer, as it should never retry.
|
||||
func (d noOpRetryer) ShouldRetry(_ *Request) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// RetryRules returns the delay duration before retrying this request again;
|
||||
// since NoOpRetryer does not retry, RetryRules always returns 0.
|
||||
func (d noOpRetryer) RetryRules(_ *Request) time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
||||
// retryableCodes is a collection of service response codes which are retry-able
|
||||
// without any further action.
|
||||
var retryableCodes = map[string]struct{}{
|
||||
"RequestError": {},
|
||||
ErrCodeRequestError: {},
|
||||
"RequestTimeout": {},
|
||||
ErrCodeResponseTimeout: {},
|
||||
"RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout
|
||||
|
@ -34,12 +83,16 @@ var retryableCodes = map[string]struct{}{
|
|||
|
||||
var throttleCodes = map[string]struct{}{
|
||||
"ProvisionedThroughputExceededException": {},
|
||||
"ThrottledException": {}, // SNS, XRay, ResourceGroupsTagging API
|
||||
"Throttling": {},
|
||||
"ThrottlingException": {},
|
||||
"RequestLimitExceeded": {},
|
||||
"RequestThrottled": {},
|
||||
"RequestThrottledException": {},
|
||||
"TooManyRequestsException": {}, // Lambda functions
|
||||
"PriorRequestNotComplete": {}, // Route53
|
||||
"TransactionInProgressException": {},
|
||||
"EC2ThrottledException": {}, // EC2
|
||||
}
|
||||
|
||||
// credsExpiredCodes is a collection of error codes which signify the credentials
|
||||
|
@ -74,10 +127,6 @@ var validParentCodes = map[string]struct{}{
|
|||
ErrCodeRead: {},
|
||||
}
|
||||
|
||||
type temporaryError interface {
|
||||
Temporary() bool
|
||||
}
|
||||
|
||||
func isNestedErrorRetryable(parentErr awserr.Error) bool {
|
||||
if parentErr == nil {
|
||||
return false
|
||||
|
@ -96,8 +145,8 @@ func isNestedErrorRetryable(parentErr awserr.Error) bool {
|
|||
return isCodeRetryable(aerr.Code())
|
||||
}
|
||||
|
||||
if t, ok := err.(temporaryError); ok {
|
||||
return t.Temporary()
|
||||
if t, ok := err.(temporary); ok {
|
||||
return t.Temporary() || isErrConnectionReset(err)
|
||||
}
|
||||
|
||||
return isErrConnectionReset(err)
|
||||
|
@ -106,32 +155,90 @@ func isNestedErrorRetryable(parentErr awserr.Error) bool {
|
|||
// IsErrorRetryable returns whether the error is retryable, based on its Code.
|
||||
// Returns false if error is nil.
|
||||
func IsErrorRetryable(err error) bool {
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
return isCodeRetryable(aerr.Code()) || isNestedErrorRetryable(aerr)
|
||||
}
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
return shouldRetryError(err)
|
||||
}
|
||||
|
||||
type temporary interface {
|
||||
Temporary() bool
|
||||
}
|
||||
|
||||
func shouldRetryError(origErr error) bool {
|
||||
switch err := origErr.(type) {
|
||||
case awserr.Error:
|
||||
if err.Code() == CanceledErrorCode {
|
||||
return false
|
||||
}
|
||||
if isNestedErrorRetryable(err) {
|
||||
return true
|
||||
}
|
||||
|
||||
origErr := err.OrigErr()
|
||||
var shouldRetry bool
|
||||
if origErr != nil {
|
||||
shouldRetry = shouldRetryError(origErr)
|
||||
if err.Code() == ErrCodeRequestError && !shouldRetry {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if isCodeRetryable(err.Code()) {
|
||||
return true
|
||||
}
|
||||
return shouldRetry
|
||||
|
||||
case *url.Error:
|
||||
if strings.Contains(err.Error(), "connection refused") {
|
||||
// Refused connections should be retried as the service may not yet
|
||||
// be running on the port. Go TCP dial considers refused
|
||||
// connections as not temporary.
|
||||
return true
|
||||
}
|
||||
// *url.Error only implements Temporary after golang 1.6 but since
|
||||
// url.Error only wraps the error:
|
||||
return shouldRetryError(err.Err)
|
||||
|
||||
case temporary:
|
||||
if netErr, ok := err.(*net.OpError); ok && netErr.Op == "dial" {
|
||||
return true
|
||||
}
|
||||
// If the error is temporary, we want to allow continuation of the
|
||||
// retry process
|
||||
return err.Temporary() || isErrConnectionReset(origErr)
|
||||
|
||||
case nil:
|
||||
// `awserr.Error.OrigErr()` can be nil, meaning there was an error but
|
||||
// because we don't know the cause, it is marked as retryable. See
|
||||
// TestRequest4xxUnretryable for an example.
|
||||
return true
|
||||
|
||||
default:
|
||||
switch err.Error() {
|
||||
case "net/http: request canceled",
|
||||
"net/http: request canceled while waiting for connection":
|
||||
// known 1.5 error case when an http request is cancelled
|
||||
return false
|
||||
}
|
||||
// here we don't know the error; so we allow a retry.
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsErrorThrottle returns whether the error is to be throttled based on its code.
|
||||
// Returns false if error is nil.
|
||||
func IsErrorThrottle(err error) bool {
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
return isCodeThrottle(aerr.Code())
|
||||
}
|
||||
if aerr, ok := err.(awserr.Error); ok && aerr != nil {
|
||||
return isCodeThrottle(aerr.Code())
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsErrorExpiredCreds returns whether the error code is a credential expiry error.
|
||||
// Returns false if error is nil.
|
||||
// IsErrorExpiredCreds returns whether the error code is a credential expiry
|
||||
// error. Returns false if error is nil.
|
||||
func IsErrorExpiredCreds(err error) bool {
|
||||
if err != nil {
|
||||
if aerr, ok := err.(awserr.Error); ok {
|
||||
return isCodeExpiredCreds(aerr.Code())
|
||||
}
|
||||
if aerr, ok := err.(awserr.Error); ok && aerr != nil {
|
||||
return isCodeExpiredCreds(aerr.Code())
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -141,17 +248,58 @@ func IsErrorExpiredCreds(err error) bool {
|
|||
//
|
||||
// Alias for the utility function IsErrorRetryable
|
||||
func (r *Request) IsErrorRetryable() bool {
|
||||
if isErrCode(r.Error, r.RetryErrorCodes) {
|
||||
return true
|
||||
}
|
||||
|
||||
// HTTP response status code 501 should not be retried.
|
||||
// 501 represents Not Implemented which means the request method is not
|
||||
// supported by the server and cannot be handled.
|
||||
if r.HTTPResponse != nil {
|
||||
// HTTP response status code 500 represents internal server error and
|
||||
// should be retried without any throttle.
|
||||
if r.HTTPResponse.StatusCode == 500 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return IsErrorRetryable(r.Error)
|
||||
}
|
||||
|
||||
// IsErrorThrottle returns whether the error is to be throttled based on its code.
|
||||
// Returns false if the request has no Error set
|
||||
// IsErrorThrottle returns whether the error is to be throttled based on its
|
||||
// code. Returns false if the request has no Error set.
|
||||
//
|
||||
// Alias for the utility function IsErrorThrottle
|
||||
func (r *Request) IsErrorThrottle() bool {
|
||||
if isErrCode(r.Error, r.ThrottleErrorCodes) {
|
||||
return true
|
||||
}
|
||||
|
||||
if r.HTTPResponse != nil {
|
||||
switch r.HTTPResponse.StatusCode {
|
||||
case
|
||||
429, // error caused due to too many requests
|
||||
502, // Bad Gateway error should be throttled
|
||||
503, // caused when service is unavailable
|
||||
504: // error occurred due to gateway timeout
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return IsErrorThrottle(r.Error)
|
||||
}
|
||||
|
||||
func isErrCode(err error, codes []string) bool {
|
||||
if aerr, ok := err.(awserr.Error); ok && aerr != nil {
|
||||
for _, code := range codes {
|
||||
if code == aerr.Code() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// IsErrorExpired returns whether the error code is a credential expiry error.
|
||||
// Returns false if the request has no Error set.
|
||||
//
|
||||
|
|
52
vendor/github.com/aws/aws-sdk-go/aws/request/validation.go
generated
vendored
52
vendor/github.com/aws/aws-sdk-go/aws/request/validation.go
generated
vendored
|
@ -17,6 +17,12 @@ const (
|
|||
ParamMinValueErrCode = "ParamMinValueError"
|
||||
// ParamMinLenErrCode is the error code for fields without enough elements.
|
||||
ParamMinLenErrCode = "ParamMinLenError"
|
||||
// ParamMaxLenErrCode is the error code for value being too long.
|
||||
ParamMaxLenErrCode = "ParamMaxLenError"
|
||||
|
||||
// ParamFormatErrCode is the error code for a field with invalid
|
||||
// format or characters.
|
||||
ParamFormatErrCode = "ParamFormatInvalidError"
|
||||
)
|
||||
|
||||
// Validator provides a way for types to perform validation logic on their
|
||||
|
@ -232,3 +238,49 @@ func NewErrParamMinLen(field string, min int) *ErrParamMinLen {
|
|||
func (e *ErrParamMinLen) MinLen() int {
|
||||
return e.min
|
||||
}
|
||||
|
||||
// An ErrParamMaxLen represents a maximum length parameter error.
|
||||
type ErrParamMaxLen struct {
|
||||
errInvalidParam
|
||||
max int
|
||||
}
|
||||
|
||||
// NewErrParamMaxLen creates a new maximum length parameter error.
|
||||
func NewErrParamMaxLen(field string, max int, value string) *ErrParamMaxLen {
|
||||
return &ErrParamMaxLen{
|
||||
errInvalidParam: errInvalidParam{
|
||||
code: ParamMaxLenErrCode,
|
||||
field: field,
|
||||
msg: fmt.Sprintf("maximum size of %v, %v", max, value),
|
||||
},
|
||||
max: max,
|
||||
}
|
||||
}
|
||||
|
||||
// MaxLen returns the field's required minimum length.
|
||||
func (e *ErrParamMaxLen) MaxLen() int {
|
||||
return e.max
|
||||
}
|
||||
|
||||
// An ErrParamFormat represents a invalid format parameter error.
|
||||
type ErrParamFormat struct {
|
||||
errInvalidParam
|
||||
format string
|
||||
}
|
||||
|
||||
// NewErrParamFormat creates a new invalid format parameter error.
|
||||
func NewErrParamFormat(field string, format, value string) *ErrParamFormat {
|
||||
return &ErrParamFormat{
|
||||
errInvalidParam: errInvalidParam{
|
||||
code: ParamFormatErrCode,
|
||||
field: field,
|
||||
msg: fmt.Sprintf("format %v, %v", format, value),
|
||||
},
|
||||
format: format,
|
||||
}
|
||||
}
|
||||
|
||||
// Format returns the field's required format.
|
||||
func (e *ErrParamFormat) Format() string {
|
||||
return e.format
|
||||
}
|
||||
|
|
26
vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport.go
generated
vendored
Normal file
26
vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport.go
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
// +build go1.7
|
||||
|
||||
package session
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Transport that should be used when a custom CA bundle is specified with the
|
||||
// SDK.
|
||||
func getCABundleTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
}
|
||||
}
|
22
vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_5.go
generated
vendored
Normal file
22
vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_5.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
// +build !go1.6,go1.5
|
||||
|
||||
package session
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Transport that should be used when a custom CA bundle is specified with the
|
||||
// SDK.
|
||||
func getCABundleTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
}
|
||||
}
|
23
vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_6.go
generated
vendored
Normal file
23
vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_6.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
// +build !go1.7,go1.6
|
||||
|
||||
package session
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Transport that should be used when a custom CA bundle is specified with the
|
||||
// SDK.
|
||||
func getCABundleTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
Dial: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).Dial,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
}
|
||||
}
|
259
vendor/github.com/aws/aws-sdk-go/aws/session/credentials.go
generated
vendored
Normal file
259
vendor/github.com/aws/aws-sdk-go/aws/session/credentials.go
generated
vendored
Normal file
|
@ -0,0 +1,259 @@
|
|||
package session
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/processcreds"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||
)
|
||||
|
||||
func resolveCredentials(cfg *aws.Config,
|
||||
envCfg envConfig, sharedCfg sharedConfig,
|
||||
handlers request.Handlers,
|
||||
sessOpts Options,
|
||||
) (*credentials.Credentials, error) {
|
||||
|
||||
switch {
|
||||
case len(sessOpts.Profile) != 0:
|
||||
// User explicitly provided an Profile in the session's configuration
|
||||
// so load that profile from shared config first.
|
||||
// Github(aws/aws-sdk-go#2727)
|
||||
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_ROLE_ARN' was not set.
|
||||
var WebIdentityEmptyRoleARNErr = awserr.New(stscreds.ErrCodeWebIdentity, "role ARN is not set", nil)
|
||||
|
||||
// WebIdentityEmptyTokenFilePathErr will occur if 'AWS_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
|
||||
const (
|
||||
credSourceEc2Metadata = "Ec2InstanceMetadata"
|
||||
credSourceEnvironment = "Environment"
|
||||
credSourceECSContainer = "EcsContainer"
|
||||
)
|
||||
|
||||
func resolveCredsFromSource(cfg *aws.Config,
|
||||
envCfg envConfig, sharedCfg sharedConfig,
|
||||
handlers request.Handlers,
|
||||
sessOpts Options,
|
||||
) (creds *credentials.Credentials, err error) {
|
||||
|
||||
switch sharedCfg.CredentialSource {
|
||||
case credSourceEc2Metadata:
|
||||
p := defaults.RemoteCredProvider(*cfg, handlers)
|
||||
creds = credentials.NewCredentials(p)
|
||||
|
||||
case credSourceEnvironment:
|
||||
creds = credentials.NewStaticCredentialsFromCreds(envCfg.Creds)
|
||||
|
||||
case credSourceECSContainer:
|
||||
if len(os.Getenv(shareddefaults.ECSCredsProviderEnvVar)) == 0 {
|
||||
return nil, ErrSharedConfigECSContainerEnvVarEmpty
|
||||
}
|
||||
|
||||
p := defaults.RemoteCredProvider(*cfg, handlers)
|
||||
creds = credentials.NewCredentials(p)
|
||||
|
||||
default:
|
||||
return nil, ErrSharedConfigInvalidCredSource
|
||||
}
|
||||
|
||||
return creds, nil
|
||||
}
|
||||
|
||||
func credsFromAssumeRole(cfg aws.Config,
|
||||
handlers request.Handlers,
|
||||
sharedCfg sharedConfig,
|
||||
sessOpts Options,
|
||||
) (*credentials.Credentials, error) {
|
||||
|
||||
if len(sharedCfg.MFASerial) != 0 && sessOpts.AssumeRoleTokenProvider == nil {
|
||||
// AssumeRole Token provider is required if doing Assume Role
|
||||
// with MFA.
|
||||
return nil, AssumeRoleTokenProviderNotSetError{}
|
||||
}
|
||||
|
||||
return stscreds.NewCredentials(
|
||||
&Session{
|
||||
Config: &cfg,
|
||||
Handlers: handlers.Copy(),
|
||||
},
|
||||
sharedCfg.RoleARN,
|
||||
func(opt *stscreds.AssumeRoleProvider) {
|
||||
opt.RoleSessionName = sharedCfg.RoleSessionName
|
||||
opt.Duration = sessOpts.AssumeRoleDuration
|
||||
|
||||
// Assume role with external ID
|
||||
if len(sharedCfg.ExternalID) > 0 {
|
||||
opt.ExternalID = aws.String(sharedCfg.ExternalID)
|
||||
}
|
||||
|
||||
// Assume role with MFA
|
||||
if len(sharedCfg.MFASerial) > 0 {
|
||||
opt.SerialNumber = aws.String(sharedCfg.MFASerial)
|
||||
opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
|
||||
}
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
// AssumeRoleTokenProviderNotSetError is an error returned when creating a
|
||||
// session when the MFAToken option is not set when shared config is configured
|
||||
// load assume a role with an MFA token.
|
||||
type AssumeRoleTokenProviderNotSetError struct{}
|
||||
|
||||
// Code is the short id of the error.
|
||||
func (e AssumeRoleTokenProviderNotSetError) Code() string {
|
||||
return "AssumeRoleTokenProviderNotSetError"
|
||||
}
|
||||
|
||||
// Message is the description of the error
|
||||
func (e AssumeRoleTokenProviderNotSetError) Message() string {
|
||||
return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.")
|
||||
}
|
||||
|
||||
// OrigErr is the underlying error that caused the failure.
|
||||
func (e AssumeRoleTokenProviderNotSetError) OrigErr() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Error satisfies the error interface.
|
||||
func (e AssumeRoleTokenProviderNotSetError) Error() string {
|
||||
return awserr.SprintError(e.Code(), e.Message(), "", nil)
|
||||
}
|
||||
|
||||
type credProviderError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (c credProviderError) Retrieve() (credentials.Value, error) {
|
||||
return credentials.Value{}, c.Err
|
||||
}
|
||||
func (c credProviderError) IsExpired() bool {
|
||||
return true
|
||||
}
|
212
vendor/github.com/aws/aws-sdk-go/aws/session/doc.go
generated
vendored
212
vendor/github.com/aws/aws-sdk-go/aws/session/doc.go
generated
vendored
|
@ -1,97 +1,93 @@
|
|||
/*
|
||||
Package session provides configuration for the SDK's service clients.
|
||||
|
||||
Sessions can be shared across all service clients that share the same base
|
||||
configuration. The Session is built from the SDK's default configuration and
|
||||
request handlers.
|
||||
|
||||
Sessions should be cached when possible, because creating a new Session will
|
||||
load all configuration values from the environment, and config files each time
|
||||
the Session is created. Sharing the Session value across all of your service
|
||||
clients will ensure the configuration is loaded the fewest number of times possible.
|
||||
|
||||
Concurrency
|
||||
Package session provides configuration for the SDK's service clients. Sessions
|
||||
can be shared across service clients that share the same base configuration.
|
||||
|
||||
Sessions are safe to use concurrently as long as the Session is not being
|
||||
modified. The SDK will not modify the Session once the Session has been created.
|
||||
Creating service clients concurrently from a shared Session is safe.
|
||||
modified. Sessions should be cached when possible, because creating a new
|
||||
Session will load all configuration values from the environment, and config
|
||||
files each time the Session is created. Sharing the Session value across all of
|
||||
your service clients will ensure the configuration is loaded the fewest number
|
||||
of times possible.
|
||||
|
||||
Sessions from Shared Config
|
||||
|
||||
Sessions can be created using the method above that will only load the
|
||||
additional config if the AWS_SDK_LOAD_CONFIG environment variable is set.
|
||||
Alternatively you can explicitly create a Session with shared config enabled.
|
||||
To do this you can use NewSessionWithOptions to configure how the Session will
|
||||
be created. Using the NewSessionWithOptions with SharedConfigState set to
|
||||
SharedConfigEnable will create the session as if the AWS_SDK_LOAD_CONFIG
|
||||
environment variable was set.
|
||||
|
||||
Creating Sessions
|
||||
|
||||
When creating Sessions optional aws.Config values can be passed in that will
|
||||
override the default, or loaded config values the Session is being created
|
||||
with. This allows you to provide additional, or case based, configuration
|
||||
as needed.
|
||||
Sessions options from Shared Config
|
||||
|
||||
By default NewSession will only load credentials from the shared credentials
|
||||
file (~/.aws/credentials). If the AWS_SDK_LOAD_CONFIG environment variable is
|
||||
set to a truthy value the Session will be created from the configuration
|
||||
values from the shared config (~/.aws/config) and shared credentials
|
||||
(~/.aws/credentials) files. See the section Sessions from Shared Config for
|
||||
more information.
|
||||
(~/.aws/credentials) files. Using the NewSessionWithOptions with
|
||||
SharedConfigState set to SharedConfigEnable will create the session as if the
|
||||
AWS_SDK_LOAD_CONFIG environment variable was set.
|
||||
|
||||
Create a Session with the default config and request handlers. With credentials
|
||||
region, and profile loaded from the environment and shared config automatically.
|
||||
Requires the AWS_PROFILE to be set, or "default" is used.
|
||||
Credential and config loading order
|
||||
|
||||
The Session will attempt to load configuration and credentials from the
|
||||
environment, configuration files, and other credential sources. The order
|
||||
configuration is loaded in is:
|
||||
|
||||
* Environment Variables
|
||||
* Shared Credentials file
|
||||
* Shared Configuration file (if SharedConfig is enabled)
|
||||
* EC2 Instance Metadata (credentials only)
|
||||
|
||||
The Environment variables for credentials will have precedence over shared
|
||||
config even if SharedConfig is enabled. To override this behavior, and use
|
||||
shared config credentials instead specify the session.Options.Profile, (e.g.
|
||||
when using credential_source=Environment to assume a role).
|
||||
|
||||
sess, err := session.NewSessionWithOptions(session.Options{
|
||||
Profile: "myProfile",
|
||||
})
|
||||
|
||||
Creating Sessions
|
||||
|
||||
Creating a Session without additional options will load credentials region, and
|
||||
profile loaded from the environment and shared config automatically. See,
|
||||
"Environment Variables" section for information on environment variables used
|
||||
by Session.
|
||||
|
||||
// Create Session
|
||||
sess := session.Must(session.NewSession())
|
||||
sess, err := session.NewSession()
|
||||
|
||||
|
||||
When creating Sessions optional aws.Config values can be passed in that will
|
||||
override the default, or loaded, config values the Session is being created
|
||||
with. This allows you to provide additional, or case based, configuration
|
||||
as needed.
|
||||
|
||||
// Create a Session with a custom region
|
||||
sess := session.Must(session.NewSession(&aws.Config{
|
||||
Region: aws.String("us-east-1"),
|
||||
}))
|
||||
sess, err := session.NewSession(&aws.Config{
|
||||
Region: aws.String("us-west-2"),
|
||||
})
|
||||
|
||||
// Create a S3 client instance from a session
|
||||
sess := session.Must(session.NewSession())
|
||||
|
||||
svc := s3.New(sess)
|
||||
|
||||
Create Session With Option Overrides
|
||||
|
||||
In addition to NewSession, Sessions can be created using NewSessionWithOptions.
|
||||
This func allows you to control and override how the Session will be created
|
||||
through code instead of being driven by environment variables only.
|
||||
|
||||
Use NewSessionWithOptions when you want to provide the config profile, or
|
||||
override the shared config state (AWS_SDK_LOAD_CONFIG).
|
||||
Use NewSessionWithOptions to provide additional configuration driving how the
|
||||
Session's configuration will be loaded. Such as, specifying shared config
|
||||
profile, or override the shared config state, (AWS_SDK_LOAD_CONFIG).
|
||||
|
||||
// Equivalent to session.NewSession()
|
||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||
sess, err := session.NewSessionWithOptions(session.Options{
|
||||
// Options
|
||||
}))
|
||||
})
|
||||
|
||||
// Specify profile to load for the session's config
|
||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||
Profile: "profile_name",
|
||||
}))
|
||||
sess, err := session.NewSessionWithOptions(session.Options{
|
||||
// Specify profile to load for the session's config
|
||||
Profile: "profile_name",
|
||||
|
||||
// Specify profile for config and region for requests
|
||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||
Config: aws.Config{Region: aws.String("us-east-1")},
|
||||
Profile: "profile_name",
|
||||
}))
|
||||
// Provide SDK Config options, such as Region.
|
||||
Config: aws.Config{
|
||||
Region: aws.String("us-west-2"),
|
||||
},
|
||||
|
||||
// Force enable Shared Config support
|
||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||
// Force enable Shared Config support
|
||||
SharedConfigState: session.SharedConfigEnable,
|
||||
}))
|
||||
})
|
||||
|
||||
Adding Handlers
|
||||
|
||||
You can add handlers to a session for processing HTTP requests. All service
|
||||
clients that use the session inherit the handlers. For example, the following
|
||||
handler logs every request and its payload made by a service client:
|
||||
You can add handlers to a session to decorate API operation, (e.g. adding HTTP
|
||||
headers). All clients that use the Session receive a copy of the Session's
|
||||
handlers. For example, the following request handler added to the Session logs
|
||||
every requests made.
|
||||
|
||||
// Create a session, and add additional handlers for all service
|
||||
// clients created with the Session to inherit. Adds logging handler.
|
||||
|
@ -99,22 +95,15 @@ handler logs every request and its payload made by a service client:
|
|||
|
||||
sess.Handlers.Send.PushFront(func(r *request.Request) {
|
||||
// Log every request made and its payload
|
||||
logger.Println("Request: %s/%s, Payload: %s",
|
||||
logger.Printf("Request: %s/%s, Params: %s",
|
||||
r.ClientInfo.ServiceName, r.Operation, r.Params)
|
||||
})
|
||||
|
||||
Deprecated "New" function
|
||||
|
||||
The New session function has been deprecated because it does not provide good
|
||||
way to return errors that occur when loading the configuration files and values.
|
||||
Because of this, NewSession was created so errors can be retrieved when
|
||||
creating a session fails.
|
||||
|
||||
Shared Config Fields
|
||||
|
||||
By default the SDK will only load the shared credentials file's (~/.aws/credentials)
|
||||
credentials values, and all other config is provided by the environment variables,
|
||||
SDK defaults, and user provided aws.Config values.
|
||||
By default the SDK will only load the shared credentials file's
|
||||
(~/.aws/credentials) credentials values, and all other config is provided by
|
||||
the environment variables, SDK defaults, and user provided aws.Config values.
|
||||
|
||||
If the AWS_SDK_LOAD_CONFIG environment variable is set, or SharedConfigEnable
|
||||
option is used to create the Session the full shared config values will be
|
||||
|
@ -125,24 +114,31 @@ files have the same format.
|
|||
|
||||
If both config files are present the configuration from both files will be
|
||||
read. The Session will be created from configuration values from the shared
|
||||
credentials file (~/.aws/credentials) over those in the shared config file (~/.aws/config).
|
||||
credentials file (~/.aws/credentials) over those in the shared config file
|
||||
(~/.aws/config).
|
||||
|
||||
Credentials are the values the SDK should use for authenticating requests with
|
||||
AWS Services. They arfrom a configuration file will need to include both
|
||||
aws_access_key_id and aws_secret_access_key must be provided together in the
|
||||
same file to be 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 other two fields are also provided.
|
||||
Credentials are the values the SDK uses to authenticating requests with AWS
|
||||
Services. When specified in a file, both aws_access_key_id and
|
||||
aws_secret_access_key must be provided together in the same file to be
|
||||
considered valid. They will be ignored if both are not present.
|
||||
aws_session_token is an optional field that can be provided in addition to the
|
||||
other two fields.
|
||||
|
||||
aws_access_key_id = AKID
|
||||
aws_secret_access_key = SECRET
|
||||
aws_session_token = TOKEN
|
||||
|
||||
Assume Role values allow you to configure the SDK to assume an IAM role using
|
||||
a set of credentials provided in a config file via the source_profile field.
|
||||
Both "role_arn" and "source_profile" are required. The SDK supports assuming
|
||||
a role with MFA token if the session option AssumeRoleTokenProvider
|
||||
is set.
|
||||
; region only supported if SharedConfigEnabled.
|
||||
region = us-east-1
|
||||
|
||||
Assume Role configuration
|
||||
|
||||
The role_arn field allows you to configure the SDK to assume an IAM role using
|
||||
a set of credentials from another source. Such as when paired with static
|
||||
credentials, "profile_source", "credential_process", or "credential_source"
|
||||
fields. If "role_arn" is provided, a source of credentials must also be
|
||||
specified, such as "source_profile", "credential_source", or
|
||||
"credential_process".
|
||||
|
||||
role_arn = arn:aws:iam::<account_number>:role/<role_name>
|
||||
source_profile = profile_with_creds
|
||||
|
@ -150,40 +146,16 @@ is set.
|
|||
mfa_serial = <serial or mfa arn>
|
||||
role_session_name = session_name
|
||||
|
||||
Region is the region the SDK should use for looking up AWS service endpoints
|
||||
and signing requests.
|
||||
|
||||
region = us-east-1
|
||||
|
||||
Assume Role with MFA token
|
||||
|
||||
To create a session with support for assuming an IAM role with MFA set the
|
||||
session option AssumeRoleTokenProvider to a function that will prompt for the
|
||||
MFA token code when the SDK assumes the role and refreshes the role's credentials.
|
||||
This allows you to configure the SDK via the shared config to assumea role
|
||||
with MFA tokens.
|
||||
|
||||
In order for the SDK to assume a role with MFA the SharedConfigState
|
||||
session option must be set to SharedConfigEnable, or AWS_SDK_LOAD_CONFIG
|
||||
environment variable set.
|
||||
|
||||
The shared configuration instructs the SDK to assume an IAM role with MFA
|
||||
when the mfa_serial configuration field is set in the shared config
|
||||
(~/.aws/config) or shared credentials (~/.aws/credentials) file.
|
||||
|
||||
If mfa_serial is set in the configuration, the SDK will assume the role, and
|
||||
the AssumeRoleTokenProvider session option is not set an an error will
|
||||
be returned when creating the session.
|
||||
The SDK supports assuming a role with MFA token. If "mfa_serial" is set, you
|
||||
must also set the Session Option.AssumeRoleTokenProvider. The Session will fail
|
||||
to load if the AssumeRoleTokenProvider is not specified.
|
||||
|
||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||
AssumeRoleTokenProvider: stscreds.StdinTokenProvider,
|
||||
}))
|
||||
|
||||
// Create service client value configured for credentials
|
||||
// from assumed role.
|
||||
svc := s3.New(sess)
|
||||
|
||||
To setup assume role outside of a session see the stscrds.AssumeRoleProvider
|
||||
To setup Assume Role outside of a session see the stscreds.AssumeRoleProvider
|
||||
documentation.
|
||||
|
||||
Environment Variables
|
||||
|
|
182
vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
generated
vendored
182
vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
generated
vendored
|
@ -1,10 +1,15 @@
|
|||
package session
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||
)
|
||||
|
||||
// EnvProviderName provides a name of the provider when config is loaded from environment.
|
||||
|
@ -78,7 +83,7 @@ type envConfig struct {
|
|||
// AWS_CONFIG_FILE=$HOME/my_shared_config
|
||||
SharedConfigFile string
|
||||
|
||||
// Sets the path to a custom Credentials Authroity (CA) Bundle PEM file
|
||||
// Sets the path to a custom Credentials Authority (CA) Bundle PEM file
|
||||
// that the SDK will use instead of the system's root CA bundle.
|
||||
// Only use this if you want to configure the SDK to use a custom set
|
||||
// of CAs.
|
||||
|
@ -95,9 +100,69 @@ type envConfig struct {
|
|||
//
|
||||
// AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle
|
||||
CustomCABundle string
|
||||
|
||||
csmEnabled string
|
||||
CSMEnabled *bool
|
||||
CSMPort string
|
||||
CSMHost string
|
||||
CSMClientID string
|
||||
|
||||
// Enables endpoint discovery via environment variables.
|
||||
//
|
||||
// AWS_ENABLE_ENDPOINT_DISCOVERY=true
|
||||
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
|
||||
|
||||
// Specifies the STS Regional Endpoint flag for the SDK to resolve the endpoint
|
||||
// for a service.
|
||||
//
|
||||
// AWS_STS_REGIONAL_ENDPOINTS=regional
|
||||
// This can take value as `regional` or `legacy`
|
||||
STSRegionalEndpoint endpoints.STSRegionalEndpoint
|
||||
|
||||
// Specifies the S3 Regional Endpoint flag for the SDK to resolve the
|
||||
// endpoint for a service.
|
||||
//
|
||||
// AWS_S3_US_EAST_1_REGIONAL_ENDPOINT=regional
|
||||
// This can take value as `regional` or `legacy`
|
||||
S3UsEast1RegionalEndpoint endpoints.S3UsEast1RegionalEndpoint
|
||||
|
||||
// Specifies if the S3 service should allow ARNs to direct the region
|
||||
// the client's requests are sent to.
|
||||
//
|
||||
// AWS_S3_USE_ARN_REGION=true
|
||||
S3UseARNRegion bool
|
||||
}
|
||||
|
||||
var (
|
||||
csmEnabledEnvKey = []string{
|
||||
"AWS_CSM_ENABLED",
|
||||
}
|
||||
csmHostEnvKey = []string{
|
||||
"AWS_CSM_HOST",
|
||||
}
|
||||
csmPortEnvKey = []string{
|
||||
"AWS_CSM_PORT",
|
||||
}
|
||||
csmClientIDEnvKey = []string{
|
||||
"AWS_CSM_CLIENT_ID",
|
||||
}
|
||||
credAccessEnvKey = []string{
|
||||
"AWS_ACCESS_KEY_ID",
|
||||
"AWS_ACCESS_KEY",
|
||||
|
@ -110,6 +175,10 @@ var (
|
|||
"AWS_SESSION_TOKEN",
|
||||
}
|
||||
|
||||
enableEndpointDiscoveryEnvKey = []string{
|
||||
"AWS_ENABLE_ENDPOINT_DISCOVERY",
|
||||
}
|
||||
|
||||
regionEnvKeys = []string{
|
||||
"AWS_REGION",
|
||||
"AWS_DEFAULT_REGION", // Only read if AWS_SDK_LOAD_CONFIG is also set
|
||||
|
@ -124,6 +193,24 @@ var (
|
|||
sharedConfigFileEnvKey = []string{
|
||||
"AWS_CONFIG_FILE",
|
||||
}
|
||||
webIdentityTokenFilePathEnvKey = []string{
|
||||
"AWS_WEB_IDENTITY_TOKEN_FILE",
|
||||
}
|
||||
roleARNEnvKey = []string{
|
||||
"AWS_ROLE_ARN",
|
||||
}
|
||||
roleSessionNameEnvKey = []string{
|
||||
"AWS_ROLE_SESSION_NAME",
|
||||
}
|
||||
stsRegionalEndpointKey = []string{
|
||||
"AWS_STS_REGIONAL_ENDPOINTS",
|
||||
}
|
||||
s3UsEast1RegionalEndpoint = []string{
|
||||
"AWS_S3_US_EAST_1_REGIONAL_ENDPOINT",
|
||||
}
|
||||
s3UseARNRegionEnvKey = []string{
|
||||
"AWS_S3_USE_ARN_REGION",
|
||||
}
|
||||
)
|
||||
|
||||
// loadEnvConfig retrieves the SDK's environment configuration.
|
||||
|
@ -132,7 +219,7 @@ var (
|
|||
// If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value
|
||||
// the shared SDK config will be loaded in addition to the SDK's specific
|
||||
// configuration values.
|
||||
func loadEnvConfig() envConfig {
|
||||
func loadEnvConfig() (envConfig, error) {
|
||||
enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG"))
|
||||
return envConfigLoad(enableSharedConfig)
|
||||
}
|
||||
|
@ -143,24 +230,42 @@ func loadEnvConfig() envConfig {
|
|||
// Loads the shared configuration in addition to the SDK's specific configuration.
|
||||
// This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG`
|
||||
// environment variable is set.
|
||||
func loadSharedEnvConfig() envConfig {
|
||||
func loadSharedEnvConfig() (envConfig, error) {
|
||||
return envConfigLoad(true)
|
||||
}
|
||||
|
||||
func envConfigLoad(enableSharedConfig bool) envConfig {
|
||||
func envConfigLoad(enableSharedConfig bool) (envConfig, error) {
|
||||
cfg := envConfig{}
|
||||
|
||||
cfg.EnableSharedConfig = enableSharedConfig
|
||||
|
||||
setFromEnvVal(&cfg.Creds.AccessKeyID, credAccessEnvKey)
|
||||
setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey)
|
||||
setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey)
|
||||
// Static environment credentials
|
||||
var creds credentials.Value
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
// Role Metadata
|
||||
setFromEnvVal(&cfg.RoleARN, roleARNEnvKey)
|
||||
setFromEnvVal(&cfg.RoleSessionName, roleSessionNameEnvKey)
|
||||
|
||||
// Web identity environment variables
|
||||
setFromEnvVal(&cfg.WebIdentityTokenFilePath, webIdentityTokenFilePathEnvKey)
|
||||
|
||||
// CSM environment variables
|
||||
setFromEnvVal(&cfg.csmEnabled, csmEnabledEnvKey)
|
||||
setFromEnvVal(&cfg.CSMHost, csmHostEnvKey)
|
||||
setFromEnvVal(&cfg.CSMPort, csmPortEnvKey)
|
||||
setFromEnvVal(&cfg.CSMClientID, csmClientIDEnvKey)
|
||||
|
||||
if len(cfg.csmEnabled) != 0 {
|
||||
v, _ := strconv.ParseBool(cfg.csmEnabled)
|
||||
cfg.CSMEnabled = &v
|
||||
}
|
||||
|
||||
regionKeys := regionEnvKeys
|
||||
|
@ -173,17 +278,66 @@ func envConfigLoad(enableSharedConfig bool) envConfig {
|
|||
setFromEnvVal(&cfg.Region, regionKeys)
|
||||
setFromEnvVal(&cfg.Profile, profileKeys)
|
||||
|
||||
// endpoint discovery is in reference to it being enabled.
|
||||
setFromEnvVal(&cfg.enableEndpointDiscovery, enableEndpointDiscoveryEnvKey)
|
||||
if len(cfg.enableEndpointDiscovery) > 0 {
|
||||
cfg.EnableEndpointDiscovery = aws.Bool(cfg.enableEndpointDiscovery != "false")
|
||||
}
|
||||
|
||||
setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey)
|
||||
setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey)
|
||||
|
||||
if len(cfg.SharedCredentialsFile) == 0 {
|
||||
cfg.SharedCredentialsFile = defaults.SharedCredentialsFilename()
|
||||
}
|
||||
if len(cfg.SharedConfigFile) == 0 {
|
||||
cfg.SharedConfigFile = defaults.SharedConfigFilename()
|
||||
}
|
||||
|
||||
cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
|
||||
|
||||
return cfg
|
||||
var err error
|
||||
// STS Regional Endpoint variable
|
||||
for _, k := range stsRegionalEndpointKey {
|
||||
if v := os.Getenv(k); len(v) != 0 {
|
||||
cfg.STSRegionalEndpoint, err = endpoints.GetSTSRegionalEndpoint(v)
|
||||
if err != nil {
|
||||
return cfg, fmt.Errorf("failed to load, %v from env config, %v", k, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// S3 Regional Endpoint variable
|
||||
for _, k := range s3UsEast1RegionalEndpoint {
|
||||
if v := os.Getenv(k); len(v) != 0 {
|
||||
cfg.S3UsEast1RegionalEndpoint, err = endpoints.GetS3UsEast1RegionalEndpoint(v)
|
||||
if err != nil {
|
||||
return cfg, fmt.Errorf("failed to load, %v from env config, %v", k, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var s3UseARNRegion string
|
||||
setFromEnvVal(&s3UseARNRegion, s3UseARNRegionEnvKey)
|
||||
if len(s3UseARNRegion) != 0 {
|
||||
switch {
|
||||
case strings.EqualFold(s3UseARNRegion, "false"):
|
||||
cfg.S3UseARNRegion = false
|
||||
case strings.EqualFold(s3UseARNRegion, "true"):
|
||||
cfg.S3UseARNRegion = true
|
||||
default:
|
||||
return envConfig{}, fmt.Errorf(
|
||||
"invalid value for environment variable, %s=%s, need true or false",
|
||||
s3UseARNRegionEnvKey[0], s3UseARNRegion)
|
||||
}
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func setFromEnvVal(dst *string, keys []string) {
|
||||
for _, k := range keys {
|
||||
if v := os.Getenv(k); len(v) > 0 {
|
||||
if v := os.Getenv(k); len(v) != 0 {
|
||||
*dst = v
|
||||
break
|
||||
}
|
||||
|
|
448
vendor/github.com/aws/aws-sdk-go/aws/session/session.go
generated
vendored
448
vendor/github.com/aws/aws-sdk-go/aws/session/session.go
generated
vendored
|
@ -8,25 +8,43 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"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/corehandlers"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go/aws/csm"
|
||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
)
|
||||
|
||||
const (
|
||||
// ErrCodeSharedConfig represents an error that occurs in the shared
|
||||
// configuration logic
|
||||
ErrCodeSharedConfig = "SharedConfigErr"
|
||||
)
|
||||
|
||||
// ErrSharedConfigSourceCollision will be returned if a section contains both
|
||||
// source_profile and credential_source
|
||||
var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only source profile or credential source can be specified, not both", nil)
|
||||
|
||||
// ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment
|
||||
// variables are empty and Environment was set as the credential source
|
||||
var ErrSharedConfigECSContainerEnvVarEmpty = awserr.New(ErrCodeSharedConfig, "EcsContainer was specified as the credential_source, but 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' was not set", nil)
|
||||
|
||||
// ErrSharedConfigInvalidCredSource will be returned if an invalid credential source was provided
|
||||
var ErrSharedConfigInvalidCredSource = awserr.New(ErrCodeSharedConfig, "credential source values must be EcsContainer, Ec2InstanceMetadata, or Environment", nil)
|
||||
|
||||
// A Session provides a central location to create service clients from and
|
||||
// store configurations and request handlers for those services.
|
||||
//
|
||||
// Sessions are safe to create service clients concurrently, but it is not safe
|
||||
// to mutate the Session concurrently.
|
||||
//
|
||||
// The Session satisfies the service client's client.ClientConfigProvider.
|
||||
// The Session satisfies the service client's client.ConfigProvider.
|
||||
type Session struct {
|
||||
Config *aws.Config
|
||||
Handlers request.Handlers
|
||||
|
@ -55,10 +73,15 @@ type Session struct {
|
|||
// func is called instead of waiting to receive an error until a request is made.
|
||||
func New(cfgs ...*aws.Config) *Session {
|
||||
// load initial config from environment
|
||||
envCfg := loadEnvConfig()
|
||||
envCfg, envErr := loadEnvConfig()
|
||||
|
||||
if envCfg.EnableSharedConfig {
|
||||
s, err := newSession(Options{}, envCfg, cfgs...)
|
||||
var cfg aws.Config
|
||||
cfg.MergeIn(cfgs...)
|
||||
s, err := NewSessionWithOptions(Options{
|
||||
Config: cfg,
|
||||
SharedConfigState: SharedConfigEnable,
|
||||
})
|
||||
if err != nil {
|
||||
// Old session.New expected all errors to be discovered when
|
||||
// a request is made, and would report the errors then. This
|
||||
|
@ -70,16 +93,31 @@ func New(cfgs ...*aws.Config) *Session {
|
|||
// Session creation failed, need to report the error and prevent
|
||||
// any requests from succeeding.
|
||||
s = &Session{Config: defaults.Config()}
|
||||
s.Config.MergeIn(cfgs...)
|
||||
s.Config.Logger.Log("ERROR:", msg, "Error:", err)
|
||||
s.Handlers.Validate.PushBack(func(r *request.Request) {
|
||||
r.Error = err
|
||||
})
|
||||
s.logDeprecatedNewSessionError(msg, err, cfgs)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
return deprecatedNewSession(cfgs...)
|
||||
s := deprecatedNewSession(cfgs...)
|
||||
if envErr != nil {
|
||||
msg := "failed to load env config"
|
||||
s.logDeprecatedNewSessionError(msg, envErr, cfgs)
|
||||
}
|
||||
|
||||
if csmCfg, err := loadCSMConfig(envCfg, []string{}); err != nil {
|
||||
if l := s.Config.Logger; l != nil {
|
||||
l.Log(fmt.Sprintf("ERROR: failed to load CSM configuration, %v", err))
|
||||
}
|
||||
} else if csmCfg.Enabled {
|
||||
err := enableCSM(&s.Handlers, csmCfg, s.Config.Logger)
|
||||
if err != nil {
|
||||
msg := "failed to enable CSM"
|
||||
s.logDeprecatedNewSessionError(msg, err, cfgs)
|
||||
}
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// NewSession returns a new Session created from SDK defaults, config files,
|
||||
|
@ -95,7 +133,7 @@ func New(cfgs ...*aws.Config) *Session {
|
|||
// to be built with retrieving credentials with AssumeRole set in the config.
|
||||
//
|
||||
// See the NewSessionWithOptions func for information on how to override or
|
||||
// control through code how the Session will be created. Such as specifying the
|
||||
// control through code how the Session will be created, such as specifying the
|
||||
// config profile, and controlling if shared config is enabled or not.
|
||||
func NewSession(cfgs ...*aws.Config) (*Session, error) {
|
||||
opts := Options{}
|
||||
|
@ -179,6 +217,12 @@ type Options struct {
|
|||
// the config enables assume role wit MFA via the mfa_serial field.
|
||||
AssumeRoleTokenProvider func() (string, error)
|
||||
|
||||
// When the SDK's shared config is configured to assume a role this option
|
||||
// may be provided to set the expiry duration of the STS credentials.
|
||||
// Defaults to 15 minutes if not set as documented in the
|
||||
// stscreds.AssumeRoleProvider.
|
||||
AssumeRoleDuration time.Duration
|
||||
|
||||
// Reader for a custom Credentials Authority (CA) bundle in PEM format that
|
||||
// the SDK will use instead of the default system's root CA bundle. Use this
|
||||
// only if you want to replace the CA bundle the SDK uses for TLS requests.
|
||||
|
@ -193,6 +237,12 @@ type Options struct {
|
|||
// to also enable this feature. CustomCABundle session option field has priority
|
||||
// over the AWS_CA_BUNDLE environment variable, and will be used if both are set.
|
||||
CustomCABundle io.Reader
|
||||
|
||||
// The handlers that the session and all API clients will be created with.
|
||||
// This must be a complete set of handlers. Use the defaults.Handlers()
|
||||
// function to initialize this value before changing the handlers to be
|
||||
// used by the SDK.
|
||||
Handlers request.Handlers
|
||||
}
|
||||
|
||||
// NewSessionWithOptions returns a new Session created from SDK defaults, config files,
|
||||
|
@ -226,13 +276,20 @@ type Options struct {
|
|||
// }))
|
||||
func NewSessionWithOptions(opts Options) (*Session, error) {
|
||||
var envCfg envConfig
|
||||
var err error
|
||||
if opts.SharedConfigState == SharedConfigEnable {
|
||||
envCfg = loadSharedEnvConfig()
|
||||
envCfg, err = loadSharedEnvConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load shared config, %v", err)
|
||||
}
|
||||
} else {
|
||||
envCfg = loadEnvConfig()
|
||||
envCfg, err = loadEnvConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load environment config, %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(opts.Profile) > 0 {
|
||||
if len(opts.Profile) != 0 {
|
||||
envCfg.Profile = opts.Profile
|
||||
}
|
||||
|
||||
|
@ -243,13 +300,6 @@ func NewSessionWithOptions(opts Options) (*Session, error) {
|
|||
envCfg.EnableSharedConfig = true
|
||||
}
|
||||
|
||||
if len(envCfg.SharedCredentialsFile) == 0 {
|
||||
envCfg.SharedCredentialsFile = defaults.SharedCredentialsFilename()
|
||||
}
|
||||
if len(envCfg.SharedConfigFile) == 0 {
|
||||
envCfg.SharedConfigFile = defaults.SharedConfigFilename()
|
||||
}
|
||||
|
||||
// Only use AWS_CA_BUNDLE if session option is not provided.
|
||||
if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil {
|
||||
f, err := os.Open(envCfg.CustomCABundle)
|
||||
|
@ -302,18 +352,36 @@ func deprecatedNewSession(cfgs ...*aws.Config) *Session {
|
|||
}
|
||||
|
||||
initHandlers(s)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func enableCSM(handlers *request.Handlers, cfg csmConfig, logger aws.Logger) error {
|
||||
if logger != nil {
|
||||
logger.Log("Enabling CSM")
|
||||
}
|
||||
|
||||
r, err := csm.Start(cfg.ClientID, csm.AddressWithDefaults(cfg.Host, cfg.Port))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.InjectHandlers(handlers)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) {
|
||||
cfg := defaults.Config()
|
||||
handlers := defaults.Handlers()
|
||||
|
||||
handlers := opts.Handlers
|
||||
if handlers.IsEmpty() {
|
||||
handlers = defaults.Handlers()
|
||||
}
|
||||
|
||||
// Get a merged version of the user provided config to determine if
|
||||
// credentials were.
|
||||
userCfg := &aws.Config{}
|
||||
userCfg.MergeIn(cfgs...)
|
||||
cfg.MergeIn(userCfg)
|
||||
|
||||
// Ordered config files will be loaded in with later files overwriting
|
||||
// previous config file values.
|
||||
|
@ -330,9 +398,17 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
|
|||
}
|
||||
|
||||
// Load additional config from file(s)
|
||||
sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles)
|
||||
sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles, envCfg.EnableSharedConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if len(envCfg.Profile) == 0 && !envCfg.EnableSharedConfig && (envCfg.Creds.HasKeys() || userCfg.Credentials != nil) {
|
||||
// Special case where the user has not explicitly specified an AWS_PROFILE,
|
||||
// or session.Options.profile, shared config is not enabled, and the
|
||||
// environment has credentials, allow the shared config file to fail to
|
||||
// load since the user has already provided credentials, and nothing else
|
||||
// is required to be read file. Github(aws/aws-sdk-go#2455)
|
||||
} else if _, ok := err.(SharedConfigProfileNotExistsError); !ok {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil {
|
||||
|
@ -346,6 +422,17 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
|
|||
|
||||
initHandlers(s)
|
||||
|
||||
if csmCfg, err := loadCSMConfig(envCfg, cfgFiles); err != nil {
|
||||
if l := s.Config.Logger; l != nil {
|
||||
l.Log(fmt.Sprintf("ERROR: failed to load CSM configuration, %v", err))
|
||||
}
|
||||
} else if csmCfg.Enabled {
|
||||
err = enableCSM(&s.Handlers, csmCfg, s.Config.Logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Setup HTTP client with custom cert bundle if enabled
|
||||
if opts.CustomCABundle != nil {
|
||||
if err := loadCustomCABundle(s, opts.CustomCABundle); err != nil {
|
||||
|
@ -356,6 +443,46 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
|
|||
return s, nil
|
||||
}
|
||||
|
||||
type csmConfig struct {
|
||||
Enabled bool
|
||||
Host string
|
||||
Port string
|
||||
ClientID string
|
||||
}
|
||||
|
||||
var csmProfileName = "aws_csm"
|
||||
|
||||
func loadCSMConfig(envCfg envConfig, cfgFiles []string) (csmConfig, error) {
|
||||
if envCfg.CSMEnabled != nil {
|
||||
if *envCfg.CSMEnabled {
|
||||
return csmConfig{
|
||||
Enabled: true,
|
||||
ClientID: envCfg.CSMClientID,
|
||||
Host: envCfg.CSMHost,
|
||||
Port: envCfg.CSMPort,
|
||||
}, nil
|
||||
}
|
||||
return csmConfig{}, nil
|
||||
}
|
||||
|
||||
sharedCfg, err := loadSharedConfig(csmProfileName, cfgFiles, false)
|
||||
if err != nil {
|
||||
if _, ok := err.(SharedConfigProfileNotExistsError); !ok {
|
||||
return csmConfig{}, err
|
||||
}
|
||||
}
|
||||
if sharedCfg.CSMEnabled != nil && *sharedCfg.CSMEnabled == true {
|
||||
return csmConfig{
|
||||
Enabled: true,
|
||||
ClientID: sharedCfg.CSMClientID,
|
||||
Host: sharedCfg.CSMHost,
|
||||
Port: sharedCfg.CSMPort,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return csmConfig{}, nil
|
||||
}
|
||||
|
||||
func loadCustomCABundle(s *Session, bundle io.Reader) error {
|
||||
var t *http.Transport
|
||||
switch v := s.Config.HTTPClient.Transport.(type) {
|
||||
|
@ -368,7 +495,10 @@ func loadCustomCABundle(s *Session, bundle io.Reader) error {
|
|||
}
|
||||
}
|
||||
if t == nil {
|
||||
t = &http.Transport{}
|
||||
// Nil transport implies `http.DefaultTransport` should be used. Since
|
||||
// the SDK cannot modify, nor copy the `DefaultTransport` specifying
|
||||
// the values the next closest behavior.
|
||||
t = getCABundleTransport()
|
||||
}
|
||||
|
||||
p, err := loadCertPool(bundle)
|
||||
|
@ -401,9 +531,11 @@ func loadCertPool(r io.Reader) (*x509.CertPool, error) {
|
|||
return p, nil
|
||||
}
|
||||
|
||||
func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers, sessOpts Options) error {
|
||||
// Merge in user provided configuration
|
||||
cfg.MergeIn(userCfg)
|
||||
func mergeConfigSrcs(cfg, userCfg *aws.Config,
|
||||
envCfg envConfig, sharedCfg sharedConfig,
|
||||
handlers request.Handlers,
|
||||
sessOpts Options,
|
||||
) error {
|
||||
|
||||
// Region if not already set by user
|
||||
if len(aws.StringValue(cfg.Region)) == 0 {
|
||||
|
@ -414,101 +546,67 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg share
|
|||
}
|
||||
}
|
||||
|
||||
// Configure credentials if not already set
|
||||
if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
|
||||
if len(envCfg.Creds.AccessKeyID) > 0 {
|
||||
cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
|
||||
envCfg.Creds,
|
||||
)
|
||||
} else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil {
|
||||
cfgCp := *cfg
|
||||
cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds(
|
||||
sharedCfg.AssumeRoleSource.Creds,
|
||||
)
|
||||
if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
|
||||
// AssumeRole Token provider is required if doing Assume Role
|
||||
// with MFA.
|
||||
return AssumeRoleTokenProviderNotSetError{}
|
||||
}
|
||||
cfg.Credentials = stscreds.NewCredentials(
|
||||
&Session{
|
||||
Config: &cfgCp,
|
||||
Handlers: handlers.Copy(),
|
||||
},
|
||||
sharedCfg.AssumeRole.RoleARN,
|
||||
func(opt *stscreds.AssumeRoleProvider) {
|
||||
opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName
|
||||
|
||||
// Assume role with external ID
|
||||
if len(sharedCfg.AssumeRole.ExternalID) > 0 {
|
||||
opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID)
|
||||
}
|
||||
|
||||
// Assume role with MFA
|
||||
if len(sharedCfg.AssumeRole.MFASerial) > 0 {
|
||||
opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial)
|
||||
opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
|
||||
}
|
||||
},
|
||||
)
|
||||
} else if len(sharedCfg.Creds.AccessKeyID) > 0 {
|
||||
cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
|
||||
sharedCfg.Creds,
|
||||
)
|
||||
} else {
|
||||
// Fallback to default credentials provider, include mock errors
|
||||
// for the credential chain so user can identify why credentials
|
||||
// failed to be retrieved.
|
||||
cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{
|
||||
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
|
||||
Providers: []credentials.Provider{
|
||||
&credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)},
|
||||
&credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)},
|
||||
defaults.RemoteCredProvider(*cfg, handlers),
|
||||
},
|
||||
})
|
||||
if cfg.EnableEndpointDiscovery == nil {
|
||||
if envCfg.EnableEndpointDiscovery != nil {
|
||||
cfg.WithEndpointDiscovery(*envCfg.EnableEndpointDiscovery)
|
||||
} else if envCfg.EnableSharedConfig && sharedCfg.EnableEndpointDiscovery != nil {
|
||||
cfg.WithEndpointDiscovery(*sharedCfg.EnableEndpointDiscovery)
|
||||
}
|
||||
}
|
||||
|
||||
// Regional Endpoint flag for STS endpoint resolving
|
||||
mergeSTSRegionalEndpointConfig(cfg, []endpoints.STSRegionalEndpoint{
|
||||
userCfg.STSRegionalEndpoint,
|
||||
envCfg.STSRegionalEndpoint,
|
||||
sharedCfg.STSRegionalEndpoint,
|
||||
endpoints.LegacySTSEndpoint,
|
||||
})
|
||||
|
||||
// Regional Endpoint flag for S3 endpoint resolving
|
||||
mergeS3UsEast1RegionalEndpointConfig(cfg, []endpoints.S3UsEast1RegionalEndpoint{
|
||||
userCfg.S3UsEast1RegionalEndpoint,
|
||||
envCfg.S3UsEast1RegionalEndpoint,
|
||||
sharedCfg.S3UsEast1RegionalEndpoint,
|
||||
endpoints.LegacyS3UsEast1Endpoint,
|
||||
})
|
||||
|
||||
// Configure credentials if not already set by the user when creating the
|
||||
// Session.
|
||||
if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
|
||||
creds, err := resolveCredentials(cfg, envCfg, sharedCfg, handlers, sessOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Credentials = creds
|
||||
}
|
||||
|
||||
cfg.S3UseARNRegion = userCfg.S3UseARNRegion
|
||||
if cfg.S3UseARNRegion == nil {
|
||||
cfg.S3UseARNRegion = &envCfg.S3UseARNRegion
|
||||
}
|
||||
if cfg.S3UseARNRegion == nil {
|
||||
cfg.S3UseARNRegion = &sharedCfg.S3UseARNRegion
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the
|
||||
// MFAToken option is not set when shared config is configured load assume a
|
||||
// role with an MFA token.
|
||||
type AssumeRoleTokenProviderNotSetError struct{}
|
||||
|
||||
// Code is the short id of the error.
|
||||
func (e AssumeRoleTokenProviderNotSetError) Code() string {
|
||||
return "AssumeRoleTokenProviderNotSetError"
|
||||
func mergeSTSRegionalEndpointConfig(cfg *aws.Config, values []endpoints.STSRegionalEndpoint) {
|
||||
for _, v := range values {
|
||||
if v != endpoints.UnsetSTSEndpoint {
|
||||
cfg.STSRegionalEndpoint = v
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Message is the description of the error
|
||||
func (e AssumeRoleTokenProviderNotSetError) Message() string {
|
||||
return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.")
|
||||
}
|
||||
|
||||
// OrigErr is the underlying error that caused the failure.
|
||||
func (e AssumeRoleTokenProviderNotSetError) OrigErr() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Error satisfies the error interface.
|
||||
func (e AssumeRoleTokenProviderNotSetError) Error() string {
|
||||
return awserr.SprintError(e.Code(), e.Message(), "", nil)
|
||||
}
|
||||
|
||||
type credProviderError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
var emptyCreds = credentials.Value{}
|
||||
|
||||
func (c credProviderError) Retrieve() (credentials.Value, error) {
|
||||
return credentials.Value{}, c.Err
|
||||
}
|
||||
func (c credProviderError) IsExpired() bool {
|
||||
return true
|
||||
func mergeS3UsEast1RegionalEndpointConfig(cfg *aws.Config, values []endpoints.S3UsEast1RegionalEndpoint) {
|
||||
for _, v := range values {
|
||||
if v != endpoints.UnsetS3UsEast1Endpoint {
|
||||
cfg.S3UsEast1RegionalEndpoint = v
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func initHandlers(s *Session) {
|
||||
|
@ -519,7 +617,7 @@ func initHandlers(s *Session) {
|
|||
}
|
||||
}
|
||||
|
||||
// Copy creates and returns a copy of the current Session, coping the config
|
||||
// Copy creates and returns a copy of the current Session, copying the config
|
||||
// and handlers. If any additional configs are provided they will be merged
|
||||
// on top of the Session's copied config.
|
||||
//
|
||||
|
@ -539,46 +637,67 @@ func (s *Session) Copy(cfgs ...*aws.Config) *Session {
|
|||
// ClientConfig satisfies the client.ConfigProvider interface and is used to
|
||||
// configure the service client instances. Passing the Session to the service
|
||||
// client's constructor (New) will use this method to configure the client.
|
||||
func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
|
||||
// Backwards compatibility, the error will be eaten if user calls ClientConfig
|
||||
// directly. All SDK services will use ClientconfigWithError.
|
||||
cfg, _ := s.clientConfigWithErr(serviceName, cfgs...)
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (client.Config, error) {
|
||||
func (s *Session) ClientConfig(service string, cfgs ...*aws.Config) client.Config {
|
||||
s = s.Copy(cfgs...)
|
||||
|
||||
var resolved endpoints.ResolvedEndpoint
|
||||
var err error
|
||||
|
||||
region := aws.StringValue(s.Config.Region)
|
||||
|
||||
if endpoint := aws.StringValue(s.Config.Endpoint); len(endpoint) != 0 {
|
||||
resolved.URL = endpoints.AddScheme(endpoint, aws.BoolValue(s.Config.DisableSSL))
|
||||
resolved.SigningRegion = region
|
||||
} else {
|
||||
resolved, err = s.Config.EndpointResolver.EndpointFor(
|
||||
serviceName, region,
|
||||
func(opt *endpoints.Options) {
|
||||
opt.DisableSSL = aws.BoolValue(s.Config.DisableSSL)
|
||||
opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack)
|
||||
|
||||
// Support the condition where the service is modeled but its
|
||||
// endpoint metadata is not available.
|
||||
opt.ResolveUnknownService = true
|
||||
},
|
||||
)
|
||||
resolved, err := s.resolveEndpoint(service, region, s.Config)
|
||||
if err != nil {
|
||||
s.Handlers.Validate.PushBack(func(r *request.Request) {
|
||||
if len(r.ClientInfo.Endpoint) != 0 {
|
||||
// Error occurred while resolving endpoint, but the request
|
||||
// being invoked has had an endpoint specified after the client
|
||||
// was created.
|
||||
return
|
||||
}
|
||||
r.Error = err
|
||||
})
|
||||
}
|
||||
|
||||
return client.Config{
|
||||
Config: s.Config,
|
||||
Handlers: s.Handlers,
|
||||
Endpoint: resolved.URL,
|
||||
SigningRegion: resolved.SigningRegion,
|
||||
SigningName: resolved.SigningName,
|
||||
}, err
|
||||
Config: s.Config,
|
||||
Handlers: s.Handlers,
|
||||
PartitionID: resolved.PartitionID,
|
||||
Endpoint: resolved.URL,
|
||||
SigningRegion: resolved.SigningRegion,
|
||||
SigningNameDerived: resolved.SigningNameDerived,
|
||||
SigningName: resolved.SigningName,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) resolveEndpoint(service, region string, cfg *aws.Config) (endpoints.ResolvedEndpoint, error) {
|
||||
|
||||
if ep := aws.StringValue(cfg.Endpoint); len(ep) != 0 {
|
||||
return endpoints.ResolvedEndpoint{
|
||||
URL: endpoints.AddScheme(ep, aws.BoolValue(cfg.DisableSSL)),
|
||||
SigningRegion: region,
|
||||
}, nil
|
||||
}
|
||||
|
||||
resolved, err := cfg.EndpointResolver.EndpointFor(service, region,
|
||||
func(opt *endpoints.Options) {
|
||||
opt.DisableSSL = aws.BoolValue(cfg.DisableSSL)
|
||||
opt.UseDualStack = aws.BoolValue(cfg.UseDualStack)
|
||||
// Support for STSRegionalEndpoint where the STSRegionalEndpoint is
|
||||
// provided in envConfig or sharedConfig with envConfig getting
|
||||
// precedence.
|
||||
opt.STSRegionalEndpoint = cfg.STSRegionalEndpoint
|
||||
|
||||
// Support for S3UsEast1RegionalEndpoint where the S3UsEast1RegionalEndpoint is
|
||||
// provided in envConfig or sharedConfig with envConfig getting
|
||||
// precedence.
|
||||
opt.S3UsEast1RegionalEndpoint = cfg.S3UsEast1RegionalEndpoint
|
||||
|
||||
// Support the condition where the service is modeled but its
|
||||
// endpoint metadata is not available.
|
||||
opt.ResolveUnknownService = true
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return endpoints.ResolvedEndpoint{}, err
|
||||
}
|
||||
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
// ClientConfigNoResolveEndpoint is the same as ClientConfig with the exception
|
||||
|
@ -588,19 +707,28 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf
|
|||
s = s.Copy(cfgs...)
|
||||
|
||||
var resolved endpoints.ResolvedEndpoint
|
||||
|
||||
region := aws.StringValue(s.Config.Region)
|
||||
|
||||
if ep := aws.StringValue(s.Config.Endpoint); len(ep) > 0 {
|
||||
resolved.URL = endpoints.AddScheme(ep, aws.BoolValue(s.Config.DisableSSL))
|
||||
resolved.SigningRegion = region
|
||||
resolved.SigningRegion = aws.StringValue(s.Config.Region)
|
||||
}
|
||||
|
||||
return client.Config{
|
||||
Config: s.Config,
|
||||
Handlers: s.Handlers,
|
||||
Endpoint: resolved.URL,
|
||||
SigningRegion: resolved.SigningRegion,
|
||||
SigningName: resolved.SigningName,
|
||||
Config: s.Config,
|
||||
Handlers: s.Handlers,
|
||||
Endpoint: resolved.URL,
|
||||
SigningRegion: resolved.SigningRegion,
|
||||
SigningNameDerived: resolved.SigningNameDerived,
|
||||
SigningName: resolved.SigningName,
|
||||
}
|
||||
}
|
||||
|
||||
// logDeprecatedNewSessionError function enables error handling for session
|
||||
func (s *Session) logDeprecatedNewSessionError(msg string, err error, cfgs []*aws.Config) {
|
||||
// Session creation failed, need to report the error and prevent
|
||||
// any requests from succeeding.
|
||||
s.Config.MergeIn(cfgs...)
|
||||
s.Config.Logger.Log("ERROR:", msg, "Error:", err)
|
||||
s.Handlers.Validate.PushBack(func(r *request.Request) {
|
||||
r.Error = err
|
||||
})
|
||||
}
|
||||
|
|
466
vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
generated
vendored
466
vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
generated
vendored
|
@ -2,11 +2,11 @@ package session
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/go-ini/ini"
|
||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||
"github.com/aws/aws-sdk-go/internal/ini"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -16,68 +16,125 @@ const (
|
|||
sessionTokenKey = `aws_session_token` // optional
|
||||
|
||||
// Assume Role Credentials group
|
||||
roleArnKey = `role_arn` // group required
|
||||
sourceProfileKey = `source_profile` // group required
|
||||
externalIDKey = `external_id` // optional
|
||||
mfaSerialKey = `mfa_serial` // optional
|
||||
roleSessionNameKey = `role_session_name` // optional
|
||||
roleArnKey = `role_arn` // group required
|
||||
sourceProfileKey = `source_profile` // group required (or credential_source)
|
||||
credentialSourceKey = `credential_source` // group required (or source_profile)
|
||||
externalIDKey = `external_id` // optional
|
||||
mfaSerialKey = `mfa_serial` // optional
|
||||
roleSessionNameKey = `role_session_name` // optional
|
||||
|
||||
// CSM options
|
||||
csmEnabledKey = `csm_enabled`
|
||||
csmHostKey = `csm_host`
|
||||
csmPortKey = `csm_port`
|
||||
csmClientIDKey = `csm_client_id`
|
||||
|
||||
// Additional Config fields
|
||||
regionKey = `region`
|
||||
|
||||
// endpoint discovery group
|
||||
enableEndpointDiscoveryKey = `endpoint_discovery_enabled` // optional
|
||||
|
||||
// External Credential Process
|
||||
credentialProcessKey = `credential_process` // optional
|
||||
|
||||
// Web Identity Token File
|
||||
webIdentityTokenFileKey = `web_identity_token_file` // optional
|
||||
|
||||
// Additional config fields for regional or legacy endpoints
|
||||
stsRegionalEndpointSharedKey = `sts_regional_endpoints`
|
||||
|
||||
// Additional config fields for regional or legacy endpoints
|
||||
s3UsEast1RegionalSharedKey = `s3_us_east_1_regional_endpoint`
|
||||
|
||||
// DefaultSharedConfigProfile is the default profile to be used when
|
||||
// loading configuration from the config files if another profile name
|
||||
// is not provided.
|
||||
DefaultSharedConfigProfile = `default`
|
||||
)
|
||||
|
||||
type assumeRoleConfig struct {
|
||||
RoleARN string
|
||||
SourceProfile string
|
||||
ExternalID string
|
||||
MFASerial string
|
||||
RoleSessionName string
|
||||
}
|
||||
// S3 ARN Region Usage
|
||||
s3UseARNRegionKey = "s3_use_arn_region"
|
||||
)
|
||||
|
||||
// sharedConfig represents the configuration fields of the SDK config files.
|
||||
type sharedConfig struct {
|
||||
// Credentials values from the config file. Both aws_access_key_id
|
||||
// and aws_secret_access_key must be provided together in the same file
|
||||
// to be 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
|
||||
// other two fields are also provided.
|
||||
// Credentials values from the config file. Both aws_access_key_id and
|
||||
// aws_secret_access_key must be provided together in the same file to be
|
||||
// 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 other two fields are also provided.
|
||||
//
|
||||
// aws_access_key_id
|
||||
// aws_secret_access_key
|
||||
// aws_session_token
|
||||
Creds credentials.Value
|
||||
|
||||
AssumeRole assumeRoleConfig
|
||||
AssumeRoleSource *sharedConfig
|
||||
CredentialSource string
|
||||
CredentialProcess string
|
||||
WebIdentityTokenFile string
|
||||
|
||||
// Region is the region the SDK should use for looking up AWS service endpoints
|
||||
// and signing requests.
|
||||
RoleARN string
|
||||
RoleSessionName string
|
||||
ExternalID string
|
||||
MFASerial string
|
||||
|
||||
SourceProfileName string
|
||||
SourceProfile *sharedConfig
|
||||
|
||||
// Region is the region the SDK should use for looking up AWS service
|
||||
// endpoints and signing requests.
|
||||
//
|
||||
// region
|
||||
Region string
|
||||
|
||||
// EnableEndpointDiscovery can be enabled in the shared config by setting
|
||||
// endpoint_discovery_enabled to true
|
||||
//
|
||||
// endpoint_discovery_enabled = true
|
||||
EnableEndpointDiscovery *bool
|
||||
|
||||
// CSM Options
|
||||
CSMEnabled *bool
|
||||
CSMHost string
|
||||
CSMPort string
|
||||
CSMClientID string
|
||||
|
||||
// Specifies the Regional Endpoint flag for the SDK to resolve the endpoint for a service
|
||||
//
|
||||
// sts_regional_endpoints = regional
|
||||
// This can take value as `LegacySTSEndpoint` or `RegionalSTSEndpoint`
|
||||
STSRegionalEndpoint endpoints.STSRegionalEndpoint
|
||||
|
||||
// Specifies the Regional Endpoint flag for the SDK to resolve the endpoint for a service
|
||||
//
|
||||
// s3_us_east_1_regional_endpoint = regional
|
||||
// This can take value as `LegacyS3UsEast1Endpoint` or `RegionalS3UsEast1Endpoint`
|
||||
S3UsEast1RegionalEndpoint endpoints.S3UsEast1RegionalEndpoint
|
||||
|
||||
// Specifies if the S3 service should allow ARNs to direct the region
|
||||
// the client's requests are sent to.
|
||||
//
|
||||
// s3_use_arn_region=true
|
||||
S3UseARNRegion bool
|
||||
}
|
||||
|
||||
type sharedConfigFile struct {
|
||||
Filename string
|
||||
IniData *ini.File
|
||||
IniData ini.Sections
|
||||
}
|
||||
|
||||
// loadSharedConfig retrieves the configuration from the list of files
|
||||
// using the profile provided. The order the files are listed will determine
|
||||
// loadSharedConfig retrieves the configuration from the list of files using
|
||||
// the profile provided. The order the files are listed will determine
|
||||
// precedence. Values in subsequent files will overwrite values defined in
|
||||
// earlier files.
|
||||
//
|
||||
// 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
|
||||
// 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 {
|
||||
profile = DefaultSharedConfigProfile
|
||||
}
|
||||
|
@ -88,16 +145,11 @@ func loadSharedConfig(profile string, filenames []string) (sharedConfig, error)
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if len(cfg.AssumeRole.SourceProfile) > 0 {
|
||||
if err := cfg.setAssumeRoleSource(profile, files); err != nil {
|
||||
return sharedConfig{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
|
@ -105,114 +157,278 @@ func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) {
|
|||
files := make([]sharedConfigFile, 0, len(filenames))
|
||||
|
||||
for _, filename := range filenames {
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
sections, err := ini.OpenFile(filename)
|
||||
if aerr, ok := err.(awserr.Error); ok && aerr.Code() == ini.ErrCodeUnableToReadFile {
|
||||
// Skip files which can't be opened and read for whatever reason
|
||||
continue
|
||||
}
|
||||
|
||||
f, err := ini.Load(b)
|
||||
if err != nil {
|
||||
} else if err != nil {
|
||||
return nil, SharedConfigLoadError{Filename: filename, Err: err}
|
||||
}
|
||||
|
||||
files = append(files, sharedConfigFile{
|
||||
Filename: filename, IniData: f,
|
||||
Filename: filename, IniData: sections,
|
||||
})
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error {
|
||||
var assumeRoleSrc sharedConfig
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
if len(assumeRoleSrc.Creds.AccessKeyID) == 0 {
|
||||
return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN}
|
||||
}
|
||||
|
||||
cfg.AssumeRoleSource = &assumeRoleSrc
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cfg *sharedConfig) setFromIniFiles(profile string, files []sharedConfigFile) error {
|
||||
func (cfg *sharedConfig) setFromIniFiles(profiles map[string]struct{}, profile string, files []sharedConfigFile, exOpts bool) error {
|
||||
// Trim files from the list that don't exist.
|
||||
var skippedFiles int
|
||||
var profileNotFoundErr error
|
||||
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 {
|
||||
// Ignore proviles missings
|
||||
// Ignore profiles not defined in individual files.
|
||||
profileNotFoundErr = err
|
||||
skippedFiles++
|
||||
continue
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// setFromFile loads the configuration from the file using
|
||||
// the profile provided. A sharedConfig pointer type value is used so that
|
||||
// multiple config file loadings can be chained.
|
||||
// setFromFile loads the configuration from the file using the profile
|
||||
// provided. A sharedConfig pointer type value is used so that multiple config
|
||||
// file loadings can be chained.
|
||||
//
|
||||
// Only loads complete logically grouped values, and will not set fields in cfg
|
||||
// for incomplete grouped values in the config. Such as credentials. For example
|
||||
// if a config file only includes aws_access_key_id but no aws_secret_access_key
|
||||
// the aws_access_key_id will be ignored.
|
||||
func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error {
|
||||
section, err := file.IniData.GetSection(profile)
|
||||
if err != nil {
|
||||
// for incomplete grouped values in the config. Such as credentials. For
|
||||
// example if a config file only includes aws_access_key_id but no
|
||||
// aws_secret_access_key the aws_access_key_id will be ignored.
|
||||
func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile, exOpts bool) error {
|
||||
section, ok := file.IniData.GetSection(profile)
|
||||
if !ok {
|
||||
// Fallback to to alternate profile name: profile <name>
|
||||
section, err = file.IniData.GetSection(fmt.Sprintf("profile %s", profile))
|
||||
if err != nil {
|
||||
return SharedConfigProfileNotExistsError{Profile: profile, Err: err}
|
||||
section, ok = file.IniData.GetSection(fmt.Sprintf("profile %s", profile))
|
||||
if !ok {
|
||||
return SharedConfigProfileNotExistsError{Profile: profile, Err: nil}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
if v := section.String(stsRegionalEndpointSharedKey); len(v) != 0 {
|
||||
sre, err := endpoints.GetSTSRegionalEndpoint(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load %s from shared config, %s, %v",
|
||||
stsRegionalEndpointSharedKey, file.Filename, err)
|
||||
}
|
||||
cfg.STSRegionalEndpoint = sre
|
||||
}
|
||||
|
||||
if v := section.String(s3UsEast1RegionalSharedKey); len(v) != 0 {
|
||||
sre, err := endpoints.GetS3UsEast1RegionalEndpoint(v)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load %s from shared config, %s, %v",
|
||||
s3UsEast1RegionalSharedKey, file.Filename, err)
|
||||
}
|
||||
cfg.S3UsEast1RegionalEndpoint = sre
|
||||
}
|
||||
}
|
||||
|
||||
updateString(&cfg.CredentialProcess, section, credentialProcessKey)
|
||||
updateString(&cfg.WebIdentityTokenFile, section, webIdentityTokenFileKey)
|
||||
|
||||
// Shared Credentials
|
||||
akid := section.Key(accessKeyIDKey).String()
|
||||
secret := section.Key(secretAccessKey).String()
|
||||
if len(akid) > 0 && len(secret) > 0 {
|
||||
cfg.Creds = credentials.Value{
|
||||
AccessKeyID: akid,
|
||||
SecretAccessKey: secret,
|
||||
SessionToken: section.Key(sessionTokenKey).String(),
|
||||
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename),
|
||||
}
|
||||
creds := credentials.Value{
|
||||
AccessKeyID: section.String(accessKeyIDKey),
|
||||
SecretAccessKey: section.String(secretAccessKey),
|
||||
SessionToken: section.String(sessionTokenKey),
|
||||
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename),
|
||||
}
|
||||
if creds.HasKeys() {
|
||||
cfg.Creds = creds
|
||||
}
|
||||
|
||||
// Assume Role
|
||||
roleArn := section.Key(roleArnKey).String()
|
||||
srcProfile := section.Key(sourceProfileKey).String()
|
||||
if len(roleArn) > 0 && len(srcProfile) > 0 {
|
||||
cfg.AssumeRole = assumeRoleConfig{
|
||||
RoleARN: roleArn,
|
||||
SourceProfile: srcProfile,
|
||||
ExternalID: section.Key(externalIDKey).String(),
|
||||
MFASerial: section.Key(mfaSerialKey).String(),
|
||||
RoleSessionName: section.Key(roleSessionNameKey).String(),
|
||||
}
|
||||
// Endpoint discovery
|
||||
updateBoolPtr(&cfg.EnableEndpointDiscovery, section, enableEndpointDiscoveryKey)
|
||||
|
||||
// CSM options
|
||||
updateBoolPtr(&cfg.CSMEnabled, section, csmEnabledKey)
|
||||
updateString(&cfg.CSMHost, section, csmHostKey)
|
||||
updateString(&cfg.CSMPort, section, csmPortKey)
|
||||
updateString(&cfg.CSMClientID, section, csmClientIDKey)
|
||||
|
||||
updateBool(&cfg.S3UseARNRegion, section, s3UseARNRegionKey)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// Region
|
||||
if v := section.Key(regionKey).String(); len(v) > 0 {
|
||||
cfg.Region = v
|
||||
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)
|
||||
}
|
||||
|
||||
// updateBool will only update the dst with the value in the section key, key
|
||||
// is present in the section.
|
||||
func updateBool(dst *bool, section ini.Section, key string) {
|
||||
if !section.Has(key) {
|
||||
return
|
||||
}
|
||||
*dst = section.Bool(key)
|
||||
}
|
||||
|
||||
// updateBoolPtr will only update the dst with the value in the section key,
|
||||
// key is present in the section.
|
||||
func updateBoolPtr(dst **bool, section ini.Section, key string) {
|
||||
if !section.Has(key) {
|
||||
return
|
||||
}
|
||||
*dst = new(bool)
|
||||
**dst = section.Bool(key)
|
||||
}
|
||||
|
||||
// SharedConfigLoadError is an error for the shared config file failed to load.
|
||||
type SharedConfigLoadError struct {
|
||||
Filename string
|
||||
|
@ -270,7 +486,8 @@ func (e SharedConfigProfileNotExistsError) Error() string {
|
|||
// profile contains assume role information, but that information is invalid
|
||||
// or not complete.
|
||||
type SharedConfigAssumeRoleError struct {
|
||||
RoleARN string
|
||||
RoleARN string
|
||||
SourceProfile string
|
||||
}
|
||||
|
||||
// Code is the short id of the error.
|
||||
|
@ -280,8 +497,10 @@ func (e SharedConfigAssumeRoleError) Code() string {
|
|||
|
||||
// Message is the description of the error
|
||||
func (e SharedConfigAssumeRoleError) Message() string {
|
||||
return fmt.Sprintf("failed to load assume role for %s, source profile has no shared credentials",
|
||||
e.RoleARN)
|
||||
return fmt.Sprintf(
|
||||
"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.
|
||||
|
@ -293,3 +512,36 @@ func (e SharedConfigAssumeRoleError) OrigErr() error {
|
|||
func (e SharedConfigAssumeRoleError) Error() string {
|
||||
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)
|
||||
}
|
||||
|
|
5
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go
generated
vendored
5
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go
generated
vendored
|
@ -1,8 +1,7 @@
|
|||
package v4
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"github.com/aws/aws-sdk-go/internal/strings"
|
||||
)
|
||||
|
||||
// validator houses a set of rule needed for validation of a
|
||||
|
@ -61,7 +60,7 @@ type patterns []string
|
|||
// been found
|
||||
func (p patterns) IsValid(value string) bool {
|
||||
for _, pattern := range p {
|
||||
if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) {
|
||||
if strings.HasPrefixFold(value, pattern) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
63
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/stream.go
generated
vendored
Normal file
63
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/stream.go
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
package v4
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
)
|
||||
|
||||
type credentialValueProvider interface {
|
||||
Get() (credentials.Value, error)
|
||||
}
|
||||
|
||||
// StreamSigner implements signing of event stream encoded payloads
|
||||
type StreamSigner struct {
|
||||
region string
|
||||
service string
|
||||
|
||||
credentials credentialValueProvider
|
||||
|
||||
prevSig []byte
|
||||
}
|
||||
|
||||
// NewStreamSigner creates a SigV4 signer used to sign Event Stream encoded messages
|
||||
func NewStreamSigner(region, service string, seedSignature []byte, credentials *credentials.Credentials) *StreamSigner {
|
||||
return &StreamSigner{
|
||||
region: region,
|
||||
service: service,
|
||||
credentials: credentials,
|
||||
prevSig: seedSignature,
|
||||
}
|
||||
}
|
||||
|
||||
// GetSignature takes an event stream encoded headers and payload and returns a signature
|
||||
func (s *StreamSigner) GetSignature(headers, payload []byte, date time.Time) ([]byte, error) {
|
||||
credValue, err := s.credentials.Get()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sigKey := deriveSigningKey(s.region, s.service, credValue.SecretAccessKey, date)
|
||||
|
||||
keyPath := buildSigningScope(s.region, s.service, date)
|
||||
|
||||
stringToSign := buildEventStreamStringToSign(headers, payload, s.prevSig, keyPath, date)
|
||||
|
||||
signature := hmacSHA256(sigKey, []byte(stringToSign))
|
||||
s.prevSig = signature
|
||||
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
func buildEventStreamStringToSign(headers, payload, prevSig []byte, scope string, date time.Time) string {
|
||||
return strings.Join([]string{
|
||||
"AWS4-HMAC-SHA256-PAYLOAD",
|
||||
formatTime(date),
|
||||
scope,
|
||||
hex.EncodeToString(prevSig),
|
||||
hex.EncodeToString(hashSHA256(headers)),
|
||||
hex.EncodeToString(hashSHA256(payload)),
|
||||
}, "\n")
|
||||
}
|
233
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
generated
vendored
233
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
generated
vendored
|
@ -71,13 +71,19 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/internal/sdkio"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/rest"
|
||||
)
|
||||
|
||||
const (
|
||||
authorizationHeader = "Authorization"
|
||||
authHeaderSignatureElem = "Signature="
|
||||
signatureQueryKey = "X-Amz-Signature"
|
||||
|
||||
authHeaderPrefix = "AWS4-HMAC-SHA256"
|
||||
timeFormat = "20060102T150405Z"
|
||||
shortTimeFormat = "20060102"
|
||||
awsV4Request = "aws4_request"
|
||||
|
||||
// emptyStringSHA256 is a SHA256 of an empty string
|
||||
emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`
|
||||
|
@ -86,9 +92,9 @@ const (
|
|||
var ignoredHeaders = rules{
|
||||
blacklist{
|
||||
mapRule{
|
||||
"Authorization": struct{}{},
|
||||
"User-Agent": struct{}{},
|
||||
"X-Amzn-Trace-Id": struct{}{},
|
||||
authorizationHeader: struct{}{},
|
||||
"User-Agent": struct{}{},
|
||||
"X-Amzn-Trace-Id": struct{}{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -97,25 +103,25 @@ var ignoredHeaders = rules{
|
|||
var requiredSignedHeaders = rules{
|
||||
whitelist{
|
||||
mapRule{
|
||||
"Cache-Control": struct{}{},
|
||||
"Content-Disposition": struct{}{},
|
||||
"Content-Encoding": struct{}{},
|
||||
"Content-Language": struct{}{},
|
||||
"Content-Md5": struct{}{},
|
||||
"Content-Type": struct{}{},
|
||||
"Expires": struct{}{},
|
||||
"If-Match": struct{}{},
|
||||
"If-Modified-Since": struct{}{},
|
||||
"If-None-Match": struct{}{},
|
||||
"If-Unmodified-Since": struct{}{},
|
||||
"Range": struct{}{},
|
||||
"X-Amz-Acl": struct{}{},
|
||||
"X-Amz-Copy-Source": struct{}{},
|
||||
"X-Amz-Copy-Source-If-Match": struct{}{},
|
||||
"X-Amz-Copy-Source-If-Modified-Since": struct{}{},
|
||||
"X-Amz-Copy-Source-If-None-Match": struct{}{},
|
||||
"X-Amz-Copy-Source-If-Unmodified-Since": struct{}{},
|
||||
"X-Amz-Copy-Source-Range": struct{}{},
|
||||
"Cache-Control": struct{}{},
|
||||
"Content-Disposition": struct{}{},
|
||||
"Content-Encoding": struct{}{},
|
||||
"Content-Language": struct{}{},
|
||||
"Content-Md5": struct{}{},
|
||||
"Content-Type": struct{}{},
|
||||
"Expires": struct{}{},
|
||||
"If-Match": struct{}{},
|
||||
"If-Modified-Since": struct{}{},
|
||||
"If-None-Match": struct{}{},
|
||||
"If-Unmodified-Since": struct{}{},
|
||||
"Range": struct{}{},
|
||||
"X-Amz-Acl": struct{}{},
|
||||
"X-Amz-Copy-Source": struct{}{},
|
||||
"X-Amz-Copy-Source-If-Match": struct{}{},
|
||||
"X-Amz-Copy-Source-If-Modified-Since": struct{}{},
|
||||
"X-Amz-Copy-Source-If-None-Match": struct{}{},
|
||||
"X-Amz-Copy-Source-If-Unmodified-Since": struct{}{},
|
||||
"X-Amz-Copy-Source-Range": struct{}{},
|
||||
"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
||||
"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{},
|
||||
"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
||||
|
@ -133,7 +139,9 @@ var requiredSignedHeaders = rules{
|
|||
"X-Amz-Server-Side-Encryption-Customer-Key": struct{}{},
|
||||
"X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
||||
"X-Amz-Storage-Class": struct{}{},
|
||||
"X-Amz-Tagging": struct{}{},
|
||||
"X-Amz-Website-Redirect-Location": struct{}{},
|
||||
"X-Amz-Content-Sha256": struct{}{},
|
||||
},
|
||||
},
|
||||
patterns{"X-Amz-Meta-"},
|
||||
|
@ -179,7 +187,7 @@ type Signer struct {
|
|||
// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
|
||||
DisableURIPathEscaping bool
|
||||
|
||||
// Disales the automatical setting of the HTTP request's Body field with the
|
||||
// Disables the automatical setting of the HTTP request's Body field with the
|
||||
// io.ReadSeeker passed in to the signer. This is useful if you're using a
|
||||
// custom wrapper around the body for the io.ReadSeeker and want to preserve
|
||||
// the Body value on the Request.Body.
|
||||
|
@ -226,11 +234,9 @@ type signingCtx struct {
|
|||
|
||||
DisableURIPathEscaping bool
|
||||
|
||||
credValues credentials.Value
|
||||
isPresign bool
|
||||
formattedTime string
|
||||
formattedShortTime string
|
||||
unsignedPayload bool
|
||||
credValues credentials.Value
|
||||
isPresign bool
|
||||
unsignedPayload bool
|
||||
|
||||
bodyDigest string
|
||||
signedHeaders string
|
||||
|
@ -341,7 +347,9 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
|
|||
|
||||
ctx.sanitizeHostForHeader()
|
||||
ctx.assignAmzQueryValues()
|
||||
ctx.build(v4.DisableHeaderHoisting)
|
||||
if err := ctx.build(v4.DisableHeaderHoisting); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If the request is not presigned the body should be attached to it. This
|
||||
// prevents the confusion of wanting to send a signed request without
|
||||
|
@ -417,7 +425,7 @@ var SignRequestHandler = request.NamedHandler{
|
|||
// If the credentials of the request's config are set to
|
||||
// credentials.AnonymousCredentials the request will not be signed.
|
||||
func SignSDKRequest(req *request.Request) {
|
||||
signSDKRequestWithCurrTime(req, time.Now)
|
||||
SignSDKRequestWithCurrentTime(req, time.Now)
|
||||
}
|
||||
|
||||
// BuildNamedHandler will build a generic handler for signing.
|
||||
|
@ -425,12 +433,15 @@ func BuildNamedHandler(name string, opts ...func(*Signer)) request.NamedHandler
|
|||
return request.NamedHandler{
|
||||
Name: name,
|
||||
Fn: func(req *request.Request) {
|
||||
signSDKRequestWithCurrTime(req, time.Now, opts...)
|
||||
SignSDKRequestWithCurrentTime(req, time.Now, opts...)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time, opts ...func(*Signer)) {
|
||||
// SignSDKRequestWithCurrentTime will sign the SDK's request using the time
|
||||
// function passed in. Behaves the same as SignSDKRequest with the exception
|
||||
// the request is signed with the value returned by the current time function.
|
||||
func SignSDKRequestWithCurrentTime(req *request.Request, curTimeFn func() time.Time, opts ...func(*Signer)) {
|
||||
// If the request does not need to be signed ignore the signing of the
|
||||
// request if the AnonymousCredentials object is used.
|
||||
if req.Config.Credentials == credentials.AnonymousCredentials {
|
||||
|
@ -466,13 +477,9 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time
|
|||
opt(v4)
|
||||
}
|
||||
|
||||
signingTime := req.Time
|
||||
if !req.LastSignedAt.IsZero() {
|
||||
signingTime = req.LastSignedAt
|
||||
}
|
||||
|
||||
curTime := curTimeFn()
|
||||
signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(),
|
||||
name, region, req.ExpireTime, req.ExpireTime > 0, signingTime,
|
||||
name, region, req.ExpireTime, req.ExpireTime > 0, curTime,
|
||||
)
|
||||
if err != nil {
|
||||
req.Error = err
|
||||
|
@ -481,7 +488,7 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time
|
|||
}
|
||||
|
||||
req.SignedHeaderVals = signedHeaders
|
||||
req.LastSignedAt = curTimeFn()
|
||||
req.LastSignedAt = curTime
|
||||
}
|
||||
|
||||
const logSignInfoMsg = `DEBUG: Request Signature:
|
||||
|
@ -503,11 +510,13 @@ func (v4 *Signer) logSigningInfo(ctx *signingCtx) {
|
|||
v4.Logger.Log(msg)
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) build(disableHeaderHoisting bool) {
|
||||
func (ctx *signingCtx) build(disableHeaderHoisting bool) error {
|
||||
ctx.buildTime() // no depends
|
||||
ctx.buildCredentialString() // no depends
|
||||
|
||||
ctx.buildBodyDigest()
|
||||
if err := ctx.buildBodyDigest(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
unsignedHeaders := ctx.Request.Header
|
||||
if ctx.isPresign {
|
||||
|
@ -526,37 +535,56 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) {
|
|||
ctx.buildSignature() // depends on string to sign
|
||||
|
||||
if ctx.isPresign {
|
||||
ctx.Request.URL.RawQuery += "&X-Amz-Signature=" + ctx.signature
|
||||
ctx.Request.URL.RawQuery += "&" + signatureQueryKey + "=" + ctx.signature
|
||||
} else {
|
||||
parts := []string{
|
||||
authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString,
|
||||
"SignedHeaders=" + ctx.signedHeaders,
|
||||
"Signature=" + ctx.signature,
|
||||
authHeaderSignatureElem + ctx.signature,
|
||||
}
|
||||
ctx.Request.Header.Set("Authorization", strings.Join(parts, ", "))
|
||||
ctx.Request.Header.Set(authorizationHeader, strings.Join(parts, ", "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetSignedRequestSignature attempts to extract the signature of the request.
|
||||
// Returning an error if the request is unsigned, or unable to extract the
|
||||
// signature.
|
||||
func GetSignedRequestSignature(r *http.Request) ([]byte, error) {
|
||||
|
||||
if auth := r.Header.Get(authorizationHeader); len(auth) != 0 {
|
||||
ps := strings.Split(auth, ", ")
|
||||
for _, p := range ps {
|
||||
if idx := strings.Index(p, authHeaderSignatureElem); idx >= 0 {
|
||||
sig := p[len(authHeaderSignatureElem):]
|
||||
if len(sig) == 0 {
|
||||
return nil, fmt.Errorf("invalid request signature authorization header")
|
||||
}
|
||||
return hex.DecodeString(sig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sig := r.URL.Query().Get("X-Amz-Signature"); len(sig) != 0 {
|
||||
return hex.DecodeString(sig)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("request not signed")
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildTime() {
|
||||
ctx.formattedTime = ctx.Time.UTC().Format(timeFormat)
|
||||
ctx.formattedShortTime = ctx.Time.UTC().Format(shortTimeFormat)
|
||||
|
||||
if ctx.isPresign {
|
||||
duration := int64(ctx.ExpireTime / time.Second)
|
||||
ctx.Query.Set("X-Amz-Date", ctx.formattedTime)
|
||||
ctx.Query.Set("X-Amz-Date", formatTime(ctx.Time))
|
||||
ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
|
||||
} else {
|
||||
ctx.Request.Header.Set("X-Amz-Date", ctx.formattedTime)
|
||||
ctx.Request.Header.Set("X-Amz-Date", formatTime(ctx.Time))
|
||||
}
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildCredentialString() {
|
||||
ctx.credentialString = strings.Join([]string{
|
||||
ctx.formattedShortTime,
|
||||
ctx.Region,
|
||||
ctx.ServiceName,
|
||||
"aws4_request",
|
||||
}, "/")
|
||||
ctx.credentialString = buildSigningScope(ctx.Region, ctx.ServiceName, ctx.Time)
|
||||
|
||||
if ctx.isPresign {
|
||||
ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString)
|
||||
|
@ -580,8 +608,7 @@ func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) {
|
|||
var headers []string
|
||||
headers = append(headers, "host")
|
||||
for k, v := range header {
|
||||
canonicalKey := http.CanonicalHeaderKey(k)
|
||||
if !r.IsValid(canonicalKey) {
|
||||
if !r.IsValid(k) {
|
||||
continue // ignored header
|
||||
}
|
||||
if ctx.SignedHeaderVals == nil {
|
||||
|
@ -645,37 +672,50 @@ func (ctx *signingCtx) buildCanonicalString() {
|
|||
func (ctx *signingCtx) buildStringToSign() {
|
||||
ctx.stringToSign = strings.Join([]string{
|
||||
authHeaderPrefix,
|
||||
ctx.formattedTime,
|
||||
formatTime(ctx.Time),
|
||||
ctx.credentialString,
|
||||
hex.EncodeToString(makeSha256([]byte(ctx.canonicalString))),
|
||||
hex.EncodeToString(hashSHA256([]byte(ctx.canonicalString))),
|
||||
}, "\n")
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildSignature() {
|
||||
secret := ctx.credValues.SecretAccessKey
|
||||
date := makeHmac([]byte("AWS4"+secret), []byte(ctx.formattedShortTime))
|
||||
region := makeHmac(date, []byte(ctx.Region))
|
||||
service := makeHmac(region, []byte(ctx.ServiceName))
|
||||
credentials := makeHmac(service, []byte("aws4_request"))
|
||||
signature := makeHmac(credentials, []byte(ctx.stringToSign))
|
||||
creds := deriveSigningKey(ctx.Region, ctx.ServiceName, ctx.credValues.SecretAccessKey, ctx.Time)
|
||||
signature := hmacSHA256(creds, []byte(ctx.stringToSign))
|
||||
ctx.signature = hex.EncodeToString(signature)
|
||||
}
|
||||
|
||||
func (ctx *signingCtx) buildBodyDigest() {
|
||||
func (ctx *signingCtx) buildBodyDigest() error {
|
||||
hash := ctx.Request.Header.Get("X-Amz-Content-Sha256")
|
||||
if hash == "" {
|
||||
if ctx.unsignedPayload || (ctx.isPresign && ctx.ServiceName == "s3") {
|
||||
includeSHA256Header := ctx.unsignedPayload ||
|
||||
ctx.ServiceName == "s3" ||
|
||||
ctx.ServiceName == "glacier"
|
||||
|
||||
s3Presign := ctx.isPresign && ctx.ServiceName == "s3"
|
||||
|
||||
if ctx.unsignedPayload || s3Presign {
|
||||
hash = "UNSIGNED-PAYLOAD"
|
||||
includeSHA256Header = !s3Presign
|
||||
} else if ctx.Body == nil {
|
||||
hash = emptyStringSHA256
|
||||
} else {
|
||||
hash = hex.EncodeToString(makeSha256Reader(ctx.Body))
|
||||
if !aws.IsReaderSeekable(ctx.Body) {
|
||||
return fmt.Errorf("cannot use unseekable request body %T, for signed request with body", ctx.Body)
|
||||
}
|
||||
hashBytes, err := makeSha256Reader(ctx.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hash = hex.EncodeToString(hashBytes)
|
||||
}
|
||||
if ctx.unsignedPayload || ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" {
|
||||
|
||||
if includeSHA256Header {
|
||||
ctx.Request.Header.Set("X-Amz-Content-Sha256", hash)
|
||||
}
|
||||
}
|
||||
ctx.bodyDigest = hash
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isRequestSigned returns if the request is currently signed or presigned
|
||||
|
@ -701,31 +741,45 @@ func (ctx *signingCtx) removePresign() {
|
|||
ctx.Query.Del("X-Amz-SignedHeaders")
|
||||
}
|
||||
|
||||
func makeHmac(key []byte, data []byte) []byte {
|
||||
func hmacSHA256(key []byte, data []byte) []byte {
|
||||
hash := hmac.New(sha256.New, key)
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
func makeSha256(data []byte) []byte {
|
||||
func hashSHA256(data []byte) []byte {
|
||||
hash := sha256.New()
|
||||
hash.Write(data)
|
||||
return hash.Sum(nil)
|
||||
}
|
||||
|
||||
func makeSha256Reader(reader io.ReadSeeker) []byte {
|
||||
func makeSha256Reader(reader io.ReadSeeker) (hashBytes []byte, err error) {
|
||||
hash := sha256.New()
|
||||
start, _ := reader.Seek(0, 1)
|
||||
defer reader.Seek(start, 0)
|
||||
start, err := reader.Seek(0, sdkio.SeekCurrent)
|
||||
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)
|
||||
}()
|
||||
|
||||
io.Copy(hash, reader)
|
||||
return hash.Sum(nil)
|
||||
// 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.
|
||||
size, err := aws.SeekerLen(reader)
|
||||
if err != nil {
|
||||
io.Copy(hash, reader)
|
||||
} else {
|
||||
io.CopyN(hash, reader, size)
|
||||
}
|
||||
|
||||
return hash.Sum(nil), nil
|
||||
}
|
||||
|
||||
const doubleSpace = " "
|
||||
|
||||
// stripExcessSpaces will rewrite the passed in slice's string values to not
|
||||
// contain muliple side-by-side spaces.
|
||||
// contain multiple side-by-side spaces.
|
||||
func stripExcessSpaces(vals []string) {
|
||||
var j, k, l, m, spaces int
|
||||
for i, str := range vals {
|
||||
|
@ -765,3 +819,28 @@ func stripExcessSpaces(vals []string) {
|
|||
vals[i] = string(buf[:m])
|
||||
}
|
||||
}
|
||||
|
||||
func buildSigningScope(region, service string, dt time.Time) string {
|
||||
return strings.Join([]string{
|
||||
formatShortTime(dt),
|
||||
region,
|
||||
service,
|
||||
awsV4Request,
|
||||
}, "/")
|
||||
}
|
||||
|
||||
func deriveSigningKey(region, service, secretKey string, dt time.Time) []byte {
|
||||
kDate := hmacSHA256([]byte("AWS4"+secretKey), []byte(formatShortTime(dt)))
|
||||
kRegion := hmacSHA256(kDate, []byte(region))
|
||||
kService := hmacSHA256(kRegion, []byte(service))
|
||||
signingKey := hmacSHA256(kService, []byte(awsV4Request))
|
||||
return signingKey
|
||||
}
|
||||
|
||||
func formatShortTime(dt time.Time) string {
|
||||
return dt.UTC().Format(shortTimeFormat)
|
||||
}
|
||||
|
||||
func formatTime(dt time.Time) string {
|
||||
return dt.UTC().Format(timeFormat)
|
||||
}
|
||||
|
|
137
vendor/github.com/aws/aws-sdk-go/aws/types.go
generated
vendored
137
vendor/github.com/aws/aws-sdk-go/aws/types.go
generated
vendored
|
@ -2,16 +2,24 @@ package aws
|
|||
|
||||
import (
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/aws/aws-sdk-go/internal/sdkio"
|
||||
)
|
||||
|
||||
// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Should
|
||||
// only be used with an io.Reader that is also an io.Seeker. Doing so may
|
||||
// cause request signature errors, or request body's not sent for GET, HEAD
|
||||
// and DELETE HTTP methods.
|
||||
// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Allows the
|
||||
// SDK to accept an io.Reader that is not also an io.Seeker for unsigned
|
||||
// streaming payload API operations.
|
||||
//
|
||||
// Deprecated: Should only be used with io.ReadSeeker. If using for
|
||||
// S3 PutObject to stream content use s3manager.Uploader instead.
|
||||
// A ReadSeekCloser wrapping an nonseekable io.Reader used in an API
|
||||
// operation's input will prevent that operation being retried in the case of
|
||||
// network errors, and cause operation requests to fail if the operation
|
||||
// requires payload signing.
|
||||
//
|
||||
// Note: If using With S3 PutObject to stream an object upload The SDK's S3
|
||||
// Upload manager (s3manager.Uploader) provides support for streaming with the
|
||||
// ability to retry network errors.
|
||||
func ReadSeekCloser(r io.Reader) ReaderSeekerCloser {
|
||||
return ReaderSeekerCloser{r}
|
||||
}
|
||||
|
@ -22,10 +30,27 @@ type ReaderSeekerCloser struct {
|
|||
r io.Reader
|
||||
}
|
||||
|
||||
// IsReaderSeekable returns if the underlying reader type can be seeked. A
|
||||
// io.Reader might not actually be seekable if it is the ReaderSeekerCloser
|
||||
// type.
|
||||
func IsReaderSeekable(r io.Reader) bool {
|
||||
switch v := r.(type) {
|
||||
case ReaderSeekerCloser:
|
||||
return v.IsSeeker()
|
||||
case *ReaderSeekerCloser:
|
||||
return v.IsSeeker()
|
||||
case io.ReadSeeker:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads from the reader up to size of p. The number of bytes read, and
|
||||
// error if it occurred will be returned.
|
||||
//
|
||||
// If the reader is not an io.Reader zero bytes read, and nil error will be returned.
|
||||
// If the reader is not an io.Reader zero bytes read, and nil error will be
|
||||
// returned.
|
||||
//
|
||||
// Performs the same functionality as io.Reader Read
|
||||
func (r ReaderSeekerCloser) Read(p []byte) (int, error) {
|
||||
|
@ -56,6 +81,71 @@ func (r ReaderSeekerCloser) IsSeeker() bool {
|
|||
return ok
|
||||
}
|
||||
|
||||
// HasLen returns the length of the underlying reader if the value implements
|
||||
// the Len() int method.
|
||||
func (r ReaderSeekerCloser) HasLen() (int, bool) {
|
||||
type lenner interface {
|
||||
Len() int
|
||||
}
|
||||
|
||||
if lr, ok := r.r.(lenner); ok {
|
||||
return lr.Len(), true
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// GetLen returns the length of the bytes remaining in the underlying reader.
|
||||
// Checks first for Len(), then io.Seeker to determine the size of the
|
||||
// underlying reader.
|
||||
//
|
||||
// Will return -1 if the length cannot be determined.
|
||||
func (r ReaderSeekerCloser) GetLen() (int64, error) {
|
||||
if l, ok := r.HasLen(); ok {
|
||||
return int64(l), nil
|
||||
}
|
||||
|
||||
if s, ok := r.r.(io.Seeker); ok {
|
||||
return seekerLen(s)
|
||||
}
|
||||
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
// SeekerLen attempts to get the number of bytes remaining at the seeker's
|
||||
// current position. Returns the number of bytes remaining or error.
|
||||
func SeekerLen(s io.Seeker) (int64, error) {
|
||||
// Determine if the seeker is actually seekable. ReaderSeekerCloser
|
||||
// hides the fact that a io.Readers might not actually be seekable.
|
||||
switch v := s.(type) {
|
||||
case ReaderSeekerCloser:
|
||||
return v.GetLen()
|
||||
case *ReaderSeekerCloser:
|
||||
return v.GetLen()
|
||||
}
|
||||
|
||||
return seekerLen(s)
|
||||
}
|
||||
|
||||
func seekerLen(s io.Seeker) (int64, error) {
|
||||
curOffset, err := s.Seek(0, sdkio.SeekCurrent)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
endOffset, err := s.Seek(0, sdkio.SeekEnd)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
_, err = s.Seek(curOffset, sdkio.SeekStart)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return endOffset - curOffset, nil
|
||||
}
|
||||
|
||||
// Close closes the ReaderSeekerCloser.
|
||||
//
|
||||
// If the ReaderSeekerCloser is not an io.Closer nothing will be done.
|
||||
|
@ -116,3 +206,36 @@ func (b *WriteAtBuffer) Bytes() []byte {
|
|||
defer b.m.Unlock()
|
||||
return b.buf
|
||||
}
|
||||
|
||||
// MultiCloser is a utility to close multiple io.Closers within a single
|
||||
// statement.
|
||||
type MultiCloser []io.Closer
|
||||
|
||||
// Close closes all of the io.Closers making up the MultiClosers. Any
|
||||
// errors that occur while closing will be returned in the order they
|
||||
// occur.
|
||||
func (m MultiCloser) Close() error {
|
||||
var errs errors
|
||||
for _, c := range m {
|
||||
err := c.Close()
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if len(errs) != 0 {
|
||||
return errs
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type errors []error
|
||||
|
||||
func (es errors) Error() string {
|
||||
var parts []string
|
||||
for _, e := range es {
|
||||
parts = append(parts, e.Error())
|
||||
}
|
||||
|
||||
return strings.Join(parts, "\n")
|
||||
}
|
||||
|
|
2
vendor/github.com/aws/aws-sdk-go/aws/version.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/version.go
generated
vendored
|
@ -5,4 +5,4 @@ package aws
|
|||
const SDKName = "aws-sdk-go"
|
||||
|
||||
// SDKVersion is the version of this SDK
|
||||
const SDKVersion = "1.12.66"
|
||||
const SDKVersion = "1.28.11"
|
||||
|
|
3
vendor/github.com/aws/aws-sdk-go/go.mod
generated
vendored
Normal file
3
vendor/github.com/aws/aws-sdk-go/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
module github.com/aws/aws-sdk-go
|
||||
|
||||
require github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af
|
120
vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go
generated
vendored
Normal file
120
vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
package ini
|
||||
|
||||
// ASTKind represents different states in the parse table
|
||||
// and the type of AST that is being constructed
|
||||
type ASTKind int
|
||||
|
||||
// ASTKind* is used in the parse table to transition between
|
||||
// the different states
|
||||
const (
|
||||
ASTKindNone = ASTKind(iota)
|
||||
ASTKindStart
|
||||
ASTKindExpr
|
||||
ASTKindEqualExpr
|
||||
ASTKindStatement
|
||||
ASTKindSkipStatement
|
||||
ASTKindExprStatement
|
||||
ASTKindSectionStatement
|
||||
ASTKindNestedSectionStatement
|
||||
ASTKindCompletedNestedSectionStatement
|
||||
ASTKindCommentStatement
|
||||
ASTKindCompletedSectionStatement
|
||||
)
|
||||
|
||||
func (k ASTKind) String() string {
|
||||
switch k {
|
||||
case ASTKindNone:
|
||||
return "none"
|
||||
case ASTKindStart:
|
||||
return "start"
|
||||
case ASTKindExpr:
|
||||
return "expr"
|
||||
case ASTKindStatement:
|
||||
return "stmt"
|
||||
case ASTKindSectionStatement:
|
||||
return "section_stmt"
|
||||
case ASTKindExprStatement:
|
||||
return "expr_stmt"
|
||||
case ASTKindCommentStatement:
|
||||
return "comment"
|
||||
case ASTKindNestedSectionStatement:
|
||||
return "nested_section_stmt"
|
||||
case ASTKindCompletedSectionStatement:
|
||||
return "completed_stmt"
|
||||
case ASTKindSkipStatement:
|
||||
return "skip"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// AST interface allows us to determine what kind of node we
|
||||
// are on and casting may not need to be necessary.
|
||||
//
|
||||
// The root is always the first node in Children
|
||||
type AST struct {
|
||||
Kind ASTKind
|
||||
Root Token
|
||||
RootToken bool
|
||||
Children []AST
|
||||
}
|
||||
|
||||
func newAST(kind ASTKind, root AST, children ...AST) AST {
|
||||
return AST{
|
||||
Kind: kind,
|
||||
Children: append([]AST{root}, children...),
|
||||
}
|
||||
}
|
||||
|
||||
func newASTWithRootToken(kind ASTKind, root Token, children ...AST) AST {
|
||||
return AST{
|
||||
Kind: kind,
|
||||
Root: root,
|
||||
RootToken: true,
|
||||
Children: children,
|
||||
}
|
||||
}
|
||||
|
||||
// AppendChild will append to the list of children an AST has.
|
||||
func (a *AST) AppendChild(child AST) {
|
||||
a.Children = append(a.Children, child)
|
||||
}
|
||||
|
||||
// GetRoot will return the root AST which can be the first entry
|
||||
// in the children list or a token.
|
||||
func (a *AST) GetRoot() AST {
|
||||
if a.RootToken {
|
||||
return *a
|
||||
}
|
||||
|
||||
if len(a.Children) == 0 {
|
||||
return AST{}
|
||||
}
|
||||
|
||||
return a.Children[0]
|
||||
}
|
||||
|
||||
// GetChildren will return the current AST's list of children
|
||||
func (a *AST) GetChildren() []AST {
|
||||
if len(a.Children) == 0 {
|
||||
return []AST{}
|
||||
}
|
||||
|
||||
if a.RootToken {
|
||||
return a.Children
|
||||
}
|
||||
|
||||
return a.Children[1:]
|
||||
}
|
||||
|
||||
// SetChildren will set and override all children of the AST.
|
||||
func (a *AST) SetChildren(children []AST) {
|
||||
if a.RootToken {
|
||||
a.Children = children
|
||||
} else {
|
||||
a.Children = append(a.Children[:1], children...)
|
||||
}
|
||||
}
|
||||
|
||||
// Start is used to indicate the starting state of the parse table.
|
||||
var Start = newAST(ASTKindStart, AST{})
|
11
vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go
generated
vendored
Normal file
11
vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
package ini
|
||||
|
||||
var commaRunes = []rune(",")
|
||||
|
||||
func isComma(b rune) bool {
|
||||
return b == ','
|
||||
}
|
||||
|
||||
func newCommaToken() Token {
|
||||
return newToken(TokenComma, commaRunes, NoneType)
|
||||
}
|
35
vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go
generated
vendored
Normal file
35
vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
package ini
|
||||
|
||||
// isComment will return whether or not the next byte(s) is a
|
||||
// comment.
|
||||
func isComment(b []rune) bool {
|
||||
if len(b) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
switch b[0] {
|
||||
case ';':
|
||||
return true
|
||||
case '#':
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// newCommentToken will create a comment token and
|
||||
// return how many bytes were read.
|
||||
func newCommentToken(b []rune) (Token, int, error) {
|
||||
i := 0
|
||||
for ; i < len(b); i++ {
|
||||
if b[i] == '\n' {
|
||||
break
|
||||
}
|
||||
|
||||
if len(b)-i > 2 && b[i] == '\r' && b[i+1] == '\n' {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return newToken(TokenComment, b[:i], NoneType), i, nil
|
||||
}
|
29
vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go
generated
vendored
Normal file
29
vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Package ini is an LL(1) parser for configuration files.
|
||||
//
|
||||
// Example:
|
||||
// sections, err := ini.OpenFile("/path/to/file")
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// profile := "foo"
|
||||
// section, ok := sections.GetSection(profile)
|
||||
// if !ok {
|
||||
// fmt.Printf("section %q could not be found", profile)
|
||||
// }
|
||||
//
|
||||
// Below is the BNF that describes this parser
|
||||
// Grammar:
|
||||
// stmt -> value stmt'
|
||||
// stmt' -> epsilon | op stmt
|
||||
// value -> number | string | boolean | quoted_string
|
||||
//
|
||||
// section -> [ section'
|
||||
// section' -> value section_close
|
||||
// section_close -> ]
|
||||
//
|
||||
// SkipState will skip (NL WS)+
|
||||
//
|
||||
// comment -> # comment' | ; comment'
|
||||
// comment' -> epsilon | value
|
||||
package ini
|
4
vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go
generated
vendored
Normal file
4
vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
package ini
|
||||
|
||||
// emptyToken is used to satisfy the Token interface
|
||||
var emptyToken = newToken(TokenNone, []rune{}, NoneType)
|
24
vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go
generated
vendored
Normal file
24
vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
package ini
|
||||
|
||||
// newExpression will return an expression AST.
|
||||
// Expr represents an expression
|
||||
//
|
||||
// grammar:
|
||||
// expr -> string | number
|
||||
func newExpression(tok Token) AST {
|
||||
return newASTWithRootToken(ASTKindExpr, tok)
|
||||
}
|
||||
|
||||
func newEqualExpr(left AST, tok Token) AST {
|
||||
return newASTWithRootToken(ASTKindEqualExpr, tok, left)
|
||||
}
|
||||
|
||||
// EqualExprKey will return a LHS value in the equal expr
|
||||
func EqualExprKey(ast AST) string {
|
||||
children := ast.GetChildren()
|
||||
if len(children) == 0 || ast.Kind != ASTKindEqualExpr {
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(children[0].Root.Raw())
|
||||
}
|
17
vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go
generated
vendored
Normal file
17
vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// +build gofuzz
|
||||
|
||||
package ini
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
b := bytes.NewReader(data)
|
||||
|
||||
if _, err := Parse(b); err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
51
vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go
generated
vendored
Normal file
51
vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
// OpenFile takes a path to a given file, and will open and parse
|
||||
// that file.
|
||||
func OpenFile(path string) (Sections, error) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
return Sections{}, awserr.New(ErrCodeUnableToReadFile, "unable to open file", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
return Parse(f)
|
||||
}
|
||||
|
||||
// Parse will parse the given file using the shared config
|
||||
// visitor.
|
||||
func Parse(f io.Reader) (Sections, error) {
|
||||
tree, err := ParseAST(f)
|
||||
if err != nil {
|
||||
return Sections{}, err
|
||||
}
|
||||
|
||||
v := NewDefaultVisitor()
|
||||
if err = Walk(tree, v); err != nil {
|
||||
return Sections{}, err
|
||||
}
|
||||
|
||||
return v.Sections, nil
|
||||
}
|
||||
|
||||
// ParseBytes will parse the given bytes and return the parsed sections.
|
||||
func ParseBytes(b []byte) (Sections, error) {
|
||||
tree, err := ParseASTBytes(b)
|
||||
if err != nil {
|
||||
return Sections{}, err
|
||||
}
|
||||
|
||||
v := NewDefaultVisitor()
|
||||
if err = Walk(tree, v); err != nil {
|
||||
return Sections{}, err
|
||||
}
|
||||
|
||||
return v.Sections, nil
|
||||
}
|
165
vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go
generated
vendored
Normal file
165
vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go
generated
vendored
Normal file
|
@ -0,0 +1,165 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
)
|
||||
|
||||
const (
|
||||
// ErrCodeUnableToReadFile is used when a file is failed to be
|
||||
// opened or read from.
|
||||
ErrCodeUnableToReadFile = "FailedRead"
|
||||
)
|
||||
|
||||
// TokenType represents the various different tokens types
|
||||
type TokenType int
|
||||
|
||||
func (t TokenType) String() string {
|
||||
switch t {
|
||||
case TokenNone:
|
||||
return "none"
|
||||
case TokenLit:
|
||||
return "literal"
|
||||
case TokenSep:
|
||||
return "sep"
|
||||
case TokenOp:
|
||||
return "op"
|
||||
case TokenWS:
|
||||
return "ws"
|
||||
case TokenNL:
|
||||
return "newline"
|
||||
case TokenComment:
|
||||
return "comment"
|
||||
case TokenComma:
|
||||
return "comma"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
// TokenType enums
|
||||
const (
|
||||
TokenNone = TokenType(iota)
|
||||
TokenLit
|
||||
TokenSep
|
||||
TokenComma
|
||||
TokenOp
|
||||
TokenWS
|
||||
TokenNL
|
||||
TokenComment
|
||||
)
|
||||
|
||||
type iniLexer struct{}
|
||||
|
||||
// Tokenize will return a list of tokens during lexical analysis of the
|
||||
// io.Reader.
|
||||
func (l *iniLexer) Tokenize(r io.Reader) ([]Token, error) {
|
||||
b, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, awserr.New(ErrCodeUnableToReadFile, "unable to read file", err)
|
||||
}
|
||||
|
||||
return l.tokenize(b)
|
||||
}
|
||||
|
||||
func (l *iniLexer) tokenize(b []byte) ([]Token, error) {
|
||||
runes := bytes.Runes(b)
|
||||
var err error
|
||||
n := 0
|
||||
tokenAmount := countTokens(runes)
|
||||
tokens := make([]Token, tokenAmount)
|
||||
count := 0
|
||||
|
||||
for len(runes) > 0 && count < tokenAmount {
|
||||
switch {
|
||||
case isWhitespace(runes[0]):
|
||||
tokens[count], n, err = newWSToken(runes)
|
||||
case isComma(runes[0]):
|
||||
tokens[count], n = newCommaToken(), 1
|
||||
case isComment(runes):
|
||||
tokens[count], n, err = newCommentToken(runes)
|
||||
case isNewline(runes):
|
||||
tokens[count], n, err = newNewlineToken(runes)
|
||||
case isSep(runes):
|
||||
tokens[count], n, err = newSepToken(runes)
|
||||
case isOp(runes):
|
||||
tokens[count], n, err = newOpToken(runes)
|
||||
default:
|
||||
tokens[count], n, err = newLitToken(runes)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
count++
|
||||
|
||||
runes = runes[n:]
|
||||
}
|
||||
|
||||
return tokens[:count], nil
|
||||
}
|
||||
|
||||
func countTokens(runes []rune) int {
|
||||
count, n := 0, 0
|
||||
var err error
|
||||
|
||||
for len(runes) > 0 {
|
||||
switch {
|
||||
case isWhitespace(runes[0]):
|
||||
_, n, err = newWSToken(runes)
|
||||
case isComma(runes[0]):
|
||||
_, n = newCommaToken(), 1
|
||||
case isComment(runes):
|
||||
_, n, err = newCommentToken(runes)
|
||||
case isNewline(runes):
|
||||
_, n, err = newNewlineToken(runes)
|
||||
case isSep(runes):
|
||||
_, n, err = newSepToken(runes)
|
||||
case isOp(runes):
|
||||
_, n, err = newOpToken(runes)
|
||||
default:
|
||||
_, n, err = newLitToken(runes)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
count++
|
||||
runes = runes[n:]
|
||||
}
|
||||
|
||||
return count + 1
|
||||
}
|
||||
|
||||
// Token indicates a metadata about a given value.
|
||||
type Token struct {
|
||||
t TokenType
|
||||
ValueType ValueType
|
||||
base int
|
||||
raw []rune
|
||||
}
|
||||
|
||||
var emptyValue = Value{}
|
||||
|
||||
func newToken(t TokenType, raw []rune, v ValueType) Token {
|
||||
return Token{
|
||||
t: t,
|
||||
raw: raw,
|
||||
ValueType: v,
|
||||
}
|
||||
}
|
||||
|
||||
// Raw return the raw runes that were consumed
|
||||
func (tok Token) Raw() []rune {
|
||||
return tok.raw
|
||||
}
|
||||
|
||||
// Type returns the token type
|
||||
func (tok Token) Type() TokenType {
|
||||
return tok.t
|
||||
}
|
356
vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go
generated
vendored
Normal file
356
vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go
generated
vendored
Normal file
|
@ -0,0 +1,356 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// State enums for the parse table
|
||||
const (
|
||||
InvalidState = iota
|
||||
// stmt -> value stmt'
|
||||
StatementState
|
||||
// stmt' -> MarkComplete | op stmt
|
||||
StatementPrimeState
|
||||
// value -> number | string | boolean | quoted_string
|
||||
ValueState
|
||||
// section -> [ section'
|
||||
OpenScopeState
|
||||
// section' -> value section_close
|
||||
SectionState
|
||||
// section_close -> ]
|
||||
CloseScopeState
|
||||
// SkipState will skip (NL WS)+
|
||||
SkipState
|
||||
// SkipTokenState will skip any token and push the previous
|
||||
// state onto the stack.
|
||||
SkipTokenState
|
||||
// comment -> # comment' | ; comment'
|
||||
// comment' -> MarkComplete | value
|
||||
CommentState
|
||||
// MarkComplete state will complete statements and move that
|
||||
// to the completed AST list
|
||||
MarkCompleteState
|
||||
// TerminalState signifies that the tokens have been fully parsed
|
||||
TerminalState
|
||||
)
|
||||
|
||||
// parseTable is a state machine to dictate the grammar above.
|
||||
var parseTable = map[ASTKind]map[TokenType]int{
|
||||
ASTKindStart: map[TokenType]int{
|
||||
TokenLit: StatementState,
|
||||
TokenSep: OpenScopeState,
|
||||
TokenWS: SkipTokenState,
|
||||
TokenNL: SkipTokenState,
|
||||
TokenComment: CommentState,
|
||||
TokenNone: TerminalState,
|
||||
},
|
||||
ASTKindCommentStatement: map[TokenType]int{
|
||||
TokenLit: StatementState,
|
||||
TokenSep: OpenScopeState,
|
||||
TokenWS: SkipTokenState,
|
||||
TokenNL: SkipTokenState,
|
||||
TokenComment: CommentState,
|
||||
TokenNone: MarkCompleteState,
|
||||
},
|
||||
ASTKindExpr: map[TokenType]int{
|
||||
TokenOp: StatementPrimeState,
|
||||
TokenLit: ValueState,
|
||||
TokenSep: OpenScopeState,
|
||||
TokenWS: ValueState,
|
||||
TokenNL: SkipState,
|
||||
TokenComment: CommentState,
|
||||
TokenNone: MarkCompleteState,
|
||||
},
|
||||
ASTKindEqualExpr: map[TokenType]int{
|
||||
TokenLit: ValueState,
|
||||
TokenWS: SkipTokenState,
|
||||
TokenNL: SkipState,
|
||||
},
|
||||
ASTKindStatement: map[TokenType]int{
|
||||
TokenLit: SectionState,
|
||||
TokenSep: CloseScopeState,
|
||||
TokenWS: SkipTokenState,
|
||||
TokenNL: SkipTokenState,
|
||||
TokenComment: CommentState,
|
||||
TokenNone: MarkCompleteState,
|
||||
},
|
||||
ASTKindExprStatement: map[TokenType]int{
|
||||
TokenLit: ValueState,
|
||||
TokenSep: OpenScopeState,
|
||||
TokenOp: ValueState,
|
||||
TokenWS: ValueState,
|
||||
TokenNL: MarkCompleteState,
|
||||
TokenComment: CommentState,
|
||||
TokenNone: TerminalState,
|
||||
TokenComma: SkipState,
|
||||
},
|
||||
ASTKindSectionStatement: map[TokenType]int{
|
||||
TokenLit: SectionState,
|
||||
TokenOp: SectionState,
|
||||
TokenSep: CloseScopeState,
|
||||
TokenWS: SectionState,
|
||||
TokenNL: SkipTokenState,
|
||||
},
|
||||
ASTKindCompletedSectionStatement: map[TokenType]int{
|
||||
TokenWS: SkipTokenState,
|
||||
TokenNL: SkipTokenState,
|
||||
TokenLit: StatementState,
|
||||
TokenSep: OpenScopeState,
|
||||
TokenComment: CommentState,
|
||||
TokenNone: MarkCompleteState,
|
||||
},
|
||||
ASTKindSkipStatement: map[TokenType]int{
|
||||
TokenLit: StatementState,
|
||||
TokenSep: OpenScopeState,
|
||||
TokenWS: SkipTokenState,
|
||||
TokenNL: SkipTokenState,
|
||||
TokenComment: CommentState,
|
||||
TokenNone: TerminalState,
|
||||
},
|
||||
}
|
||||
|
||||
// ParseAST will parse input from an io.Reader using
|
||||
// an LL(1) parser.
|
||||
func ParseAST(r io.Reader) ([]AST, error) {
|
||||
lexer := iniLexer{}
|
||||
tokens, err := lexer.Tokenize(r)
|
||||
if err != nil {
|
||||
return []AST{}, err
|
||||
}
|
||||
|
||||
return parse(tokens)
|
||||
}
|
||||
|
||||
// ParseASTBytes will parse input from a byte slice using
|
||||
// an LL(1) parser.
|
||||
func ParseASTBytes(b []byte) ([]AST, error) {
|
||||
lexer := iniLexer{}
|
||||
tokens, err := lexer.tokenize(b)
|
||||
if err != nil {
|
||||
return []AST{}, err
|
||||
}
|
||||
|
||||
return parse(tokens)
|
||||
}
|
||||
|
||||
func parse(tokens []Token) ([]AST, error) {
|
||||
start := Start
|
||||
stack := newParseStack(3, len(tokens))
|
||||
|
||||
stack.Push(start)
|
||||
s := newSkipper()
|
||||
|
||||
loop:
|
||||
for stack.Len() > 0 {
|
||||
k := stack.Pop()
|
||||
|
||||
var tok Token
|
||||
if len(tokens) == 0 {
|
||||
// this occurs when all the tokens have been processed
|
||||
// but reduction of what's left on the stack needs to
|
||||
// occur.
|
||||
tok = emptyToken
|
||||
} else {
|
||||
tok = tokens[0]
|
||||
}
|
||||
|
||||
step := parseTable[k.Kind][tok.Type()]
|
||||
if s.ShouldSkip(tok) {
|
||||
// being in a skip state with no tokens will break out of
|
||||
// the parse loop since there is nothing left to process.
|
||||
if len(tokens) == 0 {
|
||||
break loop
|
||||
}
|
||||
// if should skip is true, we skip the tokens until should skip is set to false.
|
||||
step = SkipTokenState
|
||||
}
|
||||
|
||||
switch step {
|
||||
case TerminalState:
|
||||
// Finished parsing. Push what should be the last
|
||||
// statement to the stack. If there is anything left
|
||||
// on the stack, an error in parsing has occurred.
|
||||
if k.Kind != ASTKindStart {
|
||||
stack.MarkComplete(k)
|
||||
}
|
||||
break loop
|
||||
case SkipTokenState:
|
||||
// When skipping a token, the previous state was popped off the stack.
|
||||
// To maintain the correct state, the previous state will be pushed
|
||||
// onto the stack.
|
||||
stack.Push(k)
|
||||
case StatementState:
|
||||
if k.Kind != ASTKindStart {
|
||||
stack.MarkComplete(k)
|
||||
}
|
||||
expr := newExpression(tok)
|
||||
stack.Push(expr)
|
||||
case StatementPrimeState:
|
||||
if tok.Type() != TokenOp {
|
||||
stack.MarkComplete(k)
|
||||
continue
|
||||
}
|
||||
|
||||
if k.Kind != ASTKindExpr {
|
||||
return nil, NewParseError(
|
||||
fmt.Sprintf("invalid expression: expected Expr type, but found %T type", k),
|
||||
)
|
||||
}
|
||||
|
||||
k = trimSpaces(k)
|
||||
expr := newEqualExpr(k, tok)
|
||||
stack.Push(expr)
|
||||
case ValueState:
|
||||
// ValueState requires the previous state to either be an equal expression
|
||||
// or an expression statement.
|
||||
//
|
||||
// This grammar occurs when the RHS is a number, word, or quoted string.
|
||||
// equal_expr -> lit op equal_expr'
|
||||
// equal_expr' -> number | string | quoted_string
|
||||
// quoted_string -> " quoted_string'
|
||||
// quoted_string' -> string quoted_string_end
|
||||
// quoted_string_end -> "
|
||||
//
|
||||
// otherwise
|
||||
// expr_stmt -> equal_expr (expr_stmt')*
|
||||
// expr_stmt' -> ws S | op S | MarkComplete
|
||||
// S -> equal_expr' expr_stmt'
|
||||
switch k.Kind {
|
||||
case ASTKindEqualExpr:
|
||||
// assigning a value to some key
|
||||
k.AppendChild(newExpression(tok))
|
||||
stack.Push(newExprStatement(k))
|
||||
case ASTKindExpr:
|
||||
k.Root.raw = append(k.Root.raw, tok.Raw()...)
|
||||
stack.Push(k)
|
||||
case ASTKindExprStatement:
|
||||
root := k.GetRoot()
|
||||
children := root.GetChildren()
|
||||
if len(children) == 0 {
|
||||
return nil, NewParseError(
|
||||
fmt.Sprintf("invalid expression: AST contains no children %s", k.Kind),
|
||||
)
|
||||
}
|
||||
|
||||
rhs := children[len(children)-1]
|
||||
|
||||
if rhs.Root.ValueType != QuotedStringType {
|
||||
rhs.Root.ValueType = StringType
|
||||
rhs.Root.raw = append(rhs.Root.raw, tok.Raw()...)
|
||||
|
||||
}
|
||||
|
||||
children[len(children)-1] = rhs
|
||||
k.SetChildren(children)
|
||||
|
||||
stack.Push(k)
|
||||
}
|
||||
case OpenScopeState:
|
||||
if !runeCompare(tok.Raw(), openBrace) {
|
||||
return nil, NewParseError("expected '['")
|
||||
}
|
||||
// If OpenScopeState is not at the start, we must mark the previous ast as complete
|
||||
//
|
||||
// for example: if previous ast was a skip statement;
|
||||
// we should mark it as complete before we create a new statement
|
||||
if k.Kind != ASTKindStart {
|
||||
stack.MarkComplete(k)
|
||||
}
|
||||
|
||||
stmt := newStatement()
|
||||
stack.Push(stmt)
|
||||
case CloseScopeState:
|
||||
if !runeCompare(tok.Raw(), closeBrace) {
|
||||
return nil, NewParseError("expected ']'")
|
||||
}
|
||||
|
||||
k = trimSpaces(k)
|
||||
stack.Push(newCompletedSectionStatement(k))
|
||||
case SectionState:
|
||||
var stmt AST
|
||||
|
||||
switch k.Kind {
|
||||
case ASTKindStatement:
|
||||
// If there are multiple literals inside of a scope declaration,
|
||||
// then the current token's raw value will be appended to the Name.
|
||||
//
|
||||
// This handles cases like [ profile default ]
|
||||
//
|
||||
// k will represent a SectionStatement with the children representing
|
||||
// the label of the section
|
||||
stmt = newSectionStatement(tok)
|
||||
case ASTKindSectionStatement:
|
||||
k.Root.raw = append(k.Root.raw, tok.Raw()...)
|
||||
stmt = k
|
||||
default:
|
||||
return nil, NewParseError(
|
||||
fmt.Sprintf("invalid statement: expected statement: %v", k.Kind),
|
||||
)
|
||||
}
|
||||
|
||||
stack.Push(stmt)
|
||||
case MarkCompleteState:
|
||||
if k.Kind != ASTKindStart {
|
||||
stack.MarkComplete(k)
|
||||
}
|
||||
|
||||
if stack.Len() == 0 {
|
||||
stack.Push(start)
|
||||
}
|
||||
case SkipState:
|
||||
stack.Push(newSkipStatement(k))
|
||||
s.Skip()
|
||||
case CommentState:
|
||||
if k.Kind == ASTKindStart {
|
||||
stack.Push(k)
|
||||
} else {
|
||||
stack.MarkComplete(k)
|
||||
}
|
||||
|
||||
stmt := newCommentStatement(tok)
|
||||
stack.Push(stmt)
|
||||
default:
|
||||
return nil, NewParseError(
|
||||
fmt.Sprintf("invalid state with ASTKind %v and TokenType %v",
|
||||
k, tok.Type()))
|
||||
}
|
||||
|
||||
if len(tokens) > 0 {
|
||||
tokens = tokens[1:]
|
||||
}
|
||||
}
|
||||
|
||||
// this occurs when a statement has not been completed
|
||||
if stack.top > 1 {
|
||||
return nil, NewParseError(fmt.Sprintf("incomplete ini expression"))
|
||||
}
|
||||
|
||||
// returns a sublist which excludes the start symbol
|
||||
return stack.List(), nil
|
||||
}
|
||||
|
||||
// trimSpaces will trim spaces on the left and right hand side of
|
||||
// the literal.
|
||||
func trimSpaces(k AST) AST {
|
||||
// trim left hand side of spaces
|
||||
for i := 0; i < len(k.Root.raw); i++ {
|
||||
if !isWhitespace(k.Root.raw[i]) {
|
||||
break
|
||||
}
|
||||
|
||||
k.Root.raw = k.Root.raw[1:]
|
||||
i--
|
||||
}
|
||||
|
||||
// trim right hand side of spaces
|
||||
for i := len(k.Root.raw) - 1; i >= 0; i-- {
|
||||
if !isWhitespace(k.Root.raw[i]) {
|
||||
break
|
||||
}
|
||||
|
||||
k.Root.raw = k.Root.raw[:len(k.Root.raw)-1]
|
||||
}
|
||||
|
||||
return k
|
||||
}
|
324
vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go
generated
vendored
Normal file
324
vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go
generated
vendored
Normal file
|
@ -0,0 +1,324 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
runesTrue = []rune("true")
|
||||
runesFalse = []rune("false")
|
||||
)
|
||||
|
||||
var literalValues = [][]rune{
|
||||
runesTrue,
|
||||
runesFalse,
|
||||
}
|
||||
|
||||
func isBoolValue(b []rune) bool {
|
||||
for _, lv := range literalValues {
|
||||
if isLitValue(lv, b) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isLitValue(want, have []rune) bool {
|
||||
if len(have) < len(want) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(want); i++ {
|
||||
if want[i] != have[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// isNumberValue will return whether not the leading characters in
|
||||
// a byte slice is a number. A number is delimited by whitespace or
|
||||
// the newline token.
|
||||
//
|
||||
// A number is defined to be in a binary, octal, decimal (int | float), hex format,
|
||||
// or in scientific notation.
|
||||
func isNumberValue(b []rune) bool {
|
||||
negativeIndex := 0
|
||||
helper := numberHelper{}
|
||||
needDigit := false
|
||||
|
||||
for i := 0; i < len(b); i++ {
|
||||
negativeIndex++
|
||||
|
||||
switch b[i] {
|
||||
case '-':
|
||||
if helper.IsNegative() || negativeIndex != 1 {
|
||||
return false
|
||||
}
|
||||
helper.Determine(b[i])
|
||||
needDigit = true
|
||||
continue
|
||||
case 'e', 'E':
|
||||
if err := helper.Determine(b[i]); err != nil {
|
||||
return false
|
||||
}
|
||||
negativeIndex = 0
|
||||
needDigit = true
|
||||
continue
|
||||
case 'b':
|
||||
if helper.numberFormat == hex {
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
case 'o', 'x':
|
||||
needDigit = true
|
||||
if i == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
fallthrough
|
||||
case '.':
|
||||
if err := helper.Determine(b[i]); err != nil {
|
||||
return false
|
||||
}
|
||||
needDigit = true
|
||||
continue
|
||||
}
|
||||
|
||||
if i > 0 && (isNewline(b[i:]) || isWhitespace(b[i])) {
|
||||
return !needDigit
|
||||
}
|
||||
|
||||
if !helper.CorrectByte(b[i]) {
|
||||
return false
|
||||
}
|
||||
needDigit = false
|
||||
}
|
||||
|
||||
return !needDigit
|
||||
}
|
||||
|
||||
func isValid(b []rune) (bool, int, error) {
|
||||
if len(b) == 0 {
|
||||
// TODO: should probably return an error
|
||||
return false, 0, nil
|
||||
}
|
||||
|
||||
return isValidRune(b[0]), 1, nil
|
||||
}
|
||||
|
||||
func isValidRune(r rune) bool {
|
||||
return r != ':' && r != '=' && r != '[' && r != ']' && r != ' ' && r != '\n'
|
||||
}
|
||||
|
||||
// ValueType is an enum that will signify what type
|
||||
// the Value is
|
||||
type ValueType int
|
||||
|
||||
func (v ValueType) String() string {
|
||||
switch v {
|
||||
case NoneType:
|
||||
return "NONE"
|
||||
case DecimalType:
|
||||
return "FLOAT"
|
||||
case IntegerType:
|
||||
return "INT"
|
||||
case StringType:
|
||||
return "STRING"
|
||||
case BoolType:
|
||||
return "BOOL"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// ValueType enums
|
||||
const (
|
||||
NoneType = ValueType(iota)
|
||||
DecimalType
|
||||
IntegerType
|
||||
StringType
|
||||
QuotedStringType
|
||||
BoolType
|
||||
)
|
||||
|
||||
// Value is a union container
|
||||
type Value struct {
|
||||
Type ValueType
|
||||
raw []rune
|
||||
|
||||
integer int64
|
||||
decimal float64
|
||||
boolean bool
|
||||
str string
|
||||
}
|
||||
|
||||
func newValue(t ValueType, base int, raw []rune) (Value, error) {
|
||||
v := Value{
|
||||
Type: t,
|
||||
raw: raw,
|
||||
}
|
||||
var err error
|
||||
|
||||
switch t {
|
||||
case DecimalType:
|
||||
v.decimal, err = strconv.ParseFloat(string(raw), 64)
|
||||
case IntegerType:
|
||||
if base != 10 {
|
||||
raw = raw[2:]
|
||||
}
|
||||
|
||||
v.integer, err = strconv.ParseInt(string(raw), base, 64)
|
||||
case StringType:
|
||||
v.str = string(raw)
|
||||
case QuotedStringType:
|
||||
v.str = string(raw[1 : len(raw)-1])
|
||||
case BoolType:
|
||||
v.boolean = runeCompare(v.raw, runesTrue)
|
||||
}
|
||||
|
||||
// issue 2253
|
||||
//
|
||||
// if the value trying to be parsed is too large, then we will use
|
||||
// the 'StringType' and raw value instead.
|
||||
if nerr, ok := err.(*strconv.NumError); ok && nerr.Err == strconv.ErrRange {
|
||||
v.Type = StringType
|
||||
v.str = string(raw)
|
||||
err = nil
|
||||
}
|
||||
|
||||
return v, err
|
||||
}
|
||||
|
||||
// Append will append values and change the type to a string
|
||||
// type.
|
||||
func (v *Value) Append(tok Token) {
|
||||
r := tok.Raw()
|
||||
if v.Type != QuotedStringType {
|
||||
v.Type = StringType
|
||||
r = tok.raw[1 : len(tok.raw)-1]
|
||||
}
|
||||
if tok.Type() != TokenLit {
|
||||
v.raw = append(v.raw, tok.Raw()...)
|
||||
} else {
|
||||
v.raw = append(v.raw, r...)
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) String() string {
|
||||
switch v.Type {
|
||||
case DecimalType:
|
||||
return fmt.Sprintf("decimal: %f", v.decimal)
|
||||
case IntegerType:
|
||||
return fmt.Sprintf("integer: %d", v.integer)
|
||||
case StringType:
|
||||
return fmt.Sprintf("string: %s", string(v.raw))
|
||||
case QuotedStringType:
|
||||
return fmt.Sprintf("quoted string: %s", string(v.raw))
|
||||
case BoolType:
|
||||
return fmt.Sprintf("bool: %t", v.boolean)
|
||||
default:
|
||||
return "union not set"
|
||||
}
|
||||
}
|
||||
|
||||
func newLitToken(b []rune) (Token, int, error) {
|
||||
n := 0
|
||||
var err error
|
||||
|
||||
token := Token{}
|
||||
if b[0] == '"' {
|
||||
n, err = getStringValue(b)
|
||||
if err != nil {
|
||||
return token, n, err
|
||||
}
|
||||
|
||||
token = newToken(TokenLit, b[:n], QuotedStringType)
|
||||
} else if isNumberValue(b) {
|
||||
var base int
|
||||
base, n, err = getNumericalValue(b)
|
||||
if err != nil {
|
||||
return token, 0, err
|
||||
}
|
||||
|
||||
value := b[:n]
|
||||
vType := IntegerType
|
||||
if contains(value, '.') || hasExponent(value) {
|
||||
vType = DecimalType
|
||||
}
|
||||
token = newToken(TokenLit, value, vType)
|
||||
token.base = base
|
||||
} else if isBoolValue(b) {
|
||||
n, err = getBoolValue(b)
|
||||
|
||||
token = newToken(TokenLit, b[:n], BoolType)
|
||||
} else {
|
||||
n, err = getValue(b)
|
||||
token = newToken(TokenLit, b[:n], StringType)
|
||||
}
|
||||
|
||||
return token, n, err
|
||||
}
|
||||
|
||||
// IntValue returns an integer value
|
||||
func (v Value) IntValue() int64 {
|
||||
return v.integer
|
||||
}
|
||||
|
||||
// FloatValue returns a float value
|
||||
func (v Value) FloatValue() float64 {
|
||||
return v.decimal
|
||||
}
|
||||
|
||||
// BoolValue returns a bool value
|
||||
func (v Value) BoolValue() bool {
|
||||
return v.boolean
|
||||
}
|
||||
|
||||
func isTrimmable(r rune) bool {
|
||||
switch r {
|
||||
case '\n', ' ':
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// StringValue returns the string value
|
||||
func (v Value) StringValue() string {
|
||||
switch v.Type {
|
||||
case StringType:
|
||||
return strings.TrimFunc(string(v.raw), isTrimmable)
|
||||
case QuotedStringType:
|
||||
// preserve all characters in the quotes
|
||||
return string(removeEscapedCharacters(v.raw[1 : len(v.raw)-1]))
|
||||
default:
|
||||
return strings.TrimFunc(string(v.raw), isTrimmable)
|
||||
}
|
||||
}
|
||||
|
||||
func contains(runes []rune, c rune) bool {
|
||||
for i := 0; i < len(runes); i++ {
|
||||
if runes[i] == c {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func runeCompare(v1 []rune, v2 []rune) bool {
|
||||
if len(v1) != len(v2) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i := 0; i < len(v1); i++ {
|
||||
if v1[i] != v2[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
30
vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go
generated
vendored
Normal file
30
vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
package ini
|
||||
|
||||
func isNewline(b []rune) bool {
|
||||
if len(b) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if b[0] == '\n' {
|
||||
return true
|
||||
}
|
||||
|
||||
if len(b) < 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
return b[0] == '\r' && b[1] == '\n'
|
||||
}
|
||||
|
||||
func newNewlineToken(b []rune) (Token, int, error) {
|
||||
i := 1
|
||||
if b[0] == '\r' && isNewline(b[1:]) {
|
||||
i++
|
||||
}
|
||||
|
||||
if !isNewline([]rune(b[:i])) {
|
||||
return emptyToken, 0, NewParseError("invalid new line token")
|
||||
}
|
||||
|
||||
return newToken(TokenNL, b[:i], NoneType), i, nil
|
||||
}
|
152
vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go
generated
vendored
Normal file
152
vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go
generated
vendored
Normal file
|
@ -0,0 +1,152 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
none = numberFormat(iota)
|
||||
binary
|
||||
octal
|
||||
decimal
|
||||
hex
|
||||
exponent
|
||||
)
|
||||
|
||||
type numberFormat int
|
||||
|
||||
// numberHelper is used to dictate what format a number is in
|
||||
// and what to do for negative values. Since -1e-4 is a valid
|
||||
// number, we cannot just simply check for duplicate negatives.
|
||||
type numberHelper struct {
|
||||
numberFormat numberFormat
|
||||
|
||||
negative bool
|
||||
negativeExponent bool
|
||||
}
|
||||
|
||||
func (b numberHelper) Exists() bool {
|
||||
return b.numberFormat != none
|
||||
}
|
||||
|
||||
func (b numberHelper) IsNegative() bool {
|
||||
return b.negative || b.negativeExponent
|
||||
}
|
||||
|
||||
func (b *numberHelper) Determine(c rune) error {
|
||||
if b.Exists() {
|
||||
return NewParseError(fmt.Sprintf("multiple number formats: 0%v", string(c)))
|
||||
}
|
||||
|
||||
switch c {
|
||||
case 'b':
|
||||
b.numberFormat = binary
|
||||
case 'o':
|
||||
b.numberFormat = octal
|
||||
case 'x':
|
||||
b.numberFormat = hex
|
||||
case 'e', 'E':
|
||||
b.numberFormat = exponent
|
||||
case '-':
|
||||
if b.numberFormat != exponent {
|
||||
b.negative = true
|
||||
} else {
|
||||
b.negativeExponent = true
|
||||
}
|
||||
case '.':
|
||||
b.numberFormat = decimal
|
||||
default:
|
||||
return NewParseError(fmt.Sprintf("invalid number character: %v", string(c)))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b numberHelper) CorrectByte(c rune) bool {
|
||||
switch {
|
||||
case b.numberFormat == binary:
|
||||
if !isBinaryByte(c) {
|
||||
return false
|
||||
}
|
||||
case b.numberFormat == octal:
|
||||
if !isOctalByte(c) {
|
||||
return false
|
||||
}
|
||||
case b.numberFormat == hex:
|
||||
if !isHexByte(c) {
|
||||
return false
|
||||
}
|
||||
case b.numberFormat == decimal:
|
||||
if !isDigit(c) {
|
||||
return false
|
||||
}
|
||||
case b.numberFormat == exponent:
|
||||
if !isDigit(c) {
|
||||
return false
|
||||
}
|
||||
case b.negativeExponent:
|
||||
if !isDigit(c) {
|
||||
return false
|
||||
}
|
||||
case b.negative:
|
||||
if !isDigit(c) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
if !isDigit(c) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (b numberHelper) Base() int {
|
||||
switch b.numberFormat {
|
||||
case binary:
|
||||
return 2
|
||||
case octal:
|
||||
return 8
|
||||
case hex:
|
||||
return 16
|
||||
default:
|
||||
return 10
|
||||
}
|
||||
}
|
||||
|
||||
func (b numberHelper) String() string {
|
||||
buf := bytes.Buffer{}
|
||||
i := 0
|
||||
|
||||
switch b.numberFormat {
|
||||
case binary:
|
||||
i++
|
||||
buf.WriteString(strconv.Itoa(i) + ": binary format\n")
|
||||
case octal:
|
||||
i++
|
||||
buf.WriteString(strconv.Itoa(i) + ": octal format\n")
|
||||
case hex:
|
||||
i++
|
||||
buf.WriteString(strconv.Itoa(i) + ": hex format\n")
|
||||
case exponent:
|
||||
i++
|
||||
buf.WriteString(strconv.Itoa(i) + ": exponent format\n")
|
||||
default:
|
||||
i++
|
||||
buf.WriteString(strconv.Itoa(i) + ": integer format\n")
|
||||
}
|
||||
|
||||
if b.negative {
|
||||
i++
|
||||
buf.WriteString(strconv.Itoa(i) + ": negative format\n")
|
||||
}
|
||||
|
||||
if b.negativeExponent {
|
||||
i++
|
||||
buf.WriteString(strconv.Itoa(i) + ": negative exponent format\n")
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
39
vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go
generated
vendored
Normal file
39
vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
equalOp = []rune("=")
|
||||
equalColonOp = []rune(":")
|
||||
)
|
||||
|
||||
func isOp(b []rune) bool {
|
||||
if len(b) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
switch b[0] {
|
||||
case '=':
|
||||
return true
|
||||
case ':':
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func newOpToken(b []rune) (Token, int, error) {
|
||||
tok := Token{}
|
||||
|
||||
switch b[0] {
|
||||
case '=':
|
||||
tok = newToken(TokenOp, equalOp, NoneType)
|
||||
case ':':
|
||||
tok = newToken(TokenOp, equalColonOp, NoneType)
|
||||
default:
|
||||
return tok, 0, NewParseError(fmt.Sprintf("unexpected op type, %v", b[0]))
|
||||
}
|
||||
return tok, 1, nil
|
||||
}
|
43
vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go
generated
vendored
Normal file
43
vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go
generated
vendored
Normal file
|
@ -0,0 +1,43 @@
|
|||
package ini
|
||||
|
||||
import "fmt"
|
||||
|
||||
const (
|
||||
// ErrCodeParseError is returned when a parsing error
|
||||
// has occurred.
|
||||
ErrCodeParseError = "INIParseError"
|
||||
)
|
||||
|
||||
// ParseError is an error which is returned during any part of
|
||||
// the parsing process.
|
||||
type ParseError struct {
|
||||
msg string
|
||||
}
|
||||
|
||||
// NewParseError will return a new ParseError where message
|
||||
// is the description of the error.
|
||||
func NewParseError(message string) *ParseError {
|
||||
return &ParseError{
|
||||
msg: message,
|
||||
}
|
||||
}
|
||||
|
||||
// Code will return the ErrCodeParseError
|
||||
func (err *ParseError) Code() string {
|
||||
return ErrCodeParseError
|
||||
}
|
||||
|
||||
// Message returns the error's message
|
||||
func (err *ParseError) Message() string {
|
||||
return err.msg
|
||||
}
|
||||
|
||||
// OrigError return nothing since there will never be any
|
||||
// original error.
|
||||
func (err *ParseError) OrigError() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (err *ParseError) Error() string {
|
||||
return fmt.Sprintf("%s: %s", err.Code(), err.Message())
|
||||
}
|
60
vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go
generated
vendored
Normal file
60
vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ParseStack is a stack that contains a container, the stack portion,
|
||||
// and the list which is the list of ASTs that have been successfully
|
||||
// parsed.
|
||||
type ParseStack struct {
|
||||
top int
|
||||
container []AST
|
||||
list []AST
|
||||
index int
|
||||
}
|
||||
|
||||
func newParseStack(sizeContainer, sizeList int) ParseStack {
|
||||
return ParseStack{
|
||||
container: make([]AST, sizeContainer),
|
||||
list: make([]AST, sizeList),
|
||||
}
|
||||
}
|
||||
|
||||
// Pop will return and truncate the last container element.
|
||||
func (s *ParseStack) Pop() AST {
|
||||
s.top--
|
||||
return s.container[s.top]
|
||||
}
|
||||
|
||||
// Push will add the new AST to the container
|
||||
func (s *ParseStack) Push(ast AST) {
|
||||
s.container[s.top] = ast
|
||||
s.top++
|
||||
}
|
||||
|
||||
// MarkComplete will append the AST to the list of completed statements
|
||||
func (s *ParseStack) MarkComplete(ast AST) {
|
||||
s.list[s.index] = ast
|
||||
s.index++
|
||||
}
|
||||
|
||||
// List will return the completed statements
|
||||
func (s ParseStack) List() []AST {
|
||||
return s.list[:s.index]
|
||||
}
|
||||
|
||||
// Len will return the length of the container
|
||||
func (s *ParseStack) Len() int {
|
||||
return s.top
|
||||
}
|
||||
|
||||
func (s ParseStack) String() string {
|
||||
buf := bytes.Buffer{}
|
||||
for i, node := range s.list {
|
||||
buf.WriteString(fmt.Sprintf("%d: %v\n", i+1, node))
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
41
vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go
generated
vendored
Normal file
41
vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
emptyRunes = []rune{}
|
||||
)
|
||||
|
||||
func isSep(b []rune) bool {
|
||||
if len(b) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
switch b[0] {
|
||||
case '[', ']':
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
openBrace = []rune("[")
|
||||
closeBrace = []rune("]")
|
||||
)
|
||||
|
||||
func newSepToken(b []rune) (Token, int, error) {
|
||||
tok := Token{}
|
||||
|
||||
switch b[0] {
|
||||
case '[':
|
||||
tok = newToken(TokenSep, openBrace, NoneType)
|
||||
case ']':
|
||||
tok = newToken(TokenSep, closeBrace, NoneType)
|
||||
default:
|
||||
return tok, 0, NewParseError(fmt.Sprintf("unexpected sep type, %v", b[0]))
|
||||
}
|
||||
return tok, 1, nil
|
||||
}
|
45
vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go
generated
vendored
Normal file
45
vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
package ini
|
||||
|
||||
// skipper is used to skip certain blocks of an ini file.
|
||||
// Currently skipper is used to skip nested blocks of ini
|
||||
// files. See example below
|
||||
//
|
||||
// [ foo ]
|
||||
// nested = ; this section will be skipped
|
||||
// a=b
|
||||
// c=d
|
||||
// bar=baz ; this will be included
|
||||
type skipper struct {
|
||||
shouldSkip bool
|
||||
TokenSet bool
|
||||
prevTok Token
|
||||
}
|
||||
|
||||
func newSkipper() skipper {
|
||||
return skipper{
|
||||
prevTok: emptyToken,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *skipper) ShouldSkip(tok Token) bool {
|
||||
// should skip state will be modified only if previous token was new line (NL);
|
||||
// and the current token is not WhiteSpace (WS).
|
||||
if s.shouldSkip &&
|
||||
s.prevTok.Type() == TokenNL &&
|
||||
tok.Type() != TokenWS {
|
||||
s.Continue()
|
||||
return false
|
||||
}
|
||||
s.prevTok = tok
|
||||
return s.shouldSkip
|
||||
}
|
||||
|
||||
func (s *skipper) Skip() {
|
||||
s.shouldSkip = true
|
||||
}
|
||||
|
||||
func (s *skipper) Continue() {
|
||||
s.shouldSkip = false
|
||||
// empty token is assigned as we return to default state, when should skip is false
|
||||
s.prevTok = emptyToken
|
||||
}
|
35
vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go
generated
vendored
Normal file
35
vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
package ini
|
||||
|
||||
// Statement is an empty AST mostly used for transitioning states.
|
||||
func newStatement() AST {
|
||||
return newAST(ASTKindStatement, AST{})
|
||||
}
|
||||
|
||||
// SectionStatement represents a section AST
|
||||
func newSectionStatement(tok Token) AST {
|
||||
return newASTWithRootToken(ASTKindSectionStatement, tok)
|
||||
}
|
||||
|
||||
// ExprStatement represents a completed expression AST
|
||||
func newExprStatement(ast AST) AST {
|
||||
return newAST(ASTKindExprStatement, ast)
|
||||
}
|
||||
|
||||
// CommentStatement represents a comment in the ini definition.
|
||||
//
|
||||
// grammar:
|
||||
// comment -> #comment' | ;comment'
|
||||
// comment' -> epsilon | value
|
||||
func newCommentStatement(tok Token) AST {
|
||||
return newAST(ASTKindCommentStatement, newExpression(tok))
|
||||
}
|
||||
|
||||
// CompletedSectionStatement represents a completed section
|
||||
func newCompletedSectionStatement(ast AST) AST {
|
||||
return newAST(ASTKindCompletedSectionStatement, ast)
|
||||
}
|
||||
|
||||
// SkipStatement is used to skip whole statements
|
||||
func newSkipStatement(ast AST) AST {
|
||||
return newAST(ASTKindSkipStatement, ast)
|
||||
}
|
284
vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go
generated
vendored
Normal file
284
vendor/github.com/aws/aws-sdk-go/internal/ini/value_util.go
generated
vendored
Normal file
|
@ -0,0 +1,284 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// getStringValue will return a quoted string and the amount
|
||||
// of bytes read
|
||||
//
|
||||
// an error will be returned if the string is not properly formatted
|
||||
func getStringValue(b []rune) (int, error) {
|
||||
if b[0] != '"' {
|
||||
return 0, NewParseError("strings must start with '\"'")
|
||||
}
|
||||
|
||||
endQuote := false
|
||||
i := 1
|
||||
|
||||
for ; i < len(b) && !endQuote; i++ {
|
||||
if escaped := isEscaped(b[:i], b[i]); b[i] == '"' && !escaped {
|
||||
endQuote = true
|
||||
break
|
||||
} else if escaped {
|
||||
/*c, err := getEscapedByte(b[i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
b[i-1] = c
|
||||
b = append(b[:i], b[i+1:]...)
|
||||
i--*/
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if !endQuote {
|
||||
return 0, NewParseError("missing '\"' in string value")
|
||||
}
|
||||
|
||||
return i + 1, nil
|
||||
}
|
||||
|
||||
// getBoolValue will return a boolean and the amount
|
||||
// of bytes read
|
||||
//
|
||||
// an error will be returned if the boolean is not of a correct
|
||||
// value
|
||||
func getBoolValue(b []rune) (int, error) {
|
||||
if len(b) < 4 {
|
||||
return 0, NewParseError("invalid boolean value")
|
||||
}
|
||||
|
||||
n := 0
|
||||
for _, lv := range literalValues {
|
||||
if len(lv) > len(b) {
|
||||
continue
|
||||
}
|
||||
|
||||
if isLitValue(lv, b) {
|
||||
n = len(lv)
|
||||
}
|
||||
}
|
||||
|
||||
if n == 0 {
|
||||
return 0, NewParseError("invalid boolean value")
|
||||
}
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// getNumericalValue will return a numerical string, the amount
|
||||
// of bytes read, and the base of the number
|
||||
//
|
||||
// an error will be returned if the number is not of a correct
|
||||
// value
|
||||
func getNumericalValue(b []rune) (int, int, error) {
|
||||
if !isDigit(b[0]) {
|
||||
return 0, 0, NewParseError("invalid digit value")
|
||||
}
|
||||
|
||||
i := 0
|
||||
helper := numberHelper{}
|
||||
|
||||
loop:
|
||||
for negativeIndex := 0; i < len(b); i++ {
|
||||
negativeIndex++
|
||||
|
||||
if !isDigit(b[i]) {
|
||||
switch b[i] {
|
||||
case '-':
|
||||
if helper.IsNegative() || negativeIndex != 1 {
|
||||
return 0, 0, NewParseError("parse error '-'")
|
||||
}
|
||||
|
||||
n := getNegativeNumber(b[i:])
|
||||
i += (n - 1)
|
||||
helper.Determine(b[i])
|
||||
continue
|
||||
case '.':
|
||||
if err := helper.Determine(b[i]); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
case 'e', 'E':
|
||||
if err := helper.Determine(b[i]); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
negativeIndex = 0
|
||||
case 'b':
|
||||
if helper.numberFormat == hex {
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
case 'o', 'x':
|
||||
if i == 0 && b[i] != '0' {
|
||||
return 0, 0, NewParseError("incorrect base format, expected leading '0'")
|
||||
}
|
||||
|
||||
if i != 1 {
|
||||
return 0, 0, NewParseError(fmt.Sprintf("incorrect base format found %s at %d index", string(b[i]), i))
|
||||
}
|
||||
|
||||
if err := helper.Determine(b[i]); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
default:
|
||||
if isWhitespace(b[i]) {
|
||||
break loop
|
||||
}
|
||||
|
||||
if isNewline(b[i:]) {
|
||||
break loop
|
||||
}
|
||||
|
||||
if !(helper.numberFormat == hex && isHexByte(b[i])) {
|
||||
if i+2 < len(b) && !isNewline(b[i:i+2]) {
|
||||
return 0, 0, NewParseError("invalid numerical character")
|
||||
} else if !isNewline([]rune{b[i]}) {
|
||||
return 0, 0, NewParseError("invalid numerical character")
|
||||
}
|
||||
|
||||
break loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return helper.Base(), i, nil
|
||||
}
|
||||
|
||||
// isDigit will return whether or not something is an integer
|
||||
func isDigit(b rune) bool {
|
||||
return b >= '0' && b <= '9'
|
||||
}
|
||||
|
||||
func hasExponent(v []rune) bool {
|
||||
return contains(v, 'e') || contains(v, 'E')
|
||||
}
|
||||
|
||||
func isBinaryByte(b rune) bool {
|
||||
switch b {
|
||||
case '0', '1':
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isOctalByte(b rune) bool {
|
||||
switch b {
|
||||
case '0', '1', '2', '3', '4', '5', '6', '7':
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func isHexByte(b rune) bool {
|
||||
if isDigit(b) {
|
||||
return true
|
||||
}
|
||||
return (b >= 'A' && b <= 'F') ||
|
||||
(b >= 'a' && b <= 'f')
|
||||
}
|
||||
|
||||
func getValue(b []rune) (int, error) {
|
||||
i := 0
|
||||
|
||||
for i < len(b) {
|
||||
if isNewline(b[i:]) {
|
||||
break
|
||||
}
|
||||
|
||||
if isOp(b[i:]) {
|
||||
break
|
||||
}
|
||||
|
||||
valid, n, err := isValid(b[i:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !valid {
|
||||
break
|
||||
}
|
||||
|
||||
i += n
|
||||
}
|
||||
|
||||
return i, nil
|
||||
}
|
||||
|
||||
// getNegativeNumber will return a negative number from a
|
||||
// byte slice. This will iterate through all characters until
|
||||
// a non-digit has been found.
|
||||
func getNegativeNumber(b []rune) int {
|
||||
if b[0] != '-' {
|
||||
return 0
|
||||
}
|
||||
|
||||
i := 1
|
||||
for ; i < len(b); i++ {
|
||||
if !isDigit(b[i]) {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
// isEscaped will return whether or not the character is an escaped
|
||||
// character.
|
||||
func isEscaped(value []rune, b rune) bool {
|
||||
if len(value) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
switch b {
|
||||
case '\'': // single quote
|
||||
case '"': // quote
|
||||
case 'n': // newline
|
||||
case 't': // tab
|
||||
case '\\': // backslash
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
return value[len(value)-1] == '\\'
|
||||
}
|
||||
|
||||
func getEscapedByte(b rune) (rune, error) {
|
||||
switch b {
|
||||
case '\'': // single quote
|
||||
return '\'', nil
|
||||
case '"': // quote
|
||||
return '"', nil
|
||||
case 'n': // newline
|
||||
return '\n', nil
|
||||
case 't': // table
|
||||
return '\t', nil
|
||||
case '\\': // backslash
|
||||
return '\\', nil
|
||||
default:
|
||||
return b, NewParseError(fmt.Sprintf("invalid escaped character %c", b))
|
||||
}
|
||||
}
|
||||
|
||||
func removeEscapedCharacters(b []rune) []rune {
|
||||
for i := 0; i < len(b); i++ {
|
||||
if isEscaped(b[:i], b[i]) {
|
||||
c, err := getEscapedByte(b[i])
|
||||
if err != nil {
|
||||
return b
|
||||
}
|
||||
|
||||
b[i-1] = c
|
||||
b = append(b[:i], b[i+1:]...)
|
||||
i--
|
||||
}
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
166
vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go
generated
vendored
Normal file
166
vendor/github.com/aws/aws-sdk-go/internal/ini/visitor.go
generated
vendored
Normal file
|
@ -0,0 +1,166 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Visitor is an interface used by walkers that will
|
||||
// traverse an array of ASTs.
|
||||
type Visitor interface {
|
||||
VisitExpr(AST) error
|
||||
VisitStatement(AST) error
|
||||
}
|
||||
|
||||
// DefaultVisitor is used to visit statements and expressions
|
||||
// and ensure that they are both of the correct format.
|
||||
// In addition, upon visiting this will build sections and populate
|
||||
// the Sections field which can be used to retrieve profile
|
||||
// configuration.
|
||||
type DefaultVisitor struct {
|
||||
scope string
|
||||
Sections Sections
|
||||
}
|
||||
|
||||
// NewDefaultVisitor return a DefaultVisitor
|
||||
func NewDefaultVisitor() *DefaultVisitor {
|
||||
return &DefaultVisitor{
|
||||
Sections: Sections{
|
||||
container: map[string]Section{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// VisitExpr visits expressions...
|
||||
func (v *DefaultVisitor) VisitExpr(expr AST) error {
|
||||
t := v.Sections.container[v.scope]
|
||||
if t.values == nil {
|
||||
t.values = values{}
|
||||
}
|
||||
|
||||
switch expr.Kind {
|
||||
case ASTKindExprStatement:
|
||||
opExpr := expr.GetRoot()
|
||||
switch opExpr.Kind {
|
||||
case ASTKindEqualExpr:
|
||||
children := opExpr.GetChildren()
|
||||
if len(children) <= 1 {
|
||||
return NewParseError("unexpected token type")
|
||||
}
|
||||
|
||||
rhs := children[1]
|
||||
|
||||
if rhs.Root.Type() != TokenLit {
|
||||
return NewParseError("unexpected token type")
|
||||
}
|
||||
|
||||
key := EqualExprKey(opExpr)
|
||||
v, err := newValue(rhs.Root.ValueType, rhs.Root.base, rhs.Root.Raw())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.values[key] = v
|
||||
default:
|
||||
return NewParseError(fmt.Sprintf("unsupported expression %v", expr))
|
||||
}
|
||||
default:
|
||||
return NewParseError(fmt.Sprintf("unsupported expression %v", expr))
|
||||
}
|
||||
|
||||
v.Sections.container[v.scope] = t
|
||||
return nil
|
||||
}
|
||||
|
||||
// VisitStatement visits statements...
|
||||
func (v *DefaultVisitor) VisitStatement(stmt AST) error {
|
||||
switch stmt.Kind {
|
||||
case ASTKindCompletedSectionStatement:
|
||||
child := stmt.GetRoot()
|
||||
if child.Kind != ASTKindSectionStatement {
|
||||
return NewParseError(fmt.Sprintf("unsupported child statement: %T", child))
|
||||
}
|
||||
|
||||
name := string(child.Root.Raw())
|
||||
v.Sections.container[name] = Section{}
|
||||
v.scope = name
|
||||
default:
|
||||
return NewParseError(fmt.Sprintf("unsupported statement: %s", stmt.Kind))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sections is a map of Section structures that represent
|
||||
// a configuration.
|
||||
type Sections struct {
|
||||
container map[string]Section
|
||||
}
|
||||
|
||||
// GetSection will return section p. If section p does not exist,
|
||||
// false will be returned in the second parameter.
|
||||
func (t Sections) GetSection(p string) (Section, bool) {
|
||||
v, ok := t.container[p]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
// values represents a map of union values.
|
||||
type values map[string]Value
|
||||
|
||||
// List will return a list of all sections that were successfully
|
||||
// parsed.
|
||||
func (t Sections) List() []string {
|
||||
keys := make([]string, len(t.container))
|
||||
i := 0
|
||||
for k := range t.container {
|
||||
keys[i] = k
|
||||
i++
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
// Section contains a name and values. This represent
|
||||
// a sectioned entry in a configuration file.
|
||||
type Section struct {
|
||||
Name string
|
||||
values values
|
||||
}
|
||||
|
||||
// Has will return whether or not an entry exists in a given section
|
||||
func (t Section) Has(k string) bool {
|
||||
_, ok := t.values[k]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ValueType will returned what type the union is set to. If
|
||||
// k was not found, the NoneType will be returned.
|
||||
func (t Section) ValueType(k string) (ValueType, bool) {
|
||||
v, ok := t.values[k]
|
||||
return v.Type, ok
|
||||
}
|
||||
|
||||
// Bool returns a bool value at k
|
||||
func (t Section) Bool(k string) bool {
|
||||
return t.values[k].BoolValue()
|
||||
}
|
||||
|
||||
// Int returns an integer value at k
|
||||
func (t Section) Int(k string) int64 {
|
||||
return t.values[k].IntValue()
|
||||
}
|
||||
|
||||
// Float64 returns a float value at k
|
||||
func (t Section) Float64(k string) float64 {
|
||||
return t.values[k].FloatValue()
|
||||
}
|
||||
|
||||
// String returns the string value at k
|
||||
func (t Section) String(k string) string {
|
||||
_, ok := t.values[k]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return t.values[k].StringValue()
|
||||
}
|
25
vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go
generated
vendored
Normal file
25
vendor/github.com/aws/aws-sdk-go/internal/ini/walker.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
package ini
|
||||
|
||||
// Walk will traverse the AST using the v, the Visitor.
|
||||
func Walk(tree []AST, v Visitor) error {
|
||||
for _, node := range tree {
|
||||
switch node.Kind {
|
||||
case ASTKindExpr,
|
||||
ASTKindExprStatement:
|
||||
|
||||
if err := v.VisitExpr(node); err != nil {
|
||||
return err
|
||||
}
|
||||
case ASTKindStatement,
|
||||
ASTKindCompletedSectionStatement,
|
||||
ASTKindNestedSectionStatement,
|
||||
ASTKindCompletedNestedSectionStatement:
|
||||
|
||||
if err := v.VisitStatement(node); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
24
vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go
generated
vendored
Normal file
24
vendor/github.com/aws/aws-sdk-go/internal/ini/ws_token.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
package ini
|
||||
|
||||
import (
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// isWhitespace will return whether or not the character is
|
||||
// a whitespace character.
|
||||
//
|
||||
// Whitespace is defined as a space or tab.
|
||||
func isWhitespace(c rune) bool {
|
||||
return unicode.IsSpace(c) && c != '\n' && c != '\r'
|
||||
}
|
||||
|
||||
func newWSToken(b []rune) (Token, int, error) {
|
||||
i := 0
|
||||
for ; i < len(b); i++ {
|
||||
if !isWhitespace(b[i]) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return newToken(TokenWS, b[:i], NoneType), i, nil
|
||||
}
|
12
vendor/github.com/aws/aws-sdk-go/internal/sdkio/byte.go
generated
vendored
Normal file
12
vendor/github.com/aws/aws-sdk-go/internal/sdkio/byte.go
generated
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
package sdkio
|
||||
|
||||
const (
|
||||
// Byte is 8 bits
|
||||
Byte int64 = 1
|
||||
// KibiByte (KiB) is 1024 Bytes
|
||||
KibiByte = Byte * 1024
|
||||
// MebiByte (MiB) is 1024 KiB
|
||||
MebiByte = KibiByte * 1024
|
||||
// GibiByte (GiB) is 1024 MiB
|
||||
GibiByte = MebiByte * 1024
|
||||
)
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue