Unverified Commit 09784ccf authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #65568 from eisig/aws-sdk

Automatic merge from submit-queue (batch tested with PRs 65357, 65568). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. update aws-sdk to support new region cn-northwest-1 Update aws sdk to support region cn-northwest-1 in China. **What this PR does / why we need it**: need newer aws-sdk version to support new region cn-northwest-1 **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes # **Special notes for your reviewer**: **Release note**: ```release-note NONE ```
parents da64942e 3a19e4cb
...@@ -149,163 +149,178 @@ ...@@ -149,163 +149,178 @@
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws", "ImportPath": "github.com/aws/aws-sdk-go/aws",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/awserr", "ImportPath": "github.com/aws/aws-sdk-go/aws/awserr",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil", "ImportPath": "github.com/aws/aws-sdk-go/aws/awsutil",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/client", "ImportPath": "github.com/aws/aws-sdk-go/aws/client",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata", "ImportPath": "github.com/aws/aws-sdk-go/aws/client/metadata",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers", "ImportPath": "github.com/aws/aws-sdk-go/aws/corehandlers",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials", "ImportPath": "github.com/aws/aws-sdk-go/aws/credentials",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds", "ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds", "ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/stscreds", "ImportPath": "github.com/aws/aws-sdk-go/aws/credentials/stscreds",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/aws/csm",
"Comment": "v1.14.12",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/defaults", "ImportPath": "github.com/aws/aws-sdk-go/aws/defaults",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata", "ImportPath": "github.com/aws/aws-sdk-go/aws/ec2metadata",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/endpoints", "ImportPath": "github.com/aws/aws-sdk-go/aws/endpoints",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/request", "ImportPath": "github.com/aws/aws-sdk-go/aws/request",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/session", "ImportPath": "github.com/aws/aws-sdk-go/aws/session",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/aws/signer/v4", "ImportPath": "github.com/aws/aws-sdk-go/aws/signer/v4",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/internal/sdkio",
"Comment": "v1.14.12",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
},
{
"ImportPath": "github.com/aws/aws-sdk-go/internal/sdkrand",
"Comment": "v1.14.12",
"Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/internal/shareddefaults", "ImportPath": "github.com/aws/aws-sdk-go/internal/shareddefaults",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/ec2query", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/ec2query",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/jsonrpc",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/query/queryutil",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/rest",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil", "ImportPath": "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling", "ImportPath": "github.com/aws/aws-sdk-go/service/autoscaling",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/ec2", "ImportPath": "github.com/aws/aws-sdk-go/service/ec2",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/ecr", "ImportPath": "github.com/aws/aws-sdk-go/service/ecr",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/elb", "ImportPath": "github.com/aws/aws-sdk-go/service/elb",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/elbv2", "ImportPath": "github.com/aws/aws-sdk-go/service/elbv2",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/kms", "ImportPath": "github.com/aws/aws-sdk-go/service/kms",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/aws/aws-sdk-go/service/sts", "ImportPath": "github.com/aws/aws-sdk-go/service/sts",
"Comment": "v1.12.7", "Comment": "v1.14.12",
"Rev": "760741802ad40f49ae9fc4a69ef6706d2527d62e" "Rev": "fde4ded7becdeae4d26bf1212916aabba79349b4"
}, },
{ {
"ImportPath": "github.com/bazelbuild/bazel-gazelle/cmd/gazelle", "ImportPath": "github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
......
...@@ -35,6 +35,8 @@ filegroup( ...@@ -35,6 +35,8 @@ filegroup(
"//vendor/github.com/armon/circbuf:all-srcs", "//vendor/github.com/armon/circbuf:all-srcs",
"//vendor/github.com/asaskevich/govalidator:all-srcs", "//vendor/github.com/asaskevich/govalidator:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/aws:all-srcs", "//vendor/github.com/aws/aws-sdk-go/aws:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/internal/sdkio:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/internal/sdkrand:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/internal/shareddefaults:all-srcs", "//vendor/github.com/aws/aws-sdk-go/internal/shareddefaults:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/private/protocol:all-srcs", "//vendor/github.com/aws/aws-sdk-go/private/protocol:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/service/autoscaling:all-srcs", "//vendor/github.com/aws/aws-sdk-go/service/autoscaling:all-srcs",
......
...@@ -24,6 +24,7 @@ go_library( ...@@ -24,6 +24,7 @@ go_library(
"//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/credentials:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/credentials:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/endpoints:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/endpoints:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/internal/sdkio:go_default_library",
], ],
) )
...@@ -43,6 +44,7 @@ filegroup( ...@@ -43,6 +44,7 @@ filegroup(
"//vendor/github.com/aws/aws-sdk-go/aws/client:all-srcs", "//vendor/github.com/aws/aws-sdk-go/aws/client:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/aws/corehandlers:all-srcs", "//vendor/github.com/aws/aws-sdk-go/aws/corehandlers:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/aws/credentials:all-srcs", "//vendor/github.com/aws/aws-sdk-go/aws/credentials:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/aws/csm:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/aws/defaults:all-srcs", "//vendor/github.com/aws/aws-sdk-go/aws/defaults:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/aws/ec2metadata:all-srcs", "//vendor/github.com/aws/aws-sdk-go/aws/ec2metadata:all-srcs",
"//vendor/github.com/aws/aws-sdk-go/aws/endpoints:all-srcs", "//vendor/github.com/aws/aws-sdk-go/aws/endpoints:all-srcs",
......
...@@ -14,6 +14,7 @@ go_library( ...@@ -14,6 +14,7 @@ go_library(
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/client/metadata:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/client/metadata:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/internal/sdkrand:go_default_library",
], ],
) )
......
...@@ -15,6 +15,12 @@ type Config struct { ...@@ -15,6 +15,12 @@ type Config struct {
Endpoint string Endpoint string
SigningRegion string SigningRegion string
SigningName string SigningName string
// States that the signing name did not come from a modeled source but
// was derived based on other data. Used by service client constructors
// to determine if the signin name can be overriden based on metadata the
// service has.
SigningNameDerived bool
} }
// ConfigProvider provides a generic way for a service client to receive // ConfigProvider provides a generic way for a service client to receive
...@@ -85,6 +91,6 @@ func (c *Client) AddDebugHandlers() { ...@@ -85,6 +91,6 @@ func (c *Client) AddDebugHandlers() {
return return
} }
c.Handlers.Send.PushFrontNamed(request.NamedHandler{Name: "awssdk.client.LogRequest", Fn: logRequest}) c.Handlers.Send.PushFrontNamed(LogHTTPRequestHandler)
c.Handlers.Send.PushBackNamed(request.NamedHandler{Name: "awssdk.client.LogResponse", Fn: logResponse}) c.Handlers.Send.PushBackNamed(LogHTTPResponseHandler)
} }
package client package client
import ( import (
"math/rand" "strconv"
"sync"
"time" "time"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/sdkrand"
) )
// DefaultRetryer implements basic retry logic using exponential backoff for // DefaultRetryer implements basic retry logic using exponential backoff for
...@@ -30,25 +30,27 @@ func (d DefaultRetryer) MaxRetries() int { ...@@ -30,25 +30,27 @@ 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 {
// Set the upper limit of delay in retrying at ~five minutes // Set the upper limit of delay in retrying at ~five minutes
minTime := 30 minTime := 30
throttle := d.shouldThrottle(r) throttle := d.shouldThrottle(r)
if throttle { if throttle {
if delay, ok := getRetryDelay(r); ok {
return delay
}
minTime = 500 minTime = 500
} }
retryCount := r.RetryCount retryCount := r.RetryCount
if retryCount > 13 { if throttle && retryCount > 8 {
retryCount = 13
} else if throttle && retryCount > 8 {
retryCount = 8 retryCount = 8
} else if retryCount > 13 {
retryCount = 13
} }
delay := (1 << uint(retryCount)) * (seededRand.Intn(minTime) + minTime) delay := (1 << uint(retryCount)) * (sdkrand.SeededRand.Intn(minTime) + minTime)
return time.Duration(delay) * time.Millisecond return time.Duration(delay) * time.Millisecond
} }
...@@ -60,7 +62,7 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { ...@@ -60,7 +62,7 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
return *r.Retryable return *r.Retryable
} }
if r.HTTPResponse.StatusCode >= 500 { if r.HTTPResponse.StatusCode >= 500 && r.HTTPResponse.StatusCode != 501 {
return true return true
} }
return r.IsErrorRetryable() || d.shouldThrottle(r) return r.IsErrorRetryable() || d.shouldThrottle(r)
...@@ -68,29 +70,47 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { ...@@ -68,29 +70,47 @@ func (d DefaultRetryer) ShouldRetry(r *request.Request) bool {
// ShouldThrottle returns true if the request should be throttled. // ShouldThrottle returns true if the request should be throttled.
func (d DefaultRetryer) shouldThrottle(r *request.Request) bool { func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
if r.HTTPResponse.StatusCode == 502 || switch r.HTTPResponse.StatusCode {
r.HTTPResponse.StatusCode == 503 || case 429:
r.HTTPResponse.StatusCode == 504 { case 502:
return true case 503:
} case 504:
default:
return r.IsErrorThrottle() return r.IsErrorThrottle()
} }
// lockedSource is a thread-safe implementation of rand.Source return true
type lockedSource struct {
lk sync.Mutex
src rand.Source
} }
func (r *lockedSource) Int63() (n int64) { // This will look in the Retry-After header, RFC 7231, for how long
r.lk.Lock() // it will wait before attempting another request
n = r.src.Int63() func getRetryDelay(r *request.Request) (time.Duration, bool) {
r.lk.Unlock() if !canUseRetryAfterHeader(r) {
return return 0, false
}
delayStr := r.HTTPResponse.Header.Get("Retry-After")
if len(delayStr) == 0 {
return 0, false
}
delay, err := strconv.Atoi(delayStr)
if err != nil {
return 0, false
}
return time.Duration(delay) * time.Second, true
} }
func (r *lockedSource) Seed(seed int64) { // Will look at the status code to see if the retry header pertains to
r.lk.Lock() // the status code.
r.src.Seed(seed) func canUseRetryAfterHeader(r *request.Request) bool {
r.lk.Unlock() switch r.HTTPResponse.StatusCode {
case 429:
case 503:
default:
return false
}
return true
} }
...@@ -44,22 +44,57 @@ func (reader *teeReaderCloser) Close() error { ...@@ -44,22 +44,57 @@ func (reader *teeReaderCloser) Close() error {
return reader.Source.Close() return reader.Source.Close()
} }
// LogHTTPRequestHandler is a SDK request handler to log the HTTP request sent
// to a service. Will include the HTTP request body if the LogLevel of the
// request matches LogDebugWithHTTPBody.
var LogHTTPRequestHandler = request.NamedHandler{
Name: "awssdk.client.LogRequest",
Fn: logRequest,
}
func logRequest(r *request.Request) { func logRequest(r *request.Request) {
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody) bodySeekable := aws.IsReaderSeekable(r.Body)
b, err := httputil.DumpRequestOut(r.HTTPRequest, logBody)
if err != nil { if err != nil {
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
r.ClientInfo.ServiceName, r.Operation.Name, err))
return return
} }
if logBody { if logBody {
if !bodySeekable {
r.SetReaderBody(aws.ReadSeekCloser(r.HTTPRequest.Body))
}
// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's // Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
// Body as a NoOpCloser and will not be reset after read by the HTTP // Body as a NoOpCloser and will not be reset after read by the HTTP
// client reader. // client reader.
r.ResetBody() r.ResetBody()
} }
r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody))) r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
}
// LogHTTPRequestHeaderHandler is a SDK request handler to log the HTTP request sent
// to a service. Will only log the HTTP request's headers. The request payload
// will not be read.
var LogHTTPRequestHeaderHandler = request.NamedHandler{
Name: "awssdk.client.LogRequestHeader",
Fn: logRequestHeader,
}
func logRequestHeader(r *request.Request) {
b, err := httputil.DumpRequestOut(r.HTTPRequest, false)
if err != nil {
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
r.ClientInfo.ServiceName, r.Operation.Name, err))
return
}
r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
} }
const logRespMsg = `DEBUG: Response %s/%s Details: const logRespMsg = `DEBUG: Response %s/%s Details:
...@@ -72,27 +107,44 @@ const logRespErrMsg = `DEBUG ERROR: Response %s/%s: ...@@ -72,27 +107,44 @@ const logRespErrMsg = `DEBUG ERROR: Response %s/%s:
%s %s
-----------------------------------------------------` -----------------------------------------------------`
// LogHTTPResponseHandler is a SDK request handler to log the HTTP response
// received from a service. Will include the HTTP response body if the LogLevel
// of the request matches LogDebugWithHTTPBody.
var LogHTTPResponseHandler = request.NamedHandler{
Name: "awssdk.client.LogResponse",
Fn: logResponse,
}
func logResponse(r *request.Request) { func logResponse(r *request.Request) {
lw := &logWriter{r.Config.Logger, bytes.NewBuffer(nil)} lw := &logWriter{r.Config.Logger, bytes.NewBuffer(nil)}
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
if logBody {
r.HTTPResponse.Body = &teeReaderCloser{ r.HTTPResponse.Body = &teeReaderCloser{
Reader: io.TeeReader(r.HTTPResponse.Body, lw), Reader: io.TeeReader(r.HTTPResponse.Body, lw),
Source: r.HTTPResponse.Body, Source: r.HTTPResponse.Body,
} }
}
handlerFn := func(req *request.Request) { handlerFn := func(req *request.Request) {
body, err := httputil.DumpResponse(req.HTTPResponse, false) b, err := httputil.DumpResponse(req.HTTPResponse, false)
if err != nil { if err != nil {
lw.Logger.Log(fmt.Sprintf(logRespErrMsg, req.ClientInfo.ServiceName, req.Operation.Name, err)) lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
req.ClientInfo.ServiceName, req.Operation.Name, err))
return return
} }
lw.Logger.Log(fmt.Sprintf(logRespMsg,
req.ClientInfo.ServiceName, req.Operation.Name, string(b)))
if logBody {
b, err := ioutil.ReadAll(lw.buf) b, err := ioutil.ReadAll(lw.buf)
if err != nil { if err != nil {
lw.Logger.Log(fmt.Sprintf(logRespErrMsg, req.ClientInfo.ServiceName, req.Operation.Name, err)) lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
req.ClientInfo.ServiceName, req.Operation.Name, err))
return 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)) lw.Logger.Log(string(b))
} }
} }
...@@ -106,3 +158,27 @@ func logResponse(r *request.Request) { ...@@ -106,3 +158,27 @@ func logResponse(r *request.Request) {
Name: handlerName, Fn: handlerFn, Name: handlerName, Fn: handlerFn,
}) })
} }
// LogHTTPResponseHeaderHandler is a SDK request handler to log the HTTP
// response received from a service. Will only log the HTTP response's headers.
// The response payload will not be read.
var LogHTTPResponseHeaderHandler = request.NamedHandler{
Name: "awssdk.client.LogResponseHeader",
Fn: logResponseHeader,
}
func logResponseHeader(r *request.Request) {
if r.Config.Logger == nil {
return
}
b, err := httputil.DumpResponse(r.HTTPResponse, false)
if err != nil {
r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg,
r.ClientInfo.ServiceName, r.Operation.Name, err))
return
}
r.Config.Logger.Log(fmt.Sprintf(logRespMsg,
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
}
...@@ -3,6 +3,7 @@ package metadata ...@@ -3,6 +3,7 @@ package metadata
// ClientInfo wraps immutable data from the client.Client structure. // ClientInfo wraps immutable data from the client.Client structure.
type ClientInfo struct { type ClientInfo struct {
ServiceName string ServiceName string
ServiceID string
APIVersion string APIVersion string
Endpoint string Endpoint string
SigningName string SigningName string
......
...@@ -151,6 +151,15 @@ type Config struct { ...@@ -151,6 +151,15 @@ type Config struct {
// with accelerate. // with accelerate.
S3UseAccelerate *bool S3UseAccelerate *bool
// S3DisableContentMD5Validation config option is temporarily disabled,
// For S3 GetObject API calls, #1837.
//
// Set this to `true` to disable the S3 service client from automatically
// adding the ContentMD5 to S3 Object Put and Upload API calls. This option
// will also disable the SDK from performing object ContentMD5 validation
// on GetObject API calls.
S3DisableContentMD5Validation *bool
// Set this to `true` to disable the EC2Metadata client from overriding the // 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 // 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 // EC2Metadata client to create a new http.Client. This options is only
...@@ -168,7 +177,7 @@ type Config struct { ...@@ -168,7 +177,7 @@ type Config struct {
// //
EC2MetadataDisableTimeoutOverride *bool EC2MetadataDisableTimeoutOverride *bool
// Instructs the endpiont to be generated for a service client to // Instructs the endpoint to be generated for a service client to
// be the dual stack endpoint. The dual stack endpoint will support // be the dual stack endpoint. The dual stack endpoint will support
// both IPv4 and IPv6 addressing. // both IPv4 and IPv6 addressing.
// //
...@@ -336,6 +345,15 @@ func (c *Config) WithS3Disable100Continue(disable bool) *Config { ...@@ -336,6 +345,15 @@ func (c *Config) WithS3Disable100Continue(disable bool) *Config {
func (c *Config) WithS3UseAccelerate(enable bool) *Config { func (c *Config) WithS3UseAccelerate(enable bool) *Config {
c.S3UseAccelerate = &enable c.S3UseAccelerate = &enable
return c return c
}
// WithS3DisableContentMD5Validation sets a config
// S3DisableContentMD5Validation value returning a Config pointer for chaining.
func (c *Config) WithS3DisableContentMD5Validation(enable bool) *Config {
c.S3DisableContentMD5Validation = &enable
return c
} }
// WithUseDualStack sets a config UseDualStack value returning a Config // WithUseDualStack sets a config UseDualStack value returning a Config
...@@ -435,6 +453,10 @@ func mergeInConfig(dst *Config, other *Config) { ...@@ -435,6 +453,10 @@ func mergeInConfig(dst *Config, other *Config) {
dst.S3UseAccelerate = other.S3UseAccelerate dst.S3UseAccelerate = other.S3UseAccelerate
} }
if other.S3DisableContentMD5Validation != nil {
dst.S3DisableContentMD5Validation = other.S3DisableContentMD5Validation
}
if other.UseDualStack != nil { if other.UseDualStack != nil {
dst.UseDualStack = other.UseDualStack dst.UseDualStack = other.UseDualStack
} }
......
...@@ -5,6 +5,7 @@ go_library( ...@@ -5,6 +5,7 @@ go_library(
srcs = [ srcs = [
"handlers.go", "handlers.go",
"param_validator.go", "param_validator.go",
"user_agent.go",
], ],
importmap = "k8s.io/kubernetes/vendor/github.com/aws/aws-sdk-go/aws/corehandlers", importmap = "k8s.io/kubernetes/vendor/github.com/aws/aws-sdk-go/aws/corehandlers",
importpath = "github.com/aws/aws-sdk-go/aws/corehandlers", importpath = "github.com/aws/aws-sdk-go/aws/corehandlers",
......
...@@ -3,12 +3,10 @@ package corehandlers ...@@ -3,12 +3,10 @@ package corehandlers
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"regexp" "regexp"
"runtime"
"strconv" "strconv"
"time" "time"
...@@ -36,18 +34,13 @@ var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLen ...@@ -36,18 +34,13 @@ var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLen
if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" { if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
length, _ = strconv.ParseInt(slength, 10, 64) length, _ = strconv.ParseInt(slength, 10, 64)
} else { } else {
switch body := r.Body.(type) { if r.Body != nil {
case nil: var err error
length = 0 length, err = aws.SeekerLen(r.Body)
case lener: if err != nil {
length = int64(body.Len()) r.Error = awserr.New(request.ErrCodeSerialization, "failed to get request body's length", err)
case io.Seeker: return
r.BodyStart, _ = body.Seek(0, 1) }
end, _ := body.Seek(0, 2)
body.Seek(r.BodyStart, 0) // make sure to seek back to original location
length = end - r.BodyStart
default:
panic("Cannot get length of body, must provide `ContentLength`")
} }
} }
...@@ -60,13 +53,6 @@ var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLen ...@@ -60,13 +53,6 @@ var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLen
} }
}} }}
// SDKVersionUserAgentHandler is a request handler for adding the SDK Version to the user agent.
var SDKVersionUserAgentHandler = request.NamedHandler{
Name: "core.SDKVersionUserAgentHandler",
Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion,
runtime.Version(), runtime.GOOS, runtime.GOARCH),
}
var reStatusCode = regexp.MustCompile(`^(\d{3})`) var reStatusCode = regexp.MustCompile(`^(\d{3})`)
// ValidateReqSigHandler is a request handler to ensure that the request's // ValidateReqSigHandler is a request handler to ensure that the request's
......
package corehandlers
import (
"os"
"runtime"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
)
// SDKVersionUserAgentHandler is a request handler for adding the SDK Version
// to the user agent.
var SDKVersionUserAgentHandler = request.NamedHandler{
Name: "core.SDKVersionUserAgentHandler",
Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion,
runtime.Version(), runtime.GOOS, runtime.GOARCH),
}
const execEnvVar = `AWS_EXECUTION_ENV`
const execEnvUAKey = `exec_env`
// AddHostExecEnvUserAgentHander is a request handler appending the SDK's
// execution environment to the user agent.
//
// If the environment variable AWS_EXECUTION_ENV is set, its value will be
// appended to the user agent string.
var AddHostExecEnvUserAgentHander = request.NamedHandler{
Name: "core.AddHostExecEnvUserAgentHander",
Fn: func(r *request.Request) {
v := os.Getenv(execEnvVar)
if len(v) == 0 {
return
}
request.AddToUserAgent(r, execEnvUAKey+"/"+v)
},
}
...@@ -178,7 +178,8 @@ func (e *Expiry) IsExpired() bool { ...@@ -178,7 +178,8 @@ func (e *Expiry) IsExpired() bool {
type Credentials struct { type Credentials struct {
creds Value creds Value
forceRefresh bool forceRefresh bool
m sync.Mutex
m sync.RWMutex
provider Provider provider Provider
} }
...@@ -201,6 +202,17 @@ func NewCredentials(provider Provider) *Credentials { ...@@ -201,6 +202,17 @@ func NewCredentials(provider Provider) *Credentials {
// If Credentials.Expire() was called the credentials Value will be force // If Credentials.Expire() was called the credentials Value will be force
// expired, and the next call to Get() will cause them to be refreshed. // expired, and the next call to Get() will cause them to be refreshed.
func (c *Credentials) Get() (Value, error) { func (c *Credentials) Get() (Value, error) {
// Check the cached credentials first with just the read lock.
c.m.RLock()
if !c.isExpired() {
creds := c.creds
c.m.RUnlock()
return creds, nil
}
c.m.RUnlock()
// Credentials are expired need to retrieve the credentials taking the full
// lock.
c.m.Lock() c.m.Lock()
defer c.m.Unlock() defer c.m.Unlock()
...@@ -234,8 +246,8 @@ func (c *Credentials) Expire() { ...@@ -234,8 +246,8 @@ func (c *Credentials) Expire() {
// If the Credentials were forced to be expired with Expire() this will // If the Credentials were forced to be expired with Expire() this will
// reflect that override. // reflect that override.
func (c *Credentials) IsExpired() bool { func (c *Credentials) IsExpired() bool {
c.m.Lock() c.m.RLock()
defer c.m.Unlock() defer c.m.RUnlock()
return c.isExpired() return c.isExpired()
} }
......
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"enable.go",
"metric.go",
"metricChan.go",
"reporter.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/aws/aws-sdk-go/aws/csm",
importpath = "github.com/aws/aws-sdk-go/aws/csm",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
// Package csm provides Client Side Monitoring (CSM) which enables sending metrics
// via UDP connection. Using the Start function will enable the reporting of
// metrics on a given port. If Start is called, with different parameters, again,
// a panic will occur.
//
// Pause can be called to pause any metrics publishing on a given port. Sessions
// that have had their handlers modified via InjectHandlers may still be used.
// However, the handlers will act as a no-op meaning no metrics will be published.
//
// Example:
// r, err := csm.Start("clientID", ":31000")
// if err != nil {
// panic(fmt.Errorf("failed starting CSM: %v", err))
// }
//
// sess, err := session.NewSession(&aws.Config{})
// if err != nil {
// panic(fmt.Errorf("failed loading session: %v", err))
// }
//
// r.InjectHandlers(&sess.Handlers)
//
// client := s3.New(sess)
// resp, err := client.GetObject(&s3.GetObjectInput{
// Bucket: aws.String("bucket"),
// Key: aws.String("key"),
// })
//
// // Will pause monitoring
// r.Pause()
// resp, err = client.GetObject(&s3.GetObjectInput{
// Bucket: aws.String("bucket"),
// Key: aws.String("key"),
// })
//
// // Resume monitoring
// r.Continue()
//
// Start returns a Reporter that is used to enable or disable monitoring. If
// access to the Reporter is required later, calling Get will return the Reporter
// singleton.
//
// Example:
// r := csm.Get()
// r.Continue()
package csm
package csm
import (
"fmt"
"sync"
)
var (
lock sync.Mutex
)
// Client side metric handler names
const (
APICallMetricHandlerName = "awscsm.SendAPICallMetric"
APICallAttemptMetricHandlerName = "awscsm.SendAPICallAttemptMetric"
)
// Start will start the a long running go routine to capture
// client side metrics. Calling start multiple time will only
// start the metric listener once and will panic if a different
// client ID or port is passed in.
//
// Example:
// r, err := csm.Start("clientID", "127.0.0.1:8094")
// if err != nil {
// panic(fmt.Errorf("expected no error, but received %v", err))
// }
// sess := session.NewSession()
// r.InjectHandlers(sess.Handlers)
//
// svc := s3.New(sess)
// out, err := svc.GetObject(&s3.GetObjectInput{
// Bucket: aws.String("bucket"),
// Key: aws.String("key"),
// })
func Start(clientID string, url string) (*Reporter, error) {
lock.Lock()
defer lock.Unlock()
if sender == nil {
sender = newReporter(clientID, url)
} else {
if sender.clientID != clientID {
panic(fmt.Errorf("inconsistent client IDs. %q was expected, but received %q", sender.clientID, clientID))
}
if sender.url != url {
panic(fmt.Errorf("inconsistent URLs. %q was expected, but received %q", sender.url, url))
}
}
if err := connect(url); err != nil {
sender = nil
return nil, err
}
return sender, nil
}
// Get will return a reporter if one exists, if one does not exist, nil will
// be returned.
func Get() *Reporter {
lock.Lock()
defer lock.Unlock()
return sender
}
package csm
import (
"strconv"
"time"
)
type metricTime time.Time
func (t metricTime) MarshalJSON() ([]byte, error) {
ns := time.Duration(time.Time(t).UnixNano())
return []byte(strconv.FormatInt(int64(ns/time.Millisecond), 10)), nil
}
type metric struct {
ClientID *string `json:"ClientId,omitempty"`
API *string `json:"Api,omitempty"`
Service *string `json:"Service,omitempty"`
Timestamp *metricTime `json:"Timestamp,omitempty"`
Type *string `json:"Type,omitempty"`
Version *int `json:"Version,omitempty"`
AttemptCount *int `json:"AttemptCount,omitempty"`
Latency *int `json:"Latency,omitempty"`
Fqdn *string `json:"Fqdn,omitempty"`
UserAgent *string `json:"UserAgent,omitempty"`
AttemptLatency *int `json:"AttemptLatency,omitempty"`
SessionToken *string `json:"SessionToken,omitempty"`
Region *string `json:"Region,omitempty"`
AccessKey *string `json:"AccessKey,omitempty"`
HTTPStatusCode *int `json:"HttpStatusCode,omitempty"`
XAmzID2 *string `json:"XAmzId2,omitempty"`
XAmzRequestID *string `json:"XAmznRequestId,omitempty"`
AWSException *string `json:"AwsException,omitempty"`
AWSExceptionMessage *string `json:"AwsExceptionMessage,omitempty"`
SDKException *string `json:"SdkException,omitempty"`
SDKExceptionMessage *string `json:"SdkExceptionMessage,omitempty"`
DestinationIP *string `json:"DestinationIp,omitempty"`
ConnectionReused *int `json:"ConnectionReused,omitempty"`
AcquireConnectionLatency *int `json:"AcquireConnectionLatency,omitempty"`
ConnectLatency *int `json:"ConnectLatency,omitempty"`
RequestLatency *int `json:"RequestLatency,omitempty"`
DNSLatency *int `json:"DnsLatency,omitempty"`
TCPLatency *int `json:"TcpLatency,omitempty"`
SSLLatency *int `json:"SslLatency,omitempty"`
}
package csm
import (
"sync/atomic"
)
const (
runningEnum = iota
pausedEnum
)
var (
// MetricsChannelSize of metrics to hold in the channel
MetricsChannelSize = 100
)
type metricChan struct {
ch chan metric
paused int64
}
func newMetricChan(size int) metricChan {
return metricChan{
ch: make(chan metric, size),
}
}
func (ch *metricChan) Pause() {
atomic.StoreInt64(&ch.paused, pausedEnum)
}
func (ch *metricChan) Continue() {
atomic.StoreInt64(&ch.paused, runningEnum)
}
func (ch *metricChan) IsPaused() bool {
v := atomic.LoadInt64(&ch.paused)
return v == pausedEnum
}
// Push will push metrics to the metric channel if the channel
// is not paused
func (ch *metricChan) Push(m metric) bool {
if ch.IsPaused() {
return false
}
select {
case ch.ch <- m:
return true
default:
return false
}
}
package csm
import (
"encoding/json"
"net"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
)
const (
// DefaultPort is used when no port is specified
DefaultPort = "31000"
)
// Reporter will gather metrics of API requests made and
// send those metrics to the CSM endpoint.
type Reporter struct {
clientID string
url string
conn net.Conn
metricsCh metricChan
done chan struct{}
}
var (
sender *Reporter
)
func connect(url string) error {
const network = "udp"
if err := sender.connect(network, url); err != nil {
return err
}
if sender.done == nil {
sender.done = make(chan struct{})
go sender.start()
}
return nil
}
func newReporter(clientID, url string) *Reporter {
return &Reporter{
clientID: clientID,
url: url,
metricsCh: newMetricChan(MetricsChannelSize),
}
}
func (rep *Reporter) sendAPICallAttemptMetric(r *request.Request) {
if rep == nil {
return
}
now := time.Now()
creds, _ := r.Config.Credentials.Get()
m := metric{
ClientID: aws.String(rep.clientID),
API: aws.String(r.Operation.Name),
Service: aws.String(r.ClientInfo.ServiceID),
Timestamp: (*metricTime)(&now),
UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")),
Region: r.Config.Region,
Type: aws.String("ApiCallAttempt"),
Version: aws.Int(1),
XAmzRequestID: aws.String(r.RequestID),
AttemptCount: aws.Int(r.RetryCount + 1),
AttemptLatency: aws.Int(int(now.Sub(r.AttemptTime).Nanoseconds() / int64(time.Millisecond))),
AccessKey: aws.String(creds.AccessKeyID),
}
if r.HTTPResponse != nil {
m.HTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode)
}
if r.Error != nil {
if awserr, ok := r.Error.(awserr.Error); ok {
setError(&m, awserr)
}
}
rep.metricsCh.Push(m)
}
func setError(m *metric, err awserr.Error) {
msg := err.Message()
code := err.Code()
switch code {
case "RequestError",
"SerializationError",
request.CanceledErrorCode:
m.SDKException = &code
m.SDKExceptionMessage = &msg
default:
m.AWSException = &code
m.AWSExceptionMessage = &msg
}
}
func (rep *Reporter) sendAPICallMetric(r *request.Request) {
if rep == nil {
return
}
now := time.Now()
m := metric{
ClientID: aws.String(rep.clientID),
API: aws.String(r.Operation.Name),
Service: aws.String(r.ClientInfo.ServiceID),
Timestamp: (*metricTime)(&now),
Type: aws.String("ApiCall"),
AttemptCount: aws.Int(r.RetryCount + 1),
Latency: aws.Int(int(time.Now().Sub(r.Time) / time.Millisecond)),
XAmzRequestID: aws.String(r.RequestID),
}
// TODO: Probably want to figure something out for logging dropped
// metrics
rep.metricsCh.Push(m)
}
func (rep *Reporter) connect(network, url string) error {
if rep.conn != nil {
rep.conn.Close()
}
conn, err := net.Dial(network, url)
if err != nil {
return awserr.New("UDPError", "Could not connect", err)
}
rep.conn = conn
return nil
}
func (rep *Reporter) close() {
if rep.done != nil {
close(rep.done)
}
rep.metricsCh.Pause()
}
func (rep *Reporter) start() {
defer func() {
rep.metricsCh.Pause()
}()
for {
select {
case <-rep.done:
rep.done = nil
return
case m := <-rep.metricsCh.ch:
// TODO: What to do with this error? Probably should just log
b, err := json.Marshal(m)
if err != nil {
continue
}
rep.conn.Write(b)
}
}
}
// Pause will pause the metric channel preventing any new metrics from
// being added.
func (rep *Reporter) Pause() {
lock.Lock()
defer lock.Unlock()
if rep == nil {
return
}
rep.close()
}
// Continue will reopen the metric channel and allow for monitoring
// to be resumed.
func (rep *Reporter) Continue() {
lock.Lock()
defer lock.Unlock()
if rep == nil {
return
}
if !rep.metricsCh.IsPaused() {
return
}
rep.metricsCh.Continue()
}
// InjectHandlers will will enable client side metrics and inject the proper
// handlers to handle how metrics are sent.
//
// Example:
// // Start must be called in order to inject the correct handlers
// r, err := csm.Start("clientID", "127.0.0.1:8094")
// if err != nil {
// panic(fmt.Errorf("expected no error, but received %v", err))
// }
//
// sess := session.NewSession()
// r.InjectHandlers(&sess.Handlers)
//
// // create a new service client with our client side metric session
// svc := s3.New(sess)
func (rep *Reporter) InjectHandlers(handlers *request.Handlers) {
if rep == nil {
return
}
apiCallHandler := request.NamedHandler{Name: APICallMetricHandlerName, Fn: rep.sendAPICallMetric}
handlers.Complete.PushFrontNamed(apiCallHandler)
apiCallAttemptHandler := request.NamedHandler{Name: APICallAttemptMetricHandlerName, Fn: rep.sendAPICallAttemptMetric}
handlers.AfterRetry.PushFrontNamed(apiCallAttemptHandler)
}
...@@ -9,6 +9,7 @@ package defaults ...@@ -9,6 +9,7 @@ package defaults
import ( import (
"fmt" "fmt"
"net"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
...@@ -72,6 +73,7 @@ func Handlers() request.Handlers { ...@@ -72,6 +73,7 @@ func Handlers() request.Handlers {
handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler) handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
handlers.Validate.AfterEachFn = request.HandlerListStopOnError handlers.Validate.AfterEachFn = request.HandlerListStopOnError
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler) handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHander)
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.ValidateReqSigHandler)
...@@ -118,14 +120,43 @@ func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.P ...@@ -118,14 +120,43 @@ func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.P
return ec2RoleProvider(cfg, handlers) return ec2RoleProvider(cfg, handlers)
} }
var lookupHostFn = net.LookupHost
func isLoopbackHost(host string) (bool, error) {
ip := net.ParseIP(host)
if ip != nil {
return ip.IsLoopback(), nil
}
// Host is not an ip, perform lookup
addrs, err := lookupHostFn(host)
if err != nil {
return false, err
}
for _, addr := range addrs {
if !net.ParseIP(addr).IsLoopback() {
return false, nil
}
}
return true, nil
}
func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
var errMsg string var errMsg string
parsed, err := url.Parse(u) parsed, err := url.Parse(u)
if err != nil { if err != nil {
errMsg = fmt.Sprintf("invalid URL, %v", err) errMsg = fmt.Sprintf("invalid URL, %v", err)
} else if host := aws.URLHostname(parsed); !(host == "localhost" || host == "127.0.0.1") { } else {
errMsg = fmt.Sprintf("invalid host address, %q, only localhost and 127.0.0.1 are valid.", host) host := aws.URLHostname(parsed)
if len(host) == 0 {
errMsg = "unable to parse host from local HTTP cred provider URL"
} else if isLoopback, loopbackErr := isLoopbackHost(host); loopbackErr != nil {
errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, loopbackErr)
} else if !isLoopback {
errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback hosts are allowed.", host)
}
} }
if len(errMsg) > 0 { if len(errMsg) > 0 {
......
...@@ -14,6 +14,7 @@ go_library( ...@@ -14,6 +14,7 @@ go_library(
"//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/client:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/client:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/client/metadata:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/client/metadata:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/corehandlers:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library",
], ],
) )
......
// Package ec2metadata provides the client for making API calls to the // Package ec2metadata provides the client for making API calls to the
// EC2 Metadata service. // EC2 Metadata service.
//
// This package's client can be disabled completely by setting the environment
// variable "AWS_EC2_METADATA_DISABLED=true". This environment variable set to
// true instructs the SDK to disable the EC2 Metadata client. The client cannot
// be used while the environemnt variable is set to true, (case insensitive).
package ec2metadata package ec2metadata
import ( import (
...@@ -7,17 +12,21 @@ import ( ...@@ -7,17 +12,21 @@ import (
"errors" "errors"
"io" "io"
"net/http" "net/http"
"os"
"strings"
"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/awserr"
"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/corehandlers"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
) )
// ServiceName is the name of the service. // ServiceName is the name of the service.
const ServiceName = "ec2metadata" const ServiceName = "ec2metadata"
const disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED"
// A EC2Metadata is an EC2 Metadata service Client. // A EC2Metadata is an EC2 Metadata service Client.
type EC2Metadata struct { type EC2Metadata struct {
...@@ -75,6 +84,21 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -75,6 +84,21 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
svc.Handlers.Validate.Clear() svc.Handlers.Validate.Clear()
svc.Handlers.Validate.PushBack(validateEndpointHandler) svc.Handlers.Validate.PushBack(validateEndpointHandler)
// Disable the EC2 Metadata service if the environment variable is set.
// This shortcirctes the service's functionality to always fail to send
// requests.
if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" {
svc.Handlers.Send.SwapNamed(request.NamedHandler{
Name: corehandlers.SendHandler.Name,
Fn: func(r *request.Request) {
r.Error = awserr.New(
request.CanceledErrorCode,
"EC2 IMDS access disabled via "+disableServiceEnvVar+" env var",
nil)
},
})
}
// Add additional options to the service config // Add additional options to the service config
for _, option := range opts { for _, option := range opts {
option(svc.Client) option(svc.Client)
......
...@@ -206,9 +206,10 @@ func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) ( ...@@ -206,9 +206,10 @@ func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (
// enumerating over the regions in a partition. // enumerating over the regions in a partition.
func (p Partition) Regions() map[string]Region { func (p Partition) Regions() map[string]Region {
rs := map[string]Region{} rs := map[string]Region{}
for id := range p.p.Regions { for id, r := range p.p.Regions {
rs[id] = Region{ rs[id] = Region{
id: id, id: id,
desc: r.Description,
p: p.p, p: p.p,
} }
} }
...@@ -240,6 +241,10 @@ type Region struct { ...@@ -240,6 +241,10 @@ type Region struct {
// ID returns the region's identifier. // ID returns the region's identifier.
func (r Region) ID() string { return r.id } func (r Region) ID() string { return r.id }
// Description returns the region's description. The region description
// is free text, it can be empty, and it may change between SDK releases.
func (r Region) Description() string { return r.desc }
// ResolveEndpoint resolves an endpoint from the context of the region given // ResolveEndpoint resolves an endpoint from the context of the region given
// a service. See Partition.EndpointFor for usage and errors that can be returned. // a service. See Partition.EndpointFor for usage and errors that can be returned.
func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) { func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) {
...@@ -284,9 +289,10 @@ func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (Resolve ...@@ -284,9 +289,10 @@ func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (Resolve
func (s Service) Regions() map[string]Region { func (s Service) Regions() map[string]Region {
rs := map[string]Region{} rs := map[string]Region{}
for id := range s.p.Services[s.id].Endpoints { for id := range s.p.Services[s.id].Endpoints {
if _, ok := s.p.Regions[id]; ok { if r, ok := s.p.Regions[id]; ok {
rs[id] = Region{ rs[id] = Region{
id: id, id: id,
desc: r.Description,
p: s.p, p: s.p,
} }
} }
...@@ -347,6 +353,10 @@ type ResolvedEndpoint struct { ...@@ -347,6 +353,10 @@ type ResolvedEndpoint struct {
// The service name that should be used for signing requests. // The service name that should be used for signing requests.
SigningName string SigningName string
// States that the signing name for this endpoint was derived from metadata
// passed in, but was not explicitly modeled.
SigningNameDerived bool
// The signing method that should be used for signing requests. // The signing method that should be used for signing requests.
SigningMethod string SigningMethod string
} }
......
...@@ -226,15 +226,19 @@ func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, op ...@@ -226,15 +226,19 @@ func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, op
if len(signingRegion) == 0 { if len(signingRegion) == 0 {
signingRegion = region signingRegion = region
} }
signingName := e.CredentialScope.Service signingName := e.CredentialScope.Service
var signingNameDerived bool
if len(signingName) == 0 { if len(signingName) == 0 {
signingName = service signingName = service
signingNameDerived = true
} }
return ResolvedEndpoint{ return ResolvedEndpoint{
URL: u, URL: u,
SigningRegion: signingRegion, SigningRegion: signingRegion,
SigningName: signingName, SigningName: signingName,
SigningNameDerived: signingNameDerived,
SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner), SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner),
} }
} }
......
...@@ -71,6 +71,12 @@ const ( ...@@ -71,6 +71,12 @@ const (
// LogDebugWithRequestErrors states the SDK should log when service requests fail // LogDebugWithRequestErrors states the SDK should log when service requests fail
// to build, send, validate, or unmarshal. // to build, send, validate, or unmarshal.
LogDebugWithRequestErrors LogDebugWithRequestErrors
// LogDebugWithEventStreamBody states the SDK should log EventStream
// request and response bodys. This should be used to log the EventStream
// wire unmarshaled message content of requests and responses made while
// using the SDK Will also enable LogDebug.
LogDebugWithEventStreamBody
) )
// A Logger is a minimalistic interface for the SDK to log messages to. Should // A Logger is a minimalistic interface for the SDK to log messages to. Should
......
...@@ -27,6 +27,7 @@ go_library( ...@@ -27,6 +27,7 @@ go_library(
"//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/awsutil:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/awsutil:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/client/metadata:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/client/metadata:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/internal/sdkio:go_default_library",
], ],
) )
......
...@@ -14,6 +14,7 @@ type Handlers struct { ...@@ -14,6 +14,7 @@ type Handlers struct {
Send HandlerList Send HandlerList
ValidateResponse HandlerList ValidateResponse HandlerList
Unmarshal HandlerList Unmarshal HandlerList
UnmarshalStream HandlerList
UnmarshalMeta HandlerList UnmarshalMeta HandlerList
UnmarshalError HandlerList UnmarshalError HandlerList
Retry HandlerList Retry HandlerList
...@@ -30,6 +31,7 @@ func (h *Handlers) Copy() Handlers { ...@@ -30,6 +31,7 @@ func (h *Handlers) Copy() Handlers {
Send: h.Send.copy(), Send: h.Send.copy(),
ValidateResponse: h.ValidateResponse.copy(), ValidateResponse: h.ValidateResponse.copy(),
Unmarshal: h.Unmarshal.copy(), Unmarshal: h.Unmarshal.copy(),
UnmarshalStream: h.UnmarshalStream.copy(),
UnmarshalError: h.UnmarshalError.copy(), UnmarshalError: h.UnmarshalError.copy(),
UnmarshalMeta: h.UnmarshalMeta.copy(), UnmarshalMeta: h.UnmarshalMeta.copy(),
Retry: h.Retry.copy(), Retry: h.Retry.copy(),
...@@ -45,6 +47,7 @@ func (h *Handlers) Clear() { ...@@ -45,6 +47,7 @@ func (h *Handlers) Clear() {
h.Send.Clear() h.Send.Clear()
h.Sign.Clear() h.Sign.Clear()
h.Unmarshal.Clear() h.Unmarshal.Clear()
h.UnmarshalStream.Clear()
h.UnmarshalMeta.Clear() h.UnmarshalMeta.Clear()
h.UnmarshalError.Clear() h.UnmarshalError.Clear()
h.ValidateResponse.Clear() h.ValidateResponse.Clear()
...@@ -172,6 +175,21 @@ func (l *HandlerList) SwapNamed(n NamedHandler) (swapped bool) { ...@@ -172,6 +175,21 @@ func (l *HandlerList) SwapNamed(n NamedHandler) (swapped bool) {
return swapped return swapped
} }
// Swap will swap out all handlers matching the name passed in. The matched
// handlers will be swapped in. True is returned if the handlers were swapped.
func (l *HandlerList) Swap(name string, replace NamedHandler) bool {
var swapped bool
for i := 0; i < len(l.list); i++ {
if l.list[i].Name == name {
l.list[i] = replace
swapped = true
}
}
return swapped
}
// SetBackNamed will replace the named handler if it exists in the handler list. // 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. // If the handler does not exist the handler will be added to the end of the list.
func (l *HandlerList) SetBackNamed(n NamedHandler) { func (l *HandlerList) SetBackNamed(n NamedHandler) {
......
...@@ -3,6 +3,8 @@ package request ...@@ -3,6 +3,8 @@ package request
import ( import (
"io" "io"
"sync" "sync"
"github.com/aws/aws-sdk-go/internal/sdkio"
) )
// offsetReader is a thread-safe io.ReadCloser to prevent racing // offsetReader is a thread-safe io.ReadCloser to prevent racing
...@@ -15,7 +17,7 @@ type offsetReader struct { ...@@ -15,7 +17,7 @@ type offsetReader struct {
func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader { func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader {
reader := &offsetReader{} reader := &offsetReader{}
buf.Seek(offset, 0) buf.Seek(offset, sdkio.SeekStart)
reader.buf = buf reader.buf = buf
return reader return reader
......
...@@ -21,7 +21,7 @@ func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil } ...@@ -21,7 +21,7 @@ func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil }
var NoBody = noBody{} var NoBody = noBody{}
// ResetBody rewinds the request body back to its starting position, and // ResetBody rewinds the request body back to its starting position, and
// set's the HTTP Request body reference. When the body is read prior // sets the HTTP Request body reference. When the body is read prior
// to being sent in the HTTP request it will need to be rewound. // 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 // ResetBody will automatically be called by the SDK's build handler, but if
......
...@@ -11,7 +11,7 @@ import ( ...@@ -11,7 +11,7 @@ import (
var NoBody = http.NoBody var NoBody = http.NoBody
// ResetBody rewinds the request body back to its starting position, and // ResetBody rewinds the request body back to its starting position, and
// set's the HTTP Request body reference. When the body is read prior // sets the HTTP Request body reference. When the body is read prior
// to being sent in the HTTP request it will need to be rewound. // 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 // ResetBody will automatically be called by the SDK's build handler, but if
......
...@@ -35,8 +35,12 @@ type Pagination struct { ...@@ -35,8 +35,12 @@ type Pagination struct {
// NewRequest should always be built from the same API operations. It is // NewRequest should always be built from the same API operations. It is
// undefined if different API operations are returned on subsequent calls. // undefined if different API operations are returned on subsequent calls.
NewRequest func() (*Request, error) NewRequest func() (*Request, error)
// EndPageOnSameToken, when enabled, will allow the paginator to stop on
// token that are the same as its previous tokens.
EndPageOnSameToken bool
started bool started bool
prevTokens []interface{}
nextTokens []interface{} nextTokens []interface{}
err error err error
...@@ -49,7 +53,15 @@ type Pagination struct { ...@@ -49,7 +53,15 @@ type Pagination struct {
// //
// Will always return true if Next has not been called yet. // Will always return true if Next has not been called yet.
func (p *Pagination) HasNextPage() bool { func (p *Pagination) HasNextPage() bool {
return !(p.started && len(p.nextTokens) == 0) if !p.started {
return true
}
hasNextPage := len(p.nextTokens) != 0
if p.EndPageOnSameToken {
return hasNextPage && !awsutil.DeepEqual(p.nextTokens, p.prevTokens)
}
return hasNextPage
} }
// Err returns the error Pagination encountered when retrieving the next page. // Err returns the error Pagination encountered when retrieving the next page.
...@@ -96,6 +108,7 @@ func (p *Pagination) Next() bool { ...@@ -96,6 +108,7 @@ func (p *Pagination) Next() bool {
return false return false
} }
p.prevTokens = p.nextTokens
p.nextTokens = req.nextPageTokens() p.nextTokens = req.nextPageTokens()
p.curPage = req.Data p.curPage = req.Data
...@@ -142,13 +155,28 @@ func (r *Request) nextPageTokens() []interface{} { ...@@ -142,13 +155,28 @@ func (r *Request) nextPageTokens() []interface{} {
tokens := []interface{}{} tokens := []interface{}{}
tokenAdded := false tokenAdded := false
for _, outToken := range r.Operation.OutputTokens { for _, outToken := range r.Operation.OutputTokens {
v, _ := awsutil.ValuesAtPath(r.Data, outToken) vs, _ := awsutil.ValuesAtPath(r.Data, outToken)
if len(v) > 0 { if len(vs) == 0 {
tokens = append(tokens, v[0])
tokenAdded = true
} else {
tokens = append(tokens, nil) tokens = append(tokens, nil)
continue
} }
v := vs[0]
switch tv := v.(type) {
case *string:
if len(aws.StringValue(tv)) == 0 {
tokens = append(tokens, nil)
continue
}
case string:
if len(tv) == 0 {
tokens = append(tokens, nil)
continue
}
}
tokenAdded = true
tokens = append(tokens, v)
} }
if !tokenAdded { if !tokenAdded {
return nil return nil
......
...@@ -18,6 +18,7 @@ go_library( ...@@ -18,6 +18,7 @@ go_library(
"//vendor/github.com/aws/aws-sdk-go/aws/corehandlers:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/corehandlers:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/credentials:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/credentials:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/csm:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/defaults:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/defaults:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/endpoints:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/endpoints:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library",
......
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
"strconv" "strconv"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/defaults"
) )
// EnvProviderName provides a name of the provider when config is loaded from environment. // EnvProviderName provides a name of the provider when config is loaded from environment.
...@@ -95,9 +96,23 @@ type envConfig struct { ...@@ -95,9 +96,23 @@ type envConfig struct {
// //
// AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle // AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle
CustomCABundle string CustomCABundle string
csmEnabled string
CSMEnabled bool
CSMPort string
CSMClientID string
} }
var ( var (
csmEnabledEnvKey = []string{
"AWS_CSM_ENABLED",
}
csmPortEnvKey = []string{
"AWS_CSM_PORT",
}
csmClientIDEnvKey = []string{
"AWS_CSM_CLIENT_ID",
}
credAccessEnvKey = []string{ credAccessEnvKey = []string{
"AWS_ACCESS_KEY_ID", "AWS_ACCESS_KEY_ID",
"AWS_ACCESS_KEY", "AWS_ACCESS_KEY",
...@@ -156,6 +171,12 @@ func envConfigLoad(enableSharedConfig bool) envConfig { ...@@ -156,6 +171,12 @@ func envConfigLoad(enableSharedConfig bool) envConfig {
setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey) setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey)
setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey) setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey)
// CSM environment variables
setFromEnvVal(&cfg.csmEnabled, csmEnabledEnvKey)
setFromEnvVal(&cfg.CSMPort, csmPortEnvKey)
setFromEnvVal(&cfg.CSMClientID, csmClientIDEnvKey)
cfg.CSMEnabled = len(cfg.csmEnabled) > 0
// Require logical grouping of credentials // Require logical grouping of credentials
if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 { if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 {
cfg.Creds = credentials.Value{} cfg.Creds = credentials.Value{}
...@@ -176,6 +197,13 @@ func envConfigLoad(enableSharedConfig bool) envConfig { ...@@ -176,6 +197,13 @@ func envConfigLoad(enableSharedConfig bool) envConfig {
setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey) setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey)
setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey) setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey)
if len(cfg.SharedCredentialsFile) == 0 {
cfg.SharedCredentialsFile = defaults.SharedCredentialsFilename()
}
if len(cfg.SharedConfigFile) == 0 {
cfg.SharedConfigFile = defaults.SharedConfigFilename()
}
cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE") cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
return cfg return cfg
......
...@@ -15,6 +15,7 @@ import ( ...@@ -15,6 +15,7 @@ import (
"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/stscreds" "github.com/aws/aws-sdk-go/aws/credentials/stscreds"
"github.com/aws/aws-sdk-go/aws/csm"
"github.com/aws/aws-sdk-go/aws/defaults" "github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
...@@ -26,7 +27,7 @@ import ( ...@@ -26,7 +27,7 @@ import (
// 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. // The Session satisfies the service client's client.ConfigProvider.
type Session struct { type Session struct {
Config *aws.Config Config *aws.Config
Handlers request.Handlers Handlers request.Handlers
...@@ -58,7 +59,12 @@ func New(cfgs ...*aws.Config) *Session { ...@@ -58,7 +59,12 @@ func New(cfgs ...*aws.Config) *Session {
envCfg := loadEnvConfig() envCfg := loadEnvConfig()
if envCfg.EnableSharedConfig { if envCfg.EnableSharedConfig {
s, err := newSession(Options{}, envCfg, cfgs...) var cfg aws.Config
cfg.MergeIn(cfgs...)
s, err := NewSessionWithOptions(Options{
Config: cfg,
SharedConfigState: SharedConfigEnable,
})
if err != nil { if err != nil {
// Old session.New expected all errors to be discovered when // Old session.New expected all errors to be discovered when
// a request is made, and would report the errors then. This // a request is made, and would report the errors then. This
...@@ -76,10 +82,16 @@ func New(cfgs ...*aws.Config) *Session { ...@@ -76,10 +82,16 @@ func New(cfgs ...*aws.Config) *Session {
r.Error = err r.Error = err
}) })
} }
return s return s
} }
return deprecatedNewSession(cfgs...) s := deprecatedNewSession(cfgs...)
if envCfg.CSMEnabled {
enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger)
}
return s
} }
// NewSession returns a new Session created from SDK defaults, config files, // NewSession returns a new Session created from SDK defaults, config files,
...@@ -243,13 +255,6 @@ func NewSessionWithOptions(opts Options) (*Session, error) { ...@@ -243,13 +255,6 @@ func NewSessionWithOptions(opts Options) (*Session, error) {
envCfg.EnableSharedConfig = true 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. // Only use AWS_CA_BUNDLE if session option is not provided.
if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil { if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil {
f, err := os.Open(envCfg.CustomCABundle) f, err := os.Open(envCfg.CustomCABundle)
...@@ -302,10 +307,22 @@ func deprecatedNewSession(cfgs ...*aws.Config) *Session { ...@@ -302,10 +307,22 @@ func deprecatedNewSession(cfgs ...*aws.Config) *Session {
} }
initHandlers(s) initHandlers(s)
return s return s
} }
func enableCSM(handlers *request.Handlers, clientID string, port string, logger aws.Logger) {
logger.Log("Enabling CSM")
if len(port) == 0 {
port = csm.DefaultPort
}
r, err := csm.Start(clientID, "127.0.0.1:"+port)
if err != nil {
return
}
r.InjectHandlers(handlers)
}
func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) { func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) {
cfg := defaults.Config() cfg := defaults.Config()
handlers := defaults.Handlers() handlers := defaults.Handlers()
...@@ -345,6 +362,9 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, ...@@ -345,6 +362,9 @@ func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session,
} }
initHandlers(s) initHandlers(s)
if envCfg.CSMEnabled {
enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger)
}
// Setup HTTP client with custom cert bundle if enabled // Setup HTTP client with custom cert bundle if enabled
if opts.CustomCABundle != nil { if opts.CustomCABundle != nil {
...@@ -577,6 +597,7 @@ func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) ( ...@@ -577,6 +597,7 @@ func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (
Handlers: s.Handlers, Handlers: s.Handlers,
Endpoint: resolved.URL, Endpoint: resolved.URL,
SigningRegion: resolved.SigningRegion, SigningRegion: resolved.SigningRegion,
SigningNameDerived: resolved.SigningNameDerived,
SigningName: resolved.SigningName, SigningName: resolved.SigningName,
}, err }, err
} }
...@@ -601,6 +622,7 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf ...@@ -601,6 +622,7 @@ func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Conf
Handlers: s.Handlers, Handlers: s.Handlers,
Endpoint: resolved.URL, Endpoint: resolved.URL,
SigningRegion: resolved.SigningRegion, SigningRegion: resolved.SigningRegion,
SigningNameDerived: resolved.SigningNameDerived,
SigningName: resolved.SigningName, SigningName: resolved.SigningName,
} }
} }
...@@ -15,6 +15,7 @@ go_library( ...@@ -15,6 +15,7 @@ go_library(
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/credentials:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/credentials:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/internal/sdkio:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/private/protocol/rest:go_default_library", "//vendor/github.com/aws/aws-sdk-go/private/protocol/rest:go_default_library",
], ],
) )
......
...@@ -71,6 +71,7 @@ import ( ...@@ -71,6 +71,7 @@ import (
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/sdkio"
"github.com/aws/aws-sdk-go/private/protocol/rest" "github.com/aws/aws-sdk-go/private/protocol/rest"
) )
...@@ -134,6 +135,7 @@ var requiredSignedHeaders = rules{ ...@@ -134,6 +135,7 @@ var requiredSignedHeaders = rules{
"X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
"X-Amz-Storage-Class": struct{}{}, "X-Amz-Storage-Class": struct{}{},
"X-Amz-Website-Redirect-Location": struct{}{}, "X-Amz-Website-Redirect-Location": struct{}{},
"X-Amz-Content-Sha256": struct{}{},
}, },
}, },
patterns{"X-Amz-Meta-"}, patterns{"X-Amz-Meta-"},
...@@ -268,7 +270,7 @@ type signingCtx struct { ...@@ -268,7 +270,7 @@ type signingCtx struct {
// "X-Amz-Content-Sha256" header with a precomputed value. The signer will // "X-Amz-Content-Sha256" header with a precomputed value. The signer will
// only compute the hash if the request header value is empty. // 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) { 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) return v4.signWithBody(r, body, service, region, 0, false, signTime)
} }
// Presign signs AWS v4 requests with the provided body, service name, region // Presign signs AWS v4 requests with the provided body, service name, region
...@@ -302,10 +304,10 @@ func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region strin ...@@ -302,10 +304,10 @@ func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region strin
// presigned request's signature you can set the "X-Amz-Content-Sha256" // presigned request's signature you can set the "X-Amz-Content-Sha256"
// HTTP header and that will be included in the request's signature. // 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) { 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) return v4.signWithBody(r, body, service, region, exp, true, signTime)
} }
func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) { func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, isPresign bool, signTime time.Time) (http.Header, error) {
currentTimeFn := v4.currentTimeFn currentTimeFn := v4.currentTimeFn
if currentTimeFn == nil { if currentTimeFn == nil {
currentTimeFn = time.Now currentTimeFn = time.Now
...@@ -317,7 +319,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi ...@@ -317,7 +319,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
Query: r.URL.Query(), Query: r.URL.Query(),
Time: signTime, Time: signTime,
ExpireTime: exp, ExpireTime: exp,
isPresign: exp != 0, isPresign: isPresign,
ServiceName: service, ServiceName: service,
Region: region, Region: region,
DisableURIPathEscaping: v4.DisableURIPathEscaping, DisableURIPathEscaping: v4.DisableURIPathEscaping,
...@@ -339,8 +341,11 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi ...@@ -339,8 +341,11 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
return http.Header{}, err return http.Header{}, err
} }
ctx.sanitizeHostForHeader()
ctx.assignAmzQueryValues() ctx.assignAmzQueryValues()
ctx.build(v4.DisableHeaderHoisting) if err := ctx.build(v4.DisableHeaderHoisting); err != nil {
return nil, err
}
// If the request is not presigned the body should be attached to it. This // 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 // prevents the confusion of wanting to send a signed request without
...@@ -363,6 +368,10 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi ...@@ -363,6 +368,10 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
return ctx.SignedHeaderVals, nil return ctx.SignedHeaderVals, nil
} }
func (ctx *signingCtx) sanitizeHostForHeader() {
request.SanitizeHostForHeader(ctx.Request)
}
func (ctx *signingCtx) handlePresignRemoval() { func (ctx *signingCtx) handlePresignRemoval() {
if !ctx.isPresign { if !ctx.isPresign {
return return
...@@ -467,7 +476,7 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time ...@@ -467,7 +476,7 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time
} }
signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(), signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(),
name, region, req.ExpireTime, signingTime, name, region, req.ExpireTime, req.ExpireTime > 0, signingTime,
) )
if err != nil { if err != nil {
req.Error = err req.Error = err
...@@ -498,11 +507,13 @@ func (v4 *Signer) logSigningInfo(ctx *signingCtx) { ...@@ -498,11 +507,13 @@ func (v4 *Signer) logSigningInfo(ctx *signingCtx) {
v4.Logger.Log(msg) v4.Logger.Log(msg)
} }
func (ctx *signingCtx) build(disableHeaderHoisting bool) { func (ctx *signingCtx) build(disableHeaderHoisting bool) error {
ctx.buildTime() // no depends ctx.buildTime() // no depends
ctx.buildCredentialString() // no depends ctx.buildCredentialString() // no depends
ctx.buildBodyDigest() if err := ctx.buildBodyDigest(); err != nil {
return err
}
unsignedHeaders := ctx.Request.Header unsignedHeaders := ctx.Request.Header
if ctx.isPresign { if ctx.isPresign {
...@@ -530,6 +541,8 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) { ...@@ -530,6 +541,8 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) {
} }
ctx.Request.Header.Set("Authorization", strings.Join(parts, ", ")) ctx.Request.Header.Set("Authorization", strings.Join(parts, ", "))
} }
return nil
} }
func (ctx *signingCtx) buildTime() { func (ctx *signingCtx) buildTime() {
...@@ -656,21 +669,34 @@ func (ctx *signingCtx) buildSignature() { ...@@ -656,21 +669,34 @@ func (ctx *signingCtx) buildSignature() {
ctx.signature = hex.EncodeToString(signature) ctx.signature = hex.EncodeToString(signature)
} }
func (ctx *signingCtx) buildBodyDigest() { func (ctx *signingCtx) buildBodyDigest() error {
hash := ctx.Request.Header.Get("X-Amz-Content-Sha256") hash := ctx.Request.Header.Get("X-Amz-Content-Sha256")
if hash == "" { if hash == "" {
if ctx.unsignedPayload || (ctx.isPresign && ctx.ServiceName == "s3") { includeSHA256Header := ctx.unsignedPayload ||
ctx.ServiceName == "s3" ||
ctx.ServiceName == "glacier"
s3Presign := ctx.isPresign && ctx.ServiceName == "s3"
if ctx.unsignedPayload || s3Presign {
hash = "UNSIGNED-PAYLOAD" hash = "UNSIGNED-PAYLOAD"
includeSHA256Header = !s3Presign
} else if ctx.Body == nil { } else if ctx.Body == nil {
hash = emptyStringSHA256 hash = emptyStringSHA256
} else { } else {
if !aws.IsReaderSeekable(ctx.Body) {
return fmt.Errorf("cannot use unseekable request body %T, for signed request with body", ctx.Body)
}
hash = hex.EncodeToString(makeSha256Reader(ctx.Body)) hash = hex.EncodeToString(makeSha256Reader(ctx.Body))
} }
if ctx.unsignedPayload || ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" {
if includeSHA256Header {
ctx.Request.Header.Set("X-Amz-Content-Sha256", hash) ctx.Request.Header.Set("X-Amz-Content-Sha256", hash)
} }
} }
ctx.bodyDigest = hash ctx.bodyDigest = hash
return nil
} }
// isRequestSigned returns if the request is currently signed or presigned // isRequestSigned returns if the request is currently signed or presigned
...@@ -710,8 +736,8 @@ func makeSha256(data []byte) []byte { ...@@ -710,8 +736,8 @@ func makeSha256(data []byte) []byte {
func makeSha256Reader(reader io.ReadSeeker) []byte { func makeSha256Reader(reader io.ReadSeeker) []byte {
hash := sha256.New() hash := sha256.New()
start, _ := reader.Seek(0, 1) start, _ := reader.Seek(0, sdkio.SeekCurrent)
defer reader.Seek(start, 0) defer reader.Seek(start, sdkio.SeekStart)
io.Copy(hash, reader) io.Copy(hash, reader)
return hash.Sum(nil) return hash.Sum(nil)
......
...@@ -3,6 +3,8 @@ package aws ...@@ -3,6 +3,8 @@ package aws
import ( import (
"io" "io"
"sync" "sync"
"github.com/aws/aws-sdk-go/internal/sdkio"
) )
// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Should // ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Should
...@@ -22,6 +24,22 @@ type ReaderSeekerCloser struct { ...@@ -22,6 +24,22 @@ type ReaderSeekerCloser struct {
r io.Reader r io.Reader
} }
// IsReaderSeekable returns if the underlying reader type can be seeked. A
// io.Reader might not actually be seekable if it is the ReaderSeekerCloser
// type.
func IsReaderSeekable(r io.Reader) bool {
switch v := r.(type) {
case ReaderSeekerCloser:
return v.IsSeeker()
case *ReaderSeekerCloser:
return v.IsSeeker()
case io.ReadSeeker:
return true
default:
return false
}
}
// Read reads from the reader up to size of p. The number of bytes read, and // Read reads from the reader up to size of p. The number of bytes read, and
// error if it occurred will be returned. // error if it occurred will be returned.
// //
...@@ -56,6 +74,71 @@ func (r ReaderSeekerCloser) IsSeeker() bool { ...@@ -56,6 +74,71 @@ func (r ReaderSeekerCloser) IsSeeker() bool {
return ok return ok
} }
// HasLen returns the length of the underlying reader if the value implements
// the Len() int method.
func (r ReaderSeekerCloser) HasLen() (int, bool) {
type lenner interface {
Len() int
}
if lr, ok := r.r.(lenner); ok {
return lr.Len(), true
}
return 0, false
}
// GetLen returns the length of the bytes remaining in the underlying reader.
// Checks first for Len(), then io.Seeker to determine the size of the
// underlying reader.
//
// Will return -1 if the length cannot be determined.
func (r ReaderSeekerCloser) GetLen() (int64, error) {
if l, ok := r.HasLen(); ok {
return int64(l), nil
}
if s, ok := r.r.(io.Seeker); ok {
return seekerLen(s)
}
return -1, nil
}
// SeekerLen attempts to get the number of bytes remaining at the seeker's
// current position. Returns the number of bytes remaining or error.
func SeekerLen(s io.Seeker) (int64, error) {
// Determine if the seeker is actually seekable. ReaderSeekerCloser
// hides the fact that a io.Readers might not actually be seekable.
switch v := s.(type) {
case ReaderSeekerCloser:
return v.GetLen()
case *ReaderSeekerCloser:
return v.GetLen()
}
return seekerLen(s)
}
func seekerLen(s io.Seeker) (int64, error) {
curOffset, err := s.Seek(0, sdkio.SeekCurrent)
if err != nil {
return 0, err
}
endOffset, err := s.Seek(0, sdkio.SeekEnd)
if err != nil {
return 0, err
}
_, err = s.Seek(curOffset, sdkio.SeekStart)
if err != nil {
return 0, err
}
return endOffset - curOffset, nil
}
// Close closes the ReaderSeekerCloser. // 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.
......
...@@ -5,4 +5,4 @@ package aws ...@@ -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.12.7" const SDKVersion = "1.14.12"
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"io_go1.6.go",
"io_go1.7.go",
],
importmap = "k8s.io/kubernetes/vendor/github.com/aws/aws-sdk-go/internal/sdkio",
importpath = "github.com/aws/aws-sdk-go/internal/sdkio",
visibility = ["//vendor/github.com/aws/aws-sdk-go:__subpackages__"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
// +build !go1.7
package sdkio
// Copy of Go 1.7 io package's Seeker constants.
const (
SeekStart = 0 // seek relative to the origin of the file
SeekCurrent = 1 // seek relative to the current offset
SeekEnd = 2 // seek relative to the end
)
// +build go1.7
package sdkio
import "io"
// Alias for Go 1.7 io package Seeker constants
const (
SeekStart = io.SeekStart // seek relative to the origin of the file
SeekCurrent = io.SeekCurrent // seek relative to the current offset
SeekEnd = io.SeekEnd // seek relative to the end
)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["locked_source.go"],
importmap = "k8s.io/kubernetes/vendor/github.com/aws/aws-sdk-go/internal/sdkrand",
importpath = "github.com/aws/aws-sdk-go/internal/sdkrand",
visibility = ["//vendor/github.com/aws/aws-sdk-go:__subpackages__"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
package sdkrand
import (
"math/rand"
"sync"
"time"
)
// 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()
}
// SeededRand is a new RNG using a thread safe implementation of rand.Source
var SeededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())})
...@@ -4,12 +4,18 @@ go_library( ...@@ -4,12 +4,18 @@ go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = [
"idempotency.go", "idempotency.go",
"jsonvalue.go",
"payload.go",
"unmarshal.go", "unmarshal.go",
], ],
importmap = "k8s.io/kubernetes/vendor/github.com/aws/aws-sdk-go/private/protocol", importmap = "k8s.io/kubernetes/vendor/github.com/aws/aws-sdk-go/private/protocol",
importpath = "github.com/aws/aws-sdk-go/private/protocol", importpath = "github.com/aws/aws-sdk-go/private/protocol",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = ["//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library"], deps = [
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/client/metadata:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library",
],
) )
filegroup( filegroup(
......
...@@ -24,7 +24,7 @@ func Build(r *request.Request) { ...@@ -24,7 +24,7 @@ func Build(r *request.Request) {
r.Error = awserr.New("SerializationError", "failed encoding EC2 Query request", err) r.Error = awserr.New("SerializationError", "failed encoding EC2 Query request", err)
} }
if r.ExpireTime == 0 { if !r.IsPresigned() {
r.HTTPRequest.Method = "POST" r.HTTPRequest.Method = "POST"
r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
r.SetBufferBody([]byte(body.Encode())) r.SetBufferBody([]byte(body.Encode()))
......
...@@ -9,7 +9,10 @@ go_library( ...@@ -9,7 +9,10 @@ go_library(
importmap = "k8s.io/kubernetes/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", importmap = "k8s.io/kubernetes/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil",
importpath = "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil", importpath = "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = ["//vendor/github.com/aws/aws-sdk-go/private/protocol:go_default_library"], deps = [
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/private/protocol:go_default_library",
],
) )
filegroup( filegroup(
......
...@@ -12,6 +12,7 @@ import ( ...@@ -12,6 +12,7 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/private/protocol" "github.com/aws/aws-sdk-go/private/protocol"
) )
...@@ -49,9 +50,12 @@ func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) err ...@@ -49,9 +50,12 @@ func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) err
t = "list" t = "list"
} }
case reflect.Map: case reflect.Map:
// cannot be a JSONValue map
if _, ok := value.Interface().(aws.JSONValue); !ok {
t = "map" t = "map"
} }
} }
}
switch t { switch t {
case "structure": case "structure":
...@@ -210,14 +214,11 @@ func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) erro ...@@ -210,14 +214,11 @@ func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) erro
} }
buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64)) buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64))
default: default:
switch value.Type() { switch converted := value.Interface().(type) {
case timeType: case time.Time:
converted := v.Interface().(*time.Time)
buf.Write(strconv.AppendInt(scratch[:0], converted.UTC().Unix(), 10)) buf.Write(strconv.AppendInt(scratch[:0], converted.UTC().Unix(), 10))
case byteSliceType: case []byte:
if !value.IsNil() { if !value.IsNil() {
converted := value.Interface().([]byte)
buf.WriteByte('"') buf.WriteByte('"')
if len(converted) < 1024 { if len(converted) < 1024 {
// for small buffers, using Encode directly is much faster. // for small buffers, using Encode directly is much faster.
...@@ -233,6 +234,12 @@ func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) erro ...@@ -233,6 +234,12 @@ func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) erro
} }
buf.WriteByte('"') buf.WriteByte('"')
} }
case aws.JSONValue:
str, err := protocol.EncodeJSONValue(converted, protocol.QuotedEscape)
if err != nil {
return fmt.Errorf("unable to encode JSONValue, %v", err)
}
buf.WriteString(str)
default: default:
return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type()) return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type())
} }
......
...@@ -8,6 +8,9 @@ import ( ...@@ -8,6 +8,9 @@ import (
"io/ioutil" "io/ioutil"
"reflect" "reflect"
"time" "time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/private/protocol"
) )
// UnmarshalJSON reads a stream and unmarshals the results in object v. // UnmarshalJSON reads a stream and unmarshals the results in object v.
...@@ -50,9 +53,12 @@ func unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag) ...@@ -50,9 +53,12 @@ func unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag)
t = "list" t = "list"
} }
case reflect.Map: case reflect.Map:
// cannot be a JSONValue map
if _, ok := value.Interface().(aws.JSONValue); !ok {
t = "map" t = "map"
} }
} }
}
switch t { switch t {
case "structure": case "structure":
...@@ -183,6 +189,13 @@ func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTa ...@@ -183,6 +189,13 @@ func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTa
return err return err
} }
value.Set(reflect.ValueOf(b)) value.Set(reflect.ValueOf(b))
case aws.JSONValue:
// No need to use escaping as the value is a non-quoted string.
v, err := protocol.DecodeJSONValue(d, protocol.NoEscape)
if err != nil {
return err
}
value.Set(reflect.ValueOf(v))
default: default:
return errf() return errf()
} }
......
package protocol
import (
"encoding/base64"
"encoding/json"
"fmt"
"strconv"
"github.com/aws/aws-sdk-go/aws"
)
// EscapeMode is the mode that should be use for escaping a value
type EscapeMode uint
// The modes for escaping a value before it is marshaled, and unmarshaled.
const (
NoEscape EscapeMode = iota
Base64Escape
QuotedEscape
)
// EncodeJSONValue marshals the value into a JSON string, and optionally base64
// encodes the string before returning it.
//
// Will panic if the escape mode is unknown.
func EncodeJSONValue(v aws.JSONValue, escape EscapeMode) (string, error) {
b, err := json.Marshal(v)
if err != nil {
return "", err
}
switch escape {
case NoEscape:
return string(b), nil
case Base64Escape:
return base64.StdEncoding.EncodeToString(b), nil
case QuotedEscape:
return strconv.Quote(string(b)), nil
}
panic(fmt.Sprintf("EncodeJSONValue called with unknown EscapeMode, %v", escape))
}
// DecodeJSONValue will attempt to decode the string input as a JSONValue.
// Optionally decoding base64 the value first before JSON unmarshaling.
//
// Will panic if the escape mode is unknown.
func DecodeJSONValue(v string, escape EscapeMode) (aws.JSONValue, error) {
var b []byte
var err error
switch escape {
case NoEscape:
b = []byte(v)
case Base64Escape:
b, err = base64.StdEncoding.DecodeString(v)
case QuotedEscape:
var u string
u, err = strconv.Unquote(v)
b = []byte(u)
default:
panic(fmt.Sprintf("DecodeJSONValue called with unknown EscapeMode, %v", escape))
}
if err != nil {
return nil, err
}
m := aws.JSONValue{}
err = json.Unmarshal(b, &m)
if err != nil {
return nil, err
}
return m, nil
}
package protocol
import (
"io"
"io/ioutil"
"net/http"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/request"
)
// PayloadUnmarshaler provides the interface for unmarshaling a payload's
// reader into a SDK shape.
type PayloadUnmarshaler interface {
UnmarshalPayload(io.Reader, interface{}) error
}
// HandlerPayloadUnmarshal implements the PayloadUnmarshaler from a
// HandlerList. This provides the support for unmarshaling a payload reader to
// a shape without needing a SDK request first.
type HandlerPayloadUnmarshal struct {
Unmarshalers request.HandlerList
}
// UnmarshalPayload unmarshals the io.Reader payload into the SDK shape using
// the Unmarshalers HandlerList provided. Returns an error if unable
// unmarshaling fails.
func (h HandlerPayloadUnmarshal) UnmarshalPayload(r io.Reader, v interface{}) error {
req := &request.Request{
HTTPRequest: &http.Request{},
HTTPResponse: &http.Response{
StatusCode: 200,
Header: http.Header{},
Body: ioutil.NopCloser(r),
},
Data: v,
}
h.Unmarshalers.Run(req)
return req.Error
}
// PayloadMarshaler provides the interface for marshaling a SDK shape into and
// io.Writer.
type PayloadMarshaler interface {
MarshalPayload(io.Writer, interface{}) error
}
// HandlerPayloadMarshal implements the PayloadMarshaler from a HandlerList.
// This provides support for marshaling a SDK shape into an io.Writer without
// needing a SDK request first.
type HandlerPayloadMarshal struct {
Marshalers request.HandlerList
}
// MarshalPayload marshals the SDK shape into the io.Writer using the
// Marshalers HandlerList provided. Returns an error if unable if marshal
// fails.
func (h HandlerPayloadMarshal) MarshalPayload(w io.Writer, v interface{}) error {
req := request.New(
aws.Config{},
metadata.ClientInfo{},
request.Handlers{},
nil,
&request.Operation{HTTPMethod: "GET"},
v,
nil,
)
h.Marshalers.Run(req)
if req.Error != nil {
return req.Error
}
io.Copy(w, req.GetBody())
return nil
}
...@@ -25,7 +25,7 @@ func Build(r *request.Request) { ...@@ -25,7 +25,7 @@ func Build(r *request.Request) {
return return
} }
if r.ExpireTime == 0 { if !r.IsPresigned() {
r.HTTPRequest.Method = "POST" r.HTTPRequest.Method = "POST"
r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
r.SetBufferBody([]byte(body.Encode())) r.SetBufferBody([]byte(body.Encode()))
......
...@@ -14,6 +14,7 @@ go_library( ...@@ -14,6 +14,7 @@ go_library(
"//vendor/github.com/aws/aws-sdk-go/aws:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/awserr:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/private/protocol:go_default_library",
], ],
) )
......
...@@ -4,7 +4,6 @@ package rest ...@@ -4,7 +4,6 @@ package rest
import ( import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"encoding/json"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
...@@ -18,10 +17,13 @@ import ( ...@@ -18,10 +17,13 @@ import (
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol"
) )
// RFC822 returns an RFC822 formatted timestamp for AWS protocols // RFC1123GMT is a RFC1123 (RFC822) formated timestame. This format is not
const RFC822 = "Mon, 2 Jan 2006 15:04:05 GMT" // using the standard library's time.RFC1123 due to the desire to always use
// GMT as the timezone.
const RFC1123GMT = "Mon, 2 Jan 2006 15:04:05 GMT"
// Whether the byte value can be sent without escaping in AWS URLs // Whether the byte value can be sent without escaping in AWS URLs
var noEscape [256]bool var noEscape [256]bool
...@@ -252,13 +254,12 @@ func EscapePath(path string, encodeSep bool) string { ...@@ -252,13 +254,12 @@ func EscapePath(path string, encodeSep bool) string {
return buf.String() return buf.String()
} }
func convertType(v reflect.Value, tag reflect.StructTag) (string, error) { func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error) {
v = reflect.Indirect(v) v = reflect.Indirect(v)
if !v.IsValid() { if !v.IsValid() {
return "", errValueNotSet return "", errValueNotSet
} }
var str string
switch value := v.Interface().(type) { switch value := v.Interface().(type) {
case string: case string:
str = value str = value
...@@ -271,19 +272,21 @@ func convertType(v reflect.Value, tag reflect.StructTag) (string, error) { ...@@ -271,19 +272,21 @@ func convertType(v reflect.Value, tag reflect.StructTag) (string, error) {
case float64: case float64:
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(RFC1123GMT)
case aws.JSONValue: case aws.JSONValue:
b, err := json.Marshal(value) if len(value) == 0 {
if err != nil { return "", errValueNotSet
return "", err
} }
escaping := protocol.NoEscape
if tag.Get("location") == "header" { if tag.Get("location") == "header" {
str = base64.StdEncoding.EncodeToString(b) escaping = protocol.Base64Escape
} else { }
str = string(b) str, err = protocol.EncodeJSONValue(value, escaping)
if err != nil {
return "", fmt.Errorf("unable to encode JSONValue, %v", err)
} }
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
} }
return str, nil return str, nil
......
...@@ -3,7 +3,6 @@ package rest ...@@ -3,7 +3,6 @@ package rest
import ( import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"encoding/json"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
...@@ -16,6 +15,7 @@ import ( ...@@ -16,6 +15,7 @@ import (
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/private/protocol"
) )
// UnmarshalHandler is a named request handler for unmarshaling rest protocol requests // UnmarshalHandler is a named request handler for unmarshaling rest protocol requests
...@@ -198,23 +198,17 @@ func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) erro ...@@ -198,23 +198,17 @@ func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) erro
} }
v.Set(reflect.ValueOf(&f)) v.Set(reflect.ValueOf(&f))
case *time.Time: case *time.Time:
t, err := time.Parse(RFC822, header) t, err := time.Parse(time.RFC1123, header)
if err != nil { if err != nil {
return err return err
} }
v.Set(reflect.ValueOf(&t)) v.Set(reflect.ValueOf(&t))
case aws.JSONValue: case aws.JSONValue:
b := []byte(header) escaping := protocol.NoEscape
var err error
if tag.Get("location") == "header" { if tag.Get("location") == "header" {
b, err = base64.StdEncoding.DecodeString(header) escaping = protocol.Base64Escape
if err != nil {
return err
} }
} m, err := protocol.DecodeJSONValue(header, escaping)
m := aws.JSONValue{}
err = json.Unmarshal(b, &m)
if err != nil { if err != nil {
return err return err
} }
......
...@@ -52,9 +52,15 @@ func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { ...@@ -52,9 +52,15 @@ func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
if t == "" { if t == "" {
switch rtype.Kind() { switch rtype.Kind() {
case reflect.Struct: case reflect.Struct:
// also it can't be a time object
if _, ok := r.Interface().(*time.Time); !ok {
t = "structure" t = "structure"
}
case reflect.Slice: case reflect.Slice:
// also it can't be a byte slice
if _, ok := r.Interface().([]byte); !ok {
t = "list" t = "list"
}
case reflect.Map: case reflect.Map:
t = "map" t = "map"
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -3,9 +3,10 @@ ...@@ -3,9 +3,10 @@
// Package autoscaling provides the client and types for making API // Package autoscaling provides the client and types for making API
// requests to Auto Scaling. // requests to Auto Scaling.
// //
// Auto Scaling is designed to automatically launch or terminate EC2 instances // Amazon EC2 Auto Scaling is designed to automatically launch or terminate
// based on user-defined policies, schedules, and health checks. Use this service // EC2 instances based on user-defined policies, schedules, and health checks.
// in conjunction with the Amazon CloudWatch and Elastic Load Balancing services. // Use this service in conjunction with the AWS Auto Scaling, Amazon CloudWatch,
// and Elastic Load Balancing services.
// //
// See https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01 for more information on this service. // See https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01 for more information on this service.
// //
...@@ -14,7 +15,7 @@ ...@@ -14,7 +15,7 @@
// //
// Using the Client // Using the Client
// //
// To Auto Scaling with the SDK use the New function to create // To contact Auto Scaling with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service. // a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently. // These clients are safe to use concurrently.
// //
......
...@@ -44,4 +44,10 @@ const ( ...@@ -44,4 +44,10 @@ const (
// The operation can't be performed because there are scaling activities in // The operation can't be performed because there are scaling activities in
// progress. // progress.
ErrCodeScalingActivityInProgressFault = "ScalingActivityInProgress" ErrCodeScalingActivityInProgressFault = "ScalingActivityInProgress"
// ErrCodeServiceLinkedRoleFailure for service response error code
// "ServiceLinkedRoleFailure".
//
// The service-linked role is not yet ready for use.
ErrCodeServiceLinkedRoleFailure = "ServiceLinkedRoleFailure"
) )
...@@ -29,8 +29,9 @@ var initRequest func(*request.Request) ...@@ -29,8 +29,9 @@ var initRequest func(*request.Request)
// Service information constants // Service information constants
const ( const (
ServiceName = "autoscaling" // Service endpoint prefix API calls made to. ServiceName = "autoscaling" // Name of service.
EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "Auto Scaling" // ServiceID is a unique identifer of a specific service.
) )
// New creates a new instance of the AutoScaling client with a session. // New creates a new instance of the AutoScaling client with a session.
...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
cfg, cfg,
metadata.ClientInfo{ metadata.ClientInfo{
ServiceName: ServiceName, ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
Endpoint: endpoint, Endpoint: endpoint,
......
...@@ -21,6 +21,7 @@ go_library( ...@@ -21,6 +21,7 @@ go_library(
"//vendor/github.com/aws/aws-sdk-go/aws/endpoints:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/endpoints:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/request:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/aws/signer/v4:go_default_library", "//vendor/github.com/aws/aws-sdk-go/aws/signer/v4:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/internal/sdkrand:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/private/protocol:go_default_library", "//vendor/github.com/aws/aws-sdk-go/private/protocol:go_default_library",
"//vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query:go_default_library", "//vendor/github.com/aws/aws-sdk-go/private/protocol/ec2query:go_default_library",
], ],
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -5,11 +5,64 @@ import ( ...@@ -5,11 +5,64 @@ import (
"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"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/endpoints"
"github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/sdkrand"
) )
type retryer struct {
client.DefaultRetryer
}
func (d retryer) RetryRules(r *request.Request) time.Duration {
switch r.Operation.Name {
case opModifyNetworkInterfaceAttribute:
fallthrough
case opAssignPrivateIpAddresses:
return customRetryRule(r)
default:
return d.DefaultRetryer.RetryRules(r)
}
}
func customRetryRule(r *request.Request) time.Duration {
retryTimes := []time.Duration{
time.Second,
3 * time.Second,
5 * time.Second,
}
count := r.RetryCount
if count >= len(retryTimes) {
count = len(retryTimes) - 1
}
minTime := int(retryTimes[count])
return time.Duration(sdkrand.SeededRand.Intn(minTime) + minTime)
}
func setCustomRetryer(c *client.Client) {
maxRetries := aws.IntValue(c.Config.MaxRetries)
if c.Config.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries {
maxRetries = 3
}
c.Retryer = retryer{
DefaultRetryer: client.DefaultRetryer{
NumMaxRetries: maxRetries,
},
}
}
func init() { func init() {
initClient = func(c *client.Client) {
if c.Config.Retryer == nil {
// Only override the retryer with a custom one if the config
// does not already contain a retryer
setCustomRetryer(c)
}
}
initRequest = func(r *request.Request) { initRequest = func(r *request.Request) {
if r.Operation.Name == opCopySnapshot { // fill the PresignedURL parameter if r.Operation.Name == opCopySnapshot { // fill the PresignedURL parameter
r.Handlers.Build.PushFront(fillPresignedURL) r.Handlers.Build.PushFront(fillPresignedURL)
......
...@@ -4,9 +4,8 @@ ...@@ -4,9 +4,8 @@
// requests to Amazon Elastic Compute Cloud. // requests to Amazon Elastic Compute Cloud.
// //
// Amazon Elastic Compute Cloud (Amazon EC2) provides resizable computing capacity // Amazon Elastic Compute Cloud (Amazon EC2) provides resizable computing capacity
// in the Amazon Web Services (AWS) cloud. Using Amazon EC2 eliminates your // in the AWS Cloud. Using Amazon EC2 eliminates the need to invest in hardware
// need to invest in hardware up front, so you can develop and deploy applications // up front, so you can develop and deploy applications faster.
// faster.
// //
// See https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15 for more information on this service. // See https://docs.aws.amazon.com/goto/WebAPI/ec2-2016-11-15 for more information on this service.
// //
...@@ -15,7 +14,7 @@ ...@@ -15,7 +14,7 @@
// //
// Using the Client // Using the Client
// //
// To Amazon Elastic Compute Cloud with the SDK use the New function to create // To contact Amazon Elastic Compute Cloud with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service. // a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently. // These clients are safe to use concurrently.
// //
......
...@@ -29,8 +29,9 @@ var initRequest func(*request.Request) ...@@ -29,8 +29,9 @@ var initRequest func(*request.Request)
// Service information constants // Service information constants
const ( const (
ServiceName = "ec2" // Service endpoint prefix API calls made to. ServiceName = "ec2" // Name of service.
EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "EC2" // ServiceID is a unique identifer of a specific service.
) )
// New creates a new instance of the EC2 client with a session. // New creates a new instance of the EC2 client with a session.
...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
cfg, cfg,
metadata.ClientInfo{ metadata.ClientInfo{
ServiceName: ServiceName, ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
Endpoint: endpoint, Endpoint: endpoint,
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
// Package ecr provides the client and types for making API // Package ecr provides the client and types for making API
// requests to Amazon EC2 Container Registry. // requests to Amazon EC2 Container Registry.
// //
// Amazon EC2 Container Registry (Amazon ECR) is a managed AWS Docker registry // Amazon Elastic Container Registry (Amazon ECR) is a managed Docker registry
// service. Customers can use the familiar Docker CLI to push, pull, and manage // service. Customers can use the familiar Docker CLI to push, pull, and manage
// images. Amazon ECR provides a secure, scalable, and reliable registry. Amazon // images. Amazon ECR provides a secure, scalable, and reliable registry. Amazon
// ECR supports private Docker repositories with resource-based permissions // ECR supports private Docker repositories with resource-based permissions
// using AWS IAM so that specific users or Amazon EC2 instances can access repositories // using IAM so that specific users or Amazon EC2 instances can access repositories
// and images. Developers can use the Docker CLI to author and manage images. // and images. Developers can use the Docker CLI to author and manage images.
// //
// See https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21 for more information on this service. // See https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21 for more information on this service.
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
// //
// Using the Client // Using the Client
// //
// To Amazon EC2 Container Registry with the SDK use the New function to create // To contact Amazon EC2 Container Registry with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service. // a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently. // These clients are safe to use concurrently.
// //
......
...@@ -13,8 +13,8 @@ const ( ...@@ -13,8 +13,8 @@ const (
// ErrCodeImageAlreadyExistsException for service response error code // ErrCodeImageAlreadyExistsException for service response error code
// "ImageAlreadyExistsException". // "ImageAlreadyExistsException".
// //
// The specified image has already been pushed, and there are no changes to // The specified image has already been pushed, and there were no changes to
// the manifest or image tag since the last push. // the manifest or image tag after the last push.
ErrCodeImageAlreadyExistsException = "ImageAlreadyExistsException" ErrCodeImageAlreadyExistsException = "ImageAlreadyExistsException"
// ErrCodeImageNotFoundException for service response error code // ErrCodeImageNotFoundException for service response error code
...@@ -70,13 +70,32 @@ const ( ...@@ -70,13 +70,32 @@ const (
// for this repository. // for this repository.
ErrCodeLayersNotFoundException = "LayersNotFoundException" ErrCodeLayersNotFoundException = "LayersNotFoundException"
// ErrCodeLifecyclePolicyNotFoundException for service response error code
// "LifecyclePolicyNotFoundException".
//
// The lifecycle policy could not be found, and no policy is set to the repository.
ErrCodeLifecyclePolicyNotFoundException = "LifecyclePolicyNotFoundException"
// ErrCodeLifecyclePolicyPreviewInProgressException for service response error code
// "LifecyclePolicyPreviewInProgressException".
//
// The previous lifecycle policy preview request has not completed. Please try
// again later.
ErrCodeLifecyclePolicyPreviewInProgressException = "LifecyclePolicyPreviewInProgressException"
// ErrCodeLifecyclePolicyPreviewNotFoundException for service response error code
// "LifecyclePolicyPreviewNotFoundException".
//
// There is no dry run for this repository.
ErrCodeLifecyclePolicyPreviewNotFoundException = "LifecyclePolicyPreviewNotFoundException"
// ErrCodeLimitExceededException for service response error code // ErrCodeLimitExceededException for service response error code
// "LimitExceededException". // "LimitExceededException".
// //
// The operation did not succeed because it would have exceeded a service limit // The operation did not succeed because it would have exceeded a service limit
// for your account. For more information, see Amazon ECR Default Service Limits // for your account. For more information, see Amazon ECR Default Service Limits
// (http://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html) // (http://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html)
// in the Amazon EC2 Container Registry User Guide. // in the Amazon Elastic Container Registry User Guide.
ErrCodeLimitExceededException = "LimitExceededException" ErrCodeLimitExceededException = "LimitExceededException"
// ErrCodeRepositoryAlreadyExistsException for service response error code // ErrCodeRepositoryAlreadyExistsException for service response error code
......
...@@ -29,8 +29,9 @@ var initRequest func(*request.Request) ...@@ -29,8 +29,9 @@ var initRequest func(*request.Request)
// Service information constants // Service information constants
const ( const (
ServiceName = "ecr" // Service endpoint prefix API calls made to. ServiceName = "ecr" // Name of service.
EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "ECR" // ServiceID is a unique identifer of a specific service.
) )
// New creates a new instance of the ECR client with a session. // New creates a new instance of the ECR client with a session.
...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
cfg, cfg,
metadata.ClientInfo{ metadata.ClientInfo{
ServiceName: ServiceName, ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
Endpoint: endpoint, Endpoint: endpoint,
......
...@@ -3,27 +3,22 @@ ...@@ -3,27 +3,22 @@
// Package elb provides the client and types for making API // Package elb provides the client and types for making API
// requests to Elastic Load Balancing. // requests to Elastic Load Balancing.
// //
// A load balancer distributes incoming traffic across your EC2 instances. This // A load balancer can distribute incoming traffic across your EC2 instances.
// enables you to increase the availability of your application. The load balancer // This enables you to increase the availability of your application. The load
// also monitors the health of its registered instances and ensures that it // balancer also monitors the health of its registered instances and ensures
// routes traffic only to healthy instances. You configure your load balancer // that it routes traffic only to healthy instances. You configure your load
// to accept incoming traffic by specifying one or more listeners, which are // balancer to accept incoming traffic by specifying one or more listeners,
// configured with a protocol and port number for connections from clients to // which are configured with a protocol and port number for connections from
// the load balancer and a protocol and port number for connections from the // clients to the load balancer and a protocol and port number for connections
// load balancer to the instances. // from the load balancer to the instances.
// //
// Elastic Load Balancing supports two types of load balancers: Classic Load // Elastic Load Balancing supports three types of load balancers: Application
// Balancers and Application Load Balancers (new). A Classic Load Balancer makes // Load Balancers, Network Load Balancers, and Classic Load Balancers. You can
// routing and load balancing decisions either at the transport layer (TCP/SSL) // select a load balancer based on your application needs. For more information,
// or the application layer (HTTP/HTTPS), and supports either EC2-Classic or // see the Elastic Load Balancing User Guide (http://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/).
// a VPC. An Application Load Balancer makes routing and load balancing decisions
// at the application layer (HTTP/HTTPS), supports path-based routing, and can
// route requests to one or more ports on each EC2 instance or container instance
// in your virtual private cloud (VPC). For more information, see the Elastic
// Load Balancing User Guide (http://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/what-is-load-balancing.html).
// //
// This reference covers the 2012-06-01 API, which supports Classic Load Balancers. // This reference covers the 2012-06-01 API, which supports Classic Load Balancers.
// The 2015-12-01 API supports Application Load Balancers. // The 2015-12-01 API supports Application Load Balancers and Network Load Balancers.
// //
// To get started, create a load balancer with one or more listeners using CreateLoadBalancer. // To get started, create a load balancer with one or more listeners using CreateLoadBalancer.
// Register your instances with the load balancer using RegisterInstancesWithLoadBalancer. // Register your instances with the load balancer using RegisterInstancesWithLoadBalancer.
...@@ -39,7 +34,7 @@ ...@@ -39,7 +34,7 @@
// //
// Using the Client // Using the Client
// //
// To Elastic Load Balancing with the SDK use the New function to create // To contact Elastic Load Balancing with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service. // a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently. // These clients are safe to use concurrently.
// //
......
...@@ -91,6 +91,12 @@ const ( ...@@ -91,6 +91,12 @@ const (
// The specified load balancer attribute does not exist. // The specified load balancer attribute does not exist.
ErrCodeLoadBalancerAttributeNotFoundException = "LoadBalancerAttributeNotFound" ErrCodeLoadBalancerAttributeNotFoundException = "LoadBalancerAttributeNotFound"
// ErrCodeOperationNotPermittedException for service response error code
// "OperationNotPermitted".
//
// This operation is not allowed.
ErrCodeOperationNotPermittedException = "OperationNotPermitted"
// ErrCodePolicyNotFoundException for service response error code // ErrCodePolicyNotFoundException for service response error code
// "PolicyNotFound". // "PolicyNotFound".
// //
......
...@@ -29,8 +29,9 @@ var initRequest func(*request.Request) ...@@ -29,8 +29,9 @@ var initRequest func(*request.Request)
// Service information constants // Service information constants
const ( const (
ServiceName = "elasticloadbalancing" // Service endpoint prefix API calls made to. ServiceName = "elasticloadbalancing" // Name of service.
EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "Elastic Load Balancing" // ServiceID is a unique identifer of a specific service.
) )
// New creates a new instance of the ELB client with a session. // New creates a new instance of the ELB client with a session.
...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
cfg, cfg,
metadata.ClientInfo{ metadata.ClientInfo{
ServiceName: ServiceName, ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
Endpoint: endpoint, Endpoint: endpoint,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
// //
// Using the Client // Using the Client
// //
// To Elastic Load Balancing with the SDK use the New function to create // To contact Elastic Load Balancing with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service. // a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently. // These clients are safe to use concurrently.
// //
......
...@@ -65,6 +65,12 @@ const ( ...@@ -65,6 +65,12 @@ const (
// The requested configuration is not valid. // The requested configuration is not valid.
ErrCodeInvalidConfigurationRequestException = "InvalidConfigurationRequest" ErrCodeInvalidConfigurationRequestException = "InvalidConfigurationRequest"
// ErrCodeInvalidLoadBalancerActionException for service response error code
// "InvalidLoadBalancerAction".
//
// The requested action is not valid.
ErrCodeInvalidLoadBalancerActionException = "InvalidLoadBalancerAction"
// ErrCodeInvalidSchemeException for service response error code // ErrCodeInvalidSchemeException for service response error code
// "InvalidScheme". // "InvalidScheme".
// //
...@@ -86,8 +92,8 @@ const ( ...@@ -86,8 +92,8 @@ const (
// ErrCodeInvalidTargetException for service response error code // ErrCodeInvalidTargetException for service response error code
// "InvalidTarget". // "InvalidTarget".
// //
// The specified target does not exist or is not in the same VPC as the target // The specified target does not exist, is not in the same VPC as the target
// group. // group, or has an unsupported instance type.
ErrCodeInvalidTargetException = "InvalidTarget" ErrCodeInvalidTargetException = "InvalidTarget"
// ErrCodeListenerNotFoundException for service response error code // ErrCodeListenerNotFoundException for service response error code
...@@ -150,10 +156,16 @@ const ( ...@@ -150,10 +156,16 @@ const (
// The specified target group does not exist. // The specified target group does not exist.
ErrCodeTargetGroupNotFoundException = "TargetGroupNotFound" ErrCodeTargetGroupNotFoundException = "TargetGroupNotFound"
// ErrCodeTooManyActionsException for service response error code
// "TooManyActions".
//
// You've reached the limit on the number of actions per rule.
ErrCodeTooManyActionsException = "TooManyActions"
// ErrCodeTooManyCertificatesException for service response error code // ErrCodeTooManyCertificatesException for service response error code
// "TooManyCertificates". // "TooManyCertificates".
// //
// You've reached the limit on the number of certificates per listener. // You've reached the limit on the number of certificates per load balancer.
ErrCodeTooManyCertificatesException = "TooManyCertificates" ErrCodeTooManyCertificatesException = "TooManyCertificates"
// ErrCodeTooManyListenersException for service response error code // ErrCodeTooManyListenersException for service response error code
......
...@@ -29,8 +29,9 @@ var initRequest func(*request.Request) ...@@ -29,8 +29,9 @@ var initRequest func(*request.Request)
// Service information constants // Service information constants
const ( const (
ServiceName = "elasticloadbalancing" // Service endpoint prefix API calls made to. ServiceName = "elasticloadbalancing" // Name of service.
EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "Elastic Load Balancing v2" // ServiceID is a unique identifer of a specific service.
) )
// New creates a new instance of the ELBV2 client with a session. // New creates a new instance of the ELBV2 client with a session.
...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
cfg, cfg,
metadata.ClientInfo{ metadata.ClientInfo{
ServiceName: ServiceName, ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
Endpoint: endpoint, Endpoint: endpoint,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
// //
// Using the Client // Using the Client
// //
// To AWS Key Management Service with the SDK use the New function to create // To contact AWS Key Management 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. // a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently. // These clients are safe to use concurrently.
// //
......
...@@ -28,9 +28,8 @@ const ( ...@@ -28,9 +28,8 @@ const (
// "ExpiredImportTokenException". // "ExpiredImportTokenException".
// //
// The request was rejected because the provided import token is expired. Use // The request was rejected because the provided import token is expired. Use
// GetParametersForImport to retrieve a new import token and public key, use // GetParametersForImport to get a new import token and public key, use the
// the new public key to encrypt the key material, and then try the request // new public key to encrypt the key material, and then try the request again.
// again.
ErrCodeExpiredImportTokenException = "ExpiredImportTokenException" ErrCodeExpiredImportTokenException = "ExpiredImportTokenException"
// ErrCodeIncorrectKeyMaterialException for service response error code // ErrCodeIncorrectKeyMaterialException for service response error code
...@@ -42,11 +41,11 @@ const ( ...@@ -42,11 +41,11 @@ const (
ErrCodeIncorrectKeyMaterialException = "IncorrectKeyMaterialException" ErrCodeIncorrectKeyMaterialException = "IncorrectKeyMaterialException"
// ErrCodeInternalException for service response error code // ErrCodeInternalException for service response error code
// "InternalException". // "KMSInternalException".
// //
// The request was rejected because an internal exception occurred. The request // The request was rejected because an internal exception occurred. The request
// can be retried. // can be retried.
ErrCodeInternalException = "InternalException" ErrCodeInternalException = "KMSInternalException"
// ErrCodeInvalidAliasNameException for service response error code // ErrCodeInvalidAliasNameException for service response error code
// "InvalidAliasNameException". // "InvalidAliasNameException".
...@@ -63,8 +62,9 @@ const ( ...@@ -63,8 +62,9 @@ const (
// ErrCodeInvalidCiphertextException for service response error code // ErrCodeInvalidCiphertextException for service response error code
// "InvalidCiphertextException". // "InvalidCiphertextException".
// //
// The request was rejected because the specified ciphertext has been corrupted // The request was rejected because the specified ciphertext, or additional
// or is otherwise invalid. // authenticated data incorporated into the ciphertext, such as the encryption
// context, is corrupted, missing, or otherwise invalid.
ErrCodeInvalidCiphertextException = "InvalidCiphertextException" ErrCodeInvalidCiphertextException = "InvalidCiphertextException"
// ErrCodeInvalidGrantIdException for service response error code // ErrCodeInvalidGrantIdException for service response error code
...@@ -100,7 +100,7 @@ const ( ...@@ -100,7 +100,7 @@ const (
ErrCodeInvalidMarkerException = "InvalidMarkerException" ErrCodeInvalidMarkerException = "InvalidMarkerException"
// ErrCodeInvalidStateException for service response error code // ErrCodeInvalidStateException for service response error code
// "InvalidStateException". // "KMSInvalidStateException".
// //
// The request was rejected because the state of the specified resource is not // The request was rejected because the state of the specified resource is not
// valid for this request. // valid for this request.
...@@ -108,7 +108,7 @@ const ( ...@@ -108,7 +108,7 @@ const (
// For more information about how key state affects the use of a CMK, see How // For more information about how key state affects the use of a CMK, see How
// Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html) // Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide. // in the AWS Key Management Service Developer Guide.
ErrCodeInvalidStateException = "InvalidStateException" ErrCodeInvalidStateException = "KMSInvalidStateException"
// ErrCodeKeyUnavailableException for service response error code // ErrCodeKeyUnavailableException for service response error code
// "KeyUnavailableException". // "KeyUnavailableException".
......
...@@ -29,8 +29,9 @@ var initRequest func(*request.Request) ...@@ -29,8 +29,9 @@ var initRequest func(*request.Request)
// Service information constants // Service information constants
const ( const (
ServiceName = "kms" // Service endpoint prefix API calls made to. ServiceName = "kms" // Name of service.
EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "KMS" // ServiceID is a unique identifer of a specific service.
) )
// New creates a new instance of the KMS client with a session. // New creates a new instance of the KMS client with a session.
...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
cfg, cfg,
metadata.ClientInfo{ metadata.ClientInfo{
ServiceName: ServiceName, ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
Endpoint: endpoint, Endpoint: endpoint,
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
// //
// Using the Client // Using the Client
// //
// To AWS Security Token Service with the SDK use the New function to create // To contact 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. // a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently. // These clients are safe to use concurrently.
// //
......
...@@ -29,8 +29,9 @@ var initRequest func(*request.Request) ...@@ -29,8 +29,9 @@ var initRequest func(*request.Request)
// Service information constants // Service information constants
const ( const (
ServiceName = "sts" // Service endpoint prefix API calls made to. ServiceName = "sts" // Name of service.
EndpointsID = ServiceName // Service ID for Regions and Endpoints metadata. EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "STS" // ServiceID is a unique identifer of a specific service.
) )
// New creates a new instance of the STS client with a session. // New creates a new instance of the STS client with a session.
...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio ...@@ -55,6 +56,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
cfg, cfg,
metadata.ClientInfo{ metadata.ClientInfo{
ServiceName: ServiceName, ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName, SigningName: signingName,
SigningRegion: signingRegion, SigningRegion: signingRegion,
Endpoint: endpoint, Endpoint: endpoint,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment