mirror of
https://github.com/thegeeklab/wp-s3-action.git
synced 2024-11-24 14:00:40 +00:00
Updated AWS SDK to latest version
This commit is contained in:
parent
471f743e20
commit
45c5bf6b6f
39
vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go
generated
vendored
39
vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go
generated
vendored
@ -42,9 +42,12 @@ type Error interface {
|
|||||||
OrigErr() error
|
OrigErr() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// BatchError is a batch of errors which also wraps lower level errors with code, message,
|
// BatchError is a batch of errors which also wraps lower level errors with
|
||||||
// and original errors. Calling Error() will only return the error that is at the end
|
// code, message, and original errors. Calling Error() will include all errors
|
||||||
// of the list.
|
// that occurred in the batch.
|
||||||
|
//
|
||||||
|
// Deprecated: Replaced with BatchedErrors. Only defined for backwards
|
||||||
|
// compatibility.
|
||||||
type BatchError interface {
|
type BatchError interface {
|
||||||
// Satisfy the generic error interface.
|
// Satisfy the generic error interface.
|
||||||
error
|
error
|
||||||
@ -59,17 +62,35 @@ type BatchError interface {
|
|||||||
OrigErrs() []error
|
OrigErrs() []error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BatchedErrors is a batch of errors which also wraps lower level errors with
|
||||||
|
// code, message, and original errors. Calling Error() will include all errors
|
||||||
|
// that occurred in the batch.
|
||||||
|
//
|
||||||
|
// Replaces BatchError
|
||||||
|
type BatchedErrors interface {
|
||||||
|
// Satisfy the base Error interface.
|
||||||
|
Error
|
||||||
|
|
||||||
|
// Returns the original error if one was set. Nil is returned if not set.
|
||||||
|
OrigErrs() []error
|
||||||
|
}
|
||||||
|
|
||||||
// New returns an Error object described by the code, message, and origErr.
|
// New returns an Error object described by the code, message, and origErr.
|
||||||
//
|
//
|
||||||
// If origErr satisfies the Error interface it will not be wrapped within a new
|
// If origErr satisfies the Error interface it will not be wrapped within a new
|
||||||
// Error object and will instead be returned.
|
// Error object and will instead be returned.
|
||||||
func New(code, message string, origErr error) Error {
|
func New(code, message string, origErr error) Error {
|
||||||
return newBaseError(code, message, origErr)
|
var errs []error
|
||||||
|
if origErr != nil {
|
||||||
|
errs = append(errs, origErr)
|
||||||
|
}
|
||||||
|
return newBaseError(code, message, errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBatchError returns an baseError with an expectation of an array of errors
|
// NewBatchError returns an BatchedErrors with a collection of errors as an
|
||||||
func NewBatchError(code, message string, errs []error) BatchError {
|
// array of errors.
|
||||||
return newBaseErrors(code, message, errs)
|
func NewBatchError(code, message string, errs []error) BatchedErrors {
|
||||||
|
return newBaseError(code, message, errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A RequestFailure is an interface to extract request failure information from
|
// A RequestFailure is an interface to extract request failure information from
|
||||||
@ -82,9 +103,9 @@ func NewBatchError(code, message string, errs []error) BatchError {
|
|||||||
// output, err := s3manage.Upload(svc, input, opts)
|
// output, err := s3manage.Upload(svc, input, opts)
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// if reqerr, ok := err.(RequestFailure); ok {
|
// if reqerr, ok := err.(RequestFailure); ok {
|
||||||
// log.Printf("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID())
|
// log.Println("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID())
|
||||||
// } else {
|
// } else {
|
||||||
// log.Printf("Error:", err.Error()
|
// log.Println("Error:", err.Error())
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
69
vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go
generated
vendored
69
vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go
generated
vendored
@ -34,36 +34,17 @@ type baseError struct {
|
|||||||
errs []error
|
errs []error
|
||||||
}
|
}
|
||||||
|
|
||||||
// newBaseError returns an error object for the code, message, and err.
|
// newBaseError returns an error object for the code, message, and errors.
|
||||||
//
|
//
|
||||||
// code is a short no whitespace phrase depicting the classification of
|
// code is a short no whitespace phrase depicting the classification of
|
||||||
// the error that is being created.
|
// the error that is being created.
|
||||||
//
|
//
|
||||||
// message is the free flow string containing detailed information about the error.
|
// message is the free flow string containing detailed information about the
|
||||||
|
// error.
|
||||||
//
|
//
|
||||||
// origErr is the error object which will be nested under the new error to be returned.
|
// origErrs is the error objects which will be nested under the new errors to
|
||||||
func newBaseError(code, message string, origErr error) *baseError {
|
// be returned.
|
||||||
b := &baseError{
|
func newBaseError(code, message string, origErrs []error) *baseError {
|
||||||
code: code,
|
|
||||||
message: message,
|
|
||||||
}
|
|
||||||
|
|
||||||
if origErr != nil {
|
|
||||||
b.errs = append(b.errs, origErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// newBaseErrors returns an error object for the code, message, and errors.
|
|
||||||
//
|
|
||||||
// code is a short no whitespace phrase depicting the classification of
|
|
||||||
// the error that is being created.
|
|
||||||
//
|
|
||||||
// message is the free flow string containing detailed information about the error.
|
|
||||||
//
|
|
||||||
// origErrs is the error objects which will be nested under the new errors to be returned.
|
|
||||||
func newBaseErrors(code, message string, origErrs []error) *baseError {
|
|
||||||
b := &baseError{
|
b := &baseError{
|
||||||
code: code,
|
code: code,
|
||||||
message: message,
|
message: message,
|
||||||
@ -103,19 +84,26 @@ func (b baseError) Message() string {
|
|||||||
return b.message
|
return b.message
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrigErr returns the original error if one was set. Nil is returned if no error
|
// OrigErr returns the original error if one was set. Nil is returned if no
|
||||||
// was set. This only returns the first element in the list. If the full list is
|
// error was set. This only returns the first element in the list. If the full
|
||||||
// needed, use BatchError
|
// list is needed, use BatchedErrors.
|
||||||
func (b baseError) OrigErr() error {
|
func (b baseError) OrigErr() error {
|
||||||
if size := len(b.errs); size > 0 {
|
switch len(b.errs) {
|
||||||
return b.errs[0]
|
case 0:
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
case 1:
|
||||||
|
return b.errs[0]
|
||||||
|
default:
|
||||||
|
if err, ok := b.errs[0].(Error); ok {
|
||||||
|
return NewBatchError(err.Code(), err.Message(), b.errs[1:])
|
||||||
|
}
|
||||||
|
return NewBatchError("BatchedErrors",
|
||||||
|
"multiple errors occurred", b.errs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrigErrs returns the original errors if one was set. An empty slice is returned if
|
// OrigErrs returns the original errors if one was set. An empty slice is
|
||||||
// no error was set:w
|
// returned if no error was set.
|
||||||
func (b baseError) OrigErrs() []error {
|
func (b baseError) OrigErrs() []error {
|
||||||
return b.errs
|
return b.errs
|
||||||
}
|
}
|
||||||
@ -133,8 +121,8 @@ type requestError struct {
|
|||||||
requestID string
|
requestID string
|
||||||
}
|
}
|
||||||
|
|
||||||
// newRequestError returns a wrapped error with additional information for request
|
// newRequestError returns a wrapped error with additional information for
|
||||||
// status code, and service requestID.
|
// request status code, and service requestID.
|
||||||
//
|
//
|
||||||
// Should be used to wrap all request which involve service requests. Even if
|
// 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
|
// the request failed without a service response, but had an HTTP status code
|
||||||
@ -173,6 +161,15 @@ func (r requestError) RequestID() string {
|
|||||||
return r.requestID
|
return r.requestID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OrigErrs returns the original errors if one was set. An empty slice is
|
||||||
|
// returned if no error was set.
|
||||||
|
func (r requestError) OrigErrs() []error {
|
||||||
|
if b, ok := r.awsError.(BatchedErrors); ok {
|
||||||
|
return b.OrigErrs()
|
||||||
|
}
|
||||||
|
return []error{r.OrigErr()}
|
||||||
|
}
|
||||||
|
|
||||||
// An error list that satisfies the golang interface
|
// An error list that satisfies the golang interface
|
||||||
type errorList []error
|
type errorList []error
|
||||||
|
|
||||||
|
8
vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
generated
vendored
8
vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
generated
vendored
@ -3,6 +3,7 @@ package awsutil
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Copy deeply copies a src structure to dst. Useful for copying request and
|
// Copy deeply copies a src structure to dst. Useful for copying request and
|
||||||
@ -49,7 +50,14 @@ func rcopy(dst, src reflect.Value, root bool) {
|
|||||||
} else {
|
} else {
|
||||||
e := src.Type().Elem()
|
e := src.Type().Elem()
|
||||||
if dst.CanSet() && !src.IsNil() {
|
if dst.CanSet() && !src.IsNil() {
|
||||||
|
if _, ok := src.Interface().(*time.Time); !ok {
|
||||||
dst.Set(reflect.New(e))
|
dst.Set(reflect.New(e))
|
||||||
|
} else {
|
||||||
|
tempValue := reflect.New(e)
|
||||||
|
tempValue.Elem().Set(src.Elem())
|
||||||
|
// Sets time.Time's unexported values
|
||||||
|
dst.Set(tempValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if src.Elem().IsValid() {
|
if src.Elem().IsValid() {
|
||||||
// Keep the current root state since the depth hasn't changed
|
// Keep the current root state since the depth hasn't changed
|
||||||
|
4
vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
@ -106,8 +106,8 @@ func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTer
|
|||||||
|
|
||||||
if indexStar || index != nil {
|
if indexStar || index != nil {
|
||||||
nextvals = []reflect.Value{}
|
nextvals = []reflect.Value{}
|
||||||
for _, value := range values {
|
for _, valItem := range values {
|
||||||
value := reflect.Indirect(value)
|
value := reflect.Indirect(valItem)
|
||||||
if value.Kind() != reflect.Slice {
|
if value.Kind() != reflect.Slice {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
10
vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go
generated
vendored
10
vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go
generated
vendored
@ -61,6 +61,12 @@ func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
|
|||||||
|
|
||||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
|
strtype := v.Type().String()
|
||||||
|
if strtype == "[]uint8" {
|
||||||
|
fmt.Fprintf(buf, "<binary> len %d", v.Len())
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
nl, id, id2 := "", "", ""
|
nl, id, id2 := "", "", ""
|
||||||
if v.Len() > 3 {
|
if v.Len() > 3 {
|
||||||
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
|
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
|
||||||
@ -91,6 +97,10 @@ func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
|
|||||||
|
|
||||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
||||||
default:
|
default:
|
||||||
|
if !v.IsValid() {
|
||||||
|
fmt.Fprint(buf, "<invalid value>")
|
||||||
|
return
|
||||||
|
}
|
||||||
format := "%v"
|
format := "%v"
|
||||||
switch v.Interface().(type) {
|
switch v.Interface().(type) {
|
||||||
case string:
|
case string:
|
||||||
|
56
vendor/github.com/aws/aws-sdk-go/aws/client/client.go
generated
vendored
56
vendor/github.com/aws/aws-sdk-go/aws/client/client.go
generated
vendored
@ -2,8 +2,6 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"net/http/httputil"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||||
@ -14,7 +12,9 @@ import (
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Config *aws.Config
|
Config *aws.Config
|
||||||
Handlers request.Handlers
|
Handlers request.Handlers
|
||||||
Endpoint, SigningRegion string
|
Endpoint string
|
||||||
|
SigningRegion string
|
||||||
|
SigningName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigProvider provides a generic way for a service client to receive
|
// ConfigProvider provides a generic way for a service client to receive
|
||||||
@ -23,6 +23,13 @@ type ConfigProvider interface {
|
|||||||
ClientConfig(serviceName string, cfgs ...*aws.Config) Config
|
ClientConfig(serviceName string, cfgs ...*aws.Config) Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfigNoResolveEndpointProvider same as ConfigProvider except it will not
|
||||||
|
// resolve the endpoint automatically. The service client's endpoint must be
|
||||||
|
// provided via the aws.Config.Endpoint field.
|
||||||
|
type ConfigNoResolveEndpointProvider interface {
|
||||||
|
ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) Config
|
||||||
|
}
|
||||||
|
|
||||||
// A Client implements the base client request and response handling
|
// A Client implements the base client request and response handling
|
||||||
// used by all service clients.
|
// used by all service clients.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
@ -38,7 +45,7 @@ func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, op
|
|||||||
svc := &Client{
|
svc := &Client{
|
||||||
Config: cfg,
|
Config: cfg,
|
||||||
ClientInfo: info,
|
ClientInfo: info,
|
||||||
Handlers: handlers,
|
Handlers: handlers.Copy(),
|
||||||
}
|
}
|
||||||
|
|
||||||
switch retryer, ok := cfg.Retryer.(request.Retryer); {
|
switch retryer, ok := cfg.Retryer.(request.Retryer); {
|
||||||
@ -78,43 +85,6 @@ func (c *Client) AddDebugHandlers() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Handlers.Send.PushFront(logRequest)
|
c.Handlers.Send.PushFrontNamed(request.NamedHandler{Name: "awssdk.client.LogRequest", Fn: logRequest})
|
||||||
c.Handlers.Send.PushBack(logResponse)
|
c.Handlers.Send.PushBackNamed(request.NamedHandler{Name: "awssdk.client.LogResponse", Fn: logResponse})
|
||||||
}
|
|
||||||
|
|
||||||
const logReqMsg = `DEBUG: Request %s/%s Details:
|
|
||||||
---[ REQUEST POST-SIGN ]-----------------------------
|
|
||||||
%s
|
|
||||||
-----------------------------------------------------`
|
|
||||||
|
|
||||||
func logRequest(r *request.Request) {
|
|
||||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
|
||||||
dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody)
|
|
||||||
|
|
||||||
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.Body.Seek(r.BodyStart, 0)
|
|
||||||
r.HTTPRequest.Body = ioutil.NopCloser(r.Body)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody)))
|
|
||||||
}
|
|
||||||
|
|
||||||
const logRespMsg = `DEBUG: Response %s/%s Details:
|
|
||||||
---[ RESPONSE ]--------------------------------------
|
|
||||||
%s
|
|
||||||
-----------------------------------------------------`
|
|
||||||
|
|
||||||
func logResponse(r *request.Request) {
|
|
||||||
var msg = "no response data"
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
|
||||||
dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody)
|
|
||||||
msg = string(dumpedBody)
|
|
||||||
} else if r.Error != nil {
|
|
||||||
msg = r.Error.Error()
|
|
||||||
}
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logRespMsg, r.ClientInfo.ServiceName, r.Operation.Name, msg))
|
|
||||||
}
|
}
|
||||||
|
63
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
63
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
@ -1,8 +1,8 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
@ -15,11 +15,11 @@ import (
|
|||||||
// the MaxRetries method:
|
// the MaxRetries method:
|
||||||
//
|
//
|
||||||
// type retryer struct {
|
// type retryer struct {
|
||||||
// service.DefaultRetryer
|
// client.DefaultRetryer
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// // This implementation always has 100 max retries
|
// // This implementation always has 100 max retries
|
||||||
// func (d retryer) MaxRetries() uint { return 100 }
|
// func (d retryer) MaxRetries() int { return 100 }
|
||||||
type DefaultRetryer struct {
|
type DefaultRetryer struct {
|
||||||
NumMaxRetries int
|
NumMaxRetries int
|
||||||
}
|
}
|
||||||
@ -30,16 +30,67 @@ func (d DefaultRetryer) MaxRetries() int {
|
|||||||
return d.NumMaxRetries
|
return d.NumMaxRetries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var seededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())})
|
||||||
|
|
||||||
// RetryRules returns the delay duration before retrying this request again
|
// RetryRules returns the delay duration before retrying this request again
|
||||||
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
|
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
|
||||||
delay := int(math.Pow(2, float64(r.RetryCount))) * (rand.Intn(30) + 30)
|
// Set the upper limit of delay in retrying at ~five minutes
|
||||||
|
minTime := 30
|
||||||
|
throttle := d.shouldThrottle(r)
|
||||||
|
if throttle {
|
||||||
|
minTime = 500
|
||||||
|
}
|
||||||
|
|
||||||
|
retryCount := r.RetryCount
|
||||||
|
if retryCount > 13 {
|
||||||
|
retryCount = 13
|
||||||
|
} else if throttle && retryCount > 8 {
|
||||||
|
retryCount = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime)
|
||||||
return time.Duration(delay) * time.Millisecond
|
return time.Duration(delay) * time.Millisecond
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShouldRetry returns if the request should be retried.
|
// ShouldRetry returns true if the request should be retried.
|
||||||
func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
|
func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
|
||||||
|
// 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 {
|
if r.HTTPResponse.StatusCode >= 500 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return r.IsErrorRetryable()
|
return r.IsErrorRetryable() || d.shouldThrottle(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldThrottle returns true if the request should be throttled.
|
||||||
|
func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
|
||||||
|
if r.HTTPResponse.StatusCode == 502 ||
|
||||||
|
r.HTTPResponse.StatusCode == 503 ||
|
||||||
|
r.HTTPResponse.StatusCode == 504 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return r.IsErrorThrottle()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()
|
||||||
}
|
}
|
||||||
|
108
vendor/github.com/aws/aws-sdk-go/aws/client/logger.go
generated
vendored
Normal file
108
vendor/github.com/aws/aws-sdk-go/aws/client/logger.go
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http/httputil"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
const logReqMsg = `DEBUG: Request %s/%s Details:
|
||||||
|
---[ REQUEST POST-SIGN ]-----------------------------
|
||||||
|
%s
|
||||||
|
-----------------------------------------------------`
|
||||||
|
|
||||||
|
const logReqErrMsg = `DEBUG ERROR: Request %s/%s:
|
||||||
|
---[ REQUEST DUMP ERROR ]-----------------------------
|
||||||
|
%s
|
||||||
|
------------------------------------------------------`
|
||||||
|
|
||||||
|
type logWriter struct {
|
||||||
|
// Logger is what we will use to log the payload of a response.
|
||||||
|
Logger aws.Logger
|
||||||
|
// buf stores the contents of what has been read
|
||||||
|
buf *bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (logger *logWriter) Write(b []byte) (int, error) {
|
||||||
|
return logger.buf.Write(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
type teeReaderCloser struct {
|
||||||
|
// io.Reader will be a tee reader that is used during logging.
|
||||||
|
// This structure will read from a body and write the contents to a logger.
|
||||||
|
io.Reader
|
||||||
|
// Source is used just to close when we are done reading.
|
||||||
|
Source io.ReadCloser
|
||||||
|
}
|
||||||
|
|
||||||
|
func (reader *teeReaderCloser) Close() error {
|
||||||
|
return reader.Source.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func logRequest(r *request.Request) {
|
||||||
|
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
||||||
|
dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody)
|
||||||
|
if err != nil {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody)))
|
||||||
|
}
|
||||||
|
|
||||||
|
const logRespMsg = `DEBUG: Response %s/%s Details:
|
||||||
|
---[ RESPONSE ]--------------------------------------
|
||||||
|
%s
|
||||||
|
-----------------------------------------------------`
|
||||||
|
|
||||||
|
const logRespErrMsg = `DEBUG ERROR: Response %s/%s:
|
||||||
|
---[ RESPONSE DUMP ERROR ]-----------------------------
|
||||||
|
%s
|
||||||
|
-----------------------------------------------------`
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
handlerFn := func(req *request.Request) {
|
||||||
|
body, err := httputil.DumpResponse(req.HTTPResponse, false)
|
||||||
|
if err != nil {
|
||||||
|
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(string(b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlerName = "awsdk.client.LogResponse.ResponseBody"
|
||||||
|
|
||||||
|
r.Handlers.Unmarshal.SetBackNamed(request.NamedHandler{
|
||||||
|
Name: handlerName, Fn: handlerFn,
|
||||||
|
})
|
||||||
|
r.Handlers.UnmarshalError.SetBackNamed(request.NamedHandler{
|
||||||
|
Name: handlerName, Fn: handlerFn,
|
||||||
|
})
|
||||||
|
}
|
213
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
213
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
@ -5,26 +5,39 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UseServiceDefaultRetries instructs the config to use the service's own default
|
// UseServiceDefaultRetries instructs the config to use the service's own
|
||||||
// number of retries. This will be the default action if Config.MaxRetries
|
// default number of retries. This will be the default action if
|
||||||
// is nil also.
|
// Config.MaxRetries is nil also.
|
||||||
const UseServiceDefaultRetries = -1
|
const UseServiceDefaultRetries = -1
|
||||||
|
|
||||||
// RequestRetryer is an alias for a type that implements the request.Retryer interface.
|
// RequestRetryer is an alias for a type that implements the request.Retryer
|
||||||
|
// interface.
|
||||||
type RequestRetryer interface{}
|
type RequestRetryer interface{}
|
||||||
|
|
||||||
// A Config provides service configuration for service clients. By default,
|
// A Config provides service configuration for service clients. By default,
|
||||||
// all clients will use the {defaults.DefaultConfig} structure.
|
// all clients will use the defaults.DefaultConfig tructure.
|
||||||
|
//
|
||||||
|
// // Create Session with MaxRetry configuration to be shared by multiple
|
||||||
|
// // service clients.
|
||||||
|
// sess := session.Must(session.NewSession(&aws.Config{
|
||||||
|
// MaxRetries: aws.Int(3),
|
||||||
|
// }))
|
||||||
|
//
|
||||||
|
// // Create S3 service client with a specific Region.
|
||||||
|
// svc := s3.New(sess, &aws.Config{
|
||||||
|
// Region: aws.String("us-west-2"),
|
||||||
|
// })
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// Enables verbose error printing of all credential chain errors.
|
// Enables verbose error printing of all credential chain errors.
|
||||||
// Should be used when wanting to see all errors while attempting to retreive
|
// Should be used when wanting to see all errors while attempting to
|
||||||
// credentials.
|
// retrieve credentials.
|
||||||
CredentialsChainVerboseErrors *bool
|
CredentialsChainVerboseErrors *bool
|
||||||
|
|
||||||
// The credentials object to use when signing requests. Defaults to
|
// The credentials object to use when signing requests. Defaults to a
|
||||||
// a chain of credential providers to search for credentials in environment
|
// chain of credential providers to search for credentials in environment
|
||||||
// variables, shared credential file, and EC2 Instance Roles.
|
// variables, shared credential file, and EC2 Instance Roles.
|
||||||
Credentials *credentials.Credentials
|
Credentials *credentials.Credentials
|
||||||
|
|
||||||
@ -36,6 +49,17 @@ type Config struct {
|
|||||||
// endpoint for a client.
|
// endpoint for a client.
|
||||||
Endpoint *string
|
Endpoint *string
|
||||||
|
|
||||||
|
// The resolver to use for looking up endpoints for AWS service clients
|
||||||
|
// to use based on region.
|
||||||
|
EndpointResolver endpoints.Resolver
|
||||||
|
|
||||||
|
// EnforceShouldRetryCheck is used in the AfterRetryHandler to always call
|
||||||
|
// ShouldRetry regardless of whether or not if request.Retryable is set.
|
||||||
|
// This will utilize ShouldRetry method of custom retryers. If EnforceShouldRetryCheck
|
||||||
|
// is not set, then ShouldRetry will only be called if request.Retryable is nil.
|
||||||
|
// Proper handling of the request.Retryable field is important when setting this field.
|
||||||
|
EnforceShouldRetryCheck *bool
|
||||||
|
|
||||||
// The region to send requests to. This parameter is required and must
|
// The region to send requests to. This parameter is required and must
|
||||||
// be configured globally or on a per-client basis unless otherwise
|
// be configured globally or on a per-client basis unless otherwise
|
||||||
// noted. A full list of regions is found in the "Regions and Endpoints"
|
// noted. A full list of regions is found in the "Regions and Endpoints"
|
||||||
@ -63,14 +87,15 @@ type Config struct {
|
|||||||
Logger Logger
|
Logger Logger
|
||||||
|
|
||||||
// The maximum number of times that a request will be retried for failures.
|
// The maximum number of times that a request will be retried for failures.
|
||||||
// Defaults to -1, which defers the max retry setting to the service specific
|
// Defaults to -1, which defers the max retry setting to the service
|
||||||
// configuration.
|
// specific configuration.
|
||||||
MaxRetries *int
|
MaxRetries *int
|
||||||
|
|
||||||
// Retryer guides how HTTP requests should be retried in case of recoverable failures.
|
// Retryer guides how HTTP requests should be retried in case of
|
||||||
|
// recoverable failures.
|
||||||
//
|
//
|
||||||
// When nil or the value does not implement the request.Retryer interface,
|
// When nil or the value does not implement the request.Retryer interface,
|
||||||
// the request.DefaultRetryer will be used.
|
// the client.DefaultRetryer will be used.
|
||||||
//
|
//
|
||||||
// When both Retryer and MaxRetries are non-nil, the former is used and
|
// When both Retryer and MaxRetries are non-nil, the former is used and
|
||||||
// the latter ignored.
|
// the latter ignored.
|
||||||
@ -82,8 +107,8 @@ type Config struct {
|
|||||||
//
|
//
|
||||||
Retryer RequestRetryer
|
Retryer RequestRetryer
|
||||||
|
|
||||||
// Disables semantic parameter validation, which validates input for missing
|
// Disables semantic parameter validation, which validates input for
|
||||||
// required fields and/or other semantic request input errors.
|
// missing required fields and/or other semantic request input errors.
|
||||||
DisableParamValidation *bool
|
DisableParamValidation *bool
|
||||||
|
|
||||||
// Disables the computation of request and response checksums, e.g.,
|
// Disables the computation of request and response checksums, e.g.,
|
||||||
@ -91,8 +116,8 @@ type Config struct {
|
|||||||
DisableComputeChecksums *bool
|
DisableComputeChecksums *bool
|
||||||
|
|
||||||
// Set this to `true` to force the request to use path-style addressing,
|
// Set this to `true` to force the request to use path-style addressing,
|
||||||
// i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client will
|
// i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client
|
||||||
// use virtual hosted bucket addressing when possible
|
// will use virtual hosted bucket addressing when possible
|
||||||
// (`http://BUCKET.s3.amazonaws.com/KEY`).
|
// (`http://BUCKET.s3.amazonaws.com/KEY`).
|
||||||
//
|
//
|
||||||
// @note This configuration option is specific to the Amazon S3 service.
|
// @note This configuration option is specific to the Amazon S3 service.
|
||||||
@ -100,28 +125,110 @@ type Config struct {
|
|||||||
// Amazon S3: Virtual Hosting of Buckets
|
// Amazon S3: Virtual Hosting of Buckets
|
||||||
S3ForcePathStyle *bool
|
S3ForcePathStyle *bool
|
||||||
|
|
||||||
// Set this to `true` to disable the EC2Metadata client from overriding the
|
// Set this to `true` to disable the SDK adding the `Expect: 100-Continue`
|
||||||
// default http.Client's Timeout. This is helpful if you do not want the EC2Metadata
|
// header to PUT requests over 2MB of content. 100-Continue instructs the
|
||||||
// client to create a new http.Client. This options is only meaningful if you're not
|
// HTTP client not to send the body until the service responds with a
|
||||||
// already using a custom HTTP client with the SDK. Enabled by default.
|
// `continue` status. This is useful to prevent sending the request body
|
||||||
|
// until after the request is authenticated, and validated.
|
||||||
//
|
//
|
||||||
// Must be set and provided to the session.New() in order to disable the EC2Metadata
|
// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
|
||||||
// overriding the timeout for default credentials chain.
|
//
|
||||||
|
// 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s
|
||||||
|
// `ExpectContinueTimeout` for information on adjusting the continue wait
|
||||||
|
// timeout. https://golang.org/pkg/net/http/#Transport
|
||||||
|
//
|
||||||
|
// You should use this flag to disble 100-Continue if you experience issues
|
||||||
|
// with proxies or third party S3 compatible services.
|
||||||
|
S3Disable100Continue *bool
|
||||||
|
|
||||||
|
// Set this to `true` to enable S3 Accelerate feature. For all operations
|
||||||
|
// compatible with S3 Accelerate will use the accelerate endpoint for
|
||||||
|
// requests. Requests not compatible will fall back to normal S3 requests.
|
||||||
|
//
|
||||||
|
// The bucket must be enable for accelerate to be used with S3 client with
|
||||||
|
// accelerate enabled. If the bucket is not enabled for accelerate an error
|
||||||
|
// will be returned. The bucket name must be DNS compatible to also work
|
||||||
|
// with accelerate.
|
||||||
|
S3UseAccelerate *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
|
||||||
|
// meaningful if you're not already using a custom HTTP client with the
|
||||||
|
// SDK. Enabled by default.
|
||||||
|
//
|
||||||
|
// Must be set and provided to the session.NewSession() in order to disable
|
||||||
|
// the EC2Metadata overriding the timeout for default credentials chain.
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
// sess := session.New(aws.NewConfig().WithEC2MetadataDiableTimeoutOverride(true))
|
// sess := session.Must(session.NewSession(aws.NewConfig()
|
||||||
|
// .WithEC2MetadataDiableTimeoutOverride(true)))
|
||||||
|
//
|
||||||
// svc := s3.New(sess)
|
// svc := s3.New(sess)
|
||||||
//
|
//
|
||||||
EC2MetadataDisableTimeoutOverride *bool
|
EC2MetadataDisableTimeoutOverride *bool
|
||||||
|
|
||||||
|
// Instructs the endpiont to be generated for a service client to
|
||||||
|
// be the dual stack endpoint. The dual stack endpoint will support
|
||||||
|
// both IPv4 and IPv6 addressing.
|
||||||
|
//
|
||||||
|
// Setting this for a service which does not support dual stack will fail
|
||||||
|
// to make requets. It is not recommended to set this value on the session
|
||||||
|
// as it will apply to all service clients created with the session. Even
|
||||||
|
// services which don't support dual stack endpoints.
|
||||||
|
//
|
||||||
|
// If the Endpoint config value is also provided the UseDualStack flag
|
||||||
|
// will be ignored.
|
||||||
|
//
|
||||||
|
// Only supported with.
|
||||||
|
//
|
||||||
|
// sess := session.Must(session.NewSession())
|
||||||
|
//
|
||||||
|
// svc := s3.New(sess, &aws.Config{
|
||||||
|
// UseDualStack: aws.Bool(true),
|
||||||
|
// })
|
||||||
|
UseDualStack *bool
|
||||||
|
|
||||||
|
// SleepDelay is an override for the func the SDK will call when sleeping
|
||||||
|
// during the lifecycle of a request. Specifically this will be used for
|
||||||
|
// request delays. This value should only be used for testing. To adjust
|
||||||
|
// the delay of a request see the aws/client.DefaultRetryer and
|
||||||
|
// aws/request.Retryer.
|
||||||
|
//
|
||||||
|
// SleepDelay will prevent any Context from being used for canceling retry
|
||||||
|
// delay of an API operation. It is recommended to not use SleepDelay at all
|
||||||
|
// and specify a Retryer instead.
|
||||||
SleepDelay func(time.Duration)
|
SleepDelay func(time.Duration)
|
||||||
|
|
||||||
|
// DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests.
|
||||||
|
// Will default to false. This would only be used for empty directory names in s3 requests.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// sess := session.Must(session.NewSession(&aws.Config{
|
||||||
|
// DisableRestProtocolURICleaning: aws.Bool(true),
|
||||||
|
// }))
|
||||||
|
//
|
||||||
|
// svc := s3.New(sess)
|
||||||
|
// out, err := svc.GetObject(&s3.GetObjectInput {
|
||||||
|
// Bucket: aws.String("bucketname"),
|
||||||
|
// Key: aws.String("//foo//bar//moo"),
|
||||||
|
// })
|
||||||
|
DisableRestProtocolURICleaning *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfig returns a new Config pointer that can be chained with builder methods to
|
// NewConfig returns a new Config pointer that can be chained with builder
|
||||||
// set multiple configuration values inline without using pointers.
|
// methods to set multiple configuration values inline without using pointers.
|
||||||
//
|
//
|
||||||
// svc := s3.New(aws.NewConfig().WithRegion("us-west-2").WithMaxRetries(10))
|
// // Create Session with MaxRetry configuration to be shared by multiple
|
||||||
|
// // service clients.
|
||||||
|
// sess := session.Must(session.NewSession(aws.NewConfig().
|
||||||
|
// WithMaxRetries(3),
|
||||||
|
// ))
|
||||||
//
|
//
|
||||||
|
// // Create S3 service client with a specific Region.
|
||||||
|
// svc := s3.New(sess, aws.NewConfig().
|
||||||
|
// WithRegion("us-west-2"),
|
||||||
|
// )
|
||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
return &Config{}
|
return &Config{}
|
||||||
}
|
}
|
||||||
@ -147,6 +254,13 @@ func (c *Config) WithEndpoint(endpoint string) *Config {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithEndpointResolver sets a config EndpointResolver value returning a
|
||||||
|
// Config pointer for chaining.
|
||||||
|
func (c *Config) WithEndpointResolver(resolver endpoints.Resolver) *Config {
|
||||||
|
c.EndpointResolver = resolver
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// WithRegion sets a config Region value returning a Config pointer for
|
// WithRegion sets a config Region value returning a Config pointer for
|
||||||
// chaining.
|
// chaining.
|
||||||
func (c *Config) WithRegion(region string) *Config {
|
func (c *Config) WithRegion(region string) *Config {
|
||||||
@ -210,6 +324,27 @@ func (c *Config) WithS3ForcePathStyle(force bool) *Config {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithS3Disable100Continue sets a config S3Disable100Continue value returning
|
||||||
|
// a Config pointer for chaining.
|
||||||
|
func (c *Config) WithS3Disable100Continue(disable bool) *Config {
|
||||||
|
c.S3Disable100Continue = &disable
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithS3UseAccelerate sets a config S3UseAccelerate value returning a Config
|
||||||
|
// pointer for chaining.
|
||||||
|
func (c *Config) WithS3UseAccelerate(enable bool) *Config {
|
||||||
|
c.S3UseAccelerate = &enable
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithUseDualStack sets a config UseDualStack value returning a Config
|
||||||
|
// pointer for chaining.
|
||||||
|
func (c *Config) WithUseDualStack(enable bool) *Config {
|
||||||
|
c.UseDualStack = &enable
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value
|
// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value
|
||||||
// returning a Config pointer for chaining.
|
// returning a Config pointer for chaining.
|
||||||
func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
|
func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
|
||||||
@ -248,6 +383,10 @@ func mergeInConfig(dst *Config, other *Config) {
|
|||||||
dst.Endpoint = other.Endpoint
|
dst.Endpoint = other.Endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if other.EndpointResolver != nil {
|
||||||
|
dst.EndpointResolver = other.EndpointResolver
|
||||||
|
}
|
||||||
|
|
||||||
if other.Region != nil {
|
if other.Region != nil {
|
||||||
dst.Region = other.Region
|
dst.Region = other.Region
|
||||||
}
|
}
|
||||||
@ -288,6 +427,18 @@ func mergeInConfig(dst *Config, other *Config) {
|
|||||||
dst.S3ForcePathStyle = other.S3ForcePathStyle
|
dst.S3ForcePathStyle = other.S3ForcePathStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if other.S3Disable100Continue != nil {
|
||||||
|
dst.S3Disable100Continue = other.S3Disable100Continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if other.S3UseAccelerate != nil {
|
||||||
|
dst.S3UseAccelerate = other.S3UseAccelerate
|
||||||
|
}
|
||||||
|
|
||||||
|
if other.UseDualStack != nil {
|
||||||
|
dst.UseDualStack = other.UseDualStack
|
||||||
|
}
|
||||||
|
|
||||||
if other.EC2MetadataDisableTimeoutOverride != nil {
|
if other.EC2MetadataDisableTimeoutOverride != nil {
|
||||||
dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
|
dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
|
||||||
}
|
}
|
||||||
@ -295,6 +446,14 @@ func mergeInConfig(dst *Config, other *Config) {
|
|||||||
if other.SleepDelay != nil {
|
if other.SleepDelay != nil {
|
||||||
dst.SleepDelay = other.SleepDelay
|
dst.SleepDelay = other.SleepDelay
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if other.DisableRestProtocolURICleaning != nil {
|
||||||
|
dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning
|
||||||
|
}
|
||||||
|
|
||||||
|
if other.EnforceShouldRetryCheck != nil {
|
||||||
|
dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy will return a shallow copy of the Config object. If any additional
|
// Copy will return a shallow copy of the Config object. If any additional
|
||||||
|
71
vendor/github.com/aws/aws-sdk-go/aws/context.go
generated
vendored
Normal file
71
vendor/github.com/aws/aws-sdk-go/aws/context.go
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package aws
|
||||||
|
|
||||||
|
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"
|
||||||
|
// API methods with Go v1.6 and a Context type such as golang.org/x/net/context.
|
||||||
|
//
|
||||||
|
// See https://golang.org/pkg/context on how to use contexts.
|
||||||
|
type Context interface {
|
||||||
|
// Deadline returns the time when work done on behalf of this context
|
||||||
|
// should be canceled. Deadline returns ok==false when no deadline is
|
||||||
|
// set. Successive calls to Deadline return the same results.
|
||||||
|
Deadline() (deadline time.Time, ok bool)
|
||||||
|
|
||||||
|
// Done returns a channel that's closed when work done on behalf of this
|
||||||
|
// context should be canceled. Done may return nil if this context can
|
||||||
|
// never be canceled. Successive calls to Done return the same value.
|
||||||
|
Done() <-chan struct{}
|
||||||
|
|
||||||
|
// Err returns a non-nil error value after Done is closed. Err returns
|
||||||
|
// Canceled if the context was canceled or DeadlineExceeded if the
|
||||||
|
// context's deadline passed. No other values for Err are defined.
|
||||||
|
// After Done is closed, successive calls to Err return the same value.
|
||||||
|
Err() error
|
||||||
|
|
||||||
|
// Value returns the value associated with this context for key, or nil
|
||||||
|
// if no value is associated with key. Successive calls to Value with
|
||||||
|
// the same key returns the same result.
|
||||||
|
//
|
||||||
|
// Use context values only for request-scoped data that transits
|
||||||
|
// processes and API boundaries, not for passing optional parameters to
|
||||||
|
// 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
|
||||||
|
}
|
41
vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go
generated
vendored
Normal file
41
vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// +build !go1.7
|
||||||
|
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
// An emptyCtx is a copy of the Go 1.7 context.emptyCtx type. This is copied to
|
||||||
|
// provide a 1.6 and 1.5 safe version of context that is compatible with Go
|
||||||
|
// 1.7's Context.
|
||||||
|
//
|
||||||
|
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
|
||||||
|
// struct{}, since vars of this type must have distinct addresses.
|
||||||
|
type emptyCtx int
|
||||||
|
|
||||||
|
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*emptyCtx) Done() <-chan struct{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*emptyCtx) Err() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*emptyCtx) Value(key interface{}) interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *emptyCtx) String() string {
|
||||||
|
switch e {
|
||||||
|
case backgroundCtx:
|
||||||
|
return "aws.BackgroundContext"
|
||||||
|
}
|
||||||
|
return "unknown empty Context"
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
backgroundCtx = new(emptyCtx)
|
||||||
|
)
|
9
vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go
generated
vendored
Normal file
9
vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// +build go1.7
|
||||||
|
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import "context"
|
||||||
|
|
||||||
|
var (
|
||||||
|
backgroundCtx = context.Background()
|
||||||
|
)
|
42
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
42
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
@ -2,7 +2,7 @@ package aws
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
// String returns a pointer to of the string value passed in.
|
// String returns a pointer to the string value passed in.
|
||||||
func String(v string) *string {
|
func String(v string) *string {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ func StringValueMap(src map[string]*string) map[string]string {
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool returns a pointer to of the bool value passed in.
|
// Bool returns a pointer to the bool value passed in.
|
||||||
func Bool(v bool) *bool {
|
func Bool(v bool) *bool {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ func BoolValueMap(src map[string]*bool) map[string]bool {
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int returns a pointer to of the int value passed in.
|
// Int returns a pointer to the int value passed in.
|
||||||
func Int(v int) *int {
|
func Int(v int) *int {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ func IntValueMap(src map[string]*int) map[string]int {
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int64 returns a pointer to of the int64 value passed in.
|
// Int64 returns a pointer to the int64 value passed in.
|
||||||
func Int64(v int64) *int64 {
|
func Int64(v int64) *int64 {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ func Int64ValueMap(src map[string]*int64) map[string]int64 {
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Float64 returns a pointer to of the float64 value passed in.
|
// Float64 returns a pointer to the float64 value passed in.
|
||||||
func Float64(v float64) *float64 {
|
func Float64(v float64) *float64 {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
@ -297,7 +297,7 @@ func Float64ValueMap(src map[string]*float64) map[string]float64 {
|
|||||||
return dst
|
return dst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time returns a pointer to of the time.Time value passed in.
|
// Time returns a pointer to the time.Time value passed in.
|
||||||
func Time(v time.Time) *time.Time {
|
func Time(v time.Time) *time.Time {
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
@ -311,6 +311,36 @@ func TimeValue(v *time.Time) time.Time {
|
|||||||
return time.Time{}
|
return time.Time{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SecondsTimeValue converts an int64 pointer to a time.Time value
|
||||||
|
// representing seconds since Epoch or time.Time{} if the pointer is nil.
|
||||||
|
func SecondsTimeValue(v *int64) time.Time {
|
||||||
|
if v != nil {
|
||||||
|
return time.Unix((*v / 1000), 0)
|
||||||
|
}
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MillisecondsTimeValue converts an int64 pointer to a time.Time value
|
||||||
|
// representing milliseconds sinch Epoch or time.Time{} if the pointer is nil.
|
||||||
|
func MillisecondsTimeValue(v *int64) time.Time {
|
||||||
|
if v != nil {
|
||||||
|
return time.Unix(0, (*v * 1000000))
|
||||||
|
}
|
||||||
|
return time.Time{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC".
|
||||||
|
// The result is undefined if the Unix time cannot be represented by an int64.
|
||||||
|
// Which includes calling TimeUnixMilli on a zero Time is undefined.
|
||||||
|
//
|
||||||
|
// This utility is useful for service API's such as CloudWatch Logs which require
|
||||||
|
// their unix time values to be in milliseconds.
|
||||||
|
//
|
||||||
|
// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information.
|
||||||
|
func TimeUnixMilli(t time.Time) int64 {
|
||||||
|
return t.UnixNano() / int64(time.Millisecond/time.Nanosecond)
|
||||||
|
}
|
||||||
|
|
||||||
// TimeSlice converts a slice of time.Time values into a slice of
|
// TimeSlice converts a slice of time.Time values into a slice of
|
||||||
// time.Time pointers
|
// time.Time pointers
|
||||||
func TimeSlice(src []time.Time) []*time.Time {
|
func TimeSlice(src []time.Time) []*time.Time {
|
||||||
|
127
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
generated
vendored
127
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
generated
vendored
@ -10,9 +10,11 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,14 +26,16 @@ type lener interface {
|
|||||||
// BuildContentLengthHandler builds the content length of a request based on the body,
|
// BuildContentLengthHandler builds the content length of a request based on the body,
|
||||||
// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable
|
// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable
|
||||||
// to determine request body length and no "Content-Length" was specified it will panic.
|
// to determine request body length and no "Content-Length" was specified it will panic.
|
||||||
|
//
|
||||||
|
// The Content-Length will only be added to the request if the length of the body
|
||||||
|
// is greater than 0. If the body is empty or the current `Content-Length`
|
||||||
|
// header is <= 0, the header will also be stripped.
|
||||||
var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) {
|
var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) {
|
||||||
if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
|
|
||||||
length, _ := strconv.ParseInt(slength, 10, 64)
|
|
||||||
r.HTTPRequest.ContentLength = length
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var length int64
|
var length int64
|
||||||
|
|
||||||
|
if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
|
||||||
|
length, _ = strconv.ParseInt(slength, 10, 64)
|
||||||
|
} else {
|
||||||
switch body := r.Body.(type) {
|
switch body := r.Body.(type) {
|
||||||
case nil:
|
case nil:
|
||||||
length = 0
|
length = 0
|
||||||
@ -45,9 +49,15 @@ var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLen
|
|||||||
default:
|
default:
|
||||||
panic("Cannot get length of body, must provide `ContentLength`")
|
panic("Cannot get length of body, must provide `ContentLength`")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if length > 0 {
|
||||||
r.HTTPRequest.ContentLength = length
|
r.HTTPRequest.ContentLength = length
|
||||||
r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length))
|
r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length))
|
||||||
|
} else {
|
||||||
|
r.HTTPRequest.ContentLength = 0
|
||||||
|
r.HTTPRequest.Header.Del("Content-Length")
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// SDKVersionUserAgentHandler is a request handler for adding the SDK Version to the user agent.
|
// SDKVersionUserAgentHandler is a request handler for adding the SDK Version to the user agent.
|
||||||
@ -59,14 +69,89 @@ var SDKVersionUserAgentHandler = request.NamedHandler{
|
|||||||
|
|
||||||
var reStatusCode = regexp.MustCompile(`^(\d{3})`)
|
var reStatusCode = regexp.MustCompile(`^(\d{3})`)
|
||||||
|
|
||||||
|
// ValidateReqSigHandler is a request handler to ensure that the request's
|
||||||
|
// signature doesn't expire before it is sent. This can happen when a request
|
||||||
|
// is built and signed significantly before it is sent. Or significant delays
|
||||||
|
// occur when retrying requests that would cause the signature to expire.
|
||||||
|
var ValidateReqSigHandler = request.NamedHandler{
|
||||||
|
Name: "core.ValidateReqSigHandler",
|
||||||
|
Fn: func(r *request.Request) {
|
||||||
|
// Unsigned requests are not signed
|
||||||
|
if r.Config.Credentials == credentials.AnonymousCredentials {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
signedTime := r.Time
|
||||||
|
if !r.LastSignedAt.IsZero() {
|
||||||
|
signedTime = r.LastSignedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10 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()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("request expired, resigning")
|
||||||
|
r.Sign()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// SendHandler is a request handler to send service request using HTTP client.
|
// SendHandler is a request handler to send service request using HTTP client.
|
||||||
var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *request.Request) {
|
var SendHandler = request.NamedHandler{
|
||||||
|
Name: "core.SendHandler",
|
||||||
|
Fn: func(r *request.Request) {
|
||||||
|
sender := sendFollowRedirects
|
||||||
|
if r.DisableFollowRedirects {
|
||||||
|
sender = sendWithoutFollowRedirects
|
||||||
|
}
|
||||||
|
|
||||||
|
if request.NoBody == r.HTTPRequest.Body {
|
||||||
|
// Strip off the request body if the NoBody reader was used as a
|
||||||
|
// place holder for a request body. This prevents the SDK from
|
||||||
|
// making requests with a request body when it would be invalid
|
||||||
|
// to do so.
|
||||||
|
//
|
||||||
|
// Use a shallow copy of the http.Request to ensure the race condition
|
||||||
|
// of transport on Body will not trigger
|
||||||
|
reqOrig, reqCopy := r.HTTPRequest, *r.HTTPRequest
|
||||||
|
reqCopy.Body = nil
|
||||||
|
r.HTTPRequest = &reqCopy
|
||||||
|
defer func() {
|
||||||
|
r.HTTPRequest = reqOrig
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
r.HTTPResponse, err = r.Config.HTTPClient.Do(r.HTTPRequest)
|
r.HTTPResponse, err = sender(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
handleSendError(r, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendFollowRedirects(r *request.Request) (*http.Response, error) {
|
||||||
|
return r.Config.HTTPClient.Do(r.HTTPRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendWithoutFollowRedirects(r *request.Request) (*http.Response, error) {
|
||||||
|
transport := r.Config.HTTPClient.Transport
|
||||||
|
if transport == nil {
|
||||||
|
transport = http.DefaultTransport
|
||||||
|
}
|
||||||
|
|
||||||
|
return transport.RoundTrip(r.HTTPRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleSendError(r *request.Request, err error) {
|
||||||
|
// Prevent leaking if an HTTPResponse was returned. Clean up
|
||||||
|
// the body.
|
||||||
|
if r.HTTPResponse != nil {
|
||||||
|
r.HTTPResponse.Body.Close()
|
||||||
|
}
|
||||||
// Capture the case where url.Error is returned for error processing
|
// Capture the case where url.Error is returned for error processing
|
||||||
// response. e.g. 301 without location header comes back as string
|
// response. e.g. 301 without location header comes back as string
|
||||||
// error and r.HTTPResponse is nil. Other url redirect errors will
|
// error and r.HTTPResponse is nil. Other URL redirect errors will
|
||||||
// comeback in a similar method.
|
// comeback in a similar method.
|
||||||
if e, ok := err.(*url.Error); ok && e.Err != nil {
|
if e, ok := err.(*url.Error); ok && e.Err != nil {
|
||||||
if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil {
|
if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil {
|
||||||
@ -91,8 +176,17 @@ var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *req
|
|||||||
// Catch all other request errors.
|
// Catch all other request errors.
|
||||||
r.Error = awserr.New("RequestError", "send request failed", err)
|
r.Error = awserr.New("RequestError", "send request failed", err)
|
||||||
r.Retryable = aws.Bool(true) // network errors are retryable
|
r.Retryable = aws.Bool(true) // network errors are retryable
|
||||||
|
|
||||||
|
// Override the error with a context canceled error, if that was canceled.
|
||||||
|
ctx := r.Context()
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
r.Error = awserr.New(request.CanceledErrorCode,
|
||||||
|
"request context canceled", ctx.Err())
|
||||||
|
r.Retryable = aws.Bool(false)
|
||||||
|
default:
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
|
|
||||||
// ValidateResponseHandler is a request handler to validate service response.
|
// ValidateResponseHandler is a request handler to validate service response.
|
||||||
var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) {
|
var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) {
|
||||||
@ -107,13 +201,22 @@ var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseH
|
|||||||
var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) {
|
var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) {
|
||||||
// If one of the other handlers already set the retry state
|
// If one of the other handlers already set the retry state
|
||||||
// we don't want to override it based on the service's state
|
// we don't want to override it based on the service's state
|
||||||
if r.Retryable == nil {
|
if r.Retryable == nil || aws.BoolValue(r.Config.EnforceShouldRetryCheck) {
|
||||||
r.Retryable = aws.Bool(r.ShouldRetry(r))
|
r.Retryable = aws.Bool(r.ShouldRetry(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.WillRetry() {
|
if r.WillRetry() {
|
||||||
r.RetryDelay = r.RetryRules(r)
|
r.RetryDelay = r.RetryRules(r)
|
||||||
r.Config.SleepDelay(r.RetryDelay)
|
|
||||||
|
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
|
// when the expired token exception occurs the credentials
|
||||||
// need to be expired locally so that the next request to
|
// need to be expired locally so that the next request to
|
||||||
|
150
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
generated
vendored
150
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
generated
vendored
@ -1,153 +1,17 @@
|
|||||||
package corehandlers
|
package corehandlers
|
||||||
|
|
||||||
import (
|
import "github.com/aws/aws-sdk-go/aws/request"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ValidateParametersHandler is a request handler to validate the input parameters.
|
// ValidateParametersHandler is a request handler to validate the input parameters.
|
||||||
// Validating parameters only has meaning if done prior to the request being sent.
|
// Validating parameters only has meaning if done prior to the request being sent.
|
||||||
var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) {
|
var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) {
|
||||||
if r.ParamsFilled() {
|
if !r.ParamsFilled() {
|
||||||
v := validator{errors: []string{}}
|
return
|
||||||
v.validateAny(reflect.ValueOf(r.Params), "")
|
}
|
||||||
|
|
||||||
if count := len(v.errors); count > 0 {
|
if v, ok := r.Params.(request.Validator); ok {
|
||||||
format := "%d validation errors:\n- %s"
|
if err := v.Validate(); err != nil {
|
||||||
msg := fmt.Sprintf(format, count, strings.Join(v.errors, "\n- "))
|
r.Error = err
|
||||||
r.Error = awserr.New("InvalidParameter", msg, nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// A validator validates values. Collects validations errors which occurs.
|
|
||||||
type validator struct {
|
|
||||||
errors []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// There's no validation to be done on the contents of []byte values. Prepare
|
|
||||||
// to check validateAny arguments against that type so we can quickly skip
|
|
||||||
// them.
|
|
||||||
var byteSliceType = reflect.TypeOf([]byte(nil))
|
|
||||||
|
|
||||||
// validateAny will validate any struct, slice or map type. All validations
|
|
||||||
// are also performed recursively for nested types.
|
|
||||||
func (v *validator) validateAny(value reflect.Value, path string) {
|
|
||||||
value = reflect.Indirect(value)
|
|
||||||
if !value.IsValid() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch value.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
v.validateStruct(value, path)
|
|
||||||
case reflect.Slice:
|
|
||||||
if value.Type() == byteSliceType {
|
|
||||||
// We don't need to validate the contents of []byte.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for i := 0; i < value.Len(); i++ {
|
|
||||||
v.validateAny(value.Index(i), path+fmt.Sprintf("[%d]", i))
|
|
||||||
}
|
|
||||||
case reflect.Map:
|
|
||||||
for _, n := range value.MapKeys() {
|
|
||||||
v.validateAny(value.MapIndex(n), path+fmt.Sprintf("[%q]", n.String()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// validateStruct will validate the struct value's fields. If the structure has
|
|
||||||
// nested types those types will be validated also.
|
|
||||||
func (v *validator) validateStruct(value reflect.Value, path string) {
|
|
||||||
prefix := "."
|
|
||||||
if path == "" {
|
|
||||||
prefix = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < value.Type().NumField(); i++ {
|
|
||||||
f := value.Type().Field(i)
|
|
||||||
if strings.ToLower(f.Name[0:1]) == f.Name[0:1] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
fvalue := value.FieldByName(f.Name)
|
|
||||||
|
|
||||||
err := validateField(f, fvalue, validateFieldRequired, validateFieldMin)
|
|
||||||
if err != nil {
|
|
||||||
v.errors = append(v.errors, fmt.Sprintf("%s: %s", err.Error(), path+prefix+f.Name))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
v.validateAny(fvalue, path+prefix+f.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type validatorFunc func(f reflect.StructField, fvalue reflect.Value) error
|
|
||||||
|
|
||||||
func validateField(f reflect.StructField, fvalue reflect.Value, funcs ...validatorFunc) error {
|
|
||||||
for _, fn := range funcs {
|
|
||||||
if err := fn(f, fvalue); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validates that a field has a valid value provided for required fields.
|
|
||||||
func validateFieldRequired(f reflect.StructField, fvalue reflect.Value) error {
|
|
||||||
if f.Tag.Get("required") == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch fvalue.Kind() {
|
|
||||||
case reflect.Ptr, reflect.Slice, reflect.Map:
|
|
||||||
if fvalue.IsNil() {
|
|
||||||
return fmt.Errorf("missing required parameter")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if !fvalue.IsValid() {
|
|
||||||
return fmt.Errorf("missing required parameter")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validates that if a value is provided for a field, that value must be at
|
|
||||||
// least a minimum length.
|
|
||||||
func validateFieldMin(f reflect.StructField, fvalue reflect.Value) error {
|
|
||||||
minStr := f.Tag.Get("min")
|
|
||||||
if minStr == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
min, _ := strconv.ParseInt(minStr, 10, 64)
|
|
||||||
|
|
||||||
kind := fvalue.Kind()
|
|
||||||
if kind == reflect.Ptr {
|
|
||||||
if fvalue.IsNil() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
fvalue = fvalue.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch fvalue.Kind() {
|
|
||||||
case reflect.String:
|
|
||||||
if int64(fvalue.Len()) < min {
|
|
||||||
return fmt.Errorf("field too short, minimum length %d", min)
|
|
||||||
}
|
|
||||||
case reflect.Slice, reflect.Map:
|
|
||||||
if fvalue.IsNil() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if int64(fvalue.Len()) < min {
|
|
||||||
return fmt.Errorf("field too short, minimum length %d", min)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO min can also apply to number minimum value.
|
|
||||||
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
14
vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
14
vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
@ -34,21 +34,23 @@ var (
|
|||||||
//
|
//
|
||||||
// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider.
|
// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider.
|
||||||
// In this example EnvProvider will first check if any credentials are available
|
// In this example EnvProvider will first check if any credentials are available
|
||||||
// vai the environment variables. If there are none ChainProvider will check
|
// via the environment variables. If there are none ChainProvider will check
|
||||||
// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider
|
// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider
|
||||||
// does not return any credentials ChainProvider will return the error
|
// does not return any credentials ChainProvider will return the error
|
||||||
// ErrNoValidProvidersFoundInChain
|
// ErrNoValidProvidersFoundInChain
|
||||||
//
|
//
|
||||||
// creds := NewChainCredentials(
|
// creds := credentials.NewChainCredentials(
|
||||||
// []Provider{
|
// []credentials.Provider{
|
||||||
// &EnvProvider{},
|
// &credentials.EnvProvider{},
|
||||||
// &EC2RoleProvider{
|
// &ec2rolecreds.EC2RoleProvider{
|
||||||
// Client: ec2metadata.New(sess),
|
// Client: ec2metadata.New(sess),
|
||||||
// },
|
// },
|
||||||
// })
|
// })
|
||||||
//
|
//
|
||||||
// // Usage of ChainCredentials with aws.Config
|
// // Usage of ChainCredentials with aws.Config
|
||||||
// svc := ec2.New(&aws.Config{Credentials: creds})
|
// svc := ec2.New(session.Must(session.NewSession(&aws.Config{
|
||||||
|
// Credentials: creds,
|
||||||
|
// })))
|
||||||
//
|
//
|
||||||
type ChainProvider struct {
|
type ChainProvider struct {
|
||||||
Providers []Provider
|
Providers []Provider
|
||||||
|
33
vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
33
vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
@ -14,7 +14,7 @@
|
|||||||
//
|
//
|
||||||
// Example of using the environment variable credentials.
|
// Example of using the environment variable credentials.
|
||||||
//
|
//
|
||||||
// creds := NewEnvCredentials()
|
// creds := credentials.NewEnvCredentials()
|
||||||
//
|
//
|
||||||
// // Retrieve the credentials value
|
// // Retrieve the credentials value
|
||||||
// credValue, err := creds.Get()
|
// credValue, err := creds.Get()
|
||||||
@ -26,7 +26,7 @@
|
|||||||
// This may be helpful to proactively expire credentials and refresh them sooner
|
// This may be helpful to proactively expire credentials and refresh them sooner
|
||||||
// than they would naturally expire on their own.
|
// than they would naturally expire on their own.
|
||||||
//
|
//
|
||||||
// creds := NewCredentials(&EC2RoleProvider{})
|
// creds := credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{})
|
||||||
// creds.Expire()
|
// creds.Expire()
|
||||||
// credsValue, err := creds.Get()
|
// credsValue, err := creds.Get()
|
||||||
// // New credentials will be retrieved instead of from cache.
|
// // New credentials will be retrieved instead of from cache.
|
||||||
@ -43,7 +43,7 @@
|
|||||||
// func (m *MyProvider) Retrieve() (Value, error) {...}
|
// func (m *MyProvider) Retrieve() (Value, error) {...}
|
||||||
// func (m *MyProvider) IsExpired() bool {...}
|
// func (m *MyProvider) IsExpired() bool {...}
|
||||||
//
|
//
|
||||||
// creds := NewCredentials(&MyProvider{})
|
// creds := credentials.NewCredentials(&MyProvider{})
|
||||||
// credValue, err := creds.Get()
|
// credValue, err := creds.Get()
|
||||||
//
|
//
|
||||||
package credentials
|
package credentials
|
||||||
@ -60,7 +60,9 @@ import (
|
|||||||
// when making service API calls. For example, when accessing public
|
// when making service API calls. For example, when accessing public
|
||||||
// s3 buckets.
|
// s3 buckets.
|
||||||
//
|
//
|
||||||
// svc := s3.New(&aws.Config{Credentials: AnonymousCredentials})
|
// svc := s3.New(session.Must(session.NewSession(&aws.Config{
|
||||||
|
// Credentials: credentials.AnonymousCredentials,
|
||||||
|
// })))
|
||||||
// // Access public S3 buckets.
|
// // Access public S3 buckets.
|
||||||
//
|
//
|
||||||
// @readonly
|
// @readonly
|
||||||
@ -88,7 +90,7 @@ type Value struct {
|
|||||||
// The Provider should not need to implement its own mutexes, because
|
// The Provider should not need to implement its own mutexes, because
|
||||||
// that will be managed by Credentials.
|
// that will be managed by Credentials.
|
||||||
type Provider interface {
|
type Provider interface {
|
||||||
// Refresh returns nil if it successfully retrieved the value.
|
// Retrieve returns nil if it successfully retrieved the value.
|
||||||
// Error is returned if the value were not obtainable, or empty.
|
// Error is returned if the value were not obtainable, or empty.
|
||||||
Retrieve() (Value, error)
|
Retrieve() (Value, error)
|
||||||
|
|
||||||
@ -97,6 +99,27 @@ type Provider interface {
|
|||||||
IsExpired() bool
|
IsExpired() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
type ErrorProvider struct {
|
||||||
|
// The error to be returned from Retrieve
|
||||||
|
Err error
|
||||||
|
|
||||||
|
// The provider name to set on the Retrieved returned Value
|
||||||
|
ProviderName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve will always return the error that the ErrorProvider was created with.
|
||||||
|
func (p ErrorProvider) Retrieve() (Value, error) {
|
||||||
|
return Value{ProviderName: p.ProviderName}, p.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsExpired will always return not expired.
|
||||||
|
func (p ErrorProvider) IsExpired() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// A Expiry provides shared expiration logic to be used by credentials
|
// A Expiry provides shared expiration logic to be used by credentials
|
||||||
// providers to implement expiry functionality.
|
// providers to implement expiry functionality.
|
||||||
//
|
//
|
||||||
|
2
vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
generated
vendored
@ -111,7 +111,7 @@ func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// A ec2RoleCredRespBody provides the shape for unmarshalling credential
|
// A ec2RoleCredRespBody provides the shape for unmarshaling credential
|
||||||
// request responses.
|
// request responses.
|
||||||
type ec2RoleCredRespBody struct {
|
type ec2RoleCredRespBody struct {
|
||||||
// Success State
|
// Success State
|
||||||
|
191
vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go
generated
vendored
Normal file
191
vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
// Package endpointcreds provides support for retrieving credentials from an
|
||||||
|
// arbitrary HTTP endpoint.
|
||||||
|
//
|
||||||
|
// The credentials endpoint Provider can receive both static and refreshable
|
||||||
|
// credentials that will expire. Credentials are static when an "Expiration"
|
||||||
|
// value is not provided in the endpoint's response.
|
||||||
|
//
|
||||||
|
// Static credentials will never expire once they have been retrieved. The format
|
||||||
|
// of the static credentials response:
|
||||||
|
// {
|
||||||
|
// "AccessKeyId" : "MUA...",
|
||||||
|
// "SecretAccessKey" : "/7PC5om....",
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration
|
||||||
|
// value in the response. The format of the refreshable credentials response:
|
||||||
|
// {
|
||||||
|
// "AccessKeyId" : "MUA...",
|
||||||
|
// "SecretAccessKey" : "/7PC5om....",
|
||||||
|
// "Token" : "AQoDY....=",
|
||||||
|
// "Expiration" : "2016-02-25T06:03:31Z"
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Errors should be returned in the following format and only returned with 400
|
||||||
|
// or 500 HTTP status codes.
|
||||||
|
// {
|
||||||
|
// "code": "ErrorCode",
|
||||||
|
// "message": "Helpful error message."
|
||||||
|
// }
|
||||||
|
package endpointcreds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"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/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ProviderName is the name of the credentials provider.
|
||||||
|
const ProviderName = `CredentialsEndpointProvider`
|
||||||
|
|
||||||
|
// Provider satisfies the credentials.Provider interface, and is a client to
|
||||||
|
// retrieve credentials from an arbitrary endpoint.
|
||||||
|
type Provider struct {
|
||||||
|
staticCreds bool
|
||||||
|
credentials.Expiry
|
||||||
|
|
||||||
|
// Requires a AWS Client to make HTTP requests to the endpoint with.
|
||||||
|
// the Endpoint the request will be made to is provided by the aws.Config's
|
||||||
|
// Endpoint value.
|
||||||
|
Client *client.Client
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProviderClient returns a credentials Provider for retrieving AWS credentials
|
||||||
|
// from arbitrary endpoint.
|
||||||
|
func NewProviderClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) credentials.Provider {
|
||||||
|
p := &Provider{
|
||||||
|
Client: client.New(
|
||||||
|
cfg,
|
||||||
|
metadata.ClientInfo{
|
||||||
|
ServiceName: "CredentialsEndpoint",
|
||||||
|
Endpoint: endpoint,
|
||||||
|
},
|
||||||
|
handlers,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
p.Client.Handlers.Unmarshal.PushBack(unmarshalHandler)
|
||||||
|
p.Client.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
|
p.Client.Handlers.Validate.Clear()
|
||||||
|
p.Client.Handlers.Validate.PushBack(validateEndpointHandler)
|
||||||
|
|
||||||
|
for _, option := range options {
|
||||||
|
option(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCredentialsClient returns a Credentials wrapper for retrieving credentials
|
||||||
|
// from an arbitrary endpoint concurrently. The client will request the
|
||||||
|
func NewCredentialsClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) *credentials.Credentials {
|
||||||
|
return credentials.NewCredentials(NewProviderClient(cfg, handlers, endpoint, options...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsExpired returns true if the credentials retrieved are expired, or not yet
|
||||||
|
// retrieved.
|
||||||
|
func (p *Provider) IsExpired() bool {
|
||||||
|
if p.staticCreds {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return p.Expiry.IsExpired()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve will attempt to request the credentials from the endpoint the Provider
|
||||||
|
// was configured for. And error will be returned if the retrieval fails.
|
||||||
|
func (p *Provider) Retrieve() (credentials.Value, error) {
|
||||||
|
resp, err := p.getCredentials()
|
||||||
|
if err != nil {
|
||||||
|
return credentials.Value{ProviderName: ProviderName},
|
||||||
|
awserr.New("CredentialsEndpointError", "failed to load credentials", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.Expiration != nil {
|
||||||
|
p.SetExpiration(*resp.Expiration, p.ExpiryWindow)
|
||||||
|
} else {
|
||||||
|
p.staticCreds = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return credentials.Value{
|
||||||
|
AccessKeyID: resp.AccessKeyID,
|
||||||
|
SecretAccessKey: resp.SecretAccessKey,
|
||||||
|
SessionToken: resp.Token,
|
||||||
|
ProviderName: ProviderName,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type getCredentialsOutput struct {
|
||||||
|
Expiration *time.Time
|
||||||
|
AccessKeyID string
|
||||||
|
SecretAccessKey string
|
||||||
|
Token string
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorOutput struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Provider) getCredentials() (*getCredentialsOutput, error) {
|
||||||
|
op := &request.Operation{
|
||||||
|
Name: "GetCredentials",
|
||||||
|
HTTPMethod: "GET",
|
||||||
|
}
|
||||||
|
|
||||||
|
out := &getCredentialsOutput{}
|
||||||
|
req := p.Client.NewRequest(op, nil, out)
|
||||||
|
req.HTTPRequest.Header.Set("Accept", "application/json")
|
||||||
|
|
||||||
|
return out, req.Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateEndpointHandler(r *request.Request) {
|
||||||
|
if len(r.ClientInfo.Endpoint) == 0 {
|
||||||
|
r.Error = aws.ErrMissingEndpoint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmarshalHandler(r *request.Request) {
|
||||||
|
defer r.HTTPResponse.Body.Close()
|
||||||
|
|
||||||
|
out := r.Data.(*getCredentialsOutput)
|
||||||
|
if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil {
|
||||||
|
r.Error = awserr.New("SerializationError",
|
||||||
|
"failed to decode endpoint credentials",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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(errOut.Code, errOut.Message, nil)
|
||||||
|
}
|
1
vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
1
vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
@ -29,6 +29,7 @@ var (
|
|||||||
// Environment variables used:
|
// Environment variables used:
|
||||||
//
|
//
|
||||||
// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY
|
// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY
|
||||||
|
//
|
||||||
// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
|
// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
|
||||||
type EnvProvider struct {
|
type EnvProvider struct {
|
||||||
retrieved bool
|
retrieved bool
|
||||||
|
21
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
21
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
@ -3,11 +3,11 @@ package credentials
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/go-ini/ini"
|
"github.com/go-ini/ini"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SharedCredsProviderName provides a name of SharedCreds provider
|
// SharedCredsProviderName provides a name of SharedCreds provider
|
||||||
@ -15,8 +15,6 @@ const SharedCredsProviderName = "SharedCredentialsProvider"
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
|
// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
|
||||||
//
|
|
||||||
// @readonly
|
|
||||||
ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
|
ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -117,21 +115,22 @@ func loadProfile(filename, profile string) (Value, error) {
|
|||||||
//
|
//
|
||||||
// Will return an error if the user's home directory path cannot be found.
|
// Will return an error if the user's home directory path cannot be found.
|
||||||
func (p *SharedCredentialsProvider) filename() (string, error) {
|
func (p *SharedCredentialsProvider) filename() (string, error) {
|
||||||
if p.Filename == "" {
|
if len(p.Filename) != 0 {
|
||||||
if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); p.Filename != "" {
|
|
||||||
return p.Filename, nil
|
return p.Filename, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
homeDir := os.Getenv("HOME") // *nix
|
if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(p.Filename) != 0 {
|
||||||
if homeDir == "" { // Windows
|
return p.Filename, nil
|
||||||
homeDir = os.Getenv("USERPROFILE")
|
|
||||||
}
|
}
|
||||||
if homeDir == "" {
|
|
||||||
|
if home := shareddefaults.UserHomeDir(); len(home) == 0 {
|
||||||
|
// Backwards compatibility of home directly not found error being returned.
|
||||||
|
// This error is too verbose, failure when opening the file would of been
|
||||||
|
// a better error to return.
|
||||||
return "", ErrSharedCredentialsHomeNotFound
|
return "", ErrSharedCredentialsHomeNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Filename = filepath.Join(homeDir, ".aws", "credentials")
|
p.Filename = shareddefaults.SharedCredentialsFilename()
|
||||||
}
|
|
||||||
|
|
||||||
return p.Filename, nil
|
return p.Filename, nil
|
||||||
}
|
}
|
||||||
|
11
vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
11
vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
@ -14,7 +14,7 @@ var (
|
|||||||
ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil)
|
ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// A StaticProvider is a set of credentials which are set pragmatically,
|
// A StaticProvider is a set of credentials which are set programmatically,
|
||||||
// and will never expire.
|
// and will never expire.
|
||||||
type StaticProvider struct {
|
type StaticProvider struct {
|
||||||
Value
|
Value
|
||||||
@ -30,13 +30,22 @@ func NewStaticCredentials(id, secret, token string) *Credentials {
|
|||||||
}})
|
}})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewStaticCredentialsFromCreds returns a pointer to a new Credentials object
|
||||||
|
// wrapping the static credentials value provide. Same as NewStaticCredentials
|
||||||
|
// but takes the creds Value instead of individual fields
|
||||||
|
func NewStaticCredentialsFromCreds(creds Value) *Credentials {
|
||||||
|
return NewCredentials(&StaticProvider{Value: creds})
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve returns the credentials or error if the credentials are invalid.
|
// Retrieve returns the credentials or error if the credentials are invalid.
|
||||||
func (s *StaticProvider) Retrieve() (Value, error) {
|
func (s *StaticProvider) Retrieve() (Value, error) {
|
||||||
if s.AccessKeyID == "" || s.SecretAccessKey == "" {
|
if s.AccessKeyID == "" || s.SecretAccessKey == "" {
|
||||||
return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty
|
return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(s.Value.ProviderName) == 0 {
|
||||||
s.Value.ProviderName = StaticProviderName
|
s.Value.ProviderName = StaticProviderName
|
||||||
|
}
|
||||||
return s.Value, nil
|
return s.Value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
298
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
Normal file
298
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
/*
|
||||||
|
Package stscreds are credential Providers to retrieve STS AWS credentials.
|
||||||
|
|
||||||
|
STS provides multiple ways to retrieve credentials which can be used when making
|
||||||
|
future AWS service API operation calls.
|
||||||
|
|
||||||
|
The SDK will ensure that per instance of credentials.Credentials all requests
|
||||||
|
to refresh the credentials will be synchronized. But, the SDK is unable to
|
||||||
|
ensure synchronous usage of the AssumeRoleProvider if the value is shared
|
||||||
|
between multiple Credentials, Sessions or service clients.
|
||||||
|
|
||||||
|
Assume Role
|
||||||
|
|
||||||
|
To assume an IAM role using STS with the SDK you can create a new Credentials
|
||||||
|
with the SDKs's stscreds package.
|
||||||
|
|
||||||
|
// Initial credentials loaded from SDK's default credential chain. Such as
|
||||||
|
// the environment, shared credentials (~/.aws/credentials), or EC2 Instance
|
||||||
|
// Role. These credentials will be used to to make the STS Assume Role API.
|
||||||
|
sess := session.Must(session.NewSession())
|
||||||
|
|
||||||
|
// Create the credentials from AssumeRoleProvider to assume the role
|
||||||
|
// referenced by the "myRoleARN" ARN.
|
||||||
|
creds := stscreds.NewCredentials(sess, "myRoleArn")
|
||||||
|
|
||||||
|
// Create service client value configured for credentials
|
||||||
|
// from assumed role.
|
||||||
|
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
||||||
|
|
||||||
|
Assume Role with static MFA Token
|
||||||
|
|
||||||
|
To assume an IAM role with a MFA token you can either specify a MFA token code
|
||||||
|
directly or provide a function to prompt the user each time the credentials
|
||||||
|
need to refresh the role's credentials. Specifying the TokenCode should be used
|
||||||
|
for short lived operations that will not need to be refreshed, and when you do
|
||||||
|
not want to have direct control over the user provides their MFA token.
|
||||||
|
|
||||||
|
With TokenCode the AssumeRoleProvider will be not be able to refresh the role's
|
||||||
|
credentials.
|
||||||
|
|
||||||
|
// Create the credentials from AssumeRoleProvider to assume the role
|
||||||
|
// referenced by the "myRoleARN" ARN using the MFA token code provided.
|
||||||
|
creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) {
|
||||||
|
p.SerialNumber = aws.String("myTokenSerialNumber")
|
||||||
|
p.TokenCode = aws.String("00000000")
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create service client value configured for credentials
|
||||||
|
// from assumed role.
|
||||||
|
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
||||||
|
|
||||||
|
Assume Role with MFA Token Provider
|
||||||
|
|
||||||
|
To assume an IAM role with MFA for longer running tasks where the credentials
|
||||||
|
may need to be refreshed setting the TokenProvider field of AssumeRoleProvider
|
||||||
|
will allow the credential provider to prompt for new MFA token code when the
|
||||||
|
role's credentials need to be refreshed.
|
||||||
|
|
||||||
|
The StdinTokenProvider function is available to prompt on stdin to retrieve
|
||||||
|
the MFA token code from the user. You can also implement custom prompts by
|
||||||
|
satisfing the TokenProvider function signature.
|
||||||
|
|
||||||
|
Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will
|
||||||
|
have undesirable results as the StdinTokenProvider will not be synchronized. A
|
||||||
|
single Credentials with an AssumeRoleProvider can be shared safely.
|
||||||
|
|
||||||
|
// Create the credentials from AssumeRoleProvider to assume the role
|
||||||
|
// referenced by the "myRoleARN" ARN. Prompting for MFA token from stdin.
|
||||||
|
creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) {
|
||||||
|
p.SerialNumber = aws.String("myTokenSerialNumber")
|
||||||
|
p.TokenProvider = stscreds.StdinTokenProvider
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create service client value configured for credentials
|
||||||
|
// from assumed role.
|
||||||
|
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
||||||
|
|
||||||
|
*/
|
||||||
|
package stscreds
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StdinTokenProvider will prompt on stdout 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
|
||||||
|
// to make atomic prompts from stdin across multiple gorouties.
|
||||||
|
//
|
||||||
|
// Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will
|
||||||
|
// have undesirable results as the StdinTokenProvider will not be synchronized. A
|
||||||
|
// single Credentials with an AssumeRoleProvider can be shared safely
|
||||||
|
//
|
||||||
|
// Will wait forever until something is provided on the stdin.
|
||||||
|
func StdinTokenProvider() (string, error) {
|
||||||
|
var v string
|
||||||
|
fmt.Printf("Assume Role MFA token code: ")
|
||||||
|
_, err := fmt.Scanln(&v)
|
||||||
|
|
||||||
|
return v, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProviderName provides a name of AssumeRole provider
|
||||||
|
const ProviderName = "AssumeRoleProvider"
|
||||||
|
|
||||||
|
// AssumeRoler represents the minimal subset of the STS client API used by this provider.
|
||||||
|
type AssumeRoler interface {
|
||||||
|
AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultDuration is the default amount of time in minutes that the credentials
|
||||||
|
// will be valid for.
|
||||||
|
var DefaultDuration = time.Duration(15) * time.Minute
|
||||||
|
|
||||||
|
// AssumeRoleProvider retrieves temporary credentials from the STS service, and
|
||||||
|
// keeps track of their expiration time.
|
||||||
|
//
|
||||||
|
// This credential provider will be used by the SDKs default credential change
|
||||||
|
// when shared configuration is enabled, and the shared config or shared credentials
|
||||||
|
// file configure assume role. See Session docs for how to do this.
|
||||||
|
//
|
||||||
|
// AssumeRoleProvider does not provide any synchronization and it is not safe
|
||||||
|
// to share this value across multiple Credentials, Sessions, or service clients
|
||||||
|
// without also sharing the same Credentials instance.
|
||||||
|
type AssumeRoleProvider struct {
|
||||||
|
credentials.Expiry
|
||||||
|
|
||||||
|
// STS client to make assume role request with.
|
||||||
|
Client AssumeRoler
|
||||||
|
|
||||||
|
// Role to be assumed.
|
||||||
|
RoleARN string
|
||||||
|
|
||||||
|
// Session name, if you wish to reuse the credentials elsewhere.
|
||||||
|
RoleSessionName string
|
||||||
|
|
||||||
|
// Expiry duration of the STS credentials. Defaults to 15 minutes if not set.
|
||||||
|
Duration time.Duration
|
||||||
|
|
||||||
|
// Optional ExternalID to pass along, defaults to nil if not set.
|
||||||
|
ExternalID *string
|
||||||
|
|
||||||
|
// The policy plain text must be 2048 bytes or shorter. However, an internal
|
||||||
|
// conversion compresses it into a packed binary format with a separate limit.
|
||||||
|
// The PackedPolicySize response element indicates by percentage how close to
|
||||||
|
// the upper size limit the policy is, with 100% equaling the maximum allowed
|
||||||
|
// size.
|
||||||
|
Policy *string
|
||||||
|
|
||||||
|
// The identification number of the MFA device that is associated with the user
|
||||||
|
// who is making the AssumeRole call. Specify this value if the trust policy
|
||||||
|
// of the role being assumed includes a condition that requires MFA authentication.
|
||||||
|
// The value is either the serial number for a hardware device (such as GAHT12345678)
|
||||||
|
// or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
|
||||||
|
SerialNumber *string
|
||||||
|
|
||||||
|
// The value provided by the MFA device, if the trust policy of the role being
|
||||||
|
// assumed requires MFA (that is, if the policy includes a condition that tests
|
||||||
|
// for MFA). If the role being assumed requires MFA and if the TokenCode value
|
||||||
|
// is missing or expired, the AssumeRole call returns an "access denied" error.
|
||||||
|
//
|
||||||
|
// If SerialNumber is set and neither TokenCode nor TokenProvider are also
|
||||||
|
// set an error will be returned.
|
||||||
|
TokenCode *string
|
||||||
|
|
||||||
|
// Async method of providing MFA token code for assuming an IAM role with MFA.
|
||||||
|
// The value returned by the function will be used as the TokenCode in the Retrieve
|
||||||
|
// call. See StdinTokenProvider for a provider that prompts and reads from stdin.
|
||||||
|
//
|
||||||
|
// This token provider will be called when ever the assumed role's
|
||||||
|
// credentials need to be refreshed when SerialNumber is also set and
|
||||||
|
// TokenCode is not set.
|
||||||
|
//
|
||||||
|
// If both TokenCode and TokenProvider is set, TokenProvider will be used and
|
||||||
|
// TokenCode is ignored.
|
||||||
|
TokenProvider func() (string, error)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCredentials returns a pointer to a new Credentials object wrapping the
|
||||||
|
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
||||||
|
// role will be named after a nanosecond timestamp of this operation.
|
||||||
|
//
|
||||||
|
// Takes a Config provider to create the STS client. The ConfigProvider is
|
||||||
|
// satisfied by the session.Session type.
|
||||||
|
//
|
||||||
|
// It is safe to share the returned Credentials with multiple Sessions and
|
||||||
|
// service clients. All access to the credentials and refreshing them
|
||||||
|
// will be synchronized.
|
||||||
|
func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
||||||
|
p := &AssumeRoleProvider{
|
||||||
|
Client: sts.New(c),
|
||||||
|
RoleARN: roleARN,
|
||||||
|
Duration: DefaultDuration,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, option := range options {
|
||||||
|
option(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return credentials.NewCredentials(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the
|
||||||
|
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
||||||
|
// role will be named after a nanosecond timestamp of this operation.
|
||||||
|
//
|
||||||
|
// Takes an AssumeRoler which can be satisfied by the STS client.
|
||||||
|
//
|
||||||
|
// It is safe to share the returned Credentials with multiple Sessions and
|
||||||
|
// service clients. All access to the credentials and refreshing them
|
||||||
|
// will be synchronized.
|
||||||
|
func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
||||||
|
p := &AssumeRoleProvider{
|
||||||
|
Client: svc,
|
||||||
|
RoleARN: roleARN,
|
||||||
|
Duration: DefaultDuration,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, option := range options {
|
||||||
|
option(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return credentials.NewCredentials(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano())
|
||||||
|
}
|
||||||
|
if p.Duration == 0 {
|
||||||
|
// Expire as often as AWS permits.
|
||||||
|
p.Duration = DefaultDuration
|
||||||
|
}
|
||||||
|
input := &sts.AssumeRoleInput{
|
||||||
|
DurationSeconds: aws.Int64(int64(p.Duration / time.Second)),
|
||||||
|
RoleArn: aws.String(p.RoleARN),
|
||||||
|
RoleSessionName: aws.String(p.RoleSessionName),
|
||||||
|
ExternalId: p.ExternalID,
|
||||||
|
}
|
||||||
|
if p.Policy != nil {
|
||||||
|
input.Policy = p.Policy
|
||||||
|
}
|
||||||
|
if p.SerialNumber != nil {
|
||||||
|
if p.TokenCode != nil {
|
||||||
|
input.SerialNumber = p.SerialNumber
|
||||||
|
input.TokenCode = p.TokenCode
|
||||||
|
} else if p.TokenProvider != nil {
|
||||||
|
input.SerialNumber = p.SerialNumber
|
||||||
|
code, err := p.TokenProvider()
|
||||||
|
if err != nil {
|
||||||
|
return credentials.Value{ProviderName: ProviderName}, err
|
||||||
|
}
|
||||||
|
input.TokenCode = aws.String(code)
|
||||||
|
} else {
|
||||||
|
return credentials.Value{ProviderName: ProviderName},
|
||||||
|
awserr.New("AssumeRoleTokenNotAvailable",
|
||||||
|
"assume role with MFA enabled, but neither TokenCode nor TokenProvider are set", nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
roleOutput, err := p.Client.AssumeRole(input)
|
||||||
|
if err != nil {
|
||||||
|
return credentials.Value{ProviderName: ProviderName}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// We will proactively generate new credentials before they expire.
|
||||||
|
p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow)
|
||||||
|
|
||||||
|
return credentials.Value{
|
||||||
|
AccessKeyID: *roleOutput.Credentials.AccessKeyId,
|
||||||
|
SecretAccessKey: *roleOutput.Credentials.SecretAccessKey,
|
||||||
|
SessionToken: *roleOutput.Credentials.SessionToken,
|
||||||
|
ProviderName: ProviderName,
|
||||||
|
}, nil
|
||||||
|
}
|
82
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
82
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
@ -8,17 +8,21 @@
|
|||||||
package defaults
|
package defaults
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials/endpointcreds"
|
||||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
"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/aws/request"
|
||||||
"github.com/aws/aws-sdk-go/private/endpoints"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Defaults provides a collection of default values for SDK clients.
|
// A Defaults provides a collection of default values for SDK clients.
|
||||||
@ -54,7 +58,7 @@ func Config() *aws.Config {
|
|||||||
WithMaxRetries(aws.UseServiceDefaultRetries).
|
WithMaxRetries(aws.UseServiceDefaultRetries).
|
||||||
WithLogger(aws.NewDefaultLogger()).
|
WithLogger(aws.NewDefaultLogger()).
|
||||||
WithLogLevel(aws.LogOff).
|
WithLogLevel(aws.LogOff).
|
||||||
WithSleepDelay(time.Sleep)
|
WithEndpointResolver(endpoints.DefaultResolver())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handlers returns the default request handlers.
|
// Handlers returns the default request handlers.
|
||||||
@ -66,9 +70,11 @@ func Handlers() request.Handlers {
|
|||||||
var handlers request.Handlers
|
var handlers request.Handlers
|
||||||
|
|
||||||
handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
||||||
|
handlers.Validate.AfterEachFn = request.HandlerListStopOnError
|
||||||
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
|
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
|
||||||
handlers.Build.AfterEachFn = request.HandlerListStopOnError
|
handlers.Build.AfterEachFn = request.HandlerListStopOnError
|
||||||
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
||||||
|
handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler)
|
||||||
handlers.Send.PushBackNamed(corehandlers.SendHandler)
|
handlers.Send.PushBackNamed(corehandlers.SendHandler)
|
||||||
handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
|
handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
|
||||||
handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler)
|
handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler)
|
||||||
@ -82,16 +88,76 @@ func Handlers() request.Handlers {
|
|||||||
// is available if you need to reset the credentials of an
|
// is available if you need to reset the credentials of an
|
||||||
// existing service client or session's Config.
|
// existing service client or session's Config.
|
||||||
func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
|
func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
|
||||||
endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, *cfg.Region, true)
|
|
||||||
|
|
||||||
return credentials.NewCredentials(&credentials.ChainProvider{
|
return credentials.NewCredentials(&credentials.ChainProvider{
|
||||||
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
|
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
|
||||||
Providers: []credentials.Provider{
|
Providers: []credentials.Provider{
|
||||||
&credentials.EnvProvider{},
|
&credentials.EnvProvider{},
|
||||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
|
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
|
||||||
&ec2rolecreds.EC2RoleProvider{
|
RemoteCredProvider(*cfg, handlers),
|
||||||
Client: ec2metadata.NewClient(*cfg, handlers, endpoint, signingRegion),
|
|
||||||
ExpiryWindow: 5 * time.Minute,
|
|
||||||
},
|
},
|
||||||
}})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
|
||||||
|
ecsCredsProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RemoteCredProvider returns a credentials provider for the default remote
|
||||||
|
// endpoints such as EC2 or ECS Roles.
|
||||||
|
func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
|
||||||
|
if u := os.Getenv(httpProviderEnvVar); len(u) > 0 {
|
||||||
|
return localHTTPCredProvider(cfg, handlers, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
if uri := os.Getenv(ecsCredsProviderEnvVar); len(uri) > 0 {
|
||||||
|
u := fmt.Sprintf("http://169.254.170.2%s", uri)
|
||||||
|
return httpCredProvider(cfg, handlers, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ec2RoleProvider(cfg, handlers)
|
||||||
|
}
|
||||||
|
|
||||||
|
func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
|
||||||
|
var errMsg string
|
||||||
|
|
||||||
|
parsed, err := url.Parse(u)
|
||||||
|
if err != nil {
|
||||||
|
errMsg = fmt.Sprintf("invalid URL, %v", err)
|
||||||
|
} else if host := aws.URLHostname(parsed); !(host == "localhost" || host == "127.0.0.1") {
|
||||||
|
errMsg = fmt.Sprintf("invalid host address, %q, only localhost and 127.0.0.1 are valid.", host)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(errMsg) > 0 {
|
||||||
|
if cfg.Logger != nil {
|
||||||
|
cfg.Logger.Log("Ignoring, HTTP credential provider", errMsg, err)
|
||||||
|
}
|
||||||
|
return credentials.ErrorProvider{
|
||||||
|
Err: awserr.New("CredentialsEndpointError", errMsg, err),
|
||||||
|
ProviderName: endpointcreds.ProviderName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpCredProvider(cfg, handlers, u)
|
||||||
|
}
|
||||||
|
|
||||||
|
func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
|
||||||
|
return endpointcreds.NewProviderClient(cfg, handlers, u,
|
||||||
|
func(p *endpointcreds.Provider) {
|
||||||
|
p.ExpiryWindow = 5 * time.Minute
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
|
||||||
|
resolver := cfg.EndpointResolver
|
||||||
|
if resolver == nil {
|
||||||
|
resolver = endpoints.DefaultResolver()
|
||||||
|
}
|
||||||
|
|
||||||
|
e, _ := resolver.EndpointFor(endpoints.Ec2metadataServiceID, "")
|
||||||
|
return &ec2rolecreds.EC2RoleProvider{
|
||||||
|
Client: ec2metadata.NewClient(cfg, handlers, e.URL, e.SigningRegion),
|
||||||
|
ExpiryWindow: 5 * time.Minute,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
27
vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go
generated
vendored
Normal file
27
vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package defaults
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SharedCredentialsFilename returns the SDK's default file path
|
||||||
|
// for the shared credentials file.
|
||||||
|
//
|
||||||
|
// Builds the shared config file path based on the OS's platform.
|
||||||
|
//
|
||||||
|
// - Linux/Unix: $HOME/.aws/credentials
|
||||||
|
// - Windows: %USERPROFILE%\.aws\credentials
|
||||||
|
func SharedCredentialsFilename() string {
|
||||||
|
return shareddefaults.SharedCredentialsFilename()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SharedConfigFilename returns the SDK's default file path for
|
||||||
|
// the shared config file.
|
||||||
|
//
|
||||||
|
// Builds the shared config file path based on the OS's platform.
|
||||||
|
//
|
||||||
|
// - Linux/Unix: $HOME/.aws/config
|
||||||
|
// - Windows: %USERPROFILE%\.aws\config
|
||||||
|
func SharedConfigFilename() string {
|
||||||
|
return shareddefaults.SharedConfigFilename()
|
||||||
|
}
|
56
vendor/github.com/aws/aws-sdk-go/aws/doc.go
generated
vendored
Normal file
56
vendor/github.com/aws/aws-sdk-go/aws/doc.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Package aws provides the core SDK's utilities and shared types. Use this package's
|
||||||
|
// utilities to simplify setting and reading API operations parameters.
|
||||||
|
//
|
||||||
|
// Value and Pointer Conversion Utilities
|
||||||
|
//
|
||||||
|
// This package includes a helper conversion utility for each scalar type the SDK's
|
||||||
|
// API use. These utilities make getting a pointer of the scalar, and dereferencing
|
||||||
|
// a pointer easier.
|
||||||
|
//
|
||||||
|
// Each conversion utility comes in two forms. Value to Pointer and Pointer to Value.
|
||||||
|
// The Pointer to value will safely dereference the pointer and return its value.
|
||||||
|
// If the pointer was nil, the scalar's zero value will be returned.
|
||||||
|
//
|
||||||
|
// The value to pointer functions will be named after the scalar type. So get a
|
||||||
|
// *string from a string value use the "String" function. This makes it easy to
|
||||||
|
// to get pointer of a literal string value, because getting the address of a
|
||||||
|
// literal requires assigning the value to a variable first.
|
||||||
|
//
|
||||||
|
// var strPtr *string
|
||||||
|
//
|
||||||
|
// // Without the SDK's conversion functions
|
||||||
|
// str := "my string"
|
||||||
|
// strPtr = &str
|
||||||
|
//
|
||||||
|
// // With the SDK's conversion functions
|
||||||
|
// strPtr = aws.String("my string")
|
||||||
|
//
|
||||||
|
// // Convert *string to string value
|
||||||
|
// str = aws.StringValue(strPtr)
|
||||||
|
//
|
||||||
|
// In addition to scalars the aws package also includes conversion utilities for
|
||||||
|
// map and slice for commonly types used in API parameters. The map and slice
|
||||||
|
// conversion functions use similar naming pattern as the scalar conversion
|
||||||
|
// functions.
|
||||||
|
//
|
||||||
|
// var strPtrs []*string
|
||||||
|
// var strs []string = []string{"Go", "Gophers", "Go"}
|
||||||
|
//
|
||||||
|
// // Convert []string to []*string
|
||||||
|
// strPtrs = aws.StringSlice(strs)
|
||||||
|
//
|
||||||
|
// // Convert []*string to []string
|
||||||
|
// strs = aws.StringValueSlice(strPtrs)
|
||||||
|
//
|
||||||
|
// SDK Default HTTP Client
|
||||||
|
//
|
||||||
|
// The SDK will use the http.DefaultClient if a HTTP client is not provided to
|
||||||
|
// the SDK's Session, or service client constructor. This means that if the
|
||||||
|
// http.DefaultClient is modified by other components of your application the
|
||||||
|
// modifications will be picked up by the SDK as well.
|
||||||
|
//
|
||||||
|
// In some cases this might be intended, but it is a better practice to create
|
||||||
|
// a custom HTTP Client to share explicitly through your application. You can
|
||||||
|
// configure the SDK to use the custom HTTP Client by setting the HTTPClient
|
||||||
|
// value of the SDK's Config type when creating a Session or service client.
|
||||||
|
package aws
|
121
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
generated
vendored
121
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
generated
vendored
@ -1,12 +1,20 @@
|
|||||||
package ec2metadata
|
package ec2metadata
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetMetadata uses the path provided to request
|
// GetMetadata uses the path provided to request information from the EC2
|
||||||
|
// instance metdata service. The content will be returned as a string, or
|
||||||
|
// error if the request failed.
|
||||||
func (c *EC2Metadata) GetMetadata(p string) (string, error) {
|
func (c *EC2Metadata) GetMetadata(p string) (string, error) {
|
||||||
op := &request.Operation{
|
op := &request.Operation{
|
||||||
Name: "GetMetadata",
|
Name: "GetMetadata",
|
||||||
@ -20,6 +28,89 @@ func (c *EC2Metadata) GetMetadata(p string) (string, error) {
|
|||||||
return output.Content, req.Send()
|
return output.Content, req.Send()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetUserData returns the userdata that was configured for the service. If
|
||||||
|
// there is no user-data setup for the EC2 instance a "NotFoundError" error
|
||||||
|
// code will be returned.
|
||||||
|
func (c *EC2Metadata) GetUserData() (string, error) {
|
||||||
|
op := &request.Operation{
|
||||||
|
Name: "GetUserData",
|
||||||
|
HTTPMethod: "GET",
|
||||||
|
HTTPPath: path.Join("/", "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()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDynamicData uses the path provided to request information from the EC2
|
||||||
|
// instance metadata service for dynamic data. The content will be returned
|
||||||
|
// as a string, or error if the request failed.
|
||||||
|
func (c *EC2Metadata) GetDynamicData(p string) (string, error) {
|
||||||
|
op := &request.Operation{
|
||||||
|
Name: "GetDynamicData",
|
||||||
|
HTTPMethod: "GET",
|
||||||
|
HTTPPath: path.Join("/", "dynamic", p),
|
||||||
|
}
|
||||||
|
|
||||||
|
output := &metadataOutput{}
|
||||||
|
req := c.NewRequest(op, nil, output)
|
||||||
|
|
||||||
|
return output.Content, req.Send()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInstanceIdentityDocument retrieves an identity document describing an
|
||||||
|
// instance. Error is returned if the request fails or is unable to parse
|
||||||
|
// the response.
|
||||||
|
func (c *EC2Metadata) GetInstanceIdentityDocument() (EC2InstanceIdentityDocument, error) {
|
||||||
|
resp, err := c.GetDynamicData("instance-identity/document")
|
||||||
|
if err != nil {
|
||||||
|
return EC2InstanceIdentityDocument{},
|
||||||
|
awserr.New("EC2MetadataRequestError",
|
||||||
|
"failed to get EC2 instance identity document", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
doc := EC2InstanceIdentityDocument{}
|
||||||
|
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&doc); err != nil {
|
||||||
|
return EC2InstanceIdentityDocument{},
|
||||||
|
awserr.New("SerializationError",
|
||||||
|
"failed to decode EC2 instance identity document", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return doc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IAMInfo retrieves IAM info from the metadata API
|
||||||
|
func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) {
|
||||||
|
resp, err := c.GetMetadata("iam/info")
|
||||||
|
if err != nil {
|
||||||
|
return EC2IAMInfo{},
|
||||||
|
awserr.New("EC2MetadataRequestError",
|
||||||
|
"failed to get EC2 IAM info", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
info := EC2IAMInfo{}
|
||||||
|
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&info); err != nil {
|
||||||
|
return EC2IAMInfo{},
|
||||||
|
awserr.New("SerializationError",
|
||||||
|
"failed to decode EC2 IAM info", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.Code != "Success" {
|
||||||
|
errMsg := fmt.Sprintf("failed to get EC2 IAM Info (%s)", info.Code)
|
||||||
|
return EC2IAMInfo{},
|
||||||
|
awserr.New("EC2MetadataError", errMsg, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
return info, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Region returns the region the instance is running in.
|
// Region returns the region the instance is running in.
|
||||||
func (c *EC2Metadata) Region() (string, error) {
|
func (c *EC2Metadata) Region() (string, error) {
|
||||||
resp, err := c.GetMetadata("placement/availability-zone")
|
resp, err := c.GetMetadata("placement/availability-zone")
|
||||||
@ -41,3 +132,31 @@ func (c *EC2Metadata) Available() bool {
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// An EC2IAMInfo provides the shape for unmarshaling
|
||||||
|
// an IAM info from the metadata API
|
||||||
|
type EC2IAMInfo struct {
|
||||||
|
Code string
|
||||||
|
LastUpdated time.Time
|
||||||
|
InstanceProfileArn string
|
||||||
|
InstanceProfileID string
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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"`
|
||||||
|
}
|
||||||
|
133
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
generated
vendored
Normal file
133
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
package endpoints
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
)
|
||||||
|
|
||||||
|
type modelDefinition map[string]json.RawMessage
|
||||||
|
|
||||||
|
// A DecodeModelOptions are the options for how the endpoints model definition
|
||||||
|
// are decoded.
|
||||||
|
type DecodeModelOptions struct {
|
||||||
|
SkipCustomizations bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set combines all of the option functions together.
|
||||||
|
func (d *DecodeModelOptions) Set(optFns ...func(*DecodeModelOptions)) {
|
||||||
|
for _, fn := range optFns {
|
||||||
|
fn(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeModel unmarshals a Regions and Endpoint model definition file into
|
||||||
|
// a endpoint Resolver. If the file format is not supported, or an error occurs
|
||||||
|
// when unmarshaling the model an error will be returned.
|
||||||
|
//
|
||||||
|
// Casting the return value of this func to a EnumPartitions will
|
||||||
|
// allow you to get a list of the partitions in the order the endpoints
|
||||||
|
// will be resolved in.
|
||||||
|
//
|
||||||
|
// resolver, err := endpoints.DecodeModel(reader)
|
||||||
|
//
|
||||||
|
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
|
||||||
|
// for _, p := range partitions {
|
||||||
|
// // ... inspect partitions
|
||||||
|
// }
|
||||||
|
func DecodeModel(r io.Reader, optFns ...func(*DecodeModelOptions)) (Resolver, error) {
|
||||||
|
var opts DecodeModelOptions
|
||||||
|
opts.Set(optFns...)
|
||||||
|
|
||||||
|
// Get the version of the partition file to determine what
|
||||||
|
// unmarshaling model to use.
|
||||||
|
modelDef := modelDefinition{}
|
||||||
|
if err := json.NewDecoder(r).Decode(&modelDef); err != nil {
|
||||||
|
return nil, newDecodeModelError("failed to decode endpoints model", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var version string
|
||||||
|
if b, ok := modelDef["version"]; ok {
|
||||||
|
version = string(b)
|
||||||
|
} else {
|
||||||
|
return nil, newDecodeModelError("endpoints version not found in model", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
if version == "3" {
|
||||||
|
return decodeV3Endpoints(modelDef, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, newDecodeModelError(
|
||||||
|
fmt.Sprintf("endpoints version %s, not supported", version), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resolver, error) {
|
||||||
|
b, ok := modelDef["partitions"]
|
||||||
|
if !ok {
|
||||||
|
return nil, newDecodeModelError("endpoints model missing partitions", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
ps := partitions{}
|
||||||
|
if err := json.Unmarshal(b, &ps); err != nil {
|
||||||
|
return nil, newDecodeModelError("failed to decode endpoints model", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.SkipCustomizations {
|
||||||
|
return ps, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Customization
|
||||||
|
for i := 0; i < len(ps); i++ {
|
||||||
|
p := &ps[i]
|
||||||
|
custAddEC2Metadata(p)
|
||||||
|
custAddS3DualStack(p)
|
||||||
|
custRmIotDataService(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ps, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func custAddS3DualStack(p *partition) {
|
||||||
|
if p.ID != "aws" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s, ok := p.Services["s3"]
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Defaults.HasDualStack = boxedTrue
|
||||||
|
s.Defaults.DualStackHostname = "{service}.dualstack.{region}.{dnsSuffix}"
|
||||||
|
|
||||||
|
p.Services["s3"] = s
|
||||||
|
}
|
||||||
|
|
||||||
|
func custAddEC2Metadata(p *partition) {
|
||||||
|
p.Services["ec2metadata"] = service{
|
||||||
|
IsRegionalized: boxedFalse,
|
||||||
|
PartitionEndpoint: "aws-global",
|
||||||
|
Endpoints: endpoints{
|
||||||
|
"aws-global": endpoint{
|
||||||
|
Hostname: "169.254.169.254/latest",
|
||||||
|
Protocols: []string{"http"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func custRmIotDataService(p *partition) {
|
||||||
|
delete(p.Services, "data.iot")
|
||||||
|
}
|
||||||
|
|
||||||
|
type decodeModelError struct {
|
||||||
|
awsError
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDecodeModelError(msg string, err error) decodeModelError {
|
||||||
|
return decodeModelError{
|
||||||
|
awsError: awserr.New("DecodeEndpointsModelError", msg, err),
|
||||||
|
}
|
||||||
|
}
|
2424
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
Normal file
2424
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
66
vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go
generated
vendored
Normal file
66
vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Package endpoints provides the types and functionality for defining regions
|
||||||
|
// and endpoints, as well as querying those definitions.
|
||||||
|
//
|
||||||
|
// The SDK's Regions and Endpoints metadata is code generated into the endpoints
|
||||||
|
// package, and is accessible via the DefaultResolver function. This function
|
||||||
|
// returns a endpoint Resolver will search the metadata and build an associated
|
||||||
|
// endpoint if one is found. The default resolver will search all partitions
|
||||||
|
// known by the SDK. e.g AWS Standard (aws), AWS China (aws-cn), and
|
||||||
|
// AWS GovCloud (US) (aws-us-gov).
|
||||||
|
// .
|
||||||
|
//
|
||||||
|
// Enumerating Regions and Endpoint Metadata
|
||||||
|
//
|
||||||
|
// Casting the Resolver returned by DefaultResolver to a EnumPartitions interface
|
||||||
|
// will allow you to get access to the list of underlying Partitions with the
|
||||||
|
// Partitions method. This is helpful if you want to limit the SDK's endpoint
|
||||||
|
// resolving to a single partition, or enumerate regions, services, and endpoints
|
||||||
|
// in the partition.
|
||||||
|
//
|
||||||
|
// resolver := endpoints.DefaultResolver()
|
||||||
|
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
|
||||||
|
//
|
||||||
|
// for _, p := range partitions {
|
||||||
|
// fmt.Println("Regions for", p.ID())
|
||||||
|
// for id, _ := range p.Regions() {
|
||||||
|
// fmt.Println("*", id)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fmt.Println("Services for", p.ID())
|
||||||
|
// for id, _ := range p.Services() {
|
||||||
|
// fmt.Println("*", id)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Using Custom Endpoints
|
||||||
|
//
|
||||||
|
// The endpoints package also gives you the ability to use your own logic how
|
||||||
|
// endpoints are resolved. This is a great way to define a custom endpoint
|
||||||
|
// for select services, without passing that logic down through your code.
|
||||||
|
//
|
||||||
|
// If a type implements the Resolver interface it can be used to resolve
|
||||||
|
// endpoints. To use this with the SDK's Session and Config set the value
|
||||||
|
// of the type to the EndpointsResolver field of aws.Config when initializing
|
||||||
|
// the session, or service client.
|
||||||
|
//
|
||||||
|
// In addition the ResolverFunc is a wrapper for a func matching the signature
|
||||||
|
// of Resolver.EndpointFor, converting it to a type that satisfies the
|
||||||
|
// Resolver interface.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
|
||||||
|
// if service == endpoints.S3ServiceID {
|
||||||
|
// return endpoints.ResolvedEndpoint{
|
||||||
|
// URL: "s3.custom.endpoint.com",
|
||||||
|
// SigningRegion: "custom-signing-region",
|
||||||
|
// }, nil
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return endpoints.DefaultResolver().EndpointFor(service, region, optFns...)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// sess := session.Must(session.NewSession(&aws.Config{
|
||||||
|
// Region: aws.String("us-west-2"),
|
||||||
|
// EndpointResolver: endpoints.ResolverFunc(myCustomResolver),
|
||||||
|
// }))
|
||||||
|
package endpoints
|
439
vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
generated
vendored
Normal file
439
vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
generated
vendored
Normal file
@ -0,0 +1,439 @@
|
|||||||
|
package endpoints
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Options provide the configuration needed to direct how the
|
||||||
|
// endpoints will be resolved.
|
||||||
|
type Options struct {
|
||||||
|
// DisableSSL forces the endpoint to be resolved as HTTP.
|
||||||
|
// instead of HTTPS if the service supports it.
|
||||||
|
DisableSSL bool
|
||||||
|
|
||||||
|
// Sets the resolver to resolve the endpoint as a dualstack endpoint
|
||||||
|
// for the service. If dualstack support for a service is not known and
|
||||||
|
// StrictMatching is not enabled a dualstack endpoint for the service will
|
||||||
|
// be returned. This endpoint may not be valid. If StrictMatching is
|
||||||
|
// enabled only services that are known to support dualstack will return
|
||||||
|
// dualstack endpoints.
|
||||||
|
UseDualStack bool
|
||||||
|
|
||||||
|
// Enables strict matching of services and regions resolved endpoints.
|
||||||
|
// If the partition doesn't enumerate the exact service and region an
|
||||||
|
// error will be returned. This option will prevent returning endpoints
|
||||||
|
// that look valid, but may not resolve to any real endpoint.
|
||||||
|
StrictMatching bool
|
||||||
|
|
||||||
|
// Enables resolving a service endpoint based on the region provided if the
|
||||||
|
// service does not exist. The service endpoint ID will be used as the service
|
||||||
|
// domain name prefix. By default the endpoint resolver requires the service
|
||||||
|
// to be known when resolving endpoints.
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
// the endpoint on partition list an UnknownEndpointError error will be returned.
|
||||||
|
//
|
||||||
|
// If resolving and endpoint on a partition specific resolver that partition's
|
||||||
|
// domain name pattern will be used with the service endpoint ID. If both
|
||||||
|
// region and service do not exist when resolving an endpoint on a specific
|
||||||
|
// partition the partition's domain pattern will be used to combine the
|
||||||
|
// endpoint and region together.
|
||||||
|
//
|
||||||
|
// This option is ignored if StrictMatching is enabled.
|
||||||
|
ResolveUnknownService bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set combines all of the option functions together.
|
||||||
|
func (o *Options) Set(optFns ...func(*Options)) {
|
||||||
|
for _, fn := range optFns {
|
||||||
|
fn(o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableSSLOption sets the DisableSSL options. Can be used as a functional
|
||||||
|
// option when resolving endpoints.
|
||||||
|
func DisableSSLOption(o *Options) {
|
||||||
|
o.DisableSSL = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// UseDualStackOption sets the UseDualStack option. Can be used as a functional
|
||||||
|
// option when resolving endpoints.
|
||||||
|
func UseDualStackOption(o *Options) {
|
||||||
|
o.UseDualStack = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// StrictMatchingOption sets the StrictMatching option. Can be used as a functional
|
||||||
|
// option when resolving endpoints.
|
||||||
|
func StrictMatchingOption(o *Options) {
|
||||||
|
o.StrictMatching = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResolveUnknownServiceOption sets the ResolveUnknownService option. Can be used
|
||||||
|
// as a functional option when resolving endpoints.
|
||||||
|
func ResolveUnknownServiceOption(o *Options) {
|
||||||
|
o.ResolveUnknownService = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Resolver provides the interface for functionality to resolve endpoints.
|
||||||
|
// The build in Partition and DefaultResolver return value satisfy this interface.
|
||||||
|
type Resolver interface {
|
||||||
|
EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResolverFunc is a helper utility that wraps a function so it satisfies the
|
||||||
|
// Resolver interface. This is useful when you want to add additional endpoint
|
||||||
|
// resolving logic, or stub out specific endpoints with custom values.
|
||||||
|
type ResolverFunc func(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
|
||||||
|
|
||||||
|
// EndpointFor wraps the ResolverFunc function to satisfy the Resolver interface.
|
||||||
|
func (fn ResolverFunc) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
||||||
|
return fn(service, region, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
var schemeRE = regexp.MustCompile("^([^:]+)://")
|
||||||
|
|
||||||
|
// AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no
|
||||||
|
// scheme. If disableSSL is true HTTP will set HTTP instead of the default HTTPS.
|
||||||
|
//
|
||||||
|
// If disableSSL is set, it will only set the URL's scheme if the URL does not
|
||||||
|
// contain a scheme.
|
||||||
|
func AddScheme(endpoint string, disableSSL bool) string {
|
||||||
|
if !schemeRE.MatchString(endpoint) {
|
||||||
|
scheme := "https"
|
||||||
|
if disableSSL {
|
||||||
|
scheme = "http"
|
||||||
|
}
|
||||||
|
endpoint = fmt.Sprintf("%s://%s", scheme, endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
return endpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnumPartitions a provides a way to retrieve the underlying partitions that
|
||||||
|
// make up the SDK's default Resolver, or any resolver decoded from a model
|
||||||
|
// file.
|
||||||
|
//
|
||||||
|
// Use this interface with DefaultResolver and DecodeModels to get the list of
|
||||||
|
// Partitions.
|
||||||
|
type EnumPartitions interface {
|
||||||
|
Partitions() []Partition
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegionsForService returns a map of regions for the partition and service.
|
||||||
|
// If either the partition or service does not exist false will be returned
|
||||||
|
// as the second parameter.
|
||||||
|
//
|
||||||
|
// This example shows how to get the regions for DynamoDB in the AWS partition.
|
||||||
|
// rs, exists := endpoints.RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamodbServiceID)
|
||||||
|
//
|
||||||
|
// This is equivalent to using the partition directly.
|
||||||
|
// rs := endpoints.AwsPartition().Services()[endpoints.DynamodbServiceID].Regions()
|
||||||
|
func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) {
|
||||||
|
for _, p := range ps {
|
||||||
|
if p.ID() != partitionID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := p.p.Services[serviceID]; !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
s := Service{
|
||||||
|
id: serviceID,
|
||||||
|
p: p.p,
|
||||||
|
}
|
||||||
|
return s.Regions(), true
|
||||||
|
}
|
||||||
|
|
||||||
|
return map[string]Region{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// PartitionForRegion returns the first partition which includes the region
|
||||||
|
// passed in. This includes both known regions and regions which match
|
||||||
|
// a pattern supported by the partition which may include regions that are
|
||||||
|
// not explicitly known by the partition. Use the Regions method of the
|
||||||
|
// returned Partition if explicit support is needed.
|
||||||
|
func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) {
|
||||||
|
for _, p := range ps {
|
||||||
|
if _, ok := p.p.Regions[regionID]; ok || p.p.RegionRegex.MatchString(regionID) {
|
||||||
|
return p, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Partition{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Partition provides the ability to enumerate the partition's regions
|
||||||
|
// and services.
|
||||||
|
type Partition struct {
|
||||||
|
id string
|
||||||
|
p *partition
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID returns the identifier of the partition.
|
||||||
|
func (p Partition) ID() string { return p.id }
|
||||||
|
|
||||||
|
// EndpointFor attempts to resolve the endpoint based on service and region.
|
||||||
|
// See Options for information on configuring how the endpoint is resolved.
|
||||||
|
//
|
||||||
|
// If the service cannot be found in the metadata the UnknownServiceError
|
||||||
|
// error will be returned. This validation will occur regardless if
|
||||||
|
// StrictMatching is enabled. To enable resolving unknown services set the
|
||||||
|
// "ResolveUnknownService" option to true. When StrictMatching is disabled
|
||||||
|
// this option allows the partition resolver to resolve a endpoint based on
|
||||||
|
// the service endpoint ID provided.
|
||||||
|
//
|
||||||
|
// When resolving endpoints you can choose to enable StrictMatching. This will
|
||||||
|
// 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 requires the SDK to be updated if you want to take advantage
|
||||||
|
// of new regions and services expansions.
|
||||||
|
//
|
||||||
|
// Errors that can be returned.
|
||||||
|
// * UnknownServiceError
|
||||||
|
// * UnknownEndpointError
|
||||||
|
func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
||||||
|
return p.p.EndpointFor(service, region, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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[id] = Region{
|
||||||
|
id: id,
|
||||||
|
p: p.p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rs
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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{}
|
||||||
|
for id := range p.p.Services {
|
||||||
|
ss[id] = Service{
|
||||||
|
id: id,
|
||||||
|
p: p.p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Region provides information about a region, and ability to resolve an
|
||||||
|
// endpoint from the context of a region, given a service.
|
||||||
|
type Region struct {
|
||||||
|
id, desc string
|
||||||
|
p *partition
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID returns the region's identifier.
|
||||||
|
func (r Region) ID() string { return r.id }
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
return r.p.EndpointFor(service, r.id, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Services returns a list of all services that are known to be in this region.
|
||||||
|
func (r Region) Services() map[string]Service {
|
||||||
|
ss := map[string]Service{}
|
||||||
|
for id, s := range r.p.Services {
|
||||||
|
if _, ok := s.Endpoints[r.id]; ok {
|
||||||
|
ss[id] = Service{
|
||||||
|
id: id,
|
||||||
|
p: r.p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Service provides information about a service, and ability to resolve an
|
||||||
|
// endpoint from the context of a service, given a region.
|
||||||
|
type Service struct {
|
||||||
|
id string
|
||||||
|
p *partition
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID returns the identifier for the service.
|
||||||
|
func (s Service) ID() string { return s.id }
|
||||||
|
|
||||||
|
// ResolveEndpoint resolves an endpoint from the context of a service given
|
||||||
|
// a region. See Partition.EndpointFor for usage and errors that can be returned.
|
||||||
|
func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
||||||
|
return s.p.EndpointFor(s.id, region, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regions returns a map of Regions that the service is present in.
|
||||||
|
//
|
||||||
|
// 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) Regions() map[string]Region {
|
||||||
|
rs := map[string]Region{}
|
||||||
|
for id := range s.p.Services[s.id].Endpoints {
|
||||||
|
if _, ok := s.p.Regions[id]; ok {
|
||||||
|
rs[id] = Region{
|
||||||
|
id: id,
|
||||||
|
p: s.p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Endpoints returns a map of Endpoints indexed by their ID for all known
|
||||||
|
// endpoints for a service.
|
||||||
|
//
|
||||||
|
// 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{}
|
||||||
|
for id := range s.p.Services[s.id].Endpoints {
|
||||||
|
es[id] = Endpoint{
|
||||||
|
id: id,
|
||||||
|
serviceID: s.id,
|
||||||
|
p: s.p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return es
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Endpoint provides information about endpoints, and provides the ability
|
||||||
|
// to resolve that endpoint for the service, and the region the endpoint
|
||||||
|
// represents.
|
||||||
|
type Endpoint struct {
|
||||||
|
id string
|
||||||
|
serviceID string
|
||||||
|
p *partition
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID returns the identifier for an endpoint.
|
||||||
|
func (e Endpoint) ID() string { return e.id }
|
||||||
|
|
||||||
|
// ServiceID returns the identifier the endpoint belongs to.
|
||||||
|
func (e Endpoint) ServiceID() string { return e.serviceID }
|
||||||
|
|
||||||
|
// ResolveEndpoint resolves an endpoint from the context of a service and
|
||||||
|
// region the endpoint represents. See Partition.EndpointFor for usage and
|
||||||
|
// errors that can be returned.
|
||||||
|
func (e Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) {
|
||||||
|
return e.p.EndpointFor(e.serviceID, e.id, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A ResolvedEndpoint is an endpoint that has been resolved based on a partition
|
||||||
|
// service, and region.
|
||||||
|
type ResolvedEndpoint struct {
|
||||||
|
// The endpoint URL
|
||||||
|
URL string
|
||||||
|
|
||||||
|
// The region that should be used for signing requests.
|
||||||
|
SigningRegion string
|
||||||
|
|
||||||
|
// The service name that should be used for signing requests.
|
||||||
|
SigningName string
|
||||||
|
|
||||||
|
// The signing method that should be used for signing requests.
|
||||||
|
SigningMethod string
|
||||||
|
}
|
||||||
|
|
||||||
|
// So that the Error interface type can be included as an anonymous field
|
||||||
|
// in the requestError struct and not conflict with the error.Error() method.
|
||||||
|
type awsError awserr.Error
|
||||||
|
|
||||||
|
// A EndpointNotFoundError is returned when in StrictMatching mode, and the
|
||||||
|
// endpoint for the service and region cannot be found in any of the partitions.
|
||||||
|
type EndpointNotFoundError struct {
|
||||||
|
awsError
|
||||||
|
Partition string
|
||||||
|
Service string
|
||||||
|
Region string
|
||||||
|
}
|
||||||
|
|
||||||
|
// A UnknownServiceError is returned when the service does not resolve to an
|
||||||
|
// endpoint. Includes a list of all known services for the partition. Returned
|
||||||
|
// when a partition does not support the service.
|
||||||
|
type UnknownServiceError struct {
|
||||||
|
awsError
|
||||||
|
Partition string
|
||||||
|
Service string
|
||||||
|
Known []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnknownServiceError builds and returns UnknownServiceError.
|
||||||
|
func NewUnknownServiceError(p, s string, known []string) UnknownServiceError {
|
||||||
|
return UnknownServiceError{
|
||||||
|
awsError: awserr.New("UnknownServiceError",
|
||||||
|
"could not resolve endpoint for unknown service", nil),
|
||||||
|
Partition: p,
|
||||||
|
Service: s,
|
||||||
|
Known: known,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the error.
|
||||||
|
func (e UnknownServiceError) Error() string {
|
||||||
|
extra := fmt.Sprintf("partition: %q, service: %q",
|
||||||
|
e.Partition, e.Service)
|
||||||
|
if len(e.Known) > 0 {
|
||||||
|
extra += fmt.Sprintf(", known: %v", e.Known)
|
||||||
|
}
|
||||||
|
return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the error.
|
||||||
|
func (e UnknownServiceError) String() string {
|
||||||
|
return e.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// A UnknownEndpointError is returned when in StrictMatching mode and the
|
||||||
|
// service is valid, but the region does not resolve to an endpoint. Includes
|
||||||
|
// a list of all known endpoints for the service.
|
||||||
|
type UnknownEndpointError struct {
|
||||||
|
awsError
|
||||||
|
Partition string
|
||||||
|
Service string
|
||||||
|
Region string
|
||||||
|
Known []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnknownEndpointError builds and returns UnknownEndpointError.
|
||||||
|
func NewUnknownEndpointError(p, s, r string, known []string) UnknownEndpointError {
|
||||||
|
return UnknownEndpointError{
|
||||||
|
awsError: awserr.New("UnknownEndpointError",
|
||||||
|
"could not resolve endpoint", nil),
|
||||||
|
Partition: p,
|
||||||
|
Service: s,
|
||||||
|
Region: r,
|
||||||
|
Known: known,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the error.
|
||||||
|
func (e UnknownEndpointError) Error() string {
|
||||||
|
extra := fmt.Sprintf("partition: %q, service: %q, region: %q",
|
||||||
|
e.Partition, e.Service, e.Region)
|
||||||
|
if len(e.Known) > 0 {
|
||||||
|
extra += fmt.Sprintf(", known: %v", e.Known)
|
||||||
|
}
|
||||||
|
return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the string representation of the error.
|
||||||
|
func (e UnknownEndpointError) String() string {
|
||||||
|
return e.Error()
|
||||||
|
}
|
303
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go
generated
vendored
Normal file
303
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go
generated
vendored
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
package endpoints
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type partitions []partition
|
||||||
|
|
||||||
|
func (ps partitions) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
||||||
|
var opt Options
|
||||||
|
opt.Set(opts...)
|
||||||
|
|
||||||
|
for i := 0; i < len(ps); i++ {
|
||||||
|
if !ps[i].canResolveEndpoint(service, region, opt.StrictMatching) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return ps[i].EndpointFor(service, region, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If loose matching fallback to first partition format to use
|
||||||
|
// when resolving the endpoint.
|
||||||
|
if !opt.StrictMatching && len(ps) > 0 {
|
||||||
|
return ps[0].EndpointFor(service, region, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResolvedEndpoint{}, NewUnknownEndpointError("all partitions", service, region, []string{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Partitions satisfies the EnumPartitions interface and returns a list
|
||||||
|
// of Partitions representing each partition represented in the SDK's
|
||||||
|
// endpoints model.
|
||||||
|
func (ps partitions) Partitions() []Partition {
|
||||||
|
parts := make([]Partition, 0, len(ps))
|
||||||
|
for i := 0; i < len(ps); i++ {
|
||||||
|
parts = append(parts, ps[i].Partition())
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts
|
||||||
|
}
|
||||||
|
|
||||||
|
type partition struct {
|
||||||
|
ID string `json:"partition"`
|
||||||
|
Name string `json:"partitionName"`
|
||||||
|
DNSSuffix string `json:"dnsSuffix"`
|
||||||
|
RegionRegex regionRegex `json:"regionRegex"`
|
||||||
|
Defaults endpoint `json:"defaults"`
|
||||||
|
Regions regions `json:"regions"`
|
||||||
|
Services services `json:"services"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p partition) Partition() Partition {
|
||||||
|
return Partition{
|
||||||
|
id: p.ID,
|
||||||
|
p: &p,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p partition) canResolveEndpoint(service, region string, strictMatch bool) bool {
|
||||||
|
s, hasService := p.Services[service]
|
||||||
|
_, hasEndpoint := s.Endpoints[region]
|
||||||
|
|
||||||
|
if hasEndpoint && hasService {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if strictMatch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.RegionRegex.MatchString(region)
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
// 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))
|
||||||
|
}
|
||||||
|
|
||||||
|
e, hasEndpoint := s.endpointForRegion(region)
|
||||||
|
if !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
|
||||||
|
}
|
||||||
|
|
||||||
|
func serviceList(ss services) []string {
|
||||||
|
list := make([]string, 0, len(ss))
|
||||||
|
for k := range ss {
|
||||||
|
list = append(list, k)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
func endpointList(es endpoints) []string {
|
||||||
|
list := make([]string, 0, len(es))
|
||||||
|
for k := range es {
|
||||||
|
list = append(list, k)
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
type regionRegex struct {
|
||||||
|
*regexp.Regexp
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rr *regionRegex) UnmarshalJSON(b []byte) (err error) {
|
||||||
|
// Strip leading and trailing quotes
|
||||||
|
regex, err := strconv.Unquote(string(b))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to strip quotes from regex, %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rr.Regexp, err = regexp.Compile(regex)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to unmarshal region regex, %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type regions map[string]region
|
||||||
|
|
||||||
|
type region struct {
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type services map[string]service
|
||||||
|
|
||||||
|
type service struct {
|
||||||
|
PartitionEndpoint string `json:"partitionEndpoint"`
|
||||||
|
IsRegionalized boxedBool `json:"isRegionalized,omitempty"`
|
||||||
|
Defaults endpoint `json:"defaults"`
|
||||||
|
Endpoints endpoints `json:"endpoints"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) endpointForRegion(region string) (endpoint, bool) {
|
||||||
|
if s.IsRegionalized == boxedFalse {
|
||||||
|
return s.Endpoints[s.PartitionEndpoint], region == s.PartitionEndpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
if e, ok := s.Endpoints[region]; ok {
|
||||||
|
return e, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unable to find any matching endpoint, return
|
||||||
|
// blank that will be used for generic endpoint creation.
|
||||||
|
return endpoint{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
type endpoints map[string]endpoint
|
||||||
|
|
||||||
|
type endpoint struct {
|
||||||
|
Hostname string `json:"hostname"`
|
||||||
|
Protocols []string `json:"protocols"`
|
||||||
|
CredentialScope credentialScope `json:"credentialScope"`
|
||||||
|
|
||||||
|
// Custom fields not modeled
|
||||||
|
HasDualStack boxedBool `json:"-"`
|
||||||
|
DualStackHostname string `json:"-"`
|
||||||
|
|
||||||
|
// Signature Version not used
|
||||||
|
SignatureVersions []string `json:"signatureVersions"`
|
||||||
|
|
||||||
|
// SSLCommonName not used.
|
||||||
|
SSLCommonName string `json:"sslCommonName"`
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
defaultProtocol = "https"
|
||||||
|
defaultSigner = "v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
protocolPriority = []string{"https", "http"}
|
||||||
|
signerPriority = []string{"v4", "v2"}
|
||||||
|
)
|
||||||
|
|
||||||
|
func getByPriority(s []string, p []string, def string) string {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(p); i++ {
|
||||||
|
for j := 0; j < len(s); j++ {
|
||||||
|
if s[j] == p[i] {
|
||||||
|
return s[j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, opts Options) ResolvedEndpoint {
|
||||||
|
var merged endpoint
|
||||||
|
for _, def := range defs {
|
||||||
|
merged.mergeIn(def)
|
||||||
|
}
|
||||||
|
merged.mergeIn(e)
|
||||||
|
e = merged
|
||||||
|
|
||||||
|
hostname := e.Hostname
|
||||||
|
|
||||||
|
// Offset the hostname for dualstack if enabled
|
||||||
|
if opts.UseDualStack && e.HasDualStack == boxedTrue {
|
||||||
|
hostname = e.DualStackHostname
|
||||||
|
}
|
||||||
|
|
||||||
|
u := strings.Replace(hostname, "{service}", service, 1)
|
||||||
|
u = strings.Replace(u, "{region}", region, 1)
|
||||||
|
u = strings.Replace(u, "{dnsSuffix}", dnsSuffix, 1)
|
||||||
|
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEndpointScheme(protocols []string, disableSSL bool) string {
|
||||||
|
if disableSSL {
|
||||||
|
return "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
return getByPriority(protocols, protocolPriority, defaultProtocol)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *endpoint) mergeIn(other endpoint) {
|
||||||
|
if len(other.Hostname) > 0 {
|
||||||
|
e.Hostname = other.Hostname
|
||||||
|
}
|
||||||
|
if len(other.Protocols) > 0 {
|
||||||
|
e.Protocols = other.Protocols
|
||||||
|
}
|
||||||
|
if len(other.SignatureVersions) > 0 {
|
||||||
|
e.SignatureVersions = other.SignatureVersions
|
||||||
|
}
|
||||||
|
if len(other.CredentialScope.Region) > 0 {
|
||||||
|
e.CredentialScope.Region = other.CredentialScope.Region
|
||||||
|
}
|
||||||
|
if len(other.CredentialScope.Service) > 0 {
|
||||||
|
e.CredentialScope.Service = other.CredentialScope.Service
|
||||||
|
}
|
||||||
|
if len(other.SSLCommonName) > 0 {
|
||||||
|
e.SSLCommonName = other.SSLCommonName
|
||||||
|
}
|
||||||
|
if other.HasDualStack != boxedBoolUnset {
|
||||||
|
e.HasDualStack = other.HasDualStack
|
||||||
|
}
|
||||||
|
if len(other.DualStackHostname) > 0 {
|
||||||
|
e.DualStackHostname = other.DualStackHostname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type credentialScope struct {
|
||||||
|
Region string `json:"region"`
|
||||||
|
Service string `json:"service"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type boxedBool int
|
||||||
|
|
||||||
|
func (b *boxedBool) UnmarshalJSON(buf []byte) error {
|
||||||
|
v, err := strconv.ParseBool(string(buf))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if v {
|
||||||
|
*b = boxedTrue
|
||||||
|
} else {
|
||||||
|
*b = boxedFalse
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
boxedBoolUnset boxedBool = iota
|
||||||
|
boxedFalse
|
||||||
|
boxedTrue
|
||||||
|
)
|
337
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go
generated
vendored
Normal file
337
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go
generated
vendored
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
// +build codegen
|
||||||
|
|
||||||
|
package endpoints
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
"unicode"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A CodeGenOptions are the options for code generating the endpoints into
|
||||||
|
// Go code from the endpoints model definition.
|
||||||
|
type CodeGenOptions struct {
|
||||||
|
// Options for how the model will be decoded.
|
||||||
|
DecodeModelOptions DecodeModelOptions
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set combines all of the option functions together
|
||||||
|
func (d *CodeGenOptions) Set(optFns ...func(*CodeGenOptions)) {
|
||||||
|
for _, fn := range optFns {
|
||||||
|
fn(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CodeGenModel given a endpoints model file will decode it and attempt to
|
||||||
|
// generate Go code from the model definition. Error will be returned if
|
||||||
|
// the code is unable to be generated, or decoded.
|
||||||
|
func CodeGenModel(modelFile io.Reader, outFile io.Writer, optFns ...func(*CodeGenOptions)) error {
|
||||||
|
var opts CodeGenOptions
|
||||||
|
opts.Set(optFns...)
|
||||||
|
|
||||||
|
resolver, err := DecodeModel(modelFile, func(d *DecodeModelOptions) {
|
||||||
|
*d = opts.DecodeModelOptions
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpl := template.Must(template.New("tmpl").Funcs(funcMap).Parse(v3Tmpl))
|
||||||
|
if err := tmpl.ExecuteTemplate(outFile, "defaults", resolver); err != nil {
|
||||||
|
return fmt.Errorf("failed to execute template, %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func toSymbol(v string) string {
|
||||||
|
out := []rune{}
|
||||||
|
for _, c := range strings.Title(v) {
|
||||||
|
if !(unicode.IsNumber(c) || unicode.IsLetter(c)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
out = append(out, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func quoteString(v string) string {
|
||||||
|
return fmt.Sprintf("%q", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func regionConstName(p, r string) string {
|
||||||
|
return toSymbol(p) + toSymbol(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func partitionGetter(id string) string {
|
||||||
|
return fmt.Sprintf("%sPartition", toSymbol(id))
|
||||||
|
}
|
||||||
|
|
||||||
|
func partitionVarName(id string) string {
|
||||||
|
return fmt.Sprintf("%sPartition", strings.ToLower(toSymbol(id)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func listPartitionNames(ps partitions) string {
|
||||||
|
names := []string{}
|
||||||
|
switch len(ps) {
|
||||||
|
case 1:
|
||||||
|
return ps[0].Name
|
||||||
|
case 2:
|
||||||
|
return fmt.Sprintf("%s and %s", ps[0].Name, ps[1].Name)
|
||||||
|
default:
|
||||||
|
for i, p := range ps {
|
||||||
|
if i == len(ps)-1 {
|
||||||
|
names = append(names, "and "+p.Name)
|
||||||
|
} else {
|
||||||
|
names = append(names, p.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(names, ", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func boxedBoolIfSet(msg string, v boxedBool) string {
|
||||||
|
switch v {
|
||||||
|
case boxedTrue:
|
||||||
|
return fmt.Sprintf(msg, "boxedTrue")
|
||||||
|
case boxedFalse:
|
||||||
|
return fmt.Sprintf(msg, "boxedFalse")
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringIfSet(msg, v string) string {
|
||||||
|
if len(v) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf(msg, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringSliceIfSet(msg string, vs []string) string {
|
||||||
|
if len(vs) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
names := []string{}
|
||||||
|
for _, v := range vs {
|
||||||
|
names = append(names, `"`+v+`"`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf(msg, strings.Join(names, ","))
|
||||||
|
}
|
||||||
|
|
||||||
|
func endpointIsSet(v endpoint) bool {
|
||||||
|
return !reflect.DeepEqual(v, endpoint{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func serviceSet(ps partitions) map[string]struct{} {
|
||||||
|
set := map[string]struct{}{}
|
||||||
|
for _, p := range ps {
|
||||||
|
for id := range p.Services {
|
||||||
|
set[id] = struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return set
|
||||||
|
}
|
||||||
|
|
||||||
|
var funcMap = template.FuncMap{
|
||||||
|
"ToSymbol": toSymbol,
|
||||||
|
"QuoteString": quoteString,
|
||||||
|
"RegionConst": regionConstName,
|
||||||
|
"PartitionGetter": partitionGetter,
|
||||||
|
"PartitionVarName": partitionVarName,
|
||||||
|
"ListPartitionNames": listPartitionNames,
|
||||||
|
"BoxedBoolIfSet": boxedBoolIfSet,
|
||||||
|
"StringIfSet": stringIfSet,
|
||||||
|
"StringSliceIfSet": stringSliceIfSet,
|
||||||
|
"EndpointIsSet": endpointIsSet,
|
||||||
|
"ServicesSet": serviceSet,
|
||||||
|
}
|
||||||
|
|
||||||
|
const v3Tmpl = `
|
||||||
|
{{ define "defaults" -}}
|
||||||
|
// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
package endpoints
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
{{ template "partition consts" . }}
|
||||||
|
|
||||||
|
{{ range $_, $partition := . }}
|
||||||
|
{{ template "partition region consts" $partition }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ template "service consts" . }}
|
||||||
|
|
||||||
|
{{ template "endpoint resolvers" . }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "partition consts" }}
|
||||||
|
// Partition identifiers
|
||||||
|
const (
|
||||||
|
{{ range $_, $p := . -}}
|
||||||
|
{{ ToSymbol $p.ID }}PartitionID = {{ QuoteString $p.ID }} // {{ $p.Name }} partition.
|
||||||
|
{{ end -}}
|
||||||
|
)
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "partition region consts" }}
|
||||||
|
// {{ .Name }} partition's regions.
|
||||||
|
const (
|
||||||
|
{{ range $id, $region := .Regions -}}
|
||||||
|
{{ ToSymbol $id }}RegionID = {{ QuoteString $id }} // {{ $region.Description }}.
|
||||||
|
{{ end -}}
|
||||||
|
)
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "service consts" }}
|
||||||
|
// Service identifiers
|
||||||
|
const (
|
||||||
|
{{ $serviceSet := ServicesSet . -}}
|
||||||
|
{{ range $id, $_ := $serviceSet -}}
|
||||||
|
{{ ToSymbol $id }}ServiceID = {{ QuoteString $id }} // {{ ToSymbol $id }}.
|
||||||
|
{{ end -}}
|
||||||
|
)
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "endpoint resolvers" }}
|
||||||
|
// DefaultResolver returns an Endpoint resolver that will be able
|
||||||
|
// to resolve endpoints for: {{ ListPartitionNames . }}.
|
||||||
|
//
|
||||||
|
// Use DefaultPartitions() to get the list of the default partitions.
|
||||||
|
func DefaultResolver() Resolver {
|
||||||
|
return defaultPartitions
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultPartitions returns a list of the partitions the SDK is bundled
|
||||||
|
// with. The available partitions are: {{ ListPartitionNames . }}.
|
||||||
|
//
|
||||||
|
// partitions := endpoints.DefaultPartitions
|
||||||
|
// for _, p := range partitions {
|
||||||
|
// // ... inspect partitions
|
||||||
|
// }
|
||||||
|
func DefaultPartitions() []Partition {
|
||||||
|
return defaultPartitions.Partitions()
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultPartitions = partitions{
|
||||||
|
{{ range $_, $partition := . -}}
|
||||||
|
{{ PartitionVarName $partition.ID }},
|
||||||
|
{{ end }}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{ range $_, $partition := . -}}
|
||||||
|
{{ $name := PartitionGetter $partition.ID -}}
|
||||||
|
// {{ $name }} returns the Resolver for {{ $partition.Name }}.
|
||||||
|
func {{ $name }}() Partition {
|
||||||
|
return {{ PartitionVarName $partition.ID }}.Partition()
|
||||||
|
}
|
||||||
|
var {{ PartitionVarName $partition.ID }} = {{ template "gocode Partition" $partition }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ define "default partitions" }}
|
||||||
|
func DefaultPartitions() []Partition {
|
||||||
|
return []partition{
|
||||||
|
{{ range $_, $partition := . -}}
|
||||||
|
// {{ ToSymbol $partition.ID}}Partition(),
|
||||||
|
{{ end }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
{{ define "gocode Partition" -}}
|
||||||
|
partition{
|
||||||
|
{{ StringIfSet "ID: %q,\n" .ID -}}
|
||||||
|
{{ StringIfSet "Name: %q,\n" .Name -}}
|
||||||
|
{{ StringIfSet "DNSSuffix: %q,\n" .DNSSuffix -}}
|
||||||
|
RegionRegex: {{ template "gocode RegionRegex" .RegionRegex }},
|
||||||
|
{{ if EndpointIsSet .Defaults -}}
|
||||||
|
Defaults: {{ template "gocode Endpoint" .Defaults }},
|
||||||
|
{{- end }}
|
||||||
|
Regions: {{ template "gocode Regions" .Regions }},
|
||||||
|
Services: {{ template "gocode Services" .Services }},
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "gocode RegionRegex" -}}
|
||||||
|
regionRegex{
|
||||||
|
Regexp: func() *regexp.Regexp{
|
||||||
|
reg, _ := regexp.Compile({{ QuoteString .Regexp.String }})
|
||||||
|
return reg
|
||||||
|
}(),
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "gocode Regions" -}}
|
||||||
|
regions{
|
||||||
|
{{ range $id, $region := . -}}
|
||||||
|
"{{ $id }}": {{ template "gocode Region" $region }},
|
||||||
|
{{ end -}}
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "gocode Region" -}}
|
||||||
|
region{
|
||||||
|
{{ StringIfSet "Description: %q,\n" .Description -}}
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "gocode Services" -}}
|
||||||
|
services{
|
||||||
|
{{ range $id, $service := . -}}
|
||||||
|
"{{ $id }}": {{ template "gocode Service" $service }},
|
||||||
|
{{ end }}
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "gocode Service" -}}
|
||||||
|
service{
|
||||||
|
{{ StringIfSet "PartitionEndpoint: %q,\n" .PartitionEndpoint -}}
|
||||||
|
{{ BoxedBoolIfSet "IsRegionalized: %s,\n" .IsRegionalized -}}
|
||||||
|
{{ if EndpointIsSet .Defaults -}}
|
||||||
|
Defaults: {{ template "gocode Endpoint" .Defaults -}},
|
||||||
|
{{- end }}
|
||||||
|
{{ if .Endpoints -}}
|
||||||
|
Endpoints: {{ template "gocode Endpoints" .Endpoints }},
|
||||||
|
{{- end }}
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "gocode Endpoints" -}}
|
||||||
|
endpoints{
|
||||||
|
{{ range $id, $endpoint := . -}}
|
||||||
|
"{{ $id }}": {{ template "gocode Endpoint" $endpoint }},
|
||||||
|
{{ end }}
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "gocode Endpoint" -}}
|
||||||
|
endpoint{
|
||||||
|
{{ StringIfSet "Hostname: %q,\n" .Hostname -}}
|
||||||
|
{{ StringIfSet "SSLCommonName: %q,\n" .SSLCommonName -}}
|
||||||
|
{{ StringSliceIfSet "Protocols: []string{%s},\n" .Protocols -}}
|
||||||
|
{{ StringSliceIfSet "SignatureVersions: []string{%s},\n" .SignatureVersions -}}
|
||||||
|
{{ if or .CredentialScope.Region .CredentialScope.Service -}}
|
||||||
|
CredentialScope: credentialScope{
|
||||||
|
{{ StringIfSet "Region: %q,\n" .CredentialScope.Region -}}
|
||||||
|
{{ StringIfSet "Service: %q,\n" .CredentialScope.Service -}}
|
||||||
|
},
|
||||||
|
{{- end }}
|
||||||
|
{{ BoxedBoolIfSet "HasDualStack: %s,\n" .HasDualStack -}}
|
||||||
|
{{ StringIfSet "DualStackHostname: %q,\n" .DualStackHostname -}}
|
||||||
|
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
`
|
12
vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go
generated
vendored
Normal file
12
vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package aws
|
||||||
|
|
||||||
|
// JSONValue is a representation of a grab bag type that will be marshaled
|
||||||
|
// into a json string. This type can be used just like any other map.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// values := aws.JSONValue{
|
||||||
|
// "Foo": "Bar",
|
||||||
|
// }
|
||||||
|
// values["Baz"] = "Qux"
|
||||||
|
type JSONValue map[string]interface{}
|
4
vendor/github.com/aws/aws-sdk-go/aws/logger.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/aws/logger.go
generated
vendored
@ -26,14 +26,14 @@ func (l *LogLevelType) Value() LogLevelType {
|
|||||||
|
|
||||||
// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be
|
// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be
|
||||||
// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If
|
// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If
|
||||||
// LogLevel is nill, will default to LogOff comparison.
|
// LogLevel is nil, will default to LogOff comparison.
|
||||||
func (l *LogLevelType) Matches(v LogLevelType) bool {
|
func (l *LogLevelType) Matches(v LogLevelType) bool {
|
||||||
c := l.Value()
|
c := l.Value()
|
||||||
return c&v == v
|
return c&v == v
|
||||||
}
|
}
|
||||||
|
|
||||||
// AtLeast returns true if this LogLevel is at least high enough to satisfies v.
|
// AtLeast returns true if this LogLevel is at least high enough to satisfies v.
|
||||||
// Is safe to use on nil value LogLevelTypes. If LogLevel is nill, will default
|
// Is safe to use on nil value LogLevelTypes. If LogLevel is nil, will default
|
||||||
// to LogOff comparison.
|
// to LogOff comparison.
|
||||||
func (l *LogLevelType) AtLeast(v LogLevelType) bool {
|
func (l *LogLevelType) AtLeast(v LogLevelType) bool {
|
||||||
c := l.Value()
|
c := l.Value()
|
||||||
|
19
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go
generated
vendored
Normal file
19
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// +build !appengine,!plan9
|
||||||
|
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
11
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other.go
generated
vendored
Normal file
11
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other.go
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// +build appengine plan9
|
||||||
|
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isErrConnectionReset(err error) bool {
|
||||||
|
return strings.Contains(err.Error(), "connection reset")
|
||||||
|
}
|
95
vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go
generated
vendored
95
vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go
generated
vendored
@ -18,6 +18,7 @@ type Handlers struct {
|
|||||||
UnmarshalError HandlerList
|
UnmarshalError HandlerList
|
||||||
Retry HandlerList
|
Retry HandlerList
|
||||||
AfterRetry HandlerList
|
AfterRetry HandlerList
|
||||||
|
Complete HandlerList
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy returns of this handler's lists.
|
// Copy returns of this handler's lists.
|
||||||
@ -33,6 +34,7 @@ func (h *Handlers) Copy() Handlers {
|
|||||||
UnmarshalMeta: h.UnmarshalMeta.copy(),
|
UnmarshalMeta: h.UnmarshalMeta.copy(),
|
||||||
Retry: h.Retry.copy(),
|
Retry: h.Retry.copy(),
|
||||||
AfterRetry: h.AfterRetry.copy(),
|
AfterRetry: h.AfterRetry.copy(),
|
||||||
|
Complete: h.Complete.copy(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +50,7 @@ func (h *Handlers) Clear() {
|
|||||||
h.ValidateResponse.Clear()
|
h.ValidateResponse.Clear()
|
||||||
h.Retry.Clear()
|
h.Retry.Clear()
|
||||||
h.AfterRetry.Clear()
|
h.AfterRetry.Clear()
|
||||||
|
h.Complete.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// A HandlerListRunItem represents an entry in the HandlerList which
|
// A HandlerListRunItem represents an entry in the HandlerList which
|
||||||
@ -85,13 +88,17 @@ func (l *HandlerList) copy() HandlerList {
|
|||||||
n := HandlerList{
|
n := HandlerList{
|
||||||
AfterEachFn: l.AfterEachFn,
|
AfterEachFn: l.AfterEachFn,
|
||||||
}
|
}
|
||||||
n.list = append([]NamedHandler{}, l.list...)
|
if len(l.list) == 0 {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
n.list = append(make([]NamedHandler, 0, len(l.list)), l.list...)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear clears the handler list.
|
// Clear clears the handler list.
|
||||||
func (l *HandlerList) Clear() {
|
func (l *HandlerList) Clear() {
|
||||||
l.list = []NamedHandler{}
|
l.list = l.list[0:0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Len returns the number of handlers in the list.
|
// Len returns the number of handlers in the list.
|
||||||
@ -101,33 +108,85 @@ func (l *HandlerList) Len() int {
|
|||||||
|
|
||||||
// PushBack pushes handler f to the back of the handler list.
|
// PushBack pushes handler f to the back of the handler list.
|
||||||
func (l *HandlerList) PushBack(f func(*Request)) {
|
func (l *HandlerList) PushBack(f func(*Request)) {
|
||||||
l.list = append(l.list, NamedHandler{"__anonymous", f})
|
l.PushBackNamed(NamedHandler{"__anonymous", f})
|
||||||
}
|
|
||||||
|
|
||||||
// PushFront pushes handler f to the front of the handler list.
|
|
||||||
func (l *HandlerList) PushFront(f func(*Request)) {
|
|
||||||
l.list = append([]NamedHandler{{"__anonymous", f}}, l.list...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PushBackNamed pushes named handler f to the back of the handler list.
|
// PushBackNamed pushes named handler f to the back of the handler list.
|
||||||
func (l *HandlerList) PushBackNamed(n NamedHandler) {
|
func (l *HandlerList) PushBackNamed(n NamedHandler) {
|
||||||
|
if cap(l.list) == 0 {
|
||||||
|
l.list = make([]NamedHandler, 0, 5)
|
||||||
|
}
|
||||||
l.list = append(l.list, n)
|
l.list = append(l.list, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PushFront pushes handler f to the front of the handler list.
|
||||||
|
func (l *HandlerList) PushFront(f func(*Request)) {
|
||||||
|
l.PushFrontNamed(NamedHandler{"__anonymous", f})
|
||||||
|
}
|
||||||
|
|
||||||
// PushFrontNamed pushes named handler f to the front of the handler list.
|
// PushFrontNamed pushes named handler f to the front of the handler list.
|
||||||
func (l *HandlerList) PushFrontNamed(n NamedHandler) {
|
func (l *HandlerList) PushFrontNamed(n NamedHandler) {
|
||||||
|
if cap(l.list) == len(l.list) {
|
||||||
|
// Allocating new list required
|
||||||
l.list = append([]NamedHandler{n}, l.list...)
|
l.list = append([]NamedHandler{n}, l.list...)
|
||||||
|
} else {
|
||||||
|
// Enough room to prepend into list.
|
||||||
|
l.list = append(l.list, NamedHandler{})
|
||||||
|
copy(l.list[1:], l.list)
|
||||||
|
l.list[0] = n
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes a NamedHandler n
|
// Remove removes a NamedHandler n
|
||||||
func (l *HandlerList) Remove(n NamedHandler) {
|
func (l *HandlerList) Remove(n NamedHandler) {
|
||||||
newlist := []NamedHandler{}
|
l.RemoveByName(n.Name)
|
||||||
for _, m := range l.list {
|
}
|
||||||
if m.Name != n.Name {
|
|
||||||
newlist = append(newlist, m)
|
// RemoveByName removes a NamedHandler by name.
|
||||||
|
func (l *HandlerList) RemoveByName(name string) {
|
||||||
|
for i := 0; i < len(l.list); i++ {
|
||||||
|
m := l.list[i]
|
||||||
|
if m.Name == name {
|
||||||
|
// Shift array preventing creating new arrays
|
||||||
|
copy(l.list[i:], l.list[i+1:])
|
||||||
|
l.list[len(l.list)-1] = NamedHandler{}
|
||||||
|
l.list = l.list[:len(l.list)-1]
|
||||||
|
|
||||||
|
// decrement list so next check to length is correct
|
||||||
|
i--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
l.list = newlist
|
}
|
||||||
|
|
||||||
|
// SwapNamed will swap out any existing handlers with the same name as the
|
||||||
|
// passed in NamedHandler returning true if handlers were swapped. False is
|
||||||
|
// returned otherwise.
|
||||||
|
func (l *HandlerList) SwapNamed(n NamedHandler) (swapped bool) {
|
||||||
|
for i := 0; i < len(l.list); i++ {
|
||||||
|
if l.list[i].Name == n.Name {
|
||||||
|
l.list[i].Fn = n.Fn
|
||||||
|
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) {
|
||||||
|
if !l.SwapNamed(n) {
|
||||||
|
l.PushBackNamed(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFrontNamed 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 beginning of
|
||||||
|
// the list.
|
||||||
|
func (l *HandlerList) SetFrontNamed(n NamedHandler) {
|
||||||
|
if !l.SwapNamed(n) {
|
||||||
|
l.PushFrontNamed(n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run executes all handlers in the list with a given request object.
|
// Run executes all handlers in the list with a given request object.
|
||||||
@ -163,6 +222,16 @@ func HandlerListStopOnError(item HandlerListRunItem) bool {
|
|||||||
return item.Request.Error == nil
|
return item.Request.Error == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithAppendUserAgent will add a string to the user agent prefixed with a
|
||||||
|
// single white space.
|
||||||
|
func WithAppendUserAgent(s string) Option {
|
||||||
|
return func(r *Request) {
|
||||||
|
r.Handlers.Build.PushBack(func(r2 *Request) {
|
||||||
|
AddToUserAgent(r, s)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request
|
// MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request
|
||||||
// header. If the extra parameters are provided they will be added as metadata to the
|
// header. If the extra parameters are provided they will be added as metadata to the
|
||||||
// name/version pair resulting in the following format.
|
// name/version pair resulting in the following format.
|
||||||
|
24
vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go
generated
vendored
Normal file
24
vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request {
|
||||||
|
req := new(http.Request)
|
||||||
|
*req = *r
|
||||||
|
req.URL = &url.URL{}
|
||||||
|
*req.URL = *r.URL
|
||||||
|
req.Body = body
|
||||||
|
|
||||||
|
req.Header = http.Header{}
|
||||||
|
for k, v := range r.Header {
|
||||||
|
for _, vv := range v {
|
||||||
|
req.Header.Add(k, vv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return req
|
||||||
|
}
|
58
vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go
generated
vendored
Normal file
58
vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go
generated
vendored
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// offsetReader is a thread-safe io.ReadCloser to prevent racing
|
||||||
|
// with retrying requests
|
||||||
|
type offsetReader struct {
|
||||||
|
buf io.ReadSeeker
|
||||||
|
lock sync.Mutex
|
||||||
|
closed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader {
|
||||||
|
reader := &offsetReader{}
|
||||||
|
buf.Seek(offset, 0)
|
||||||
|
|
||||||
|
reader.buf = buf
|
||||||
|
return reader
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close will close the instance of the offset reader's access to
|
||||||
|
// the underlying io.ReadSeeker.
|
||||||
|
func (o *offsetReader) Close() error {
|
||||||
|
o.lock.Lock()
|
||||||
|
defer o.lock.Unlock()
|
||||||
|
o.closed = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read is a thread-safe read of the underlying io.ReadSeeker
|
||||||
|
func (o *offsetReader) Read(p []byte) (int, error) {
|
||||||
|
o.lock.Lock()
|
||||||
|
defer o.lock.Unlock()
|
||||||
|
|
||||||
|
if o.closed {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.buf.Read(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek is a thread-safe seeking operation.
|
||||||
|
func (o *offsetReader) Seek(offset int64, whence int) (int64, error) {
|
||||||
|
o.lock.Lock()
|
||||||
|
defer o.lock.Unlock()
|
||||||
|
|
||||||
|
return o.buf.Seek(offset, whence)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
return newOffsetReader(o.buf, offset)
|
||||||
|
}
|
351
vendor/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
351
vendor/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
@ -4,7 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -12,9 +12,28 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ErrCodeSerialization is the serialization error code that is received
|
||||||
|
// during protocol unmarshaling.
|
||||||
|
ErrCodeSerialization = "SerializationError"
|
||||||
|
|
||||||
|
// ErrCodeRead is an error that is returned during HTTP reads.
|
||||||
|
ErrCodeRead = "ReadError"
|
||||||
|
|
||||||
|
// ErrCodeResponseTimeout is the connection timeout error that is received
|
||||||
|
// during body reads.
|
||||||
|
ErrCodeResponseTimeout = "ResponseTimeout"
|
||||||
|
|
||||||
|
// CanceledErrorCode is the error code that will be returned by an
|
||||||
|
// API request that was canceled. Requests given a aws.Context may
|
||||||
|
// return this error when canceled.
|
||||||
|
CanceledErrorCode = "RequestCanceled"
|
||||||
|
)
|
||||||
|
|
||||||
// A Request is the service request to be made.
|
// A Request is the service request to be made.
|
||||||
type Request struct {
|
type Request struct {
|
||||||
Config aws.Config
|
Config aws.Config
|
||||||
@ -38,8 +57,18 @@ type Request struct {
|
|||||||
RetryDelay time.Duration
|
RetryDelay time.Duration
|
||||||
NotHoist bool
|
NotHoist bool
|
||||||
SignedHeaderVals http.Header
|
SignedHeaderVals http.Header
|
||||||
|
LastSignedAt time.Time
|
||||||
|
DisableFollowRedirects bool
|
||||||
|
|
||||||
|
context aws.Context
|
||||||
|
|
||||||
built bool
|
built bool
|
||||||
|
|
||||||
|
// Need to persist an intermediate body between the input Body and HTTP
|
||||||
|
// request body because the HTTP Client's transport can maintain a reference
|
||||||
|
// to the HTTP request's body after the client has returned. This value is
|
||||||
|
// safe to use concurrently and wrap the input Body for each HTTP request.
|
||||||
|
safeBody *offsetReader
|
||||||
}
|
}
|
||||||
|
|
||||||
// An Operation is the service API operation to be made.
|
// An Operation is the service API operation to be made.
|
||||||
@ -48,14 +77,8 @@ type Operation struct {
|
|||||||
HTTPMethod string
|
HTTPMethod string
|
||||||
HTTPPath string
|
HTTPPath string
|
||||||
*Paginator
|
*Paginator
|
||||||
}
|
|
||||||
|
|
||||||
// Paginator keeps track of pagination configuration for an API operation.
|
BeforePresignFn func(r *Request) error
|
||||||
type Paginator struct {
|
|
||||||
InputTokens []string
|
|
||||||
OutputTokens []string
|
|
||||||
LimitToken string
|
|
||||||
TruncationToken string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a new Request pointer for the service API
|
// New returns a new Request pointer for the service API
|
||||||
@ -71,13 +94,15 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
|
|||||||
if method == "" {
|
if method == "" {
|
||||||
method = "POST"
|
method = "POST"
|
||||||
}
|
}
|
||||||
p := operation.HTTPPath
|
|
||||||
if p == "" {
|
|
||||||
p = "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
httpReq, _ := http.NewRequest(method, "", nil)
|
httpReq, _ := http.NewRequest(method, "", nil)
|
||||||
httpReq.URL, _ = url.Parse(clientInfo.Endpoint + p)
|
|
||||||
|
var err error
|
||||||
|
httpReq.URL, err = url.Parse(clientInfo.Endpoint + operation.HTTPPath)
|
||||||
|
if err != nil {
|
||||||
|
httpReq.URL = &url.URL{}
|
||||||
|
err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err)
|
||||||
|
}
|
||||||
|
|
||||||
r := &Request{
|
r := &Request{
|
||||||
Config: cfg,
|
Config: cfg,
|
||||||
@ -91,7 +116,7 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
|
|||||||
HTTPRequest: httpReq,
|
HTTPRequest: httpReq,
|
||||||
Body: nil,
|
Body: nil,
|
||||||
Params: params,
|
Params: params,
|
||||||
Error: nil,
|
Error: err,
|
||||||
Data: data,
|
Data: data,
|
||||||
}
|
}
|
||||||
r.SetBufferBody([]byte{})
|
r.SetBufferBody([]byte{})
|
||||||
@ -99,6 +124,94 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A Option is a functional option that can augment or modify a request when
|
||||||
|
// using a WithContext API operation method.
|
||||||
|
type Option func(*Request)
|
||||||
|
|
||||||
|
// WithGetResponseHeader builds a request Option which will retrieve a single
|
||||||
|
// header value from the HTTP Response. If there are multiple values for the
|
||||||
|
// header key use WithGetResponseHeaders instead to access the http.Header
|
||||||
|
// map directly. The passed in val pointer must be non-nil.
|
||||||
|
//
|
||||||
|
// This Option can be used multiple times with a single API operation.
|
||||||
|
//
|
||||||
|
// var id2, versionID string
|
||||||
|
// svc.PutObjectWithContext(ctx, params,
|
||||||
|
// request.WithGetResponseHeader("x-amz-id-2", &id2),
|
||||||
|
// request.WithGetResponseHeader("x-amz-version-id", &versionID),
|
||||||
|
// )
|
||||||
|
func WithGetResponseHeader(key string, val *string) Option {
|
||||||
|
return func(r *Request) {
|
||||||
|
r.Handlers.Complete.PushBack(func(req *Request) {
|
||||||
|
*val = req.HTTPResponse.Header.Get(key)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithGetResponseHeaders builds a request Option which will retrieve the
|
||||||
|
// headers from the HTTP response and assign them to the passed in headers
|
||||||
|
// variable. The passed in headers pointer must be non-nil.
|
||||||
|
//
|
||||||
|
// var headers http.Header
|
||||||
|
// svc.PutObjectWithContext(ctx, params, request.WithGetResponseHeaders(&headers))
|
||||||
|
func WithGetResponseHeaders(headers *http.Header) Option {
|
||||||
|
return func(r *Request) {
|
||||||
|
r.Handlers.Complete.PushBack(func(req *Request) {
|
||||||
|
*headers = req.HTTPResponse.Header
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithLogLevel is a request option that will set the request to use a specific
|
||||||
|
// log level when the request is made.
|
||||||
|
//
|
||||||
|
// svc.PutObjectWithContext(ctx, params, request.WithLogLevel(aws.LogDebugWithHTTPBody)
|
||||||
|
func WithLogLevel(l aws.LogLevelType) Option {
|
||||||
|
return func(r *Request) {
|
||||||
|
r.Config.LogLevel = aws.LogLevel(l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplyOptions will apply each option to the request calling them in the order
|
||||||
|
// the were provided.
|
||||||
|
func (r *Request) ApplyOptions(opts ...Option) {
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context will always returns a non-nil context. If Request does not have a
|
||||||
|
// context aws.BackgroundContext will be returned.
|
||||||
|
func (r *Request) Context() aws.Context {
|
||||||
|
if r.context != nil {
|
||||||
|
return r.context
|
||||||
|
}
|
||||||
|
return aws.BackgroundContext()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContext adds a Context to the current request that can be used to cancel
|
||||||
|
// a in-flight request. The Context value must not be nil, or this method will
|
||||||
|
// panic.
|
||||||
|
//
|
||||||
|
// Unlike http.Request.WithContext, SetContext does not return a copy of the
|
||||||
|
// Request. It is not safe to use use a single Request value for multiple
|
||||||
|
// requests. A new Request should be created for each API operation request.
|
||||||
|
//
|
||||||
|
// Go 1.6 and below:
|
||||||
|
// The http.Request's Cancel field will be set to the Done() value of
|
||||||
|
// the context. This will overwrite the Cancel field's value.
|
||||||
|
//
|
||||||
|
// Go 1.7 and above:
|
||||||
|
// The http.Request.WithContext will be used to set the context on the underlying
|
||||||
|
// http.Request. This will create a shallow copy of the http.Request. The SDK
|
||||||
|
// may create sub contexts in the future for nested requests such as retries.
|
||||||
|
func (r *Request) SetContext(ctx aws.Context) {
|
||||||
|
if ctx == nil {
|
||||||
|
panic("context cannot be nil")
|
||||||
|
}
|
||||||
|
setRequestContext(r, ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// WillRetry returns if the request's can be retried.
|
// WillRetry returns if the request's can be retried.
|
||||||
func (r *Request) WillRetry() bool {
|
func (r *Request) WillRetry() bool {
|
||||||
return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries()
|
return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries()
|
||||||
@ -131,8 +244,8 @@ func (r *Request) SetStringBody(s string) {
|
|||||||
|
|
||||||
// SetReaderBody will set the request's body reader.
|
// SetReaderBody will set the request's body reader.
|
||||||
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
||||||
r.HTTPRequest.Body = ioutil.NopCloser(reader)
|
|
||||||
r.Body = reader
|
r.Body = reader
|
||||||
|
r.ResetBody()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Presign returns the request's signed URL. Error will be returned
|
// Presign returns the request's signed URL. Error will be returned
|
||||||
@ -140,6 +253,15 @@ func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
|||||||
func (r *Request) Presign(expireTime time.Duration) (string, error) {
|
func (r *Request) Presign(expireTime time.Duration) (string, error) {
|
||||||
r.ExpireTime = expireTime
|
r.ExpireTime = expireTime
|
||||||
r.NotHoist = false
|
r.NotHoist = false
|
||||||
|
|
||||||
|
if r.Operation.BeforePresignFn != nil {
|
||||||
|
r = r.copy()
|
||||||
|
err := r.Operation.BeforePresignFn(r)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
r.Sign()
|
r.Sign()
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
return "", r.Error
|
return "", r.Error
|
||||||
@ -147,11 +269,17 @@ func (r *Request) Presign(expireTime time.Duration) (string, error) {
|
|||||||
return r.HTTPRequest.URL.String(), nil
|
return r.HTTPRequest.URL.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PresignRequest behaves just like presign, but hoists all headers and signs them.
|
// PresignRequest behaves just like presign, with the addition of returning a
|
||||||
// Also returns the signed hash back to the user
|
// set of headers that were signed.
|
||||||
|
//
|
||||||
|
// Returns the URL string for the API operation with signature in the query string,
|
||||||
|
// and the HTTP headers that were included in the signature. These headers must
|
||||||
|
// be included in any HTTP request made with the presigned URL.
|
||||||
|
//
|
||||||
|
// To prevent hoisting any headers to the query string set NotHoist to true on
|
||||||
|
// this Request value prior to calling PresignRequest.
|
||||||
func (r *Request) PresignRequest(expireTime time.Duration) (string, http.Header, error) {
|
func (r *Request) PresignRequest(expireTime time.Duration) (string, http.Header, error) {
|
||||||
r.ExpireTime = expireTime
|
r.ExpireTime = expireTime
|
||||||
r.NotHoist = true
|
|
||||||
r.Sign()
|
r.Sign()
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
return "", nil, r.Error
|
return "", nil, r.Error
|
||||||
@ -185,7 +313,6 @@ func debugLogReqError(r *Request, stage string, retrying bool, err error) {
|
|||||||
// which occurred will be returned.
|
// which occurred will be returned.
|
||||||
func (r *Request) Build() error {
|
func (r *Request) Build() error {
|
||||||
if !r.built {
|
if !r.built {
|
||||||
r.Error = nil
|
|
||||||
r.Handlers.Validate.Run(r)
|
r.Handlers.Validate.Run(r)
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
debugLogReqError(r, "Validate Request", false, r.Error)
|
debugLogReqError(r, "Validate Request", false, r.Error)
|
||||||
@ -202,7 +329,7 @@ func (r *Request) Build() error {
|
|||||||
return r.Error
|
return r.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign will sign the request retuning 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
|
// Send will build the request prior to signing. All Sign Handlers will
|
||||||
// be executed in the order they were set.
|
// be executed in the order they were set.
|
||||||
@ -217,52 +344,171 @@ func (r *Request) Sign() error {
|
|||||||
return r.Error
|
return r.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
|
||||||
|
if r.safeBody != nil {
|
||||||
|
r.safeBody.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
r.safeBody = newOffsetReader(r.Body, r.BodyStart)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// of if the Request.Body was empty, or actually had bytes in it. The SDK
|
||||||
|
// always sets the Request.Body even if it is empty and should not actually
|
||||||
|
// be sent. This is incorrect.
|
||||||
|
//
|
||||||
|
// Go 1.8 did add a http.NoBody value that the SDK can use to tell the http
|
||||||
|
// client that the request really should be sent without a body. The
|
||||||
|
// Request.Body cannot be set to nil, which is preferable, because the
|
||||||
|
// field is exported and could introduce nil pointer dereferences for users
|
||||||
|
// of the SDK if they used that field.
|
||||||
|
//
|
||||||
|
// Related golang/go#18257
|
||||||
|
l, err := computeBodyLength(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
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 {
|
||||||
|
body = r.safeBody
|
||||||
|
} else {
|
||||||
|
// Hack to prevent sending bodies for methods where the body
|
||||||
|
// should be ignored by the server. Sending bodies on these
|
||||||
|
// methods without an associated ContentLength will cause the
|
||||||
|
// request to socket timeout because the server does not handle
|
||||||
|
// 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.
|
||||||
|
switch r.Operation.HTTPMethod {
|
||||||
|
case "GET", "HEAD", "DELETE":
|
||||||
|
body = NoBody
|
||||||
|
default:
|
||||||
|
body = r.safeBody
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
// Send will sign the request prior to sending. All Send Handlers will
|
||||||
// be executed in the order they were set.
|
// be executed in the order they were set.
|
||||||
|
//
|
||||||
|
// Canceling a request is non-deterministic. If a request has been canceled,
|
||||||
|
// then the transport will choose, randomly, one of the state channels during
|
||||||
|
// reads or getting the connection.
|
||||||
|
//
|
||||||
|
// readLoop() and getConn(req *Request, cm connectMethod)
|
||||||
|
// https://github.com/golang/go/blob/master/src/net/http/transport.go
|
||||||
|
//
|
||||||
|
// Send will not close the request.Request's body.
|
||||||
func (r *Request) Send() error {
|
func (r *Request) Send() error {
|
||||||
for {
|
defer func() {
|
||||||
r.Sign()
|
// Regardless of success or failure of the request trigger the Complete
|
||||||
if r.Error != nil {
|
// request handlers.
|
||||||
return r.Error
|
r.Handlers.Complete.Run(r)
|
||||||
}
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
if aws.BoolValue(r.Retryable) {
|
if aws.BoolValue(r.Retryable) {
|
||||||
if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
|
if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
|
||||||
r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
|
r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
|
r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-seek the body back to the original point in for a retry so that
|
// The previous http.Request will have a reference to the r.Body
|
||||||
// send will send the body's contents again in the upcoming request.
|
// and the HTTP Client's Transport may still be reading from
|
||||||
r.Body.Seek(r.BodyStart, 0)
|
// the request's body even though the Client's Do returned.
|
||||||
r.HTTPRequest.Body = ioutil.NopCloser(r.Body)
|
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()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Sign()
|
||||||
|
if r.Error != nil {
|
||||||
|
return r.Error
|
||||||
|
}
|
||||||
|
|
||||||
r.Retryable = nil
|
r.Retryable = nil
|
||||||
|
|
||||||
r.Handlers.Send.Run(r)
|
r.Handlers.Send.Run(r)
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
|
if !shouldRetryCancel(r) {
|
||||||
|
return r.Error
|
||||||
|
}
|
||||||
|
|
||||||
err := r.Error
|
err := r.Error
|
||||||
r.Handlers.Retry.Run(r)
|
r.Handlers.Retry.Run(r)
|
||||||
r.Handlers.AfterRetry.Run(r)
|
r.Handlers.AfterRetry.Run(r)
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
debugLogReqError(r, "Send Request", false, r.Error)
|
debugLogReqError(r, "Send Request", false, err)
|
||||||
return r.Error
|
return r.Error
|
||||||
}
|
}
|
||||||
debugLogReqError(r, "Send Request", true, err)
|
debugLogReqError(r, "Send Request", true, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Handlers.UnmarshalMeta.Run(r)
|
r.Handlers.UnmarshalMeta.Run(r)
|
||||||
r.Handlers.ValidateResponse.Run(r)
|
r.Handlers.ValidateResponse.Run(r)
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
err := r.Error
|
|
||||||
r.Handlers.UnmarshalError.Run(r)
|
r.Handlers.UnmarshalError.Run(r)
|
||||||
|
err := r.Error
|
||||||
|
|
||||||
r.Handlers.Retry.Run(r)
|
r.Handlers.Retry.Run(r)
|
||||||
r.Handlers.AfterRetry.Run(r)
|
r.Handlers.AfterRetry.Run(r)
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
debugLogReqError(r, "Validate Response", false, r.Error)
|
debugLogReqError(r, "Validate Response", false, err)
|
||||||
return r.Error
|
return r.Error
|
||||||
}
|
}
|
||||||
debugLogReqError(r, "Validate Response", true, err)
|
debugLogReqError(r, "Validate Response", true, err)
|
||||||
@ -275,7 +521,7 @@ func (r *Request) Send() error {
|
|||||||
r.Handlers.Retry.Run(r)
|
r.Handlers.Retry.Run(r)
|
||||||
r.Handlers.AfterRetry.Run(r)
|
r.Handlers.AfterRetry.Run(r)
|
||||||
if r.Error != nil {
|
if r.Error != nil {
|
||||||
debugLogReqError(r, "Unmarshal Response", false, r.Error)
|
debugLogReqError(r, "Unmarshal Response", false, err)
|
||||||
return r.Error
|
return r.Error
|
||||||
}
|
}
|
||||||
debugLogReqError(r, "Unmarshal Response", true, err)
|
debugLogReqError(r, "Unmarshal Response", true, err)
|
||||||
@ -288,6 +534,17 @@ func (r *Request) Send() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy will copy a request which will allow for local manipulation of the
|
||||||
|
// request.
|
||||||
|
func (r *Request) copy() *Request {
|
||||||
|
req := &Request{}
|
||||||
|
*req = *r
|
||||||
|
req.Handlers = r.Handlers.Copy()
|
||||||
|
op := *r.Operation
|
||||||
|
req.Operation = &op
|
||||||
|
return req
|
||||||
|
}
|
||||||
|
|
||||||
// AddToUserAgent adds the string to the end of the request's current user agent.
|
// AddToUserAgent adds the string to the end of the request's current user agent.
|
||||||
func AddToUserAgent(r *Request, s string) {
|
func AddToUserAgent(r *Request, s string) {
|
||||||
curUA := r.HTTPRequest.Header.Get("User-Agent")
|
curUA := r.HTTPRequest.Header.Get("User-Agent")
|
||||||
@ -296,3 +553,29 @@ func AddToUserAgent(r *Request, s string) {
|
|||||||
}
|
}
|
||||||
r.HTTPRequest.Header.Set("User-Agent", s)
|
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")
|
||||||
|
|
||||||
|
}
|
||||||
|
39
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go
generated
vendored
Normal file
39
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// +build !go1.8
|
||||||
|
|
||||||
|
package request
|
||||||
|
|
||||||
|
import "io"
|
||||||
|
|
||||||
|
// NoBody is an io.ReadCloser with no bytes. Read always returns EOF
|
||||||
|
// and Close always returns nil. It can be used in an outgoing client
|
||||||
|
// request to explicitly signal that a request has zero bytes.
|
||||||
|
// An alternative, however, is to simply set Request.Body to nil.
|
||||||
|
//
|
||||||
|
// Copy of Go 1.8 NoBody type from net/http/http.go
|
||||||
|
type noBody struct{}
|
||||||
|
|
||||||
|
func (noBody) Read([]byte) (int, error) { return 0, io.EOF }
|
||||||
|
func (noBody) Close() error { return nil }
|
||||||
|
func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil }
|
||||||
|
|
||||||
|
// NoBody is an empty reader that will trigger the Go HTTP client to not include
|
||||||
|
// and body in the HTTP request.
|
||||||
|
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
|
||||||
|
// 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
|
||||||
|
// the request is being used directly ResetBody must be called before the request
|
||||||
|
// is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically
|
||||||
|
// call ResetBody.
|
||||||
|
func (r *Request) ResetBody() {
|
||||||
|
body, err := r.getNextRequestBody()
|
||||||
|
if err != nil {
|
||||||
|
r.Error = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.HTTPRequest.Body = body
|
||||||
|
}
|
33
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go
generated
vendored
Normal file
33
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NoBody is a http.NoBody reader instructing Go HTTP client to not include
|
||||||
|
// and body in the HTTP request.
|
||||||
|
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
|
||||||
|
// 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
|
||||||
|
// the request is being used directly ResetBody must be called before the request
|
||||||
|
// is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically
|
||||||
|
// call ResetBody.
|
||||||
|
//
|
||||||
|
// Will also set the Go 1.8's http.Request.GetBody member to allow retrying
|
||||||
|
// PUT/POST redirects.
|
||||||
|
func (r *Request) ResetBody() {
|
||||||
|
body, err := r.getNextRequestBody()
|
||||||
|
if err != nil {
|
||||||
|
r.Error = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.HTTPRequest.Body = body
|
||||||
|
r.HTTPRequest.GetBody = r.getNextRequestBody
|
||||||
|
}
|
14
vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go
generated
vendored
Normal file
14
vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// +build go1.7
|
||||||
|
|
||||||
|
package request
|
||||||
|
|
||||||
|
import "github.com/aws/aws-sdk-go/aws"
|
||||||
|
|
||||||
|
// setContext updates the Request to use the passed in context for cancellation.
|
||||||
|
// Context will also be used for request retry delay.
|
||||||
|
//
|
||||||
|
// Creates shallow copy of the http.Request with the WithContext method.
|
||||||
|
func setRequestContext(r *Request, ctx aws.Context) {
|
||||||
|
r.context = ctx
|
||||||
|
r.HTTPRequest = r.HTTPRequest.WithContext(ctx)
|
||||||
|
}
|
14
vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go
generated
vendored
Normal file
14
vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// +build !go1.7
|
||||||
|
|
||||||
|
package request
|
||||||
|
|
||||||
|
import "github.com/aws/aws-sdk-go/aws"
|
||||||
|
|
||||||
|
// setContext updates the Request to use the passed in context for cancellation.
|
||||||
|
// Context will also be used for request retry delay.
|
||||||
|
//
|
||||||
|
// Creates shallow copy of the http.Request with the WithContext method.
|
||||||
|
func setRequestContext(r *Request, ctx aws.Context) {
|
||||||
|
r.context = ctx
|
||||||
|
r.HTTPRequest.Cancel = ctx.Done()
|
||||||
|
}
|
152
vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
generated
vendored
152
vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
generated
vendored
@ -2,29 +2,125 @@ package request
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
//type Paginater interface {
|
// A Pagination provides paginating of SDK API operations which are paginatable.
|
||||||
// HasNextPage() bool
|
// Generally you should not use this type directly, but use the "Pages" API
|
||||||
// NextPage() *Request
|
// operations method to automatically perform pagination for you. Such as,
|
||||||
// EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error
|
// "S3.ListObjectsPages", and "S3.ListObjectsPagesWithContext" methods.
|
||||||
|
//
|
||||||
|
// Pagination differs from a Paginator type in that pagination is the type that
|
||||||
|
// does the pagination between API operations, and Paginator defines the
|
||||||
|
// configuration that will be used per page request.
|
||||||
|
//
|
||||||
|
// cont := true
|
||||||
|
// for p.Next() && cont {
|
||||||
|
// data := p.Page().(*s3.ListObjectsOutput)
|
||||||
|
// // process the page's data
|
||||||
// }
|
// }
|
||||||
|
// return p.Err()
|
||||||
|
//
|
||||||
|
// See service client API operation Pages methods for examples how the SDK will
|
||||||
|
// use the Pagination type.
|
||||||
|
type Pagination struct {
|
||||||
|
// Function to return a Request value for each pagination request.
|
||||||
|
// Any configuration or handlers that need to be applied to the request
|
||||||
|
// prior to getting the next page should be done here before the request
|
||||||
|
// returned.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
|
||||||
// HasNextPage returns true if this request has more pages of data available.
|
started bool
|
||||||
func (r *Request) HasNextPage() bool {
|
nextTokens []interface{}
|
||||||
return len(r.nextPageTokens()) > 0
|
|
||||||
|
err error
|
||||||
|
curPage interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nextPageTokens returns the tokens to use when asking for the next page of
|
// HasNextPage will return true if Pagination is able to determine that the API
|
||||||
// data.
|
// operation has additional pages. False will be returned if there are no more
|
||||||
|
// pages remaining.
|
||||||
|
//
|
||||||
|
// Will always return true if Next has not been called yet.
|
||||||
|
func (p *Pagination) HasNextPage() bool {
|
||||||
|
return !(p.started && len(p.nextTokens) == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Err returns the error Pagination encountered when retrieving the next page.
|
||||||
|
func (p *Pagination) Err() error {
|
||||||
|
return p.err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Page returns the current page. Page should only be called after a successful
|
||||||
|
// call to Next. It is undefined what Page will return if Page is called after
|
||||||
|
// Next returns false.
|
||||||
|
func (p *Pagination) Page() interface{} {
|
||||||
|
return p.curPage
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next will attempt to retrieve the next page for the API operation. When a page
|
||||||
|
// is retrieved true will be returned. If the page cannot be retrieved, or there
|
||||||
|
// are no more pages false will be returned.
|
||||||
|
//
|
||||||
|
// Use the Page method to retrieve the current page data. The data will need
|
||||||
|
// to be cast to the API operation's output type.
|
||||||
|
//
|
||||||
|
// Use the Err method to determine if an error occurred if Page returns false.
|
||||||
|
func (p *Pagination) Next() bool {
|
||||||
|
if !p.HasNextPage() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := p.NewRequest()
|
||||||
|
if err != nil {
|
||||||
|
p.err = err
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.started {
|
||||||
|
for i, intok := range req.Operation.InputTokens {
|
||||||
|
awsutil.SetValueAtPath(req.Params, intok, p.nextTokens[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.started = true
|
||||||
|
|
||||||
|
err = req.Send()
|
||||||
|
if err != nil {
|
||||||
|
p.err = err
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
p.nextTokens = req.nextPageTokens()
|
||||||
|
p.curPage = req.Data
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Paginator is the configuration data that defines how an API operation
|
||||||
|
// should be paginated. This type is used by the API service models to define
|
||||||
|
// the generated pagination config for service APIs.
|
||||||
|
//
|
||||||
|
// The Pagination type is what provides iterating between pages of an API. It
|
||||||
|
// is only used to store the token metadata the SDK should use for performing
|
||||||
|
// pagination.
|
||||||
|
type Paginator struct {
|
||||||
|
InputTokens []string
|
||||||
|
OutputTokens []string
|
||||||
|
LimitToken string
|
||||||
|
TruncationToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
// nextPageTokens returns the tokens to use when asking for the next page of data.
|
||||||
func (r *Request) nextPageTokens() []interface{} {
|
func (r *Request) nextPageTokens() []interface{} {
|
||||||
if r.Operation.Paginator == nil {
|
if r.Operation.Paginator == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.Operation.TruncationToken != "" {
|
if r.Operation.TruncationToken != "" {
|
||||||
tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken)
|
tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken)
|
||||||
if len(tr) == 0 {
|
if len(tr) == 0 {
|
||||||
@ -61,9 +157,40 @@ func (r *Request) nextPageTokens() []interface{} {
|
|||||||
return tokens
|
return tokens
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure a deprecated item is only logged once instead of each time its used.
|
||||||
|
func logDeprecatedf(logger aws.Logger, flag *int32, msg string) {
|
||||||
|
if logger == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if atomic.CompareAndSwapInt32(flag, 0, 1) {
|
||||||
|
logger.Log(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
logDeprecatedHasNextPage int32
|
||||||
|
logDeprecatedNextPage int32
|
||||||
|
logDeprecatedEachPage int32
|
||||||
|
)
|
||||||
|
|
||||||
|
// HasNextPage returns true if this request has more pages of data available.
|
||||||
|
//
|
||||||
|
// Deprecated Use Pagination type for configurable pagination of API operations
|
||||||
|
func (r *Request) HasNextPage() bool {
|
||||||
|
logDeprecatedf(r.Config.Logger, &logDeprecatedHasNextPage,
|
||||||
|
"Request.HasNextPage deprecated. Use Pagination type for configurable pagination of API operations")
|
||||||
|
|
||||||
|
return len(r.nextPageTokens()) > 0
|
||||||
|
}
|
||||||
|
|
||||||
// NextPage returns a new Request that can be executed to return the next
|
// NextPage returns a new Request that can be executed to return the next
|
||||||
// page of result data. Call .Send() on this request to execute it.
|
// page of result data. Call .Send() on this request to execute it.
|
||||||
|
//
|
||||||
|
// Deprecated Use Pagination type for configurable pagination of API operations
|
||||||
func (r *Request) NextPage() *Request {
|
func (r *Request) NextPage() *Request {
|
||||||
|
logDeprecatedf(r.Config.Logger, &logDeprecatedNextPage,
|
||||||
|
"Request.NextPage deprecated. Use Pagination type for configurable pagination of API operations")
|
||||||
|
|
||||||
tokens := r.nextPageTokens()
|
tokens := r.nextPageTokens()
|
||||||
if len(tokens) == 0 {
|
if len(tokens) == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -90,7 +217,12 @@ func (r *Request) NextPage() *Request {
|
|||||||
// as the structure "T". The lastPage value represents whether the page is
|
// as the structure "T". The lastPage value represents whether the page is
|
||||||
// the last page of data or not. The return value of this function should
|
// the last page of data or not. The return value of this function should
|
||||||
// return true to keep iterating or false to stop.
|
// return true to keep iterating or false to stop.
|
||||||
|
//
|
||||||
|
// Deprecated Use Pagination type for configurable pagination of API operations
|
||||||
func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error {
|
func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error {
|
||||||
|
logDeprecatedf(r.Config.Logger, &logDeprecatedEachPage,
|
||||||
|
"Request.EachPage deprecated. Use Pagination type for configurable pagination of API operations")
|
||||||
|
|
||||||
for page := r; page != nil; page = page.NextPage() {
|
for page := r; page != nil; page = page.NextPage() {
|
||||||
if err := page.Send(); err != nil {
|
if err := page.Send(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
105
vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
generated
vendored
105
vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
generated
vendored
@ -8,7 +8,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Retryer is an interface to control retry logic for a given service.
|
// Retryer is an interface to control retry logic for a given service.
|
||||||
// The default implementation used by most services is the service.DefaultRetryer
|
// The default implementation used by most services is the client.DefaultRetryer
|
||||||
// structure, which contains basic retry logic using exponential backoff.
|
// structure, which contains basic retry logic using exponential backoff.
|
||||||
type Retryer interface {
|
type Retryer interface {
|
||||||
RetryRules(*Request) time.Duration
|
RetryRules(*Request) time.Duration
|
||||||
@ -28,13 +28,18 @@ func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config {
|
|||||||
var retryableCodes = map[string]struct{}{
|
var retryableCodes = map[string]struct{}{
|
||||||
"RequestError": {},
|
"RequestError": {},
|
||||||
"RequestTimeout": {},
|
"RequestTimeout": {},
|
||||||
|
ErrCodeResponseTimeout: {},
|
||||||
|
"RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout
|
||||||
|
}
|
||||||
|
|
||||||
|
var throttleCodes = map[string]struct{}{
|
||||||
"ProvisionedThroughputExceededException": {},
|
"ProvisionedThroughputExceededException": {},
|
||||||
"Throttling": {},
|
"Throttling": {},
|
||||||
"ThrottlingException": {},
|
"ThrottlingException": {},
|
||||||
"RequestLimitExceeded": {},
|
"RequestLimitExceeded": {},
|
||||||
"RequestThrottled": {},
|
"RequestThrottled": {},
|
||||||
"LimitExceededException": {}, // Deleting 10+ DynamoDb tables at once
|
|
||||||
"TooManyRequestsException": {}, // Lambda functions
|
"TooManyRequestsException": {}, // Lambda functions
|
||||||
|
"PriorRequestNotComplete": {}, // Route53
|
||||||
}
|
}
|
||||||
|
|
||||||
// credsExpiredCodes is a collection of error codes which signify the credentials
|
// credsExpiredCodes is a collection of error codes which signify the credentials
|
||||||
@ -46,6 +51,11 @@ var credsExpiredCodes = map[string]struct{}{
|
|||||||
"RequestExpired": {}, // EC2 Only
|
"RequestExpired": {}, // EC2 Only
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isCodeThrottle(code string) bool {
|
||||||
|
_, ok := throttleCodes[code]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
func isCodeRetryable(code string) bool {
|
func isCodeRetryable(code string) bool {
|
||||||
if _, ok := retryableCodes[code]; ok {
|
if _, ok := retryableCodes[code]; ok {
|
||||||
return true
|
return true
|
||||||
@ -59,24 +69,93 @@ func isCodeExpiredCreds(code string) bool {
|
|||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var validParentCodes = map[string]struct{}{
|
||||||
|
ErrCodeSerialization: {},
|
||||||
|
ErrCodeRead: {},
|
||||||
|
}
|
||||||
|
|
||||||
|
type temporaryError interface {
|
||||||
|
Temporary() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNestedErrorRetryable(parentErr awserr.Error) bool {
|
||||||
|
if parentErr == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := validParentCodes[parentErr.Code()]; !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
err := parentErr.OrigErr()
|
||||||
|
if err == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if aerr, ok := err.(awserr.Error); ok {
|
||||||
|
return isCodeRetryable(aerr.Code())
|
||||||
|
}
|
||||||
|
|
||||||
|
if t, ok := err.(temporaryError); ok {
|
||||||
|
return t.Temporary()
|
||||||
|
}
|
||||||
|
|
||||||
|
return isErrConnectionReset(err)
|
||||||
|
}
|
||||||
|
|
||||||
// IsErrorRetryable returns whether the error is retryable, based on its Code.
|
// IsErrorRetryable returns whether the error is retryable, based on its Code.
|
||||||
// Returns false if the request has no Error set.
|
// Returns false if error is nil.
|
||||||
func (r *Request) IsErrorRetryable() bool {
|
func IsErrorRetryable(err error) bool {
|
||||||
if r.Error != nil {
|
if err != nil {
|
||||||
if err, ok := r.Error.(awserr.Error); ok {
|
if aerr, ok := err.(awserr.Error); ok {
|
||||||
return isCodeRetryable(err.Code())
|
return isCodeRetryable(aerr.Code()) || isNestedErrorRetryable(aerr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsErrorExpired returns whether the error code is a credential expiry error.
|
// IsErrorThrottle returns whether the error is to be throttled based on its code.
|
||||||
// Returns false if the request has no Error set.
|
// Returns false if error is nil.
|
||||||
func (r *Request) IsErrorExpired() bool {
|
func IsErrorThrottle(err error) bool {
|
||||||
if r.Error != nil {
|
if err != nil {
|
||||||
if err, ok := r.Error.(awserr.Error); ok {
|
if aerr, ok := err.(awserr.Error); ok {
|
||||||
return isCodeExpiredCreds(err.Code())
|
return isCodeThrottle(aerr.Code())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrorRetryable returns whether the error is retryable, based on its Code.
|
||||||
|
// Returns false if the request has no Error set.
|
||||||
|
//
|
||||||
|
// Alias for the utility function IsErrorRetryable
|
||||||
|
func (r *Request) IsErrorRetryable() bool {
|
||||||
|
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
|
||||||
|
//
|
||||||
|
// Alias for the utility function IsErrorThrottle
|
||||||
|
func (r *Request) IsErrorThrottle() bool {
|
||||||
|
return IsErrorThrottle(r.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrorExpired returns whether the error code is a credential expiry error.
|
||||||
|
// Returns false if the request has no Error set.
|
||||||
|
//
|
||||||
|
// Alias for the utility function IsErrorExpiredCreds
|
||||||
|
func (r *Request) IsErrorExpired() bool {
|
||||||
|
return IsErrorExpiredCreds(r.Error)
|
||||||
|
}
|
||||||
|
94
vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go
generated
vendored
Normal file
94
vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
)
|
||||||
|
|
||||||
|
var timeoutErr = awserr.New(
|
||||||
|
ErrCodeResponseTimeout,
|
||||||
|
"read on body has reached the timeout limit",
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
type readResult struct {
|
||||||
|
n int
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// timeoutReadCloser will handle body reads that take too long.
|
||||||
|
// We will return a ErrReadTimeout error if a timeout occurs.
|
||||||
|
type timeoutReadCloser struct {
|
||||||
|
reader io.ReadCloser
|
||||||
|
duration time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read will spin off a goroutine to call the reader's Read method. We will
|
||||||
|
// select on the timer's channel or the read's channel. Whoever completes first
|
||||||
|
// will be returned.
|
||||||
|
func (r *timeoutReadCloser) Read(b []byte) (int, error) {
|
||||||
|
timer := time.NewTimer(r.duration)
|
||||||
|
c := make(chan readResult, 1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
n, err := r.reader.Read(b)
|
||||||
|
timer.Stop()
|
||||||
|
c <- readResult{n: n, err: err}
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case data := <-c:
|
||||||
|
return data.n, data.err
|
||||||
|
case <-timer.C:
|
||||||
|
return 0, timeoutErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *timeoutReadCloser) Close() error {
|
||||||
|
return r.reader.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// HandlerResponseTimeout is what we use to signify the name of the
|
||||||
|
// response timeout handler.
|
||||||
|
HandlerResponseTimeout = "ResponseTimeoutHandler"
|
||||||
|
)
|
||||||
|
|
||||||
|
// adaptToResponseTimeoutError is a handler that will replace any top level error
|
||||||
|
// to a ErrCodeResponseTimeout, if its child is that.
|
||||||
|
func adaptToResponseTimeoutError(req *Request) {
|
||||||
|
if err, ok := req.Error.(awserr.Error); ok {
|
||||||
|
aerr, ok := err.OrigErr().(awserr.Error)
|
||||||
|
if ok && aerr.Code() == ErrCodeResponseTimeout {
|
||||||
|
req.Error = aerr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithResponseReadTimeout is a request option that will wrap the body in a timeout read closer.
|
||||||
|
// This will allow for per read timeouts. If a timeout occurred, we will return the
|
||||||
|
// ErrCodeResponseTimeout.
|
||||||
|
//
|
||||||
|
// svc.PutObjectWithContext(ctx, params, request.WithTimeoutReadCloser(30 * time.Second)
|
||||||
|
func WithResponseReadTimeout(duration time.Duration) Option {
|
||||||
|
return func(r *Request) {
|
||||||
|
|
||||||
|
var timeoutHandler = NamedHandler{
|
||||||
|
HandlerResponseTimeout,
|
||||||
|
func(req *Request) {
|
||||||
|
req.HTTPResponse.Body = &timeoutReadCloser{
|
||||||
|
reader: req.HTTPResponse.Body,
|
||||||
|
duration: duration,
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
// remove the handler so we are not stomping over any new durations.
|
||||||
|
r.Handlers.Send.RemoveByName(HandlerResponseTimeout)
|
||||||
|
r.Handlers.Send.PushBackNamed(timeoutHandler)
|
||||||
|
|
||||||
|
r.Handlers.Unmarshal.PushBack(adaptToResponseTimeoutError)
|
||||||
|
r.Handlers.UnmarshalError.PushBack(adaptToResponseTimeoutError)
|
||||||
|
}
|
||||||
|
}
|
234
vendor/github.com/aws/aws-sdk-go/aws/request/validation.go
generated
vendored
Normal file
234
vendor/github.com/aws/aws-sdk-go/aws/request/validation.go
generated
vendored
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// InvalidParameterErrCode is the error code for invalid parameters errors
|
||||||
|
InvalidParameterErrCode = "InvalidParameter"
|
||||||
|
// ParamRequiredErrCode is the error code for required parameter errors
|
||||||
|
ParamRequiredErrCode = "ParamRequiredError"
|
||||||
|
// ParamMinValueErrCode is the error code for fields with too low of a
|
||||||
|
// number value.
|
||||||
|
ParamMinValueErrCode = "ParamMinValueError"
|
||||||
|
// ParamMinLenErrCode is the error code for fields without enough elements.
|
||||||
|
ParamMinLenErrCode = "ParamMinLenError"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Validator provides a way for types to perform validation logic on their
|
||||||
|
// input values that external code can use to determine if a type's values
|
||||||
|
// are valid.
|
||||||
|
type Validator interface {
|
||||||
|
Validate() error
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ErrInvalidParams provides wrapping of invalid parameter errors found when
|
||||||
|
// validating API operation input parameters.
|
||||||
|
type ErrInvalidParams struct {
|
||||||
|
// Context is the base context of the invalid parameter group.
|
||||||
|
Context string
|
||||||
|
errs []ErrInvalidParam
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds a new invalid parameter error to the collection of invalid
|
||||||
|
// parameters. The context of the invalid parameter will be updated to reflect
|
||||||
|
// this collection.
|
||||||
|
func (e *ErrInvalidParams) Add(err ErrInvalidParam) {
|
||||||
|
err.SetContext(e.Context)
|
||||||
|
e.errs = append(e.errs, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNested adds the invalid parameter errors from another ErrInvalidParams
|
||||||
|
// value into this collection. The nested errors will have their nested context
|
||||||
|
// updated and base context to reflect the merging.
|
||||||
|
//
|
||||||
|
// Use for nested validations errors.
|
||||||
|
func (e *ErrInvalidParams) AddNested(nestedCtx string, nested ErrInvalidParams) {
|
||||||
|
for _, err := range nested.errs {
|
||||||
|
err.SetContext(e.Context)
|
||||||
|
err.AddNestedContext(nestedCtx)
|
||||||
|
e.errs = append(e.errs, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the number of invalid parameter errors
|
||||||
|
func (e ErrInvalidParams) Len() int {
|
||||||
|
return len(e.errs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code returns the code of the error
|
||||||
|
func (e ErrInvalidParams) Code() string {
|
||||||
|
return InvalidParameterErrCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message returns the message of the error
|
||||||
|
func (e ErrInvalidParams) Message() string {
|
||||||
|
return fmt.Sprintf("%d validation error(s) found.", len(e.errs))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns the string formatted form of the invalid parameters.
|
||||||
|
func (e ErrInvalidParams) Error() string {
|
||||||
|
w := &bytes.Buffer{}
|
||||||
|
fmt.Fprintf(w, "%s: %s\n", e.Code(), e.Message())
|
||||||
|
|
||||||
|
for _, err := range e.errs {
|
||||||
|
fmt.Fprintf(w, "- %s\n", err.Message())
|
||||||
|
}
|
||||||
|
|
||||||
|
return w.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrigErr returns the invalid parameters as a awserr.BatchedErrors value
|
||||||
|
func (e ErrInvalidParams) OrigErr() error {
|
||||||
|
return awserr.NewBatchError(
|
||||||
|
InvalidParameterErrCode, e.Message(), e.OrigErrs())
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrigErrs returns a slice of the invalid parameters
|
||||||
|
func (e ErrInvalidParams) OrigErrs() []error {
|
||||||
|
errs := make([]error, len(e.errs))
|
||||||
|
for i := 0; i < len(errs); i++ {
|
||||||
|
errs[i] = e.errs[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ErrInvalidParam represents an invalid parameter error type.
|
||||||
|
type ErrInvalidParam interface {
|
||||||
|
awserr.Error
|
||||||
|
|
||||||
|
// Field name the error occurred on.
|
||||||
|
Field() string
|
||||||
|
|
||||||
|
// SetContext updates the context of the error.
|
||||||
|
SetContext(string)
|
||||||
|
|
||||||
|
// AddNestedContext updates the error's context to include a nested level.
|
||||||
|
AddNestedContext(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
type errInvalidParam struct {
|
||||||
|
context string
|
||||||
|
nestedContext string
|
||||||
|
field string
|
||||||
|
code string
|
||||||
|
msg string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code returns the error code for the type of invalid parameter.
|
||||||
|
func (e *errInvalidParam) Code() string {
|
||||||
|
return e.code
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message returns the reason the parameter was invalid, and its context.
|
||||||
|
func (e *errInvalidParam) Message() string {
|
||||||
|
return fmt.Sprintf("%s, %s.", e.msg, e.Field())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns the string version of the invalid parameter error.
|
||||||
|
func (e *errInvalidParam) Error() string {
|
||||||
|
return fmt.Sprintf("%s: %s", e.code, e.Message())
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrigErr returns nil, Implemented for awserr.Error interface.
|
||||||
|
func (e *errInvalidParam) OrigErr() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Field Returns the field and context the error occurred.
|
||||||
|
func (e *errInvalidParam) Field() string {
|
||||||
|
field := e.context
|
||||||
|
if len(field) > 0 {
|
||||||
|
field += "."
|
||||||
|
}
|
||||||
|
if len(e.nestedContext) > 0 {
|
||||||
|
field += fmt.Sprintf("%s.", e.nestedContext)
|
||||||
|
}
|
||||||
|
field += e.field
|
||||||
|
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContext updates the base context of the error.
|
||||||
|
func (e *errInvalidParam) SetContext(ctx string) {
|
||||||
|
e.context = ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddNestedContext prepends a context to the field's path.
|
||||||
|
func (e *errInvalidParam) AddNestedContext(ctx string) {
|
||||||
|
if len(e.nestedContext) == 0 {
|
||||||
|
e.nestedContext = ctx
|
||||||
|
} else {
|
||||||
|
e.nestedContext = fmt.Sprintf("%s.%s", ctx, e.nestedContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ErrParamRequired represents an required parameter error.
|
||||||
|
type ErrParamRequired struct {
|
||||||
|
errInvalidParam
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewErrParamRequired creates a new required parameter error.
|
||||||
|
func NewErrParamRequired(field string) *ErrParamRequired {
|
||||||
|
return &ErrParamRequired{
|
||||||
|
errInvalidParam{
|
||||||
|
code: ParamRequiredErrCode,
|
||||||
|
field: field,
|
||||||
|
msg: fmt.Sprintf("missing required field"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ErrParamMinValue represents a minimum value parameter error.
|
||||||
|
type ErrParamMinValue struct {
|
||||||
|
errInvalidParam
|
||||||
|
min float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewErrParamMinValue creates a new minimum value parameter error.
|
||||||
|
func NewErrParamMinValue(field string, min float64) *ErrParamMinValue {
|
||||||
|
return &ErrParamMinValue{
|
||||||
|
errInvalidParam: errInvalidParam{
|
||||||
|
code: ParamMinValueErrCode,
|
||||||
|
field: field,
|
||||||
|
msg: fmt.Sprintf("minimum field value of %v", min),
|
||||||
|
},
|
||||||
|
min: min,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MinValue returns the field's require minimum value.
|
||||||
|
//
|
||||||
|
// float64 is returned for both int and float min values.
|
||||||
|
func (e *ErrParamMinValue) MinValue() float64 {
|
||||||
|
return e.min
|
||||||
|
}
|
||||||
|
|
||||||
|
// An ErrParamMinLen represents a minimum length parameter error.
|
||||||
|
type ErrParamMinLen struct {
|
||||||
|
errInvalidParam
|
||||||
|
min int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewErrParamMinLen creates a new minimum length parameter error.
|
||||||
|
func NewErrParamMinLen(field string, min int) *ErrParamMinLen {
|
||||||
|
return &ErrParamMinLen{
|
||||||
|
errInvalidParam: errInvalidParam{
|
||||||
|
code: ParamMinLenErrCode,
|
||||||
|
field: field,
|
||||||
|
msg: fmt.Sprintf("minimum field size of %v", min),
|
||||||
|
},
|
||||||
|
min: min,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MinLen returns the field's required minimum length.
|
||||||
|
func (e *ErrParamMinLen) MinLen() int {
|
||||||
|
return e.min
|
||||||
|
}
|
295
vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go
generated
vendored
Normal file
295
vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go
generated
vendored
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awsutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WaiterResourceNotReadyErrorCode is the error code returned by a waiter when
|
||||||
|
// the waiter's max attempts have been exhausted.
|
||||||
|
const WaiterResourceNotReadyErrorCode = "ResourceNotReady"
|
||||||
|
|
||||||
|
// A WaiterOption is a function that will update the Waiter value's fields to
|
||||||
|
// configure the waiter.
|
||||||
|
type WaiterOption func(*Waiter)
|
||||||
|
|
||||||
|
// WithWaiterMaxAttempts returns the maximum number of times the waiter should
|
||||||
|
// attempt to check the resource for the target state.
|
||||||
|
func WithWaiterMaxAttempts(max int) WaiterOption {
|
||||||
|
return func(w *Waiter) {
|
||||||
|
w.MaxAttempts = max
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaiterDelay will return a delay the waiter should pause between attempts to
|
||||||
|
// check the resource state. The passed in attempt is the number of times the
|
||||||
|
// Waiter has checked the resource state.
|
||||||
|
//
|
||||||
|
// Attempt is the number of attempts the Waiter has made checking the resource
|
||||||
|
// state.
|
||||||
|
type WaiterDelay func(attempt int) time.Duration
|
||||||
|
|
||||||
|
// ConstantWaiterDelay returns a WaiterDelay that will always return a constant
|
||||||
|
// delay the waiter should use between attempts. It ignores the number of
|
||||||
|
// attempts made.
|
||||||
|
func ConstantWaiterDelay(delay time.Duration) WaiterDelay {
|
||||||
|
return func(attempt int) time.Duration {
|
||||||
|
return delay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithWaiterDelay will set the Waiter to use the WaiterDelay passed in.
|
||||||
|
func WithWaiterDelay(delayer WaiterDelay) WaiterOption {
|
||||||
|
return func(w *Waiter) {
|
||||||
|
w.Delay = delayer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithWaiterLogger returns a waiter option to set the logger a waiter
|
||||||
|
// should use to log warnings and errors to.
|
||||||
|
func WithWaiterLogger(logger aws.Logger) WaiterOption {
|
||||||
|
return func(w *Waiter) {
|
||||||
|
w.Logger = logger
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithWaiterRequestOptions returns a waiter option setting the request
|
||||||
|
// options for each request the waiter makes. Appends to waiter's request
|
||||||
|
// options already set.
|
||||||
|
func WithWaiterRequestOptions(opts ...Option) WaiterOption {
|
||||||
|
return func(w *Waiter) {
|
||||||
|
w.RequestOptions = append(w.RequestOptions, opts...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Waiter provides the functionality to perform a blocking call which will
|
||||||
|
// wait for a resource state to be satisfied by a service.
|
||||||
|
//
|
||||||
|
// This type should not be used directly. The API operations provided in the
|
||||||
|
// service packages prefixed with "WaitUntil" should be used instead.
|
||||||
|
type Waiter struct {
|
||||||
|
Name string
|
||||||
|
Acceptors []WaiterAcceptor
|
||||||
|
Logger aws.Logger
|
||||||
|
|
||||||
|
MaxAttempts int
|
||||||
|
Delay WaiterDelay
|
||||||
|
|
||||||
|
RequestOptions []Option
|
||||||
|
NewRequest func([]Option) (*Request, error)
|
||||||
|
SleepWithContext func(aws.Context, time.Duration) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplyOptions updates the waiter with the list of waiter options provided.
|
||||||
|
func (w *Waiter) ApplyOptions(opts ...WaiterOption) {
|
||||||
|
for _, fn := range opts {
|
||||||
|
fn(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaiterState are states the waiter uses based on WaiterAcceptor definitions
|
||||||
|
// to identify if the resource state the waiter is waiting on has occurred.
|
||||||
|
type WaiterState int
|
||||||
|
|
||||||
|
// String returns the string representation of the waiter state.
|
||||||
|
func (s WaiterState) String() string {
|
||||||
|
switch s {
|
||||||
|
case SuccessWaiterState:
|
||||||
|
return "success"
|
||||||
|
case FailureWaiterState:
|
||||||
|
return "failure"
|
||||||
|
case RetryWaiterState:
|
||||||
|
return "retry"
|
||||||
|
default:
|
||||||
|
return "unknown waiter state"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// States the waiter acceptors will use to identify target resource states.
|
||||||
|
const (
|
||||||
|
SuccessWaiterState WaiterState = iota // waiter successful
|
||||||
|
FailureWaiterState // waiter failed
|
||||||
|
RetryWaiterState // waiter needs to be retried
|
||||||
|
)
|
||||||
|
|
||||||
|
// WaiterMatchMode is the mode that the waiter will use to match the WaiterAcceptor
|
||||||
|
// definition's Expected attribute.
|
||||||
|
type WaiterMatchMode int
|
||||||
|
|
||||||
|
// Modes the waiter will use when inspecting API response to identify target
|
||||||
|
// resource states.
|
||||||
|
const (
|
||||||
|
PathAllWaiterMatch WaiterMatchMode = iota // match on all paths
|
||||||
|
PathWaiterMatch // match on specific path
|
||||||
|
PathAnyWaiterMatch // match on any path
|
||||||
|
PathListWaiterMatch // match on list of paths
|
||||||
|
StatusWaiterMatch // match on status code
|
||||||
|
ErrorWaiterMatch // match on error
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of the waiter match mode.
|
||||||
|
func (m WaiterMatchMode) String() string {
|
||||||
|
switch m {
|
||||||
|
case PathAllWaiterMatch:
|
||||||
|
return "pathAll"
|
||||||
|
case PathWaiterMatch:
|
||||||
|
return "path"
|
||||||
|
case PathAnyWaiterMatch:
|
||||||
|
return "pathAny"
|
||||||
|
case PathListWaiterMatch:
|
||||||
|
return "pathList"
|
||||||
|
case StatusWaiterMatch:
|
||||||
|
return "status"
|
||||||
|
case ErrorWaiterMatch:
|
||||||
|
return "error"
|
||||||
|
default:
|
||||||
|
return "unknown waiter match mode"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitWithContext will make requests for the API operation using NewRequest to
|
||||||
|
// build API requests. The request's response will be compared against the
|
||||||
|
// Waiter's Acceptors to determine the successful state of the resource the
|
||||||
|
// waiter is inspecting.
|
||||||
|
//
|
||||||
|
// The passed in context must not be nil. If it is nil a panic will occur. The
|
||||||
|
// Context will be used to cancel the waiter's pending requests and retry delays.
|
||||||
|
// Use aws.BackgroundContext if no context is available.
|
||||||
|
//
|
||||||
|
// The waiter will continue until the target state defined by the Acceptors,
|
||||||
|
// or the max attempts expires.
|
||||||
|
//
|
||||||
|
// Will return the WaiterResourceNotReadyErrorCode error code if the waiter's
|
||||||
|
// retryer ShouldRetry returns false. This normally will happen when the max
|
||||||
|
// wait attempts expires.
|
||||||
|
func (w Waiter) WaitWithContext(ctx aws.Context) error {
|
||||||
|
|
||||||
|
for attempt := 1; ; attempt++ {
|
||||||
|
req, err := w.NewRequest(w.RequestOptions)
|
||||||
|
if err != nil {
|
||||||
|
waiterLogf(w.Logger, "unable to create request %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
req.Handlers.Build.PushBack(MakeAddToUserAgentFreeFormHandler("Waiter"))
|
||||||
|
err = req.Send()
|
||||||
|
|
||||||
|
// See if any of the acceptors match the request's response, or error
|
||||||
|
for _, a := range w.Acceptors {
|
||||||
|
if matched, matchErr := a.match(w.Name, w.Logger, req, err); matched {
|
||||||
|
return matchErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Waiter should only check the resource state MaxAttempts times
|
||||||
|
// This is here instead of in the for loop above to prevent delaying
|
||||||
|
// unnecessary when the waiter will not retry.
|
||||||
|
if attempt == w.MaxAttempts {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delay to wait before inspecting the resource again
|
||||||
|
delay := w.Delay(attempt)
|
||||||
|
if sleepFn := req.Config.SleepDelay; sleepFn != nil {
|
||||||
|
// Support SleepDelay for backwards compatibility and testing
|
||||||
|
sleepFn(delay)
|
||||||
|
} else {
|
||||||
|
sleepCtxFn := w.SleepWithContext
|
||||||
|
if sleepCtxFn == nil {
|
||||||
|
sleepCtxFn = aws.SleepWithContext
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := sleepCtxFn(ctx, delay); err != nil {
|
||||||
|
return awserr.New(CanceledErrorCode, "waiter context canceled", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return awserr.New(WaiterResourceNotReadyErrorCode, "exceeded wait attempts", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// A WaiterAcceptor provides the information needed to wait for an API operation
|
||||||
|
// to complete.
|
||||||
|
type WaiterAcceptor struct {
|
||||||
|
State WaiterState
|
||||||
|
Matcher WaiterMatchMode
|
||||||
|
Argument string
|
||||||
|
Expected interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// match returns if the acceptor found a match with the passed in request
|
||||||
|
// or error. True is returned if the acceptor made a match, error is returned
|
||||||
|
// if there was an error attempting to perform the match.
|
||||||
|
func (a *WaiterAcceptor) match(name string, l aws.Logger, req *Request, err error) (bool, error) {
|
||||||
|
result := false
|
||||||
|
var vals []interface{}
|
||||||
|
|
||||||
|
switch a.Matcher {
|
||||||
|
case PathAllWaiterMatch, PathWaiterMatch:
|
||||||
|
// Require all matches to be equal for result to match
|
||||||
|
vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument)
|
||||||
|
if len(vals) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
result = true
|
||||||
|
for _, val := range vals {
|
||||||
|
if !awsutil.DeepEqual(val, a.Expected) {
|
||||||
|
result = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case PathAnyWaiterMatch:
|
||||||
|
// Only a single match needs to equal for the result to match
|
||||||
|
vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument)
|
||||||
|
for _, val := range vals {
|
||||||
|
if awsutil.DeepEqual(val, a.Expected) {
|
||||||
|
result = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case PathListWaiterMatch:
|
||||||
|
// ignored matcher
|
||||||
|
case StatusWaiterMatch:
|
||||||
|
s := a.Expected.(int)
|
||||||
|
result = s == req.HTTPResponse.StatusCode
|
||||||
|
case ErrorWaiterMatch:
|
||||||
|
if aerr, ok := err.(awserr.Error); ok {
|
||||||
|
result = aerr.Code() == a.Expected.(string)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
waiterLogf(l, "WARNING: Waiter %s encountered unexpected matcher: %s",
|
||||||
|
name, a.Matcher)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !result {
|
||||||
|
// If there was no matching result found there is nothing more to do
|
||||||
|
// for this response, retry the request.
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch a.State {
|
||||||
|
case SuccessWaiterState:
|
||||||
|
// waiter completed
|
||||||
|
return true, nil
|
||||||
|
case FailureWaiterState:
|
||||||
|
// Waiter failure state triggered
|
||||||
|
return true, awserr.New(WaiterResourceNotReadyErrorCode,
|
||||||
|
"failed waiting for successful resource state", err)
|
||||||
|
case RetryWaiterState:
|
||||||
|
// clear the error and retry the operation
|
||||||
|
return false, nil
|
||||||
|
default:
|
||||||
|
waiterLogf(l, "WARNING: Waiter %s encountered unexpected state: %s",
|
||||||
|
name, a.State)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func waiterLogf(logger aws.Logger, msg string, args ...interface{}) {
|
||||||
|
if logger != nil {
|
||||||
|
logger.Log(fmt.Sprintf(msg, args...))
|
||||||
|
}
|
||||||
|
}
|
273
vendor/github.com/aws/aws-sdk-go/aws/session/doc.go
generated
vendored
Normal file
273
vendor/github.com/aws/aws-sdk-go/aws/session/doc.go
generated
vendored
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
// Create Session
|
||||||
|
sess := session.Must(session.NewSession())
|
||||||
|
|
||||||
|
// Create a Session with a custom region
|
||||||
|
sess := session.Must(session.NewSession(&aws.Config{
|
||||||
|
Region: aws.String("us-east-1"),
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 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).
|
||||||
|
|
||||||
|
// Equivalent to session.NewSession()
|
||||||
|
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||||
|
// Options
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Specify profile to load for the session's config
|
||||||
|
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||||
|
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",
|
||||||
|
}))
|
||||||
|
|
||||||
|
// Force enable Shared Config support
|
||||||
|
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||||
|
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:
|
||||||
|
|
||||||
|
// Create a session, and add additional handlers for all service
|
||||||
|
// clients created with the Session to inherit. Adds logging handler.
|
||||||
|
sess := session.Must(session.NewSession())
|
||||||
|
|
||||||
|
sess.Handlers.Send.PushFront(func(r *request.Request) {
|
||||||
|
// Log every request made and its payload
|
||||||
|
logger.Println("Request: %s/%s, Payload: %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.
|
||||||
|
|
||||||
|
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
|
||||||
|
loaded. This includes credentials, region, and support for assume role. In
|
||||||
|
addition the Session will load its configuration from both the shared config
|
||||||
|
file (~/.aws/config) and shared credentials file (~/.aws/credentials). Both
|
||||||
|
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 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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
role_arn = arn:aws:iam::<account_number>:role/<role_name>
|
||||||
|
source_profile = profile_with_creds
|
||||||
|
external_id = 1234
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
Environment Variables
|
||||||
|
|
||||||
|
When a Session is created several environment variables can be set to adjust
|
||||||
|
how the SDK functions, and what configuration data it loads when creating
|
||||||
|
Sessions. All environment values are optional, but some values like credentials
|
||||||
|
require multiple of the values to set or the partial values will be ignored.
|
||||||
|
All environment variable values are strings unless otherwise noted.
|
||||||
|
|
||||||
|
Environment configuration values. If set both Access Key ID and Secret Access
|
||||||
|
Key must be provided. Session Token and optionally also be provided, but is
|
||||||
|
not required.
|
||||||
|
|
||||||
|
# Access Key ID
|
||||||
|
AWS_ACCESS_KEY_ID=AKID
|
||||||
|
AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set.
|
||||||
|
|
||||||
|
# Secret Access Key
|
||||||
|
AWS_SECRET_ACCESS_KEY=SECRET
|
||||||
|
AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set.
|
||||||
|
|
||||||
|
# Session Token
|
||||||
|
AWS_SESSION_TOKEN=TOKEN
|
||||||
|
|
||||||
|
Region value will instruct the SDK where to make service API requests to. If is
|
||||||
|
not provided in the environment the region must be provided before a service
|
||||||
|
client request is made.
|
||||||
|
|
||||||
|
AWS_REGION=us-east-1
|
||||||
|
|
||||||
|
# AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set,
|
||||||
|
# and AWS_REGION is not also set.
|
||||||
|
AWS_DEFAULT_REGION=us-east-1
|
||||||
|
|
||||||
|
Profile name the SDK should load use when loading shared config from the
|
||||||
|
configuration files. If not provided "default" will be used as the profile name.
|
||||||
|
|
||||||
|
AWS_PROFILE=my_profile
|
||||||
|
|
||||||
|
# AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set,
|
||||||
|
# and AWS_PROFILE is not also set.
|
||||||
|
AWS_DEFAULT_PROFILE=my_profile
|
||||||
|
|
||||||
|
SDK load config instructs the SDK to load the shared config in addition to
|
||||||
|
shared credentials. This also expands the configuration loaded so the shared
|
||||||
|
credentials will have parity with the shared config file. This also enables
|
||||||
|
Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE
|
||||||
|
env values as well.
|
||||||
|
|
||||||
|
AWS_SDK_LOAD_CONFIG=1
|
||||||
|
|
||||||
|
Shared credentials file path can be set to instruct the SDK to use an alternative
|
||||||
|
file for the shared credentials. If not set the file will be loaded from
|
||||||
|
$HOME/.aws/credentials on Linux/Unix based systems, and
|
||||||
|
%USERPROFILE%\.aws\credentials on Windows.
|
||||||
|
|
||||||
|
AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials
|
||||||
|
|
||||||
|
Shared config file path can be set to instruct the SDK to use an alternative
|
||||||
|
file for the shared config. If not set the file will be loaded from
|
||||||
|
$HOME/.aws/config on Linux/Unix based systems, and
|
||||||
|
%USERPROFILE%\.aws\config on Windows.
|
||||||
|
|
||||||
|
AWS_CONFIG_FILE=$HOME/my_shared_config
|
||||||
|
|
||||||
|
Path to a custom Credentials Authority (CA) bundle PEM file 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.
|
||||||
|
|
||||||
|
AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle
|
||||||
|
|
||||||
|
Enabling this option will attempt to merge the Transport into the SDK's HTTP
|
||||||
|
client. If the client's Transport is not a http.Transport an error will be
|
||||||
|
returned. If the Transport's TLS config is set this option will cause the SDK
|
||||||
|
to overwrite the Transport's TLS config's RootCAs value. If the CA bundle file
|
||||||
|
contains multiple certificates all of them will be loaded.
|
||||||
|
|
||||||
|
The Session option CustomCABundle is also available when creating sessions
|
||||||
|
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.
|
||||||
|
|
||||||
|
Setting a custom HTTPClient in the aws.Config options will override this setting.
|
||||||
|
To use this option and custom HTTP client, the HTTP client needs to be provided
|
||||||
|
when creating the session. Not the service client.
|
||||||
|
*/
|
||||||
|
package session
|
191
vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
generated
vendored
Normal file
191
vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
package session
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EnvProviderName provides a name of the provider when config is loaded from environment.
|
||||||
|
const EnvProviderName = "EnvConfigCredentials"
|
||||||
|
|
||||||
|
// envConfig is a collection of environment values the SDK will read
|
||||||
|
// setup config from. All environment values are optional. But some values
|
||||||
|
// such as credentials require multiple values to be complete or the values
|
||||||
|
// will be ignored.
|
||||||
|
type envConfig struct {
|
||||||
|
// Environment configuration values. If set both Access Key ID and Secret Access
|
||||||
|
// Key must be provided. Session Token and optionally also be provided, but is
|
||||||
|
// not required.
|
||||||
|
//
|
||||||
|
// # Access Key ID
|
||||||
|
// AWS_ACCESS_KEY_ID=AKID
|
||||||
|
// AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set.
|
||||||
|
//
|
||||||
|
// # Secret Access Key
|
||||||
|
// AWS_SECRET_ACCESS_KEY=SECRET
|
||||||
|
// AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set.
|
||||||
|
//
|
||||||
|
// # Session Token
|
||||||
|
// AWS_SESSION_TOKEN=TOKEN
|
||||||
|
Creds credentials.Value
|
||||||
|
|
||||||
|
// Region value will instruct the SDK where to make service API requests to. If is
|
||||||
|
// not provided in the environment the region must be provided before a service
|
||||||
|
// client request is made.
|
||||||
|
//
|
||||||
|
// AWS_REGION=us-east-1
|
||||||
|
//
|
||||||
|
// # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set,
|
||||||
|
// # and AWS_REGION is not also set.
|
||||||
|
// AWS_DEFAULT_REGION=us-east-1
|
||||||
|
Region string
|
||||||
|
|
||||||
|
// Profile name the SDK should load use when loading shared configuration from the
|
||||||
|
// shared configuration files. If not provided "default" will be used as the
|
||||||
|
// profile name.
|
||||||
|
//
|
||||||
|
// AWS_PROFILE=my_profile
|
||||||
|
//
|
||||||
|
// # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set,
|
||||||
|
// # and AWS_PROFILE is not also set.
|
||||||
|
// AWS_DEFAULT_PROFILE=my_profile
|
||||||
|
Profile string
|
||||||
|
|
||||||
|
// SDK load config instructs the SDK to load the shared config in addition to
|
||||||
|
// shared credentials. This also expands the configuration loaded from the shared
|
||||||
|
// credentials to have parity with the shared config file. This also enables
|
||||||
|
// Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE
|
||||||
|
// env values as well.
|
||||||
|
//
|
||||||
|
// AWS_SDK_LOAD_CONFIG=1
|
||||||
|
EnableSharedConfig bool
|
||||||
|
|
||||||
|
// Shared credentials file path can be set to instruct the SDK to use an alternate
|
||||||
|
// file for the shared credentials. If not set the file will be loaded from
|
||||||
|
// $HOME/.aws/credentials on Linux/Unix based systems, and
|
||||||
|
// %USERPROFILE%\.aws\credentials on Windows.
|
||||||
|
//
|
||||||
|
// AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials
|
||||||
|
SharedCredentialsFile string
|
||||||
|
|
||||||
|
// Shared config file path can be set to instruct the SDK to use an alternate
|
||||||
|
// file for the shared config. If not set the file will be loaded from
|
||||||
|
// $HOME/.aws/config on Linux/Unix based systems, and
|
||||||
|
// %USERPROFILE%\.aws\config on Windows.
|
||||||
|
//
|
||||||
|
// AWS_CONFIG_FILE=$HOME/my_shared_config
|
||||||
|
SharedConfigFile string
|
||||||
|
|
||||||
|
// Sets the path to a custom Credentials Authroity (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.
|
||||||
|
//
|
||||||
|
// Enabling this option will attempt to merge the Transport
|
||||||
|
// into the SDK's HTTP client. If the client's Transport is
|
||||||
|
// not a http.Transport an error will be returned. If the
|
||||||
|
// Transport's TLS config is set this option will cause the
|
||||||
|
// SDK to overwrite the Transport's TLS config's RootCAs value.
|
||||||
|
//
|
||||||
|
// Setting a custom HTTPClient in the aws.Config options will override this setting.
|
||||||
|
// To use this option and custom HTTP client, the HTTP client needs to be provided
|
||||||
|
// when creating the session. Not the service client.
|
||||||
|
//
|
||||||
|
// AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle
|
||||||
|
CustomCABundle string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
credAccessEnvKey = []string{
|
||||||
|
"AWS_ACCESS_KEY_ID",
|
||||||
|
"AWS_ACCESS_KEY",
|
||||||
|
}
|
||||||
|
credSecretEnvKey = []string{
|
||||||
|
"AWS_SECRET_ACCESS_KEY",
|
||||||
|
"AWS_SECRET_KEY",
|
||||||
|
}
|
||||||
|
credSessionEnvKey = []string{
|
||||||
|
"AWS_SESSION_TOKEN",
|
||||||
|
}
|
||||||
|
|
||||||
|
regionEnvKeys = []string{
|
||||||
|
"AWS_REGION",
|
||||||
|
"AWS_DEFAULT_REGION", // Only read if AWS_SDK_LOAD_CONFIG is also set
|
||||||
|
}
|
||||||
|
profileEnvKeys = []string{
|
||||||
|
"AWS_PROFILE",
|
||||||
|
"AWS_DEFAULT_PROFILE", // Only read if AWS_SDK_LOAD_CONFIG is also set
|
||||||
|
}
|
||||||
|
sharedCredsFileEnvKey = []string{
|
||||||
|
"AWS_SHARED_CREDENTIALS_FILE",
|
||||||
|
}
|
||||||
|
sharedConfigFileEnvKey = []string{
|
||||||
|
"AWS_CONFIG_FILE",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// loadEnvConfig retrieves the SDK's environment configuration.
|
||||||
|
// See `envConfig` for the values that will be retrieved.
|
||||||
|
//
|
||||||
|
// 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 {
|
||||||
|
enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG"))
|
||||||
|
return envConfigLoad(enableSharedConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// loadEnvSharedConfig retrieves the SDK's environment configuration, and the
|
||||||
|
// SDK shared config. See `envConfig` for the values that will be retrieved.
|
||||||
|
//
|
||||||
|
// 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 {
|
||||||
|
return envConfigLoad(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func envConfigLoad(enableSharedConfig bool) envConfig {
|
||||||
|
cfg := envConfig{}
|
||||||
|
|
||||||
|
cfg.EnableSharedConfig = enableSharedConfig
|
||||||
|
|
||||||
|
setFromEnvVal(&cfg.Creds.AccessKeyID, credAccessEnvKey)
|
||||||
|
setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey)
|
||||||
|
setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey)
|
||||||
|
|
||||||
|
// Require logical grouping of credentials
|
||||||
|
if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 {
|
||||||
|
cfg.Creds = credentials.Value{}
|
||||||
|
} else {
|
||||||
|
cfg.Creds.ProviderName = EnvProviderName
|
||||||
|
}
|
||||||
|
|
||||||
|
regionKeys := regionEnvKeys
|
||||||
|
profileKeys := profileEnvKeys
|
||||||
|
if !cfg.EnableSharedConfig {
|
||||||
|
regionKeys = regionKeys[:1]
|
||||||
|
profileKeys = profileKeys[:1]
|
||||||
|
}
|
||||||
|
|
||||||
|
setFromEnvVal(&cfg.Region, regionKeys)
|
||||||
|
setFromEnvVal(&cfg.Profile, profileKeys)
|
||||||
|
|
||||||
|
setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey)
|
||||||
|
setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey)
|
||||||
|
|
||||||
|
cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
func setFromEnvVal(dst *string, keys []string) {
|
||||||
|
for _, k := range keys {
|
||||||
|
if v := os.Getenv(k); len(v) > 0 {
|
||||||
|
*dst = v
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
574
vendor/github.com/aws/aws-sdk-go/aws/session/session.go
generated
vendored
574
vendor/github.com/aws/aws-sdk-go/aws/session/session.go
generated
vendored
@ -1,62 +1,296 @@
|
|||||||
// Package session provides a way to create service clients with shared configuration
|
|
||||||
// and handlers.
|
|
||||||
//
|
|
||||||
// Generally this package should be used instead of the `defaults` package.
|
|
||||||
//
|
|
||||||
// A session should be used to share configurations and request handlers between multiple
|
|
||||||
// service clients. When service clients need specific configuration aws.Config can be
|
|
||||||
// used to provide additional configuration directly to the service client.
|
|
||||||
package session
|
package session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
"github.com/aws/aws-sdk-go/aws/client"
|
||||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
||||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
"github.com/aws/aws-sdk-go/aws/defaults"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
"github.com/aws/aws-sdk-go/private/endpoints"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Session provides a central location to create service clients from and
|
// A Session provides a central location to create service clients from and
|
||||||
// store configurations and request handlers for those services.
|
// store configurations and request handlers for those services.
|
||||||
//
|
//
|
||||||
// Sessions are safe to create service clients concurrently, but it is not safe
|
// Sessions are safe to create service clients concurrently, but it is not safe
|
||||||
// to mutate the session concurrently.
|
// to mutate the Session concurrently.
|
||||||
|
//
|
||||||
|
// The Session satisfies the service client's client.ClientConfigProvider.
|
||||||
type Session struct {
|
type Session struct {
|
||||||
Config *aws.Config
|
Config *aws.Config
|
||||||
Handlers request.Handlers
|
Handlers request.Handlers
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new instance of the handlers merging in the provided Configs
|
// New creates a new instance of the handlers merging in the provided configs
|
||||||
// on top of the SDK's default configurations. Once the session is created it
|
// on top of the SDK's default configurations. Once the Session is created it
|
||||||
// can be mutated to modify Configs or Handlers. The session is safe to be read
|
// can be mutated to modify the Config or Handlers. The Session is safe to be
|
||||||
// concurrently, but it should not be written to concurrently.
|
// read concurrently, but it should not be written to concurrently.
|
||||||
//
|
//
|
||||||
// Example:
|
// If the AWS_SDK_LOAD_CONFIG environment is set to a truthy value, the New
|
||||||
// // Create a session with the default config and request handlers.
|
// method could now encounter an error when loading the configuration. When
|
||||||
// sess := session.New()
|
// The environment variable is set, and an error occurs, New will return a
|
||||||
|
// session that will fail all requests reporting the error that occurred while
|
||||||
|
// loading the session. Use NewSession to get the error when creating the
|
||||||
|
// session.
|
||||||
//
|
//
|
||||||
// // Create a session with a custom region
|
// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
|
||||||
// sess := session.New(&aws.Config{Region: aws.String("us-east-1")})
|
// the shared config file (~/.aws/config) will also be loaded, in addition to
|
||||||
|
// the shared credentials file (~/.aws/credentials). Values set in both the
|
||||||
|
// shared config, and shared credentials will be taken from the shared
|
||||||
|
// credentials file.
|
||||||
//
|
//
|
||||||
// // Create a session, and add additional handlers for all service
|
// Deprecated: Use NewSession functions to create sessions instead. NewSession
|
||||||
// // clients created with the session to inherit. Adds logging handler.
|
// has the same functionality as New except an error can be returned when the
|
||||||
// sess := session.New()
|
// func is called instead of waiting to receive an error until a request is made.
|
||||||
// sess.Handlers.Send.PushFront(func(r *request.Request) {
|
|
||||||
// // Log every request made and its payload
|
|
||||||
// logger.Println("Request: %s/%s, Payload: %s", r.ClientInfo.ServiceName, r.Operation, r.Params)
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// // Create a S3 client instance from a session
|
|
||||||
// sess := session.New()
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
func New(cfgs ...*aws.Config) *Session {
|
func New(cfgs ...*aws.Config) *Session {
|
||||||
|
// load initial config from environment
|
||||||
|
envCfg := loadEnvConfig()
|
||||||
|
|
||||||
|
if envCfg.EnableSharedConfig {
|
||||||
|
s, err := newSession(Options{}, envCfg, cfgs...)
|
||||||
|
if err != nil {
|
||||||
|
// Old session.New expected all errors to be discovered when
|
||||||
|
// a request is made, and would report the errors then. This
|
||||||
|
// needs to be replicated if an error occurs while creating
|
||||||
|
// the session.
|
||||||
|
msg := "failed to create session with AWS_SDK_LOAD_CONFIG enabled. " +
|
||||||
|
"Use session.NewSession to handle errors occurring during session creation."
|
||||||
|
|
||||||
|
// 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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
return deprecatedNewSession(cfgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSession returns a new Session created from SDK defaults, config files,
|
||||||
|
// environment, and user provided config files. Once the Session is created
|
||||||
|
// it can be mutated to modify the Config or Handlers. The Session is safe to
|
||||||
|
// be read concurrently, but it should not be written to concurrently.
|
||||||
|
//
|
||||||
|
// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
|
||||||
|
// the shared config file (~/.aws/config) will also be loaded in addition to
|
||||||
|
// the shared credentials file (~/.aws/credentials). Values set in both the
|
||||||
|
// shared config, and shared credentials will be taken from the shared
|
||||||
|
// credentials file. Enabling the Shared Config will also allow the 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
|
||||||
|
// config profile, and controlling if shared config is enabled or not.
|
||||||
|
func NewSession(cfgs ...*aws.Config) (*Session, error) {
|
||||||
|
opts := Options{}
|
||||||
|
opts.Config.MergeIn(cfgs...)
|
||||||
|
|
||||||
|
return NewSessionWithOptions(opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SharedConfigState provides the ability to optionally override the state
|
||||||
|
// of the session's creation based on the shared config being enabled or
|
||||||
|
// disabled.
|
||||||
|
type SharedConfigState int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SharedConfigStateFromEnv does not override any state of the
|
||||||
|
// AWS_SDK_LOAD_CONFIG env var. It is the default value of the
|
||||||
|
// SharedConfigState type.
|
||||||
|
SharedConfigStateFromEnv SharedConfigState = iota
|
||||||
|
|
||||||
|
// SharedConfigDisable overrides the AWS_SDK_LOAD_CONFIG env var value
|
||||||
|
// and disables the shared config functionality.
|
||||||
|
SharedConfigDisable
|
||||||
|
|
||||||
|
// SharedConfigEnable overrides the AWS_SDK_LOAD_CONFIG env var value
|
||||||
|
// and enables the shared config functionality.
|
||||||
|
SharedConfigEnable
|
||||||
|
)
|
||||||
|
|
||||||
|
// Options provides the means to control how a Session is created and what
|
||||||
|
// configuration values will be loaded.
|
||||||
|
//
|
||||||
|
type Options struct {
|
||||||
|
// Provides config values for the SDK to use when creating service clients
|
||||||
|
// and making API requests to services. Any value set in with this field
|
||||||
|
// will override the associated value provided by the SDK defaults,
|
||||||
|
// environment or config files where relevant.
|
||||||
|
//
|
||||||
|
// If not set, configuration values from from SDK defaults, environment,
|
||||||
|
// config will be used.
|
||||||
|
Config aws.Config
|
||||||
|
|
||||||
|
// Overrides the config profile the Session should be created from. If not
|
||||||
|
// set the value of the environment variable will be loaded (AWS_PROFILE,
|
||||||
|
// or AWS_DEFAULT_PROFILE if the Shared Config is enabled).
|
||||||
|
//
|
||||||
|
// If not set and environment variables are not set the "default"
|
||||||
|
// (DefaultSharedConfigProfile) will be used as the profile to load the
|
||||||
|
// session config from.
|
||||||
|
Profile string
|
||||||
|
|
||||||
|
// Instructs how the Session will be created based on the AWS_SDK_LOAD_CONFIG
|
||||||
|
// environment variable. By default a Session will be created using the
|
||||||
|
// value provided by the AWS_SDK_LOAD_CONFIG environment variable.
|
||||||
|
//
|
||||||
|
// Setting this value to SharedConfigEnable or SharedConfigDisable
|
||||||
|
// will allow you to override the AWS_SDK_LOAD_CONFIG environment variable
|
||||||
|
// and enable or disable the shared config functionality.
|
||||||
|
SharedConfigState SharedConfigState
|
||||||
|
|
||||||
|
// Ordered list of files the session will load configuration from.
|
||||||
|
// It will override environment variable AWS_SHARED_CREDENTIALS_FILE, AWS_CONFIG_FILE.
|
||||||
|
SharedConfigFiles []string
|
||||||
|
|
||||||
|
// When the SDK's shared config is configured to assume a role with MFA
|
||||||
|
// this option is required in order to provide the mechanism that will
|
||||||
|
// retrieve the MFA token. There is no default value for this field. If
|
||||||
|
// it is not set an error will be returned when creating the session.
|
||||||
|
//
|
||||||
|
// This token provider will be called when ever the assumed role's
|
||||||
|
// credentials need to be refreshed. Within the context of service clients
|
||||||
|
// all sharing the same session the SDK will ensure calls to the token
|
||||||
|
// provider are atomic. When sharing a token provider across multiple
|
||||||
|
// sessions additional synchronization logic is needed to ensure the
|
||||||
|
// token providers do not introduce race conditions. It is recommend to
|
||||||
|
// share the session where possible.
|
||||||
|
//
|
||||||
|
// stscreds.StdinTokenProvider is a basic implementation that will prompt
|
||||||
|
// from stdin for the MFA token code.
|
||||||
|
//
|
||||||
|
// This field is only used if the shared configuration is enabled, and
|
||||||
|
// the config enables assume role wit MFA via the mfa_serial field.
|
||||||
|
AssumeRoleTokenProvider func() (string, error)
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// Enabling this option will attempt to merge the Transport into the SDK's HTTP
|
||||||
|
// client. If the client's Transport is not a http.Transport an error will be
|
||||||
|
// returned. If the Transport's TLS config is set this option will cause the SDK
|
||||||
|
// to overwrite the Transport's TLS config's RootCAs value. If the CA
|
||||||
|
// bundle reader contains multiple certificates all of them will be loaded.
|
||||||
|
//
|
||||||
|
// The Session option CustomCABundle is also available when creating sessions
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSessionWithOptions returns a new Session created from SDK defaults, config files,
|
||||||
|
// environment, and user provided config files. This func uses the Options
|
||||||
|
// values to configure how the Session is created.
|
||||||
|
//
|
||||||
|
// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
|
||||||
|
// the shared config file (~/.aws/config) will also be loaded in addition to
|
||||||
|
// the shared credentials file (~/.aws/credentials). Values set in both the
|
||||||
|
// shared config, and shared credentials will be taken from the shared
|
||||||
|
// credentials file. Enabling the Shared Config will also allow the Session
|
||||||
|
// to be built with retrieving credentials with AssumeRole set in the config.
|
||||||
|
//
|
||||||
|
// // Equivalent to session.New
|
||||||
|
// sess := session.Must(session.NewSessionWithOptions(session.Options{}))
|
||||||
|
//
|
||||||
|
// // Specify profile to load for the session's config
|
||||||
|
// sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||||
|
// 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",
|
||||||
|
// }))
|
||||||
|
//
|
||||||
|
// // Force enable Shared Config support
|
||||||
|
// sess := session.Must(session.NewSessionWithOptions(session.Options{
|
||||||
|
// SharedConfigState: session.SharedConfigEnable,
|
||||||
|
// }))
|
||||||
|
func NewSessionWithOptions(opts Options) (*Session, error) {
|
||||||
|
var envCfg envConfig
|
||||||
|
if opts.SharedConfigState == SharedConfigEnable {
|
||||||
|
envCfg = loadSharedEnvConfig()
|
||||||
|
} else {
|
||||||
|
envCfg = loadEnvConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(opts.Profile) > 0 {
|
||||||
|
envCfg.Profile = opts.Profile
|
||||||
|
}
|
||||||
|
|
||||||
|
switch opts.SharedConfigState {
|
||||||
|
case SharedConfigDisable:
|
||||||
|
envCfg.EnableSharedConfig = false
|
||||||
|
case SharedConfigEnable:
|
||||||
|
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)
|
||||||
|
if err != nil {
|
||||||
|
return nil, awserr.New("LoadCustomCABundleError",
|
||||||
|
"failed to open custom CA bundle PEM file", err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
opts.CustomCABundle = f
|
||||||
|
}
|
||||||
|
|
||||||
|
return newSession(opts, envCfg, &opts.Config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must is a helper function to ensure the Session is valid and there was no
|
||||||
|
// error when calling a NewSession function.
|
||||||
|
//
|
||||||
|
// This helper is intended to be used in variable initialization to load the
|
||||||
|
// Session and configuration at startup. Such as:
|
||||||
|
//
|
||||||
|
// var sess = session.Must(session.NewSession())
|
||||||
|
func Must(sess *Session, err error) *Session {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sess
|
||||||
|
}
|
||||||
|
|
||||||
|
func deprecatedNewSession(cfgs ...*aws.Config) *Session {
|
||||||
cfg := defaults.Config()
|
cfg := defaults.Config()
|
||||||
handlers := defaults.Handlers()
|
handlers := defaults.Handlers()
|
||||||
|
|
||||||
// Apply the passed in configs so the configuration can be applied to the
|
// Apply the passed in configs so the configuration can be applied to the
|
||||||
// default credential chain
|
// default credential chain
|
||||||
cfg.MergeIn(cfgs...)
|
cfg.MergeIn(cfgs...)
|
||||||
|
if cfg.EndpointResolver == nil {
|
||||||
|
// An endpoint resolver is required for a session to be able to provide
|
||||||
|
// endpoints for service client configurations.
|
||||||
|
cfg.EndpointResolver = endpoints.DefaultResolver()
|
||||||
|
}
|
||||||
cfg.Credentials = defaults.CredChain(cfg, handlers)
|
cfg.Credentials = defaults.CredChain(cfg, handlers)
|
||||||
|
|
||||||
// Reapply any passed in configs to override credentials if set
|
// Reapply any passed in configs to override credentials if set
|
||||||
@ -72,6 +306,211 @@ func New(cfgs ...*aws.Config) *Session {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) {
|
||||||
|
cfg := defaults.Config()
|
||||||
|
handlers := defaults.Handlers()
|
||||||
|
|
||||||
|
// Get a merged version of the user provided config to determine if
|
||||||
|
// credentials were.
|
||||||
|
userCfg := &aws.Config{}
|
||||||
|
userCfg.MergeIn(cfgs...)
|
||||||
|
|
||||||
|
// Ordered config files will be loaded in with later files overwriting
|
||||||
|
// previous config file values.
|
||||||
|
var cfgFiles []string
|
||||||
|
if opts.SharedConfigFiles != nil {
|
||||||
|
cfgFiles = opts.SharedConfigFiles
|
||||||
|
} else {
|
||||||
|
cfgFiles = []string{envCfg.SharedConfigFile, envCfg.SharedCredentialsFile}
|
||||||
|
if !envCfg.EnableSharedConfig {
|
||||||
|
// The shared config file (~/.aws/config) is only loaded if instructed
|
||||||
|
// to load via the envConfig.EnableSharedConfig (AWS_SDK_LOAD_CONFIG).
|
||||||
|
cfgFiles = cfgFiles[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load additional config from file(s)
|
||||||
|
sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &Session{
|
||||||
|
Config: cfg,
|
||||||
|
Handlers: handlers,
|
||||||
|
}
|
||||||
|
|
||||||
|
initHandlers(s)
|
||||||
|
|
||||||
|
// Setup HTTP client with custom cert bundle if enabled
|
||||||
|
if opts.CustomCABundle != nil {
|
||||||
|
if err := loadCustomCABundle(s, opts.CustomCABundle); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCustomCABundle(s *Session, bundle io.Reader) error {
|
||||||
|
var t *http.Transport
|
||||||
|
switch v := s.Config.HTTPClient.Transport.(type) {
|
||||||
|
case *http.Transport:
|
||||||
|
t = v
|
||||||
|
default:
|
||||||
|
if s.Config.HTTPClient.Transport != nil {
|
||||||
|
return awserr.New("LoadCustomCABundleError",
|
||||||
|
"unable to load custom CA bundle, HTTPClient's transport unsupported type", nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if t == nil {
|
||||||
|
t = &http.Transport{}
|
||||||
|
}
|
||||||
|
|
||||||
|
p, err := loadCertPool(bundle)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if t.TLSClientConfig == nil {
|
||||||
|
t.TLSClientConfig = &tls.Config{}
|
||||||
|
}
|
||||||
|
t.TLSClientConfig.RootCAs = p
|
||||||
|
|
||||||
|
s.Config.HTTPClient.Transport = t
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCertPool(r io.Reader) (*x509.CertPool, error) {
|
||||||
|
b, err := ioutil.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, awserr.New("LoadCustomCABundleError",
|
||||||
|
"failed to read custom CA bundle PEM file", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
p := x509.NewCertPool()
|
||||||
|
if !p.AppendCertsFromPEM(b) {
|
||||||
|
return nil, awserr.New("LoadCustomCABundleError",
|
||||||
|
"failed to load custom CA bundle PEM file", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
// Region if not already set by user
|
||||||
|
if len(aws.StringValue(cfg.Region)) == 0 {
|
||||||
|
if len(envCfg.Region) > 0 {
|
||||||
|
cfg.WithRegion(envCfg.Region)
|
||||||
|
} else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 {
|
||||||
|
cfg.WithRegion(sharedCfg.Region)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message is the description of the error
|
||||||
|
func (e AssumeRoleTokenProviderNotSetError) Message() string {
|
||||||
|
return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrigErr is the underlying error that caused the failure.
|
||||||
|
func (e AssumeRoleTokenProviderNotSetError) OrigErr() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error satisfies the error interface.
|
||||||
|
func (e AssumeRoleTokenProviderNotSetError) Error() string {
|
||||||
|
return awserr.SprintError(e.Code(), e.Message(), "", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
type credProviderError struct {
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
var emptyCreds = credentials.Value{}
|
||||||
|
|
||||||
|
func (c credProviderError) Retrieve() (credentials.Value, error) {
|
||||||
|
return credentials.Value{}, c.Err
|
||||||
|
}
|
||||||
|
func (c credProviderError) IsExpired() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func initHandlers(s *Session) {
|
func initHandlers(s *Session) {
|
||||||
// Add the Validate parameter handler if it is not disabled.
|
// Add the Validate parameter handler if it is not disabled.
|
||||||
s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
|
s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
|
||||||
@ -80,13 +519,12 @@ 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, coping the config
|
||||||
// and handlers. If any additional configs are provided they will be merged
|
// and handlers. If any additional configs are provided they will be merged
|
||||||
// on top of the session's copied config.
|
// on top of the Session's copied config.
|
||||||
//
|
//
|
||||||
// Example:
|
// // Create a copy of the current Session, configured for the us-west-2 region.
|
||||||
// // Create a copy of the current session, configured for the us-west-2 region.
|
// sess.Copy(&aws.Config{Region: aws.String("us-west-2")})
|
||||||
// sess.Copy(&aws.Config{Region: aws.String("us-west-2"})
|
|
||||||
func (s *Session) Copy(cfgs ...*aws.Config) *Session {
|
func (s *Session) Copy(cfgs ...*aws.Config) *Session {
|
||||||
newSession := &Session{
|
newSession := &Session{
|
||||||
Config: s.Config.Copy(cfgs...),
|
Config: s.Config.Copy(cfgs...),
|
||||||
@ -101,20 +539,68 @@ func (s *Session) Copy(cfgs ...*aws.Config) *Session {
|
|||||||
// ClientConfig satisfies the client.ConfigProvider interface and is used to
|
// ClientConfig satisfies the client.ConfigProvider interface and is used to
|
||||||
// configure the service client instances. Passing the Session to the service
|
// configure the service client instances. Passing the Session to the service
|
||||||
// client's constructor (New) will use this method to configure the client.
|
// client's constructor (New) will use this method to configure the client.
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// sess := session.New()
|
|
||||||
// s3.New(sess)
|
|
||||||
func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
|
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) {
|
||||||
s = s.Copy(cfgs...)
|
s = s.Copy(cfgs...)
|
||||||
endpoint, signingRegion := endpoints.NormalizeEndpoint(
|
|
||||||
aws.StringValue(s.Config.Endpoint), serviceName,
|
var resolved endpoints.ResolvedEndpoint
|
||||||
aws.StringValue(s.Config.Region), aws.BoolValue(s.Config.DisableSSL))
|
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
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return client.Config{
|
return client.Config{
|
||||||
Config: s.Config,
|
Config: s.Config,
|
||||||
Handlers: s.Handlers,
|
Handlers: s.Handlers,
|
||||||
Endpoint: endpoint,
|
Endpoint: resolved.URL,
|
||||||
SigningRegion: signingRegion,
|
SigningRegion: resolved.SigningRegion,
|
||||||
|
SigningName: resolved.SigningName,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientConfigNoResolveEndpoint is the same as ClientConfig with the exception
|
||||||
|
// that the EndpointResolver will not be used to resolve the endpoint. The only
|
||||||
|
// endpoint set must come from the aws.Config.Endpoint field.
|
||||||
|
func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Config {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
return client.Config{
|
||||||
|
Config: s.Config,
|
||||||
|
Handlers: s.Handlers,
|
||||||
|
Endpoint: resolved.URL,
|
||||||
|
SigningRegion: resolved.SigningRegion,
|
||||||
|
SigningName: resolved.SigningName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
295
vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
generated
vendored
Normal file
295
vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
generated
vendored
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Static Credentials group
|
||||||
|
accessKeyIDKey = `aws_access_key_id` // group required
|
||||||
|
secretAccessKey = `aws_secret_access_key` // group required
|
||||||
|
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
|
||||||
|
|
||||||
|
// Additional Config fields
|
||||||
|
regionKey = `region`
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// aws_access_key_id
|
||||||
|
// aws_secret_access_key
|
||||||
|
// aws_session_token
|
||||||
|
Creds credentials.Value
|
||||||
|
|
||||||
|
AssumeRole assumeRoleConfig
|
||||||
|
AssumeRoleSource *sharedConfig
|
||||||
|
|
||||||
|
// Region is the region the SDK should use for looking up AWS service endpoints
|
||||||
|
// and signing requests.
|
||||||
|
//
|
||||||
|
// region
|
||||||
|
Region string
|
||||||
|
}
|
||||||
|
|
||||||
|
type sharedConfigFile struct {
|
||||||
|
Filename string
|
||||||
|
IniData *ini.File
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// See sharedConfig.setFromFile for information how the config files
|
||||||
|
// will be loaded.
|
||||||
|
func loadSharedConfig(profile string, filenames []string) (sharedConfig, error) {
|
||||||
|
if len(profile) == 0 {
|
||||||
|
profile = DefaultSharedConfigProfile
|
||||||
|
}
|
||||||
|
|
||||||
|
files, err := loadSharedConfigIniFiles(filenames)
|
||||||
|
if err != nil {
|
||||||
|
return sharedConfig{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := sharedConfig{}
|
||||||
|
if err = cfg.setFromIniFiles(profile, files); 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) {
|
||||||
|
files := make([]sharedConfigFile, 0, len(filenames))
|
||||||
|
|
||||||
|
for _, filename := range filenames {
|
||||||
|
b, err := ioutil.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
// Skip files which can't be opened and read for whatever reason
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := ini.Load(b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, SharedConfigLoadError{Filename: filename, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
files = append(files, sharedConfigFile{
|
||||||
|
Filename: filename, IniData: f,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
// Trim files from the list that don't exist.
|
||||||
|
for _, f := range files {
|
||||||
|
if err := cfg.setFromIniFile(profile, f); err != nil {
|
||||||
|
if _, ok := err.(SharedConfigProfileNotExistsError); ok {
|
||||||
|
// Ignore proviles missings
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
//
|
||||||
|
// 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 {
|
||||||
|
// 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}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Region
|
||||||
|
if v := section.Key(regionKey).String(); len(v) > 0 {
|
||||||
|
cfg.Region = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SharedConfigLoadError is an error for the shared config file failed to load.
|
||||||
|
type SharedConfigLoadError struct {
|
||||||
|
Filename string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code is the short id of the error.
|
||||||
|
func (e SharedConfigLoadError) Code() string {
|
||||||
|
return "SharedConfigLoadError"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message is the description of the error
|
||||||
|
func (e SharedConfigLoadError) Message() string {
|
||||||
|
return fmt.Sprintf("failed to load config file, %s", e.Filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrigErr is the underlying error that caused the failure.
|
||||||
|
func (e SharedConfigLoadError) OrigErr() error {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error satisfies the error interface.
|
||||||
|
func (e SharedConfigLoadError) Error() string {
|
||||||
|
return awserr.SprintError(e.Code(), e.Message(), "", e.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SharedConfigProfileNotExistsError is an error for the shared config when
|
||||||
|
// the profile was not find in the config file.
|
||||||
|
type SharedConfigProfileNotExistsError struct {
|
||||||
|
Profile string
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code is the short id of the error.
|
||||||
|
func (e SharedConfigProfileNotExistsError) Code() string {
|
||||||
|
return "SharedConfigProfileNotExistsError"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message is the description of the error
|
||||||
|
func (e SharedConfigProfileNotExistsError) Message() string {
|
||||||
|
return fmt.Sprintf("failed to get profile, %s", e.Profile)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrigErr is the underlying error that caused the failure.
|
||||||
|
func (e SharedConfigProfileNotExistsError) OrigErr() error {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error satisfies the error interface.
|
||||||
|
func (e SharedConfigProfileNotExistsError) Error() string {
|
||||||
|
return awserr.SprintError(e.Code(), e.Message(), "", e.Err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SharedConfigAssumeRoleError is an error for the shared config when the
|
||||||
|
// profile contains assume role information, but that information is invalid
|
||||||
|
// or not complete.
|
||||||
|
type SharedConfigAssumeRoleError struct {
|
||||||
|
RoleARN string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code is the short id of the error.
|
||||||
|
func (e SharedConfigAssumeRoleError) Code() string {
|
||||||
|
return "SharedConfigAssumeRoleError"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OrigErr is the underlying error that caused the failure.
|
||||||
|
func (e SharedConfigAssumeRoleError) OrigErr() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error satisfies the error interface.
|
||||||
|
func (e SharedConfigAssumeRoleError) Error() string {
|
||||||
|
return awserr.SprintError(e.Code(), e.Message(), "", nil)
|
||||||
|
}
|
7
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go
generated
vendored
Normal file
7
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package v4
|
||||||
|
|
||||||
|
// WithUnsignedPayload will enable and set the UnsignedPayload field to
|
||||||
|
// true of the signer.
|
||||||
|
func WithUnsignedPayload(v4 *Signer) {
|
||||||
|
v4.UnsignedPayload = true
|
||||||
|
}
|
24
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go
generated
vendored
Normal file
24
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// +build go1.5
|
||||||
|
|
||||||
|
package v4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getURIPath(u *url.URL) string {
|
||||||
|
var uri string
|
||||||
|
|
||||||
|
if len(u.Opaque) > 0 {
|
||||||
|
uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/")
|
||||||
|
} else {
|
||||||
|
uri = u.EscapedPath()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(uri) == 0 {
|
||||||
|
uri = "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
return uri
|
||||||
|
}
|
762
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
generated
vendored
Normal file
762
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
generated
vendored
Normal file
@ -0,0 +1,762 @@
|
|||||||
|
// Package v4 implements signing for AWS V4 signer
|
||||||
|
//
|
||||||
|
// Provides request signing for request that need to be signed with
|
||||||
|
// AWS V4 Signatures.
|
||||||
|
//
|
||||||
|
// Standalone Signer
|
||||||
|
//
|
||||||
|
// Generally using the signer outside of the SDK should not require any additional
|
||||||
|
// logic when using Go v1.5 or higher. The signer does this by taking advantage
|
||||||
|
// of the URL.EscapedPath method. If your request URI requires additional escaping
|
||||||
|
// you many need to use the URL.Opaque to define what the raw URI should be sent
|
||||||
|
// to the service as.
|
||||||
|
//
|
||||||
|
// The signer will first check the URL.Opaque field, and use its value if set.
|
||||||
|
// The signer does require the URL.Opaque field to be set in the form of:
|
||||||
|
//
|
||||||
|
// "//<hostname>/<path>"
|
||||||
|
//
|
||||||
|
// // e.g.
|
||||||
|
// "//example.com/some/path"
|
||||||
|
//
|
||||||
|
// The leading "//" and hostname are required or the URL.Opaque escaping will
|
||||||
|
// not work correctly.
|
||||||
|
//
|
||||||
|
// If URL.Opaque is not set the signer will fallback to the URL.EscapedPath()
|
||||||
|
// method and using the returned value. If you're using Go v1.4 you must set
|
||||||
|
// URL.Opaque if the URI path needs escaping. If URL.Opaque is not set with
|
||||||
|
// Go v1.5 the signer will fallback to URL.Path.
|
||||||
|
//
|
||||||
|
// AWS v4 signature validation requires that the canonical string's URI path
|
||||||
|
// element must be the URI escaped form of the HTTP request's path.
|
||||||
|
// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
|
||||||
|
//
|
||||||
|
// The Go HTTP client will perform escaping automatically on the request. Some
|
||||||
|
// of these escaping may cause signature validation errors because the HTTP
|
||||||
|
// request differs from the URI path or query that the signature was generated.
|
||||||
|
// https://golang.org/pkg/net/url/#URL.EscapedPath
|
||||||
|
//
|
||||||
|
// Because of this, it is recommended that when using the signer outside of the
|
||||||
|
// SDK that explicitly escaping the request prior to being signed is preferable,
|
||||||
|
// and will help prevent signature validation errors. This can be done by setting
|
||||||
|
// the URL.Opaque or URL.RawPath. The SDK will use URL.Opaque first and then
|
||||||
|
// call URL.EscapedPath() if Opaque is not set.
|
||||||
|
//
|
||||||
|
// If signing a request intended for HTTP2 server, and you're using Go 1.6.2
|
||||||
|
// through 1.7.4 you should use the URL.RawPath as the pre-escaped form of the
|
||||||
|
// request URL. https://github.com/golang/go/issues/16847 points to a bug in
|
||||||
|
// Go pre 1.8 that fails to make HTTP2 requests using absolute URL in the HTTP
|
||||||
|
// message. URL.Opaque generally will force Go to make requests with absolute URL.
|
||||||
|
// URL.RawPath does not do this, but RawPath must be a valid escaping of Path
|
||||||
|
// or url.EscapedPath will ignore the RawPath escaping.
|
||||||
|
//
|
||||||
|
// Test `TestStandaloneSign` provides a complete example of using the signer
|
||||||
|
// outside of the SDK and pre-escaping the URI path.
|
||||||
|
package v4
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"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/private/protocol/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
authHeaderPrefix = "AWS4-HMAC-SHA256"
|
||||||
|
timeFormat = "20060102T150405Z"
|
||||||
|
shortTimeFormat = "20060102"
|
||||||
|
|
||||||
|
// emptyStringSHA256 is a SHA256 of an empty string
|
||||||
|
emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`
|
||||||
|
)
|
||||||
|
|
||||||
|
var ignoredHeaders = rules{
|
||||||
|
blacklist{
|
||||||
|
mapRule{
|
||||||
|
"Authorization": struct{}{},
|
||||||
|
"User-Agent": struct{}{},
|
||||||
|
"X-Amzn-Trace-Id": struct{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// requiredSignedHeaders is a whitelist for build canonical headers.
|
||||||
|
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{}{},
|
||||||
|
"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{}{},
|
||||||
|
"X-Amz-Grant-Full-control": struct{}{},
|
||||||
|
"X-Amz-Grant-Read": struct{}{},
|
||||||
|
"X-Amz-Grant-Read-Acp": struct{}{},
|
||||||
|
"X-Amz-Grant-Write": struct{}{},
|
||||||
|
"X-Amz-Grant-Write-Acp": struct{}{},
|
||||||
|
"X-Amz-Metadata-Directive": struct{}{},
|
||||||
|
"X-Amz-Mfa": struct{}{},
|
||||||
|
"X-Amz-Request-Payer": struct{}{},
|
||||||
|
"X-Amz-Server-Side-Encryption": struct{}{},
|
||||||
|
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{},
|
||||||
|
"X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
||||||
|
"X-Amz-Server-Side-Encryption-Customer-Key": struct{}{},
|
||||||
|
"X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
||||||
|
"X-Amz-Storage-Class": struct{}{},
|
||||||
|
"X-Amz-Website-Redirect-Location": struct{}{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
patterns{"X-Amz-Meta-"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// allowedHoisting is a whitelist for build query headers. The boolean value
|
||||||
|
// represents whether or not it is a pattern.
|
||||||
|
var allowedQueryHoisting = inclusiveRules{
|
||||||
|
blacklist{requiredSignedHeaders},
|
||||||
|
patterns{"X-Amz-"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signer applies AWS v4 signing to given request. Use this to sign requests
|
||||||
|
// that need to be signed with AWS V4 Signatures.
|
||||||
|
type Signer struct {
|
||||||
|
// The authentication credentials the request will be signed against.
|
||||||
|
// This value must be set to sign requests.
|
||||||
|
Credentials *credentials.Credentials
|
||||||
|
|
||||||
|
// Sets the log level the signer should use when reporting information to
|
||||||
|
// the logger. If the logger is nil nothing will be logged. See
|
||||||
|
// aws.LogLevelType for more information on available logging levels
|
||||||
|
//
|
||||||
|
// By default nothing will be logged.
|
||||||
|
Debug aws.LogLevelType
|
||||||
|
|
||||||
|
// The logger loging information will be written to. If there the logger
|
||||||
|
// is nil, nothing will be logged.
|
||||||
|
Logger aws.Logger
|
||||||
|
|
||||||
|
// Disables the Signer's moving HTTP header key/value pairs from the HTTP
|
||||||
|
// request header to the request's query string. This is most commonly used
|
||||||
|
// with pre-signed requests preventing headers from being added to the
|
||||||
|
// request's query string.
|
||||||
|
DisableHeaderHoisting bool
|
||||||
|
|
||||||
|
// Disables the automatic escaping of the URI path of the request for the
|
||||||
|
// siganture's canonical string's path. For services that do not need additional
|
||||||
|
// escaping then use this to disable the signer escaping the path.
|
||||||
|
//
|
||||||
|
// S3 is an example of a service that does not need additional escaping.
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// This does run the risk of signing a request with a body that will not be
|
||||||
|
// sent in the request. Need to ensure that the underlying data of the Body
|
||||||
|
// values are the same.
|
||||||
|
DisableRequestBodyOverwrite bool
|
||||||
|
|
||||||
|
// currentTimeFn returns the time value which represents the current time.
|
||||||
|
// This value should only be used for testing. If it is nil the default
|
||||||
|
// time.Now will be used.
|
||||||
|
currentTimeFn func() time.Time
|
||||||
|
|
||||||
|
// UnsignedPayload will prevent signing of the payload. This will only
|
||||||
|
// work for services that have support for this.
|
||||||
|
UnsignedPayload bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSigner returns a Signer pointer configured with the credentials and optional
|
||||||
|
// option values provided. If not options are provided the Signer will use its
|
||||||
|
// default configuration.
|
||||||
|
func NewSigner(credentials *credentials.Credentials, options ...func(*Signer)) *Signer {
|
||||||
|
v4 := &Signer{
|
||||||
|
Credentials: credentials,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, option := range options {
|
||||||
|
option(v4)
|
||||||
|
}
|
||||||
|
|
||||||
|
return v4
|
||||||
|
}
|
||||||
|
|
||||||
|
type signingCtx struct {
|
||||||
|
ServiceName string
|
||||||
|
Region string
|
||||||
|
Request *http.Request
|
||||||
|
Body io.ReadSeeker
|
||||||
|
Query url.Values
|
||||||
|
Time time.Time
|
||||||
|
ExpireTime time.Duration
|
||||||
|
SignedHeaderVals http.Header
|
||||||
|
|
||||||
|
DisableURIPathEscaping bool
|
||||||
|
|
||||||
|
credValues credentials.Value
|
||||||
|
isPresign bool
|
||||||
|
formattedTime string
|
||||||
|
formattedShortTime string
|
||||||
|
unsignedPayload bool
|
||||||
|
|
||||||
|
bodyDigest string
|
||||||
|
signedHeaders string
|
||||||
|
canonicalHeaders string
|
||||||
|
canonicalString string
|
||||||
|
credentialString string
|
||||||
|
stringToSign string
|
||||||
|
signature string
|
||||||
|
authorization string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign signs AWS v4 requests with the provided body, service name, region the
|
||||||
|
// request is made to, and time the request is signed at. The signTime allows
|
||||||
|
// you to specify that a request is signed for the future, and cannot be
|
||||||
|
// used until then.
|
||||||
|
//
|
||||||
|
// Returns a list of HTTP headers that were included in the signature or an
|
||||||
|
// error if signing the request failed. Generally for signed requests this value
|
||||||
|
// is not needed as the full request context will be captured by the http.Request
|
||||||
|
// value. It is included for reference though.
|
||||||
|
//
|
||||||
|
// Sign will set the request's Body to be the `body` parameter passed in. If
|
||||||
|
// the body is not already an io.ReadCloser, it will be wrapped within one. If
|
||||||
|
// a `nil` body parameter passed to Sign, the request's Body field will be
|
||||||
|
// also set to nil. Its important to note that this functionality will not
|
||||||
|
// change the request's ContentLength of the request.
|
||||||
|
//
|
||||||
|
// Sign differs from Presign in that it will sign the request using HTTP
|
||||||
|
// header values. This type of signing is intended for http.Request values that
|
||||||
|
// will not be shared, or are shared in a way the header values on the request
|
||||||
|
// will not be lost.
|
||||||
|
//
|
||||||
|
// The requests body is an io.ReadSeeker so the SHA256 of the body can be
|
||||||
|
// generated. To bypass the signer computing the hash you can set the
|
||||||
|
// "X-Amz-Content-Sha256" header with a precomputed value. The signer will
|
||||||
|
// only compute the hash if the request header value is empty.
|
||||||
|
func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) {
|
||||||
|
return v4.signWithBody(r, body, service, region, 0, signTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Presign signs AWS v4 requests with the provided body, service name, region
|
||||||
|
// the request is made to, and time the request is signed at. The signTime
|
||||||
|
// allows you to specify that a request is signed for the future, and cannot
|
||||||
|
// be used until then.
|
||||||
|
//
|
||||||
|
// Returns a list of HTTP headers that were included in the signature or an
|
||||||
|
// error if signing the request failed. For presigned requests these headers
|
||||||
|
// and their values must be included on the HTTP request when it is made. This
|
||||||
|
// is helpful to know what header values need to be shared with the party the
|
||||||
|
// presigned request will be distributed to.
|
||||||
|
//
|
||||||
|
// Presign differs from Sign in that it will sign the request using query string
|
||||||
|
// instead of header values. This allows you to share the Presigned Request's
|
||||||
|
// URL with third parties, or distribute it throughout your system with minimal
|
||||||
|
// dependencies.
|
||||||
|
//
|
||||||
|
// Presign also takes an exp value which is the duration the
|
||||||
|
// signed request will be valid after the signing time. This is allows you to
|
||||||
|
// set when the request will expire.
|
||||||
|
//
|
||||||
|
// The requests body is an io.ReadSeeker so the SHA256 of the body can be
|
||||||
|
// generated. To bypass the signer computing the hash you can set the
|
||||||
|
// "X-Amz-Content-Sha256" header with a precomputed value. The signer will
|
||||||
|
// only compute the hash if the request header value is empty.
|
||||||
|
//
|
||||||
|
// Presigning a S3 request will not compute the body's SHA256 hash by default.
|
||||||
|
// This is done due to the general use case for S3 presigned URLs is to share
|
||||||
|
// PUT/GET capabilities. If you would like to include the body's SHA256 in the
|
||||||
|
// presigned request's signature you can set the "X-Amz-Content-Sha256"
|
||||||
|
// HTTP header and that will be included in the request's signature.
|
||||||
|
func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
|
||||||
|
return v4.signWithBody(r, body, service, region, exp, signTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
|
||||||
|
currentTimeFn := v4.currentTimeFn
|
||||||
|
if currentTimeFn == nil {
|
||||||
|
currentTimeFn = time.Now
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := &signingCtx{
|
||||||
|
Request: r,
|
||||||
|
Body: body,
|
||||||
|
Query: r.URL.Query(),
|
||||||
|
Time: signTime,
|
||||||
|
ExpireTime: exp,
|
||||||
|
isPresign: exp != 0,
|
||||||
|
ServiceName: service,
|
||||||
|
Region: region,
|
||||||
|
DisableURIPathEscaping: v4.DisableURIPathEscaping,
|
||||||
|
unsignedPayload: v4.UnsignedPayload,
|
||||||
|
}
|
||||||
|
|
||||||
|
for key := range ctx.Query {
|
||||||
|
sort.Strings(ctx.Query[key])
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.isRequestSigned() {
|
||||||
|
ctx.Time = currentTimeFn()
|
||||||
|
ctx.handlePresignRemoval()
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
ctx.credValues, err = v4.Credentials.Get()
|
||||||
|
if err != nil {
|
||||||
|
return http.Header{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.assignAmzQueryValues()
|
||||||
|
ctx.build(v4.DisableHeaderHoisting)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// the body the request was signed for attached.
|
||||||
|
if !(v4.DisableRequestBodyOverwrite || ctx.isPresign) {
|
||||||
|
var reader io.ReadCloser
|
||||||
|
if body != nil {
|
||||||
|
var ok bool
|
||||||
|
if reader, ok = body.(io.ReadCloser); !ok {
|
||||||
|
reader = ioutil.NopCloser(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.Body = reader
|
||||||
|
}
|
||||||
|
|
||||||
|
if v4.Debug.Matches(aws.LogDebugWithSigning) {
|
||||||
|
v4.logSigningInfo(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.SignedHeaderVals, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *signingCtx) handlePresignRemoval() {
|
||||||
|
if !ctx.isPresign {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// The credentials have expired for this request. The current signing
|
||||||
|
// is invalid, and needs to be request because the request will fail.
|
||||||
|
ctx.removePresign()
|
||||||
|
|
||||||
|
// Update the request's query string to ensure the values stays in
|
||||||
|
// sync in the case retrieving the new credentials fails.
|
||||||
|
ctx.Request.URL.RawQuery = ctx.Query.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *signingCtx) assignAmzQueryValues() {
|
||||||
|
if ctx.isPresign {
|
||||||
|
ctx.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
|
||||||
|
if ctx.credValues.SessionToken != "" {
|
||||||
|
ctx.Query.Set("X-Amz-Security-Token", ctx.credValues.SessionToken)
|
||||||
|
} else {
|
||||||
|
ctx.Query.Del("X-Amz-Security-Token")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.credValues.SessionToken != "" {
|
||||||
|
ctx.Request.Header.Set("X-Amz-Security-Token", ctx.credValues.SessionToken)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignRequestHandler is a named request handler the SDK will use to sign
|
||||||
|
// service client request with using the V4 signature.
|
||||||
|
var SignRequestHandler = request.NamedHandler{
|
||||||
|
Name: "v4.SignRequestHandler", Fn: SignSDKRequest,
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignSDKRequest signs an AWS request with the V4 signature. This
|
||||||
|
// request handler should only be used with the SDK's built in service client's
|
||||||
|
// API operation requests.
|
||||||
|
//
|
||||||
|
// This function should not be used on its on its own, but in conjunction with
|
||||||
|
// an AWS service client's API operation call. To sign a standalone request
|
||||||
|
// not created by a service client's API operation method use the "Sign" or
|
||||||
|
// "Presign" functions of the "Signer" type.
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BuildNamedHandler will build a generic handler for signing.
|
||||||
|
func BuildNamedHandler(name string, opts ...func(*Signer)) request.NamedHandler {
|
||||||
|
return request.NamedHandler{
|
||||||
|
Name: name,
|
||||||
|
Fn: func(req *request.Request) {
|
||||||
|
signSDKRequestWithCurrTime(req, time.Now, opts...)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func signSDKRequestWithCurrTime(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 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
region := req.ClientInfo.SigningRegion
|
||||||
|
if region == "" {
|
||||||
|
region = aws.StringValue(req.Config.Region)
|
||||||
|
}
|
||||||
|
|
||||||
|
name := req.ClientInfo.SigningName
|
||||||
|
if name == "" {
|
||||||
|
name = req.ClientInfo.ServiceName
|
||||||
|
}
|
||||||
|
|
||||||
|
v4 := NewSigner(req.Config.Credentials, func(v4 *Signer) {
|
||||||
|
v4.Debug = req.Config.LogLevel.Value()
|
||||||
|
v4.Logger = req.Config.Logger
|
||||||
|
v4.DisableHeaderHoisting = req.NotHoist
|
||||||
|
v4.currentTimeFn = curTimeFn
|
||||||
|
if name == "s3" {
|
||||||
|
// S3 service should not have any escaping applied
|
||||||
|
v4.DisableURIPathEscaping = true
|
||||||
|
}
|
||||||
|
// Prevents setting the HTTPRequest's Body. Since the Body could be
|
||||||
|
// wrapped in a custom io.Closer that we do not want to be stompped
|
||||||
|
// on top of by the signer.
|
||||||
|
v4.DisableRequestBodyOverwrite = true
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt(v4)
|
||||||
|
}
|
||||||
|
|
||||||
|
signingTime := req.Time
|
||||||
|
if !req.LastSignedAt.IsZero() {
|
||||||
|
signingTime = req.LastSignedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(),
|
||||||
|
name, region, req.ExpireTime, signingTime,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
req.Error = err
|
||||||
|
req.SignedHeaderVals = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
req.SignedHeaderVals = signedHeaders
|
||||||
|
req.LastSignedAt = curTimeFn()
|
||||||
|
}
|
||||||
|
|
||||||
|
const logSignInfoMsg = `DEBUG: Request Signature:
|
||||||
|
---[ CANONICAL STRING ]-----------------------------
|
||||||
|
%s
|
||||||
|
---[ STRING TO SIGN ]--------------------------------
|
||||||
|
%s%s
|
||||||
|
-----------------------------------------------------`
|
||||||
|
const logSignedURLMsg = `
|
||||||
|
---[ SIGNED URL ]------------------------------------
|
||||||
|
%s`
|
||||||
|
|
||||||
|
func (v4 *Signer) logSigningInfo(ctx *signingCtx) {
|
||||||
|
signedURLMsg := ""
|
||||||
|
if ctx.isPresign {
|
||||||
|
signedURLMsg = fmt.Sprintf(logSignedURLMsg, ctx.Request.URL.String())
|
||||||
|
}
|
||||||
|
msg := fmt.Sprintf(logSignInfoMsg, ctx.canonicalString, ctx.stringToSign, signedURLMsg)
|
||||||
|
v4.Logger.Log(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *signingCtx) build(disableHeaderHoisting bool) {
|
||||||
|
ctx.buildTime() // no depends
|
||||||
|
ctx.buildCredentialString() // no depends
|
||||||
|
|
||||||
|
ctx.buildBodyDigest()
|
||||||
|
|
||||||
|
unsignedHeaders := ctx.Request.Header
|
||||||
|
if ctx.isPresign {
|
||||||
|
if !disableHeaderHoisting {
|
||||||
|
urlValues := url.Values{}
|
||||||
|
urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends
|
||||||
|
for k := range urlValues {
|
||||||
|
ctx.Query[k] = urlValues[k]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders)
|
||||||
|
ctx.buildCanonicalString() // depends on canon headers / signed headers
|
||||||
|
ctx.buildStringToSign() // depends on canon string
|
||||||
|
ctx.buildSignature() // depends on string to sign
|
||||||
|
|
||||||
|
if ctx.isPresign {
|
||||||
|
ctx.Request.URL.RawQuery += "&X-Amz-Signature=" + ctx.signature
|
||||||
|
} else {
|
||||||
|
parts := []string{
|
||||||
|
authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString,
|
||||||
|
"SignedHeaders=" + ctx.signedHeaders,
|
||||||
|
"Signature=" + ctx.signature,
|
||||||
|
}
|
||||||
|
ctx.Request.Header.Set("Authorization", strings.Join(parts, ", "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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-Expires", strconv.FormatInt(duration, 10))
|
||||||
|
} else {
|
||||||
|
ctx.Request.Header.Set("X-Amz-Date", ctx.formattedTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *signingCtx) buildCredentialString() {
|
||||||
|
ctx.credentialString = strings.Join([]string{
|
||||||
|
ctx.formattedShortTime,
|
||||||
|
ctx.Region,
|
||||||
|
ctx.ServiceName,
|
||||||
|
"aws4_request",
|
||||||
|
}, "/")
|
||||||
|
|
||||||
|
if ctx.isPresign {
|
||||||
|
ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildQuery(r rule, header http.Header) (url.Values, http.Header) {
|
||||||
|
query := url.Values{}
|
||||||
|
unsignedHeaders := http.Header{}
|
||||||
|
for k, h := range header {
|
||||||
|
if r.IsValid(k) {
|
||||||
|
query[k] = h
|
||||||
|
} else {
|
||||||
|
unsignedHeaders[k] = h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return query, unsignedHeaders
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
continue // ignored header
|
||||||
|
}
|
||||||
|
if ctx.SignedHeaderVals == nil {
|
||||||
|
ctx.SignedHeaderVals = make(http.Header)
|
||||||
|
}
|
||||||
|
|
||||||
|
lowerCaseKey := strings.ToLower(k)
|
||||||
|
if _, ok := ctx.SignedHeaderVals[lowerCaseKey]; ok {
|
||||||
|
// include additional values
|
||||||
|
ctx.SignedHeaderVals[lowerCaseKey] = append(ctx.SignedHeaderVals[lowerCaseKey], v...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = append(headers, lowerCaseKey)
|
||||||
|
ctx.SignedHeaderVals[lowerCaseKey] = v
|
||||||
|
}
|
||||||
|
sort.Strings(headers)
|
||||||
|
|
||||||
|
ctx.signedHeaders = strings.Join(headers, ";")
|
||||||
|
|
||||||
|
if ctx.isPresign {
|
||||||
|
ctx.Query.Set("X-Amz-SignedHeaders", ctx.signedHeaders)
|
||||||
|
}
|
||||||
|
|
||||||
|
headerValues := make([]string, len(headers))
|
||||||
|
for i, k := range headers {
|
||||||
|
if k == "host" {
|
||||||
|
if ctx.Request.Host != "" {
|
||||||
|
headerValues[i] = "host:" + ctx.Request.Host
|
||||||
|
} else {
|
||||||
|
headerValues[i] = "host:" + ctx.Request.URL.Host
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
headerValues[i] = k + ":" +
|
||||||
|
strings.Join(ctx.SignedHeaderVals[k], ",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stripExcessSpaces(headerValues)
|
||||||
|
ctx.canonicalHeaders = strings.Join(headerValues, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *signingCtx) buildCanonicalString() {
|
||||||
|
ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1)
|
||||||
|
|
||||||
|
uri := getURIPath(ctx.Request.URL)
|
||||||
|
|
||||||
|
if !ctx.DisableURIPathEscaping {
|
||||||
|
uri = rest.EscapePath(uri, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.canonicalString = strings.Join([]string{
|
||||||
|
ctx.Request.Method,
|
||||||
|
uri,
|
||||||
|
ctx.Request.URL.RawQuery,
|
||||||
|
ctx.canonicalHeaders + "\n",
|
||||||
|
ctx.signedHeaders,
|
||||||
|
ctx.bodyDigest,
|
||||||
|
}, "\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *signingCtx) buildStringToSign() {
|
||||||
|
ctx.stringToSign = strings.Join([]string{
|
||||||
|
authHeaderPrefix,
|
||||||
|
ctx.formattedTime,
|
||||||
|
ctx.credentialString,
|
||||||
|
hex.EncodeToString(makeSha256([]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))
|
||||||
|
ctx.signature = hex.EncodeToString(signature)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *signingCtx) buildBodyDigest() {
|
||||||
|
hash := ctx.Request.Header.Get("X-Amz-Content-Sha256")
|
||||||
|
if hash == "" {
|
||||||
|
if ctx.unsignedPayload || (ctx.isPresign && ctx.ServiceName == "s3") {
|
||||||
|
hash = "UNSIGNED-PAYLOAD"
|
||||||
|
} else if ctx.Body == nil {
|
||||||
|
hash = emptyStringSHA256
|
||||||
|
} else {
|
||||||
|
hash = hex.EncodeToString(makeSha256Reader(ctx.Body))
|
||||||
|
}
|
||||||
|
if ctx.unsignedPayload || ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" {
|
||||||
|
ctx.Request.Header.Set("X-Amz-Content-Sha256", hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.bodyDigest = hash
|
||||||
|
}
|
||||||
|
|
||||||
|
// isRequestSigned returns if the request is currently signed or presigned
|
||||||
|
func (ctx *signingCtx) isRequestSigned() bool {
|
||||||
|
if ctx.isPresign && ctx.Query.Get("X-Amz-Signature") != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if ctx.Request.Header.Get("Authorization") != "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsign removes signing flags for both signed and presigned requests.
|
||||||
|
func (ctx *signingCtx) removePresign() {
|
||||||
|
ctx.Query.Del("X-Amz-Algorithm")
|
||||||
|
ctx.Query.Del("X-Amz-Signature")
|
||||||
|
ctx.Query.Del("X-Amz-Security-Token")
|
||||||
|
ctx.Query.Del("X-Amz-Date")
|
||||||
|
ctx.Query.Del("X-Amz-Expires")
|
||||||
|
ctx.Query.Del("X-Amz-Credential")
|
||||||
|
ctx.Query.Del("X-Amz-SignedHeaders")
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeHmac(key []byte, data []byte) []byte {
|
||||||
|
hash := hmac.New(sha256.New, key)
|
||||||
|
hash.Write(data)
|
||||||
|
return hash.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeSha256(data []byte) []byte {
|
||||||
|
hash := sha256.New()
|
||||||
|
hash.Write(data)
|
||||||
|
return hash.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeSha256Reader(reader io.ReadSeeker) []byte {
|
||||||
|
hash := sha256.New()
|
||||||
|
start, _ := reader.Seek(0, 1)
|
||||||
|
defer reader.Seek(start, 0)
|
||||||
|
|
||||||
|
io.Copy(hash, reader)
|
||||||
|
return hash.Sum(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
const doubleSpace = " "
|
||||||
|
|
||||||
|
// stripExcessSpaces will rewrite the passed in slice's string values to not
|
||||||
|
// contain muliple side-by-side spaces.
|
||||||
|
func stripExcessSpaces(vals []string) {
|
||||||
|
var j, k, l, m, spaces int
|
||||||
|
for i, str := range vals {
|
||||||
|
// Trim trailing spaces
|
||||||
|
for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim leading spaces
|
||||||
|
for k = 0; k < j && str[k] == ' '; k++ {
|
||||||
|
}
|
||||||
|
str = str[k : j+1]
|
||||||
|
|
||||||
|
// Strip multiple spaces.
|
||||||
|
j = strings.Index(str, doubleSpace)
|
||||||
|
if j < 0 {
|
||||||
|
vals[i] = str
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := []byte(str)
|
||||||
|
for k, m, l = j, j, len(buf); k < l; k++ {
|
||||||
|
if buf[k] == ' ' {
|
||||||
|
if spaces == 0 {
|
||||||
|
// First space.
|
||||||
|
buf[m] = buf[k]
|
||||||
|
m++
|
||||||
|
}
|
||||||
|
spaces++
|
||||||
|
} else {
|
||||||
|
// End of multiple spaces.
|
||||||
|
spaces = 0
|
||||||
|
buf[m] = buf[k]
|
||||||
|
m++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vals[i] = string(buf[:m])
|
||||||
|
}
|
||||||
|
}
|
42
vendor/github.com/aws/aws-sdk-go/aws/types.go
generated
vendored
42
vendor/github.com/aws/aws-sdk-go/aws/types.go
generated
vendored
@ -5,7 +5,13 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser
|
// 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.
|
||||||
|
//
|
||||||
|
// Deprecated: Should only be used with io.ReadSeeker. If using for
|
||||||
|
// S3 PutObject to stream content use s3manager.Uploader instead.
|
||||||
func ReadSeekCloser(r io.Reader) ReaderSeekerCloser {
|
func ReadSeekCloser(r io.Reader) ReaderSeekerCloser {
|
||||||
return ReaderSeekerCloser{r}
|
return ReaderSeekerCloser{r}
|
||||||
}
|
}
|
||||||
@ -44,6 +50,12 @@ func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) {
|
|||||||
return int64(0), nil
|
return int64(0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSeeker returns if the underlying reader is also a seeker.
|
||||||
|
func (r ReaderSeekerCloser) IsSeeker() bool {
|
||||||
|
_, ok := r.r.(io.Seeker)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
// Close closes the ReaderSeekerCloser.
|
// Close closes the ReaderSeekerCloser.
|
||||||
//
|
//
|
||||||
// If the ReaderSeekerCloser is not an io.Closer nothing will be done.
|
// If the ReaderSeekerCloser is not an io.Closer nothing will be done.
|
||||||
@ -61,28 +73,46 @@ func (r ReaderSeekerCloser) Close() error {
|
|||||||
type WriteAtBuffer struct {
|
type WriteAtBuffer struct {
|
||||||
buf []byte
|
buf []byte
|
||||||
m sync.Mutex
|
m sync.Mutex
|
||||||
|
|
||||||
|
// GrowthCoeff defines the growth rate of the internal buffer. By
|
||||||
|
// default, the growth rate is 1, where expanding the internal
|
||||||
|
// buffer will allocate only enough capacity to fit the new expected
|
||||||
|
// length.
|
||||||
|
GrowthCoeff float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWriteAtBuffer creates a WriteAtBuffer with an internal buffer
|
||||||
|
// provided by buf.
|
||||||
|
func NewWriteAtBuffer(buf []byte) *WriteAtBuffer {
|
||||||
|
return &WriteAtBuffer{buf: buf}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteAt writes a slice of bytes to a buffer starting at the position provided
|
// WriteAt writes a slice of bytes to a buffer starting at the position provided
|
||||||
// The number of bytes written will be returned, or error. Can overwrite previous
|
// The number of bytes written will be returned, or error. Can overwrite previous
|
||||||
// written slices if the write ats overlap.
|
// written slices if the write ats overlap.
|
||||||
func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) {
|
func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) {
|
||||||
|
pLen := len(p)
|
||||||
|
expLen := pos + int64(pLen)
|
||||||
b.m.Lock()
|
b.m.Lock()
|
||||||
defer b.m.Unlock()
|
defer b.m.Unlock()
|
||||||
|
|
||||||
expLen := pos + int64(len(p))
|
|
||||||
if int64(len(b.buf)) < expLen {
|
if int64(len(b.buf)) < expLen {
|
||||||
newBuf := make([]byte, expLen)
|
if int64(cap(b.buf)) < expLen {
|
||||||
|
if b.GrowthCoeff < 1 {
|
||||||
|
b.GrowthCoeff = 1
|
||||||
|
}
|
||||||
|
newBuf := make([]byte, expLen, int64(b.GrowthCoeff*float64(expLen)))
|
||||||
copy(newBuf, b.buf)
|
copy(newBuf, b.buf)
|
||||||
b.buf = newBuf
|
b.buf = newBuf
|
||||||
}
|
}
|
||||||
|
b.buf = b.buf[:expLen]
|
||||||
|
}
|
||||||
copy(b.buf[pos:], p)
|
copy(b.buf[pos:], p)
|
||||||
return len(p), nil
|
return pLen, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns a slice of bytes written to the buffer.
|
// Bytes returns a slice of bytes written to the buffer.
|
||||||
func (b *WriteAtBuffer) Bytes() []byte {
|
func (b *WriteAtBuffer) Bytes() []byte {
|
||||||
b.m.Lock()
|
b.m.Lock()
|
||||||
defer b.m.Unlock()
|
defer b.m.Unlock()
|
||||||
return b.buf[:len(b.buf):len(b.buf)]
|
return b.buf
|
||||||
}
|
}
|
||||||
|
12
vendor/github.com/aws/aws-sdk-go/aws/url.go
generated
vendored
Normal file
12
vendor/github.com/aws/aws-sdk-go/aws/url.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import "net/url"
|
||||||
|
|
||||||
|
// URLHostname will extract the Hostname without port from the URL value.
|
||||||
|
//
|
||||||
|
// Wrapper of net/url#URL.Hostname for backwards Go version compatibility.
|
||||||
|
func URLHostname(url *url.URL) string {
|
||||||
|
return url.Hostname()
|
||||||
|
}
|
29
vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go
generated
vendored
Normal file
29
vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// +build !go1.8
|
||||||
|
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// URLHostname will extract the Hostname without port from the URL value.
|
||||||
|
//
|
||||||
|
// Copy of Go 1.8's net/url#URL.Hostname functionality.
|
||||||
|
func URLHostname(url *url.URL) string {
|
||||||
|
return stripPort(url.Host)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// stripPort is copy of Go 1.8 url#URL.Hostname functionality.
|
||||||
|
// https://golang.org/src/net/url/url.go
|
||||||
|
func stripPort(hostport string) string {
|
||||||
|
colon := strings.IndexByte(hostport, ':')
|
||||||
|
if colon == -1 {
|
||||||
|
return hostport
|
||||||
|
}
|
||||||
|
if i := strings.IndexByte(hostport, ']'); i != -1 {
|
||||||
|
return strings.TrimPrefix(hostport[:i], "[")
|
||||||
|
}
|
||||||
|
return hostport[:colon]
|
||||||
|
}
|
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"
|
const SDKName = "aws-sdk-go"
|
||||||
|
|
||||||
// SDKVersion is the version of this SDK
|
// SDKVersion is the version of this SDK
|
||||||
const SDKVersion = "1.1.4"
|
const SDKVersion = "1.10.51"
|
||||||
|
40
vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go
generated
vendored
Normal file
40
vendor/github.com/aws/aws-sdk-go/internal/shareddefaults/shared_config.go
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package shareddefaults
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SharedCredentialsFilename returns the SDK's default file path
|
||||||
|
// for the shared credentials file.
|
||||||
|
//
|
||||||
|
// Builds the shared config file path based on the OS's platform.
|
||||||
|
//
|
||||||
|
// - Linux/Unix: $HOME/.aws/credentials
|
||||||
|
// - Windows: %USERPROFILE%\.aws\credentials
|
||||||
|
func SharedCredentialsFilename() string {
|
||||||
|
return filepath.Join(UserHomeDir(), ".aws", "credentials")
|
||||||
|
}
|
||||||
|
|
||||||
|
// SharedConfigFilename returns the SDK's default file path for
|
||||||
|
// the shared config file.
|
||||||
|
//
|
||||||
|
// Builds the shared config file path based on the OS's platform.
|
||||||
|
//
|
||||||
|
// - Linux/Unix: $HOME/.aws/config
|
||||||
|
// - Windows: %USERPROFILE%\.aws\config
|
||||||
|
func SharedConfigFilename() string {
|
||||||
|
return filepath.Join(UserHomeDir(), ".aws", "config")
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserHomeDir returns the home directory for the user the process is
|
||||||
|
// running under.
|
||||||
|
func UserHomeDir() string {
|
||||||
|
if runtime.GOOS == "windows" { // Windows
|
||||||
|
return os.Getenv("USERPROFILE")
|
||||||
|
}
|
||||||
|
|
||||||
|
// *nix
|
||||||
|
return os.Getenv("HOME")
|
||||||
|
}
|
65
vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go
generated
vendored
65
vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.go
generated
vendored
@ -1,65 +0,0 @@
|
|||||||
// Package endpoints validates regional endpoints for services.
|
|
||||||
package endpoints
|
|
||||||
|
|
||||||
//go:generate go run ../model/cli/gen-endpoints/main.go endpoints.json endpoints_map.go
|
|
||||||
//go:generate gofmt -s -w endpoints_map.go
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NormalizeEndpoint takes and endpoint and service API information to return a
|
|
||||||
// normalized endpoint and signing region. If the endpoint is not an empty string
|
|
||||||
// the service name and region will be used to look up the service's API endpoint.
|
|
||||||
// If the endpoint is provided the scheme will be added if it is not present.
|
|
||||||
func NormalizeEndpoint(endpoint, serviceName, region string, disableSSL bool) (normEndpoint, signingRegion string) {
|
|
||||||
if endpoint == "" {
|
|
||||||
return EndpointForRegion(serviceName, region, disableSSL)
|
|
||||||
}
|
|
||||||
|
|
||||||
return AddScheme(endpoint, disableSSL), ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// EndpointForRegion returns an endpoint and its signing region for a service and region.
|
|
||||||
// if the service and region pair are not found endpoint and signingRegion will be empty.
|
|
||||||
func EndpointForRegion(svcName, region string, disableSSL bool) (endpoint, signingRegion string) {
|
|
||||||
derivedKeys := []string{
|
|
||||||
region + "/" + svcName,
|
|
||||||
region + "/*",
|
|
||||||
"*/" + svcName,
|
|
||||||
"*/*",
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, key := range derivedKeys {
|
|
||||||
if val, ok := endpointsMap.Endpoints[key]; ok {
|
|
||||||
ep := val.Endpoint
|
|
||||||
ep = strings.Replace(ep, "{region}", region, -1)
|
|
||||||
ep = strings.Replace(ep, "{service}", svcName, -1)
|
|
||||||
|
|
||||||
endpoint = ep
|
|
||||||
signingRegion = val.SigningRegion
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return AddScheme(endpoint, disableSSL), signingRegion
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regular expression to determine if the endpoint string is prefixed with a scheme.
|
|
||||||
var schemeRE = regexp.MustCompile("^([^:]+)://")
|
|
||||||
|
|
||||||
// AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no
|
|
||||||
// scheme. If disableSSL is true HTTP will be added instead of the default HTTPS.
|
|
||||||
func AddScheme(endpoint string, disableSSL bool) string {
|
|
||||||
if endpoint != "" && !schemeRE.MatchString(endpoint) {
|
|
||||||
scheme := "https"
|
|
||||||
if disableSSL {
|
|
||||||
scheme = "http"
|
|
||||||
}
|
|
||||||
endpoint = fmt.Sprintf("%s://%s", scheme, endpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
return endpoint
|
|
||||||
}
|
|
70
vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json
generated
vendored
70
vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints.json
generated
vendored
@ -1,70 +0,0 @@
|
|||||||
{
|
|
||||||
"version": 2,
|
|
||||||
"endpoints": {
|
|
||||||
"*/*": {
|
|
||||||
"endpoint": "{service}.{region}.amazonaws.com"
|
|
||||||
},
|
|
||||||
"cn-north-1/*": {
|
|
||||||
"endpoint": "{service}.{region}.amazonaws.com.cn",
|
|
||||||
"signatureVersion": "v4"
|
|
||||||
},
|
|
||||||
"us-gov-west-1/iam": {
|
|
||||||
"endpoint": "iam.us-gov.amazonaws.com"
|
|
||||||
},
|
|
||||||
"us-gov-west-1/sts": {
|
|
||||||
"endpoint": "sts.us-gov-west-1.amazonaws.com"
|
|
||||||
},
|
|
||||||
"us-gov-west-1/s3": {
|
|
||||||
"endpoint": "s3-{region}.amazonaws.com"
|
|
||||||
},
|
|
||||||
"*/cloudfront": {
|
|
||||||
"endpoint": "cloudfront.amazonaws.com",
|
|
||||||
"signingRegion": "us-east-1"
|
|
||||||
},
|
|
||||||
"*/cloudsearchdomain": {
|
|
||||||
"endpoint": "",
|
|
||||||
"signingRegion": "us-east-1"
|
|
||||||
},
|
|
||||||
"*/data.iot": {
|
|
||||||
"endpoint": "",
|
|
||||||
"signingRegion": "us-east-1"
|
|
||||||
},
|
|
||||||
"*/ec2metadata": {
|
|
||||||
"endpoint": "http://169.254.169.254/latest",
|
|
||||||
"signingRegion": "us-east-1"
|
|
||||||
},
|
|
||||||
"*/iam": {
|
|
||||||
"endpoint": "iam.amazonaws.com",
|
|
||||||
"signingRegion": "us-east-1"
|
|
||||||
},
|
|
||||||
"*/importexport": {
|
|
||||||
"endpoint": "importexport.amazonaws.com",
|
|
||||||
"signingRegion": "us-east-1"
|
|
||||||
},
|
|
||||||
"*/route53": {
|
|
||||||
"endpoint": "route53.amazonaws.com",
|
|
||||||
"signingRegion": "us-east-1"
|
|
||||||
},
|
|
||||||
"*/sts": {
|
|
||||||
"endpoint": "sts.amazonaws.com",
|
|
||||||
"signingRegion": "us-east-1"
|
|
||||||
},
|
|
||||||
"*/waf": {
|
|
||||||
"endpoint": "waf.amazonaws.com",
|
|
||||||
"signingRegion": "us-east-1"
|
|
||||||
},
|
|
||||||
"us-east-1/sdb": {
|
|
||||||
"endpoint": "sdb.amazonaws.com",
|
|
||||||
"signingRegion": "us-east-1"
|
|
||||||
},
|
|
||||||
"*/s3": {
|
|
||||||
"endpoint": "s3-{region}.amazonaws.com"
|
|
||||||
},
|
|
||||||
"us-east-1/s3": {
|
|
||||||
"endpoint": "s3.amazonaws.com"
|
|
||||||
},
|
|
||||||
"eu-central-1/s3": {
|
|
||||||
"endpoint": "{service}.{region}.amazonaws.com"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
83
vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go
generated
vendored
83
vendor/github.com/aws/aws-sdk-go/private/endpoints/endpoints_map.go
generated
vendored
@ -1,83 +0,0 @@
|
|||||||
package endpoints
|
|
||||||
|
|
||||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
|
||||||
|
|
||||||
type endpointStruct struct {
|
|
||||||
Version int
|
|
||||||
Endpoints map[string]endpointEntry
|
|
||||||
}
|
|
||||||
|
|
||||||
type endpointEntry struct {
|
|
||||||
Endpoint string
|
|
||||||
SigningRegion string
|
|
||||||
}
|
|
||||||
|
|
||||||
var endpointsMap = endpointStruct{
|
|
||||||
Version: 2,
|
|
||||||
Endpoints: map[string]endpointEntry{
|
|
||||||
"*/*": {
|
|
||||||
Endpoint: "{service}.{region}.amazonaws.com",
|
|
||||||
},
|
|
||||||
"*/cloudfront": {
|
|
||||||
Endpoint: "cloudfront.amazonaws.com",
|
|
||||||
SigningRegion: "us-east-1",
|
|
||||||
},
|
|
||||||
"*/cloudsearchdomain": {
|
|
||||||
Endpoint: "",
|
|
||||||
SigningRegion: "us-east-1",
|
|
||||||
},
|
|
||||||
"*/data.iot": {
|
|
||||||
Endpoint: "",
|
|
||||||
SigningRegion: "us-east-1",
|
|
||||||
},
|
|
||||||
"*/ec2metadata": {
|
|
||||||
Endpoint: "http://169.254.169.254/latest",
|
|
||||||
SigningRegion: "us-east-1",
|
|
||||||
},
|
|
||||||
"*/iam": {
|
|
||||||
Endpoint: "iam.amazonaws.com",
|
|
||||||
SigningRegion: "us-east-1",
|
|
||||||
},
|
|
||||||
"*/importexport": {
|
|
||||||
Endpoint: "importexport.amazonaws.com",
|
|
||||||
SigningRegion: "us-east-1",
|
|
||||||
},
|
|
||||||
"*/route53": {
|
|
||||||
Endpoint: "route53.amazonaws.com",
|
|
||||||
SigningRegion: "us-east-1",
|
|
||||||
},
|
|
||||||
"*/s3": {
|
|
||||||
Endpoint: "s3-{region}.amazonaws.com",
|
|
||||||
},
|
|
||||||
"*/sts": {
|
|
||||||
Endpoint: "sts.amazonaws.com",
|
|
||||||
SigningRegion: "us-east-1",
|
|
||||||
},
|
|
||||||
"*/waf": {
|
|
||||||
Endpoint: "waf.amazonaws.com",
|
|
||||||
SigningRegion: "us-east-1",
|
|
||||||
},
|
|
||||||
"cn-north-1/*": {
|
|
||||||
Endpoint: "{service}.{region}.amazonaws.com.cn",
|
|
||||||
},
|
|
||||||
"eu-central-1/s3": {
|
|
||||||
Endpoint: "{service}.{region}.amazonaws.com",
|
|
||||||
},
|
|
||||||
"us-east-1/s3": {
|
|
||||||
Endpoint: "s3.amazonaws.com",
|
|
||||||
},
|
|
||||||
"us-east-1/sdb": {
|
|
||||||
Endpoint: "sdb.amazonaws.com",
|
|
||||||
SigningRegion: "us-east-1",
|
|
||||||
},
|
|
||||||
"us-gov-west-1/iam": {
|
|
||||||
Endpoint: "iam.us-gov.amazonaws.com",
|
|
||||||
},
|
|
||||||
"us-gov-west-1/s3": {
|
|
||||||
Endpoint: "s3-{region}.amazonaws.com",
|
|
||||||
},
|
|
||||||
"us-gov-west-1/sts": {
|
|
||||||
Endpoint: "sts.us-gov-west-1.amazonaws.com",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
4
vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go
generated
vendored
@ -1,7 +1,7 @@
|
|||||||
// Package query provides serialisation of AWS query requests, and responses.
|
// Package query provides serialization of AWS query requests, and responses.
|
||||||
package query
|
package query
|
||||||
|
|
||||||
//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/query.json build_test.go
|
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/query.json build_test.go
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
"net/url"
|
||||||
|
7
vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go
generated
vendored
7
vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go
generated
vendored
@ -76,6 +76,9 @@ func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix stri
|
|||||||
if field.PkgPath != "" {
|
if field.PkgPath != "" {
|
||||||
continue // ignore unexported fields
|
continue // ignore unexported fields
|
||||||
}
|
}
|
||||||
|
if field.Tag.Get("ignore") != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if protocol.CanSetIdempotencyToken(value.Field(i), field) {
|
if protocol.CanSetIdempotencyToken(value.Field(i), field) {
|
||||||
token := protocol.GetIdempotencyToken()
|
token := protocol.GetIdempotencyToken()
|
||||||
@ -120,7 +123,11 @@ func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string
|
|||||||
|
|
||||||
// check for unflattened list member
|
// check for unflattened list member
|
||||||
if !q.isEC2 && tag.Get("flattened") == "" {
|
if !q.isEC2 && tag.Get("flattened") == "" {
|
||||||
|
if listName := tag.Get("locationNameList"); listName == "" {
|
||||||
prefix += ".member"
|
prefix += ".member"
|
||||||
|
} else {
|
||||||
|
prefix += "." + listName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < value.Len(); i++ {
|
for i := 0; i < value.Len(); i++ {
|
||||||
|
2
vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go
generated
vendored
2
vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
package query
|
package query
|
||||||
|
|
||||||
//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/query.json unmarshal_test.go
|
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/query.json unmarshal_test.go
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
38
vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go
generated
vendored
38
vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go
generated
vendored
@ -2,7 +2,7 @@ package query
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"io"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
@ -15,6 +15,10 @@ type xmlErrorResponse struct {
|
|||||||
RequestID string `xml:"RequestId"`
|
RequestID string `xml:"RequestId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type xmlServiceUnavailableResponse struct {
|
||||||
|
XMLName xml.Name `xml:"ServiceUnavailableException"`
|
||||||
|
}
|
||||||
|
|
||||||
// UnmarshalErrorHandler is a name request handler to unmarshal request errors
|
// UnmarshalErrorHandler is a name request handler to unmarshal request errors
|
||||||
var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError}
|
var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError}
|
||||||
|
|
||||||
@ -22,11 +26,16 @@ var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalEr
|
|||||||
func UnmarshalError(r *request.Request) {
|
func UnmarshalError(r *request.Request) {
|
||||||
defer r.HTTPResponse.Body.Close()
|
defer r.HTTPResponse.Body.Close()
|
||||||
|
|
||||||
resp := &xmlErrorResponse{}
|
bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||||
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
|
if err != nil {
|
||||||
if err != nil && err != io.EOF {
|
r.Error = awserr.New("SerializationError", "failed to read from query HTTP response body", err)
|
||||||
r.Error = awserr.New("SerializationError", "failed to decode query XML error response", err)
|
return
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
// First check for specific error
|
||||||
|
resp := xmlErrorResponse{}
|
||||||
|
decodeErr := xml.Unmarshal(bodyBytes, &resp)
|
||||||
|
if decodeErr == nil {
|
||||||
reqID := resp.RequestID
|
reqID := resp.RequestID
|
||||||
if reqID == "" {
|
if reqID == "" {
|
||||||
reqID = r.RequestID
|
reqID = r.RequestID
|
||||||
@ -36,5 +45,22 @@ func UnmarshalError(r *request.Request) {
|
|||||||
r.HTTPResponse.StatusCode,
|
r.HTTPResponse.StatusCode,
|
||||||
reqID,
|
reqID,
|
||||||
)
|
)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for unhandled error
|
||||||
|
servUnavailResp := xmlServiceUnavailableResponse{}
|
||||||
|
unavailErr := xml.Unmarshal(bodyBytes, &servUnavailResp)
|
||||||
|
if unavailErr == nil {
|
||||||
|
r.Error = awserr.NewRequestFailure(
|
||||||
|
awserr.New("ServiceUnavailableException", "service is unavailable", nil),
|
||||||
|
r.HTTPResponse.StatusCode,
|
||||||
|
r.RequestID,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed to retrieve any error message from the response body
|
||||||
|
r.Error = awserr.New("SerializationError",
|
||||||
|
"failed to decode query XML error response", decodeErr)
|
||||||
}
|
}
|
||||||
|
111
vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go
generated
vendored
111
vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go
generated
vendored
@ -4,6 +4,7 @@ package rest
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -14,6 +15,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
)
|
)
|
||||||
@ -46,14 +48,29 @@ var BuildHandler = request.NamedHandler{Name: "awssdk.rest.Build", Fn: Build}
|
|||||||
func Build(r *request.Request) {
|
func Build(r *request.Request) {
|
||||||
if r.ParamsFilled() {
|
if r.ParamsFilled() {
|
||||||
v := reflect.ValueOf(r.Params).Elem()
|
v := reflect.ValueOf(r.Params).Elem()
|
||||||
buildLocationElements(r, v)
|
buildLocationElements(r, v, false)
|
||||||
buildBody(r, v)
|
buildBody(r, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildLocationElements(r *request.Request, v reflect.Value) {
|
// BuildAsGET builds the REST component of a service request with the ability to hoist
|
||||||
|
// data from the body.
|
||||||
|
func BuildAsGET(r *request.Request) {
|
||||||
|
if r.ParamsFilled() {
|
||||||
|
v := reflect.ValueOf(r.Params).Elem()
|
||||||
|
buildLocationElements(r, v, true)
|
||||||
|
buildBody(r, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bool) {
|
||||||
query := r.HTTPRequest.URL.Query()
|
query := r.HTTPRequest.URL.Query()
|
||||||
|
|
||||||
|
// Setup the raw path to match the base path pattern. This is needed
|
||||||
|
// so that when the path is mutated a custom escaped version can be
|
||||||
|
// stored in RawPath that will be used by the Go client.
|
||||||
|
r.HTTPRequest.URL.RawPath = r.HTTPRequest.URL.Path
|
||||||
|
|
||||||
for i := 0; i < v.NumField(); i++ {
|
for i := 0; i < v.NumField(); i++ {
|
||||||
m := v.Field(i)
|
m := v.Field(i)
|
||||||
if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) {
|
if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) {
|
||||||
@ -66,23 +83,34 @@ func buildLocationElements(r *request.Request, v reflect.Value) {
|
|||||||
if name == "" {
|
if name == "" {
|
||||||
name = field.Name
|
name = field.Name
|
||||||
}
|
}
|
||||||
if m.Kind() == reflect.Ptr {
|
if kind := m.Kind(); kind == reflect.Ptr {
|
||||||
m = m.Elem()
|
m = m.Elem()
|
||||||
|
} else if kind == reflect.Interface {
|
||||||
|
if !m.Elem().IsValid() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !m.IsValid() {
|
if !m.IsValid() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if field.Tag.Get("ignore") != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
switch field.Tag.Get("location") {
|
switch field.Tag.Get("location") {
|
||||||
case "headers": // header maps
|
case "headers": // header maps
|
||||||
err = buildHeaderMap(&r.HTTPRequest.Header, m, field.Tag.Get("locationName"))
|
err = buildHeaderMap(&r.HTTPRequest.Header, m, field.Tag)
|
||||||
case "header":
|
case "header":
|
||||||
err = buildHeader(&r.HTTPRequest.Header, m, name)
|
err = buildHeader(&r.HTTPRequest.Header, m, name, field.Tag)
|
||||||
case "uri":
|
case "uri":
|
||||||
err = buildURI(r.HTTPRequest.URL, m, name)
|
err = buildURI(r.HTTPRequest.URL, m, name, field.Tag)
|
||||||
case "querystring":
|
case "querystring":
|
||||||
err = buildQueryString(query, m, name)
|
err = buildQueryString(query, m, name, field.Tag)
|
||||||
|
default:
|
||||||
|
if buildGETQuery {
|
||||||
|
err = buildQueryString(query, m, name, field.Tag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
r.Error = err
|
r.Error = err
|
||||||
}
|
}
|
||||||
@ -92,7 +120,9 @@ func buildLocationElements(r *request.Request, v reflect.Value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
r.HTTPRequest.URL.RawQuery = query.Encode()
|
r.HTTPRequest.URL.RawQuery = query.Encode()
|
||||||
updatePath(r.HTTPRequest.URL, r.HTTPRequest.URL.Path)
|
if !aws.BoolValue(r.Config.DisableRestProtocolURICleaning) {
|
||||||
|
cleanPath(r.HTTPRequest.URL)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildBody(r *request.Request, v reflect.Value) {
|
func buildBody(r *request.Request, v reflect.Value) {
|
||||||
@ -120,8 +150,8 @@ func buildBody(r *request.Request, v reflect.Value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildHeader(header *http.Header, v reflect.Value, name string) error {
|
func buildHeader(header *http.Header, v reflect.Value, name string, tag reflect.StructTag) error {
|
||||||
str, err := convertType(v)
|
str, err := convertType(v, tag)
|
||||||
if err == errValueNotSet {
|
if err == errValueNotSet {
|
||||||
return nil
|
return nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@ -133,9 +163,10 @@ func buildHeader(header *http.Header, v reflect.Value, name string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildHeaderMap(header *http.Header, v reflect.Value, prefix string) error {
|
func buildHeaderMap(header *http.Header, v reflect.Value, tag reflect.StructTag) error {
|
||||||
|
prefix := tag.Get("locationName")
|
||||||
for _, key := range v.MapKeys() {
|
for _, key := range v.MapKeys() {
|
||||||
str, err := convertType(v.MapIndex(key))
|
str, err := convertType(v.MapIndex(key), tag)
|
||||||
if err == errValueNotSet {
|
if err == errValueNotSet {
|
||||||
continue
|
continue
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@ -148,23 +179,24 @@ func buildHeaderMap(header *http.Header, v reflect.Value, prefix string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildURI(u *url.URL, v reflect.Value, name string) error {
|
func buildURI(u *url.URL, v reflect.Value, name string, tag reflect.StructTag) error {
|
||||||
value, err := convertType(v)
|
value, err := convertType(v, tag)
|
||||||
if err == errValueNotSet {
|
if err == errValueNotSet {
|
||||||
return nil
|
return nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return awserr.New("SerializationError", "failed to encode REST request", err)
|
return awserr.New("SerializationError", "failed to encode REST request", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
uri := u.Path
|
u.Path = strings.Replace(u.Path, "{"+name+"}", value, -1)
|
||||||
uri = strings.Replace(uri, "{"+name+"}", EscapePath(value, true), -1)
|
u.Path = strings.Replace(u.Path, "{"+name+"+}", value, -1)
|
||||||
uri = strings.Replace(uri, "{"+name+"+}", EscapePath(value, false), -1)
|
|
||||||
u.Path = uri
|
u.RawPath = strings.Replace(u.RawPath, "{"+name+"}", EscapePath(value, true), -1)
|
||||||
|
u.RawPath = strings.Replace(u.RawPath, "{"+name+"+}", EscapePath(value, false), -1)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildQueryString(query url.Values, v reflect.Value, name string) error {
|
func buildQueryString(query url.Values, v reflect.Value, name string, tag reflect.StructTag) error {
|
||||||
switch value := v.Interface().(type) {
|
switch value := v.Interface().(type) {
|
||||||
case []*string:
|
case []*string:
|
||||||
for _, item := range value {
|
for _, item := range value {
|
||||||
@ -181,7 +213,7 @@ func buildQueryString(query url.Values, v reflect.Value, name string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
str, err := convertType(v)
|
str, err := convertType(v, tag)
|
||||||
if err == errValueNotSet {
|
if err == errValueNotSet {
|
||||||
return nil
|
return nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
@ -193,25 +225,17 @@ func buildQueryString(query url.Values, v reflect.Value, name string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatePath(url *url.URL, urlPath string) {
|
func cleanPath(u *url.URL) {
|
||||||
scheme, query := url.Scheme, url.RawQuery
|
hasSlash := strings.HasSuffix(u.Path, "/")
|
||||||
|
|
||||||
hasSlash := strings.HasSuffix(urlPath, "/")
|
// clean up path, removing duplicate `/`
|
||||||
|
u.Path = path.Clean(u.Path)
|
||||||
|
u.RawPath = path.Clean(u.RawPath)
|
||||||
|
|
||||||
// clean up path
|
if hasSlash && !strings.HasSuffix(u.Path, "/") {
|
||||||
urlPath = path.Clean(urlPath)
|
u.Path += "/"
|
||||||
if hasSlash && !strings.HasSuffix(urlPath, "/") {
|
u.RawPath += "/"
|
||||||
urlPath += "/"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get formatted URL minus scheme so we can build this into Opaque
|
|
||||||
url.Scheme, url.Path, url.RawQuery = "", "", ""
|
|
||||||
s := url.String()
|
|
||||||
url.Scheme = scheme
|
|
||||||
url.RawQuery = query
|
|
||||||
|
|
||||||
// build opaque URI
|
|
||||||
url.Opaque = s + urlPath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EscapePath escapes part of a URL path in Amazon style
|
// EscapePath escapes part of a URL path in Amazon style
|
||||||
@ -222,14 +246,13 @@ func EscapePath(path string, encodeSep bool) string {
|
|||||||
if noEscape[c] || (c == '/' && !encodeSep) {
|
if noEscape[c] || (c == '/' && !encodeSep) {
|
||||||
buf.WriteByte(c)
|
buf.WriteByte(c)
|
||||||
} else {
|
} else {
|
||||||
buf.WriteByte('%')
|
fmt.Fprintf(&buf, "%%%02X", c)
|
||||||
buf.WriteString(strings.ToUpper(strconv.FormatUint(uint64(c), 16)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertType(v reflect.Value) (string, error) {
|
func convertType(v reflect.Value, tag reflect.StructTag) (string, error) {
|
||||||
v = reflect.Indirect(v)
|
v = reflect.Indirect(v)
|
||||||
if !v.IsValid() {
|
if !v.IsValid() {
|
||||||
return "", errValueNotSet
|
return "", errValueNotSet
|
||||||
@ -249,6 +272,16 @@ func convertType(v reflect.Value) (string, error) {
|
|||||||
str = strconv.FormatFloat(value, 'f', -1, 64)
|
str = strconv.FormatFloat(value, 'f', -1, 64)
|
||||||
case time.Time:
|
case time.Time:
|
||||||
str = value.UTC().Format(RFC822)
|
str = value.UTC().Format(RFC822)
|
||||||
|
case aws.JSONValue:
|
||||||
|
b, err := json.Marshal(value)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if tag.Get("location") == "header" {
|
||||||
|
str = base64.StdEncoding.EncodeToString(b)
|
||||||
|
} else {
|
||||||
|
str = string(b)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
|
err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
|
||||||
return "", err
|
return "", err
|
||||||
|
46
vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go
generated
vendored
46
vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go
generated
vendored
@ -1,8 +1,11 @@
|
|||||||
package rest
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -51,6 +54,7 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
|
|||||||
if payload.IsValid() {
|
if payload.IsValid() {
|
||||||
switch payload.Interface().(type) {
|
switch payload.Interface().(type) {
|
||||||
case []byte:
|
case []byte:
|
||||||
|
defer r.HTTPResponse.Body.Close()
|
||||||
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
|
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
|
||||||
@ -58,6 +62,7 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
|
|||||||
payload.Set(reflect.ValueOf(b))
|
payload.Set(reflect.ValueOf(b))
|
||||||
}
|
}
|
||||||
case *string:
|
case *string:
|
||||||
|
defer r.HTTPResponse.Body.Close()
|
||||||
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
|
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
|
||||||
@ -67,11 +72,19 @@ func unmarshalBody(r *request.Request, v reflect.Value) {
|
|||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
switch payload.Type().String() {
|
switch payload.Type().String() {
|
||||||
case "io.ReadSeeker":
|
case "io.ReadCloser":
|
||||||
payload.Set(reflect.ValueOf(aws.ReadSeekCloser(r.HTTPResponse.Body)))
|
|
||||||
case "aws.ReadSeekCloser", "io.ReadCloser":
|
|
||||||
payload.Set(reflect.ValueOf(r.HTTPResponse.Body))
|
payload.Set(reflect.ValueOf(r.HTTPResponse.Body))
|
||||||
|
case "io.ReadSeeker":
|
||||||
|
b, err := ioutil.ReadAll(r.HTTPResponse.Body)
|
||||||
|
if err != nil {
|
||||||
|
r.Error = awserr.New("SerializationError",
|
||||||
|
"failed to read response body", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
payload.Set(reflect.ValueOf(ioutil.NopCloser(bytes.NewReader(b))))
|
||||||
default:
|
default:
|
||||||
|
io.Copy(ioutil.Discard, r.HTTPResponse.Body)
|
||||||
|
defer r.HTTPResponse.Body.Close()
|
||||||
r.Error = awserr.New("SerializationError",
|
r.Error = awserr.New("SerializationError",
|
||||||
"failed to decode REST response",
|
"failed to decode REST response",
|
||||||
fmt.Errorf("unknown payload type %s", payload.Type()))
|
fmt.Errorf("unknown payload type %s", payload.Type()))
|
||||||
@ -100,7 +113,7 @@ func unmarshalLocationElements(r *request.Request, v reflect.Value) {
|
|||||||
case "statusCode":
|
case "statusCode":
|
||||||
unmarshalStatusCode(m, r.HTTPResponse.StatusCode)
|
unmarshalStatusCode(m, r.HTTPResponse.StatusCode)
|
||||||
case "header":
|
case "header":
|
||||||
err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name))
|
err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name), field.Tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
|
r.Error = awserr.New("SerializationError", "failed to decode REST response", err)
|
||||||
break
|
break
|
||||||
@ -147,8 +160,13 @@ func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalHeader(v reflect.Value, header string) error {
|
func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) error {
|
||||||
if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) {
|
isJSONValue := tag.Get("type") == "jsonvalue"
|
||||||
|
if isJSONValue {
|
||||||
|
if len(header) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
} else if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,6 +203,22 @@ func unmarshalHeader(v reflect.Value, header string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.Set(reflect.ValueOf(&t))
|
v.Set(reflect.ValueOf(&t))
|
||||||
|
case aws.JSONValue:
|
||||||
|
b := []byte(header)
|
||||||
|
var err error
|
||||||
|
if tag.Get("location") == "header" {
|
||||||
|
b, err = base64.StdEncoding.DecodeString(header)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m := aws.JSONValue{}
|
||||||
|
err = json.Unmarshal(b, &m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v.Set(reflect.ValueOf(m))
|
||||||
default:
|
default:
|
||||||
err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
|
err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type())
|
||||||
return err
|
return err
|
||||||
|
6
vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go
generated
vendored
6
vendor/github.com/aws/aws-sdk-go/private/protocol/restxml/restxml.go
generated
vendored
@ -1,9 +1,9 @@
|
|||||||
// Package restxml provides RESTful XML serialisation of AWS
|
// Package restxml provides RESTful XML serialization of AWS
|
||||||
// requests and responses.
|
// requests and responses.
|
||||||
package restxml
|
package restxml
|
||||||
|
|
||||||
//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/rest-xml.json build_test.go
|
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/rest-xml.json build_test.go
|
||||||
//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/rest-xml.json unmarshal_test.go
|
//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/rest-xml.json unmarshal_test.go
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
5
vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go
generated
vendored
5
vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// Package xmlutil provides XML serialisation of AWS requests and responses.
|
// Package xmlutil provides XML serialization of AWS requests and responses.
|
||||||
package xmlutil
|
package xmlutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -127,6 +127,9 @@ func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag refl
|
|||||||
if field.PkgPath != "" {
|
if field.PkgPath != "" {
|
||||||
continue // ignore unexported fields
|
continue // ignore unexported fields
|
||||||
}
|
}
|
||||||
|
if field.Tag.Get("ignore") != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
mTag := field.Tag
|
mTag := field.Tag
|
||||||
if mTag.Get("location") != "" { // skip non-body members
|
if mTag.Get("location") != "" { // skip non-body members
|
||||||
|
14
vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go
generated
vendored
14
vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go
generated
vendored
@ -15,7 +15,10 @@ import (
|
|||||||
// needs to match the shape of the XML expected to be decoded.
|
// needs to match the shape of the XML expected to be decoded.
|
||||||
// If the shape doesn't match unmarshaling will fail.
|
// If the shape doesn't match unmarshaling will fail.
|
||||||
func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error {
|
func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error {
|
||||||
n, _ := XMLToStruct(d, nil)
|
n, err := XMLToStruct(d, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if n.Children != nil {
|
if n.Children != nil {
|
||||||
for _, root := range n.Children {
|
for _, root := range n.Children {
|
||||||
for _, c := range root {
|
for _, c := range root {
|
||||||
@ -23,7 +26,7 @@ func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error {
|
|||||||
c = wrappedChild[0] // pull out wrapped element
|
c = wrappedChild[0] // pull out wrapped element
|
||||||
}
|
}
|
||||||
|
|
||||||
err := parse(reflect.ValueOf(v), c, "")
|
err = parse(reflect.ValueOf(v), c, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return nil
|
return nil
|
||||||
@ -111,11 +114,8 @@ func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
|||||||
elems := node.Children[name]
|
elems := node.Children[name]
|
||||||
|
|
||||||
if elems == nil { // try to find the field in attributes
|
if elems == nil { // try to find the field in attributes
|
||||||
for _, a := range node.Attr {
|
if val, ok := node.findElem(name); ok {
|
||||||
if name == a.Name.Local {
|
elems = []*XMLNode{{Text: val}}
|
||||||
// turn this into a text node for de-serializing
|
|
||||||
elems = []*XMLNode{{Text: a.Value}}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
48
vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go
generated
vendored
48
vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go
generated
vendored
@ -2,6 +2,7 @@ package xmlutil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
@ -12,6 +13,9 @@ type XMLNode struct {
|
|||||||
Children map[string][]*XMLNode `json:",omitempty"`
|
Children map[string][]*XMLNode `json:",omitempty"`
|
||||||
Text string `json:",omitempty"`
|
Text string `json:",omitempty"`
|
||||||
Attr []xml.Attr `json:",omitempty"`
|
Attr []xml.Attr `json:",omitempty"`
|
||||||
|
|
||||||
|
namespaces map[string]string
|
||||||
|
parent *XMLNode
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewXMLElement returns a pointer to a new XMLNode initialized to default values.
|
// NewXMLElement returns a pointer to a new XMLNode initialized to default values.
|
||||||
@ -36,12 +40,17 @@ func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) {
|
|||||||
out := &XMLNode{}
|
out := &XMLNode{}
|
||||||
for {
|
for {
|
||||||
tok, err := d.Token()
|
tok, err := d.Token()
|
||||||
if tok == nil || err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tok == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
switch typed := tok.(type) {
|
switch typed := tok.(type) {
|
||||||
case xml.CharData:
|
case xml.CharData:
|
||||||
@ -59,21 +68,54 @@ func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) {
|
|||||||
slice = []*XMLNode{}
|
slice = []*XMLNode{}
|
||||||
}
|
}
|
||||||
node, e := XMLToStruct(d, &el)
|
node, e := XMLToStruct(d, &el)
|
||||||
|
out.findNamespaces()
|
||||||
if e != nil {
|
if e != nil {
|
||||||
return out, e
|
return out, e
|
||||||
}
|
}
|
||||||
node.Name = typed.Name
|
node.Name = typed.Name
|
||||||
|
node.findNamespaces()
|
||||||
|
tempOut := *out
|
||||||
|
// Save into a temp variable, simply because out gets squashed during
|
||||||
|
// loop iterations
|
||||||
|
node.parent = &tempOut
|
||||||
slice = append(slice, node)
|
slice = append(slice, node)
|
||||||
out.Children[name] = slice
|
out.Children[name] = slice
|
||||||
case xml.EndElement:
|
case xml.EndElement:
|
||||||
if s != nil && s.Name.Local == typed.Name.Local { // matching end token
|
if s != nil && s.Name.Local == typed.Name.Local { // matching end token
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
out = &XMLNode{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *XMLNode) findNamespaces() {
|
||||||
|
ns := map[string]string{}
|
||||||
|
for _, a := range n.Attr {
|
||||||
|
if a.Name.Space == "xmlns" {
|
||||||
|
ns[a.Value] = a.Name.Local
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n.namespaces = ns
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *XMLNode) findElem(name string) (string, bool) {
|
||||||
|
for node := n; node != nil; node = node.parent {
|
||||||
|
for _, a := range node.Attr {
|
||||||
|
namespace := a.Name.Space
|
||||||
|
if v, ok := node.namespaces[namespace]; ok {
|
||||||
|
namespace = v
|
||||||
|
}
|
||||||
|
if name == fmt.Sprintf("%s:%s", namespace, a.Name.Local) {
|
||||||
|
return a.Value, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
// StructToXML writes an XMLNode to a xml.Encoder as tokens.
|
// StructToXML writes an XMLNode to a xml.Encoder as tokens.
|
||||||
func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
|
func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
|
||||||
e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr})
|
e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr})
|
||||||
|
438
vendor/github.com/aws/aws-sdk-go/private/signer/v4/v4.go
generated
vendored
438
vendor/github.com/aws/aws-sdk-go/private/signer/v4/v4.go
generated
vendored
@ -1,438 +0,0 @@
|
|||||||
// Package v4 implements signing for AWS V4 signer
|
|
||||||
package v4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/hmac"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"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/private/protocol/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
authHeaderPrefix = "AWS4-HMAC-SHA256"
|
|
||||||
timeFormat = "20060102T150405Z"
|
|
||||||
shortTimeFormat = "20060102"
|
|
||||||
)
|
|
||||||
|
|
||||||
var ignoredHeaders = rules{
|
|
||||||
blacklist{
|
|
||||||
mapRule{
|
|
||||||
"Content-Length": struct{}{},
|
|
||||||
"User-Agent": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// requiredSignedHeaders is a whitelist for build canonical headers.
|
|
||||||
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{}{},
|
|
||||||
"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{}{},
|
|
||||||
"X-Amz-Grant-Full-control": struct{}{},
|
|
||||||
"X-Amz-Grant-Read": struct{}{},
|
|
||||||
"X-Amz-Grant-Read-Acp": struct{}{},
|
|
||||||
"X-Amz-Grant-Write": struct{}{},
|
|
||||||
"X-Amz-Grant-Write-Acp": struct{}{},
|
|
||||||
"X-Amz-Metadata-Directive": struct{}{},
|
|
||||||
"X-Amz-Mfa": struct{}{},
|
|
||||||
"X-Amz-Request-Payer": struct{}{},
|
|
||||||
"X-Amz-Server-Side-Encryption": struct{}{},
|
|
||||||
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{},
|
|
||||||
"X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
|
||||||
"X-Amz-Server-Side-Encryption-Customer-Key": struct{}{},
|
|
||||||
"X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
|
||||||
"X-Amz-Storage-Class": struct{}{},
|
|
||||||
"X-Amz-Website-Redirect-Location": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
patterns{"X-Amz-Meta-"},
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowedHoisting is a whitelist for build query headers. The boolean value
|
|
||||||
// represents whether or not it is a pattern.
|
|
||||||
var allowedQueryHoisting = inclusiveRules{
|
|
||||||
blacklist{requiredSignedHeaders},
|
|
||||||
patterns{"X-Amz-"},
|
|
||||||
}
|
|
||||||
|
|
||||||
type signer struct {
|
|
||||||
Request *http.Request
|
|
||||||
Time time.Time
|
|
||||||
ExpireTime time.Duration
|
|
||||||
ServiceName string
|
|
||||||
Region string
|
|
||||||
CredValues credentials.Value
|
|
||||||
Credentials *credentials.Credentials
|
|
||||||
Query url.Values
|
|
||||||
Body io.ReadSeeker
|
|
||||||
Debug aws.LogLevelType
|
|
||||||
Logger aws.Logger
|
|
||||||
|
|
||||||
isPresign bool
|
|
||||||
formattedTime string
|
|
||||||
formattedShortTime string
|
|
||||||
|
|
||||||
signedHeaders string
|
|
||||||
canonicalHeaders string
|
|
||||||
canonicalString string
|
|
||||||
credentialString string
|
|
||||||
stringToSign string
|
|
||||||
signature string
|
|
||||||
authorization string
|
|
||||||
notHoist bool
|
|
||||||
signedHeaderVals http.Header
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign requests with signature version 4.
|
|
||||||
//
|
|
||||||
// Will sign the requests with the service config's Credentials object
|
|
||||||
// Signing is skipped if the credentials is the credentials.AnonymousCredentials
|
|
||||||
// object.
|
|
||||||
func Sign(req *request.Request) {
|
|
||||||
// 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 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
region := req.ClientInfo.SigningRegion
|
|
||||||
if region == "" {
|
|
||||||
region = aws.StringValue(req.Config.Region)
|
|
||||||
}
|
|
||||||
|
|
||||||
name := req.ClientInfo.SigningName
|
|
||||||
if name == "" {
|
|
||||||
name = req.ClientInfo.ServiceName
|
|
||||||
}
|
|
||||||
|
|
||||||
s := signer{
|
|
||||||
Request: req.HTTPRequest,
|
|
||||||
Time: req.Time,
|
|
||||||
ExpireTime: req.ExpireTime,
|
|
||||||
Query: req.HTTPRequest.URL.Query(),
|
|
||||||
Body: req.Body,
|
|
||||||
ServiceName: name,
|
|
||||||
Region: region,
|
|
||||||
Credentials: req.Config.Credentials,
|
|
||||||
Debug: req.Config.LogLevel.Value(),
|
|
||||||
Logger: req.Config.Logger,
|
|
||||||
notHoist: req.NotHoist,
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Error = s.sign()
|
|
||||||
req.SignedHeaderVals = s.signedHeaderVals
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v4 *signer) sign() error {
|
|
||||||
if v4.ExpireTime != 0 {
|
|
||||||
v4.isPresign = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if v4.isRequestSigned() {
|
|
||||||
if !v4.Credentials.IsExpired() {
|
|
||||||
// If the request is already signed, and the credentials have not
|
|
||||||
// expired yet ignore the signing request.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// The credentials have expired for this request. The current signing
|
|
||||||
// is invalid, and needs to be request because the request will fail.
|
|
||||||
if v4.isPresign {
|
|
||||||
v4.removePresign()
|
|
||||||
// Update the request's query string to ensure the values stays in
|
|
||||||
// sync in the case retrieving the new credentials fails.
|
|
||||||
v4.Request.URL.RawQuery = v4.Query.Encode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
v4.CredValues, err = v4.Credentials.Get()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if v4.isPresign {
|
|
||||||
v4.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
|
|
||||||
if v4.CredValues.SessionToken != "" {
|
|
||||||
v4.Query.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
|
|
||||||
} else {
|
|
||||||
v4.Query.Del("X-Amz-Security-Token")
|
|
||||||
}
|
|
||||||
} else if v4.CredValues.SessionToken != "" {
|
|
||||||
v4.Request.Header.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
|
|
||||||
}
|
|
||||||
|
|
||||||
v4.build()
|
|
||||||
|
|
||||||
if v4.Debug.Matches(aws.LogDebugWithSigning) {
|
|
||||||
v4.logSigningInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const logSignInfoMsg = `DEBUG: Request Signiture:
|
|
||||||
---[ CANONICAL STRING ]-----------------------------
|
|
||||||
%s
|
|
||||||
---[ STRING TO SIGN ]--------------------------------
|
|
||||||
%s%s
|
|
||||||
-----------------------------------------------------`
|
|
||||||
const logSignedURLMsg = `
|
|
||||||
---[ SIGNED URL ]------------------------------------
|
|
||||||
%s`
|
|
||||||
|
|
||||||
func (v4 *signer) logSigningInfo() {
|
|
||||||
signedURLMsg := ""
|
|
||||||
if v4.isPresign {
|
|
||||||
signedURLMsg = fmt.Sprintf(logSignedURLMsg, v4.Request.URL.String())
|
|
||||||
}
|
|
||||||
msg := fmt.Sprintf(logSignInfoMsg, v4.canonicalString, v4.stringToSign, signedURLMsg)
|
|
||||||
v4.Logger.Log(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v4 *signer) build() {
|
|
||||||
|
|
||||||
v4.buildTime() // no depends
|
|
||||||
v4.buildCredentialString() // no depends
|
|
||||||
|
|
||||||
unsignedHeaders := v4.Request.Header
|
|
||||||
if v4.isPresign {
|
|
||||||
if !v4.notHoist {
|
|
||||||
urlValues := url.Values{}
|
|
||||||
urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends
|
|
||||||
for k := range urlValues {
|
|
||||||
v4.Query[k] = urlValues[k]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v4.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders)
|
|
||||||
v4.buildCanonicalString() // depends on canon headers / signed headers
|
|
||||||
v4.buildStringToSign() // depends on canon string
|
|
||||||
v4.buildSignature() // depends on string to sign
|
|
||||||
|
|
||||||
if v4.isPresign {
|
|
||||||
v4.Request.URL.RawQuery += "&X-Amz-Signature=" + v4.signature
|
|
||||||
} else {
|
|
||||||
parts := []string{
|
|
||||||
authHeaderPrefix + " Credential=" + v4.CredValues.AccessKeyID + "/" + v4.credentialString,
|
|
||||||
"SignedHeaders=" + v4.signedHeaders,
|
|
||||||
"Signature=" + v4.signature,
|
|
||||||
}
|
|
||||||
v4.Request.Header.Set("Authorization", strings.Join(parts, ", "))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v4 *signer) buildTime() {
|
|
||||||
v4.formattedTime = v4.Time.UTC().Format(timeFormat)
|
|
||||||
v4.formattedShortTime = v4.Time.UTC().Format(shortTimeFormat)
|
|
||||||
|
|
||||||
if v4.isPresign {
|
|
||||||
duration := int64(v4.ExpireTime / time.Second)
|
|
||||||
v4.Query.Set("X-Amz-Date", v4.formattedTime)
|
|
||||||
v4.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
|
|
||||||
} else {
|
|
||||||
v4.Request.Header.Set("X-Amz-Date", v4.formattedTime)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v4 *signer) buildCredentialString() {
|
|
||||||
v4.credentialString = strings.Join([]string{
|
|
||||||
v4.formattedShortTime,
|
|
||||||
v4.Region,
|
|
||||||
v4.ServiceName,
|
|
||||||
"aws4_request",
|
|
||||||
}, "/")
|
|
||||||
|
|
||||||
if v4.isPresign {
|
|
||||||
v4.Query.Set("X-Amz-Credential", v4.CredValues.AccessKeyID+"/"+v4.credentialString)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildQuery(r rule, header http.Header) (url.Values, http.Header) {
|
|
||||||
query := url.Values{}
|
|
||||||
unsignedHeaders := http.Header{}
|
|
||||||
for k, h := range header {
|
|
||||||
if r.IsValid(k) {
|
|
||||||
query[k] = h
|
|
||||||
} else {
|
|
||||||
unsignedHeaders[k] = h
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return query, unsignedHeaders
|
|
||||||
}
|
|
||||||
func (v4 *signer) 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) {
|
|
||||||
continue // ignored header
|
|
||||||
}
|
|
||||||
|
|
||||||
lowerCaseKey := strings.ToLower(k)
|
|
||||||
headers = append(headers, lowerCaseKey)
|
|
||||||
|
|
||||||
if v4.signedHeaderVals == nil {
|
|
||||||
v4.signedHeaderVals = make(http.Header)
|
|
||||||
}
|
|
||||||
v4.signedHeaderVals[lowerCaseKey] = v
|
|
||||||
}
|
|
||||||
sort.Strings(headers)
|
|
||||||
|
|
||||||
v4.signedHeaders = strings.Join(headers, ";")
|
|
||||||
|
|
||||||
if v4.isPresign {
|
|
||||||
v4.Query.Set("X-Amz-SignedHeaders", v4.signedHeaders)
|
|
||||||
}
|
|
||||||
|
|
||||||
headerValues := make([]string, len(headers))
|
|
||||||
for i, k := range headers {
|
|
||||||
if k == "host" {
|
|
||||||
headerValues[i] = "host:" + v4.Request.URL.Host
|
|
||||||
} else {
|
|
||||||
headerValues[i] = k + ":" +
|
|
||||||
strings.Join(v4.Request.Header[http.CanonicalHeaderKey(k)], ",")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v4.canonicalHeaders = strings.Join(headerValues, "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v4 *signer) buildCanonicalString() {
|
|
||||||
v4.Request.URL.RawQuery = strings.Replace(v4.Query.Encode(), "+", "%20", -1)
|
|
||||||
uri := v4.Request.URL.Opaque
|
|
||||||
if uri != "" {
|
|
||||||
uri = "/" + strings.Join(strings.Split(uri, "/")[3:], "/")
|
|
||||||
} else {
|
|
||||||
uri = v4.Request.URL.Path
|
|
||||||
}
|
|
||||||
if uri == "" {
|
|
||||||
uri = "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
if v4.ServiceName != "s3" {
|
|
||||||
uri = rest.EscapePath(uri, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
v4.canonicalString = strings.Join([]string{
|
|
||||||
v4.Request.Method,
|
|
||||||
uri,
|
|
||||||
v4.Request.URL.RawQuery,
|
|
||||||
v4.canonicalHeaders + "\n",
|
|
||||||
v4.signedHeaders,
|
|
||||||
v4.bodyDigest(),
|
|
||||||
}, "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v4 *signer) buildStringToSign() {
|
|
||||||
v4.stringToSign = strings.Join([]string{
|
|
||||||
authHeaderPrefix,
|
|
||||||
v4.formattedTime,
|
|
||||||
v4.credentialString,
|
|
||||||
hex.EncodeToString(makeSha256([]byte(v4.canonicalString))),
|
|
||||||
}, "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v4 *signer) buildSignature() {
|
|
||||||
secret := v4.CredValues.SecretAccessKey
|
|
||||||
date := makeHmac([]byte("AWS4"+secret), []byte(v4.formattedShortTime))
|
|
||||||
region := makeHmac(date, []byte(v4.Region))
|
|
||||||
service := makeHmac(region, []byte(v4.ServiceName))
|
|
||||||
credentials := makeHmac(service, []byte("aws4_request"))
|
|
||||||
signature := makeHmac(credentials, []byte(v4.stringToSign))
|
|
||||||
v4.signature = hex.EncodeToString(signature)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v4 *signer) bodyDigest() string {
|
|
||||||
hash := v4.Request.Header.Get("X-Amz-Content-Sha256")
|
|
||||||
if hash == "" {
|
|
||||||
if v4.isPresign && v4.ServiceName == "s3" {
|
|
||||||
hash = "UNSIGNED-PAYLOAD"
|
|
||||||
} else if v4.Body == nil {
|
|
||||||
hash = hex.EncodeToString(makeSha256([]byte{}))
|
|
||||||
} else {
|
|
||||||
hash = hex.EncodeToString(makeSha256Reader(v4.Body))
|
|
||||||
}
|
|
||||||
v4.Request.Header.Add("X-Amz-Content-Sha256", hash)
|
|
||||||
}
|
|
||||||
return hash
|
|
||||||
}
|
|
||||||
|
|
||||||
// isRequestSigned returns if the request is currently signed or presigned
|
|
||||||
func (v4 *signer) isRequestSigned() bool {
|
|
||||||
if v4.isPresign && v4.Query.Get("X-Amz-Signature") != "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if v4.Request.Header.Get("Authorization") != "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// unsign removes signing flags for both signed and presigned requests.
|
|
||||||
func (v4 *signer) removePresign() {
|
|
||||||
v4.Query.Del("X-Amz-Algorithm")
|
|
||||||
v4.Query.Del("X-Amz-Signature")
|
|
||||||
v4.Query.Del("X-Amz-Security-Token")
|
|
||||||
v4.Query.Del("X-Amz-Date")
|
|
||||||
v4.Query.Del("X-Amz-Expires")
|
|
||||||
v4.Query.Del("X-Amz-Credential")
|
|
||||||
v4.Query.Del("X-Amz-SignedHeaders")
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeHmac(key []byte, data []byte) []byte {
|
|
||||||
hash := hmac.New(sha256.New, key)
|
|
||||||
hash.Write(data)
|
|
||||||
return hash.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeSha256(data []byte) []byte {
|
|
||||||
hash := sha256.New()
|
|
||||||
hash.Write(data)
|
|
||||||
return hash.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeSha256Reader(reader io.ReadSeeker) []byte {
|
|
||||||
hash := sha256.New()
|
|
||||||
start, _ := reader.Seek(0, 1)
|
|
||||||
defer reader.Seek(start, 0)
|
|
||||||
|
|
||||||
io.Copy(hash, reader)
|
|
||||||
return hash.Sum(nil)
|
|
||||||
}
|
|
134
vendor/github.com/aws/aws-sdk-go/private/waiter/waiter.go
generated
vendored
134
vendor/github.com/aws/aws-sdk-go/private/waiter/waiter.go
generated
vendored
@ -1,134 +0,0 @@
|
|||||||
package waiter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Config provides a collection of configuration values to setup a generated
|
|
||||||
// waiter code with.
|
|
||||||
type Config struct {
|
|
||||||
Name string
|
|
||||||
Delay int
|
|
||||||
MaxAttempts int
|
|
||||||
Operation string
|
|
||||||
Acceptors []WaitAcceptor
|
|
||||||
}
|
|
||||||
|
|
||||||
// A WaitAcceptor provides the information needed to wait for an API operation
|
|
||||||
// to complete.
|
|
||||||
type WaitAcceptor struct {
|
|
||||||
Expected interface{}
|
|
||||||
Matcher string
|
|
||||||
State string
|
|
||||||
Argument string
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Waiter provides waiting for an operation to complete.
|
|
||||||
type Waiter struct {
|
|
||||||
Config
|
|
||||||
Client interface{}
|
|
||||||
Input interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait waits for an operation to complete, expire max attempts, or fail. Error
|
|
||||||
// is returned if the operation fails.
|
|
||||||
func (w *Waiter) Wait() error {
|
|
||||||
client := reflect.ValueOf(w.Client)
|
|
||||||
in := reflect.ValueOf(w.Input)
|
|
||||||
method := client.MethodByName(w.Config.Operation + "Request")
|
|
||||||
|
|
||||||
for i := 0; i < w.MaxAttempts; i++ {
|
|
||||||
res := method.Call([]reflect.Value{in})
|
|
||||||
req := res[0].Interface().(*request.Request)
|
|
||||||
req.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Waiter"))
|
|
||||||
|
|
||||||
err := req.Send()
|
|
||||||
for _, a := range w.Acceptors {
|
|
||||||
result := false
|
|
||||||
var vals []interface{}
|
|
||||||
switch a.Matcher {
|
|
||||||
case "pathAll", "path":
|
|
||||||
// Require all matches to be equal for result to match
|
|
||||||
vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument)
|
|
||||||
if len(vals) == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
result = true
|
|
||||||
for _, val := range vals {
|
|
||||||
if !awsutil.DeepEqual(val, a.Expected) {
|
|
||||||
result = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "pathAny":
|
|
||||||
// Only a single match needs to equal for the result to match
|
|
||||||
vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument)
|
|
||||||
for _, val := range vals {
|
|
||||||
if awsutil.DeepEqual(val, a.Expected) {
|
|
||||||
result = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "status":
|
|
||||||
s := a.Expected.(int)
|
|
||||||
result = s == req.HTTPResponse.StatusCode
|
|
||||||
case "error":
|
|
||||||
if aerr, ok := err.(awserr.Error); ok {
|
|
||||||
result = aerr.Code() == a.Expected.(string)
|
|
||||||
}
|
|
||||||
case "pathList":
|
|
||||||
// ignored matcher
|
|
||||||
default:
|
|
||||||
logf(client, "WARNING: Waiter for %s encountered unexpected matcher: %s",
|
|
||||||
w.Config.Operation, a.Matcher)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !result {
|
|
||||||
// If there was no matching result found there is nothing more to do
|
|
||||||
// for this response, retry the request.
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
switch a.State {
|
|
||||||
case "success":
|
|
||||||
// waiter completed
|
|
||||||
return nil
|
|
||||||
case "failure":
|
|
||||||
// Waiter failure state triggered
|
|
||||||
return awserr.New("ResourceNotReady",
|
|
||||||
fmt.Sprintf("failed waiting for successful resource state"), err)
|
|
||||||
case "retry":
|
|
||||||
// clear the error and retry the operation
|
|
||||||
err = nil
|
|
||||||
default:
|
|
||||||
logf(client, "WARNING: Waiter for %s encountered unexpected state: %s",
|
|
||||||
w.Config.Operation, a.State)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
time.Sleep(time.Second * time.Duration(w.Delay))
|
|
||||||
}
|
|
||||||
|
|
||||||
return awserr.New("ResourceNotReady",
|
|
||||||
fmt.Sprintf("exceeded %d wait attempts", w.MaxAttempts), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func logf(client reflect.Value, msg string, args ...interface{}) {
|
|
||||||
cfgVal := client.FieldByName("Config")
|
|
||||||
if !cfgVal.IsValid() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if cfg, ok := cfgVal.Interface().(*aws.Config); ok && cfg.Logger != nil {
|
|
||||||
cfg.Logger.Log(fmt.Sprintf(msg, args...))
|
|
||||||
}
|
|
||||||
}
|
|
8463
vendor/github.com/aws/aws-sdk-go/service/cloudfront/api.go
generated
vendored
8463
vendor/github.com/aws/aws-sdk-go/service/cloudfront/api.go
generated
vendored
File diff suppressed because it is too large
Load Diff
31
vendor/github.com/aws/aws-sdk-go/service/cloudfront/doc.go
generated
vendored
Normal file
31
vendor/github.com/aws/aws-sdk-go/service/cloudfront/doc.go
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Package cloudfront provides the client and types for making API
|
||||||
|
// requests to Amazon CloudFront.
|
||||||
|
//
|
||||||
|
// This is the Amazon CloudFront API Reference. This guide is for developers
|
||||||
|
// who need detailed information about the CloudFront API actions, data types,
|
||||||
|
// and errors. For detailed information about CloudFront features and their
|
||||||
|
// associated API calls, see the Amazon CloudFront Developer Guide.
|
||||||
|
//
|
||||||
|
// See https://docs.aws.amazon.com/goto/WebAPI/cloudfront-2017-03-25 for more information on this service.
|
||||||
|
//
|
||||||
|
// See cloudfront package documentation for more information.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/service/cloudfront/
|
||||||
|
//
|
||||||
|
// Using the Client
|
||||||
|
//
|
||||||
|
// To Amazon CloudFront with the SDK use the New function to create
|
||||||
|
// a new service client. With that client you can make API requests to the service.
|
||||||
|
// These clients are safe to use concurrently.
|
||||||
|
//
|
||||||
|
// See the SDK's documentation for more information on how to use the SDK.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||||
|
//
|
||||||
|
// See aws.Config documentation for more information on configuring SDK clients.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||||
|
//
|
||||||
|
// See the Amazon CloudFront client CloudFront for more
|
||||||
|
// information on creating client for this service.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/service/cloudfront/#New
|
||||||
|
package cloudfront
|
333
vendor/github.com/aws/aws-sdk-go/service/cloudfront/errors.go
generated
vendored
Normal file
333
vendor/github.com/aws/aws-sdk-go/service/cloudfront/errors.go
generated
vendored
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
package cloudfront
|
||||||
|
|
||||||
|
const (
|
||||||
|
|
||||||
|
// ErrCodeAccessDenied for service response error code
|
||||||
|
// "AccessDenied".
|
||||||
|
//
|
||||||
|
// Access denied.
|
||||||
|
ErrCodeAccessDenied = "AccessDenied"
|
||||||
|
|
||||||
|
// ErrCodeBatchTooLarge for service response error code
|
||||||
|
// "BatchTooLarge".
|
||||||
|
ErrCodeBatchTooLarge = "BatchTooLarge"
|
||||||
|
|
||||||
|
// ErrCodeCNAMEAlreadyExists for service response error code
|
||||||
|
// "CNAMEAlreadyExists".
|
||||||
|
ErrCodeCNAMEAlreadyExists = "CNAMEAlreadyExists"
|
||||||
|
|
||||||
|
// ErrCodeDistributionAlreadyExists for service response error code
|
||||||
|
// "DistributionAlreadyExists".
|
||||||
|
//
|
||||||
|
// The caller reference you attempted to create the distribution with is associated
|
||||||
|
// with another distribution.
|
||||||
|
ErrCodeDistributionAlreadyExists = "DistributionAlreadyExists"
|
||||||
|
|
||||||
|
// ErrCodeDistributionNotDisabled for service response error code
|
||||||
|
// "DistributionNotDisabled".
|
||||||
|
ErrCodeDistributionNotDisabled = "DistributionNotDisabled"
|
||||||
|
|
||||||
|
// ErrCodeIllegalUpdate for service response error code
|
||||||
|
// "IllegalUpdate".
|
||||||
|
//
|
||||||
|
// Origin and CallerReference cannot be updated.
|
||||||
|
ErrCodeIllegalUpdate = "IllegalUpdate"
|
||||||
|
|
||||||
|
// ErrCodeInconsistentQuantities for service response error code
|
||||||
|
// "InconsistentQuantities".
|
||||||
|
//
|
||||||
|
// The value of Quantity and the size of Items do not match.
|
||||||
|
ErrCodeInconsistentQuantities = "InconsistentQuantities"
|
||||||
|
|
||||||
|
// ErrCodeInvalidArgument for service response error code
|
||||||
|
// "InvalidArgument".
|
||||||
|
//
|
||||||
|
// The argument is invalid.
|
||||||
|
ErrCodeInvalidArgument = "InvalidArgument"
|
||||||
|
|
||||||
|
// ErrCodeInvalidDefaultRootObject for service response error code
|
||||||
|
// "InvalidDefaultRootObject".
|
||||||
|
//
|
||||||
|
// The default root object file name is too big or contains an invalid character.
|
||||||
|
ErrCodeInvalidDefaultRootObject = "InvalidDefaultRootObject"
|
||||||
|
|
||||||
|
// ErrCodeInvalidErrorCode for service response error code
|
||||||
|
// "InvalidErrorCode".
|
||||||
|
ErrCodeInvalidErrorCode = "InvalidErrorCode"
|
||||||
|
|
||||||
|
// ErrCodeInvalidForwardCookies for service response error code
|
||||||
|
// "InvalidForwardCookies".
|
||||||
|
//
|
||||||
|
// Your request contains forward cookies option which doesn't match with the
|
||||||
|
// expectation for the whitelisted list of cookie names. Either list of cookie
|
||||||
|
// names has been specified when not allowed or list of cookie names is missing
|
||||||
|
// when expected.
|
||||||
|
ErrCodeInvalidForwardCookies = "InvalidForwardCookies"
|
||||||
|
|
||||||
|
// ErrCodeInvalidGeoRestrictionParameter for service response error code
|
||||||
|
// "InvalidGeoRestrictionParameter".
|
||||||
|
ErrCodeInvalidGeoRestrictionParameter = "InvalidGeoRestrictionParameter"
|
||||||
|
|
||||||
|
// ErrCodeInvalidHeadersForS3Origin for service response error code
|
||||||
|
// "InvalidHeadersForS3Origin".
|
||||||
|
ErrCodeInvalidHeadersForS3Origin = "InvalidHeadersForS3Origin"
|
||||||
|
|
||||||
|
// ErrCodeInvalidIfMatchVersion for service response error code
|
||||||
|
// "InvalidIfMatchVersion".
|
||||||
|
//
|
||||||
|
// The If-Match version is missing or not valid for the distribution.
|
||||||
|
ErrCodeInvalidIfMatchVersion = "InvalidIfMatchVersion"
|
||||||
|
|
||||||
|
// ErrCodeInvalidLambdaFunctionAssociation for service response error code
|
||||||
|
// "InvalidLambdaFunctionAssociation".
|
||||||
|
//
|
||||||
|
// The specified Lambda function association is invalid.
|
||||||
|
ErrCodeInvalidLambdaFunctionAssociation = "InvalidLambdaFunctionAssociation"
|
||||||
|
|
||||||
|
// ErrCodeInvalidLocationCode for service response error code
|
||||||
|
// "InvalidLocationCode".
|
||||||
|
ErrCodeInvalidLocationCode = "InvalidLocationCode"
|
||||||
|
|
||||||
|
// ErrCodeInvalidMinimumProtocolVersion for service response error code
|
||||||
|
// "InvalidMinimumProtocolVersion".
|
||||||
|
ErrCodeInvalidMinimumProtocolVersion = "InvalidMinimumProtocolVersion"
|
||||||
|
|
||||||
|
// ErrCodeInvalidOrigin for service response error code
|
||||||
|
// "InvalidOrigin".
|
||||||
|
//
|
||||||
|
// The Amazon S3 origin server specified does not refer to a valid Amazon S3
|
||||||
|
// bucket.
|
||||||
|
ErrCodeInvalidOrigin = "InvalidOrigin"
|
||||||
|
|
||||||
|
// ErrCodeInvalidOriginAccessIdentity for service response error code
|
||||||
|
// "InvalidOriginAccessIdentity".
|
||||||
|
//
|
||||||
|
// The origin access identity is not valid or doesn't exist.
|
||||||
|
ErrCodeInvalidOriginAccessIdentity = "InvalidOriginAccessIdentity"
|
||||||
|
|
||||||
|
// ErrCodeInvalidOriginKeepaliveTimeout for service response error code
|
||||||
|
// "InvalidOriginKeepaliveTimeout".
|
||||||
|
ErrCodeInvalidOriginKeepaliveTimeout = "InvalidOriginKeepaliveTimeout"
|
||||||
|
|
||||||
|
// ErrCodeInvalidOriginReadTimeout for service response error code
|
||||||
|
// "InvalidOriginReadTimeout".
|
||||||
|
ErrCodeInvalidOriginReadTimeout = "InvalidOriginReadTimeout"
|
||||||
|
|
||||||
|
// ErrCodeInvalidProtocolSettings for service response error code
|
||||||
|
// "InvalidProtocolSettings".
|
||||||
|
//
|
||||||
|
// You cannot specify SSLv3 as the minimum protocol version if you only want
|
||||||
|
// to support only clients that support Server Name Indication (SNI).
|
||||||
|
ErrCodeInvalidProtocolSettings = "InvalidProtocolSettings"
|
||||||
|
|
||||||
|
// ErrCodeInvalidQueryStringParameters for service response error code
|
||||||
|
// "InvalidQueryStringParameters".
|
||||||
|
ErrCodeInvalidQueryStringParameters = "InvalidQueryStringParameters"
|
||||||
|
|
||||||
|
// ErrCodeInvalidRelativePath for service response error code
|
||||||
|
// "InvalidRelativePath".
|
||||||
|
//
|
||||||
|
// The relative path is too big, is not URL-encoded, or does not begin with
|
||||||
|
// a slash (/).
|
||||||
|
ErrCodeInvalidRelativePath = "InvalidRelativePath"
|
||||||
|
|
||||||
|
// ErrCodeInvalidRequiredProtocol for service response error code
|
||||||
|
// "InvalidRequiredProtocol".
|
||||||
|
//
|
||||||
|
// This operation requires the HTTPS protocol. Ensure that you specify the HTTPS
|
||||||
|
// protocol in your request, or omit the RequiredProtocols element from your
|
||||||
|
// distribution configuration.
|
||||||
|
ErrCodeInvalidRequiredProtocol = "InvalidRequiredProtocol"
|
||||||
|
|
||||||
|
// ErrCodeInvalidResponseCode for service response error code
|
||||||
|
// "InvalidResponseCode".
|
||||||
|
ErrCodeInvalidResponseCode = "InvalidResponseCode"
|
||||||
|
|
||||||
|
// ErrCodeInvalidTTLOrder for service response error code
|
||||||
|
// "InvalidTTLOrder".
|
||||||
|
ErrCodeInvalidTTLOrder = "InvalidTTLOrder"
|
||||||
|
|
||||||
|
// ErrCodeInvalidTagging for service response error code
|
||||||
|
// "InvalidTagging".
|
||||||
|
ErrCodeInvalidTagging = "InvalidTagging"
|
||||||
|
|
||||||
|
// ErrCodeInvalidViewerCertificate for service response error code
|
||||||
|
// "InvalidViewerCertificate".
|
||||||
|
ErrCodeInvalidViewerCertificate = "InvalidViewerCertificate"
|
||||||
|
|
||||||
|
// ErrCodeInvalidWebACLId for service response error code
|
||||||
|
// "InvalidWebACLId".
|
||||||
|
ErrCodeInvalidWebACLId = "InvalidWebACLId"
|
||||||
|
|
||||||
|
// ErrCodeMissingBody for service response error code
|
||||||
|
// "MissingBody".
|
||||||
|
//
|
||||||
|
// This operation requires a body. Ensure that the body is present and the Content-Type
|
||||||
|
// header is set.
|
||||||
|
ErrCodeMissingBody = "MissingBody"
|
||||||
|
|
||||||
|
// ErrCodeNoSuchCloudFrontOriginAccessIdentity for service response error code
|
||||||
|
// "NoSuchCloudFrontOriginAccessIdentity".
|
||||||
|
//
|
||||||
|
// The specified origin access identity does not exist.
|
||||||
|
ErrCodeNoSuchCloudFrontOriginAccessIdentity = "NoSuchCloudFrontOriginAccessIdentity"
|
||||||
|
|
||||||
|
// ErrCodeNoSuchDistribution for service response error code
|
||||||
|
// "NoSuchDistribution".
|
||||||
|
//
|
||||||
|
// The specified distribution does not exist.
|
||||||
|
ErrCodeNoSuchDistribution = "NoSuchDistribution"
|
||||||
|
|
||||||
|
// ErrCodeNoSuchInvalidation for service response error code
|
||||||
|
// "NoSuchInvalidation".
|
||||||
|
//
|
||||||
|
// The specified invalidation does not exist.
|
||||||
|
ErrCodeNoSuchInvalidation = "NoSuchInvalidation"
|
||||||
|
|
||||||
|
// ErrCodeNoSuchOrigin for service response error code
|
||||||
|
// "NoSuchOrigin".
|
||||||
|
//
|
||||||
|
// No origin exists with the specified Origin Id.
|
||||||
|
ErrCodeNoSuchOrigin = "NoSuchOrigin"
|
||||||
|
|
||||||
|
// ErrCodeNoSuchResource for service response error code
|
||||||
|
// "NoSuchResource".
|
||||||
|
ErrCodeNoSuchResource = "NoSuchResource"
|
||||||
|
|
||||||
|
// ErrCodeNoSuchStreamingDistribution for service response error code
|
||||||
|
// "NoSuchStreamingDistribution".
|
||||||
|
//
|
||||||
|
// The specified streaming distribution does not exist.
|
||||||
|
ErrCodeNoSuchStreamingDistribution = "NoSuchStreamingDistribution"
|
||||||
|
|
||||||
|
// ErrCodeOriginAccessIdentityAlreadyExists for service response error code
|
||||||
|
// "OriginAccessIdentityAlreadyExists".
|
||||||
|
//
|
||||||
|
// If the CallerReference is a value you already sent in a previous request
|
||||||
|
// to create an identity but the content of the CloudFrontOriginAccessIdentityConfig
|
||||||
|
// is different from the original request, CloudFront returns a CloudFrontOriginAccessIdentityAlreadyExists
|
||||||
|
// error.
|
||||||
|
ErrCodeOriginAccessIdentityAlreadyExists = "OriginAccessIdentityAlreadyExists"
|
||||||
|
|
||||||
|
// ErrCodeOriginAccessIdentityInUse for service response error code
|
||||||
|
// "OriginAccessIdentityInUse".
|
||||||
|
ErrCodeOriginAccessIdentityInUse = "OriginAccessIdentityInUse"
|
||||||
|
|
||||||
|
// ErrCodePreconditionFailed for service response error code
|
||||||
|
// "PreconditionFailed".
|
||||||
|
//
|
||||||
|
// The precondition given in one or more of the request-header fields evaluated
|
||||||
|
// to false.
|
||||||
|
ErrCodePreconditionFailed = "PreconditionFailed"
|
||||||
|
|
||||||
|
// ErrCodeStreamingDistributionAlreadyExists for service response error code
|
||||||
|
// "StreamingDistributionAlreadyExists".
|
||||||
|
ErrCodeStreamingDistributionAlreadyExists = "StreamingDistributionAlreadyExists"
|
||||||
|
|
||||||
|
// ErrCodeStreamingDistributionNotDisabled for service response error code
|
||||||
|
// "StreamingDistributionNotDisabled".
|
||||||
|
ErrCodeStreamingDistributionNotDisabled = "StreamingDistributionNotDisabled"
|
||||||
|
|
||||||
|
// ErrCodeTooManyCacheBehaviors for service response error code
|
||||||
|
// "TooManyCacheBehaviors".
|
||||||
|
//
|
||||||
|
// You cannot create more cache behaviors for the distribution.
|
||||||
|
ErrCodeTooManyCacheBehaviors = "TooManyCacheBehaviors"
|
||||||
|
|
||||||
|
// ErrCodeTooManyCertificates for service response error code
|
||||||
|
// "TooManyCertificates".
|
||||||
|
//
|
||||||
|
// You cannot create anymore custom SSL/TLS certificates.
|
||||||
|
ErrCodeTooManyCertificates = "TooManyCertificates"
|
||||||
|
|
||||||
|
// ErrCodeTooManyCloudFrontOriginAccessIdentities for service response error code
|
||||||
|
// "TooManyCloudFrontOriginAccessIdentities".
|
||||||
|
//
|
||||||
|
// Processing your request would cause you to exceed the maximum number of origin
|
||||||
|
// access identities allowed.
|
||||||
|
ErrCodeTooManyCloudFrontOriginAccessIdentities = "TooManyCloudFrontOriginAccessIdentities"
|
||||||
|
|
||||||
|
// ErrCodeTooManyCookieNamesInWhiteList for service response error code
|
||||||
|
// "TooManyCookieNamesInWhiteList".
|
||||||
|
//
|
||||||
|
// Your request contains more cookie names in the whitelist than are allowed
|
||||||
|
// per cache behavior.
|
||||||
|
ErrCodeTooManyCookieNamesInWhiteList = "TooManyCookieNamesInWhiteList"
|
||||||
|
|
||||||
|
// ErrCodeTooManyDistributionCNAMEs for service response error code
|
||||||
|
// "TooManyDistributionCNAMEs".
|
||||||
|
//
|
||||||
|
// Your request contains more CNAMEs than are allowed per distribution.
|
||||||
|
ErrCodeTooManyDistributionCNAMEs = "TooManyDistributionCNAMEs"
|
||||||
|
|
||||||
|
// ErrCodeTooManyDistributions for service response error code
|
||||||
|
// "TooManyDistributions".
|
||||||
|
//
|
||||||
|
// Processing your request would cause you to exceed the maximum number of distributions
|
||||||
|
// allowed.
|
||||||
|
ErrCodeTooManyDistributions = "TooManyDistributions"
|
||||||
|
|
||||||
|
// ErrCodeTooManyDistributionsWithLambdaAssociations for service response error code
|
||||||
|
// "TooManyDistributionsWithLambdaAssociations".
|
||||||
|
//
|
||||||
|
// Processing your request would cause the maximum number of distributions with
|
||||||
|
// Lambda function associations per owner to be exceeded.
|
||||||
|
ErrCodeTooManyDistributionsWithLambdaAssociations = "TooManyDistributionsWithLambdaAssociations"
|
||||||
|
|
||||||
|
// ErrCodeTooManyHeadersInForwardedValues for service response error code
|
||||||
|
// "TooManyHeadersInForwardedValues".
|
||||||
|
ErrCodeTooManyHeadersInForwardedValues = "TooManyHeadersInForwardedValues"
|
||||||
|
|
||||||
|
// ErrCodeTooManyInvalidationsInProgress for service response error code
|
||||||
|
// "TooManyInvalidationsInProgress".
|
||||||
|
//
|
||||||
|
// You have exceeded the maximum number of allowable InProgress invalidation
|
||||||
|
// batch requests, or invalidation objects.
|
||||||
|
ErrCodeTooManyInvalidationsInProgress = "TooManyInvalidationsInProgress"
|
||||||
|
|
||||||
|
// ErrCodeTooManyLambdaFunctionAssociations for service response error code
|
||||||
|
// "TooManyLambdaFunctionAssociations".
|
||||||
|
//
|
||||||
|
// Your request contains more Lambda function associations than are allowed
|
||||||
|
// per distribution.
|
||||||
|
ErrCodeTooManyLambdaFunctionAssociations = "TooManyLambdaFunctionAssociations"
|
||||||
|
|
||||||
|
// ErrCodeTooManyOriginCustomHeaders for service response error code
|
||||||
|
// "TooManyOriginCustomHeaders".
|
||||||
|
ErrCodeTooManyOriginCustomHeaders = "TooManyOriginCustomHeaders"
|
||||||
|
|
||||||
|
// ErrCodeTooManyOrigins for service response error code
|
||||||
|
// "TooManyOrigins".
|
||||||
|
//
|
||||||
|
// You cannot create more origins for the distribution.
|
||||||
|
ErrCodeTooManyOrigins = "TooManyOrigins"
|
||||||
|
|
||||||
|
// ErrCodeTooManyQueryStringParameters for service response error code
|
||||||
|
// "TooManyQueryStringParameters".
|
||||||
|
ErrCodeTooManyQueryStringParameters = "TooManyQueryStringParameters"
|
||||||
|
|
||||||
|
// ErrCodeTooManyStreamingDistributionCNAMEs for service response error code
|
||||||
|
// "TooManyStreamingDistributionCNAMEs".
|
||||||
|
ErrCodeTooManyStreamingDistributionCNAMEs = "TooManyStreamingDistributionCNAMEs"
|
||||||
|
|
||||||
|
// ErrCodeTooManyStreamingDistributions for service response error code
|
||||||
|
// "TooManyStreamingDistributions".
|
||||||
|
//
|
||||||
|
// Processing your request would cause you to exceed the maximum number of streaming
|
||||||
|
// distributions allowed.
|
||||||
|
ErrCodeTooManyStreamingDistributions = "TooManyStreamingDistributions"
|
||||||
|
|
||||||
|
// ErrCodeTooManyTrustedSigners for service response error code
|
||||||
|
// "TooManyTrustedSigners".
|
||||||
|
//
|
||||||
|
// Your request contains more trusted signers than are allowed per distribution.
|
||||||
|
ErrCodeTooManyTrustedSigners = "TooManyTrustedSigners"
|
||||||
|
|
||||||
|
// ErrCodeTrustedSignerDoesNotExist for service response error code
|
||||||
|
// "TrustedSignerDoesNotExist".
|
||||||
|
//
|
||||||
|
// One or more of your trusted signers do not exist.
|
||||||
|
ErrCodeTrustedSignerDoesNotExist = "TrustedSignerDoesNotExist"
|
||||||
|
)
|
31
vendor/github.com/aws/aws-sdk-go/service/cloudfront/service.go
generated
vendored
31
vendor/github.com/aws/aws-sdk-go/service/cloudfront/service.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||||
|
|
||||||
package cloudfront
|
package cloudfront
|
||||||
|
|
||||||
@ -7,13 +7,16 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/aws/client"
|
"github.com/aws/aws-sdk-go/aws/client"
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||||
"github.com/aws/aws-sdk-go/private/protocol/restxml"
|
"github.com/aws/aws-sdk-go/private/protocol/restxml"
|
||||||
"github.com/aws/aws-sdk-go/private/signer/v4"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CloudFront is a client for CloudFront.
|
// CloudFront provides the API operation methods for making requests to
|
||||||
//The service client's operations are safe to be used concurrently.
|
// Amazon CloudFront. See this package's package overview docs
|
||||||
// It is not safe to mutate any of the client's properties though.
|
// for details on the service.
|
||||||
|
//
|
||||||
|
// CloudFront methods are safe to use concurrently. It is not safe to
|
||||||
|
// modify mutate any of the struct's properties though.
|
||||||
type CloudFront struct {
|
type CloudFront struct {
|
||||||
*client.Client
|
*client.Client
|
||||||
}
|
}
|
||||||
@ -24,8 +27,11 @@ var initClient func(*client.Client)
|
|||||||
// Used for custom request initialization logic
|
// Used for custom request initialization logic
|
||||||
var initRequest func(*request.Request)
|
var initRequest func(*request.Request)
|
||||||
|
|
||||||
// A ServiceName is the name of the service the client will make API calls to.
|
// Service information constants
|
||||||
const ServiceName = "cloudfront"
|
const (
|
||||||
|
ServiceName = "cloudfront" // Service endpoint prefix API calls made to.
|
||||||
|
EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata.
|
||||||
|
)
|
||||||
|
|
||||||
// New creates a new instance of the CloudFront client with a session.
|
// New creates a new instance of the CloudFront client with a session.
|
||||||
// If additional configuration is needed for the client instance use the optional
|
// If additional configuration is needed for the client instance use the optional
|
||||||
@ -38,27 +44,28 @@ const ServiceName = "cloudfront"
|
|||||||
// // Create a CloudFront client with additional configuration
|
// // Create a CloudFront client with additional configuration
|
||||||
// svc := cloudfront.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
// svc := cloudfront.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *CloudFront {
|
func New(p client.ConfigProvider, cfgs ...*aws.Config) *CloudFront {
|
||||||
c := p.ClientConfig(ServiceName, cfgs...)
|
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||||
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
|
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newClient creates, initializes and returns a new service client instance.
|
// newClient creates, initializes and returns a new service client instance.
|
||||||
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *CloudFront {
|
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *CloudFront {
|
||||||
svc := &CloudFront{
|
svc := &CloudFront{
|
||||||
Client: client.New(
|
Client: client.New(
|
||||||
cfg,
|
cfg,
|
||||||
metadata.ClientInfo{
|
metadata.ClientInfo{
|
||||||
ServiceName: ServiceName,
|
ServiceName: ServiceName,
|
||||||
|
SigningName: signingName,
|
||||||
SigningRegion: signingRegion,
|
SigningRegion: signingRegion,
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
APIVersion: "2016-01-28",
|
APIVersion: "2017-03-25",
|
||||||
},
|
},
|
||||||
handlers,
|
handlers,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
svc.Handlers.Sign.PushBack(v4.Sign)
|
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||||
svc.Handlers.Build.PushBackNamed(restxml.BuildHandler)
|
svc.Handlers.Build.PushBackNamed(restxml.BuildHandler)
|
||||||
svc.Handlers.Unmarshal.PushBackNamed(restxml.UnmarshalHandler)
|
svc.Handlers.Unmarshal.PushBackNamed(restxml.UnmarshalHandler)
|
||||||
svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler)
|
svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler)
|
||||||
|
162
vendor/github.com/aws/aws-sdk-go/service/cloudfront/waiters.go
generated
vendored
162
vendor/github.com/aws/aws-sdk-go/service/cloudfront/waiters.go
generated
vendored
@ -1,76 +1,148 @@
|
|||||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||||
|
|
||||||
package cloudfront
|
package cloudfront
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/aws/aws-sdk-go/private/waiter"
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// WaitUntilDistributionDeployed uses the CloudFront API operation
|
||||||
|
// GetDistribution to wait for a condition to be met before returning.
|
||||||
|
// If the condition is not met within the max attempt window, an error will
|
||||||
|
// be returned.
|
||||||
func (c *CloudFront) WaitUntilDistributionDeployed(input *GetDistributionInput) error {
|
func (c *CloudFront) WaitUntilDistributionDeployed(input *GetDistributionInput) error {
|
||||||
waiterCfg := waiter.Config{
|
return c.WaitUntilDistributionDeployedWithContext(aws.BackgroundContext(), input)
|
||||||
Operation: "GetDistribution",
|
}
|
||||||
Delay: 60,
|
|
||||||
|
// WaitUntilDistributionDeployedWithContext is an extended version of WaitUntilDistributionDeployed.
|
||||||
|
// With the support for passing in a context and options to configure the
|
||||||
|
// Waiter and the underlying request options.
|
||||||
|
//
|
||||||
|
// The context must be non-nil and will be used for request cancellation. If
|
||||||
|
// the context is nil a panic will occur. In the future the SDK may create
|
||||||
|
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||||
|
// for more information on using Contexts.
|
||||||
|
func (c *CloudFront) WaitUntilDistributionDeployedWithContext(ctx aws.Context, input *GetDistributionInput, opts ...request.WaiterOption) error {
|
||||||
|
w := request.Waiter{
|
||||||
|
Name: "WaitUntilDistributionDeployed",
|
||||||
MaxAttempts: 25,
|
MaxAttempts: 25,
|
||||||
Acceptors: []waiter.WaitAcceptor{
|
Delay: request.ConstantWaiterDelay(60 * time.Second),
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
{
|
{
|
||||||
State: "success",
|
State: request.SuccessWaiterState,
|
||||||
Matcher: "path",
|
Matcher: request.PathWaiterMatch, Argument: "Distribution.Status",
|
||||||
Argument: "Distribution.Status",
|
|
||||||
Expected: "Deployed",
|
Expected: "Deployed",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Logger: c.Config.Logger,
|
||||||
|
NewRequest: func(opts []request.Option) (*request.Request, error) {
|
||||||
|
var inCpy *GetDistributionInput
|
||||||
|
if input != nil {
|
||||||
|
tmp := *input
|
||||||
|
inCpy = &tmp
|
||||||
|
}
|
||||||
|
req, _ := c.GetDistributionRequest(inCpy)
|
||||||
|
req.SetContext(ctx)
|
||||||
|
req.ApplyOptions(opts...)
|
||||||
|
return req, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
w.ApplyOptions(opts...)
|
||||||
|
|
||||||
|
return w.WaitWithContext(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
w := waiter.Waiter{
|
// WaitUntilInvalidationCompleted uses the CloudFront API operation
|
||||||
Client: c,
|
// GetInvalidation to wait for a condition to be met before returning.
|
||||||
Input: input,
|
// If the condition is not met within the max attempt window, an error will
|
||||||
Config: waiterCfg,
|
// be returned.
|
||||||
}
|
|
||||||
return w.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CloudFront) WaitUntilInvalidationCompleted(input *GetInvalidationInput) error {
|
func (c *CloudFront) WaitUntilInvalidationCompleted(input *GetInvalidationInput) error {
|
||||||
waiterCfg := waiter.Config{
|
return c.WaitUntilInvalidationCompletedWithContext(aws.BackgroundContext(), input)
|
||||||
Operation: "GetInvalidation",
|
}
|
||||||
Delay: 20,
|
|
||||||
|
// WaitUntilInvalidationCompletedWithContext is an extended version of WaitUntilInvalidationCompleted.
|
||||||
|
// With the support for passing in a context and options to configure the
|
||||||
|
// Waiter and the underlying request options.
|
||||||
|
//
|
||||||
|
// The context must be non-nil and will be used for request cancellation. If
|
||||||
|
// the context is nil a panic will occur. In the future the SDK may create
|
||||||
|
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||||
|
// for more information on using Contexts.
|
||||||
|
func (c *CloudFront) WaitUntilInvalidationCompletedWithContext(ctx aws.Context, input *GetInvalidationInput, opts ...request.WaiterOption) error {
|
||||||
|
w := request.Waiter{
|
||||||
|
Name: "WaitUntilInvalidationCompleted",
|
||||||
MaxAttempts: 30,
|
MaxAttempts: 30,
|
||||||
Acceptors: []waiter.WaitAcceptor{
|
Delay: request.ConstantWaiterDelay(20 * time.Second),
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
{
|
{
|
||||||
State: "success",
|
State: request.SuccessWaiterState,
|
||||||
Matcher: "path",
|
Matcher: request.PathWaiterMatch, Argument: "Invalidation.Status",
|
||||||
Argument: "Invalidation.Status",
|
|
||||||
Expected: "Completed",
|
Expected: "Completed",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Logger: c.Config.Logger,
|
||||||
|
NewRequest: func(opts []request.Option) (*request.Request, error) {
|
||||||
|
var inCpy *GetInvalidationInput
|
||||||
|
if input != nil {
|
||||||
|
tmp := *input
|
||||||
|
inCpy = &tmp
|
||||||
|
}
|
||||||
|
req, _ := c.GetInvalidationRequest(inCpy)
|
||||||
|
req.SetContext(ctx)
|
||||||
|
req.ApplyOptions(opts...)
|
||||||
|
return req, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
w.ApplyOptions(opts...)
|
||||||
|
|
||||||
|
return w.WaitWithContext(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
w := waiter.Waiter{
|
// WaitUntilStreamingDistributionDeployed uses the CloudFront API operation
|
||||||
Client: c,
|
// GetStreamingDistribution to wait for a condition to be met before returning.
|
||||||
Input: input,
|
// If the condition is not met within the max attempt window, an error will
|
||||||
Config: waiterCfg,
|
// be returned.
|
||||||
}
|
|
||||||
return w.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CloudFront) WaitUntilStreamingDistributionDeployed(input *GetStreamingDistributionInput) error {
|
func (c *CloudFront) WaitUntilStreamingDistributionDeployed(input *GetStreamingDistributionInput) error {
|
||||||
waiterCfg := waiter.Config{
|
return c.WaitUntilStreamingDistributionDeployedWithContext(aws.BackgroundContext(), input)
|
||||||
Operation: "GetStreamingDistribution",
|
}
|
||||||
Delay: 60,
|
|
||||||
|
// WaitUntilStreamingDistributionDeployedWithContext is an extended version of WaitUntilStreamingDistributionDeployed.
|
||||||
|
// With the support for passing in a context and options to configure the
|
||||||
|
// Waiter and the underlying request options.
|
||||||
|
//
|
||||||
|
// The context must be non-nil and will be used for request cancellation. If
|
||||||
|
// the context is nil a panic will occur. In the future the SDK may create
|
||||||
|
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||||
|
// for more information on using Contexts.
|
||||||
|
func (c *CloudFront) WaitUntilStreamingDistributionDeployedWithContext(ctx aws.Context, input *GetStreamingDistributionInput, opts ...request.WaiterOption) error {
|
||||||
|
w := request.Waiter{
|
||||||
|
Name: "WaitUntilStreamingDistributionDeployed",
|
||||||
MaxAttempts: 25,
|
MaxAttempts: 25,
|
||||||
Acceptors: []waiter.WaitAcceptor{
|
Delay: request.ConstantWaiterDelay(60 * time.Second),
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
{
|
{
|
||||||
State: "success",
|
State: request.SuccessWaiterState,
|
||||||
Matcher: "path",
|
Matcher: request.PathWaiterMatch, Argument: "StreamingDistribution.Status",
|
||||||
Argument: "StreamingDistribution.Status",
|
|
||||||
Expected: "Deployed",
|
Expected: "Deployed",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Logger: c.Config.Logger,
|
||||||
|
NewRequest: func(opts []request.Option) (*request.Request, error) {
|
||||||
|
var inCpy *GetStreamingDistributionInput
|
||||||
|
if input != nil {
|
||||||
|
tmp := *input
|
||||||
|
inCpy = &tmp
|
||||||
}
|
}
|
||||||
|
req, _ := c.GetStreamingDistributionRequest(inCpy)
|
||||||
|
req.SetContext(ctx)
|
||||||
|
req.ApplyOptions(opts...)
|
||||||
|
return req, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
w.ApplyOptions(opts...)
|
||||||
|
|
||||||
w := waiter.Waiter{
|
return w.WaitWithContext(ctx)
|
||||||
Client: c,
|
|
||||||
Input: input,
|
|
||||||
Config: waiterCfg,
|
|
||||||
}
|
|
||||||
return w.Wait()
|
|
||||||
}
|
}
|
||||||
|
14309
vendor/github.com/aws/aws-sdk-go/service/s3/api.go
generated
vendored
14309
vendor/github.com/aws/aws-sdk-go/service/s3/api.go
generated
vendored
File diff suppressed because it is too large
Load Diff
65
vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go
generated
vendored
65
vendor/github.com/aws/aws-sdk-go/service/s3/bucket_location.go
generated
vendored
@ -12,6 +12,69 @@ import (
|
|||||||
|
|
||||||
var reBucketLocation = regexp.MustCompile(`>([^<>]+)<\/Location`)
|
var reBucketLocation = regexp.MustCompile(`>([^<>]+)<\/Location`)
|
||||||
|
|
||||||
|
// NormalizeBucketLocation is a utility function which will update the
|
||||||
|
// passed in value to always be a region ID. Generally this would be used
|
||||||
|
// with GetBucketLocation API operation.
|
||||||
|
//
|
||||||
|
// Replaces empty string with "us-east-1", and "EU" with "eu-west-1".
|
||||||
|
//
|
||||||
|
// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
|
||||||
|
// for more information on the values that can be returned.
|
||||||
|
func NormalizeBucketLocation(loc string) string {
|
||||||
|
switch loc {
|
||||||
|
case "":
|
||||||
|
loc = "us-east-1"
|
||||||
|
case "EU":
|
||||||
|
loc = "eu-west-1"
|
||||||
|
}
|
||||||
|
|
||||||
|
return loc
|
||||||
|
}
|
||||||
|
|
||||||
|
// NormalizeBucketLocationHandler is a request handler which will update the
|
||||||
|
// GetBucketLocation's result LocationConstraint value to always be a region ID.
|
||||||
|
//
|
||||||
|
// Replaces empty string with "us-east-1", and "EU" with "eu-west-1".
|
||||||
|
//
|
||||||
|
// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
|
||||||
|
// for more information on the values that can be returned.
|
||||||
|
//
|
||||||
|
// req, result := svc.GetBucketLocationRequest(&s3.GetBucketLocationInput{
|
||||||
|
// Bucket: aws.String(bucket),
|
||||||
|
// })
|
||||||
|
// req.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler)
|
||||||
|
// err := req.Send()
|
||||||
|
var NormalizeBucketLocationHandler = request.NamedHandler{
|
||||||
|
Name: "awssdk.s3.NormalizeBucketLocation",
|
||||||
|
Fn: func(req *request.Request) {
|
||||||
|
if req.Error != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
out := req.Data.(*GetBucketLocationOutput)
|
||||||
|
loc := NormalizeBucketLocation(aws.StringValue(out.LocationConstraint))
|
||||||
|
out.LocationConstraint = aws.String(loc)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNormalizeBucketLocation is a request option which will update the
|
||||||
|
// GetBucketLocation's result LocationConstraint value to always be a region ID.
|
||||||
|
//
|
||||||
|
// Replaces empty string with "us-east-1", and "EU" with "eu-west-1".
|
||||||
|
//
|
||||||
|
// See http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
|
||||||
|
// for more information on the values that can be returned.
|
||||||
|
//
|
||||||
|
// result, err := svc.GetBucketLocationWithContext(ctx,
|
||||||
|
// &s3.GetBucketLocationInput{
|
||||||
|
// Bucket: aws.String(bucket),
|
||||||
|
// },
|
||||||
|
// s3.WithNormalizeBucketLocation,
|
||||||
|
// )
|
||||||
|
func WithNormalizeBucketLocation(r *request.Request) {
|
||||||
|
r.Handlers.Unmarshal.PushBackNamed(NormalizeBucketLocationHandler)
|
||||||
|
}
|
||||||
|
|
||||||
func buildGetBucketLocation(r *request.Request) {
|
func buildGetBucketLocation(r *request.Request) {
|
||||||
if r.DataFilled() {
|
if r.DataFilled() {
|
||||||
out := r.Data.(*GetBucketLocationOutput)
|
out := r.Data.(*GetBucketLocationOutput)
|
||||||
@ -24,7 +87,7 @@ func buildGetBucketLocation(r *request.Request) {
|
|||||||
match := reBucketLocation.FindSubmatch(b)
|
match := reBucketLocation.FindSubmatch(b)
|
||||||
if len(match) > 1 {
|
if len(match) > 1 {
|
||||||
loc := string(match[1])
|
loc := string(match[1])
|
||||||
out.LocationConstraint = &loc
|
out.LocationConstraint = aws.String(loc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
37
vendor/github.com/aws/aws-sdk-go/service/s3/customizations.go
generated
vendored
37
vendor/github.com/aws/aws-sdk-go/service/s3/customizations.go
generated
vendored
@ -6,9 +6,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
initClient = func(c *client.Client) {
|
initClient = defaultInitClientFn
|
||||||
// Support building custom host-style bucket endpoints
|
initRequest = defaultInitRequestFn
|
||||||
c.Handlers.Build.PushFront(updateHostWithBucket)
|
}
|
||||||
|
|
||||||
|
func defaultInitClientFn(c *client.Client) {
|
||||||
|
// Support building custom endpoints based on config
|
||||||
|
c.Handlers.Build.PushFront(updateEndpointForS3Config)
|
||||||
|
|
||||||
// Require SSL when using SSE keys
|
// Require SSL when using SSE keys
|
||||||
c.Handlers.Validate.PushBack(validateSSERequiresSSL)
|
c.Handlers.Validate.PushBack(validateSSERequiresSSL)
|
||||||
@ -19,9 +23,15 @@ func init() {
|
|||||||
c.Handlers.UnmarshalError.PushBack(unmarshalError)
|
c.Handlers.UnmarshalError.PushBack(unmarshalError)
|
||||||
}
|
}
|
||||||
|
|
||||||
initRequest = func(r *request.Request) {
|
func defaultInitRequestFn(r *request.Request) {
|
||||||
|
// Add reuest handlers for specific platforms.
|
||||||
|
// e.g. 100-continue support for PUT requests using Go 1.6
|
||||||
|
platformRequestHandlers(r)
|
||||||
|
|
||||||
switch r.Operation.Name {
|
switch r.Operation.Name {
|
||||||
case opPutBucketCors, opPutBucketLifecycle, opPutBucketPolicy, opPutBucketTagging, opDeleteObjects, opPutBucketLifecycleConfiguration:
|
case opPutBucketCors, opPutBucketLifecycle, opPutBucketPolicy,
|
||||||
|
opPutBucketTagging, opDeleteObjects, opPutBucketLifecycleConfiguration,
|
||||||
|
opPutBucketReplication:
|
||||||
// These S3 operations require Content-MD5 to be set
|
// These S3 operations require Content-MD5 to be set
|
||||||
r.Handlers.Build.PushBack(contentMD5)
|
r.Handlers.Build.PushBack(contentMD5)
|
||||||
case opGetBucketLocation:
|
case opGetBucketLocation:
|
||||||
@ -34,4 +44,21 @@ func init() {
|
|||||||
r.Handlers.Unmarshal.PushFront(copyMultipartStatusOKUnmarhsalError)
|
r.Handlers.Unmarshal.PushFront(copyMultipartStatusOKUnmarhsalError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bucketGetter is an accessor interface to grab the "Bucket" field from
|
||||||
|
// an S3 type.
|
||||||
|
type bucketGetter interface {
|
||||||
|
getBucket() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// sseCustomerKeyGetter is an accessor interface to grab the "SSECustomerKey"
|
||||||
|
// field from an S3 type.
|
||||||
|
type sseCustomerKeyGetter interface {
|
||||||
|
getSSECustomerKey() string
|
||||||
|
}
|
||||||
|
|
||||||
|
// copySourceSSECustomerKeyGetter is an accessor interface to grab the
|
||||||
|
// "CopySourceSSECustomerKey" field from an S3 type.
|
||||||
|
type copySourceSSECustomerKeyGetter interface {
|
||||||
|
getCopySourceSSECustomerKey() string
|
||||||
}
|
}
|
||||||
|
26
vendor/github.com/aws/aws-sdk-go/service/s3/doc.go
generated
vendored
Normal file
26
vendor/github.com/aws/aws-sdk-go/service/s3/doc.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Package s3 provides the client and types for making API
|
||||||
|
// requests to Amazon Simple Storage Service.
|
||||||
|
//
|
||||||
|
// See https://docs.aws.amazon.com/goto/WebAPI/s3-2006-03-01 for more information on this service.
|
||||||
|
//
|
||||||
|
// See s3 package documentation for more information.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/
|
||||||
|
//
|
||||||
|
// Using the Client
|
||||||
|
//
|
||||||
|
// To Amazon Simple Storage Service with the SDK use the New function to create
|
||||||
|
// a new service client. With that client you can make API requests to the service.
|
||||||
|
// These clients are safe to use concurrently.
|
||||||
|
//
|
||||||
|
// See the SDK's documentation for more information on how to use the SDK.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||||
|
//
|
||||||
|
// See aws.Config documentation for more information on configuring SDK clients.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||||
|
//
|
||||||
|
// See the Amazon Simple Storage Service client S3 for more
|
||||||
|
// information on creating client for this service.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/#New
|
||||||
|
package s3
|
109
vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go
generated
vendored
Normal file
109
vendor/github.com/aws/aws-sdk-go/service/s3/doc_custom.go
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// Upload Managers
|
||||||
|
//
|
||||||
|
// The s3manager package's Uploader provides concurrent upload of content to S3
|
||||||
|
// by taking advantage of S3's Multipart APIs. The Uploader also supports both
|
||||||
|
// io.Reader for streaming uploads, and will also take advantage of io.ReadSeeker
|
||||||
|
// for optimizations if the Body satisfies that type. Once the Uploader instance
|
||||||
|
// is created you can call Upload concurrently from multiple goroutines safely.
|
||||||
|
//
|
||||||
|
// // The session the S3 Uploader will use
|
||||||
|
// sess := session.Must(session.NewSession())
|
||||||
|
//
|
||||||
|
// // Create an uploader with the session and default options
|
||||||
|
// uploader := s3manager.NewUploader(sess)
|
||||||
|
//
|
||||||
|
// f, err := os.Open(filename)
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("failed to open file %q, %v", filename, err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Upload the file to S3.
|
||||||
|
// result, err := uploader.Upload(&s3manager.UploadInput{
|
||||||
|
// Bucket: aws.String(myBucket),
|
||||||
|
// Key: aws.String(myString),
|
||||||
|
// Body: f,
|
||||||
|
// })
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("failed to upload file, %v", err)
|
||||||
|
// }
|
||||||
|
// fmt.Printf("file uploaded to, %s\n", aws.StringValue(result.Location))
|
||||||
|
//
|
||||||
|
// See the s3manager package's Uploader type documentation for more information.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Uploader
|
||||||
|
//
|
||||||
|
// Download Manager
|
||||||
|
//
|
||||||
|
// The s3manager package's Downloader provides concurrently downloading of Objects
|
||||||
|
// from S3. The Downloader will write S3 Object content with an io.WriterAt.
|
||||||
|
// Once the Downloader instance is created you can call Upload concurrently from
|
||||||
|
// multiple goroutines safely.
|
||||||
|
//
|
||||||
|
// // The session the S3 Downloader will use
|
||||||
|
// sess := session.Must(session.NewSession())
|
||||||
|
//
|
||||||
|
// // Create a downloader with the session and default options
|
||||||
|
// downloader := s3manager.NewDownloader(sess)
|
||||||
|
//
|
||||||
|
// // Create a file to write the S3 Object contents to.
|
||||||
|
// f, err := os.Create(filename)
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("failed to create file %q, %v", filename, err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Write the contents of S3 Object to the file
|
||||||
|
// n, err := downloader.Download(f, &s3.GetObjectInput{
|
||||||
|
// Bucket: aws.String(myBucket),
|
||||||
|
// Key: aws.String(myString),
|
||||||
|
// })
|
||||||
|
// if err != nil {
|
||||||
|
// return fmt.Errorf("failed to upload file, %v", err)
|
||||||
|
// }
|
||||||
|
// fmt.Printf("file downloaded, %d bytes\n", n)
|
||||||
|
//
|
||||||
|
// See the s3manager package's Downloader type documentation for more information.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#Downloader
|
||||||
|
//
|
||||||
|
// Get Bucket Region
|
||||||
|
//
|
||||||
|
// GetBucketRegion will attempt to get the region for a bucket using a region
|
||||||
|
// hint to determine which AWS partition to perform the query on. Use this utility
|
||||||
|
// to determine the region a bucket is in.
|
||||||
|
//
|
||||||
|
// sess := session.Must(session.NewSession())
|
||||||
|
//
|
||||||
|
// bucket := "my-bucket"
|
||||||
|
// region, err := s3manager.GetBucketRegion(ctx, sess, bucket, "us-west-2")
|
||||||
|
// if err != nil {
|
||||||
|
// if aerr, ok := err.(awserr.Error); ok && aerr.Code() == "NotFound" {
|
||||||
|
// fmt.Fprintf(os.Stderr, "unable to find bucket %s's region not found\n", bucket)
|
||||||
|
// }
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// fmt.Printf("Bucket %s is in %s region\n", bucket, region)
|
||||||
|
//
|
||||||
|
// See the s3manager package's GetBucketRegion function documentation for more information
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3manager/#GetBucketRegion
|
||||||
|
//
|
||||||
|
// S3 Crypto Client
|
||||||
|
//
|
||||||
|
// The s3crypto package provides the tools to upload and download encrypted
|
||||||
|
// content from S3. The Encryption and Decryption clients can be used concurrently
|
||||||
|
// once the client is created.
|
||||||
|
//
|
||||||
|
// sess := session.Must(session.NewSession())
|
||||||
|
//
|
||||||
|
// // Create the decryption client.
|
||||||
|
// svc := s3crypto.NewDecryptionClient(sess)
|
||||||
|
//
|
||||||
|
// // The object will be downloaded from S3 and decrypted locally. By metadata
|
||||||
|
// // about the object's encryption will instruct the decryption client how
|
||||||
|
// // decrypt the content of the object. By default KMS is used for keys.
|
||||||
|
// result, err := svc.GetObject(&s3.GetObjectInput {
|
||||||
|
// Bucket: aws.String(myBucket),
|
||||||
|
// Key: aws.String(myKey),
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// See the s3crypto package documentation for more information.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/service/s3/s3crypto/
|
||||||
|
//
|
||||||
|
package s3
|
48
vendor/github.com/aws/aws-sdk-go/service/s3/errors.go
generated
vendored
Normal file
48
vendor/github.com/aws/aws-sdk-go/service/s3/errors.go
generated
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
package s3
|
||||||
|
|
||||||
|
const (
|
||||||
|
|
||||||
|
// ErrCodeBucketAlreadyExists for service response error code
|
||||||
|
// "BucketAlreadyExists".
|
||||||
|
//
|
||||||
|
// The requested bucket name is not available. The bucket namespace is shared
|
||||||
|
// by all users of the system. Please select a different name and try again.
|
||||||
|
ErrCodeBucketAlreadyExists = "BucketAlreadyExists"
|
||||||
|
|
||||||
|
// ErrCodeBucketAlreadyOwnedByYou for service response error code
|
||||||
|
// "BucketAlreadyOwnedByYou".
|
||||||
|
ErrCodeBucketAlreadyOwnedByYou = "BucketAlreadyOwnedByYou"
|
||||||
|
|
||||||
|
// ErrCodeNoSuchBucket for service response error code
|
||||||
|
// "NoSuchBucket".
|
||||||
|
//
|
||||||
|
// The specified bucket does not exist.
|
||||||
|
ErrCodeNoSuchBucket = "NoSuchBucket"
|
||||||
|
|
||||||
|
// ErrCodeNoSuchKey for service response error code
|
||||||
|
// "NoSuchKey".
|
||||||
|
//
|
||||||
|
// The specified key does not exist.
|
||||||
|
ErrCodeNoSuchKey = "NoSuchKey"
|
||||||
|
|
||||||
|
// ErrCodeNoSuchUpload for service response error code
|
||||||
|
// "NoSuchUpload".
|
||||||
|
//
|
||||||
|
// The specified multipart upload does not exist.
|
||||||
|
ErrCodeNoSuchUpload = "NoSuchUpload"
|
||||||
|
|
||||||
|
// ErrCodeObjectAlreadyInActiveTierError for service response error code
|
||||||
|
// "ObjectAlreadyInActiveTierError".
|
||||||
|
//
|
||||||
|
// This operation is not allowed against this storage tier
|
||||||
|
ErrCodeObjectAlreadyInActiveTierError = "ObjectAlreadyInActiveTierError"
|
||||||
|
|
||||||
|
// ErrCodeObjectNotInActiveTierError for service response error code
|
||||||
|
// "ObjectNotInActiveTierError".
|
||||||
|
//
|
||||||
|
// The source object of the COPY operation is not in the active tier and is
|
||||||
|
// only stored in Amazon Glacier.
|
||||||
|
ErrCodeObjectNotInActiveTierError = "ObjectNotInActiveTierError"
|
||||||
|
)
|
169
vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go
generated
vendored
169
vendor/github.com/aws/aws-sdk-go/service/s3/host_style_bucket.go
generated
vendored
@ -1,14 +1,139 @@
|
|||||||
package s3
|
package s3
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// an operationBlacklist is a list of operation names that should a
|
||||||
|
// request handler should not be executed with.
|
||||||
|
type operationBlacklist []string
|
||||||
|
|
||||||
|
// Continue will return true of the Request's operation name is not
|
||||||
|
// in the blacklist. False otherwise.
|
||||||
|
func (b operationBlacklist) Continue(r *request.Request) bool {
|
||||||
|
for i := 0; i < len(b); i++ {
|
||||||
|
if b[i] == r.Operation.Name {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
var accelerateOpBlacklist = operationBlacklist{
|
||||||
|
opListBuckets, opCreateBucket, opDeleteBucket,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request handler to automatically add the bucket name to the endpoint domain
|
||||||
|
// if possible. This style of bucket is valid for all bucket names which are
|
||||||
|
// DNS compatible and do not contain "."
|
||||||
|
func updateEndpointForS3Config(r *request.Request) {
|
||||||
|
forceHostStyle := aws.BoolValue(r.Config.S3ForcePathStyle)
|
||||||
|
accelerate := aws.BoolValue(r.Config.S3UseAccelerate)
|
||||||
|
|
||||||
|
if accelerate && accelerateOpBlacklist.Continue(r) {
|
||||||
|
if forceHostStyle {
|
||||||
|
if r.Config.Logger != nil {
|
||||||
|
r.Config.Logger.Log("ERROR: aws.Config.S3UseAccelerate is not compatible with aws.Config.S3ForcePathStyle, ignoring S3ForcePathStyle.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateEndpointForAccelerate(r)
|
||||||
|
} else if !forceHostStyle && r.Operation.Name != opGetBucketLocation {
|
||||||
|
updateEndpointForHostStyle(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateEndpointForHostStyle(r *request.Request) {
|
||||||
|
bucket, ok := bucketNameFromReqParams(r.Params)
|
||||||
|
if !ok {
|
||||||
|
// Ignore operation requests if the bucketname was not provided
|
||||||
|
// if this is an input validation error the validation handler
|
||||||
|
// will report it.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hostCompatibleBucketName(r.HTTPRequest.URL, bucket) {
|
||||||
|
// bucket name must be valid to put into the host
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
moveBucketToHost(r.HTTPRequest.URL, bucket)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
accelElem = []byte("s3-accelerate.dualstack.")
|
||||||
|
)
|
||||||
|
|
||||||
|
func updateEndpointForAccelerate(r *request.Request) {
|
||||||
|
bucket, ok := bucketNameFromReqParams(r.Params)
|
||||||
|
if !ok {
|
||||||
|
// Ignore operation requests if the bucketname was not provided
|
||||||
|
// if this is an input validation error the validation handler
|
||||||
|
// will report it.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !hostCompatibleBucketName(r.HTTPRequest.URL, bucket) {
|
||||||
|
r.Error = awserr.New("InvalidParameterException",
|
||||||
|
fmt.Sprintf("bucket name %s is not compatible with S3 Accelerate", bucket),
|
||||||
|
nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Split(r.HTTPRequest.URL.Host, ".")
|
||||||
|
if len(parts) < 3 {
|
||||||
|
r.Error = awserr.New("InvalidParameterExecption",
|
||||||
|
fmt.Sprintf("unable to update endpoint host for S3 accelerate, hostname invalid, %s",
|
||||||
|
r.HTTPRequest.URL.Host), nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if parts[0] == "s3" || strings.HasPrefix(parts[0], "s3-") {
|
||||||
|
parts[0] = "s3-accelerate"
|
||||||
|
}
|
||||||
|
for i := 1; i+1 < len(parts); i++ {
|
||||||
|
if parts[i] == aws.StringValue(r.Config.Region) {
|
||||||
|
parts = append(parts[:i], parts[i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r.HTTPRequest.URL.Host = strings.Join(parts, ".")
|
||||||
|
|
||||||
|
moveBucketToHost(r.HTTPRequest.URL, bucket)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempts to retrieve the bucket name from the request input parameters.
|
||||||
|
// If no bucket is found, or the field is empty "", false will be returned.
|
||||||
|
func bucketNameFromReqParams(params interface{}) (string, bool) {
|
||||||
|
if iface, ok := params.(bucketGetter); ok {
|
||||||
|
b := iface.getBucket()
|
||||||
|
return b, len(b) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// hostCompatibleBucketName returns true if the request should
|
||||||
|
// put the bucket in the host. This is false if S3ForcePathStyle is
|
||||||
|
// explicitly set or if the bucket is not DNS compatible.
|
||||||
|
func hostCompatibleBucketName(u *url.URL, bucket string) bool {
|
||||||
|
// Bucket might be DNS compatible but dots in the hostname will fail
|
||||||
|
// certificate validation, so do not use host-style.
|
||||||
|
if u.Scheme == "https" && strings.Contains(bucket, ".") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the bucket is DNS compatible
|
||||||
|
return dnsCompatibleBucketName(bucket)
|
||||||
|
}
|
||||||
|
|
||||||
var reDomain = regexp.MustCompile(`^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$`)
|
var reDomain = regexp.MustCompile(`^[a-z0-9][a-z0-9\.\-]{1,61}[a-z0-9]$`)
|
||||||
var reIPAddress = regexp.MustCompile(`^(\d+\.){3}\d+$`)
|
var reIPAddress = regexp.MustCompile(`^(\d+\.){3}\d+$`)
|
||||||
|
|
||||||
@ -20,41 +145,11 @@ func dnsCompatibleBucketName(bucket string) bool {
|
|||||||
!strings.Contains(bucket, "..")
|
!strings.Contains(bucket, "..")
|
||||||
}
|
}
|
||||||
|
|
||||||
// hostStyleBucketName returns true if the request should put the bucket in
|
// moveBucketToHost moves the bucket name from the URI path to URL host.
|
||||||
// the host. This is false if S3ForcePathStyle is explicitly set or if the
|
func moveBucketToHost(u *url.URL, bucket string) {
|
||||||
// bucket is not DNS compatible.
|
u.Host = bucket + "." + u.Host
|
||||||
func hostStyleBucketName(r *request.Request, bucket string) bool {
|
u.Path = strings.Replace(u.Path, "/{Bucket}", "", -1)
|
||||||
if aws.BoolValue(r.Config.S3ForcePathStyle) {
|
if u.Path == "" {
|
||||||
return false
|
u.Path = "/"
|
||||||
}
|
|
||||||
|
|
||||||
// Bucket might be DNS compatible but dots in the hostname will fail
|
|
||||||
// certificate validation, so do not use host-style.
|
|
||||||
if r.HTTPRequest.URL.Scheme == "https" && strings.Contains(bucket, ".") {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBucketLocation should be able to be called from any region within
|
|
||||||
// a partition, and return the associated region of the bucket.
|
|
||||||
if r.Operation.Name == opGetBucketLocation {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use host-style if the bucket is DNS compatible
|
|
||||||
return dnsCompatibleBucketName(bucket)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateHostWithBucket(r *request.Request) {
|
|
||||||
b, _ := awsutil.ValuesAtPath(r.Params, "Bucket")
|
|
||||||
if len(b) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if bucket := b[0].(*string); aws.StringValue(bucket) != "" && hostStyleBucketName(r, *bucket) {
|
|
||||||
r.HTTPRequest.URL.Host = *bucket + "." + r.HTTPRequest.URL.Host
|
|
||||||
r.HTTPRequest.URL.Path = strings.Replace(r.HTTPRequest.URL.Path, "/{Bucket}", "", -1)
|
|
||||||
if r.HTTPRequest.URL.Path == "" {
|
|
||||||
r.HTTPRequest.URL.Path = "/"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/aws/aws-sdk-go/service/s3/platform_handlers.go
generated
vendored
Normal file
8
vendor/github.com/aws/aws-sdk-go/service/s3/platform_handlers.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// +build !go1.6
|
||||||
|
|
||||||
|
package s3
|
||||||
|
|
||||||
|
import "github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
|
||||||
|
func platformRequestHandlers(r *request.Request) {
|
||||||
|
}
|
28
vendor/github.com/aws/aws-sdk-go/service/s3/platform_handlers_go1.6.go
generated
vendored
Normal file
28
vendor/github.com/aws/aws-sdk-go/service/s3/platform_handlers_go1.6.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// +build go1.6
|
||||||
|
|
||||||
|
package s3
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
func platformRequestHandlers(r *request.Request) {
|
||||||
|
if r.Operation.HTTPMethod == "PUT" {
|
||||||
|
// 100-Continue should only be used on put requests.
|
||||||
|
r.Handlers.Sign.PushBack(add100Continue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func add100Continue(r *request.Request) {
|
||||||
|
if aws.BoolValue(r.Config.S3Disable100Continue) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if r.HTTPRequest.ContentLength < 1024*1024*2 {
|
||||||
|
// Ignore requests smaller than 2MB. This helps prevent delaying
|
||||||
|
// requests unnecessarily.
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.HTTPRequest.Header.Set("Expect", "100-Continue")
|
||||||
|
}
|
29
vendor/github.com/aws/aws-sdk-go/service/s3/service.go
generated
vendored
29
vendor/github.com/aws/aws-sdk-go/service/s3/service.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||||
|
|
||||||
package s3
|
package s3
|
||||||
|
|
||||||
@ -7,13 +7,16 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/aws/client"
|
"github.com/aws/aws-sdk-go/aws/client"
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||||
"github.com/aws/aws-sdk-go/private/protocol/restxml"
|
"github.com/aws/aws-sdk-go/private/protocol/restxml"
|
||||||
"github.com/aws/aws-sdk-go/private/signer/v4"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// S3 is a client for Amazon S3.
|
// S3 provides the API operation methods for making requests to
|
||||||
//The service client's operations are safe to be used concurrently.
|
// Amazon Simple Storage Service. See this package's package overview docs
|
||||||
// It is not safe to mutate any of the client's properties though.
|
// for details on the service.
|
||||||
|
//
|
||||||
|
// S3 methods are safe to use concurrently. It is not safe to
|
||||||
|
// modify mutate any of the struct's properties though.
|
||||||
type S3 struct {
|
type S3 struct {
|
||||||
*client.Client
|
*client.Client
|
||||||
}
|
}
|
||||||
@ -24,8 +27,11 @@ var initClient func(*client.Client)
|
|||||||
// Used for custom request initialization logic
|
// Used for custom request initialization logic
|
||||||
var initRequest func(*request.Request)
|
var initRequest func(*request.Request)
|
||||||
|
|
||||||
// A ServiceName is the name of the service the client will make API calls to.
|
// Service information constants
|
||||||
const ServiceName = "s3"
|
const (
|
||||||
|
ServiceName = "s3" // Service endpoint prefix API calls made to.
|
||||||
|
EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata.
|
||||||
|
)
|
||||||
|
|
||||||
// New creates a new instance of the S3 client with a session.
|
// New creates a new instance of the S3 client with a session.
|
||||||
// If additional configuration is needed for the client instance use the optional
|
// If additional configuration is needed for the client instance use the optional
|
||||||
@ -38,17 +44,18 @@ const ServiceName = "s3"
|
|||||||
// // Create a S3 client with additional configuration
|
// // Create a S3 client with additional configuration
|
||||||
// svc := s3.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
// svc := s3.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *S3 {
|
func New(p client.ConfigProvider, cfgs ...*aws.Config) *S3 {
|
||||||
c := p.ClientConfig(ServiceName, cfgs...)
|
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||||
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
|
return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newClient creates, initializes and returns a new service client instance.
|
// newClient creates, initializes and returns a new service client instance.
|
||||||
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *S3 {
|
func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *S3 {
|
||||||
svc := &S3{
|
svc := &S3{
|
||||||
Client: client.New(
|
Client: client.New(
|
||||||
cfg,
|
cfg,
|
||||||
metadata.ClientInfo{
|
metadata.ClientInfo{
|
||||||
ServiceName: ServiceName,
|
ServiceName: ServiceName,
|
||||||
|
SigningName: signingName,
|
||||||
SigningRegion: signingRegion,
|
SigningRegion: signingRegion,
|
||||||
Endpoint: endpoint,
|
Endpoint: endpoint,
|
||||||
APIVersion: "2006-03-01",
|
APIVersion: "2006-03-01",
|
||||||
@ -58,7 +65,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
svc.Handlers.Sign.PushBack(v4.Sign)
|
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||||
svc.Handlers.Build.PushBackNamed(restxml.BuildHandler)
|
svc.Handlers.Build.PushBackNamed(restxml.BuildHandler)
|
||||||
svc.Handlers.Unmarshal.PushBackNamed(restxml.UnmarshalHandler)
|
svc.Handlers.Unmarshal.PushBackNamed(restxml.UnmarshalHandler)
|
||||||
svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler)
|
svc.Handlers.UnmarshalMeta.PushBackNamed(restxml.UnmarshalMetaHandler)
|
||||||
|
18
vendor/github.com/aws/aws-sdk-go/service/s3/sse.go
generated
vendored
18
vendor/github.com/aws/aws-sdk-go/service/s3/sse.go
generated
vendored
@ -5,17 +5,27 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
var errSSERequiresSSL = awserr.New("ConfigError", "cannot send SSE keys over HTTP.", nil)
|
var errSSERequiresSSL = awserr.New("ConfigError", "cannot send SSE keys over HTTP.", nil)
|
||||||
|
|
||||||
func validateSSERequiresSSL(r *request.Request) {
|
func validateSSERequiresSSL(r *request.Request) {
|
||||||
if r.HTTPRequest.URL.Scheme != "https" {
|
if r.HTTPRequest.URL.Scheme == "https" {
|
||||||
p, _ := awsutil.ValuesAtPath(r.Params, "SSECustomerKey||CopySourceSSECustomerKey")
|
return
|
||||||
if len(p) > 0 {
|
}
|
||||||
|
|
||||||
|
if iface, ok := r.Params.(sseCustomerKeyGetter); ok {
|
||||||
|
if len(iface.getSSECustomerKey()) > 0 {
|
||||||
r.Error = errSSERequiresSSL
|
r.Error = errSSERequiresSSL
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if iface, ok := r.Params.(copySourceSSECustomerKeyGetter); ok {
|
||||||
|
if len(iface.getCopySourceSSECustomerKey()) > 0 {
|
||||||
|
r.Error = errSSERequiresSSL
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/aws/aws-sdk-go/service/s3/statusok_error.go
generated
vendored
5
vendor/github.com/aws/aws-sdk-go/service/s3/statusok_error.go
generated
vendored
@ -5,7 +5,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
)
|
)
|
||||||
@ -17,8 +16,8 @@ func copyMultipartStatusOKUnmarhsalError(r *request.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
body := bytes.NewReader(b)
|
body := bytes.NewReader(b)
|
||||||
r.HTTPResponse.Body = aws.ReadSeekCloser(body)
|
r.HTTPResponse.Body = ioutil.NopCloser(body)
|
||||||
defer r.HTTPResponse.Body.(aws.ReaderSeekerCloser).Seek(0, 0)
|
defer body.Seek(0, 0)
|
||||||
|
|
||||||
if body.Len() == 0 {
|
if body.Len() == 0 {
|
||||||
// If there is no body don't attempt to parse the body.
|
// If there is no body don't attempt to parse the body.
|
||||||
|
76
vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go
generated
vendored
76
vendor/github.com/aws/aws-sdk-go/service/s3/unmarshal_error.go
generated
vendored
@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -20,38 +21,83 @@ type xmlErrorResponse struct {
|
|||||||
|
|
||||||
func unmarshalError(r *request.Request) {
|
func unmarshalError(r *request.Request) {
|
||||||
defer r.HTTPResponse.Body.Close()
|
defer r.HTTPResponse.Body.Close()
|
||||||
|
defer io.Copy(ioutil.Discard, r.HTTPResponse.Body)
|
||||||
|
|
||||||
|
hostID := r.HTTPResponse.Header.Get("X-Amz-Id-2")
|
||||||
|
|
||||||
|
// Bucket exists in a different region, and request needs
|
||||||
|
// to be made to the correct region.
|
||||||
if r.HTTPResponse.StatusCode == http.StatusMovedPermanently {
|
if r.HTTPResponse.StatusCode == http.StatusMovedPermanently {
|
||||||
r.Error = awserr.NewRequestFailure(
|
r.Error = requestFailure{
|
||||||
|
RequestFailure: awserr.NewRequestFailure(
|
||||||
awserr.New("BucketRegionError",
|
awserr.New("BucketRegionError",
|
||||||
fmt.Sprintf("incorrect region, the bucket is not in '%s' region",
|
fmt.Sprintf("incorrect region, the bucket is not in '%s' region",
|
||||||
aws.StringValue(r.Config.Region)),
|
aws.StringValue(r.Config.Region)),
|
||||||
nil),
|
nil),
|
||||||
r.HTTPResponse.StatusCode,
|
r.HTTPResponse.StatusCode,
|
||||||
r.RequestID,
|
r.RequestID,
|
||||||
)
|
),
|
||||||
|
hostID: hostID,
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.HTTPResponse.ContentLength == 0 {
|
var errCode, errMsg string
|
||||||
// No body, use status code to generate an awserr.Error
|
|
||||||
r.Error = awserr.NewRequestFailure(
|
|
||||||
awserr.New(strings.Replace(r.HTTPResponse.Status, " ", "", -1), r.HTTPResponse.Status, nil),
|
|
||||||
r.HTTPResponse.StatusCode,
|
|
||||||
r.RequestID,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Attempt to parse error from body if it is known
|
||||||
resp := &xmlErrorResponse{}
|
resp := &xmlErrorResponse{}
|
||||||
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
|
err := xml.NewDecoder(r.HTTPResponse.Body).Decode(resp)
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
r.Error = awserr.New("SerializationError", "failed to decode S3 XML error response", nil)
|
errCode = "SerializationError"
|
||||||
|
errMsg = "failed to decode S3 XML error response"
|
||||||
} else {
|
} else {
|
||||||
r.Error = awserr.NewRequestFailure(
|
errCode = resp.Code
|
||||||
awserr.New(resp.Code, resp.Message, nil),
|
errMsg = resp.Message
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to status code converted to message if still no error code
|
||||||
|
if len(errCode) == 0 {
|
||||||
|
statusText := http.StatusText(r.HTTPResponse.StatusCode)
|
||||||
|
errCode = strings.Replace(statusText, " ", "", -1)
|
||||||
|
errMsg = statusText
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Error = requestFailure{
|
||||||
|
RequestFailure: awserr.NewRequestFailure(
|
||||||
|
awserr.New(errCode, errMsg, err),
|
||||||
r.HTTPResponse.StatusCode,
|
r.HTTPResponse.StatusCode,
|
||||||
r.RequestID,
|
r.RequestID,
|
||||||
)
|
),
|
||||||
|
hostID: hostID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A RequestFailure provides access to the S3 Request ID and Host ID values
|
||||||
|
// returned from API operation errors. Getting the error as a string will
|
||||||
|
// return the formated error with the same information as awserr.RequestFailure,
|
||||||
|
// while also adding the HostID value from the response.
|
||||||
|
type RequestFailure interface {
|
||||||
|
awserr.RequestFailure
|
||||||
|
|
||||||
|
// Host ID is the S3 Host ID needed for debug, and contacting support
|
||||||
|
HostID() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type requestFailure struct {
|
||||||
|
awserr.RequestFailure
|
||||||
|
|
||||||
|
hostID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r requestFailure) Error() string {
|
||||||
|
extra := fmt.Sprintf("status code: %d, request id: %s, host id: %s",
|
||||||
|
r.StatusCode(), r.RequestID(), r.hostID)
|
||||||
|
return awserr.SprintError(r.Code(), r.Message(), extra, r.OrigErr())
|
||||||
|
}
|
||||||
|
func (r requestFailure) String() string {
|
||||||
|
return r.Error()
|
||||||
|
}
|
||||||
|
func (r requestFailure) HostID() string {
|
||||||
|
return r.hostID
|
||||||
|
}
|
||||||
|
235
vendor/github.com/aws/aws-sdk-go/service/s3/waiters.go
generated
vendored
235
vendor/github.com/aws/aws-sdk-go/service/s3/waiters.go
generated
vendored
@ -1,117 +1,214 @@
|
|||||||
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
|
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||||
|
|
||||||
package s3
|
package s3
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/aws/aws-sdk-go/private/waiter"
|
"time"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/aws/request"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// WaitUntilBucketExists uses the Amazon S3 API operation
|
||||||
|
// HeadBucket to wait for a condition to be met before returning.
|
||||||
|
// If the condition is not met within the max attempt window, an error will
|
||||||
|
// be returned.
|
||||||
func (c *S3) WaitUntilBucketExists(input *HeadBucketInput) error {
|
func (c *S3) WaitUntilBucketExists(input *HeadBucketInput) error {
|
||||||
waiterCfg := waiter.Config{
|
return c.WaitUntilBucketExistsWithContext(aws.BackgroundContext(), input)
|
||||||
Operation: "HeadBucket",
|
}
|
||||||
Delay: 5,
|
|
||||||
|
// WaitUntilBucketExistsWithContext is an extended version of WaitUntilBucketExists.
|
||||||
|
// With the support for passing in a context and options to configure the
|
||||||
|
// Waiter and the underlying request options.
|
||||||
|
//
|
||||||
|
// The context must be non-nil and will be used for request cancellation. If
|
||||||
|
// the context is nil a panic will occur. In the future the SDK may create
|
||||||
|
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||||
|
// for more information on using Contexts.
|
||||||
|
func (c *S3) WaitUntilBucketExistsWithContext(ctx aws.Context, input *HeadBucketInput, opts ...request.WaiterOption) error {
|
||||||
|
w := request.Waiter{
|
||||||
|
Name: "WaitUntilBucketExists",
|
||||||
MaxAttempts: 20,
|
MaxAttempts: 20,
|
||||||
Acceptors: []waiter.WaitAcceptor{
|
Delay: request.ConstantWaiterDelay(5 * time.Second),
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
{
|
{
|
||||||
State: "success",
|
State: request.SuccessWaiterState,
|
||||||
Matcher: "status",
|
Matcher: request.StatusWaiterMatch,
|
||||||
Argument: "",
|
|
||||||
Expected: 200,
|
Expected: 200,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
State: "success",
|
State: request.SuccessWaiterState,
|
||||||
Matcher: "status",
|
Matcher: request.StatusWaiterMatch,
|
||||||
Argument: "",
|
Expected: 301,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
State: request.SuccessWaiterState,
|
||||||
|
Matcher: request.StatusWaiterMatch,
|
||||||
Expected: 403,
|
Expected: 403,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
State: "retry",
|
State: request.RetryWaiterState,
|
||||||
Matcher: "status",
|
Matcher: request.StatusWaiterMatch,
|
||||||
Argument: "",
|
|
||||||
Expected: 404,
|
Expected: 404,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Logger: c.Config.Logger,
|
||||||
|
NewRequest: func(opts []request.Option) (*request.Request, error) {
|
||||||
|
var inCpy *HeadBucketInput
|
||||||
|
if input != nil {
|
||||||
|
tmp := *input
|
||||||
|
inCpy = &tmp
|
||||||
|
}
|
||||||
|
req, _ := c.HeadBucketRequest(inCpy)
|
||||||
|
req.SetContext(ctx)
|
||||||
|
req.ApplyOptions(opts...)
|
||||||
|
return req, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
w.ApplyOptions(opts...)
|
||||||
|
|
||||||
|
return w.WaitWithContext(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
w := waiter.Waiter{
|
// WaitUntilBucketNotExists uses the Amazon S3 API operation
|
||||||
Client: c,
|
// HeadBucket to wait for a condition to be met before returning.
|
||||||
Input: input,
|
// If the condition is not met within the max attempt window, an error will
|
||||||
Config: waiterCfg,
|
// be returned.
|
||||||
}
|
|
||||||
return w.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *S3) WaitUntilBucketNotExists(input *HeadBucketInput) error {
|
func (c *S3) WaitUntilBucketNotExists(input *HeadBucketInput) error {
|
||||||
waiterCfg := waiter.Config{
|
return c.WaitUntilBucketNotExistsWithContext(aws.BackgroundContext(), input)
|
||||||
Operation: "HeadBucket",
|
}
|
||||||
Delay: 5,
|
|
||||||
|
// WaitUntilBucketNotExistsWithContext is an extended version of WaitUntilBucketNotExists.
|
||||||
|
// With the support for passing in a context and options to configure the
|
||||||
|
// Waiter and the underlying request options.
|
||||||
|
//
|
||||||
|
// The context must be non-nil and will be used for request cancellation. If
|
||||||
|
// the context is nil a panic will occur. In the future the SDK may create
|
||||||
|
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||||
|
// for more information on using Contexts.
|
||||||
|
func (c *S3) WaitUntilBucketNotExistsWithContext(ctx aws.Context, input *HeadBucketInput, opts ...request.WaiterOption) error {
|
||||||
|
w := request.Waiter{
|
||||||
|
Name: "WaitUntilBucketNotExists",
|
||||||
MaxAttempts: 20,
|
MaxAttempts: 20,
|
||||||
Acceptors: []waiter.WaitAcceptor{
|
Delay: request.ConstantWaiterDelay(5 * time.Second),
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
{
|
{
|
||||||
State: "success",
|
State: request.SuccessWaiterState,
|
||||||
Matcher: "status",
|
Matcher: request.StatusWaiterMatch,
|
||||||
Argument: "",
|
|
||||||
Expected: 404,
|
Expected: 404,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Logger: c.Config.Logger,
|
||||||
|
NewRequest: func(opts []request.Option) (*request.Request, error) {
|
||||||
|
var inCpy *HeadBucketInput
|
||||||
|
if input != nil {
|
||||||
|
tmp := *input
|
||||||
|
inCpy = &tmp
|
||||||
|
}
|
||||||
|
req, _ := c.HeadBucketRequest(inCpy)
|
||||||
|
req.SetContext(ctx)
|
||||||
|
req.ApplyOptions(opts...)
|
||||||
|
return req, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
w.ApplyOptions(opts...)
|
||||||
|
|
||||||
|
return w.WaitWithContext(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
w := waiter.Waiter{
|
// WaitUntilObjectExists uses the Amazon S3 API operation
|
||||||
Client: c,
|
// HeadObject to wait for a condition to be met before returning.
|
||||||
Input: input,
|
// If the condition is not met within the max attempt window, an error will
|
||||||
Config: waiterCfg,
|
// be returned.
|
||||||
}
|
|
||||||
return w.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *S3) WaitUntilObjectExists(input *HeadObjectInput) error {
|
func (c *S3) WaitUntilObjectExists(input *HeadObjectInput) error {
|
||||||
waiterCfg := waiter.Config{
|
return c.WaitUntilObjectExistsWithContext(aws.BackgroundContext(), input)
|
||||||
Operation: "HeadObject",
|
}
|
||||||
Delay: 5,
|
|
||||||
|
// WaitUntilObjectExistsWithContext is an extended version of WaitUntilObjectExists.
|
||||||
|
// With the support for passing in a context and options to configure the
|
||||||
|
// Waiter and the underlying request options.
|
||||||
|
//
|
||||||
|
// The context must be non-nil and will be used for request cancellation. If
|
||||||
|
// the context is nil a panic will occur. In the future the SDK may create
|
||||||
|
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||||
|
// for more information on using Contexts.
|
||||||
|
func (c *S3) WaitUntilObjectExistsWithContext(ctx aws.Context, input *HeadObjectInput, opts ...request.WaiterOption) error {
|
||||||
|
w := request.Waiter{
|
||||||
|
Name: "WaitUntilObjectExists",
|
||||||
MaxAttempts: 20,
|
MaxAttempts: 20,
|
||||||
Acceptors: []waiter.WaitAcceptor{
|
Delay: request.ConstantWaiterDelay(5 * time.Second),
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
{
|
{
|
||||||
State: "success",
|
State: request.SuccessWaiterState,
|
||||||
Matcher: "status",
|
Matcher: request.StatusWaiterMatch,
|
||||||
Argument: "",
|
|
||||||
Expected: 200,
|
Expected: 200,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
State: "retry",
|
State: request.RetryWaiterState,
|
||||||
Matcher: "status",
|
Matcher: request.StatusWaiterMatch,
|
||||||
Argument: "",
|
|
||||||
Expected: 404,
|
Expected: 404,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Logger: c.Config.Logger,
|
||||||
|
NewRequest: func(opts []request.Option) (*request.Request, error) {
|
||||||
|
var inCpy *HeadObjectInput
|
||||||
|
if input != nil {
|
||||||
|
tmp := *input
|
||||||
|
inCpy = &tmp
|
||||||
|
}
|
||||||
|
req, _ := c.HeadObjectRequest(inCpy)
|
||||||
|
req.SetContext(ctx)
|
||||||
|
req.ApplyOptions(opts...)
|
||||||
|
return req, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
w.ApplyOptions(opts...)
|
||||||
|
|
||||||
|
return w.WaitWithContext(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
w := waiter.Waiter{
|
// WaitUntilObjectNotExists uses the Amazon S3 API operation
|
||||||
Client: c,
|
// HeadObject to wait for a condition to be met before returning.
|
||||||
Input: input,
|
// If the condition is not met within the max attempt window, an error will
|
||||||
Config: waiterCfg,
|
// be returned.
|
||||||
}
|
|
||||||
return w.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *S3) WaitUntilObjectNotExists(input *HeadObjectInput) error {
|
func (c *S3) WaitUntilObjectNotExists(input *HeadObjectInput) error {
|
||||||
waiterCfg := waiter.Config{
|
return c.WaitUntilObjectNotExistsWithContext(aws.BackgroundContext(), input)
|
||||||
Operation: "HeadObject",
|
}
|
||||||
Delay: 5,
|
|
||||||
|
// WaitUntilObjectNotExistsWithContext is an extended version of WaitUntilObjectNotExists.
|
||||||
|
// With the support for passing in a context and options to configure the
|
||||||
|
// Waiter and the underlying request options.
|
||||||
|
//
|
||||||
|
// The context must be non-nil and will be used for request cancellation. If
|
||||||
|
// the context is nil a panic will occur. In the future the SDK may create
|
||||||
|
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
|
||||||
|
// for more information on using Contexts.
|
||||||
|
func (c *S3) WaitUntilObjectNotExistsWithContext(ctx aws.Context, input *HeadObjectInput, opts ...request.WaiterOption) error {
|
||||||
|
w := request.Waiter{
|
||||||
|
Name: "WaitUntilObjectNotExists",
|
||||||
MaxAttempts: 20,
|
MaxAttempts: 20,
|
||||||
Acceptors: []waiter.WaitAcceptor{
|
Delay: request.ConstantWaiterDelay(5 * time.Second),
|
||||||
|
Acceptors: []request.WaiterAcceptor{
|
||||||
{
|
{
|
||||||
State: "success",
|
State: request.SuccessWaiterState,
|
||||||
Matcher: "status",
|
Matcher: request.StatusWaiterMatch,
|
||||||
Argument: "",
|
|
||||||
Expected: 404,
|
Expected: 404,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Logger: c.Config.Logger,
|
||||||
|
NewRequest: func(opts []request.Option) (*request.Request, error) {
|
||||||
|
var inCpy *HeadObjectInput
|
||||||
|
if input != nil {
|
||||||
|
tmp := *input
|
||||||
|
inCpy = &tmp
|
||||||
}
|
}
|
||||||
|
req, _ := c.HeadObjectRequest(inCpy)
|
||||||
|
req.SetContext(ctx)
|
||||||
|
req.ApplyOptions(opts...)
|
||||||
|
return req, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
w.ApplyOptions(opts...)
|
||||||
|
|
||||||
w := waiter.Waiter{
|
return w.WaitWithContext(ctx)
|
||||||
Client: c,
|
|
||||||
Input: input,
|
|
||||||
Config: waiterCfg,
|
|
||||||
}
|
|
||||||
return w.Wait()
|
|
||||||
}
|
}
|
||||||
|
2358
vendor/github.com/aws/aws-sdk-go/service/sts/api.go
generated
vendored
Normal file
2358
vendor/github.com/aws/aws-sdk-go/service/sts/api.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
vendor/github.com/aws/aws-sdk-go/service/sts/customizations.go
generated
vendored
Normal file
12
vendor/github.com/aws/aws-sdk-go/service/sts/customizations.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package sts
|
||||||
|
|
||||||
|
import "github.com/aws/aws-sdk-go/aws/request"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
initRequest = func(r *request.Request) {
|
||||||
|
switch r.Operation.Name {
|
||||||
|
case opAssumeRoleWithSAML, opAssumeRoleWithWebIdentity:
|
||||||
|
r.Handlers.Sign.Clear() // these operations are unsigned
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
72
vendor/github.com/aws/aws-sdk-go/service/sts/doc.go
generated
vendored
Normal file
72
vendor/github.com/aws/aws-sdk-go/service/sts/doc.go
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Package sts provides the client and types for making API
|
||||||
|
// requests to AWS Security Token Service.
|
||||||
|
//
|
||||||
|
// The AWS Security Token Service (STS) is a web service that enables you to
|
||||||
|
// request temporary, limited-privilege credentials for AWS Identity and Access
|
||||||
|
// Management (IAM) users or for users that you authenticate (federated users).
|
||||||
|
// This guide provides descriptions of the STS API. For more detailed information
|
||||||
|
// about using this service, go to Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html).
|
||||||
|
//
|
||||||
|
// As an alternative to using the API, you can use one of the AWS SDKs, which
|
||||||
|
// consist of libraries and sample code for various programming languages and
|
||||||
|
// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient
|
||||||
|
// way to create programmatic access to STS. For example, the SDKs take care
|
||||||
|
// of cryptographically signing requests, managing errors, and retrying requests
|
||||||
|
// automatically. For information about the AWS SDKs, including how to download
|
||||||
|
// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/).
|
||||||
|
//
|
||||||
|
// For information about setting up signatures and authorization through the
|
||||||
|
// API, go to Signing AWS API Requests (http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html)
|
||||||
|
// in the AWS General Reference. For general information about the Query API,
|
||||||
|
// go to Making Query Requests (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html)
|
||||||
|
// in Using IAM. For information about using security tokens with other AWS
|
||||||
|
// products, go to AWS Services That Work with IAM (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html)
|
||||||
|
// in the IAM User Guide.
|
||||||
|
//
|
||||||
|
// If you're new to AWS and need additional technical information about a specific
|
||||||
|
// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/
|
||||||
|
// (http://aws.amazon.com/documentation/).
|
||||||
|
//
|
||||||
|
// Endpoints
|
||||||
|
//
|
||||||
|
// The AWS Security Token Service (STS) has a default endpoint of https://sts.amazonaws.com
|
||||||
|
// that maps to the US East (N. Virginia) region. Additional regions are available
|
||||||
|
// and are activated by default. For more information, see Activating and Deactivating
|
||||||
|
// AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)
|
||||||
|
// in the IAM User Guide.
|
||||||
|
//
|
||||||
|
// For information about STS endpoints, see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region)
|
||||||
|
// in the AWS General Reference.
|
||||||
|
//
|
||||||
|
// Recording API requests
|
||||||
|
//
|
||||||
|
// STS supports AWS CloudTrail, which is a service that records AWS calls for
|
||||||
|
// your AWS account and delivers log files to an Amazon S3 bucket. By using
|
||||||
|
// information collected by CloudTrail, you can determine what requests were
|
||||||
|
// successfully made to STS, who made the request, when it was made, and so
|
||||||
|
// on. To learn more about CloudTrail, including how to turn it on and find
|
||||||
|
// your log files, see the AWS CloudTrail User Guide (http://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html).
|
||||||
|
//
|
||||||
|
// See https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service.
|
||||||
|
//
|
||||||
|
// See sts package documentation for more information.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/
|
||||||
|
//
|
||||||
|
// Using the Client
|
||||||
|
//
|
||||||
|
// To AWS Security Token Service with the SDK use the New function to create
|
||||||
|
// a new service client. With that client you can make API requests to the service.
|
||||||
|
// These clients are safe to use concurrently.
|
||||||
|
//
|
||||||
|
// See the SDK's documentation for more information on how to use the SDK.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||||
|
//
|
||||||
|
// See aws.Config documentation for more information on configuring SDK clients.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||||
|
//
|
||||||
|
// See the AWS Security Token Service client STS for more
|
||||||
|
// information on creating client for this service.
|
||||||
|
// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/#New
|
||||||
|
package sts
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user