Update go dep (#1560)

This fix updates go dep with `dep ensure --update` as well as the following:
- Removed github.com/ugorji/go restriction in Gopkg.toml (fixes  #1557)
- Added github.com/flynn/go-shlex in Makefile (neede by Caddy, maybe removed later)

This fix fixes #1557

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang 2018-02-23 12:10:34 -08:00 committed by Miek Gieben
parent 9047bdf3a0
commit 604c0045e7
563 changed files with 107278 additions and 95314 deletions

View file

@ -1,3 +1,248 @@
Release v1.13.4 (2018-02-23)
===
### Service Client Updates
* `service/appstream`: Updates service API and documentation
* This API update is to enable customers to copy their Amazon AppStream 2.0 images within and between AWS Regions
* `aws/endpoints`: Updated Regions and Endpoints metadata.
Release v1.13.3 (2018-02-22)
===
### Service Client Updates
* `service/ce`: Updates service API and documentation
* `service/elasticloadbalancingv2`: Updates service documentation
* `aws/endpoints`: Updated Regions and Endpoints metadata.
Release v1.13.2 (2018-02-21)
===
### Service Client Updates
* `service/codecommit`: Updates service API and documentation
* This release adds an API for adding a file directly to an AWS CodeCommit repository without requiring a Git client.
* `service/ec2`: Updates service API and documentation
* Adds support for tagging an EBS snapshot as part of the API call that creates the EBS snapshot
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/serverlessrepo`: Updates service API, documentation, and paginators
Release v1.13.1 (2018-02-20)
===
### Service Client Updates
* `service/autoscaling`: Updates service API and documentation
* Amazon EC2 Auto Scaling support for service-linked roles
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/waf`: Updates service API and documentation
* The new PermissionPolicy APIs in AWS WAF Regional allow customers to attach resource-based policies to their entities.
* `service/waf-regional`: Updates service API and documentation
Release v1.13.0 (2018-02-19)
===
### Service Client Updates
* `service/config`: Updates service API
* With this release, AWS Config updated the ConfigurationItemStatus enum values. The values prior to this update did not represent appropriate values returned by GetResourceConfigHistory. You must update your code to enumerate the new enum values so this is a breaking change. To map old properties to new properties, use the following descriptions: New discovered resource - Old property: Discovered, New property: ResourceDiscovered. Updated resource - Old property: Ok, New property: OK. Deleted resource - Old property: Deleted, New property: ResourceDeleted or ResourceDeletedNotRecorded. Not-recorded resource - Old property: N/A, New property: ResourceNotRecorded or ResourceDeletedNotRecorded.
Release v1.12.79 (2018-02-16)
===
### Service Client Updates
* `service/rds`: Updates service API and documentation
* Updates RDS API to indicate whether a DBEngine supports read replicas.
Release v1.12.78 (2018-02-15)
===
### Service Client Updates
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/gamelift`: Updates service API and documentation
* Updates to allow Fleets to run on On-Demand or Spot instances.
* `service/mediaconvert`: Updates service API and documentation
* Nielsen ID3 tags can now be inserted into transport stream (TS) and HLS outputs. For more information on Nielsen configuration you can go to https://docs.aws.amazon.com/mediaconvert/latest/apireference/jobs.html#jobs-nielsenconfiguration
Release v1.12.77 (2018-02-14)
===
### Service Client Updates
* `service/appsync`: Updates service API and documentation
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/lex-models`: Updates service API and documentation
Release v1.12.76 (2018-02-13)
===
### Service Client Updates
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/glacier`: Updates service documentation
* Documentation updates for glacier
* `service/route53`: Updates service API
* Added support for creating Private Hosted Zones and metric-based healthchecks in the ap-northeast-3 region for whitelisted customers.
Release v1.12.75 (2018-02-12)
===
### Service Client Updates
* `service/cognito-idp`: Updates service API and documentation
* `service/ec2`: Updates service API and documentation
* Network interfaces now supply the following additional status of "associated" to better distinguish the current status.
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/guardduty`: Updates service API and documentation
* Added PortProbeAction information to the Action section of the port probe-type finding.
* `service/kms`: Updates service API
* This release of AWS Key Management Service includes support for InvalidArnException in the RetireGrant API.
* `service/rds`: Updates service documentation
* Aurora MySQL now supports MySQL 5.7.
Release v1.12.74 (2018-02-09)
===
### Service Client Updates
* `service/ec2`: Updates service API and documentation
* Users can now better understand the longer ID opt-in status of their account using the two new APIs DescribeAggregateIdFormat and DescribePrincipalIdFormat
* `service/lex-models`: Updates service API and documentation
* `service/runtime.lex`: Updates service API and documentation
Release v1.12.73 (2018-02-08)
===
### Service Client Updates
* `service/appstream`: Updates service API and documentation
* Adds support for allowing customers to provide a redirect URL for a stack. Users will be redirected to the link provided by the admin at the end of their streaming session.
* `service/budgets`: Updates service API and documentation
* Making budgetLimit and timePeriod optional, and updating budgets docs.
* `service/dms`: Updates service API, documentation, and paginators
* This release includes the addition of two new APIs: describe replication instance task logs and reboot instance. The first allows user to see how much storage each log for a task on a given instance is occupying. The second gives users the option to reboot the application software on the instance and force a fail over for MAZ instances to test robustness of their integration with our service.
* `service/ds`: Updates service API
* Updated the regex of some input parameters to support longer EC2 identifiers.
* `service/dynamodb`: Updates service API and documentation
* Amazon DynamoDB now supports server-side encryption using a default service key (alias/aws/dynamodb) from the AWS Key Management Service (KMS). AWS KMS is a service that combines secure, highly available hardware and software to provide a key management system scaled for the cloud. AWS KMS is used via the AWS Management Console or APIs to centrally create encryption keys, define the policies that control how keys can be used, and audit key usage to prove they are being used correctly. For more information, see the Amazon DynamoDB Developer Guide.
* `service/gamelift`: Updates service API and documentation
* Amazon GameLift FlexMatch added the StartMatchBackfill API. This API allows developers to add new players to an existing game session using the same matchmaking rules and player data that were used to initially create the session.
* `service/medialive`: Updates service API and documentation
* AWS Elemental MediaLive has added support for updating channel settings for idle channels. You can now update channel name, channel outputs and output destinations, encoder settings, user role ARN, and input specifications. Channel settings can be updated in the console or with API calls. Please note that running channels need to be stopped before they can be updated. We've also deprecated the 'Reserved' field.
* `service/mediastore`: Updates service API and documentation
* AWS Elemental MediaStore now supports per-container CORS configuration.
Release v1.12.72 (2018-02-07)
===
### Service Client Updates
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/glue`: Updates service API and documentation
* This new feature will now allow customers to add a customized json classifier. They can specify a json path to indicate the object, array or field of the json documents they'd like crawlers to inspect when they crawl json files.
* `service/servicecatalog`: Updates service API, documentation, and paginators
* This release of Service Catalog adds SearchProvisionedProducts API and ProvisionedProductPlan APIs.
* `service/servicediscovery`: Updates service API and documentation
* This release adds support for registering CNAME record types and creating Route 53 alias records that route traffic to Amazon Elastic Load Balancers using Amazon Route 53 Auto Naming APIs.
* `service/ssm`: Updates service API and documentation
* This Patch Manager release supports configuring Linux repos as part of patch baselines, controlling updates of non-OS security packages and also creating patch baselines for SUSE12
### SDK Enhancements
* `private/model/api`: Add validation to ensure there is no duplication of services in models/apis ([#1758](https://github.com/aws/aws-sdk-go/pull/1758))
* Prevents the SDK from mistakenly generating code a single service multiple times with different model versions.
* `example/service/ec2/instancesbyRegion`: Fix typos in example ([#1762](https://github.com/aws/aws-sdk-go/pull/1762))
* `private/model/api`: removing SDK API reference crosslinks from input/output shapes. (#1765)
### SDK Bugs
* `aws/session`: Fix bug in session.New not supporting AWS_SDK_LOAD_CONFIG ([#1770](https://github.com/aws/aws-sdk-go/pull/1770))
* Fixes a bug in the session.New function that was not correctly sourcing the shared configuration files' path.
* Fixes [#1771](https://github.com/aws/aws-sdk-go/pull/1771)
Release v1.12.71 (2018-02-05)
===
### Service Client Updates
* `service/acm`: Updates service documentation
* Documentation updates for acm
* `service/cloud9`: Updates service documentation and examples
* API usage examples for AWS Cloud9.
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/kinesis`: Updates service API and documentation
* Using ListShards a Kinesis Data Streams customer or client can get information about shards in a data stream (including meta-data for each shard) without obtaining data stream level information.
* `service/opsworks`: Updates service API, documentation, and waiters
* AWS OpsWorks Stacks supports EBS encryption and HDD volume types. Also, a new DescribeOperatingSystems API is available, which lists all operating systems supported by OpsWorks Stacks.
Release v1.12.70 (2018-01-26)
===
### Service Client Updates
* `service/devicefarm`: Updates service API and documentation
* Add InteractionMode in CreateRemoteAccessSession for DirectDeviceAccess feature.
* `service/medialive`: Updates service API and documentation
* Add InputSpecification to CreateChannel (specification of input attributes is used for channel sizing and affects pricing); add NotFoundException to DeleteInputSecurityGroups.
* `service/mturk-requester`: Updates service documentation
Release v1.12.69 (2018-01-26)
===
### SDK Bugs
* `models/api`: Fix colliding names [#1754](https://github.com/aws/aws-sdk-go/pull/1754) [#1756](https://github.com/aws/aws-sdk-go/pull/1756)
* SDK had duplicate folders that were causing errors in some builds.
* Fixes [#1753](https://github.com/aws/aws-sdk-go/issues/1753)
Release v1.12.68 (2018-01-25)
===
### Service Client Updates
* `service/alexaforbusiness`: Updates service API and documentation
* `service/codebuild`: Updates service API and documentation
* Adding support for Shallow Clone and GitHub Enterprise in AWS CodeBuild.
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/guardduty`: Adds new service
* Added the missing AccessKeyDetails object to the resource shape.
* `service/lambda`: Updates service API and documentation
* AWS Lambda now supports Revision ID on your function versions and aliases, to track and apply conditional updates when you are updating your function version or alias resources.
### SDK Bugs
* `service/s3/s3manager`: Fix check for nil OrigErr in Error() [#1749](https://github.com/aws/aws-sdk-go/issues/1749)
* S3 Manager's `Error` type did not check for nil of `OrigErr` when calling `Error()`
* Fixes [#1748](https://github.com/aws/aws-sdk-go/issues/1748)
Release v1.12.67 (2018-01-22)
===
### Service Client Updates
* `service/budgets`: Updates service API and documentation
* Add additional costTypes: IncludeDiscount, UseAmortized, to support finer control for different charges included in a cost budget.
Release v1.12.66 (2018-01-19)
===
### Service Client Updates
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/glue`: Updates service API and documentation
* New AWS Glue DataCatalog APIs to manage table versions and a new feature to skip archiving of the old table version when updating table.
* `service/transcribe`: Adds new service
Release v1.12.65 (2018-01-18)
===
### Service Client Updates
* `service/sagemaker`: Updates service API and documentation
* CreateTrainingJob and CreateEndpointConfig now supports KMS Key for volume encryption.
Release v1.12.64 (2018-01-17)
===
### Service Client Updates
* `service/autoscaling-plans`: Updates service documentation
* `service/ec2`: Updates service documentation
* Documentation updates for EC2
Release v1.12.63 (2018-01-17)
===
### Service Client Updates
* `service/application-autoscaling`: Updates service API and documentation
* `service/autoscaling-plans`: Adds new service
* `service/rds`: Updates service API and documentation
* With this release you can now integrate RDS DB instances with CloudWatch Logs. We have added parameters to the operations for creating and modifying DB instances (for example CreateDBInstance) to allow you to take advantage of this capability through the CLI and API. Once you enable this feature, a stream of log events will publish to CloudWatch Logs for each log type you enable.
Release v1.12.62 (2018-01-15)
===
### Service Client Updates
* `aws/endpoints`: Updated Regions and Endpoints metadata.
* `service/lambda`: Updates service API and documentation
* Support for creating Lambda Functions using 'dotnetcore2.0' and 'go1.x'.
Release v1.12.61 (2018-01-12)
===

View file

@ -1,12 +1,11 @@
package client
import (
"math/rand"
"strconv"
"sync"
"time"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/internal/sdkrand"
)
// DefaultRetryer implements basic retry logic using exponential backoff for
@ -31,8 +30,6 @@ func (d DefaultRetryer) MaxRetries() int {
return d.NumMaxRetries
}
var seededRand = rand.New(&lockedSource{src: rand.NewSource(time.Now().UnixNano())})
// RetryRules returns the delay duration before retrying this request again
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
// Set the upper limit of delay in retrying at ~five minutes
@ -53,7 +50,7 @@ func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
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
}
@ -117,22 +114,3 @@ func canUseRetryAfterHeader(r *request.Request) bool {
return true
}
// lockedSource is a thread-safe implementation of rand.Source
type lockedSource struct {
lk sync.Mutex
src rand.Source
}
func (r *lockedSource) Int63() (n int64) {
r.lk.Lock()
n = r.src.Int63()
r.lk.Unlock()
return
}
func (r *lockedSource) Seed(seed int64) {
r.lk.Lock()
r.src.Seed(seed)
r.lk.Unlock()
}

View file

@ -46,6 +46,7 @@ func (reader *teeReaderCloser) Close() error {
func logRequest(r *request.Request) {
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
bodySeekable := aws.IsReaderSeekable(r.Body)
dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody)
if err != nil {
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err))
@ -53,6 +54,9 @@ func logRequest(r *request.Request) {
}
if logBody {
if !bodySeekable {
r.SetReaderBody(aws.ReadSeekCloser(r.HTTPRequest.Body))
}
// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
// Body as a NoOpCloser and will not be reset after read by the HTTP
// client reader.

View file

@ -2,8 +2,17 @@ package client
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"reflect"
"testing"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/request"
)
type mockCloser struct {
@ -55,3 +64,81 @@ func TestLogWriter(t *testing.T) {
t.Errorf("Expected %q, but received %q", expected, lw.buf.String())
}
}
func TestLogRequest(t *testing.T) {
cases := []struct {
Body io.ReadSeeker
ExpectBody []byte
LogLevel aws.LogLevelType
}{
{
Body: aws.ReadSeekCloser(bytes.NewBuffer([]byte("body content"))),
ExpectBody: []byte("body content"),
},
{
Body: aws.ReadSeekCloser(bytes.NewBuffer([]byte("body content"))),
LogLevel: aws.LogDebugWithHTTPBody,
ExpectBody: []byte("body content"),
},
{
Body: bytes.NewReader([]byte("body content")),
ExpectBody: []byte("body content"),
},
{
Body: bytes.NewReader([]byte("body content")),
LogLevel: aws.LogDebugWithHTTPBody,
ExpectBody: []byte("body content"),
},
}
for i, c := range cases {
logW := bytes.NewBuffer(nil)
req := request.New(
aws.Config{
Credentials: credentials.AnonymousCredentials,
Logger: &bufLogger{w: logW},
LogLevel: aws.LogLevel(c.LogLevel),
},
metadata.ClientInfo{
Endpoint: "https://mock-service.mock-region.amazonaws.com",
},
testHandlers(),
nil,
&request.Operation{
Name: "APIName",
HTTPMethod: "POST",
HTTPPath: "/",
},
struct{}{}, nil,
)
req.SetReaderBody(c.Body)
req.Build()
logRequest(req)
b, err := ioutil.ReadAll(req.HTTPRequest.Body)
if err != nil {
t.Fatalf("%d, expect to read SDK request Body", i)
}
if e, a := c.ExpectBody, b; !reflect.DeepEqual(e, a) {
t.Errorf("%d, expect %v body, got %v", i, e, a)
}
}
}
type bufLogger struct {
w *bytes.Buffer
}
func (l *bufLogger) Log(args ...interface{}) {
fmt.Fprintln(l.w, args...)
}
func testHandlers() request.Handlers {
var handlers request.Handlers
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
return handlers
}

View file

@ -3,7 +3,6 @@ package corehandlers
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
@ -36,18 +35,13 @@ var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLen
if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
length, _ = strconv.ParseInt(slength, 10, 64)
} else {
switch body := r.Body.(type) {
case nil:
length = 0
case lener:
length = int64(body.Len())
case io.Seeker:
r.BodyStart, _ = body.Seek(0, 1)
end, _ := body.Seek(0, 2)
body.Seek(r.BodyStart, 0) // make sure to seek back to original location
length = end - r.BodyStart
default:
panic("Cannot get length of body, must provide `ContentLength`")
if r.Body != nil {
var err error
length, err = aws.SeekerLen(r.Body)
if err != nil {
r.Error = awserr.New(request.ErrCodeSerialization, "failed to get request body's length", err)
return
}
}
}

View file

@ -1,5 +1,10 @@
// Package ec2metadata provides the client for making API calls to the
// EC2 Metadata service.
//
// This package's client can be disabled completely by setting the environment
// variable "AWS_EC2_METADATA_DISABLED=true". This environment variable set to
// true instructs the SDK to disable the EC2 Metadata client. The client cannot
// be used while the environemnt variable is set to true, (case insensitive).
package ec2metadata
import (
@ -7,17 +12,21 @@ import (
"errors"
"io"
"net/http"
"os"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/request"
)
// ServiceName is the name of the service.
const ServiceName = "ec2metadata"
const disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED"
// A EC2Metadata is an EC2 Metadata service Client.
type EC2Metadata struct {
@ -75,6 +84,21 @@ func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio
svc.Handlers.Validate.Clear()
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
for _, option := range opts {
option(svc.Client)

View file

@ -3,21 +3,30 @@ package ec2metadata_test
import (
"net/http"
"net/http/httptest"
"os"
"strings"
"sync"
"testing"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/awstesting"
"github.com/aws/aws-sdk-go/awstesting/unit"
"github.com/stretchr/testify/assert"
)
func TestClientOverrideDefaultHTTPClientTimeout(t *testing.T) {
svc := ec2metadata.New(unit.Session)
assert.NotEqual(t, http.DefaultClient, svc.Config.HTTPClient)
assert.Equal(t, 5*time.Second, svc.Config.HTTPClient.Timeout)
if e, a := http.DefaultClient, svc.Config.HTTPClient; e == a {
t.Errorf("expect %v, not to equal %v", e, a)
}
if e, a := 5*time.Second, svc.Config.HTTPClient.Timeout; e != a {
t.Errorf("expect %v to be %v", e, a)
}
}
func TestClientNotOverrideDefaultHTTPClientTimeout(t *testing.T) {
@ -28,18 +37,25 @@ func TestClientNotOverrideDefaultHTTPClientTimeout(t *testing.T) {
svc := ec2metadata.New(unit.Session)
assert.Equal(t, http.DefaultClient, svc.Config.HTTPClient)
if e, a := http.DefaultClient, svc.Config.HTTPClient; e != a {
t.Errorf("expect %v, got %v", e, a)
}
tr, ok := svc.Config.HTTPClient.Transport.(*http.Transport)
assert.True(t, ok)
assert.NotNil(t, tr)
assert.Nil(t, tr.Dial)
tr := svc.Config.HTTPClient.Transport.(*http.Transport)
if tr == nil {
t.Fatalf("expect transport not to be nil")
}
if tr.Dial != nil {
t.Errorf("expect dial to be nil, was not")
}
}
func TestClientDisableOverrideDefaultHTTPClientTimeout(t *testing.T) {
svc := ec2metadata.New(unit.Session, aws.NewConfig().WithEC2MetadataDisableTimeoutOverride(true))
assert.Equal(t, http.DefaultClient, svc.Config.HTTPClient)
if e, a := http.DefaultClient, svc.Config.HTTPClient; e != a {
t.Errorf("expect %v, got %v", e, a)
}
}
func TestClientOverrideDefaultHTTPClientTimeoutRace(t *testing.T) {
@ -63,6 +79,30 @@ func TestClientOverrideDefaultHTTPClientTimeoutRaceWithTransport(t *testing.T) {
runEC2MetadataClients(t, cfg, 100)
}
func TestClientDisableIMDS(t *testing.T) {
env := awstesting.StashEnv()
defer awstesting.PopEnv(env)
os.Setenv("AWS_EC2_METADATA_DISABLED", "true")
svc := ec2metadata.New(unit.Session)
resp, err := svc.Region()
if err == nil {
t.Fatalf("expect error, got none")
}
if len(resp) != 0 {
t.Errorf("expect no response, got %v", resp)
}
aerr := err.(awserr.Error)
if e, a := request.CanceledErrorCode, aerr.Code(); e != a {
t.Errorf("expect %v error code, got %v", e, a)
}
if e, a := "AWS_EC2_METADATA_DISABLED", aerr.Message(); !strings.Contains(a, e) {
t.Errorf("expect %v in error message, got %v", e, a)
}
}
func runEC2MetadataClients(t *testing.T, cfg *aws.Config, atOnce int) {
var wg sync.WaitGroup
wg.Add(atOnce)
@ -70,7 +110,9 @@ func runEC2MetadataClients(t *testing.T, cfg *aws.Config, atOnce int) {
go func() {
svc := ec2metadata.New(unit.Session, cfg)
_, err := svc.Region()
assert.NoError(t, err)
if err != nil {
t.Fatalf("expect no error, got %v", err)
}
wg.Done()
}()
}

View file

@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"io"
"os"
"github.com/aws/aws-sdk-go/aws/awserr"
)
@ -84,11 +85,34 @@ func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resol
custAddEC2Metadata(p)
custAddS3DualStack(p)
custRmIotDataService(p)
custFixCloudHSMv2SigningName(p)
}
return ps, nil
}
func custFixCloudHSMv2SigningName(p *partition) {
// Workaround for aws/aws-sdk-go#1745 until the endpoint model can be
// fixed upstream. TODO remove this once the endpoints model is updated.
s, ok := p.Services["cloudhsmv2"]
if !ok {
return
}
if len(s.Defaults.CredentialScope.Service) != 0 {
fmt.Fprintf(os.Stderr, "cloudhsmv2 signing name already set, ignoring override.\n")
// If the value is already set don't override
return
}
s.Defaults.CredentialScope.Service = "cloudhsm"
fmt.Fprintf(os.Stderr, "cloudhsmv2 signing name not set, overriding.\n")
p.Services["cloudhsmv2"] = s
}
func custAddS3DualStack(p *partition) {
if p.ID != "aws" {
return

View file

@ -115,3 +115,126 @@ func TestDecodeModelOptionsSet(t *testing.T) {
t.Errorf("expect %v options got %v", expect, actual)
}
}
func TestDecode_CustFixCloudHSMv2SigningName(t *testing.T) {
cases := []struct {
Doc string
Expect string
}{
{
Doc: `
{
"version": 3,
"partitions": [
{
"defaults": {
"hostname": "{service}.{region}.{dnsSuffix}",
"protocols": [
"https"
],
"signatureVersions": [
"v4"
]
},
"dnsSuffix": "amazonaws.com",
"partition": "aws",
"partitionName": "AWS Standard",
"regionRegex": "^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$",
"regions": {
"ap-northeast-1": {
"description": "Asia Pacific (Tokyo)"
},
"us-east-1": {
"description": "US East (N. Virginia)"
}
},
"services": {
"cloudhsmv2": {
"endpoints": {
"us-east-1": {}
}
},
"s3": {
"endpoints": {
"ap-northeast-1": {}
}
}
}
}
]
}`,
Expect: "cloudhsm",
},
{
Doc: `
{
"version": 3,
"partitions": [
{
"defaults": {
"hostname": "{service}.{region}.{dnsSuffix}",
"protocols": [
"https"
],
"signatureVersions": [
"v4"
]
},
"dnsSuffix": "amazonaws.com",
"partition": "aws",
"partitionName": "AWS Standard",
"regionRegex": "^(us|eu|ap|sa|ca)\\-\\w+\\-\\d+$",
"regions": {
"ap-northeast-1": {
"description": "Asia Pacific (Tokyo)"
},
"us-east-1": {
"description": "US East (N. Virginia)"
}
},
"services": {
"cloudhsmv2": {
"defaults": {
"credentialScope": {
"service": "coolSigningName"
}
},
"endpoints": {
"us-east-1": {}
}
},
"s3": {
"endpoints": {
"ap-northeast-1": {}
}
}
}
}
]
}`,
Expect: "coolSigningName",
},
}
for i, c := range cases {
resolver, err := DecodeModel(strings.NewReader(c.Doc))
if err != nil {
t.Fatalf("%d, expected no error, got %v", i, err)
}
p := resolver.(partitions)[0]
defaults := p.Services["cloudhsmv2"].Defaults
if e, a := c.Expect, defaults.CredentialScope.Service; e != a {
t.Errorf("%d, expect %v, got %v", i, e, a)
}
endpoint, err := resolver.EndpointFor("cloudhsmv2", "us-east-1")
if err != nil {
t.Fatalf("%d, failed to resolve endpoint, %v", i, err)
}
if e, a := c.Expect, endpoint.SigningName; e != a {
t.Errorf("%d, expected %q go %q", i, e, a)
}
}
}

View file

@ -52,6 +52,7 @@ const (
Appstream2ServiceID = "appstream2" // Appstream2.
AthenaServiceID = "athena" // Athena.
AutoscalingServiceID = "autoscaling" // Autoscaling.
AutoscalingPlansServiceID = "autoscaling-plans" // AutoscalingPlans.
BatchServiceID = "batch" // Batch.
BudgetsServiceID = "budgets" // Budgets.
ClouddirectoryServiceID = "clouddirectory" // Clouddirectory.
@ -105,12 +106,16 @@ const (
IotServiceID = "iot" // Iot.
KinesisServiceID = "kinesis" // Kinesis.
KinesisanalyticsServiceID = "kinesisanalytics" // Kinesisanalytics.
KinesisvideoServiceID = "kinesisvideo" // Kinesisvideo.
KmsServiceID = "kms" // Kms.
LambdaServiceID = "lambda" // Lambda.
LightsailServiceID = "lightsail" // Lightsail.
LogsServiceID = "logs" // Logs.
MachinelearningServiceID = "machinelearning" // Machinelearning.
MarketplacecommerceanalyticsServiceID = "marketplacecommerceanalytics" // Marketplacecommerceanalytics.
MediaconvertServiceID = "mediaconvert" // Mediaconvert.
MedialiveServiceID = "medialive" // Medialive.
MediapackageServiceID = "mediapackage" // Mediapackage.
MeteringMarketplaceServiceID = "metering.marketplace" // MeteringMarketplace.
MghServiceID = "mgh" // Mgh.
MobileanalyticsServiceID = "mobileanalytics" // Mobileanalytics.
@ -131,6 +136,7 @@ const (
S3ServiceID = "s3" // S3.
SdbServiceID = "sdb" // Sdb.
ServicecatalogServiceID = "servicecatalog" // Servicecatalog.
ServicediscoveryServiceID = "servicediscovery" // Servicediscovery.
ShieldServiceID = "shield" // Shield.
SmsServiceID = "sms" // Sms.
SnowballServiceID = "snowball" // Snowball.
@ -370,6 +376,22 @@ var awsPartition = partition{
"us-west-2": endpoint{},
},
},
"autoscaling-plans": service{
Defaults: endpoint{
Hostname: "autoscaling.{region}.amazonaws.com",
Protocols: []string{"http", "https"},
CredentialScope: credentialScope{
Service: "autoscaling-plans",
},
},
Endpoints: endpoints{
"ap-southeast-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
"batch": service{
Endpoints: endpoints{
@ -402,6 +424,7 @@ var awsPartition = partition{
Endpoints: endpoints{
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"us-east-1": endpoint{},
@ -459,7 +482,11 @@ var awsPartition = partition{
},
},
"cloudhsmv2": service{
Defaults: endpoint{
CredentialScope: credentialScope{
Service: "cloudhsm",
},
},
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-south-1": endpoint{},
@ -577,6 +604,7 @@ var awsPartition = partition{
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
@ -588,6 +616,7 @@ var awsPartition = partition{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-northeast-2": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
@ -689,6 +718,8 @@ var awsPartition = partition{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-west-1": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
@ -740,6 +771,7 @@ var awsPartition = partition{
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"sa-east-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
@ -1043,10 +1075,13 @@ var awsPartition = partition{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
},
},
@ -1093,10 +1128,11 @@ var awsPartition = partition{
"glue": service{
Endpoints: endpoints{
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
"ap-northeast-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
"greengrass": service{
@ -1156,6 +1192,7 @@ var awsPartition = partition{
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
},
@ -1207,6 +1244,16 @@ var awsPartition = partition{
"us-west-2": endpoint{},
},
},
"kinesisvideo": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-west-2": endpoint{},
},
},
"kms": service{
Endpoints: endpoints{
@ -1295,6 +1342,44 @@ var awsPartition = partition{
"us-east-1": endpoint{},
},
},
"mediaconvert": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-west-1": endpoint{},
"us-west-2": endpoint{},
},
},
"medialive": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-west-2": endpoint{},
},
},
"mediapackage": service{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-3": endpoint{},
"us-east-1": endpoint{},
"us-west-2": endpoint{},
},
},
"metering.marketplace": service{
Defaults: endpoint{
CredentialScope: credentialScope{
@ -1489,6 +1574,7 @@ var awsPartition = partition{
Endpoints: endpoints{
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
@ -1619,6 +1705,15 @@ var awsPartition = partition{
"us-west-2": endpoint{},
},
},
"servicediscovery": service{
Endpoints: endpoints{
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
"us-west-2": endpoint{},
},
},
"shield": service{
IsRegionalized: boxedFalse,
Defaults: endpoint{
@ -1636,8 +1731,10 @@ var awsPartition = partition{
"ap-northeast-2": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
"eu-west-3": endpoint{},
"us-east-1": endpoint{},
"us-east-2": endpoint{},
@ -1651,6 +1748,7 @@ var awsPartition = partition{
"ap-northeast-1": endpoint{},
"ap-south-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
@ -1733,7 +1831,9 @@ var awsPartition = partition{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-southeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"ca-central-1": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"eu-west-2": endpoint{},
@ -1912,6 +2012,8 @@ var awsPartition = partition{
Endpoints: endpoints{
"ap-northeast-1": endpoint{},
"ap-southeast-2": endpoint{},
"eu-central-1": endpoint{},
"eu-west-1": endpoint{},
"us-east-1": endpoint{},
"us-west-1": endpoint{},
@ -2233,6 +2335,12 @@ var awscnPartition = partition{
"cn-northwest-1": endpoint{},
},
},
"sms": service{
Endpoints: endpoints{
"cn-north-1": endpoint{},
},
},
"snowball": service{
Endpoints: endpoints{
@ -2423,6 +2531,18 @@ var awsusgovPartition = partition{
},
},
},
"ecr": service{
Endpoints: endpoints{
"us-gov-west-1": endpoint{},
},
},
"ecs": service{
Endpoints: endpoints{
"us-gov-west-1": endpoint{},
},
},
"elasticache": service{
Endpoints: endpoints{
@ -2451,6 +2571,12 @@ var awsusgovPartition = partition{
},
},
},
"es": service{
Endpoints: endpoints{
"us-gov-west-1": endpoint{},
},
},
"events": service{
Endpoints: endpoints{

View file

@ -224,6 +224,9 @@ func (r *Request) SetContext(ctx aws.Context) {
// WillRetry returns if the request's can be retried.
func (r *Request) WillRetry() bool {
if !aws.IsReaderSeekable(r.Body) && r.HTTPRequest.Body != NoBody {
return false
}
return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries()
}
@ -255,6 +258,7 @@ func (r *Request) SetStringBody(s string) {
// SetReaderBody will set the request's body reader.
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
r.Body = reader
r.BodyStart, _ = reader.Seek(0, 1) // Get the Bodies current offset.
r.ResetBody()
}
@ -393,7 +397,7 @@ func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
// of the SDK if they used that field.
//
// Related golang/go#18257
l, err := computeBodyLength(r.Body)
l, err := aws.SeekerLen(r.Body)
if err != nil {
return nil, awserr.New(ErrCodeSerialization, "failed to compute request body size", err)
}
@ -411,7 +415,8 @@ func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
// Transfer-Encoding: chunked bodies for these methods.
//
// This would only happen if a aws.ReaderSeekerCloser was used with
// a io.Reader that was not also an io.Seeker.
// a io.Reader that was not also an io.Seeker, or did not implement
// Len() method.
switch r.Operation.HTTPMethod {
case "GET", "HEAD", "DELETE":
body = NoBody
@ -423,42 +428,6 @@ func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
return body, nil
}
// Attempts to compute the length of the body of the reader using the
// io.Seeker interface. If the value is not seekable because of being
// a ReaderSeekerCloser without an unerlying Seeker -1 will be returned.
// If no error occurs the length of the body will be returned.
func computeBodyLength(r io.ReadSeeker) (int64, error) {
seekable := true
// Determine if the seeker is actually seekable. ReaderSeekerCloser
// hides the fact that a io.Readers might not actually be seekable.
switch v := r.(type) {
case aws.ReaderSeekerCloser:
seekable = v.IsSeeker()
case *aws.ReaderSeekerCloser:
seekable = v.IsSeeker()
}
if !seekable {
return -1, nil
}
curOffset, err := r.Seek(0, 1)
if err != nil {
return 0, err
}
endOffset, err := r.Seek(0, 2)
if err != nil {
return 0, err
}
_, err = r.Seek(curOffset, 0)
if err != nil {
return 0, err
}
return endOffset - curOffset, nil
}
// GetBody will return an io.ReadSeeker of the Request's underlying
// input body with a concurrency safe wrapper.
func (r *Request) GetBody() io.ReadSeeker {

View file

@ -142,13 +142,28 @@ func (r *Request) nextPageTokens() []interface{} {
tokens := []interface{}{}
tokenAdded := false
for _, outToken := range r.Operation.OutputTokens {
v, _ := awsutil.ValuesAtPath(r.Data, outToken)
if len(v) > 0 {
tokens = append(tokens, v[0])
tokenAdded = true
} else {
vs, _ := awsutil.ValuesAtPath(r.Data, outToken)
if len(vs) == 0 {
tokens = append(tokens, nil)
continue
}
v := vs[0]
switch tv := v.(type) {
case *string:
if len(aws.StringValue(tv)) == 0 {
tokens = append(tokens, nil)
continue
}
case string:
if len(tv) == 0 {
tokens = append(tokens, nil)
continue
}
}
tokenAdded = true
tokens = append(tokens, v)
}
if !tokenAdded {
return nil

View file

@ -454,78 +454,93 @@ func TestPaginationWithContextNilInput(t *testing.T) {
}
}
type testPageInput struct {
NextToken string
}
type testPageOutput struct {
Value string
NextToken *string
}
func TestPagination_Standalone(t *testing.T) {
expect := []struct {
Value, PrevToken, NextToken string
}{
{"FirstValue", "InitalToken", "FirstToken"},
{"SecondValue", "FirstToken", "SecondToken"},
{"ThirdValue", "SecondToken", ""},
type testPageInput struct {
NextToken *string
}
input := testPageInput{
NextToken: expect[0].PrevToken,
type testPageOutput struct {
Value *string
NextToken *string
}
type testCase struct {
Value, PrevToken, NextToken *string
}
c := awstesting.NewClient()
i := 0
p := request.Pagination{
NewRequest: func() (*request.Request, error) {
r := c.NewRequest(
&request.Operation{
Name: "Operation",
Paginator: &request.Paginator{
InputTokens: []string{"NextToken"},
OutputTokens: []string{"NextToken"},
},
},
&input, &testPageOutput{},
)
// Setup handlers for testing
r.Handlers.Clear()
r.Handlers.Build.PushBack(func(req *request.Request) {
in := req.Params.(*testPageInput)
if e, a := expect[i].PrevToken, in.NextToken; e != a {
t.Errorf("%d, expect NextToken input %q, got %q", i, e, a)
}
})
r.Handlers.Unmarshal.PushBack(func(req *request.Request) {
out := &testPageOutput{
Value: expect[i].Value,
}
if len(expect[i].NextToken) > 0 {
out.NextToken = aws.String(expect[i].NextToken)
}
req.Data = out
})
return r, nil
cases := [][]testCase{
{
testCase{aws.String("FirstValue"), aws.String("InitalToken"), aws.String("FirstToken")},
testCase{aws.String("SecondValue"), aws.String("FirstToken"), aws.String("SecondToken")},
testCase{aws.String("ThirdValue"), aws.String("SecondToken"), nil},
},
{
testCase{aws.String("FirstValue"), aws.String("InitalToken"), aws.String("FirstToken")},
testCase{aws.String("SecondValue"), aws.String("FirstToken"), aws.String("SecondToken")},
testCase{aws.String("ThirdValue"), aws.String("SecondToken"), aws.String("")},
},
}
for p.Next() {
data := p.Page().(*testPageOutput)
if e, a := expect[i].Value, data.Value; e != a {
t.Errorf("%d, expect Value to be %q, got %q", i, e, a)
}
if e, a := expect[i].NextToken, aws.StringValue(data.NextToken); e != a {
t.Errorf("%d, expect NextToken to be %q, got %q", i, e, a)
for _, c := range cases {
input := testPageInput{
NextToken: c[0].PrevToken,
}
i++
}
if e, a := len(expect), i; e != a {
t.Errorf("expected to process %d pages, did %d", e, a)
}
if err := p.Err(); err != nil {
t.Fatalf("%d, expected no error, got %v", i, err)
svc := awstesting.NewClient()
i := 0
p := request.Pagination{
NewRequest: func() (*request.Request, error) {
r := svc.NewRequest(
&request.Operation{
Name: "Operation",
Paginator: &request.Paginator{
InputTokens: []string{"NextToken"},
OutputTokens: []string{"NextToken"},
},
},
&input, &testPageOutput{},
)
// Setup handlers for testing
r.Handlers.Clear()
r.Handlers.Build.PushBack(func(req *request.Request) {
if e, a := len(c), i+1; a > e {
t.Fatalf("expect no more than %d requests, got %d", e, a)
}
in := req.Params.(*testPageInput)
if e, a := aws.StringValue(c[i].PrevToken), aws.StringValue(in.NextToken); e != a {
t.Errorf("%d, expect NextToken input %q, got %q", i, e, a)
}
})
r.Handlers.Unmarshal.PushBack(func(req *request.Request) {
out := &testPageOutput{
Value: c[i].Value,
}
if c[i].NextToken != nil {
next := *c[i].NextToken
out.NextToken = aws.String(next)
}
req.Data = out
})
return r, nil
},
}
for p.Next() {
data := p.Page().(*testPageOutput)
if e, a := aws.StringValue(c[i].Value), aws.StringValue(data.Value); e != a {
t.Errorf("%d, expect Value to be %q, got %q", i, e, a)
}
if e, a := aws.StringValue(c[i].NextToken), aws.StringValue(data.NextToken); e != a {
t.Errorf("%d, expect NextToken to be %q, got %q", i, e, a)
}
i++
}
if e, a := len(c), i; e != a {
t.Errorf("expected to process %d pages, did %d", e, a)
}
if err := p.Err(); err != nil {
t.Fatalf("%d, expected no error, got %v", i, err)
}
}
}

View file

@ -2,6 +2,7 @@ package request
import (
"bytes"
"io"
"net/http"
"strings"
"testing"
@ -25,21 +26,70 @@ func TestResetBody_WithBodyContents(t *testing.T) {
}
}
func TestResetBody_ExcludeUnseekableBodyByMethod(t *testing.T) {
type mockReader struct{}
func (mockReader) Read([]byte) (int, error) {
return 0, io.EOF
}
func TestResetBody_ExcludeEmptyUnseekableBodyByMethod(t *testing.T) {
cases := []struct {
Method string
Body io.ReadSeeker
IsNoBody bool
}{
{"GET", true},
{"HEAD", true},
{"DELETE", true},
{"PUT", false},
{"PATCH", false},
{"POST", false},
{
Method: "GET",
IsNoBody: true,
Body: aws.ReadSeekCloser(mockReader{}),
},
{
Method: "HEAD",
IsNoBody: true,
Body: aws.ReadSeekCloser(mockReader{}),
},
{
Method: "DELETE",
IsNoBody: true,
Body: aws.ReadSeekCloser(mockReader{}),
},
{
Method: "PUT",
IsNoBody: false,
Body: aws.ReadSeekCloser(mockReader{}),
},
{
Method: "PATCH",
IsNoBody: false,
Body: aws.ReadSeekCloser(mockReader{}),
},
{
Method: "POST",
IsNoBody: false,
Body: aws.ReadSeekCloser(mockReader{}),
},
{
Method: "GET",
IsNoBody: false,
Body: aws.ReadSeekCloser(bytes.NewBuffer([]byte("abc"))),
},
{
Method: "GET",
IsNoBody: true,
Body: aws.ReadSeekCloser(bytes.NewBuffer(nil)),
},
{
Method: "POST",
IsNoBody: false,
Body: aws.ReadSeekCloser(bytes.NewBuffer([]byte("abc"))),
},
{
Method: "POST",
IsNoBody: true,
Body: aws.ReadSeekCloser(bytes.NewBuffer(nil)),
},
}
reader := aws.ReadSeekCloser(bytes.NewBuffer([]byte("abc")))
for i, c := range cases {
r := Request{
HTTPRequest: &http.Request{},
@ -47,8 +97,7 @@ func TestResetBody_ExcludeUnseekableBodyByMethod(t *testing.T) {
HTTPMethod: c.Method,
},
}
r.SetReaderBody(reader)
r.SetReaderBody(c.Body)
if a, e := r.HTTPRequest.Body == NoBody, c.IsNoBody; a != e {
t.Errorf("%d, expect body to be set to noBody(%t), but was %t", i, e, a)

View file

@ -22,13 +22,13 @@ import (
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/defaults"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/signer/v4"
"github.com/aws/aws-sdk-go/awstesting"
"github.com/aws/aws-sdk-go/awstesting/unit"
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
"github.com/aws/aws-sdk-go/private/protocol/rest"
"github.com/aws/aws-sdk-go/aws/defaults"
)
type testData struct {
@ -893,7 +893,6 @@ func TestRequest_Presign(t *testing.T) {
},
SignerFn: func(r *request.Request) {
r.HTTPRequest.URL = mustParseURL("https://endpoint/presignedURL")
fmt.Println("url", r.HTTPRequest.URL.String())
if r.NotHoist {
r.Error = fmt.Errorf("expect NotHoist to be cleared")
}
@ -961,7 +960,7 @@ func TestRequest_Presign(t *testing.T) {
}
}
}
func TestNew_EndpointWithDefaultPort(t *testing.T) {
endpoint := "https://estest.us-east-1.es.amazonaws.com:443"
expectedRequestHost := "estest.us-east-1.es.amazonaws.com"
@ -983,7 +982,7 @@ func TestNew_EndpointWithDefaultPort(t *testing.T) {
func TestSanitizeHostForHeader(t *testing.T) {
cases := []struct {
url string
url string
expectedRequestHost string
}{
{"https://estest.us-east-1.es.amazonaws.com:443", "estest.us-east-1.es.amazonaws.com"},
@ -999,6 +998,91 @@ func TestSanitizeHostForHeader(t *testing.T) {
if h := r.Host; h != c.expectedRequestHost {
t.Errorf("expect %v host, got %q", c.expectedRequestHost, h)
}
}
}
}
}
func TestRequestWillRetry_ByBody(t *testing.T) {
svc := awstesting.NewClient()
cases := []struct {
WillRetry bool
HTTPMethod string
Body io.ReadSeeker
IsReqNoBody bool
}{
{
WillRetry: true,
HTTPMethod: "GET",
Body: bytes.NewReader([]byte{}),
IsReqNoBody: true,
},
{
WillRetry: true,
HTTPMethod: "GET",
Body: bytes.NewReader(nil),
IsReqNoBody: true,
},
{
WillRetry: true,
HTTPMethod: "POST",
Body: bytes.NewReader([]byte("abc123")),
},
{
WillRetry: true,
HTTPMethod: "POST",
Body: aws.ReadSeekCloser(bytes.NewReader([]byte("abc123"))),
},
{
WillRetry: true,
HTTPMethod: "GET",
Body: aws.ReadSeekCloser(bytes.NewBuffer(nil)),
IsReqNoBody: true,
},
{
WillRetry: true,
HTTPMethod: "POST",
Body: aws.ReadSeekCloser(bytes.NewBuffer(nil)),
IsReqNoBody: true,
},
{
WillRetry: false,
HTTPMethod: "POST",
Body: aws.ReadSeekCloser(bytes.NewBuffer([]byte("abc123"))),
},
}
for i, c := range cases {
req := svc.NewRequest(&request.Operation{
Name: "Operation",
HTTPMethod: c.HTTPMethod,
HTTPPath: "/",
}, nil, nil)
req.SetReaderBody(c.Body)
req.Build()
req.Error = fmt.Errorf("some error")
req.Retryable = aws.Bool(true)
req.HTTPResponse = &http.Response{
StatusCode: 500,
}
if e, a := c.IsReqNoBody, request.NoBody == req.HTTPRequest.Body; e != a {
t.Errorf("%d, expect request to be no body, %t, got %t, %T", i, e, a, req.HTTPRequest.Body)
}
if e, a := c.WillRetry, req.WillRetry(); e != a {
t.Errorf("%d, expect %t willRetry, got %t", i, e, a)
}
if req.Error == nil {
t.Fatalf("%d, expect error, got none", i)
}
if e, a := "some error", req.Error.Error(); !strings.Contains(a, e) {
t.Errorf("%d, expect %q error in %q", i, e, a)
}
if e, a := 0, req.RetryCount; e != a {
t.Errorf("%d, expect retry count to be %d, got %d", i, e, a)
}
}
}

View file

@ -5,6 +5,7 @@ import (
"strconv"
"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.
@ -176,6 +177,13 @@ func envConfigLoad(enableSharedConfig bool) envConfig {
setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey)
setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey)
if len(cfg.SharedCredentialsFile) == 0 {
cfg.SharedCredentialsFile = defaults.SharedCredentialsFilename()
}
if len(cfg.SharedConfigFile) == 0 {
cfg.SharedConfigFile = defaults.SharedConfigFilename()
}
cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
return cfg

View file

@ -7,6 +7,7 @@ import (
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/awstesting"
"github.com/aws/aws-sdk-go/internal/shareddefaults"
)
func TestLoadEnvConfig_Creds(t *testing.T) {
@ -105,6 +106,8 @@ func TestLoadEnvConfig(t *testing.T) {
},
Config: envConfig{
Region: "region", Profile: "profile",
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
},
{
@ -116,6 +119,8 @@ func TestLoadEnvConfig(t *testing.T) {
},
Config: envConfig{
Region: "region", Profile: "profile",
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
},
{
@ -128,7 +133,9 @@ func TestLoadEnvConfig(t *testing.T) {
},
Config: envConfig{
Region: "region", Profile: "profile",
EnableSharedConfig: true,
EnableSharedConfig: true,
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
},
{
@ -136,6 +143,10 @@ func TestLoadEnvConfig(t *testing.T) {
"AWS_DEFAULT_REGION": "default_region",
"AWS_DEFAULT_PROFILE": "default_profile",
},
Config: envConfig{
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
},
{
Env: map[string]string{
@ -145,7 +156,9 @@ func TestLoadEnvConfig(t *testing.T) {
},
Config: envConfig{
Region: "default_region", Profile: "default_profile",
EnableSharedConfig: true,
EnableSharedConfig: true,
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
},
{
@ -155,7 +168,9 @@ func TestLoadEnvConfig(t *testing.T) {
},
Config: envConfig{
Region: "region", Profile: "profile",
EnableSharedConfig: true,
EnableSharedConfig: true,
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
UseSharedConfigCall: true,
},
@ -168,7 +183,9 @@ func TestLoadEnvConfig(t *testing.T) {
},
Config: envConfig{
Region: "region", Profile: "profile",
EnableSharedConfig: true,
EnableSharedConfig: true,
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
UseSharedConfigCall: true,
},
@ -182,7 +199,9 @@ func TestLoadEnvConfig(t *testing.T) {
},
Config: envConfig{
Region: "region", Profile: "profile",
EnableSharedConfig: true,
EnableSharedConfig: true,
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
UseSharedConfigCall: true,
},
@ -193,7 +212,9 @@ func TestLoadEnvConfig(t *testing.T) {
},
Config: envConfig{
Region: "default_region", Profile: "default_profile",
EnableSharedConfig: true,
EnableSharedConfig: true,
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
UseSharedConfigCall: true,
},
@ -205,7 +226,9 @@ func TestLoadEnvConfig(t *testing.T) {
},
Config: envConfig{
Region: "default_region", Profile: "default_profile",
EnableSharedConfig: true,
EnableSharedConfig: true,
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
UseSharedConfigCall: true,
},
@ -214,7 +237,9 @@ func TestLoadEnvConfig(t *testing.T) {
"AWS_CA_BUNDLE": "custom_ca_bundle",
},
Config: envConfig{
CustomCABundle: "custom_ca_bundle",
CustomCABundle: "custom_ca_bundle",
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
},
{
@ -222,8 +247,10 @@ func TestLoadEnvConfig(t *testing.T) {
"AWS_CA_BUNDLE": "custom_ca_bundle",
},
Config: envConfig{
CustomCABundle: "custom_ca_bundle",
EnableSharedConfig: true,
CustomCABundle: "custom_ca_bundle",
EnableSharedConfig: true,
SharedCredentialsFile: shareddefaults.SharedCredentialsFilename(),
SharedConfigFile: shareddefaults.SharedConfigFilename(),
},
UseSharedConfigCall: true,
},

View file

@ -58,7 +58,12 @@ func New(cfgs ...*aws.Config) *Session {
envCfg := loadEnvConfig()
if envCfg.EnableSharedConfig {
s, err := newSession(Options{}, envCfg, cfgs...)
var cfg aws.Config
cfg.MergeIn(cfgs...)
s, err := NewSessionWithOptions(Options{
Config: cfg,
SharedConfigState: SharedConfigEnable,
})
if err != nil {
// Old session.New expected all errors to be discovered when
// a request is made, and would report the errors then. This
@ -243,13 +248,6 @@ func NewSessionWithOptions(opts Options) (*Session, error) {
envCfg.EnableSharedConfig = true
}
if len(envCfg.SharedCredentialsFile) == 0 {
envCfg.SharedCredentialsFile = defaults.SharedCredentialsFilename()
}
if len(envCfg.SharedConfigFile) == 0 {
envCfg.SharedConfigFile = defaults.SharedConfigFilename()
}
// Only use AWS_CA_BUNDLE if session option is not provided.
if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil {
f, err := os.Open(envCfg.CustomCABundle)

View file

@ -341,7 +341,9 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi
ctx.sanitizeHostForHeader()
ctx.assignAmzQueryValues()
ctx.build(v4.DisableHeaderHoisting)
if err := ctx.build(v4.DisableHeaderHoisting); err != nil {
return nil, err
}
// If the request is not presigned the body should be attached to it. This
// prevents the confusion of wanting to send a signed request without
@ -503,11 +505,13 @@ func (v4 *Signer) logSigningInfo(ctx *signingCtx) {
v4.Logger.Log(msg)
}
func (ctx *signingCtx) build(disableHeaderHoisting bool) {
func (ctx *signingCtx) build(disableHeaderHoisting bool) error {
ctx.buildTime() // no depends
ctx.buildCredentialString() // no depends
ctx.buildBodyDigest()
if err := ctx.buildBodyDigest(); err != nil {
return err
}
unsignedHeaders := ctx.Request.Header
if ctx.isPresign {
@ -535,6 +539,8 @@ func (ctx *signingCtx) build(disableHeaderHoisting bool) {
}
ctx.Request.Header.Set("Authorization", strings.Join(parts, ", "))
}
return nil
}
func (ctx *signingCtx) buildTime() {
@ -661,7 +667,7 @@ func (ctx *signingCtx) buildSignature() {
ctx.signature = hex.EncodeToString(signature)
}
func (ctx *signingCtx) buildBodyDigest() {
func (ctx *signingCtx) buildBodyDigest() error {
hash := ctx.Request.Header.Get("X-Amz-Content-Sha256")
if hash == "" {
if ctx.unsignedPayload || (ctx.isPresign && ctx.ServiceName == "s3") {
@ -669,6 +675,9 @@ func (ctx *signingCtx) buildBodyDigest() {
} else if ctx.Body == nil {
hash = emptyStringSHA256
} 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))
}
if ctx.unsignedPayload || ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" {
@ -676,6 +685,8 @@ func (ctx *signingCtx) buildBodyDigest() {
}
}
ctx.bodyDigest = hash
return nil
}
// isRequestSigned returns if the request is currently signed or presigned

View file

@ -7,6 +7,7 @@ import (
"net/http"
"net/http/httptest"
"reflect"
"strconv"
"strings"
"testing"
"time"
@ -61,17 +62,42 @@ func TestStripExcessHeaders(t *testing.T) {
}
func buildRequest(serviceName, region, body string) (*http.Request, io.ReadSeeker) {
endpoint := "https://" + serviceName + "." + region + ".amazonaws.com"
reader := strings.NewReader(body)
req, _ := http.NewRequest("POST", endpoint, reader)
return buildRequestWithBodyReader(serviceName, region, reader)
}
func buildRequestWithBodyReader(serviceName, region string, body io.Reader) (*http.Request, io.ReadSeeker) {
var bodyLen int
type lenner interface {
Len() int
}
if lr, ok := body.(lenner); ok {
bodyLen = lr.Len()
}
endpoint := "https://" + serviceName + "." + region + ".amazonaws.com"
req, _ := http.NewRequest("POST", endpoint, body)
req.URL.Opaque = "//example.org/bucket/key-._~,!@#$%^&*()"
req.Header.Add("X-Amz-Target", "prefix.Operation")
req.Header.Add("Content-Type", "application/x-amz-json-1.0")
req.Header.Add("Content-Length", string(len(body)))
req.Header.Add("X-Amz-Meta-Other-Header", "some-value=!@#$%^&* (+)")
req.Header.Set("X-Amz-Target", "prefix.Operation")
req.Header.Set("Content-Type", "application/x-amz-json-1.0")
if bodyLen > 0 {
req.Header.Set("Content-Length", strconv.Itoa(bodyLen))
}
req.Header.Set("X-Amz-Meta-Other-Header", "some-value=!@#$%^&* (+)")
req.Header.Add("X-Amz-Meta-Other-Header_With_Underscore", "some-value=!@#$%^&* (+)")
req.Header.Add("X-amz-Meta-Other-Header_With_Underscore", "some-value=!@#$%^&* (+)")
return req, reader
var seeker io.ReadSeeker
if sr, ok := body.(io.ReadSeeker); ok {
seeker = sr
} else {
seeker = aws.ReadSeekCloser(body)
}
return req, seeker
}
func buildSigner() Signer {
@ -101,7 +127,7 @@ func TestPresignRequest(t *testing.T) {
expectedDate := "19700101T000000Z"
expectedHeaders := "content-length;content-type;host;x-amz-meta-other-header;x-amz-meta-other-header_with_underscore"
expectedSig := "ea7856749041f727690c580569738282e99c79355fe0d8f125d3b5535d2ece83"
expectedSig := "122f0b9e091e4ba84286097e2b3404a1f1f4c4aad479adda95b7dff0ccbe5581"
expectedCred := "AKID/19700101/us-east-1/dynamodb/aws4_request"
expectedTarget := "prefix.Operation"
@ -135,7 +161,7 @@ func TestPresignBodyWithArrayRequest(t *testing.T) {
expectedDate := "19700101T000000Z"
expectedHeaders := "content-length;content-type;host;x-amz-meta-other-header;x-amz-meta-other-header_with_underscore"
expectedSig := "fef6002062400bbf526d70f1a6456abc0fb2e213fe1416012737eebd42a62924"
expectedSig := "e3ac55addee8711b76c6d608d762cff285fe8b627a057f8b5ec9268cf82c08b1"
expectedCred := "AKID/19700101/us-east-1/dynamodb/aws4_request"
expectedTarget := "prefix.Operation"
@ -166,14 +192,14 @@ func TestSignRequest(t *testing.T) {
signer.Sign(req, body, "dynamodb", "us-east-1", time.Unix(0, 0))
expectedDate := "19700101T000000Z"
expectedSig := "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/dynamodb/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-meta-other-header;x-amz-meta-other-header_with_underscore;x-amz-security-token;x-amz-target, Signature=ea766cabd2ec977d955a3c2bae1ae54f4515d70752f2207618396f20aa85bd21"
expectedSig := "AWS4-HMAC-SHA256 Credential=AKID/19700101/us-east-1/dynamodb/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-meta-other-header;x-amz-meta-other-header_with_underscore;x-amz-security-token;x-amz-target, Signature=a518299330494908a70222cec6899f6f32f297f8595f6df1776d998936652ad9"
q := req.Header
if e, a := expectedSig, q.Get("Authorization"); e != a {
t.Errorf("expect %v, got %v", e, a)
t.Errorf("expect\n%v\nactual\n%v\n", e, a)
}
if e, a := expectedDate, q.Get("X-Amz-Date"); e != a {
t.Errorf("expect %v, got %v", e, a)
t.Errorf("expect\n%v\nactual\n%v\n", e, a)
}
}
@ -207,6 +233,53 @@ func TestPresignEmptyBodyS3(t *testing.T) {
}
}
func TestSignUnseekableBody(t *testing.T) {
req, body := buildRequestWithBodyReader("mock-service", "mock-region", bytes.NewBuffer([]byte("hello")))
signer := buildSigner()
_, err := signer.Sign(req, body, "mock-service", "mock-region", time.Now())
if err == nil {
t.Fatalf("expect error signing request")
}
if e, a := "unseekable request body", err.Error(); !strings.Contains(a, e) {
t.Errorf("expect %q to be in %q", e, a)
}
}
func TestSignUnsignedPayloadUnseekableBody(t *testing.T) {
req, body := buildRequestWithBodyReader("mock-service", "mock-region", bytes.NewBuffer([]byte("hello")))
signer := buildSigner()
signer.UnsignedPayload = true
_, err := signer.Sign(req, body, "mock-service", "mock-region", time.Now())
if err != nil {
t.Fatalf("expect no error, got %v", err)
}
hash := req.Header.Get("X-Amz-Content-Sha256")
if e, a := "UNSIGNED-PAYLOAD", hash; e != a {
t.Errorf("expect %v, got %v", e, a)
}
}
func TestSignPreComputedHashUnseekableBody(t *testing.T) {
req, body := buildRequestWithBodyReader("mock-service", "mock-region", bytes.NewBuffer([]byte("hello")))
signer := buildSigner()
req.Header.Set("X-Amz-Content-Sha256", "some-content-sha256")
_, err := signer.Sign(req, body, "mock-service", "mock-region", time.Now())
if err != nil {
t.Fatalf("expect no error, got %v", err)
}
hash := req.Header.Get("X-Amz-Content-Sha256")
if e, a := "some-content-sha256", hash; e != a {
t.Errorf("expect %v, got %v", e, a)
}
}
func TestSignPrecomputedBodyChecksum(t *testing.T) {
req, body := buildRequest("dynamodb", "us-east-1", "hello")
req.Header.Set("X-Amz-Content-Sha256", "PRECOMPUTED")

View file

@ -22,6 +22,22 @@ type ReaderSeekerCloser struct {
r io.Reader
}
// IsReaderSeekable returns if the underlying reader type can be seeked. A
// io.Reader might not actually be seekable if it is the ReaderSeekerCloser
// type.
func IsReaderSeekable(r io.Reader) bool {
switch v := r.(type) {
case ReaderSeekerCloser:
return v.IsSeeker()
case *ReaderSeekerCloser:
return v.IsSeeker()
case io.ReadSeeker:
return true
default:
return false
}
}
// Read reads from the reader up to size of p. The number of bytes read, and
// error if it occurred will be returned.
//
@ -56,6 +72,71 @@ func (r ReaderSeekerCloser) IsSeeker() bool {
return ok
}
// HasLen returns the length of the underlying reader if the value implements
// the Len() int method.
func (r ReaderSeekerCloser) HasLen() (int, bool) {
type lenner interface {
Len() int
}
if lr, ok := r.r.(lenner); ok {
return lr.Len(), true
}
return 0, false
}
// GetLen returns the length of the bytes remaining in the underlying reader.
// Checks first for Len(), then io.Seeker to determine the size of the
// underlying reader.
//
// Will return -1 if the length cannot be determined.
func (r ReaderSeekerCloser) GetLen() (int64, error) {
if l, ok := r.HasLen(); ok {
return int64(l), nil
}
if s, ok := r.r.(io.Seeker); ok {
return seekerLen(s)
}
return -1, nil
}
// SeekerLen attempts to get the number of bytes remaining at the seeker's
// current position. Returns the number of bytes remaining or error.
func SeekerLen(s io.Seeker) (int64, error) {
// Determine if the seeker is actually seekable. ReaderSeekerCloser
// hides the fact that a io.Readers might not actually be seekable.
switch v := s.(type) {
case ReaderSeekerCloser:
return v.GetLen()
case *ReaderSeekerCloser:
return v.GetLen()
}
return seekerLen(s)
}
func seekerLen(s io.Seeker) (int64, error) {
curOffset, err := s.Seek(0, 1)
if err != nil {
return 0, err
}
endOffset, err := s.Seek(0, 2)
if err != nil {
return 0, err
}
_, err = s.Seek(curOffset, 0)
if err != nil {
return 0, err
}
return endOffset - curOffset, nil
}
// Close closes the ReaderSeekerCloser.
//
// If the ReaderSeekerCloser is not an io.Closer nothing will be done.

View file

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

View file

@ -0,0 +1,29 @@
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())})

File diff suppressed because it is too large Load diff

View file

@ -83,6 +83,16 @@ func ExampleRoute53_ChangeResourceRecordSets_shared00() {
Changes: []*route53.Change{
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
Name: aws.String("example.com"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.44"),
},
},
TTL: aws.Int64(60),
Type: aws.String("A"),
},
},
},
Comment: aws.String("Web server for example.com"),
@ -130,9 +140,35 @@ func ExampleRoute53_ChangeResourceRecordSets_shared01() {
Changes: []*route53.Change{
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
HealthCheckId: aws.String("abcdef11-2222-3333-4444-555555fedcba"),
Name: aws.String("example.com"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.44"),
},
},
SetIdentifier: aws.String("Seattle data center"),
TTL: aws.Int64(60),
Type: aws.String("A"),
Weight: aws.Int64(100),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
HealthCheckId: aws.String("abcdef66-7777-8888-9999-000000fedcba"),
Name: aws.String("example.com"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.45"),
},
},
SetIdentifier: aws.String("Portland data center"),
TTL: aws.Int64(60),
Type: aws.String("A"),
Weight: aws.Int64(200),
},
},
},
Comment: aws.String("Web servers for example.com"),
@ -179,6 +215,15 @@ func ExampleRoute53_ChangeResourceRecordSets_shared02() {
Changes: []*route53.Change{
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("d123rk29d0stfj.cloudfront.net"),
EvaluateTargetHealth: aws.Bool(false),
HostedZoneId: aws.String("Z2FDTNDATAQYW2"),
},
Name: aws.String("example.com"),
Type: aws.String("A"),
},
},
},
Comment: aws.String("CloudFront distribution for example.com"),
@ -227,9 +272,31 @@ func ExampleRoute53_ChangeResourceRecordSets_shared03() {
Changes: []*route53.Change{
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("example-com-123456789.us-east-2.elb.amazonaws.com "),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z3AADJGX6KTTL2"),
},
Name: aws.String("example.com"),
SetIdentifier: aws.String("Ohio region"),
Type: aws.String("A"),
Weight: aws.Int64(100),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("example-com-987654321.us-west-2.elb.amazonaws.com "),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z1H1FL5HABSF5"),
},
Name: aws.String("example.com"),
SetIdentifier: aws.String("Oregon region"),
Type: aws.String("A"),
Weight: aws.Int64(200),
},
},
},
Comment: aws.String("ELB load balancers for example.com"),
@ -277,9 +344,35 @@ func ExampleRoute53_ChangeResourceRecordSets_shared04() {
Changes: []*route53.Change{
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
HealthCheckId: aws.String("abcdef11-2222-3333-4444-555555fedcba"),
Name: aws.String("example.com"),
Region: aws.String("us-east-2"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.44"),
},
},
SetIdentifier: aws.String("Ohio region"),
TTL: aws.Int64(60),
Type: aws.String("A"),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
HealthCheckId: aws.String("abcdef66-7777-8888-9999-000000fedcba"),
Name: aws.String("example.com"),
Region: aws.String("us-west-2"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.45"),
},
},
SetIdentifier: aws.String("Oregon region"),
TTL: aws.Int64(60),
Type: aws.String("A"),
},
},
},
Comment: aws.String("EC2 instances for example.com"),
@ -327,9 +420,31 @@ func ExampleRoute53_ChangeResourceRecordSets_shared05() {
Changes: []*route53.Change{
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("example-com-123456789.us-east-2.elb.amazonaws.com "),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z3AADJGX6KTTL2"),
},
Name: aws.String("example.com"),
Region: aws.String("us-east-2"),
SetIdentifier: aws.String("Ohio region"),
Type: aws.String("A"),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("example-com-987654321.us-west-2.elb.amazonaws.com "),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z1H1FL5HABSF5"),
},
Name: aws.String("example.com"),
Region: aws.String("us-west-2"),
SetIdentifier: aws.String("Oregon region"),
Type: aws.String("A"),
},
},
},
Comment: aws.String("ELB load balancers for example.com"),
@ -378,9 +493,35 @@ func ExampleRoute53_ChangeResourceRecordSets_shared06() {
Changes: []*route53.Change{
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
Failover: aws.String("PRIMARY"),
HealthCheckId: aws.String("abcdef11-2222-3333-4444-555555fedcba"),
Name: aws.String("example.com"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.44"),
},
},
SetIdentifier: aws.String("Ohio region"),
TTL: aws.Int64(60),
Type: aws.String("A"),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
Failover: aws.String("SECONDARY"),
HealthCheckId: aws.String("abcdef66-7777-8888-9999-000000fedcba"),
Name: aws.String("example.com"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.45"),
},
},
SetIdentifier: aws.String("Oregon region"),
TTL: aws.Int64(60),
Type: aws.String("A"),
},
},
},
Comment: aws.String("Failover configuration for example.com"),
@ -429,9 +570,31 @@ func ExampleRoute53_ChangeResourceRecordSets_shared07() {
Changes: []*route53.Change{
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("example-com-123456789.us-east-2.elb.amazonaws.com "),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z3AADJGX6KTTL2"),
},
Failover: aws.String("PRIMARY"),
Name: aws.String("example.com"),
SetIdentifier: aws.String("Ohio region"),
Type: aws.String("A"),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("example-com-987654321.us-west-2.elb.amazonaws.com "),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z1H1FL5HABSF5"),
},
Failover: aws.String("SECONDARY"),
Name: aws.String("example.com"),
SetIdentifier: aws.String("Oregon region"),
Type: aws.String("A"),
},
},
},
Comment: aws.String("Failover alias configuration for example.com"),
@ -480,15 +643,71 @@ func ExampleRoute53_ChangeResourceRecordSets_shared08() {
Changes: []*route53.Change{
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
GeoLocation: &route53.GeoLocation{
ContinentCode: aws.String("NA"),
},
Name: aws.String("example.com"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.44"),
},
},
SetIdentifier: aws.String("North America"),
TTL: aws.Int64(60),
Type: aws.String("A"),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
GeoLocation: &route53.GeoLocation{
ContinentCode: aws.String("SA"),
},
Name: aws.String("example.com"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.45"),
},
},
SetIdentifier: aws.String("South America"),
TTL: aws.Int64(60),
Type: aws.String("A"),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
GeoLocation: &route53.GeoLocation{
ContinentCode: aws.String("EU"),
},
Name: aws.String("example.com"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.46"),
},
},
SetIdentifier: aws.String("Europe"),
TTL: aws.Int64(60),
Type: aws.String("A"),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
GeoLocation: &route53.GeoLocation{
CountryCode: aws.String("*"),
},
Name: aws.String("example.com"),
ResourceRecords: []*route53.ResourceRecord{
{
Value: aws.String("192.0.2.47"),
},
},
SetIdentifier: aws.String("Other locations"),
TTL: aws.Int64(60),
Type: aws.String("A"),
},
},
},
Comment: aws.String("Geolocation configuration for example.com"),
@ -537,15 +756,67 @@ func ExampleRoute53_ChangeResourceRecordSets_shared09() {
Changes: []*route53.Change{
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("example-com-123456789.us-east-2.elb.amazonaws.com "),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z3AADJGX6KTTL2"),
},
GeoLocation: &route53.GeoLocation{
ContinentCode: aws.String("NA"),
},
Name: aws.String("example.com"),
SetIdentifier: aws.String("North America"),
Type: aws.String("A"),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("example-com-234567890.sa-east-1.elb.amazonaws.com "),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z2P70J7HTTTPLU"),
},
GeoLocation: &route53.GeoLocation{
ContinentCode: aws.String("SA"),
},
Name: aws.String("example.com"),
SetIdentifier: aws.String("South America"),
Type: aws.String("A"),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("example-com-234567890.eu-central-1.elb.amazonaws.com "),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z215JYRZR1TBD5"),
},
GeoLocation: &route53.GeoLocation{
ContinentCode: aws.String("EU"),
},
Name: aws.String("example.com"),
SetIdentifier: aws.String("Europe"),
Type: aws.String("A"),
},
},
{
Action: aws.String("CREATE"),
ResourceRecordSet: &route53.ResourceRecordSet{
AliasTarget: &route53.AliasTarget{
DNSName: aws.String("example-com-234567890.ap-southeast-1.elb.amazonaws.com "),
EvaluateTargetHealth: aws.Bool(true),
HostedZoneId: aws.String("Z1LMS91P8CMLE5"),
},
GeoLocation: &route53.GeoLocation{
CountryCode: aws.String("*"),
},
Name: aws.String("example.com"),
SetIdentifier: aws.String("Other locations"),
Type: aws.String("A"),
},
},
},
Comment: aws.String("Geolocation alias configuration for example.com"),

View file

@ -1049,7 +1049,6 @@ func (c *STS) GetSessionTokenWithContext(ctx aws.Context, input *GetSessionToken
return out, req.Send()
}
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleRequest
type AssumeRoleInput struct {
_ struct{} `type:"structure"`
@ -1241,7 +1240,6 @@ func (s *AssumeRoleInput) SetTokenCode(v string) *AssumeRoleInput {
// Contains the response to a successful AssumeRole request, including temporary
// AWS credentials that can be used to make AWS requests.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleResponse
type AssumeRoleOutput struct {
_ struct{} `type:"structure"`
@ -1295,7 +1293,6 @@ func (s *AssumeRoleOutput) SetPackedPolicySize(v int64) *AssumeRoleOutput {
return s
}
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLRequest
type AssumeRoleWithSAMLInput struct {
_ struct{} `type:"structure"`
@ -1436,7 +1433,6 @@ func (s *AssumeRoleWithSAMLInput) SetSAMLAssertion(v string) *AssumeRoleWithSAML
// Contains the response to a successful AssumeRoleWithSAML request, including
// temporary AWS credentials that can be used to make AWS requests.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAMLResponse
type AssumeRoleWithSAMLOutput struct {
_ struct{} `type:"structure"`
@ -1548,7 +1544,6 @@ func (s *AssumeRoleWithSAMLOutput) SetSubjectType(v string) *AssumeRoleWithSAMLO
return s
}
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityRequest
type AssumeRoleWithWebIdentityInput struct {
_ struct{} `type:"structure"`
@ -1711,7 +1706,6 @@ func (s *AssumeRoleWithWebIdentityInput) SetWebIdentityToken(v string) *AssumeRo
// Contains the response to a successful AssumeRoleWithWebIdentity request,
// including temporary AWS credentials that can be used to make AWS requests.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentityResponse
type AssumeRoleWithWebIdentityOutput struct {
_ struct{} `type:"structure"`
@ -1804,7 +1798,6 @@ func (s *AssumeRoleWithWebIdentityOutput) SetSubjectFromWebIdentityToken(v strin
// The identifiers for the temporary security credentials that the operation
// returns.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser
type AssumedRoleUser struct {
_ struct{} `type:"structure"`
@ -1847,7 +1840,6 @@ func (s *AssumedRoleUser) SetAssumedRoleId(v string) *AssumedRoleUser {
}
// AWS credentials for API authentication.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/Credentials
type Credentials struct {
_ struct{} `type:"structure"`
@ -1906,7 +1898,6 @@ func (s *Credentials) SetSessionToken(v string) *Credentials {
return s
}
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageRequest
type DecodeAuthorizationMessageInput struct {
_ struct{} `type:"structure"`
@ -1951,7 +1942,6 @@ func (s *DecodeAuthorizationMessageInput) SetEncodedMessage(v string) *DecodeAut
// A document that contains additional information about the authorization status
// of a request from an encoded message that is returned in response to an AWS
// request.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessageResponse
type DecodeAuthorizationMessageOutput struct {
_ struct{} `type:"structure"`
@ -1976,7 +1966,6 @@ func (s *DecodeAuthorizationMessageOutput) SetDecodedMessage(v string) *DecodeAu
}
// Identifiers for the federated user that is associated with the credentials.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/FederatedUser
type FederatedUser struct {
_ struct{} `type:"structure"`
@ -2017,7 +2006,6 @@ func (s *FederatedUser) SetFederatedUserId(v string) *FederatedUser {
return s
}
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityRequest
type GetCallerIdentityInput struct {
_ struct{} `type:"structure"`
}
@ -2034,7 +2022,6 @@ func (s GetCallerIdentityInput) GoString() string {
// Contains the response to a successful GetCallerIdentity request, including
// information about the entity making the request.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentityResponse
type GetCallerIdentityOutput struct {
_ struct{} `type:"structure"`
@ -2080,7 +2067,6 @@ func (s *GetCallerIdentityOutput) SetUserId(v string) *GetCallerIdentityOutput {
return s
}
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenRequest
type GetFederationTokenInput struct {
_ struct{} `type:"structure"`
@ -2189,7 +2175,6 @@ func (s *GetFederationTokenInput) SetPolicy(v string) *GetFederationTokenInput {
// Contains the response to a successful GetFederationToken request, including
// temporary AWS credentials that can be used to make AWS requests.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationTokenResponse
type GetFederationTokenOutput struct {
_ struct{} `type:"structure"`
@ -2242,7 +2227,6 @@ func (s *GetFederationTokenOutput) SetPackedPolicySize(v int64) *GetFederationTo
return s
}
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenRequest
type GetSessionTokenInput struct {
_ struct{} `type:"structure"`
@ -2327,7 +2311,6 @@ func (s *GetSessionTokenInput) SetTokenCode(v string) *GetSessionTokenInput {
// Contains the response to a successful GetSessionToken request, including
// temporary AWS credentials that can be used to make AWS requests.
// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionTokenResponse
type GetSessionTokenOutput struct {
_ struct{} `type:"structure"`