From 8bd3a8aa096ad83df323788bd8c461c00a10b552 Mon Sep 17 00:00:00 2001 From: Dave Henderson Date: Thu, 20 Apr 2017 19:21:55 -0500 Subject: [PATCH] Updating vendored deps Signed-off-by: Dave Henderson --- glide.lock | 7 +- .../aws/aws-sdk-go/.github/ISSUE_TEMPLATE.md | 14 + .../.github/PULL_REQUEST_TEMPLATE.md | 3 + vendor/github.com/aws/aws-sdk-go/.travis.yml | 1 + vendor/github.com/aws/aws-sdk-go/CHANGELOG.md | 418 + .../aws/aws-sdk-go/CHANGELOG_PENDING.md | 5 + .../github.com/aws/aws-sdk-go/CONTRIBUTING.md | 5 + vendor/github.com/aws/aws-sdk-go/Makefile | 3 + vendor/github.com/aws/aws-sdk-go/README.md | 90 +- .../aws/aws-sdk-go/aws/client/client.go | 9 +- .../aws/aws-sdk-go/aws/client/client_test.go | 78 + .../aws-sdk-go/aws/client/default_retryer.go | 6 + .../github.com/aws/aws-sdk-go/aws/config.go | 32 +- .../github.com/aws/aws-sdk-go/aws/context.go | 71 + .../aws/aws-sdk-go/aws/context_1_6.go | 41 + .../aws/aws-sdk-go/aws/context_1_7.go | 9 + .../aws/aws-sdk-go/aws/context_test.go | 37 + .../aws-sdk-go/aws/corehandlers/handlers.go | 116 +- .../aws/corehandlers/handlers_test.go | 121 + .../aws-sdk-go/aws/credentials/credentials.go | 23 +- .../stscreds/assume_role_provider.go | 159 +- .../stscreds/assume_role_provider_test.go | 94 + .../aws/aws-sdk-go/aws/defaults/defaults.go | 47 +- .../aws-sdk-go/aws/defaults/defaults_test.go | 84 +- .../aws/aws-sdk-go/aws/endpoints/defaults.go | 110 +- .../aws/endpoints/v3model_codegen.go | 2 +- .../aws/aws-sdk-go/aws/jsonvalue.go | 11 + .../aws/request/connection_reset_error.go | 19 + .../connection_reset_error_appengine.go | 11 + .../connection_reset_error_appengine_test.go | 9 + .../request/connection_reset_error_test.go | 11 + .../aws/aws-sdk-go/aws/request/handlers.go | 66 +- .../aws-sdk-go/aws/request/handlers_test.go | 70 + .../aws/aws-sdk-go/aws/request/request.go | 166 +- .../aws-sdk-go/aws/request/request_context.go | 14 + .../aws/request/request_context_1_6.go | 14 + .../aws/request/request_context_test.go | 46 + .../aws/request/request_internal_test.go | 15 +- .../aws/request/request_pagination.go | 154 +- .../aws/request/request_pagination_test.go | 149 + .../aws-sdk-go/aws/request/request_test.go | 456 +- .../aws/aws-sdk-go/aws/request/retryer.go | 88 +- .../aws/request/timeout_read_closer.go | 94 + .../timeout_read_closer_benchmark_test.go | 76 + .../aws/request/timeout_read_closer_test.go | 118 + .../aws/aws-sdk-go/aws/request/waiter.go | 287 + .../aws/aws-sdk-go/aws/request/waiter_test.go | 636 ++ .../aws/session/custom_ca_bundle_test.go | 319 + .../aws/aws-sdk-go/aws/session/doc.go | 93 +- .../aws/aws-sdk-go/aws/session/env_config.go | 20 + .../aws-sdk-go/aws/session/env_config_test.go | 15 + .../aws/aws-sdk-go/aws/session/session.go | 178 +- .../aws-sdk-go/aws/session/session_test.go | 84 +- .../aws/session/shared_config_test.go | 10 + .../aws/session/testdata/shared_config | 5 + .../aws/aws-sdk-go/aws/signer/v4/options.go | 7 + .../aws/aws-sdk-go/aws/signer/v4/v4.go | 27 +- vendor/github.com/aws/aws-sdk-go/aws/url.go | 12 + .../github.com/aws/aws-sdk-go/aws/url_1_7.go | 29 + .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- .../aws/aws-sdk-go/awstesting/assert.go | 31 +- .../aws/aws-sdk-go/awstesting/assert_test.go | 25 + .../awstesting/cmd/bucket_cleanup/main.go | 94 + .../customizations/s3/s3crypto/client.go | 2 +- .../s3/s3crypto/s3_crypto.feature | 25 +- .../customizations/s3/s3crypto/stepdef.go | 12 +- .../s3/s3manager/bucket_region_test.go | 27 + .../s3/s3manager/integration_test.go | 121 +- .../aws/aws-sdk-go/awstesting/util.go | 27 + .../doc-src/aws-godoc/templates/godoc.html | 12 + .../aws/endpoints/customEndpoint/README.md | 10 +- .../aws/endpoints/enumEndpoints/README.md | 4 +- .../handleServiceErrorCodes.go | 5 +- .../example/aws/request/withContext/README.md | 13 + .../aws/request/withContext/withContext.go | 71 + .../service/dynamodb/scanItems/README.md | 5 +- .../service/dynamodb/scanItems/scanItems.go | 5 +- .../service/dynamodb/unitTest/README.md | 11 +- .../service/ec2/filterInstances/README.md | 4 +- .../ec2/filterInstances/filter_ec2_by_tag.go | 5 +- .../service/s3/concatObjects/README.md | 4 +- .../example/service/s3/listObjects/README.md | 4 +- .../service/s3/listObjects/listObjects.go | 8 +- .../s3/listObjectsConcurrently/README.md | 2 +- .../service/s3/putObjectAcl/putObjectAcl.go | 11 +- .../sqs/mockingClientsForTests/README.md | 4 +- .../mockingClientsForTests/ifaceExample.go | 2 + .../ifaceExample_test.go | 2 + .../apis/apigateway/2015-07-09/api-2.json | 224 +- .../apis/apigateway/2015-07-09/docs-2.json | 169 +- .../apigateway/2015-07-09/paginators-1.json | 28 +- .../2016-02-06/api-2.json | 6 +- .../2016-02-06/docs-2.json | 42 +- .../2016-02-06/paginators-1.json | 16 +- .../models/apis/batch/2016-08-10/api-2.json | 41 +- .../models/apis/batch/2016-08-10/docs-2.json | 45 +- .../apis/batch/2016-08-10/paginators-1.json | 4 + .../models/apis/budgets/2016-10-20/api-2.json | 7 +- .../apis/budgets/2016-10-20/paginators-1.json | 4 + .../apis/clouddirectory/2016-05-10/api-2.json | 81 +- .../clouddirectory/2016-05-10/docs-2.json | 166 +- .../2016-05-10/paginators-1.json | 5 + .../2010-05-15/paginators-1.json | 12 +- .../cloudformation/2010-05-15/waiters-2.json | 25 + .../apis/cloudfront/2017-03-25/api-2.json | 2689 +++++ .../apis/cloudfront/2017-03-25/docs-2.json | 1449 +++ .../cloudfront/2017-03-25/examples-1.json | 83 + .../cloudfront/2017-03-25/paginators-1.json | 32 + .../apis/cloudfront/2017-03-25/waiters-2.json | 47 + .../apis/cloudtrail/2013-11-01/api-2.json | 5 + .../apis/cloudtrail/2013-11-01/docs-2.json | 26 +- .../cloudtrail/2013-11-01/paginators-1.json | 4 +- .../apis/codebuild/2016-10-06/docs-2.json | 2 +- .../codedeploy/2014-10-06/paginators-1.json | 32 +- .../apis/codestar/2017-04-19/api-2.json | 755 ++ .../apis/codestar/2017-04-19/docs-2.json | 474 + .../apis/codestar/2017-04-19/examples-1.json | 5 + .../codestar/2017-04-19/paginators-1.json | 4 + .../cognito-identity/2014-06-30/api-2.json | 7 +- .../cognito-identity/2014-06-30/docs-2.json | 6 + .../2014-06-30/paginators-1.json | 4 + .../models/apis/config/2014-11-12/api-2.json | 3 +- .../models/apis/config/2014-11-12/docs-2.json | 17 +- .../apis/devicefarm/2015-06-23/api-2.json | 299 +- .../apis/devicefarm/2015-06-23/docs-2.json | 251 +- .../devicefarm/2015-06-23/examples-1.json | 14 +- .../devicefarm/2015-06-23/paginators-1.json | 7 +- .../apis/directconnect/2012-10-25/api-2.json | 323 +- .../apis/directconnect/2012-10-25/docs-2.json | 200 +- .../2012-10-25/paginators-1.json | 2 +- .../apis/discovery/2015-11-01/api-2.json | 73 +- .../apis/discovery/2015-11-01/docs-2.json | 148 +- .../discovery/2015-11-01/paginators-1.json | 4 + .../apis/dynamodb/2012-08-10/api-2.json | 91 + .../apis/dynamodb/2012-08-10/docs-2.json | 68 +- .../models/apis/ec2/2016-11-15/api-2.json | 224 +- .../models/apis/ec2/2016-11-15/docs-2.json | 165 +- .../apis/ec2/2016-11-15/paginators-1.json | 6 + .../models/apis/ec2/2016-11-15/waiters-2.json | 18 + .../apis/elasticache/2015-02-02/api-2.json | 82 +- .../apis/elasticache/2015-02-02/docs-2.json | 79 +- .../elasticache/2015-02-02/examples-1.json | 1993 ++-- .../elasticache/2015-02-02/paginators-1.json | 36 +- .../elasticbeanstalk/2010-12-01/api-2.json | 299 +- .../elasticbeanstalk/2010-12-01/docs-2.json | 308 +- .../2010-12-01/paginators-1.json | 4 +- .../2015-12-01/docs-2.json | 24 +- .../2015-12-01/waiters-2.json | 64 + .../elasticmapreduce/2009-03-31/api-2.json | 270 +- .../elasticmapreduce/2009-03-31/docs-2.json | 340 +- .../2009-03-31/paginators-1.json | 7 +- .../2009-03-31/waiters-2.json | 19 + .../models/apis/es/2015-01-01/api-2.json | 237 +- .../models/apis/es/2015-01-01/docs-2.json | 182 +- .../models/apis/es/2015-01-01/examples-1.json | 5 + .../apis/es/2015-01-01/paginators-1.json | 14 + .../models/apis/events/2015-10-07/api-2.json | 293 +- .../models/apis/events/2015-10-07/docs-2.json | 268 +- .../apis/events/2015-10-07/examples-1.json | 4 +- .../apis/events/2015-10-07/paginators-1.json | 4 + .../apis/gamelift/2015-10-01/api-2.json | 356 +- .../apis/gamelift/2015-10-01/docs-2.json | 635 +- .../gamelift/2015-10-01/paginators-1.json | 4 + .../models/apis/iam/2010-05-08/api-2.json | 113 +- .../models/apis/iam/2010-05-08/docs-2.json | 117 +- .../apis/iam/2010-05-08/paginators-1.json | 12 +- .../models/apis/kms/2014-11-01/api-2.json | 129 +- .../models/apis/kms/2014-11-01/docs-2.json | 129 +- .../apis/kms/2014-11-01/examples-1.json | 91 +- .../apis/kms/2014-11-01/paginators-1.json | 18 +- .../models/apis/lambda/2015-03-31/api-2.json | 141 +- .../models/apis/lambda/2015-03-31/docs-2.json | 144 +- .../apis/lambda/2015-03-31/paginators-1.json | 6 +- .../apis/lex-models/2017-04-19/api-2.json | 1922 ++++ .../apis/lex-models/2017-04-19/docs-2.json | 1089 ++ .../lex-models/2017-04-19/examples-1.json | 5 + .../lex-models/2017-04-19/paginators-1.json | 54 + .../2015-07-01/api-2.json | 3 +- .../2015-07-01/docs-2.json | 4 +- .../2015-07-01/paginators-1.json | 4 + .../apis/monitoring/2010-08-01/api-2.json | 26 +- .../apis/monitoring/2010-08-01/docs-2.json | 20 +- .../monitoring/2010-08-01/paginators-1.json | 6 +- .../mturk-requester/2017-01-17/api-2.json | 1665 +++ .../mturk-requester/2017-01-17/docs-2.json | 1088 ++ .../2017-01-17/examples-1.json | 5 + .../2017-01-17/paginators-1.json | 54 + .../apis/opsworks/2013-02-18/api-2.json | 145 +- .../apis/opsworks/2013-02-18/docs-2.json | 185 +- .../opsworks/2013-02-18/paginators-1.json | 4 +- .../apis/opsworkscm/2016-11-01/api-2.json | 30 +- .../apis/opsworkscm/2016-11-01/docs-2.json | 107 +- .../opsworkscm/2016-11-01/paginators-1.json | 4 + .../apis/organizations/2016-11-28/api-2.json | 1989 ++++ .../apis/organizations/2016-11-28/docs-2.json | 1206 ++ .../organizations/2016-11-28/examples-1.json | 1398 +++ .../2016-11-28/paginators-1.json | 4 + .../apis/pinpoint/2016-12-01/api-2.json | 223 +- .../apis/pinpoint/2016-12-01/docs-2.json | 181 +- .../models/apis/polly/2016-06-10/api-2.json | 36 +- .../models/apis/polly/2016-06-10/docs-2.json | 28 +- .../apis/polly/2016-06-10/paginators-1.json | 4 + .../models/apis/rds/2014-10-31/api-2.json | 6 +- .../models/apis/rds/2014-10-31/docs-2.json | 10 +- .../apis/redshift/2012-12-01/api-2.json | 73 +- .../apis/redshift/2012-12-01/docs-2.json | 39 +- .../redshift/2012-12-01/paginators-1.json | 32 +- .../apis/rekognition/2016-06-27/api-2.json | 44 + .../apis/rekognition/2016-06-27/docs-2.json | 44 +- .../2017-01-26/api-2.json | 331 + .../2017-01-26/docs-2.json | 253 + .../2017-01-26/examples-1.json | 5 + .../2017-01-26/paginators-1.json | 4 + .../models/apis/route53/2013-04-01/api-2.json | 4 +- .../apis/route53/2013-04-01/docs-2.json | 410 +- .../apis/route53/2013-04-01/examples-1.json | 757 ++ .../apis/route53domains/2014-05-15/api-2.json | 4 +- .../route53domains/2014-05-15/docs-2.json | 312 +- .../2014-05-15/paginators-1.json | 7 +- .../apis/runtime.lex/2016-11-28/api-2.json | 149 +- .../apis/runtime.lex/2016-11-28/docs-2.json | 116 +- .../models/apis/ssm/2014-11-06/api-2.json | 42 +- .../models/apis/ssm/2014-11-06/docs-2.json | 145 +- .../apis/ssm/2014-11-06/paginators-1.json | 24 +- .../apis/storagegateway/2013-06-30/api-2.json | 43 +- .../storagegateway/2013-06-30/docs-2.json | 116 +- .../streams.dynamodb/2012-08-10/api-2.json | 10 +- .../streams.dynamodb/2012-08-10/docs-2.json | 46 +- .../2012-08-10/paginators-1.json | 4 + .../apis/waf-regional/2016-11-28/api-2.json | 12 +- .../apis/waf-regional/2016-11-28/docs-2.json | 16 +- .../waf-regional/2016-11-28/paginators-1.json | 4 + .../models/apis/waf/2015-08-24/api-2.json | 13 +- .../models/apis/waf/2015-08-24/docs-2.json | 16 +- .../apis/waf/2015-08-24/paginators-1.json | 4 + .../apis/workdocs/2016-05-01/api-2.json | 1781 +++ .../apis/workdocs/2016-05-01/docs-2.json | 931 ++ .../apis/workdocs/2016-05-01/examples-1.json | 5 + .../workdocs/2016-05-01/paginators-1.json | 25 + .../models/endpoints/endpoints.json | 81 +- .../models/protocol_tests/generate.go | 70 +- .../models/protocol_tests/input/ec2.json | 18 +- .../models/protocol_tests/input/json.json | 12 +- .../models/protocol_tests/input/query.json | 16 +- .../protocol_tests/input/rest-json.json | 132 +- .../models/protocol_tests/input/rest-xml.json | 71 +- .../models/protocol_tests/output/query.json | 3 +- .../protocol_tests/output/rest-json.json | 40 + .../aws/aws-sdk-go/private/model/api/api.go | 12 +- .../aws-sdk-go/private/model/api/api_test.go | 22 +- .../private/model/api/customization_passes.go | 21 + .../private/model/api/docstring_test.go | 44 +- .../private/model/api/list_of_shame.go | 495 + .../aws-sdk-go/private/model/api/load_test.go | 6 +- .../aws-sdk-go/private/model/api/operation.go | 101 +- .../aws-sdk-go/private/model/api/passes.go | 33 +- .../private/model/api/passes_test.go | 169 + .../aws/aws-sdk-go/private/model/api/shape.go | 15 +- .../private/model/api/shapetag_test.go | 9 +- .../aws-sdk-go/private/model/api/waiters.go | 110 +- .../private/model/cli/gen-api/main.go | 2 +- .../private/protocol/ec2query/build_test.go | 236 +- .../protocol/ec2query/unmarshal_test.go | 173 +- .../private/protocol/jsonrpc/build_test.go | 390 +- .../protocol/jsonrpc/unmarshal_test.go | 155 +- .../private/protocol/query/build_test.go | 633 +- .../protocol/query/queryutil/queryutil.go | 7 +- .../private/protocol/query/unmarshal_test.go | 289 +- .../aws-sdk-go/private/protocol/rest/build.go | 46 +- .../private/protocol/rest/rest_test.go | 63 + .../private/protocol/rest/unmarshal.go | 29 +- .../private/protocol/restjson/build_test.go | 2261 ++-- .../protocol/restjson/unmarshal_test.go | 371 +- .../private/protocol/restxml/build_test.go | 2200 ++-- .../protocol/restxml/unmarshal_test.go | 285 +- .../aws/aws-sdk-go/private/waiter/waiter.go | 134 - .../aws-sdk-go/private/waiter/waiter_test.go | 401 - .../service/acm/acmiface/interface.go | 46 +- .../aws/aws-sdk-go/service/acm/api.go | 230 +- .../aws/aws-sdk-go/service/acm/errors.go | 2 +- .../aws-sdk-go/service/acm/examples_test.go | 62 +- .../aws/aws-sdk-go/service/acm/service.go | 2 +- .../aws/aws-sdk-go/service/apigateway/api.go | 3623 +++++- .../apigateway/apigatewayiface/interface.go | 436 +- .../aws-sdk-go/service/apigateway/errors.go | 2 +- .../service/apigateway/examples_test.go | 746 +- .../aws-sdk-go/service/apigateway/service.go | 2 +- .../service/applicationautoscaling/api.go | 313 +- .../applicationautoscalingiface/interface.go | 36 +- .../service/applicationautoscaling/errors.go | 2 +- .../applicationautoscaling/examples_test.go | 44 +- .../service/applicationautoscaling/service.go | 6 +- .../applicationdiscoveryservice/api.go | 809 +- .../interface.go | 77 +- .../applicationdiscoveryservice/errors.go | 2 +- .../examples_test.go | 146 +- .../applicationdiscoveryservice/service.go | 14 +- .../aws/aws-sdk-go/service/appstream/api.go | 345 +- .../appstream/appstreamiface/interface.go | 79 +- .../aws-sdk-go/service/appstream/errors.go | 2 +- .../service/appstream/examples_test.go | 110 +- .../aws-sdk-go/service/appstream/service.go | 2 +- .../aws-sdk-go/service/appstream/waiters.go | 117 +- .../aws/aws-sdk-go/service/autoscaling/api.go | 1287 ++- .../autoscaling/autoscalingiface/interface.go | 224 +- .../aws-sdk-go/service/autoscaling/errors.go | 2 +- .../service/autoscaling/examples_test.go | 314 +- .../aws-sdk-go/service/autoscaling/service.go | 2 +- .../aws-sdk-go/service/autoscaling/waiters.go | 157 +- .../aws/aws-sdk-go/service/batch/api.go | 529 +- .../service/batch/batchiface/interface.go | 69 +- .../aws/aws-sdk-go/service/batch/errors.go | 2 +- .../aws-sdk-go/service/batch/examples_test.go | 105 +- .../aws/aws-sdk-go/service/batch/service.go | 2 +- .../aws/aws-sdk-go/service/budgets/api.go | 254 +- .../service/budgets/budgetsiface/interface.go | 57 +- .../aws/aws-sdk-go/service/budgets/errors.go | 2 +- .../service/budgets/examples_test.go | 80 +- .../aws/aws-sdk-go/service/budgets/service.go | 2 +- .../aws-sdk-go/service/clouddirectory/api.go | 2004 +++- .../clouddirectoryiface/interface.go | 217 +- .../service/clouddirectory/errors.go | 2 +- .../service/clouddirectory/examples_test.go | 324 +- .../service/clouddirectory/service.go | 2 +- .../aws-sdk-go/service/cloudformation/api.go | 757 +- .../cloudformationiface/interface.go | 120 +- .../service/cloudformation/errors.go | 2 +- .../service/cloudformation/examples_test.go | 158 +- .../service/cloudformation/service.go | 2 +- .../service/cloudformation/waiters.go | 328 +- .../aws/aws-sdk-go/service/cloudfront/api.go | 1151 +- .../cloudfront/cloudfrontiface/interface.go | 120 +- .../aws-sdk-go/service/cloudfront/errors.go | 10 +- .../service/cloudfront/examples_test.go | 188 +- .../aws-sdk-go/service/cloudfront/service.go | 6 +- .../aws-sdk-go/service/cloudfront/waiters.go | 142 +- .../aws/aws-sdk-go/service/cloudhsm/api.go | 383 +- .../cloudhsm/cloudhsmiface/interface.go | 85 +- .../aws/aws-sdk-go/service/cloudhsm/errors.go | 2 +- .../service/cloudhsm/examples_test.go | 122 +- .../aws-sdk-go/service/cloudhsm/service.go | 2 +- .../aws/aws-sdk-go/service/cloudsearch/api.go | 459 +- .../cloudsearch/cloudsearchiface/interface.go | 101 +- .../aws-sdk-go/service/cloudsearch/errors.go | 2 +- .../service/cloudsearch/examples_test.go | 146 +- .../aws-sdk-go/service/cloudsearch/service.go | 2 +- .../service/cloudsearchdomain/api.go | 60 +- .../cloudsearchdomainiface/interface.go | 17 +- .../service/cloudsearchdomain/errors.go | 2 +- .../cloudsearchdomain/examples_test.go | 20 +- .../service/cloudsearchdomain/service.go | 2 +- .../aws/aws-sdk-go/service/cloudtrail/api.go | 394 +- .../cloudtrail/cloudtrailiface/interface.go | 62 +- .../aws-sdk-go/service/cloudtrail/errors.go | 4 +- .../service/cloudtrail/examples_test.go | 92 +- .../aws-sdk-go/service/cloudtrail/service.go | 2 +- .../aws/aws-sdk-go/service/cloudwatch/api.go | 411 +- .../cloudwatch/cloudwatchiface/interface.go | 53 +- .../aws-sdk-go/service/cloudwatch/errors.go | 2 +- .../service/cloudwatch/examples_test.go | 76 +- .../aws-sdk-go/service/cloudwatch/service.go | 2 +- .../aws-sdk-go/service/cloudwatch/waiters.go | 52 +- .../service/cloudwatchevents/api.go | 911 +- .../cloudwatcheventsiface/interface.go | 53 +- .../service/cloudwatchevents/errors.go | 9 +- .../service/cloudwatchevents/examples_test.go | 105 +- .../service/cloudwatchevents/service.go | 10 +- .../aws-sdk-go/service/cloudwatchlogs/api.go | 794 +- .../cloudwatchlogsiface/interface.go | 124 +- .../service/cloudwatchlogs/errors.go | 2 +- .../service/cloudwatchlogs/examples_test.go | 170 +- .../service/cloudwatchlogs/service.go | 2 +- .../aws/aws-sdk-go/service/codebuild/api.go | 229 +- .../codebuild/codebuildiface/interface.go | 49 +- .../aws-sdk-go/service/codebuild/errors.go | 2 +- .../service/codebuild/examples_test.go | 68 +- .../aws-sdk-go/service/codebuild/service.go | 2 +- .../aws/aws-sdk-go/service/codecommit/api.go | 437 +- .../codecommit/codecommitiface/interface.go | 76 +- .../aws-sdk-go/service/codecommit/errors.go | 2 +- .../service/codecommit/examples_test.go | 104 +- .../aws-sdk-go/service/codecommit/service.go | 2 +- .../aws/aws-sdk-go/service/codedeploy/api.go | 1042 +- .../codedeploy/codedeployiface/interface.go | 160 +- .../aws-sdk-go/service/codedeploy/errors.go | 2 +- .../service/codedeploy/examples_test.go | 224 +- .../aws-sdk-go/service/codedeploy/service.go | 2 +- .../aws-sdk-go/service/codedeploy/waiters.go | 62 +- .../aws-sdk-go/service/codepipeline/api.go | 497 +- .../codepipelineiface/interface.go | 109 +- .../aws-sdk-go/service/codepipeline/errors.go | 2 +- .../service/codepipeline/examples_test.go | 158 +- .../service/codepipeline/service.go | 2 +- .../aws/aws-sdk-go/service/codestar/api.go | 3196 ++++++ .../codestar/codestariface/interface.go | 124 + .../aws/aws-sdk-go/service/codestar/errors.go | 91 + .../service/codestar/examples_test.go | 358 + .../aws-sdk-go/service/codestar/service.go | 140 + .../aws-sdk-go/service/cognitoidentity/api.go | 355 +- .../cognitoidentityiface/interface.go | 77 +- .../service/cognitoidentity/errors.go | 2 +- .../service/cognitoidentity/examples_test.go | 120 +- .../service/cognitoidentity/service.go | 2 +- .../service/cognitoidentityprovider/api.go | 1238 ++- .../cognitoidentityprovideriface/interface.go | 265 +- .../service/cognitoidentityprovider/errors.go | 2 +- .../cognitoidentityprovider/examples_test.go | 392 +- .../cognitoidentityprovider/service.go | 2 +- .../aws/aws-sdk-go/service/cognitosync/api.go | 326 +- .../cognitosync/cognitosynciface/interface.go | 73 +- .../aws-sdk-go/service/cognitosync/errors.go | 2 +- .../service/cognitosync/examples_test.go | 104 +- .../aws-sdk-go/service/cognitosync/service.go | 2 +- .../aws-sdk-go/service/configservice/api.go | 625 +- .../configserviceiface/interface.go | 110 +- .../service/configservice/errors.go | 4 +- .../service/configservice/examples_test.go | 159 +- .../service/configservice/service.go | 2 +- .../service/costandusagereportservice/api.go | 97 +- .../interface.go | 18 +- .../costandusagereportservice/errors.go | 2 +- .../examples_test.go | 20 +- .../costandusagereportservice/service.go | 2 +- .../service/databasemigrationservice/api.go | 630 +- .../interface.go | 137 +- .../databasemigrationservice/errors.go | 2 +- .../databasemigrationservice/examples_test.go | 200 +- .../databasemigrationservice/service.go | 2 +- .../aws-sdk-go/service/datapipeline/api.go | 475 +- .../datapipelineiface/interface.go | 84 +- .../aws-sdk-go/service/datapipeline/errors.go | 2 +- .../service/datapipeline/examples_test.go | 116 +- .../service/datapipeline/service.go | 2 +- .../aws/aws-sdk-go/service/devicefarm/api.go | 3237 +++++- .../devicefarm/devicefarmiface/interface.go | 205 +- .../aws-sdk-go/service/devicefarm/errors.go | 2 +- .../service/devicefarm/examples_test.go | 413 +- .../aws-sdk-go/service/devicefarm/service.go | 2 +- .../aws-sdk-go/service/directconnect/api.go | 3520 +++++- .../directconnectiface/interface.go | 133 +- .../service/directconnect/errors.go | 2 +- .../service/directconnect/examples_test.go | 379 +- .../service/directconnect/service.go | 2 +- .../service/directoryservice/api.go | 725 +- .../directoryserviceiface/interface.go | 157 +- .../service/directoryservice/errors.go | 2 +- .../service/directoryservice/examples_test.go | 230 +- .../service/directoryservice/service.go | 2 +- .../aws/aws-sdk-go/service/dynamodb/api.go | 963 +- .../service/dynamodb/customizations.go | 23 +- .../service/dynamodb/customizations_test.go | 83 +- .../dynamodb/dynamodbattribute/decode.go | 64 +- .../dynamodb/dynamodbattribute/decode_test.go | 33 + .../service/dynamodb/dynamodbattribute/doc.go | 6 +- .../dynamodb/dynamodbattribute/encode.go | 56 +- .../dynamodb/dynamodbattribute/encode_test.go | 31 + .../service/dynamodb/dynamodbattribute/tag.go | 3 + .../dynamodb/dynamodbiface/interface.go | 83 +- .../aws/aws-sdk-go/service/dynamodb/errors.go | 2 +- .../service/dynamodb/examples_test.go | 146 +- .../aws-sdk-go/service/dynamodb/service.go | 2 +- .../aws-sdk-go/service/dynamodb/waiters.go | 102 +- .../aws-sdk-go/service/dynamodbstreams/api.go | 132 +- .../dynamodbstreamsiface/interface.go | 21 +- .../service/dynamodbstreams/errors.go | 2 +- .../service/dynamodbstreams/examples_test.go | 26 +- .../service/dynamodbstreams/service.go | 14 +- .../aws/aws-sdk-go/service/ec2/api.go | 5719 +++++++++- .../service/ec2/ec2iface/interface.go | 955 +- .../aws/aws-sdk-go/service/ec2/errors.go | 2 +- .../aws-sdk-go/service/ec2/examples_test.go | 1466 +-- .../aws/aws-sdk-go/service/ec2/service.go | 2 +- .../aws/aws-sdk-go/service/ec2/waiters.go | 1581 ++- .../aws/aws-sdk-go/service/ecr/api.go | 437 +- .../service/ecr/ecriface/interface.go | 76 +- .../aws/aws-sdk-go/service/ecr/errors.go | 2 +- .../aws-sdk-go/service/ecr/examples_test.go | 104 +- .../aws/aws-sdk-go/service/ecr/service.go | 2 +- .../aws/aws-sdk-go/service/ecs/api.go | 814 +- .../service/ecs/ecsiface/interface.go | 139 +- .../aws/aws-sdk-go/service/ecs/errors.go | 2 +- .../aws-sdk-go/service/ecs/examples_test.go | 188 +- .../aws/aws-sdk-go/service/ecs/service.go | 2 +- .../aws/aws-sdk-go/service/ecs/waiters.go | 217 +- .../aws/aws-sdk-go/service/efs/api.go | 212 +- .../service/efs/efsiface/interface.go | 49 +- .../aws/aws-sdk-go/service/efs/errors.go | 2 +- .../aws-sdk-go/service/efs/examples_test.go | 68 +- .../aws/aws-sdk-go/service/efs/service.go | 2 +- .../aws/aws-sdk-go/service/elasticache/api.go | 1525 ++- .../elasticache/elasticacheiface/interface.go | 175 +- .../aws-sdk-go/service/elasticache/errors.go | 22 +- .../service/elasticache/examples_test.go | 262 +- .../aws-sdk-go/service/elasticache/service.go | 2 +- .../aws-sdk-go/service/elasticache/waiters.go | 257 +- .../service/elasticbeanstalk/api.go | 2012 +++- .../elasticbeanstalkiface/interface.go | 162 +- .../service/elasticbeanstalk/errors.go | 16 +- .../service/elasticbeanstalk/examples_test.go | 324 +- .../service/elasticbeanstalk/service.go | 2 +- .../service/elasticsearchservice/api.go | 1218 ++- .../elasticsearchserviceiface/interface.go | 57 +- .../service/elasticsearchservice/errors.go | 2 +- .../elasticsearchservice/examples_test.go | 123 +- .../service/elasticsearchservice/service.go | 2 +- .../service/elastictranscoder/api.go | 474 +- .../elastictranscoderiface/interface.go | 78 +- .../service/elastictranscoder/errors.go | 2 +- .../elastictranscoder/examples_test.go | 104 +- .../service/elastictranscoder/service.go | 2 +- .../service/elastictranscoder/waiters.go | 62 +- .../aws/aws-sdk-go/service/elb/api.go | 572 +- .../service/elb/elbiface/interface.go | 121 +- .../aws/aws-sdk-go/service/elb/errors.go | 2 +- .../aws-sdk-go/service/elb/examples_test.go | 170 +- .../aws/aws-sdk-go/service/elb/service.go | 2 +- .../aws/aws-sdk-go/service/elb/waiters.go | 147 +- .../aws/aws-sdk-go/service/elbv2/api.go | 759 +- .../service/elbv2/elbv2iface/interface.go | 135 +- .../aws/aws-sdk-go/service/elbv2/errors.go | 4 +- .../aws-sdk-go/service/elbv2/examples_test.go | 182 +- .../aws/aws-sdk-go/service/elbv2/service.go | 2 +- .../aws/aws-sdk-go/service/elbv2/waiters.go | 168 + .../aws/aws-sdk-go/service/emr/api.go | 2666 ++++- .../service/emr/emriface/interface.go | 124 +- .../aws/aws-sdk-go/service/emr/errors.go | 2 +- .../aws-sdk-go/service/emr/examples_test.go | 324 +- .../aws/aws-sdk-go/service/emr/service.go | 2 +- .../aws/aws-sdk-go/service/emr/waiters.go | 176 +- .../aws/aws-sdk-go/service/firehose/api.go | 136 +- .../aws/aws-sdk-go/service/firehose/errors.go | 2 +- .../service/firehose/examples_test.go | 44 +- .../firehose/firehoseiface/interface.go | 33 +- .../aws-sdk-go/service/firehose/service.go | 2 +- .../aws/aws-sdk-go/service/gamelift/api.go | 4156 +++++-- .../aws/aws-sdk-go/service/gamelift/errors.go | 2 +- .../service/gamelift/examples_test.go | 437 +- .../gamelift/gameliftiface/interface.go | 179 +- .../aws-sdk-go/service/gamelift/service.go | 234 +- .../aws/aws-sdk-go/service/glacier/api.go | 778 +- .../aws/aws-sdk-go/service/glacier/errors.go | 2 +- .../service/glacier/examples_test.go | 200 +- .../service/glacier/glacieriface/interface.go | 143 +- .../aws/aws-sdk-go/service/glacier/service.go | 2 +- .../aws-sdk-go/service/glacier/treehash.go | 12 +- .../service/glacier/treehash_test.go | 45 +- .../aws/aws-sdk-go/service/glacier/waiters.go | 107 +- .../aws/aws-sdk-go/service/health/api.go | 265 +- .../aws/aws-sdk-go/service/health/errors.go | 2 +- .../service/health/examples_test.go | 38 +- .../service/health/healthiface/interface.go | 33 +- .../aws/aws-sdk-go/service/health/service.go | 2 +- .../aws/aws-sdk-go/service/iam/api.go | 3860 ++++++- .../aws/aws-sdk-go/service/iam/errors.go | 11 +- .../aws-sdk-go/service/iam/examples_test.go | 748 +- .../service/iam/iamiface/interface.go | 509 +- .../aws/aws-sdk-go/service/iam/service.go | 2 +- .../aws/aws-sdk-go/service/iam/waiters.go | 107 +- .../aws/aws-sdk-go/service/inspector/api.go | 611 +- .../aws-sdk-go/service/inspector/errors.go | 2 +- .../service/inspector/examples_test.go | 194 +- .../inspector/inspectoriface/interface.go | 133 +- .../aws-sdk-go/service/inspector/service.go | 2 +- .../aws/aws-sdk-go/service/iot/api.go | 1086 +- .../aws/aws-sdk-go/service/iot/errors.go | 2 +- .../aws-sdk-go/service/iot/examples_test.go | 344 +- .../service/iot/iotiface/interface.go | 233 +- .../aws/aws-sdk-go/service/iot/service.go | 2 +- .../aws-sdk-go/service/iotdataplane/api.go | 79 +- .../aws-sdk-go/service/iotdataplane/errors.go | 2 +- .../service/iotdataplane/examples_test.go | 26 +- .../iotdataplaneiface/interface.go | 21 +- .../service/iotdataplane/service.go | 2 +- .../aws/aws-sdk-go/service/kinesis/api.go | 438 +- .../service/kinesis/customizations.go | 22 + .../service/kinesis/customizations_test.go | 89 + .../aws/aws-sdk-go/service/kinesis/errors.go | 2 +- .../service/kinesis/examples_test.go | 116 +- .../service/kinesis/kinesisiface/interface.go | 84 +- .../aws/aws-sdk-go/service/kinesis/service.go | 2 +- .../aws/aws-sdk-go/service/kinesis/waiters.go | 52 +- .../service/kinesisanalytics/api.go | 250 +- .../service/kinesisanalytics/errors.go | 2 +- .../service/kinesisanalytics/examples_test.go | 80 +- .../kinesisanalyticsiface/interface.go | 57 +- .../service/kinesisanalytics/service.go | 2 +- .../aws/aws-sdk-go/service/kms/api.go | 1663 ++- .../aws/aws-sdk-go/service/kms/errors.go | 8 +- .../aws-sdk-go/service/kms/examples_test.go | 269 +- .../service/kms/kmsiface/interface.go | 143 +- .../aws/aws-sdk-go/service/kms/service.go | 2 +- .../aws/aws-sdk-go/service/lambda/api.go | 1248 ++- .../aws/aws-sdk-go/service/lambda/errors.go | 2 +- .../service/lambda/examples_test.go | 227 +- .../service/lambda/lambdaiface/interface.go | 113 +- .../aws/aws-sdk-go/service/lambda/service.go | 2 +- .../service/lexmodelbuildingservice/api.go | 9374 ++++++++++++++++ .../service/lexmodelbuildingservice/errors.go | 61 + .../lexmodelbuildingservice/examples_test.go | 838 ++ .../lexmodelbuildingserviceiface/interface.go | 214 + .../lexmodelbuildingservice/service.go | 97 + .../service/lexruntimeservice/api.go | 852 +- .../service/lexruntimeservice/errors.go | 27 +- .../lexruntimeservice/examples_test.go | 31 +- .../lexruntimeserviceiface/interface.go | 15 +- .../service/lexruntimeservice/service.go | 22 +- .../aws/aws-sdk-go/service/lightsail/api.go | 896 +- .../aws-sdk-go/service/lightsail/errors.go | 2 +- .../service/lightsail/examples_test.go | 284 +- .../lightsail/lightsailiface/interface.go | 193 +- .../aws-sdk-go/service/lightsail/service.go | 2 +- .../aws-sdk-go/service/machinelearning/api.go | 683 +- .../service/machinelearning/errors.go | 2 +- .../service/machinelearning/examples_test.go | 170 +- .../machinelearningiface/interface.go | 125 +- .../service/machinelearning/service.go | 2 +- .../service/machinelearning/waiters.go | 207 +- .../marketplacecommerceanalytics/api.go | 46 +- .../marketplacecommerceanalytics/errors.go | 2 +- .../examples_test.go | 14 +- .../interface.go | 13 +- .../marketplacecommerceanalytics/service.go | 2 +- .../service/marketplacemetering/api.go | 60 +- .../service/marketplacemetering/errors.go | 2 +- .../marketplacemetering/examples_test.go | 20 +- .../marketplacemeteringiface/interface.go | 17 +- .../service/marketplacemetering/service.go | 2 +- .../aws-sdk-go/service/mobileanalytics/api.go | 29 +- .../service/mobileanalytics/errors.go | 2 +- .../service/mobileanalytics/examples_test.go | 8 +- .../mobileanalyticsiface/interface.go | 9 +- .../service/mobileanalytics/service.go | 3 +- .../aws/aws-sdk-go/service/mturk/api.go | 9688 +++++++++++++++++ .../aws/aws-sdk-go/service/mturk/errors.go | 19 + .../aws-sdk-go/service/mturk/examples_test.go | 1096 ++ .../service/mturk/mturkiface/interface.go | 250 + .../aws/aws-sdk-go/service/mturk/service.go | 92 + .../aws/aws-sdk-go/service/opsworks/api.go | 2311 +++- .../aws/aws-sdk-go/service/opsworks/errors.go | 2 +- .../service/opsworks/examples_test.go | 468 +- .../opsworks/opsworksiface/interface.go | 292 +- .../aws-sdk-go/service/opsworks/service.go | 30 +- .../aws-sdk-go/service/opsworks/waiters.go | 452 +- .../aws/aws-sdk-go/service/opsworkscm/api.go | 627 +- .../aws-sdk-go/service/opsworkscm/errors.go | 2 +- .../service/opsworkscm/examples_test.go | 127 +- .../opsworkscm/opsworkscmiface/interface.go | 65 +- .../aws-sdk-go/service/opsworkscm/service.go | 23 +- .../aws-sdk-go/service/organizations/api.go | 9146 ++++++++++++++++ .../service/organizations/errors.go | 274 + .../service/organizations/examples_test.go | 881 ++ .../organizationsiface/interface.go | 220 + .../service/organizations/service.go | 204 + .../aws/aws-sdk-go/service/pinpoint/api.go | 1564 ++- .../aws/aws-sdk-go/service/pinpoint/errors.go | 2 +- .../service/pinpoint/examples_test.go | 258 +- .../pinpoint/pinpointiface/interface.go | 131 +- .../aws-sdk-go/service/pinpoint/service.go | 3 +- .../aws/aws-sdk-go/service/polly/api.go | 156 +- .../aws/aws-sdk-go/service/polly/errors.go | 15 +- .../aws-sdk-go/service/polly/examples_test.go | 44 +- .../service/polly/pollyiface/interface.go | 29 +- .../aws/aws-sdk-go/service/polly/service.go | 2 +- .../aws/aws-sdk-go/service/rds/api.go | 2510 ++++- .../aws-sdk-go/service/rds/customizations.go | 32 +- .../service/rds/customizations_test.go | 24 + .../aws/aws-sdk-go/service/rds/errors.go | 2 +- .../aws-sdk-go/service/rds/examples_test.go | 532 +- .../service/rds/rdsiface/interface.go | 372 +- .../aws/aws-sdk-go/service/rds/service.go | 2 +- .../aws/aws-sdk-go/service/rds/waiters.go | 147 +- .../aws/aws-sdk-go/service/redshift/api.go | 2043 +++- .../aws/aws-sdk-go/service/redshift/errors.go | 9 +- .../service/redshift/examples_test.go | 399 +- .../redshift/redshiftiface/interface.go | 274 +- .../aws-sdk-go/service/redshift/service.go | 2 +- .../aws-sdk-go/service/redshift/waiters.go | 222 +- .../aws/aws-sdk-go/service/rekognition/api.go | 581 +- .../aws-sdk-go/service/rekognition/errors.go | 2 +- .../service/rekognition/examples_test.go | 93 +- .../rekognition/rekognitioniface/interface.go | 53 +- .../aws-sdk-go/service/rekognition/service.go | 2 +- .../service/resourcegroupstaggingapi/api.go | 1160 ++ .../resourcegroupstaggingapi/errors.go | 33 + .../resourcegroupstaggingapi/examples_test.go | 151 + .../interface.go | 84 + .../resourcegroupstaggingapi/service.go | 129 + .../aws/aws-sdk-go/service/route53/api.go | 2754 +++-- .../aws/aws-sdk-go/service/route53/errors.go | 25 +- .../service/route53/examples_test.go | 296 +- .../service/route53/route53iface/interface.go | 205 +- .../aws/aws-sdk-go/service/route53/service.go | 2 +- .../aws/aws-sdk-go/service/route53/waiters.go | 52 +- .../aws-sdk-go/service/route53domains/api.go | 1495 +-- .../service/route53domains/errors.go | 2 +- .../service/route53domains/examples_test.go | 140 +- .../route53domainsiface/interface.go | 99 +- .../service/route53domains/service.go | 5 +- .../aws/aws-sdk-go/service/s3/api.go | 1602 ++- .../aws-sdk-go/service/s3/bucket_location.go | 65 +- .../service/s3/bucket_location_test.go | 85 +- .../aws/aws-sdk-go/service/s3/errors.go | 2 +- .../aws-sdk-go/service/s3/examples_test.go | 446 +- .../service/s3/host_style_bucket_test.go | 28 +- .../aws-sdk-go/service/s3/s3crypto/aes_cbc.go | 190 + .../s3/s3crypto/aes_cbc_content_cipher.go | 73 + .../s3crypto/aes_cbc_content_cipher_test.go | 20 + .../service/s3/s3crypto/aes_cbc_padder.go | 29 + .../s3/s3crypto/aes_cbc_padder_test.go | 41 + .../service/s3/s3crypto/aes_cbc_test.go | 501 + .../service/s3/s3crypto/cipher_builder.go | 2 + .../service/s3/s3crypto/cipher_util.go | 26 +- .../service/s3/s3crypto/cipher_util_test.go | 7 + .../service/s3/s3crypto/decryption_client.go | 41 +- .../s3/s3crypto/decryption_client_test.go | 143 +- .../aws/aws-sdk-go/service/s3/s3crypto/doc.go | 4 +- .../service/s3/s3crypto/encryption_client.go | 15 + .../s3/s3crypto/encryption_client_test.go | 32 + .../aws-sdk-go/service/s3/s3crypto/padder.go | 35 + .../service/s3/s3crypto/pkcs7_padder.go | 80 + .../service/s3/s3crypto/pkcs7_padder_test.go | 57 + .../service/s3/s3iface/interface.go | 310 +- .../service/s3/s3manager/bucket_region.go | 83 + .../s3/s3manager/bucket_region_test.go | 92 + .../service/s3/s3manager/download.go | 74 +- .../service/s3/s3manager/download_test.go | 30 + .../s3/s3manager/s3manageriface/interface.go | 3 + .../aws-sdk-go/service/s3/s3manager/upload.go | 133 +- .../service/s3/s3manager/upload_test.go | 83 + .../aws/aws-sdk-go/service/s3/service.go | 2 +- .../aws-sdk-go/service/s3/unmarshal_error.go | 64 +- .../service/s3/unmarshal_error_test.go | 151 +- .../aws/aws-sdk-go/service/s3/waiters.go | 207 +- .../aws-sdk-go/service/servicecatalog/api.go | 820 +- .../service/servicecatalog/errors.go | 2 +- .../service/servicecatalog/examples_test.go | 260 +- .../service/servicecatalog/service.go | 2 +- .../servicecatalogiface/interface.go | 177 +- .../aws/aws-sdk-go/service/ses/api.go | 971 +- .../aws/aws-sdk-go/service/ses/errors.go | 2 +- .../aws-sdk-go/service/ses/examples_test.go | 296 +- .../aws/aws-sdk-go/service/ses/service.go | 2 +- .../service/ses/sesiface/interface.go | 203 +- .../aws/aws-sdk-go/service/ses/waiters.go | 52 +- .../aws/aws-sdk-go/service/sfn/api.go | 474 +- .../aws/aws-sdk-go/service/sfn/errors.go | 2 +- .../aws-sdk-go/service/sfn/examples_test.go | 104 +- .../aws/aws-sdk-go/service/sfn/service.go | 2 +- .../service/sfn/sfniface/interface.go | 77 +- .../aws/aws-sdk-go/service/shield/api.go | 174 +- .../aws/aws-sdk-go/service/shield/errors.go | 2 +- .../service/shield/examples_test.go | 56 +- .../aws/aws-sdk-go/service/shield/service.go | 2 +- .../service/shield/shieldiface/interface.go | 41 +- .../aws/aws-sdk-go/service/simpledb/api.go | 324 +- .../aws/aws-sdk-go/service/simpledb/errors.go | 2 +- .../service/simpledb/examples_test.go | 62 +- .../aws-sdk-go/service/simpledb/service.go | 3 +- .../simpledb/simpledbiface/interface.go | 47 +- .../aws/aws-sdk-go/service/sms/api.go | 360 +- .../aws/aws-sdk-go/service/sms/errors.go | 2 +- .../aws-sdk-go/service/sms/examples_test.go | 68 +- .../aws/aws-sdk-go/service/sms/service.go | 2 +- .../service/sms/smsiface/interface.go | 53 +- .../aws/aws-sdk-go/service/snowball/api.go | 400 +- .../aws/aws-sdk-go/service/snowball/errors.go | 2 +- .../service/snowball/examples_test.go | 104 +- .../aws-sdk-go/service/snowball/service.go | 2 +- .../snowball/snowballiface/interface.go | 75 +- .../aws/aws-sdk-go/service/sns/api.go | 758 +- .../aws/aws-sdk-go/service/sns/errors.go | 2 +- .../aws-sdk-go/service/sns/examples_test.go | 182 +- .../aws/aws-sdk-go/service/sns/service.go | 2 +- .../service/sns/snsiface/interface.go | 130 +- .../aws/aws-sdk-go/service/sqs/api.go | 326 +- .../aws/aws-sdk-go/service/sqs/errors.go | 2 +- .../aws-sdk-go/service/sqs/examples_test.go | 104 +- .../aws/aws-sdk-go/service/sqs/service.go | 2 +- .../service/sqs/sqsiface/interface.go | 73 +- .../aws/aws-sdk-go/service/ssm/api.go | 2111 +++- .../aws/aws-sdk-go/service/ssm/errors.go | 24 +- .../aws-sdk-go/service/ssm/examples_test.go | 492 +- .../aws/aws-sdk-go/service/ssm/service.go | 18 +- .../service/ssm/ssmiface/interface.go | 331 +- .../aws-sdk-go/service/storagegateway/api.go | 1752 ++- .../service/storagegateway/errors.go | 2 +- .../service/storagegateway/examples_test.go | 389 +- .../service/storagegateway/service.go | 2 +- .../storagegatewayiface/interface.go | 257 +- .../aws/aws-sdk-go/service/sts/api.go | 136 +- .../aws/aws-sdk-go/service/sts/errors.go | 2 +- .../aws-sdk-go/service/sts/examples_test.go | 44 +- .../aws/aws-sdk-go/service/sts/service.go | 2 +- .../service/sts/stsiface/interface.go | 33 +- .../aws/aws-sdk-go/service/support/api.go | 343 +- .../aws/aws-sdk-go/service/support/errors.go | 2 +- .../service/support/examples_test.go | 86 +- .../aws/aws-sdk-go/service/support/service.go | 2 +- .../service/support/supportiface/interface.go | 63 +- .../aws/aws-sdk-go/service/swf/api.go | 851 +- .../aws/aws-sdk-go/service/swf/errors.go | 2 +- .../aws-sdk-go/service/swf/examples_test.go | 188 +- .../aws/aws-sdk-go/service/swf/service.go | 2 +- .../service/swf/swfiface/interface.go | 136 +- .../aws/aws-sdk-go/service/waf/api.go | 729 +- .../aws/aws-sdk-go/service/waf/errors.go | 2 +- .../aws-sdk-go/service/waf/examples_test.go | 230 +- .../aws/aws-sdk-go/service/waf/service.go | 2 +- .../service/waf/wafiface/interface.go | 157 +- .../aws/aws-sdk-go/service/wafregional/api.go | 805 +- .../aws-sdk-go/service/wafregional/errors.go | 2 +- .../service/wafregional/examples_test.go | 254 +- .../aws-sdk-go/service/wafregional/service.go | 2 +- .../wafregional/wafregionaliface/interface.go | 173 +- .../aws/aws-sdk-go/service/workdocs/api.go | 6809 ++++++++++++ .../aws/aws-sdk-go/service/workdocs/errors.go | 105 + .../service/workdocs/examples_test.go | 703 ++ .../aws-sdk-go/service/workdocs/service.go | 122 + .../workdocs/workdocsiface/interface.go | 189 + .../aws/aws-sdk-go/service/workspaces/api.go | 380 +- .../aws-sdk-go/service/workspaces/errors.go | 2 +- .../service/workspaces/examples_test.go | 86 +- .../aws-sdk-go/service/workspaces/service.go | 2 +- .../workspaces/workspacesiface/interface.go | 64 +- .../aws/aws-sdk-go/service/xray/api.go | 117 +- .../aws/aws-sdk-go/service/xray/errors.go | 2 +- .../aws-sdk-go/service/xray/examples_test.go | 38 +- .../aws/aws-sdk-go/service/xray/service.go | 2 +- .../service/xray/xrayiface/interface.go | 29 +- .../vendor/github.com/go-ini/ini/.gitignore | 1 + .../vendor/github.com/go-ini/ini/.travis.yml | 17 + .../vendor/github.com/go-ini/ini/Makefile | 12 + .../vendor/github.com/go-ini/ini/README.md | 210 +- .../vendor/github.com/go-ini/ini/README_ZH.md | 214 +- .../vendor/github.com/go-ini/ini/error.go | 32 + .../vendor/github.com/go-ini/ini/ini.go | 1007 +- .../vendor/github.com/go-ini/ini/ini_test.go | 559 +- .../vendor/github.com/go-ini/ini/key.go | 703 ++ .../vendor/github.com/go-ini/ini/key_test.go | 573 + .../vendor/github.com/go-ini/ini/parser.go | 358 + .../github.com/go-ini/ini/parser_test.go | 42 + .../vendor/github.com/go-ini/ini/section.go | 234 + .../github.com/go-ini/ini/section_test.go | 75 + .../vendor/github.com/go-ini/ini/struct.go | 214 +- .../github.com/go-ini/ini/struct_test.go | 118 +- .../go-ini/ini/testdata/UTF-16-BE-BOM.ini | Bin 0 -> 56 bytes .../go-ini/ini/testdata/UTF-16-LE-BOM.ini | Bin 0 -> 56 bytes .../go-ini/ini/testdata/UTF-8-BOM.ini | 2 + .../github.com/go-ini/ini/testdata/aicc.ini | 11 + .../github.com/go-ini/ini/testdata/conf.ini | 2 +- vendor/gopkg.in/yaml.v2/decode.go | 1 - vendor/gopkg.in/yaml.v2/emitterc.go | 1 - vendor/gopkg.in/yaml.v2/parserc.go | 1 - 853 files changed, 185202 insertions(+), 40909 deletions(-) create mode 100644 vendor/github.com/aws/aws-sdk-go/.github/ISSUE_TEMPLATE.md create mode 100644 vendor/github.com/aws/aws-sdk-go/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 vendor/github.com/aws/aws-sdk-go/CHANGELOG_PENDING.md create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/client/client_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/context_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_appengine.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_appengine_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/request_context_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_benchmark_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/request/waiter_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/custom_ca_bundle_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/url.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go create mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/cmd/bucket_cleanup/main.go create mode 100644 vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3manager/bucket_region_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/example/aws/request/withContext/README.md create mode 100644 vendor/github.com/aws/aws-sdk-go/example/aws/request/withContext/withContext.go create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/batch/2016-08-10/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/budgets/2016-10-20/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/cloudfront/2017-03-25/api-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/cloudfront/2017-03-25/docs-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/cloudfront/2017-03-25/examples-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/cloudfront/2017-03-25/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/cloudfront/2017-03-25/waiters-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/codestar/2017-04-19/api-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/codestar/2017-04-19/docs-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/codestar/2017-04-19/examples-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/codestar/2017-04-19/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/cognito-identity/2014-06-30/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/discovery/2015-11-01/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/elasticloadbalancingv2/2015-12-01/waiters-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/es/2015-01-01/examples-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/es/2015-01-01/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/events/2015-10-07/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/gamelift/2015-10-01/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/lex-models/2017-04-19/api-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/lex-models/2017-04-19/docs-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/lex-models/2017-04-19/examples-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/lex-models/2017-04-19/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/marketplacecommerceanalytics/2015-07-01/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/mturk-requester/2017-01-17/api-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/mturk-requester/2017-01-17/docs-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/mturk-requester/2017-01-17/examples-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/mturk-requester/2017-01-17/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/opsworkscm/2016-11-01/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/organizations/2016-11-28/api-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/organizations/2016-11-28/docs-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/organizations/2016-11-28/examples-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/organizations/2016-11-28/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/polly/2016-06-10/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/resourcegroupstaggingapi/2017-01-26/api-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/resourcegroupstaggingapi/2017-01-26/docs-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/resourcegroupstaggingapi/2017-01-26/examples-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/resourcegroupstaggingapi/2017-01-26/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/streams.dynamodb/2012-08-10/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/waf-regional/2016-11-28/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/waf/2015-08-24/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/workdocs/2016-05-01/api-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/workdocs/2016-05-01/docs-2.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/workdocs/2016-05-01/examples-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/models/apis/workdocs/2016-05-01/paginators-1.json create mode 100644 vendor/github.com/aws/aws-sdk-go/private/model/api/list_of_shame.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/model/api/passes_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/rest_test.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/waiter/waiter.go delete mode 100644 vendor/github.com/aws/aws-sdk-go/private/waiter/waiter_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/codestar/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/codestar/codestariface/interface.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/codestar/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/codestar/examples_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/codestar/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/elbv2/waiters.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/kinesis/customizations.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/kinesis/customizations_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/lexmodelbuildingservice/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/lexmodelbuildingservice/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/lexmodelbuildingservice/examples_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/lexmodelbuildingservice/lexmodelbuildingserviceiface/interface.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/lexmodelbuildingservice/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/mturk/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/mturk/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/mturk/examples_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/mturk/mturkiface/interface.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/mturk/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/organizations/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/organizations/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/organizations/examples_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/organizations/organizationsiface/interface.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/organizations/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/examples_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/resourcegroupstaggingapiiface/interface.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3crypto/aes_cbc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3crypto/aes_cbc_content_cipher.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3crypto/aes_cbc_content_cipher_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3crypto/aes_cbc_padder.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3crypto/aes_cbc_padder_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3crypto/aes_cbc_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3crypto/padder.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3crypto/pkcs7_padder.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3crypto/pkcs7_padder_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3manager/bucket_region.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/s3/s3manager/bucket_region_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/workdocs/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/workdocs/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/workdocs/examples_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/workdocs/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/workdocs/workdocsiface/interface.go create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/.travis.yml create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/Makefile create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/key.go create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/key_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/parser.go create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/parser_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/section.go create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/section_test.go create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/testdata/UTF-16-BE-BOM.ini create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/testdata/UTF-16-LE-BOM.ini create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/testdata/UTF-8-BOM.ini create mode 100644 vendor/github.com/aws/aws-sdk-go/vendor/github.com/go-ini/ini/testdata/aicc.ini diff --git a/glide.lock b/glide.lock index c384df234..515c2b27b 100644 --- a/glide.lock +++ b/glide.lock @@ -1,8 +1,8 @@ hash: 01c19d423d90e790bc9d99bb469f318dc4d04f66d4464ba1b3276d746c994901 -updated: 2017-02-11T13:38:09.099507894-05:00 +updated: 2017-04-20T19:20:59.31591402-05:00 imports: - name: github.com/aws/aws-sdk-go - version: f615b0905b52177eb0efa0fe59340c05c0ea0ed9 + version: ccc54a4047c1470fdf5af9badadfd60a8a7f82bf subpackages: - aws - aws/awserr @@ -26,7 +26,6 @@ imports: - private/protocol/query/queryutil - private/protocol/rest - private/protocol/xml/xmlutil - - private/waiter - service/ec2 - service/sts - name: github.com/blang/vfs @@ -40,7 +39,7 @@ imports: - name: github.com/urfave/cli version: 0bdeddeeb0f650497d603c4ad7b20cfe685682f6 - name: gopkg.in/yaml.v2 - version: a3f3340b5840cee44f372bddb5880fcbc419b46a + version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b repo: https://github.com/go-yaml/yaml.git testImports: - name: github.com/davecgh/go-spew diff --git a/vendor/github.com/aws/aws-sdk-go/.github/ISSUE_TEMPLATE.md b/vendor/github.com/aws/aws-sdk-go/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..1ecb636bf --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,14 @@ +Please fill out the sections below to help us address your issue. + +### Version of AWS SDK for Go? + + +### Version of Go (`go version`)? + + +### What issue did you see? + +### Steps to reproduce + +If you have have an runnable example, please include it. + diff --git a/vendor/github.com/aws/aws-sdk-go/.github/PULL_REQUEST_TEMPLATE.md b/vendor/github.com/aws/aws-sdk-go/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..a9aaa9a8e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,3 @@ +For changes to files under the `/model/` folder, and manual edits to autogenerated code (e.g. `/service/s3/api.go`) please create an Issue instead of a PR for those type of changes. + +If there is an existing bug or feature this PR is answers please reference it here. diff --git a/vendor/github.com/aws/aws-sdk-go/.travis.yml b/vendor/github.com/aws/aws-sdk-go/.travis.yml index 8a53f5fd3..02c93210a 100644 --- a/vendor/github.com/aws/aws-sdk-go/.travis.yml +++ b/vendor/github.com/aws/aws-sdk-go/.travis.yml @@ -6,6 +6,7 @@ go: - 1.5 - 1.6 - 1.7 + - 1.8 - tip # Use Go 1.5's vendoring experiment for 1.5 tests. diff --git a/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md index 9855dcb9d..084374803 100644 --- a/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go/CHANGELOG.md @@ -1,3 +1,421 @@ +Release v1.8.15 (2017-04-20) +=== + +### Service Client Updates +* `service/devicefarm`: Updates service API and documentation + * API Update for AWS Device Farm: Support for Deals and Promotions +* `service/directconnect`: Updates service documentation + * Documentation updates for AWS Direct Connect. +* `service/elbv2`: Updates service waiters +* `service/kms`: Updates service documentation and examples + * Doc-only update for Key Management Service (KMS): Update docs for GrantConstraints and GenerateRandom +* `service/route53`: Updates service documentation + * Release notes: SDK documentation now includes examples for ChangeResourceRecordSets for all types of resource record set, such as weighted, alias, and failover. +* `service/route53domains`: Updates service API, documentation, and paginators + * Adding examples and other documentation updates. + +### SDK Enhancements +* `service/s3`: Add utilities to make getting a bucket's region easier (#1207) + * Adds two features which make it easier to get a bucket's region, `s3.NormalizeBucketLocation` and `s3manager.GetBucketRegion`. + +### SDK Bugs +* `service/s3`: Fix HeadObject's incorrect documented error codes (#1213) + * The HeadObject's model incorrectly states that the operation can return the NoSuchKey error code. + * Fixes #1208 +Release v1.8.14 (2017-04-19) +=== + +### Service Client Updates +* `service/apigateway`: Updates service API and documentation + * Add support for "embed" property. +* `service/codestar`: Adds new service + * AWS CodeStar is a cloud-based service for creating, managing, and working with software development projects on AWS. An AWS CodeStar project creates and integrates AWS services for your project development toolchain. AWS CodeStar also manages the permissions required for project users. +* `service/ec2`: Updates service API and documentation + * Adds support for creating an Amazon FPGA Image (AFI) from a specified design checkpoint (DCP). +* `service/iam`: Updates service API and documentation + * This changes introduces a new IAM role type, Service Linked Role, which works like a normal role but must be managed via services' control. +* `service/lambda`: Updates service API and documentation + * Lambda integration with CloudDebugger service to enable customers to enable tracing for the Lambda functions and send trace information to the CloudDebugger service. +* `service/lexmodelbuildingservice`: Adds new service +* `service/polly`: Updates service API, documentation, and paginators + * API Update for Amazon Polly: Add support for speech marks +* `service/rekognition`: Updates service API and documentation + * Given an image, the API detects explicit or suggestive adult content in the image and returns a list of corresponding labels with confidence scores, as well as a taxonomy (parent-child relation) for each label. + +Release v1.8.13 (2017-04-18) +=== + +### Service Client Updates +* `service/lambda`: Updates service API and documentation + * You can use tags to group and filter your Lambda functions, making it easier to analyze them for billing allocation purposes. For more information, see Tagging Lambda Functions. You can now write or upgrade your Lambda functions using Python version 3.6. For more information, see Programming Model for Authoring Lambda Functions in Python. Note: Features will be rolled out in the US regions on 4/19. + +### SDK Enhancements +* `aws/request`: add support for appengine's custom standard library (#1190) + * Remove syscall error checking on appengine platforms. + +Release v1.8.12 (2017-04-11) +=== + +### Service Client Updates +* `service/apigateway`: Updates service API and documentation + * API Gateway request validators +* `service/batch`: Updates service API and documentation + * API Update for AWS Batch: Customer provided AMI for MANAGED Compute Environment +* `service/gamelift`: Updates service API and documentation + * Allows developers to utilize an improved workflow when calling our Queues API and introduces a new feature that allows developers to specify a maximum allowable latency per Queue. +* `service/opsworks`: Updates service API, documentation, and paginators + * Cloudwatch Logs agent configuration can now be attached to OpsWorks Layers using CreateLayer and UpdateLayer. OpsWorks will then automatically install and manage the CloudWatch Logs agent on the instances part of the OpsWorks Layer. + +### SDK Bugs +* `aws/client`: Fix clients polluting handler list (#1197) + * Fixes the clients potentially polluting the passed in handler list with the client's customizations. This change ensures every client always works with a clean copy of the request handlers and it cannot pollute the handlers back upstream. + * Fixes #1184 +* `aws/request`: Fix waiter error match condition (#1195) + * Fixes the waiters's matching overwriting the request's err, effectively ignoring the error condition. This broke waiters with the FailureWaiterState matcher state. +Release v1.8.11 (2017-04-07) +=== + +### Service Client Updates +* `service/redshift`: Updates service API, documentation, and paginators + * This update adds the GetClusterCredentials API which is used to get temporary login credentials to the cluster. AccountWithRestoreAccess now has a new member AccountAlias, this is the identifier of the AWS support account authorized to restore the specified snapshot. This is added to support the feature where the customer can share their snapshot with the Amazon Redshift Support Account without having to manually specify the AWS Redshift Service account ID on the AWS Console/API. + +Release v1.8.10 (2017-04-06) +=== + +### Service Client Updates +* `service/elbv2`: Updates service documentation + +Release v1.8.9 (2017-04-05) +=== + +### Service Client Updates +* `service/elasticache`: Updates service API, documentation, paginators, and examples + * ElastiCache added support for testing the Elasticache Multi-AZ feature with Automatic Failover. + +Release v1.8.8 (2017-04-04) +=== + +### Service Client Updates +* `service/cloudwatch`: Updates service API, documentation, and paginators + * Amazon Web Services announced the immediate availability of two additional alarm configuration rules for Amazon CloudWatch Alarms. The first rule is for configuring missing data treatment. Customers have the options to treat missing data as alarm threshold breached, alarm threshold not breached, maintain alarm state and the current default treatment. The second rule is for alarms based on percentiles metrics that can trigger unnecassarily if the percentile is calculated from a small number of samples. The new rule can treat percentiles with low sample counts as same as missing data. If the first rule is enabled, the same treatment will be applied when an alarm encounters a percentile with low sample counts. + +Release v1.8.7 (2017-04-03) +=== + +### Service Client Updates +* `service/lexruntimeservice`: Updates service API and documentation + * Adds support to PostContent for speech input + +### SDK Enhancements +* `aws/request`: Improve handler copy, push back, push front performance (#1171) + * Minor optimization to the handler list's handling of copying and pushing request handlers to the handler list. +* Update codegen header to use Go std wording (#1172) + * Go recently accepted the proposal for standard generated file header wording in, https://golang.org/s/generatedcode. + +### SDK Bugs +* `service/dynamodb`: Fix DynamoDB using custom retryer (#1170) + * Fixes (#1139) the DynamoDB service client clobbering any custom retryer that was passed into the service client or Session's config. +Release v1.8.6 (2017-04-01) +=== + +### Service Client Updates +* `service/clouddirectory`: Updates service API and documentation + * ListObjectAttributes now supports filtering by facet. +* `aws/endpoints`: Updated Regions and Endpoints metadata. + +Release v1.8.5 (2017-03-30) +=== + +### Service Client Updates +* `service/cloudformation`: Updates service waiters and paginators + * Adding paginators for ListExports and ListImports +* `service/cloudfront`: Adds new service + * Amazon CloudFront now supports user configurable HTTP Read and Keep-Alive Idle Timeouts for your Custom Origin Servers +* `service/configservice`: Updates service documentation +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/resourcegroupstaggingapi`: Adds new service +* `service/storagegateway`: Updates service API and documentation + * File gateway mode in AWS Storage gateway provides access to objects in S3 as files on a Network File System (NFS) mount point. Once a file share is created, any changes made externally to the S3 bucket will not be reflected by the gateway. Using the cache refresh feature in this update, the customer can trigger an on-demand scan of the keys in their S3 bucket and refresh the file namespace cached on the gateway. It takes as an input the fileShare ARN and refreshes the cache for only that file share. Additionally there is new functionality on file gateway that allows you configure what squash options they would like on their file share, this allows a customer to configure their gateway to not squash root permissions. This can be done by setting options in NfsOptions for CreateNfsFileShare and UpdateNfsFileShare APIs. + +Release v1.8.4 (2017-03-28) +=== + +### Service Client Updates +* `service/batch`: Updates service API, documentation, and paginators + * Customers can now provide a retryStrategy as part of the RegisterJobDefinition and SubmitJob API calls. The retryStrategy object has a number value for attempts. This is the number of non successful executions before a job is considered FAILED. In addition, the JobDetail object now has an attempts field and shows all execution attempts. +* `service/ec2`: Updates service API and documentation + * Customers can now tag their Amazon EC2 Instances and Amazon EBS Volumes at + the time of their creation. You can do this from the EC2 Instance launch + wizard or through the RunInstances or CreateVolume APIs. By tagging + resources at the time of creation, you can eliminate the need to run custom + tagging scripts after resource creation. In addition, you can now set + resource-level permissions on the CreateVolume, CreateTags, DeleteTags, and + the RunInstances APIs. This allows you to implement stronger security + policies by giving you more granular control over which users and groups + have access to these APIs. You can also enforce the use of tagging and + control what tag keys and values are set on your resources. When you combine + tag usage and resource-level IAM policies together, you can ensure your + instances and volumes are properly secured upon creation and achieve more + accurate cost allocation reporting. These new features are provided at no + additional cost. + +### SDK Enhancements +* `aws/request`: Add retry support for RequestTimeoutException (#1158) + * Adds support for retrying RequestTimeoutException error code that is returned by some services. + +### SDK Bugs +* `private/model/api`: Fix Waiter and Paginators panic on nil param inputs (#1157) + * Corrects the code generation for Paginators and waiters that caused a panic if nil input parameters were used with the operations. +Release v1.8.3 (2017-03-27) +=== + +## Service Client Updates +* `service/ssm`: Updates service API, documentation, and paginators + * Updated validation rules for SendCommand and RegisterTaskWithMaintenanceWindow APIs. +Release v1.8.2 (2017-03-24) +=== + +Service Client Updates +--- +* `service/applicationautoscaling`: Updates service API, documentation, and paginators + * Application AutoScaling is launching support for a new target resource (AppStream 2.0 Fleets) as a scalable target. +* `service/cloudtrail`: Updates service API and documentation + * Doc-only Update for CloudTrail: Add required parameters for GetEventSelectors and PutEventSelectors + +Release v1.8.1 (2017-03-23) +=== + +Service Client Updates +--- +* `service/applicationdiscoveryservice`: Updates service API, documentation, and paginators + * Adds export configuration options to the AWS Discovery Service API. +* `service/elbv2`: Updates waiters +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/lambda`: Updates service API and paginators + * Adds support for new runtime Node.js v6.10 for AWS Lambda service + +Release v1.8.0 (2017-03-22) +=== + +Service Client Updates +--- +* `service/codebuild`: Updates service documentation +* `service/directconnect`: Updates service API + * Deprecated DescribeConnectionLoa, DescribeInterconnectLoa, AllocateConnectionOnInterconnect and DescribeConnectionsOnInterconnect operations in favor of DescribeLoa, DescribeLoa, AllocateHostedConnection and DescribeHostedConnections respectively. +* `service/marketplacecommerceanalytics`: Updates service API, documentation, and paginators + * This update adds a new data set, us_sales_and_use_tax_records, which enables AWS Marketplace sellers to programmatically access to their U.S. Sales and Use Tax report data. +* `service/pinpoint`: Updates service API and documentation + * Amazon Pinpoint User Segmentation + * Added ability to segment endpoints by user attributes in addition to endpoint attributes. Amazon Pinpoint Event Stream Preview + * Added functionality to publish raw app analytics and campaign events data as events streams to Kinesis and Kinesis Firehose + * The feature provides developers with increased flexibility of exporting raw events to S3, Redshift, Elasticsearch using a Kinesis Firehose stream or enable real time event processing use cases using a Kinesis stream +* `service/rekognition`: Updates service documentation. + +SDK Features +--- +* `aws/request`: Add support for context.Context to SDK API operation requests (#1132) + * Adds support for context.Context to the SDK by adding `WithContext` methods for each API operation, Paginators and Waiters. e.g `PutObjectWithContext`. This change also adds the ability to provide request functional options to the method calls instead of requiring you to use the `Request` API operation method (e.g `PutObjectRequest`). + * Adds a `Complete` Request handler list that will be called ever time a request is completed. This includes both success and failure. Complete will only be called once per API operation request. + * `private/waiter` package moved from the private group to `aws/request/waiter` and made publicly available. + * Adds Context support to all API operations, Waiters(WaitUntil) and Paginators(Pages) methods. + * Adds Context support for s3manager and s3crypto clients. + +SDK Enhancements +--- +* `aws/signer/v4`: Adds support for unsigned payload signer config (#1130) + * Adds configuration option to the v4.Signer to specify the request's body should not be signed. This will only correclty function on services that support unsigned payload. e.g. S3, Glacier. + +SDK Bug Fixes +--- +* `service/s3`: Fix S3 HostID to be available in S3 request error message (#1131) + * Adds a new type s3.RequestFailure which exposes the S3 HostID value from a S3 API operation response. This is helpful when you have an error with S3, and need to contact support. Both RequestID and HostID are needed. +* `private/model/api`: Do not return a link if uid is empty (#1133) + * Fixes SDK's doc generation to not generate API reference doc links if the SDK us unable to create a valid link. +* `aws/request`: Optimization to handler list copy to prevent multiple alloc calls. (#1134) +Release v1.7.9 (2017-03-13) +=== + +Service Client Updates +--- +* `service/devicefarm`: Updates service API, documentation, paginators, and examples + * Network shaping allows users to simulate network connections and conditions while testing their Android, iOS, and web apps with AWS Device Farm. +* `service/cloudwatchevents`: Updates service API, documentation, and examples + +SDK Enhancement +=== +* `aws/session`: Add support for side loaded CA bundles (#1117) + * Adds supports for side loading Certificate Authority bundle files to the SDK using AWS_CA_BUNDLE environment variable or CustomCABundle session option. +* `service/s3/s3crypto`: Add support for AES/CBC/PKCS5Padding (#1124) + +SDK Bug +=== +* `service/rds`: Fixing issue when not providing `SourceRegion` on cross +region operations (#1127) +* `service/rds`: Enables cross region for `CopyDBClusterSnapshot` and +`CreateDBCluster` (#1128) + +Release v1.7.8 (2017-03-10) +=== + +Service Client Updates +--- +* `service/codedeploy`: Updates service paginators + * Add paginators for Codedeploy +* `service/emr`: Updates service API, documentation, and paginators + * This release includes support for instance fleets in Amazon EMR. + +Release v1.7.7 (2017-03-09) +=== + +Service Client Updates +--- +* `service/apigateway`: Updates service API, documentation, and paginators + * API Gateway has added support for ACM certificates on custom domain names. Both Amazon-issued certificates and uploaded third-part certificates are supported. +* `service/clouddirectory`: Updates service API, documentation, and paginators + * Introduces a new Cloud Directory API that enables you to retrieve all available parent paths for any type of object (a node, leaf node, policy node, and index node) in a hierarchy. + +Release v1.7.6 (2017-03-09) +=== + +Service Client Updates +--- +* `service/organizations`: Updates service documentation and examples + * Doc-only Update for Organizations: Add SDK Code Snippets +* `service/workdocs`: Adds new service + * The Administrative SDKs for Amazon WorkDocs provides full administrator level access to WorkDocs site resources, allowing developers to integrate their applications to manage WorkDocs users, content and permissions programmatically + +Release v1.7.5 (2017-03-08) +=== + +Service Client Updates +--- +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/rds`: Updates service API and documentation + * Add support to using encrypted clusters as cross-region replication masters. Update CopyDBClusterSnapshot API to support encrypted cross region copy of Aurora cluster snapshots. + +Release v1.7.4 (2017-03-06) +=== + +Service Client Updates +--- +* `service/budgets`: Updates service API and paginators + * When creating or editing a budget via the AWS Budgets API you can define notifications that are sent to subscribers when the actual or forecasted value for cost or usage exceeds the notificationThreshold associated with the budget notification object. Starting today, the maximum allowed value for the notificationThreshold was raised from 100 to 300. This change was made to give you more flexibility when setting budget notifications. +* `service/cloudtrail`: Updates service documentation and paginators + * Doc-only update for AWSCloudTrail: Updated links/descriptions +* `aws/endpoints`: Updated Regions and Endpoints metadata. +* `service/opsworkscm`: Updates service API, documentation, and paginators + * OpsWorks for Chef Automate has added a new field "AssociatePublicIpAddress" to the CreateServer request, "CloudFormationStackArn" to the Server model and "TERMINATED" server state. + + +Release v1.7.3 (2017-02-28) +=== + +Service Client Updates +--- +* `service/mturk`: Renaming service + * service/mechanicalturkrequesterservice was renamed to service/mturk. Be sure to change any references of the old client to the new. + +Release v1.7.2 (2017-02-28) +=== + +Service Client Updates +--- +* `service/dynamodb`: Updates service API and documentation + * Release notes: Time to Live (TTL) is a feature that allows you to define when items in a table expire and can be purged from the database, so that you don't have to track expired data and delete it manually. With TTL enabled on a DynamoDB table, you can set a timestamp for deletion on a per-item basis, allowing you to limit storage usage to only those records that are relevant. +* `service/iam`: Updates service API, documentation, and paginators + * This release adds support for AWS Organizations service control policies (SCPs) to SimulatePrincipalPolicy operation. If there are SCPs associated with the simulated user's account, their effect on the result is captured in the OrganizationDecisionDetail element in the EvaluationResult. +* `service/mechanicalturkrequesterservice`: Adds new service + * Amazon Mechanical Turk is a web service that provides an on-demand, scalable, human workforce to complete jobs that humans can do better than computers, for example, recognizing objects in photos. +* `service/organizations`: Adds new service + * AWS Organizations is a web service that enables you to consolidate your multiple AWS accounts into an organization and centrally manage your accounts and their resources. +* `service/dynamodbstreams`: Updates service API, documentation, and paginators +* `service/waf`: Updates service API, documentation, and paginators + * Aws WAF - For GetSampledRequests action, changed max number of samples from 100 to 500. +* `service/wafregional`: Updates service API, documentation, and paginators + +Release v1.7.1 (2017-02-24) +=== + +Service Client Updates +--- +* `service/elasticsearchservice`: Updates service API, documentation, paginators, and examples + * Added three new API calls to existing Amazon Elasticsearch service to expose Amazon Elasticsearch imposed limits to customers. + +Release v1.7.0 (2017-02-23) +=== + +Service Client Updates +--- +* `service/ec2`: Updates service API + * New EC2 I3 instance type + +SDK Bug +--- +* `service/s3/s3manager`: Adding support for SSE (#1097) + * Fixes SSE fields not being applied to a part during multi part upload. + +SDK Feature +--- +* `aws/session`: Add support for AssumeRoles with MFA (#1088) + * Adds support for assuming IAM roles with MFA enabled. A TokenProvider func was added to stscreds.AssumeRoleProvider that will be called each time the role's credentials need to be refreshed. A basic token provider that sources the MFA token from stdin as stscreds.StdinTokenProvider. +* `aws/session`: Update SDK examples and docs to use session.Must (#1099) + * Updates the SDK's example and docs to use session.Must where possible to highlight its usage as apposed to session error checking that is most cases errors will be terminal to the application anyways. +Release v1.6.27 (2017-02-22) +=== + +Service Client Updates +--- +* `service/clouddirectory`: Updates service documentation + * ListObjectAttributes documentation updated based on forum feedback +* `service/elasticbeanstalk`: Updates service API, documentation, and paginators + * Elastic Beanstalk adds support for creating and managing custom platform. +* `service/gamelift`: Updates service API, documentation, and paginators + * Allow developers to configure global queues for creating GameSessions. Allow PlayerData on PlayerSessions to store player-specific data. +* `service/route53`: Updates service API, documentation, and examples + * Added support for operations CreateVPCAssociationAuthorization and DeleteVPCAssociationAuthorization to throw a ConcurrentModification error when a conflicting modification occurs in parallel to the authorizations in place for a given hosted zone. + +Release v1.6.26 (2017-02-21) +=== + +Service Client Updates +--- +* `service/ec2`: Updates service API and documentation + * Added the billingProduct parameter to the RegisterImage API. + +Release v1.6.25 (2017-02-17) +=== + +Service Client Updates +--- +* `service/directconnect`: Updates service API, documentation, and paginators + * This update will introduce the ability for Direct Connect customers to take advantage of Link Aggregation (LAG). This allows you to bundle many individual physical interfaces into a single logical interface, referred to as a LAG. This makes administration much simpler as the majority of configuration is done on the LAG while you are free to add or remove physical interfaces from the bundle as bandwidth demand increases or decreases. A concrete example of the simplification added by LAG is that customers need only a single BGP session as opposed to one session per physical connection. + +Release v1.6.24 (2017-02-16) +=== + +Service Client Updates +--- +* `service/cognitoidentity`: Updates service API, documentation, and paginators + * Allow createIdentityPool and updateIdentityPool API to set server side token check value on identity pool +* `service/configservice`: Updates service API and documentation + * AWS Config now supports a new test mode for the PutEvaluations API. Set the TestMode parameter to true in your custom rule to verify whether your AWS Lambda function will deliver evaluation results to AWS Config. No updates occur to your existing evaluations, and evaluation results are not sent to AWS Config. + +Release v1.6.23 (2017-02-15) +=== + +Service Client Updates +--- +* `service/kms`: Updates service API, documentation, paginators, and examples + * his release of AWS Key Management Service introduces the ability to tag keys. Tagging keys can help you organize your keys and track your KMS costs in the cost allocation report. This release also increases the maximum length of a key ID to accommodate ARNs that include a long key alias. + +Release v1.6.22 (2017-02-14) +=== + +Service Client Updates +--- +* `service/ec2`: Updates service API, documentation, and paginators + * Adds support for the new Modify Volumes apis. + Release v1.6.21 (2017-02-11) === diff --git a/vendor/github.com/aws/aws-sdk-go/CHANGELOG_PENDING.md b/vendor/github.com/aws/aws-sdk-go/CHANGELOG_PENDING.md new file mode 100644 index 000000000..8a1927a39 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/CHANGELOG_PENDING.md @@ -0,0 +1,5 @@ +### SDK Features + +### SDK Enhancements + +### SDK Bugs diff --git a/vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md b/vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md index 81edbfaeb..7c0186f0c 100644 --- a/vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md +++ b/vendor/github.com/aws/aws-sdk-go/CONTRIBUTING.md @@ -64,6 +64,11 @@ Please be aware of the following notes prior to opening a pull request: SDK's test coverage percentage are unlikely to be merged until tests have been added. +5. The JSON files under the SDK's `models` folder are sourced from outside the SDK. + Such as `models/apis/ec2/2016-11-15/api.json`. We will not accept pull requests + directly on these models. If you discover an issue with the models please + create a Github [issue](issues) describing the issue. + ### Testing To run the tests locally, running the `make unit` command will `go get` the diff --git a/vendor/github.com/aws/aws-sdk-go/Makefile b/vendor/github.com/aws/aws-sdk-go/Makefile index fc2bc0cef..b1611d2e3 100644 --- a/vendor/github.com/aws/aws-sdk-go/Makefile +++ b/vendor/github.com/aws/aws-sdk-go/Makefile @@ -64,6 +64,9 @@ integration: get-deps-tests integ-custom smoke-tests performance integ-custom: go test -tags "integration" ./awstesting/integration/customizations/... +cleanup-integ: + go run -tags "integration" ./awstesting/cmd/bucket_cleanup/main.go "aws-sdk-go-integration" + smoke-tests: get-deps-tests gucumber -go-tags "integration" ./awstesting/integration/smoke diff --git a/vendor/github.com/aws/aws-sdk-go/README.md b/vendor/github.com/aws/aws-sdk-go/README.md index bde1fed8d..fefe453f3 100644 --- a/vendor/github.com/aws/aws-sdk-go/README.md +++ b/vendor/github.com/aws/aws-sdk-go/README.md @@ -1,11 +1,4 @@ -# AWS SDK for Go - - -[![API Reference](http://img.shields.io/badge/api-reference-blue.svg)](http://docs.aws.amazon.com/sdk-for-go/api) -[![Join the chat at https://gitter.im/aws/aws-sdk-go](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aws/aws-sdk-go?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://img.shields.io/travis/aws/aws-sdk-go.svg)](https://travis-ci.org/aws/aws-sdk-go) -[![Apache V2 License](http://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt) - +# AWS SDK for Go [![API Reference](http://img.shields.io/badge/api-reference-blue.svg)](http://docs.aws.amazon.com/sdk-for-go/api) [![Join the chat at https://gitter.im/aws/aws-sdk-go](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/aws/aws-sdk-go?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://img.shields.io/travis/aws/aws-sdk-go.svg)](https://travis-ci.org/aws/aws-sdk-go) [![Apache V2 License](http://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/aws/aws-sdk-go/blob/master/LICENSE.txt) aws-sdk-go is the official AWS SDK for the Go programming language. @@ -33,7 +26,7 @@ These two processes will still include the `vendor` folder and it should be dele ## Getting Help Please use these community resources for getting help. We use the GitHub issues for tracking bugs and feature requests. -* Ask a question on [StackOverflow](http://stackoverflow.com/) and tag it with the `aws-sdk-go` tag. +* Ask a question on [StackOverflow](http://stackoverflow.com/) and tag it with the [`aws-sdk-go`](http://stackoverflow.com/questions/tagged/aws-sdk-go) tag. * Come join the AWS SDK for Go community chat on [gitter](https://gitter.im/aws/aws-sdk-go). * Open a support ticket with [AWS Support](http://docs.aws.amazon.com/awssupport/latest/user/getting-started.html). * If you think you may of found a bug, please open an [issue](https://github.com/aws/aws-sdk-go/issues/new). @@ -77,7 +70,7 @@ AWS_SECRET_ACCESS_KEY=MY-SECRET-KEY ``` ### AWS shared config file (`~/.aws/config`) -The AWS SDK for Go added support the shared config file in release [v1.3.0](https://github.com/aws/aws-sdk-go/releases/tag/v1.3.0). You can opt into enabling support for the shared config by setting the environment variable `AWS_SDK_LOAD_CONFIG` to a truthy value. See the [Session](https://github.com/aws/aws-sdk-go/wiki/sessions) wiki for more information about this feature. +The AWS SDK for Go added support the shared config file in release [v1.3.0](https://github.com/aws/aws-sdk-go/releases/tag/v1.3.0). You can opt into enabling support for the shared config by setting the environment variable `AWS_SDK_LOAD_CONFIG` to a truthy value. See the [Session](https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/sessions.html) docs for more information about this feature. ## Using the Go SDK @@ -85,44 +78,77 @@ To use a service in the SDK, create a service variable by calling the `New()` function. Once you have a service client, you can call API operations which each return response data and a possible error. -To list a set of instance IDs from EC2, you could run: +For example the following code shows how to upload an object to Amazon S3 with a Context timeout. ```go package main import ( + "context" + "flag" "fmt" + "os" + "time" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/ec2" + "github.com/aws/aws-sdk-go/service/s3" ) +// Uploads a file to S3 given a bucket and object key. Also takes a duration +// value to terminate the update if it doesn't complete within that time. +// +// The AWS Region needs to be provided in the AWS shared config or on the +// environment variable as `AWS_REGION`. Credentials also must be provided +// Will default to shared config file, but can load from environment if provided. +// +// Usage: +// # Upload myfile.txt to myBucket/myKey. Must complete within 10 minutes or will fail +// go run withContext.go -b mybucket -k myKey -d 10m < myfile.txt func main() { - sess, err := session.NewSession() - if err != nil { - panic(err) + var bucket, key string + var timeout time.Duration + + flag.StringVar(&bucket, "b", "", "Bucket name.") + flag.StringVar(&key, "k", "", "Object key name.") + flag.DurationVar(&timeout, "d", 0, "Upload timeout.") + flag.Parse() + + sess := session.Must(session.NewSession()) + svc := s3.New(sess) + + // Create a context with a timeout that will abort the upload if it takes + // more than the passed in timeout. + ctx := context.Background() + var cancelFn func() + if timeout > 0 { + ctx, cancelFn = context.WithTimeout(ctx, timeout) } - - // Create an EC2 service object in the "us-west-2" region - // Note that you can also configure your region globally by - // exporting the AWS_REGION environment variable - svc := ec2.New(sess, &aws.Config{Region: aws.String("us-west-2")}) - - // Call the DescribeInstances Operation - resp, err := svc.DescribeInstances(nil) + // Ensure the context is canceled to prevent leaking. + // See context package for more information, https://golang.org/pkg/context/ + defer cancelFn() + + // Uploads the object to S3. The Context will interrupt the request if the + // timeout expires. + _, err := svc.PutObjectWithContext(ctx, &s3.PutObjectInput{ + Bucket: aws.String(bucket), + Key: aws.String(key), + Body: os.Stdin, + }) if err != nil { - panic(err) - } - - // resp has all of the response data, pull out instance IDs: - fmt.Println("> Number of reservation sets: ", len(resp.Reservations)) - for idx, res := range resp.Reservations { - fmt.Println(" > Number of instances: ", len(res.Instances)) - for _, inst := range resp.Reservations[idx].Instances { - fmt.Println(" - Instance ID: ", *inst.InstanceId) + if aerr, ok := err.(awserr.Error); ok && aerr.Code() == request.CanceledErrorCode { + // If the SDK can determine the request or retry delay was canceled + // by a context the CanceledErrorCode error code will be returned. + fmt.Fprintf(os.Stderr, "upload canceled due to timeout, %v\n", err) + } else { + fmt.Fprintf(os.Stderr, "failed to upload object, %v\n", err) } + os.Exit(1) } + + fmt.Printf("successfully uploaded file to %s/%s\n", bucket, key) } ``` diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/client.go b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go index 17fc76a0f..48b0fbd93 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/client/client.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/client.go @@ -5,6 +5,7 @@ import ( "net/http/httputil" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/client/metadata" "github.com/aws/aws-sdk-go/aws/request" ) @@ -46,7 +47,7 @@ func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, op svc := &Client{ Config: cfg, ClientInfo: info, - Handlers: handlers, + Handlers: handlers.Copy(), } switch retryer, ok := cfg.Retryer.(request.Retryer); { @@ -86,8 +87,8 @@ func (c *Client) AddDebugHandlers() { return } - c.Handlers.Send.PushFront(logRequest) - c.Handlers.Send.PushBack(logResponse) + c.Handlers.Send.PushFrontNamed(request.NamedHandler{Name: "awssdk.client.LogRequest", Fn: logRequest}) + c.Handlers.Send.PushBackNamed(request.NamedHandler{Name: "awssdk.client.LogResponse", Fn: logResponse}) } const logReqMsg = `DEBUG: Request %s/%s Details: @@ -105,6 +106,7 @@ func logRequest(r *request.Request) { dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody) if err != nil { r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) + r.Error = awserr.New(request.ErrCodeRead, "an error occurred during request body reading", err) return } @@ -135,6 +137,7 @@ func logResponse(r *request.Request) { dumpedBody, err := httputil.DumpResponse(r.HTTPResponse, logBody) if err != nil { r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) + r.Error = awserr.New(request.ErrCodeRead, "an error occurred during response body reading", err) return } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/client_test.go b/vendor/github.com/aws/aws-sdk-go/aws/client/client_test.go new file mode 100644 index 000000000..30d3b9997 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/client_test.go @@ -0,0 +1,78 @@ +package client + +import ( + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" +) + +func pushBackTestHandler(name string, list *request.HandlerList) *bool { + called := false + (*list).PushBackNamed(request.NamedHandler{ + Name: name, + Fn: func(r *request.Request) { + called = true + }, + }) + + return &called +} + +func pushFrontTestHandler(name string, list *request.HandlerList) *bool { + called := false + (*list).PushFrontNamed(request.NamedHandler{ + Name: name, + Fn: func(r *request.Request) { + called = true + }, + }) + + return &called +} + +func TestNewClient_CopyHandlers(t *testing.T) { + handlers := request.Handlers{} + firstCalled := pushBackTestHandler("first", &handlers.Send) + secondCalled := pushBackTestHandler("second", &handlers.Send) + + var clientHandlerCalled *bool + c := New(aws.Config{}, metadata.ClientInfo{}, handlers, + func(c *Client) { + clientHandlerCalled = pushFrontTestHandler("client handler", &c.Handlers.Send) + }, + ) + + if e, a := 2, handlers.Send.Len(); e != a { + t.Errorf("expect %d original handlers, got %d", e, a) + } + if e, a := 3, c.Handlers.Send.Len(); e != a { + t.Errorf("expect %d client handlers, got %d", e, a) + } + + handlers.Send.Run(nil) + if !*firstCalled { + t.Errorf("expect first handler to of been called") + } + *firstCalled = false + if !*secondCalled { + t.Errorf("expect second handler to of been called") + } + *secondCalled = false + if *clientHandlerCalled { + t.Errorf("expect client handler to not of been called, but was") + } + + c.Handlers.Send.Run(nil) + if !*firstCalled { + t.Errorf("expect client's first handler to of been called") + } + if !*secondCalled { + t.Errorf("expect client's second handler to of been called") + } + if !*clientHandlerCalled { + t.Errorf("expect client's client handler to of been called") + } + +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go index 43a3676b7..1313478f2 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go @@ -54,6 +54,12 @@ func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration { // ShouldRetry returns true if the request should be retried. func (d DefaultRetryer) ShouldRetry(r *request.Request) bool { + // If one of the other handlers already set the retry state + // we don't want to override it based on the service's state + if r.Retryable != nil { + return *r.Retryable + } + if r.HTTPResponse.StatusCode >= 500 { return true } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/config.go b/vendor/github.com/aws/aws-sdk-go/aws/config.go index d58b81280..d1f31f1c6 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/config.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/config.go @@ -22,9 +22,9 @@ type RequestRetryer interface{} // // // Create Session with MaxRetry configuration to be shared by multiple // // service clients. -// sess, err := session.NewSession(&aws.Config{ +// sess := session.Must(session.NewSession(&aws.Config{ // MaxRetries: aws.Int(3), -// }) +// })) // // // Create S3 service client with a specific Region. // svc := s3.New(sess, &aws.Config{ @@ -53,6 +53,13 @@ type Config struct { // to use based on region. EndpointResolver endpoints.Resolver + // EnforceShouldRetryCheck is used in the AfterRetryHandler to always call + // ShouldRetry regardless of whether or not if request.Retryable is set. + // This will utilize ShouldRetry method of custom retryers. If EnforceShouldRetryCheck + // is not set, then ShouldRetry will only be called if request.Retryable is nil. + // Proper handling of the request.Retryable field is important when setting this field. + EnforceShouldRetryCheck *bool + // The region to send requests to. This parameter is required and must // be configured globally or on a per-client basis unless otherwise // noted. A full list of regions is found in the "Regions and Endpoints" @@ -154,7 +161,8 @@ type Config struct { // the EC2Metadata overriding the timeout for default credentials chain. // // Example: - // sess, err := session.NewSession(aws.NewConfig().WithEC2MetadataDiableTimeoutOverride(true)) + // sess := session.Must(session.NewSession(aws.NewConfig() + // .WithEC2MetadataDiableTimeoutOverride(true))) // // svc := s3.New(sess) // @@ -174,7 +182,7 @@ type Config struct { // // Only supported with. // - // sess, err := session.NewSession() + // sess := session.Must(session.NewSession()) // // svc := s3.New(sess, &aws.Config{ // UseDualStack: aws.Bool(true), @@ -186,13 +194,19 @@ type Config struct { // request delays. This value should only be used for testing. To adjust // the delay of a request see the aws/client.DefaultRetryer and // aws/request.Retryer. + // + // SleepDelay will prevent any Context from being used for canceling retry + // delay of an API operation. It is recommended to not use SleepDelay at all + // and specify a Retryer instead. SleepDelay func(time.Duration) // DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests. // Will default to false. This would only be used for empty directory names in s3 requests. // // Example: - // sess, err := session.NewSession(&aws.Config{DisableRestProtocolURICleaning: aws.Bool(true)) + // sess := session.Must(session.NewSession(&aws.Config{ + // DisableRestProtocolURICleaning: aws.Bool(true), + // })) // // svc := s3.New(sess) // out, err := svc.GetObject(&s3.GetObjectInput { @@ -207,9 +221,9 @@ type Config struct { // // // Create Session with MaxRetry configuration to be shared by multiple // // service clients. -// sess, err := session.NewSession(aws.NewConfig(). +// sess := session.Must(session.NewSession(aws.NewConfig(). // WithMaxRetries(3), -// ) +// )) // // // Create S3 service client with a specific Region. // svc := s3.New(sess, aws.NewConfig(). @@ -436,6 +450,10 @@ func mergeInConfig(dst *Config, other *Config) { if other.DisableRestProtocolURICleaning != nil { dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning } + + if other.EnforceShouldRetryCheck != nil { + dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck + } } // Copy will return a shallow copy of the Config object. If any additional diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context.go b/vendor/github.com/aws/aws-sdk-go/aws/context.go new file mode 100644 index 000000000..79f426853 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context.go @@ -0,0 +1,71 @@ +package aws + +import ( + "time" +) + +// Context is an copy of the Go v1.7 stdlib's context.Context interface. +// It is represented as a SDK interface to enable you to use the "WithContext" +// API methods with Go v1.6 and a Context type such as golang.org/x/net/context. +// +// See https://golang.org/pkg/context on how to use contexts. +type Context interface { + // Deadline returns the time when work done on behalf of this context + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that's closed when work done on behalf of this + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. + Done() <-chan struct{} + + // Err returns a non-nil error value after Done is closed. Err returns + // Canceled if the context was canceled or DeadlineExceeded if the + // context's deadline passed. No other values for Err are defined. + // After Done is closed, successive calls to Err return the same value. + Err() error + + // Value returns the value associated with this context for key, or nil + // if no value is associated with key. Successive calls to Value with + // the same key returns the same result. + // + // Use context values only for request-scoped data that transits + // processes and API boundaries, not for passing optional parameters to + // functions. + Value(key interface{}) interface{} +} + +// BackgroundContext returns a context that will never be canceled, has no +// values, and no deadline. This context is used by the SDK to provide +// backwards compatibility with non-context API operations and functionality. +// +// Go 1.6 and before: +// This context function is equivalent to context.Background in the Go stdlib. +// +// Go 1.7 and later: +// The context returned will be the value returned by context.Background() +// +// See https://golang.org/pkg/context for more information on Contexts. +func BackgroundContext() Context { + return backgroundCtx +} + +// SleepWithContext will wait for the timer duration to expire, or the context +// is canceled. Which ever happens first. If the context is canceled the Context's +// error will be returned. +// +// Expects Context to always return a non-nil error if the Done channel is closed. +func SleepWithContext(ctx Context, dur time.Duration) error { + t := time.NewTimer(dur) + defer t.Stop() + + select { + case <-t.C: + break + case <-ctx.Done(): + return ctx.Err() + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go b/vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go new file mode 100644 index 000000000..e8cf93d26 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go @@ -0,0 +1,41 @@ +// +build !go1.7 + +package aws + +import "time" + +// An emptyCtx is a copy of the the Go 1.7 context.emptyCtx type. This +// is copied to provide a 1.6 and 1.5 safe version of context that is compatible +// with Go 1.7's Context. +// +// An emptyCtx is never canceled, has no values, and has no deadline. It is not +// struct{}, since vars of this type must have distinct addresses. +type emptyCtx int + +func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { + return +} + +func (*emptyCtx) Done() <-chan struct{} { + return nil +} + +func (*emptyCtx) Err() error { + return nil +} + +func (*emptyCtx) Value(key interface{}) interface{} { + return nil +} + +func (e *emptyCtx) String() string { + switch e { + case backgroundCtx: + return "aws.BackgroundContext" + } + return "unknown empty Context" +} + +var ( + backgroundCtx = new(emptyCtx) +) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go new file mode 100644 index 000000000..064f75c92 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go @@ -0,0 +1,9 @@ +// +build go1.7 + +package aws + +import "context" + +var ( + backgroundCtx = context.Background() +) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/context_test.go b/vendor/github.com/aws/aws-sdk-go/aws/context_test.go new file mode 100644 index 000000000..d80a1bb6d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/context_test.go @@ -0,0 +1,37 @@ +package aws_test + +import ( + "fmt" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/awstesting" +) + +func TestSleepWithContext(t *testing.T) { + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} + + err := aws.SleepWithContext(ctx, 1*time.Millisecond) + if err != nil { + t.Errorf("expect context to not be canceled, got %v", err) + } +} + +func TestSleepWithContext_Canceled(t *testing.T) { + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} + + expectErr := fmt.Errorf("context canceled") + + ctx.Error = expectErr + close(ctx.DoneCh) + + err := aws.SleepWithContext(ctx, 1*time.Millisecond) + if err == nil { + t.Fatalf("expect error, did not get one") + } + + if e, a := expectErr, err; e != a { + t.Errorf("expect %v error, got %v", e, a) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go index 8a7bafc78..25b461c31 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go @@ -27,7 +27,7 @@ type lener interface { // or will use the HTTPRequest.Header's "Content-Length" if defined. If unable // to determine request body length and no "Content-Length" was specified it will panic. // -// The Content-Length will only be aded to the request if the length of the body +// The Content-Length will only be added to the request if the length of the body // is greater than 0. If the body is empty or the current `Content-Length` // header is <= 0, the header will also be stripped. var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) { @@ -71,8 +71,8 @@ var reStatusCode = regexp.MustCompile(`^(\d{3})`) // ValidateReqSigHandler is a request handler to ensure that the request's // signature doesn't expire before it is sent. This can happen when a request -// is built and signed signficantly before it is sent. Or significant delays -// occur whne retrying requests that would cause the signature to expire. +// is built and signed significantly before it is sent. Or significant delays +// occur when retrying requests that would cause the signature to expire. var ValidateReqSigHandler = request.NamedHandler{ Name: "core.ValidateReqSigHandler", Fn: func(r *request.Request) { @@ -98,44 +98,79 @@ var ValidateReqSigHandler = request.NamedHandler{ } // SendHandler is a request handler to send service request using HTTP client. -var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *request.Request) { - var err error - r.HTTPResponse, err = r.Config.HTTPClient.Do(r.HTTPRequest) - if err != nil { - // Prevent leaking if an HTTPResponse was returned. Clean up - // the body. - if r.HTTPResponse != nil { - r.HTTPResponse.Body.Close() +var SendHandler = request.NamedHandler{ + Name: "core.SendHandler", + Fn: func(r *request.Request) { + sender := sendFollowRedirects + if r.DisableFollowRedirects { + sender = sendWithoutFollowRedirects } - // Capture the case where url.Error is returned for error processing - // response. e.g. 301 without location header comes back as string - // error and r.HTTPResponse is nil. Other url redirect errors will - // comeback in a similar method. - if e, ok := err.(*url.Error); ok && e.Err != nil { - if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil { - code, _ := strconv.ParseInt(s[1], 10, 64) - r.HTTPResponse = &http.Response{ - StatusCode: int(code), - Status: http.StatusText(int(code)), - Body: ioutil.NopCloser(bytes.NewReader([]byte{})), - } - return - } + + var err error + r.HTTPResponse, err = sender(r) + if err != nil { + handleSendError(r, err) } - if r.HTTPResponse == nil { - // Add a dummy request response object to ensure the HTTPResponse - // value is consistent. + }, +} + +func sendFollowRedirects(r *request.Request) (*http.Response, error) { + return r.Config.HTTPClient.Do(r.HTTPRequest) +} + +func sendWithoutFollowRedirects(r *request.Request) (*http.Response, error) { + transport := r.Config.HTTPClient.Transport + if transport == nil { + transport = http.DefaultTransport + } + + return transport.RoundTrip(r.HTTPRequest) +} + +func handleSendError(r *request.Request, err error) { + // Prevent leaking if an HTTPResponse was returned. Clean up + // the body. + if r.HTTPResponse != nil { + r.HTTPResponse.Body.Close() + } + // Capture the case where url.Error is returned for error processing + // response. e.g. 301 without location header comes back as string + // error and r.HTTPResponse is nil. Other URL redirect errors will + // comeback in a similar method. + if e, ok := err.(*url.Error); ok && e.Err != nil { + if s := reStatusCode.FindStringSubmatch(e.Err.Error()); s != nil { + code, _ := strconv.ParseInt(s[1], 10, 64) r.HTTPResponse = &http.Response{ - StatusCode: int(0), - Status: http.StatusText(int(0)), + StatusCode: int(code), + Status: http.StatusText(int(code)), Body: ioutil.NopCloser(bytes.NewReader([]byte{})), } + return } - // Catch all other request errors. - r.Error = awserr.New("RequestError", "send request failed", err) - r.Retryable = aws.Bool(true) // network errors are retryable } -}} + if r.HTTPResponse == nil { + // Add a dummy request response object to ensure the HTTPResponse + // value is consistent. + r.HTTPResponse = &http.Response{ + StatusCode: int(0), + Status: http.StatusText(int(0)), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + } + // Catch all other request errors. + r.Error = awserr.New("RequestError", "send request failed", err) + r.Retryable = aws.Bool(true) // network errors are retryable + + // Override the error with a context canceled error, if that was canceled. + ctx := r.Context() + select { + case <-ctx.Done(): + r.Error = awserr.New(request.CanceledErrorCode, + "request context canceled", ctx.Err()) + r.Retryable = aws.Bool(false) + default: + } +} // ValidateResponseHandler is a request handler to validate service response. var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseHandler", Fn: func(r *request.Request) { @@ -150,13 +185,22 @@ var ValidateResponseHandler = request.NamedHandler{Name: "core.ValidateResponseH var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) { // If one of the other handlers already set the retry state // we don't want to override it based on the service's state - if r.Retryable == nil { + if r.Retryable == nil || aws.BoolValue(r.Config.EnforceShouldRetryCheck) { r.Retryable = aws.Bool(r.ShouldRetry(r)) } if r.WillRetry() { r.RetryDelay = r.RetryRules(r) - r.Config.SleepDelay(r.RetryDelay) + + if sleepFn := r.Config.SleepDelay; sleepFn != nil { + // Support SleepDelay for backwards compatibility and testing + sleepFn(r.RetryDelay) + } else if err := aws.SleepWithContext(r.Context(), r.RetryDelay); err != nil { + r.Error = awserr.New(request.CanceledErrorCode, + "request context canceled", err) + r.Retryable = aws.Bool(false) + return + } // when the expired token exception occurs the credentials // need to be expired locally so that the next request to diff --git a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go index 799285198..fe7d3c9bc 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers_test.go @@ -96,6 +96,94 @@ func TestAfterRetryRefreshCreds(t *testing.T) { assert.True(t, credProvider.retrieveCalled) } +func TestAfterRetryWithContextCanceled(t *testing.T) { + c := awstesting.NewClient() + + req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{}, 0)} + req.SetContext(ctx) + + req.Error = fmt.Errorf("some error") + req.Retryable = aws.Bool(true) + req.HTTPResponse = &http.Response{ + StatusCode: 500, + } + + close(ctx.DoneCh) + ctx.Error = fmt.Errorf("context canceled") + + corehandlers.AfterRetryHandler.Fn(req) + + if req.Error == nil { + t.Fatalf("expect error but didn't receive one") + } + + aerr := req.Error.(awserr.Error) + + if e, a := request.CanceledErrorCode, aerr.Code(); e != a { + t.Errorf("expect %q, error code got %q", e, a) + } +} + +func TestAfterRetryWithContext(t *testing.T) { + c := awstesting.NewClient() + + req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{}, 0)} + req.SetContext(ctx) + + req.Error = fmt.Errorf("some error") + req.Retryable = aws.Bool(true) + req.HTTPResponse = &http.Response{ + StatusCode: 500, + } + + corehandlers.AfterRetryHandler.Fn(req) + + if req.Error != nil { + t.Fatalf("expect no error, got %v", req.Error) + } + if e, a := 1, req.RetryCount; e != a { + t.Errorf("expect retry count to be %d, got %d", e, a) + } +} + +func TestSendWithContextCanceled(t *testing.T) { + c := awstesting.NewClient(&aws.Config{ + SleepDelay: func(dur time.Duration) { + t.Errorf("SleepDelay should not be called") + }, + }) + + req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{}, 0)} + req.SetContext(ctx) + + req.Error = fmt.Errorf("some error") + req.Retryable = aws.Bool(true) + req.HTTPResponse = &http.Response{ + StatusCode: 500, + } + + close(ctx.DoneCh) + ctx.Error = fmt.Errorf("context canceled") + + corehandlers.SendHandler.Fn(req) + + if req.Error == nil { + t.Fatalf("expect error but didn't receive one") + } + + aerr := req.Error.(awserr.Error) + + if e, a := request.CanceledErrorCode, aerr.Code(); e != a { + t.Errorf("expect %q, error code got %q", e, a) + } +} + type testSendHandlerTransport struct{} func (t *testSendHandlerTransport) RoundTrip(r *http.Request) (*http.Response, error) { @@ -118,6 +206,39 @@ func TestSendHandlerError(t *testing.T) { assert.NotNil(t, r.HTTPResponse) } +func TestSendWithoutFollowRedirects(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/original": + w.Header().Set("Location", "/redirected") + w.WriteHeader(301) + case "/redirected": + t.Fatalf("expect not to redirect, but was") + } + })) + + svc := awstesting.NewClient(&aws.Config{ + DisableSSL: aws.Bool(true), + Endpoint: aws.String(server.URL), + }) + svc.Handlers.Clear() + svc.Handlers.Send.PushBackNamed(corehandlers.SendHandler) + + r := svc.NewRequest(&request.Operation{ + Name: "Operation", + HTTPPath: "/original", + }, nil, nil) + r.DisableFollowRedirects = true + + err := r.Send() + if err != nil { + t.Errorf("expect no error, got %v", err) + } + if e, a := 301, r.HTTPResponse.StatusCode; e != a { + t.Errorf("expect %d status code, got %d", e, a) + } +} + func TestValidateReqSigHandler(t *testing.T) { cases := []struct { Req *request.Request diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go index 7b8ebf5f9..03630cf0d 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go @@ -88,7 +88,7 @@ type Value struct { // The Provider should not need to implement its own mutexes, because // that will be managed by Credentials. type Provider interface { - // Refresh returns nil if it successfully retrieved the value. + // Retrieve returns nil if it successfully retrieved the value. // Error is returned if the value were not obtainable, or empty. Retrieve() (Value, error) @@ -97,6 +97,27 @@ type Provider interface { IsExpired() bool } +// An ErrorProvider is a stub credentials provider that always returns an error +// this is used by the SDK when construction a known provider is not possible +// due to an error. +type ErrorProvider struct { + // The error to be returned from Retrieve + Err error + + // The provider name to set on the Retrieved returned Value + ProviderName string +} + +// Retrieve will always return the error that the ErrorProvider was created with. +func (p ErrorProvider) Retrieve() (Value, error) { + return Value{ProviderName: p.ProviderName}, p.Err +} + +// IsExpired will always return not expired. +func (p ErrorProvider) IsExpired() bool { + return false +} + // A Expiry provides shared expiration logic to be used by credentials // providers to implement expiry functionality. // diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go index 30c847ae2..b84062332 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go @@ -1,7 +1,81 @@ -// Package stscreds are credential Providers to retrieve STS AWS credentials. -// -// STS provides multiple ways to retrieve credentials which can be used when making -// future AWS service API operation calls. +/* +Package stscreds are credential Providers to retrieve STS AWS credentials. + +STS provides multiple ways to retrieve credentials which can be used when making +future AWS service API operation calls. + +The SDK will ensure that per instance of credentials.Credentials all requests +to refresh the credentials will be synchronized. But, the SDK is unable to +ensure synchronous usage of the AssumeRoleProvider if the value is shared +between multiple Credentials, Sessions or service clients. + +Assume Role + +To assume an IAM role using STS with the SDK you can create a new Credentials +with the SDKs's stscreds package. + + // Initial credentials loaded from SDK's default credential chain. Such as + // the environment, shared credentials (~/.aws/credentials), or EC2 Instance + // Role. These credentials will be used to to make the STS Assume Role API. + sess := session.Must(session.NewSession()) + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN. + creds := stscreds.NewCredentials(sess, "myRoleArn") + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +Assume Role with static MFA Token + +To assume an IAM role with a MFA token you can either specify a MFA token code +directly or provide a function to prompt the user each time the credentials +need to refresh the role's credentials. Specifying the TokenCode should be used +for short lived operations that will not need to be refreshed, and when you do +not want to have direct control over the user provides their MFA token. + +With TokenCode the AssumeRoleProvider will be not be able to refresh the role's +credentials. + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN using the MFA token code provided. + creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) { + p.SerialNumber = aws.String("myTokenSerialNumber") + p.TokenCode = aws.String("00000000") + }) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +Assume Role with MFA Token Provider + +To assume an IAM role with MFA for longer running tasks where the credentials +may need to be refreshed setting the TokenProvider field of AssumeRoleProvider +will allow the credential provider to prompt for new MFA token code when the +role's credentials need to be refreshed. + +The StdinTokenProvider function is available to prompt on stdin to retrieve +the MFA token code from the user. You can also implement custom prompts by +satisfing the TokenProvider function signature. + +Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will +have undesirable results as the StdinTokenProvider will not be synchronized. A +single Credentials with an AssumeRoleProvider can be shared safely. + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN. Prompting for MFA token from stdin. + creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) { + p.SerialNumber = aws.String("myTokenSerialNumber") + p.TokenProvider = stscreds.StdinTokenProvider + }) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +*/ package stscreds import ( @@ -9,11 +83,31 @@ import ( "time" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/client" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/service/sts" ) +// StdinTokenProvider will prompt on stdout and read from stdin for a string value. +// An error is returned if reading from stdin fails. +// +// Use this function go read MFA tokens from stdin. The function makes no attempt +// to make atomic prompts from stdin across multiple gorouties. +// +// Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will +// have undesirable results as the StdinTokenProvider will not be synchronized. A +// single Credentials with an AssumeRoleProvider can be shared safely +// +// Will wait forever until something is provided on the stdin. +func StdinTokenProvider() (string, error) { + var v string + fmt.Printf("Assume Role MFA token code: ") + _, err := fmt.Scanln(&v) + + return v, err +} + // ProviderName provides a name of AssumeRole provider const ProviderName = "AssumeRoleProvider" @@ -27,8 +121,15 @@ type AssumeRoler interface { var DefaultDuration = time.Duration(15) * time.Minute // AssumeRoleProvider retrieves temporary credentials from the STS service, and -// keeps track of their expiration time. This provider must be used explicitly, -// as it is not included in the credentials chain. +// keeps track of their expiration time. +// +// This credential provider will be used by the SDKs default credential change +// when shared configuration is enabled, and the shared config or shared credentials +// file configure assume role. See Session docs for how to do this. +// +// AssumeRoleProvider does not provide any synchronization and it is not safe +// to share this value across multiple Credentials, Sessions, or service clients +// without also sharing the same Credentials instance. type AssumeRoleProvider struct { credentials.Expiry @@ -65,8 +166,23 @@ type AssumeRoleProvider struct { // assumed requires MFA (that is, if the policy includes a condition that tests // for MFA). If the role being assumed requires MFA and if the TokenCode value // is missing or expired, the AssumeRole call returns an "access denied" error. + // + // If SerialNumber is set and neither TokenCode nor TokenProvider are also + // set an error will be returned. TokenCode *string + // Async method of providing MFA token code for assuming an IAM role with MFA. + // The value returned by the function will be used as the TokenCode in the Retrieve + // call. See StdinTokenProvider for a provider that prompts and reads from stdin. + // + // This token provider will be called when ever the assumed role's + // credentials need to be refreshed when SerialNumber is also set and + // TokenCode is not set. + // + // If both TokenCode and TokenProvider is set, TokenProvider will be used and + // TokenCode is ignored. + TokenProvider func() (string, error) + // ExpiryWindow will allow the credentials to trigger refreshing prior to // the credentials actually expiring. This is beneficial so race conditions // with expiring credentials do not cause request to fail unexpectedly @@ -85,6 +201,10 @@ type AssumeRoleProvider struct { // // Takes a Config provider to create the STS client. The ConfigProvider is // satisfied by the session.Session type. +// +// It is safe to share the returned Credentials with multiple Sessions and +// service clients. All access to the credentials and refreshing them +// will be synchronized. func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { p := &AssumeRoleProvider{ Client: sts.New(c), @@ -103,7 +223,11 @@ func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*As // AssumeRoleProvider. The credentials will expire every 15 minutes and the // role will be named after a nanosecond timestamp of this operation. // -// Takes an AssumeRoler which can be satisfiede by the STS client. +// Takes an AssumeRoler which can be satisfied by the STS client. +// +// It is safe to share the returned Credentials with multiple Sessions and +// service clients. All access to the credentials and refreshing them +// will be synchronized. func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { p := &AssumeRoleProvider{ Client: svc, @@ -139,12 +263,25 @@ func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) { if p.Policy != nil { input.Policy = p.Policy } - if p.SerialNumber != nil && p.TokenCode != nil { - input.SerialNumber = p.SerialNumber - input.TokenCode = p.TokenCode + if p.SerialNumber != nil { + if p.TokenCode != nil { + input.SerialNumber = p.SerialNumber + input.TokenCode = p.TokenCode + } else if p.TokenProvider != nil { + input.SerialNumber = p.SerialNumber + code, err := p.TokenProvider() + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + input.TokenCode = aws.String(code) + } else { + return credentials.Value{ProviderName: ProviderName}, + awserr.New("AssumeRoleTokenNotAvailable", + "assume role with MFA enabled, but neither TokenCode nor TokenProvider are set", nil) + } } - roleOutput, err := p.Client.AssumeRole(input) + roleOutput, err := p.Client.AssumeRole(input) if err != nil { return credentials.Value{ProviderName: ProviderName}, err } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go index 6bd6e9197..4c0212a01 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider_test.go @@ -1,6 +1,7 @@ package stscreds import ( + "fmt" "testing" "time" @@ -10,9 +11,13 @@ import ( ) type stubSTS struct { + TestInput func(*sts.AssumeRoleInput) } func (s *stubSTS) AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) { + if s.TestInput != nil { + s.TestInput(input) + } expiry := time.Now().Add(60 * time.Minute) return &sts.AssumeRoleOutput{ Credentials: &sts.Credentials{ @@ -40,6 +45,95 @@ func TestAssumeRoleProvider(t *testing.T) { assert.Equal(t, "assumedSessionToken", creds.SessionToken, "Expect session token to match") } +func TestAssumeRoleProvider_WithTokenCode(t *testing.T) { + stub := &stubSTS{ + TestInput: func(in *sts.AssumeRoleInput) { + assert.Equal(t, "0123456789", *in.SerialNumber) + assert.Equal(t, "code", *in.TokenCode) + }, + } + p := &AssumeRoleProvider{ + Client: stub, + RoleARN: "roleARN", + SerialNumber: aws.String("0123456789"), + TokenCode: aws.String("code"), + } + + creds, err := p.Retrieve() + assert.Nil(t, err, "Expect no error") + + assert.Equal(t, "roleARN", creds.AccessKeyID, "Expect access key ID to be reflected role ARN") + assert.Equal(t, "assumedSecretAccessKey", creds.SecretAccessKey, "Expect secret access key to match") + assert.Equal(t, "assumedSessionToken", creds.SessionToken, "Expect session token to match") +} + +func TestAssumeRoleProvider_WithTokenProvider(t *testing.T) { + stub := &stubSTS{ + TestInput: func(in *sts.AssumeRoleInput) { + assert.Equal(t, "0123456789", *in.SerialNumber) + assert.Equal(t, "code", *in.TokenCode) + }, + } + p := &AssumeRoleProvider{ + Client: stub, + RoleARN: "roleARN", + SerialNumber: aws.String("0123456789"), + TokenProvider: func() (string, error) { + return "code", nil + }, + } + + creds, err := p.Retrieve() + assert.Nil(t, err, "Expect no error") + + assert.Equal(t, "roleARN", creds.AccessKeyID, "Expect access key ID to be reflected role ARN") + assert.Equal(t, "assumedSecretAccessKey", creds.SecretAccessKey, "Expect secret access key to match") + assert.Equal(t, "assumedSessionToken", creds.SessionToken, "Expect session token to match") +} + +func TestAssumeRoleProvider_WithTokenProviderError(t *testing.T) { + stub := &stubSTS{ + TestInput: func(in *sts.AssumeRoleInput) { + assert.Fail(t, "API request should not of been called") + }, + } + p := &AssumeRoleProvider{ + Client: stub, + RoleARN: "roleARN", + SerialNumber: aws.String("0123456789"), + TokenProvider: func() (string, error) { + return "", fmt.Errorf("error occurred") + }, + } + + creds, err := p.Retrieve() + assert.Error(t, err) + + assert.Empty(t, creds.AccessKeyID) + assert.Empty(t, creds.SecretAccessKey) + assert.Empty(t, creds.SessionToken) +} + +func TestAssumeRoleProvider_MFAWithNoToken(t *testing.T) { + stub := &stubSTS{ + TestInput: func(in *sts.AssumeRoleInput) { + assert.Fail(t, "API request should not of been called") + }, + } + p := &AssumeRoleProvider{ + Client: stub, + RoleARN: "roleARN", + SerialNumber: aws.String("0123456789"), + } + + creds, err := p.Retrieve() + assert.Error(t, err) + + assert.Empty(t, creds.AccessKeyID) + assert.Empty(t, creds.SecretAccessKey) + assert.Empty(t, creds.SessionToken) +} + func BenchmarkAssumeRoleProvider(b *testing.B) { stub := &stubSTS{} p := &AssumeRoleProvider{ diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go index 0ef55040a..07afe3b8e 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go @@ -10,10 +10,12 @@ package defaults import ( "fmt" "net/http" + "net/url" "os" "time" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/corehandlers" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" @@ -56,7 +58,6 @@ func Config() *aws.Config { WithMaxRetries(aws.UseServiceDefaultRetries). WithLogger(aws.NewDefaultLogger()). WithLogLevel(aws.LogOff). - WithSleepDelay(time.Sleep). WithEndpointResolver(endpoints.DefaultResolver()) } @@ -97,23 +98,51 @@ func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credenti }) } -// RemoteCredProvider returns a credenitials provider for the default remote +const ( + httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI" + ecsCredsProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" +) + +// RemoteCredProvider returns a credentials provider for the default remote // endpoints such as EC2 or ECS Roles. func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { - ecsCredURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") + if u := os.Getenv(httpProviderEnvVar); len(u) > 0 { + return localHTTPCredProvider(cfg, handlers, u) + } - if len(ecsCredURI) > 0 { - return ecsCredProvider(cfg, handlers, ecsCredURI) + if uri := os.Getenv(ecsCredsProviderEnvVar); len(uri) > 0 { + u := fmt.Sprintf("http://169.254.170.2%s", uri) + return httpCredProvider(cfg, handlers, u) } return ec2RoleProvider(cfg, handlers) } -func ecsCredProvider(cfg aws.Config, handlers request.Handlers, uri string) credentials.Provider { - const host = `169.254.170.2` +func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { + var errMsg string + + parsed, err := url.Parse(u) + if err != nil { + errMsg = fmt.Sprintf("invalid URL, %v", err) + } else if host := aws.URLHostname(parsed); !(host == "localhost" || host == "127.0.0.1") { + errMsg = fmt.Sprintf("invalid host address, %q, only localhost and 127.0.0.1 are valid.", host) + } + + if len(errMsg) > 0 { + if cfg.Logger != nil { + cfg.Logger.Log("Ignoring, HTTP credential provider", errMsg, err) + } + return credentials.ErrorProvider{ + Err: awserr.New("CredentialsEndpointError", errMsg, err), + ProviderName: endpointcreds.ProviderName, + } + } + + return httpCredProvider(cfg, handlers, u) +} - return endpointcreds.NewProviderClient(cfg, handlers, - fmt.Sprintf("http://%s%s", host, uri), +func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { + return endpointcreds.NewProviderClient(cfg, handlers, u, func(p *endpointcreds.Provider) { p.ExpiryWindow = 5 * time.Minute }, diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults_test.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults_test.go index bea61dea8..d3e4a86b6 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults_test.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults_test.go @@ -6,39 +6,83 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds" "github.com/aws/aws-sdk-go/aws/request" - "github.com/stretchr/testify/assert" ) -func TestECSCredProvider(t *testing.T) { - defer os.Clearenv() - os.Setenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", "/abc/123") +func TestHTTPCredProvider(t *testing.T) { + cases := []struct { + Host string + Fail bool + }{ + {"localhost", false}, {"127.0.0.1", false}, + {"www.example.com", true}, {"169.254.170.2", true}, + } - provider := RemoteCredProvider(aws.Config{}, request.Handlers{}) + defer os.Clearenv() - assert.NotNil(t, provider) + for i, c := range cases { + u := fmt.Sprintf("http://%s/abc/123", c.Host) + os.Setenv(httpProviderEnvVar, u) - ecsProvider, ok := provider.(*endpointcreds.Provider) - assert.NotNil(t, ecsProvider) - assert.True(t, ok) + provider := RemoteCredProvider(aws.Config{}, request.Handlers{}) + if provider == nil { + t.Fatalf("%d, expect provider not to be nil, but was", i) + } - assert.Equal(t, fmt.Sprintf("http://169.254.170.2/abc/123"), - ecsProvider.Client.Endpoint) + if c.Fail { + creds, err := provider.Retrieve() + if err == nil { + t.Fatalf("%d, expect error but got none", i) + } else { + aerr := err.(awserr.Error) + if e, a := "CredentialsEndpointError", aerr.Code(); e != a { + t.Errorf("%d, expect %s error code, got %s", i, e, a) + } + } + if e, a := endpointcreds.ProviderName, creds.ProviderName; e != a { + t.Errorf("%d, expect %s provider name got %s", i, e, a) + } + } else { + httpProvider := provider.(*endpointcreds.Provider) + if e, a := u, httpProvider.Client.Endpoint; e != a { + t.Errorf("%d, expect %q endpoint, got %q", i, e, a) + } + } + } } -func TestDefaultEC2RoleProvider(t *testing.T) { - provider := RemoteCredProvider(aws.Config{}, request.Handlers{}) +func TestECSCredProvider(t *testing.T) { + defer os.Clearenv() + os.Setenv(ecsCredsProviderEnvVar, "/abc/123") - assert.NotNil(t, provider) + provider := RemoteCredProvider(aws.Config{}, request.Handlers{}) + if provider == nil { + t.Fatalf("expect provider not to be nil, but was") + } - ec2Provider, ok := provider.(*ec2rolecreds.EC2RoleProvider) - assert.NotNil(t, ec2Provider) - assert.True(t, ok) + httpProvider := provider.(*endpointcreds.Provider) + if httpProvider == nil { + t.Fatalf("expect provider not to be nil, but was") + } + if e, a := "http://169.254.170.2/abc/123", httpProvider.Client.Endpoint; e != a { + t.Errorf("expect %q endpoint, got %q", e, a) + } +} - fmt.Println(ec2Provider.Client.Endpoint) +func TestDefaultEC2RoleProvider(t *testing.T) { + provider := RemoteCredProvider(aws.Config{}, request.Handlers{}) + if provider == nil { + t.Fatalf("expect provider not to be nil, but was") + } - assert.Equal(t, fmt.Sprintf("http://169.254.169.254/latest"), - ec2Provider.Client.Endpoint) + ec2Provider := provider.(*ec2rolecreds.EC2RoleProvider) + if ec2Provider == nil { + t.Fatalf("expect provider not to be nil, but was") + } + if e, a := "http://169.254.169.254/latest", ec2Provider.Client.Endpoint; e != a { + t.Errorf("expect %q endpoint, got %q", e, a) + } } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index 53616560d..4adca3a7f 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -1,4 +1,4 @@ -// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT. package endpoints @@ -104,8 +104,10 @@ const ( MeteringMarketplaceServiceID = "metering.marketplace" // MeteringMarketplace. MobileanalyticsServiceID = "mobileanalytics" // Mobileanalytics. MonitoringServiceID = "monitoring" // Monitoring. + MturkRequesterServiceID = "mturk-requester" // MturkRequester. OpsworksServiceID = "opsworks" // Opsworks. OpsworksCmServiceID = "opsworks-cm" // OpsworksCm. + OrganizationsServiceID = "organizations" // Organizations. PinpointServiceID = "pinpoint" // Pinpoint. PollyServiceID = "polly" // Polly. RdsServiceID = "rds" // Rds. @@ -129,8 +131,10 @@ const ( StsServiceID = "sts" // Sts. SupportServiceID = "support" // Support. SwfServiceID = "swf" // Swf. + TaggingServiceID = "tagging" // Tagging. WafServiceID = "waf" // Waf. WafRegionalServiceID = "waf-regional" // WafRegional. + WorkdocsServiceID = "workdocs" // Workdocs. WorkspacesServiceID = "workspaces" // Workspaces. XrayServiceID = "xray" // Xray. ) @@ -246,6 +250,7 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, @@ -432,10 +437,14 @@ var awsPartition = partition{ "codebuild": service{ Endpoints: endpoints{ - "eu-west-1": endpoint{}, - "us-east-1": endpoint{}, - "us-east-2": endpoint{}, - "us-west-2": endpoint{}, + "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-2": endpoint{}, }, }, "codecommit": service{ @@ -488,6 +497,7 @@ var awsPartition = partition{ "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-2": endpoint{}, @@ -501,6 +511,7 @@ var awsPartition = partition{ "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-2": endpoint{}, @@ -514,6 +525,7 @@ var awsPartition = partition{ "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-2": endpoint{}, @@ -749,10 +761,11 @@ var awsPartition = partition{ "elasticfilesystem": service{ Endpoints: endpoints{ - "eu-west-1": endpoint{}, - "us-east-1": endpoint{}, - "us-east-2": endpoint{}, - "us-west-2": endpoint{}, + "ap-southeast-2": endpoint{}, + "eu-west-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-2": endpoint{}, }, }, "elasticloadbalancing": service{ @@ -848,6 +861,7 @@ var awsPartition = partition{ "ap-south-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{}, @@ -958,6 +972,7 @@ var awsPartition = partition{ "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, + "eu-west-2": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, "us-west-2": endpoint{}, @@ -1014,6 +1029,7 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, "ap-northeast-2": endpoint{}, + "ap-south-1": endpoint{}, "ap-southeast-1": endpoint{}, "ap-southeast-2": endpoint{}, "eu-central-1": endpoint{}, @@ -1075,10 +1091,13 @@ var awsPartition = partition{ "ap-south-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{}, "sa-east-1": endpoint{}, "us-east-1": endpoint{}, + "us-east-2": endpoint{}, "us-west-1": endpoint{}, "us-west-2": endpoint{}, }, @@ -1110,6 +1129,16 @@ var awsPartition = partition{ "us-west-2": endpoint{}, }, }, + "mturk-requester": service{ + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "sandbox": endpoint{ + Hostname: "mturk-requester-sandbox.us-east-1.amazonaws.com", + }, + "us-east-1": endpoint{}, + }, + }, "opsworks": service{ Endpoints: endpoints{ @@ -1136,6 +1165,19 @@ var awsPartition = partition{ "us-west-2": endpoint{}, }, }, + "organizations": service{ + PartitionEndpoint: "aws-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-global": endpoint{ + Hostname: "organizations.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + }, + }, "pinpoint": service{ Defaults: endpoint{ CredentialScope: credentialScope{ @@ -1346,7 +1388,6 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-south-1": endpoint{}, "ap-southeast-2": endpoint{}, - "ca-central-1": endpoint{}, "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, @@ -1421,6 +1462,7 @@ var awsPartition = partition{ Endpoints: endpoints{ "ap-northeast-1": endpoint{}, + "eu-central-1": endpoint{}, "eu-west-1": endpoint{}, "us-east-1": endpoint{}, "us-east-2": endpoint{}, @@ -1532,6 +1574,25 @@ var awsPartition = partition{ "us-west-2": endpoint{}, }, }, + "tagging": service{ + + Endpoints: endpoints{ + "ap-northeast-1": endpoint{}, + "ap-northeast-2": endpoint{}, + "ap-south-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{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, + }, + }, "waf": service{ PartitionEndpoint: "aws-global", IsRegionalized: boxedFalse, @@ -1554,6 +1615,17 @@ var awsPartition = partition{ "us-west-2": endpoint{}, }, }, + "workdocs": 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{}, + }, + }, "workspaces": service{ Endpoints: endpoints{ @@ -1632,6 +1704,12 @@ var awscnPartition = partition{ "cn-north-1": endpoint{}, }, }, + "codedeploy": service{ + + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, "config": service{ Endpoints: endpoints{ @@ -1809,6 +1887,12 @@ var awscnPartition = partition{ }, "swf": service{ + Endpoints: endpoints{ + "cn-north-1": endpoint{}, + }, + }, + "tagging": service{ + Endpoints: endpoints{ "cn-north-1": endpoint{}, }, @@ -1946,6 +2030,12 @@ var awsusgovPartition = partition{ }, }, }, + "kinesis": service{ + + Endpoints: endpoints{ + "us-gov-west-1": endpoint{}, + }, + }, "kms": service{ Endpoints: endpoints{ diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go index 1e7369dbf..fc7eada77 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go @@ -158,7 +158,7 @@ var funcMap = template.FuncMap{ const v3Tmpl = ` {{ define "defaults" -}} -// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT. package endpoints diff --git a/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go new file mode 100644 index 000000000..a94f04107 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go @@ -0,0 +1,11 @@ +package aws + +// JSONValue is a representation of a grab bag type that will be marshaled +// into a json string. This type can be used just like any other map. +// +// Example: +// values := JSONValue{ +// "Foo": "Bar", +// } +// values["Baz"] = "Qux" +type JSONValue map[string]interface{} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go new file mode 100644 index 000000000..10fc8cb24 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go @@ -0,0 +1,19 @@ +// +build !appengine + +package request + +import ( + "net" + "os" + "syscall" +) + +func isErrConnectionReset(err error) bool { + if opErr, ok := err.(*net.OpError); ok { + if sysErr, ok := opErr.Err.(*os.SyscallError); ok { + return sysErr.Err == syscall.ECONNRESET + } + } + + return false +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_appengine.go b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_appengine.go new file mode 100644 index 000000000..996196e73 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_appengine.go @@ -0,0 +1,11 @@ +// +build appengine + +package request + +import ( + "strings" +) + +func isErrConnectionReset(err error) bool { + return strings.Contains(err.Error(), "connection reset") +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_appengine_test.go b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_appengine_test.go new file mode 100644 index 000000000..29660da23 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_appengine_test.go @@ -0,0 +1,9 @@ +// +build appengine + +package request_test + +import ( + "errors" +) + +var stubConnectionResetError = errors.New("connection reset") diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_test.go b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_test.go new file mode 100644 index 000000000..f02c507d5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_test.go @@ -0,0 +1,11 @@ +// +build !appengine + +package request_test + +import ( + "net" + "os" + "syscall" +) + +var stubConnectionResetError = &net.OpError{Err: &os.SyscallError{Syscall: "read", Err: syscall.ECONNRESET}} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go index 5279c19c0..6c14336f6 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go @@ -18,6 +18,7 @@ type Handlers struct { UnmarshalError HandlerList Retry HandlerList AfterRetry HandlerList + Complete HandlerList } // Copy returns of this handler's lists. @@ -33,6 +34,7 @@ func (h *Handlers) Copy() Handlers { UnmarshalMeta: h.UnmarshalMeta.copy(), Retry: h.Retry.copy(), AfterRetry: h.AfterRetry.copy(), + Complete: h.Complete.copy(), } } @@ -48,6 +50,7 @@ func (h *Handlers) Clear() { h.ValidateResponse.Clear() h.Retry.Clear() h.AfterRetry.Clear() + h.Complete.Clear() } // A HandlerListRunItem represents an entry in the HandlerList which @@ -85,13 +88,17 @@ func (l *HandlerList) copy() HandlerList { n := HandlerList{ AfterEachFn: l.AfterEachFn, } - n.list = append([]NamedHandler{}, l.list...) + if len(l.list) == 0 { + return n + } + + n.list = append(make([]NamedHandler, 0, len(l.list)), l.list...) return n } // Clear clears the handler list. func (l *HandlerList) Clear() { - l.list = []NamedHandler{} + l.list = l.list[0:0] } // Len returns the number of handlers in the list. @@ -101,33 +108,54 @@ func (l *HandlerList) Len() int { // PushBack pushes handler f to the back of the handler list. func (l *HandlerList) PushBack(f func(*Request)) { - l.list = append(l.list, NamedHandler{"__anonymous", f}) -} - -// PushFront pushes handler f to the front of the handler list. -func (l *HandlerList) PushFront(f func(*Request)) { - l.list = append([]NamedHandler{{"__anonymous", f}}, l.list...) + l.PushBackNamed(NamedHandler{"__anonymous", f}) } // PushBackNamed pushes named handler f to the back of the handler list. func (l *HandlerList) PushBackNamed(n NamedHandler) { + if cap(l.list) == 0 { + l.list = make([]NamedHandler, 0, 5) + } l.list = append(l.list, n) } +// PushFront pushes handler f to the front of the handler list. +func (l *HandlerList) PushFront(f func(*Request)) { + l.PushFrontNamed(NamedHandler{"__anonymous", f}) +} + // PushFrontNamed pushes named handler f to the front of the handler list. func (l *HandlerList) PushFrontNamed(n NamedHandler) { - l.list = append([]NamedHandler{n}, l.list...) + if cap(l.list) == len(l.list) { + // Allocating new list required + l.list = append([]NamedHandler{n}, l.list...) + } else { + // Enough room to prepend into list. + l.list = append(l.list, NamedHandler{}) + copy(l.list[1:], l.list) + l.list[0] = n + } } // Remove removes a NamedHandler n func (l *HandlerList) Remove(n NamedHandler) { - newlist := []NamedHandler{} - for _, m := range l.list { - if m.Name != n.Name { - newlist = append(newlist, m) + l.RemoveByName(n.Name) +} + +// RemoveByName removes a NamedHandler by name. +func (l *HandlerList) RemoveByName(name string) { + for i := 0; i < len(l.list); i++ { + m := l.list[i] + if m.Name == name { + // Shift array preventing creating new arrays + copy(l.list[i:], l.list[i+1:]) + l.list[len(l.list)-1] = NamedHandler{} + l.list = l.list[:len(l.list)-1] + + // decrement list so next check to length is correct + i-- } } - l.list = newlist } // Run executes all handlers in the list with a given request object. @@ -163,6 +191,16 @@ func HandlerListStopOnError(item HandlerListRunItem) bool { return item.Request.Error == nil } +// WithAppendUserAgent will add a string to the user agent prefixed with a +// single white space. +func WithAppendUserAgent(s string) Option { + return func(r *Request) { + r.Handlers.Build.PushBack(func(r2 *Request) { + AddToUserAgent(r, s) + }) + } +} + // MakeAddToUserAgentHandler will add the name/version pair to the User-Agent request // header. If the extra parameters are provided they will be added as metadata to the // name/version pair resulting in the following format. diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/handlers_test.go b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers_test.go index b32a6510d..e375a998f 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/handlers_test.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/handlers_test.go @@ -7,6 +7,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/awstesting/unit" + "github.com/aws/aws-sdk-go/service/s3" ) func TestHandlerList(t *testing.T) { @@ -85,3 +87,71 @@ func TestStopHandlers(t *testing.T) { assert.Equal(t, 2, called, "Expect only two handlers to be called") } + +func BenchmarkNewRequest(b *testing.B) { + svc := s3.New(unit.Session) + + for i := 0; i < b.N; i++ { + r, _ := svc.GetObjectRequest(nil) + if r == nil { + b.Fatal("r should not be nil") + } + } +} + +func BenchmarkHandlersCopy(b *testing.B) { + handlers := request.Handlers{} + + handlers.Validate.PushBack(func(r *request.Request) {}) + handlers.Validate.PushBack(func(r *request.Request) {}) + handlers.Build.PushBack(func(r *request.Request) {}) + handlers.Build.PushBack(func(r *request.Request) {}) + handlers.Send.PushBack(func(r *request.Request) {}) + handlers.Send.PushBack(func(r *request.Request) {}) + handlers.Unmarshal.PushBack(func(r *request.Request) {}) + handlers.Unmarshal.PushBack(func(r *request.Request) {}) + + for i := 0; i < b.N; i++ { + h := handlers.Copy() + if e, a := handlers.Validate.Len(), h.Validate.Len(); e != a { + b.Fatalf("expected %d handlers got %d", e, a) + } + } +} + +func BenchmarkHandlersPushBack(b *testing.B) { + handlers := request.Handlers{} + + for i := 0; i < b.N; i++ { + h := handlers.Copy() + h.Validate.PushBack(func(r *request.Request) {}) + h.Validate.PushBack(func(r *request.Request) {}) + h.Validate.PushBack(func(r *request.Request) {}) + h.Validate.PushBack(func(r *request.Request) {}) + } +} + +func BenchmarkHandlersPushFront(b *testing.B) { + handlers := request.Handlers{} + + for i := 0; i < b.N; i++ { + h := handlers.Copy() + h.Validate.PushFront(func(r *request.Request) {}) + h.Validate.PushFront(func(r *request.Request) {}) + h.Validate.PushFront(func(r *request.Request) {}) + h.Validate.PushFront(func(r *request.Request) {}) + } +} + +func BenchmarkHandlersClear(b *testing.B) { + handlers := request.Handlers{} + + for i := 0; i < b.N; i++ { + h := handlers.Copy() + h.Validate.PushFront(func(r *request.Request) {}) + h.Validate.PushFront(func(r *request.Request) {}) + h.Validate.PushFront(func(r *request.Request) {}) + h.Validate.PushFront(func(r *request.Request) {}) + h.Clear() + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go index 77312bb66..4f4f1123a 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/request.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request.go @@ -16,6 +16,24 @@ import ( "github.com/aws/aws-sdk-go/aws/client/metadata" ) +const ( + // ErrCodeSerialization is the serialization error code that is received + // during protocol unmarshaling. + ErrCodeSerialization = "SerializationError" + + // ErrCodeRead is an error that is returned during HTTP reads. + ErrCodeRead = "ReadError" + + // ErrCodeResponseTimeout is the connection timeout error that is recieved + // during body reads. + ErrCodeResponseTimeout = "ResponseTimeout" + + // CanceledErrorCode is the error code that will be returned by an + // API request that was canceled. Requests given a aws.Context may + // return this error when canceled. + CanceledErrorCode = "RequestCanceled" +) + // A Request is the service request to be made. type Request struct { Config aws.Config @@ -23,30 +41,33 @@ type Request struct { Handlers Handlers Retryer - Time time.Time - ExpireTime time.Duration - Operation *Operation - HTTPRequest *http.Request - HTTPResponse *http.Response - Body io.ReadSeeker - BodyStart int64 // offset from beginning of Body that the request body starts - Params interface{} - Error error - Data interface{} - RequestID string - RetryCount int - Retryable *bool - RetryDelay time.Duration - NotHoist bool - SignedHeaderVals http.Header - LastSignedAt time.Time + Time time.Time + ExpireTime time.Duration + Operation *Operation + HTTPRequest *http.Request + HTTPResponse *http.Response + Body io.ReadSeeker + BodyStart int64 // offset from beginning of Body that the request body starts + Params interface{} + Error error + Data interface{} + RequestID string + RetryCount int + Retryable *bool + RetryDelay time.Duration + NotHoist bool + SignedHeaderVals http.Header + LastSignedAt time.Time + DisableFollowRedirects bool + + context aws.Context built bool - // Need to persist an intermideant body betweend the input Body and HTTP + // Need to persist an intermediate body between the input Body and HTTP // request body because the HTTP Client's transport can maintain a reference // to the HTTP request's body after the client has returned. This value is - // safe to use concurrently and rewraps the input Body for each HTTP request. + // safe to use concurrently and wrap the input Body for each HTTP request. safeBody *offsetReader } @@ -60,14 +81,6 @@ type Operation struct { BeforePresignFn func(r *Request) error } -// Paginator keeps track of pagination configuration for an API operation. -type Paginator struct { - InputTokens []string - OutputTokens []string - LimitToken string - TruncationToken string -} - // New returns a new Request pointer for the service API // operation and parameters. // @@ -111,6 +124,94 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers, return r } +// A Option is a functional option that can augment or modify a request when +// using a WithContext API operation method. +type Option func(*Request) + +// WithGetResponseHeader builds a request Option which will retrieve a single +// header value from the HTTP Response. If there are multiple values for the +// header key use WithGetResponseHeaders instead to access the http.Header +// map directly. The passed in val pointer must be non-nil. +// +// This Option can be used multiple times with a single API operation. +// +// var id2, versionID string +// svc.PutObjectWithContext(ctx, params, +// request.WithGetResponseHeader("x-amz-id-2", &id2), +// request.WithGetResponseHeader("x-amz-version-id", &versionID), +// ) +func WithGetResponseHeader(key string, val *string) Option { + return func(r *Request) { + r.Handlers.Complete.PushBack(func(req *Request) { + *val = req.HTTPResponse.Header.Get(key) + }) + } +} + +// WithGetResponseHeaders builds a request Option which will retrieve the +// headers from the HTTP response and assign them to the passed in headers +// variable. The passed in headers pointer must be non-nil. +// +// var headers http.Header +// svc.PutObjectWithContext(ctx, params, request.WithGetResponseHeaders(&headers)) +func WithGetResponseHeaders(headers *http.Header) Option { + return func(r *Request) { + r.Handlers.Complete.PushBack(func(req *Request) { + *headers = req.HTTPResponse.Header + }) + } +} + +// WithLogLevel is a request option that will set the request to use a specific +// log level when the request is made. +// +// svc.PutObjectWithContext(ctx, params, request.WithLogLevel(aws.LogDebugWithHTTPBody) +func WithLogLevel(l aws.LogLevelType) Option { + return func(r *Request) { + r.Config.LogLevel = aws.LogLevel(l) + } +} + +// ApplyOptions will apply each option to the request calling them in the order +// the were provided. +func (r *Request) ApplyOptions(opts ...Option) { + for _, opt := range opts { + opt(r) + } +} + +// Context will always returns a non-nil context. If Request does not have a +// context aws.BackgroundContext will be returned. +func (r *Request) Context() aws.Context { + if r.context != nil { + return r.context + } + return aws.BackgroundContext() +} + +// SetContext adds a Context to the current request that can be used to cancel +// a in-flight request. The Context value must not be nil, or this method will +// panic. +// +// Unlike http.Request.WithContext, SetContext does not return a copy of the +// Request. It is not safe to use use a single Request value for multiple +// requests. A new Request should be created for each API operation request. +// +// Go 1.6 and below: +// The http.Request's Cancel field will be set to the Done() value of +// the context. This will overwrite the Cancel field's value. +// +// Go 1.7 and above: +// The http.Request.WithContext will be used to set the context on the underlying +// http.Request. This will create a shallow copy of the http.Request. The SDK +// may create sub contexts in the future for nested requests such as retries. +func (r *Request) SetContext(ctx aws.Context) { + if ctx == nil { + panic("context cannot be nil") + } + setRequestContext(r, ctx) +} + // WillRetry returns if the request's can be retried. func (r *Request) WillRetry() bool { return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries() @@ -262,7 +363,7 @@ func (r *Request) ResetBody() { // Related golang/go#18257 l, err := computeBodyLength(r.Body) if err != nil { - r.Error = awserr.New("SerializationError", "failed to compute request body size", err) + r.Error = awserr.New(ErrCodeSerialization, "failed to compute request body size", err) return } @@ -344,6 +445,12 @@ func (r *Request) GetBody() io.ReadSeeker { // // Send will not close the request.Request's body. func (r *Request) Send() error { + defer func() { + // Regardless of success or failure of the request trigger the Complete + // request handlers. + r.Handlers.Complete.Run(r) + }() + for { if aws.BoolValue(r.Retryable) { if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) { @@ -446,6 +553,9 @@ func shouldRetryCancel(r *Request) bool { timeoutErr := false errStr := r.Error.Error() if ok { + if awsErr.Code() == CanceledErrorCode { + return false + } err := awsErr.OrigErr() netErr, netOK := err.(net.Error) timeoutErr = netOK && netErr.Temporary() diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go new file mode 100644 index 000000000..a7365cd1e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go @@ -0,0 +1,14 @@ +// +build go1.7 + +package request + +import "github.com/aws/aws-sdk-go/aws" + +// setContext updates the Request to use the passed in context for cancellation. +// Context will also be used for request retry delay. +// +// Creates shallow copy of the http.Request with the WithContext method. +func setRequestContext(r *Request, ctx aws.Context) { + r.context = ctx + r.HTTPRequest = r.HTTPRequest.WithContext(ctx) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go new file mode 100644 index 000000000..307fa0705 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go @@ -0,0 +1,14 @@ +// +build !go1.7 + +package request + +import "github.com/aws/aws-sdk-go/aws" + +// setContext updates the Request to use the passed in context for cancellation. +// Context will also be used for request retry delay. +// +// Creates shallow copy of the http.Request with the WithContext method. +func setRequestContext(r *Request, ctx aws.Context) { + r.context = ctx + r.HTTPRequest.Cancel = ctx.Done() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_test.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_test.go new file mode 100644 index 000000000..2af286756 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_context_test.go @@ -0,0 +1,46 @@ +package request_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/awstesting" +) + +func TestRequest_SetContext(t *testing.T) { + svc := awstesting.NewClient() + svc.Handlers.Clear() + svc.Handlers.Send.PushBackNamed(corehandlers.SendHandler) + + r := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} + r.SetContext(ctx) + + ctx.Error = fmt.Errorf("context canceled") + close(ctx.DoneCh) + + err := r.Send() + if err == nil { + t.Fatalf("expected error, got none") + } + + // Only check against canceled because go 1.6 will not use the context's + // Err(). + if e, a := "canceled", err.Error(); !strings.Contains(a, e) { + t.Errorf("expect %q to be in %q, but was not", e, a) + } +} + +func TestRequest_SetContextPanic(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Fatalf("expect SetContext to panic, did not") + } + }() + r := &request.Request{} + + r.SetContext(nil) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_internal_test.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_internal_test.go index 660f4d49e..966f93455 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/request_internal_test.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_internal_test.go @@ -2,8 +2,6 @@ package request import ( "testing" - - "github.com/stretchr/testify/assert" ) func TestCopy(t *testing.T) { @@ -15,6 +13,15 @@ func TestCopy(t *testing.T) { req.Handlers = handlers r := req.copy() - assert.NotEqual(t, req, r) - assert.Equal(t, req.Operation.HTTPMethod, r.Operation.HTTPMethod) + + if r == req { + t.Fatal("expect request pointer copy to be different") + } + if r.Operation == req.Operation { + t.Errorf("expect request operation pointer to be different") + } + + if e, a := req.Operation.HTTPMethod, r.Operation.HTTPMethod; e != a { + t.Errorf("expect %q http method, got %q", e, a) + } } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go index 2939ec473..59de6736b 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go @@ -2,29 +2,125 @@ package request import ( "reflect" + "sync/atomic" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awsutil" ) -//type Paginater interface { -// HasNextPage() bool -// NextPage() *Request -// EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error -//} +// A Pagination provides paginating of SDK API operations which are paginatable. +// Generally you should not use this type directly, but use the "Pages" API +// operations method to automatically perform pagination for you. Such as, +// "S3.ListObjectsPages", and "S3.ListObjectsPagesWithContext" methods. +// +// Pagination differs from a Paginator type in that pagination is the type that +// does the pagination between API operations, and Paginator defines the +// configuration that will be used per page request. +// +// cont := true +// for p.Next() && cont { +// data := p.Page().(*s3.ListObjectsOutput) +// // process the page's data +// } +// return p.Err() +// +// See service client API operation Pages methods for examples how the SDK will +// use the Pagination type. +type Pagination struct { + // Function to return a Request value for each pagination request. + // Any configuration or handlers that need to be applied to the request + // prior to getting the next page should be done here before the request + // returned. + // + // NewRequest should always be built from the same API operations. It is + // undefined if different API operations are returned on subsequent calls. + NewRequest func() (*Request, error) -// HasNextPage returns true if this request has more pages of data available. -func (r *Request) HasNextPage() bool { - return len(r.nextPageTokens()) > 0 + started bool + nextTokens []interface{} + + err error + curPage interface{} } -// nextPageTokens returns the tokens to use when asking for the next page of -// data. +// HasNextPage will return true if Pagination is able to determine that the API +// operation has additional pages. False will be returned if there are no more +// pages remaining. +// +// Will always return true if Next has not been called yet. +func (p *Pagination) HasNextPage() bool { + return !(p.started && len(p.nextTokens) == 0) +} + +// Err returns the error Pagination encountered when retrieving the next page. +func (p *Pagination) Err() error { + return p.err +} + +// Page returns the current page. Page should only be called after a successful +// call to Next. It is undefined what Page will return if Page is called after +// Next returns false. +func (p *Pagination) Page() interface{} { + return p.curPage +} + +// Next will attempt to retrieve the next page for the API operation. When a page +// is retrieved true will be returned. If the page cannot be retrieved, or there +// are no more pages false will be returned. +// +// Use the Page method to retrieve the current page data. The data will need +// to be cast to the API operation's output type. +// +// Use the Err method to determine if an error occurred if Page returns false. +func (p *Pagination) Next() bool { + if !p.HasNextPage() { + return false + } + + req, err := p.NewRequest() + if err != nil { + p.err = err + return false + } + + if p.started { + for i, intok := range req.Operation.InputTokens { + awsutil.SetValueAtPath(req.Params, intok, p.nextTokens[i]) + } + } + p.started = true + + err = req.Send() + if err != nil { + p.err = err + return false + } + + p.nextTokens = req.nextPageTokens() + p.curPage = req.Data + + return true +} + +// A Paginator is the configuration data that defines how an API operation +// should be paginated. This type is used by the API service models to define +// the generated pagination config for service APIs. +// +// The Pagination type is what provides iterating between pages of an API. It +// is only used to store the token metadata the SDK should use for performing +// pagination. +type Paginator struct { + InputTokens []string + OutputTokens []string + LimitToken string + TruncationToken string +} + +// nextPageTokens returns the tokens to use when asking for the next page of data. func (r *Request) nextPageTokens() []interface{} { if r.Operation.Paginator == nil { return nil } - if r.Operation.TruncationToken != "" { tr, _ := awsutil.ValuesAtPath(r.Data, r.Operation.TruncationToken) if len(tr) == 0 { @@ -61,9 +157,40 @@ func (r *Request) nextPageTokens() []interface{} { return tokens } +// Ensure a deprecated item is only logged once instead of each time its used. +func logDeprecatedf(logger aws.Logger, flag *int32, msg string) { + if logger == nil { + return + } + if atomic.CompareAndSwapInt32(flag, 0, 1) { + logger.Log(msg) + } +} + +var ( + logDeprecatedHasNextPage int32 + logDeprecatedNextPage int32 + logDeprecatedEachPage int32 +) + +// HasNextPage returns true if this request has more pages of data available. +// +// Deprecated Use Pagination type for configurable pagination of API operations +func (r *Request) HasNextPage() bool { + logDeprecatedf(r.Config.Logger, &logDeprecatedHasNextPage, + "Request.HasNextPage deprecated. Use Pagination type for configurable pagination of API operations") + + return len(r.nextPageTokens()) > 0 +} + // NextPage returns a new Request that can be executed to return the next // page of result data. Call .Send() on this request to execute it. +// +// Deprecated Use Pagination type for configurable pagination of API operations func (r *Request) NextPage() *Request { + logDeprecatedf(r.Config.Logger, &logDeprecatedNextPage, + "Request.NextPage deprecated. Use Pagination type for configurable pagination of API operations") + tokens := r.nextPageTokens() if len(tokens) == 0 { return nil @@ -90,7 +217,12 @@ func (r *Request) NextPage() *Request { // as the structure "T". The lastPage value represents whether the page is // the last page of data or not. The return value of this function should // return true to keep iterating or false to stop. +// +// Deprecated Use Pagination type for configurable pagination of API operations func (r *Request) EachPage(fn func(data interface{}, isLastPage bool) (shouldContinue bool)) error { + logDeprecatedf(r.Config.Logger, &logDeprecatedEachPage, + "Request.EachPage deprecated. Use Pagination type for configurable pagination of API operations") + for page := r; page != nil; page = page.NextPage() { if err := page.Send(); err != nil { return err diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go index 725ea25cb..73a95bad8 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination_test.go @@ -7,6 +7,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "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/aws/aws-sdk-go/service/dynamodb" "github.com/aws/aws-sdk-go/service/route53" @@ -380,6 +381,154 @@ func TestPaginationNilToken(t *testing.T) { assert.Equal(t, []string{"first.example.com.", "second.example.com.", "third.example.com."}, results) } +func TestPaginationNilInput(t *testing.T) { + // Code generation doesn't have a great way to verify the code is correct + // other than being run via unit tests in the SDK. This should be fixed + // So code generation can be validated independently. + + client := s3.New(unit.Session) + client.Handlers.Validate.Clear() + client.Handlers.Send.Clear() // mock sending + client.Handlers.Unmarshal.Clear() + client.Handlers.UnmarshalMeta.Clear() + client.Handlers.ValidateResponse.Clear() + client.Handlers.Unmarshal.PushBack(func(r *request.Request) { + r.Data = &s3.ListObjectsOutput{} + }) + + gotToEnd := false + numPages := 0 + err := client.ListObjectsPages(nil, func(p *s3.ListObjectsOutput, last bool) bool { + numPages++ + if last { + gotToEnd = true + } + return true + }) + + if err != nil { + t.Fatalf("expect no error, but got %v", err) + } + if e, a := 1, numPages; e != a { + t.Errorf("expect %d number pages but got %d", e, a) + } + if !gotToEnd { + t.Errorf("expect to of gotten to end, did not") + } +} + +func TestPaginationWithContextNilInput(t *testing.T) { + // Code generation doesn't have a great way to verify the code is correct + // other than being run via unit tests in the SDK. This should be fixed + // So code generation can be validated independently. + + client := s3.New(unit.Session) + client.Handlers.Validate.Clear() + client.Handlers.Send.Clear() // mock sending + client.Handlers.Unmarshal.Clear() + client.Handlers.UnmarshalMeta.Clear() + client.Handlers.ValidateResponse.Clear() + client.Handlers.Unmarshal.PushBack(func(r *request.Request) { + r.Data = &s3.ListObjectsOutput{} + }) + + gotToEnd := false + numPages := 0 + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} + err := client.ListObjectsPagesWithContext(ctx, nil, func(p *s3.ListObjectsOutput, last bool) bool { + numPages++ + if last { + gotToEnd = true + } + return true + }) + + if err != nil { + t.Fatalf("expect no error, but got %v", err) + } + if e, a := 1, numPages; e != a { + t.Errorf("expect %d number pages but got %d", e, a) + } + if !gotToEnd { + t.Errorf("expect to of gotten to end, did not") + } +} + +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", ""}, + } + input := testPageInput{ + NextToken: expect[0].PrevToken, + } + + 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 + }, + } + + 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) + } + + 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) + } +} + // Benchmarks var benchResps = []*dynamodb.ListTablesOutput{ {TableNames: []*string{aws.String("TABLE"), aws.String("NXT")}, LastEvaluatedTableName: aws.String("NXT")}, diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/request_test.go b/vendor/github.com/aws/aws-sdk-go/aws/request/request_test.go index 213dcdb8e..c741b5ee6 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/request_test.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/request_test.go @@ -3,23 +3,29 @@ package request_test import ( "bytes" "encoding/json" + "errors" "fmt" "io" "io/ioutil" "net/http" "net/http/httptest" + "reflect" "runtime" "strconv" "testing" "time" - "github.com/stretchr/testify/assert" - "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/credentials" "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" ) @@ -91,9 +97,15 @@ func TestRequestRecoverRetry5xx(t *testing.T) { out := &testData{} r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) err := r.Send() - assert.Nil(t, err) - assert.Equal(t, 2, int(r.RetryCount)) - assert.Equal(t, "valid", out.Data) + if err != nil { + t.Fatalf("expect no error, but got %v", err) + } + if e, a := 2, int(r.RetryCount); e != a { + t.Errorf("expect %d retry count, got %d", e, a) + } + if e, a := "valid", out.Data; e != a { + t.Errorf("expect %q output got %q", e, a) + } } // test that retries occur for 4xx status codes with a response type that can be retried - see `shouldRetry` @@ -117,9 +129,15 @@ func TestRequestRecoverRetry4xxRetryable(t *testing.T) { out := &testData{} r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) err := r.Send() - assert.Nil(t, err) - assert.Equal(t, 2, int(r.RetryCount)) - assert.Equal(t, "valid", out.Data) + if err != nil { + t.Fatalf("expect no error, but got %v", err) + } + if e, a := 2, int(r.RetryCount); e != a { + t.Errorf("expect %d retry count, got %d", e, a) + } + if e, a := "valid", out.Data; e != a { + t.Errorf("expect %q output got %q", e, a) + } } // test that retries don't occur for 4xx status codes with a response type that can't be retried @@ -135,15 +153,22 @@ func TestRequest4xxUnretryable(t *testing.T) { out := &testData{} r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) err := r.Send() - assert.NotNil(t, err) - if e, ok := err.(awserr.RequestFailure); ok { - assert.Equal(t, 401, e.StatusCode()) - } else { - assert.Fail(t, "Expected error to be a service failure") + if err == nil { + t.Fatalf("expect error, but did not get one") + } + aerr := err.(awserr.RequestFailure) + if e, a := 401, aerr.StatusCode(); e != a { + t.Errorf("expect %d status code, got %d", e, a) + } + if e, a := "SignatureDoesNotMatch", aerr.Code(); e != a { + t.Errorf("expect %q error code, got %q", e, a) + } + if e, a := "Signature does not match.", aerr.Message(); e != a { + t.Errorf("expect %q error message, got %q", e, a) + } + if e, a := 0, int(r.RetryCount); e != a { + t.Errorf("expect %d retry count, got %d", e, a) } - assert.Equal(t, "SignatureDoesNotMatch", err.(awserr.Error).Code()) - assert.Equal(t, "Signature does not match.", err.(awserr.Error).Message()) - assert.Equal(t, 0, int(r.RetryCount)) } func TestRequestExhaustRetries(t *testing.T) { @@ -171,22 +196,31 @@ func TestRequestExhaustRetries(t *testing.T) { }) r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) err := r.Send() - assert.NotNil(t, err) - if e, ok := err.(awserr.RequestFailure); ok { - assert.Equal(t, 500, e.StatusCode()) - } else { - assert.Fail(t, "Expected error to be a service failure") + if err == nil { + t.Fatalf("expect error, but did not get one") + } + aerr := err.(awserr.RequestFailure) + if e, a := 500, aerr.StatusCode(); e != a { + t.Errorf("expect %d status code, got %d", e, a) + } + if e, a := "UnknownError", aerr.Code(); e != a { + t.Errorf("expect %q error code, got %q", e, a) + } + if e, a := "An error occurred.", aerr.Message(); e != a { + t.Errorf("expect %q error message, got %q", e, a) + } + if e, a := 3, int(r.RetryCount); e != a { + t.Errorf("expect %d retry count, got %d", e, a) } - assert.Equal(t, "UnknownError", err.(awserr.Error).Code()) - assert.Equal(t, "An error occurred.", err.(awserr.Error).Message()) - assert.Equal(t, 3, int(r.RetryCount)) expectDelays := []struct{ min, max time.Duration }{{30, 59}, {60, 118}, {120, 236}} for i, v := range delays { min := expectDelays[i].min * time.Millisecond max := expectDelays[i].max * time.Millisecond - assert.True(t, min <= v && v <= max, - "Expect delay to be within range, i:%d, v:%s, min:%s, max:%s", i, v, min, max) + if !(min <= v && v <= max) { + t.Errorf("Expect delay to be within range, i:%d, v:%s, min:%s, max:%s", + i, v, min, max) + } } } @@ -222,14 +256,26 @@ func TestRequestRecoverExpiredCreds(t *testing.T) { out := &testData{} r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) err := r.Send() - assert.Nil(t, err) + if err != nil { + t.Fatalf("expect no error, got %v", err) + } - assert.False(t, credExpiredBeforeRetry, "Expect valid creds before retry check") - assert.True(t, credExpiredAfterRetry, "Expect expired creds after retry check") - assert.False(t, s.Config.Credentials.IsExpired(), "Expect valid creds after cred expired recovery") + if credExpiredBeforeRetry { + t.Errorf("Expect valid creds before retry check") + } + if !credExpiredAfterRetry { + t.Errorf("Expect expired creds after retry check") + } + if s.Config.Credentials.IsExpired() { + t.Errorf("Expect valid creds after cred expired recovery") + } - assert.Equal(t, 1, int(r.RetryCount)) - assert.Equal(t, "valid", out.Data) + if e, a := 1, int(r.RetryCount); e != a { + t.Errorf("expect %d retry count, got %d", e, a) + } + if e, a := "valid", out.Data; e != a { + t.Errorf("expect %q output got %q", e, a) + } } func TestMakeAddtoUserAgentHandler(t *testing.T) { @@ -238,7 +284,9 @@ func TestMakeAddtoUserAgentHandler(t *testing.T) { r.HTTPRequest.Header.Set("User-Agent", "foo/bar") fn(r) - assert.Equal(t, "foo/bar name/version (extra1; extra2)", r.HTTPRequest.Header.Get("User-Agent")) + if e, a := "foo/bar name/version (extra1; extra2)", r.HTTPRequest.Header.Get("User-Agent"); e != a { + t.Errorf("expect %q user agent, got %q", e, a) + } } func TestMakeAddtoUserAgentFreeFormHandler(t *testing.T) { @@ -247,7 +295,9 @@ func TestMakeAddtoUserAgentFreeFormHandler(t *testing.T) { r.HTTPRequest.Header.Set("User-Agent", "foo/bar") fn(r) - assert.Equal(t, "foo/bar name/version (extra1; extra2)", r.HTTPRequest.Header.Get("User-Agent")) + if e, a := "foo/bar name/version (extra1; extra2)", r.HTTPRequest.Header.Get("User-Agent"); e != a { + t.Errorf("expect %q user agent, got %q", e, a) + } } func TestRequestUserAgent(t *testing.T) { @@ -256,11 +306,15 @@ func TestRequestUserAgent(t *testing.T) { req := s.NewRequest(&request.Operation{Name: "Operation"}, nil, &testData{}) req.HTTPRequest.Header.Set("User-Agent", "foo/bar") - assert.NoError(t, req.Build()) + if err := req.Build(); err != nil { + t.Fatalf("expect no error, got %v", err) + } expectUA := fmt.Sprintf("foo/bar %s/%s (%s; %s; %s)", aws.SDKName, aws.SDKVersion, runtime.Version(), runtime.GOOS, runtime.GOARCH) - assert.Equal(t, expectUA, req.HTTPRequest.Header.Get("User-Agent")) + if e, a := expectUA, req.HTTPRequest.Header.Get("User-Agent"); e != a { + t.Errorf("expect %q user agent, got %q", e, a) + } } func TestRequestThrottleRetries(t *testing.T) { @@ -288,22 +342,31 @@ func TestRequestThrottleRetries(t *testing.T) { }) r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) err := r.Send() - assert.NotNil(t, err) - if e, ok := err.(awserr.RequestFailure); ok { - assert.Equal(t, 500, e.StatusCode()) - } else { - assert.Fail(t, "Expected error to be a service failure") + if err == nil { + t.Fatalf("expect error, but did not get one") + } + aerr := err.(awserr.RequestFailure) + if e, a := 500, aerr.StatusCode(); e != a { + t.Errorf("expect %d status code, got %d", e, a) + } + if e, a := "Throttling", aerr.Code(); e != a { + t.Errorf("expect %q error code, got %q", e, a) + } + if e, a := "An error occurred.", aerr.Message(); e != a { + t.Errorf("expect %q error message, got %q", e, a) + } + if e, a := 3, int(r.RetryCount); e != a { + t.Errorf("expect %d retry count, got %d", e, a) } - assert.Equal(t, "Throttling", err.(awserr.Error).Code()) - assert.Equal(t, "An error occurred.", err.(awserr.Error).Message()) - assert.Equal(t, 3, int(r.RetryCount)) expectDelays := []struct{ min, max time.Duration }{{500, 999}, {1000, 1998}, {2000, 3996}} for i, v := range delays { min := expectDelays[i].min * time.Millisecond max := expectDelays[i].max * time.Millisecond - assert.True(t, min <= v && v <= max, - "Expect delay to be within range, i:%d, v:%s, min:%s, max:%s", i, v, min, max) + if !(min <= v && v <= max) { + t.Errorf("Expect delay to be within range, i:%d, v:%s, min:%s, max:%s", + i, v, min, max) + } } } @@ -339,9 +402,15 @@ func TestRequestRecoverTimeoutWithNilBody(t *testing.T) { out := &testData{} r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) err := r.Send() - assert.Nil(t, err) - assert.Equal(t, 1, int(r.RetryCount)) - assert.Equal(t, "valid", out.Data) + if err != nil { + t.Fatalf("expect no error, but got %v", err) + } + if e, a := 1, int(r.RetryCount); e != a { + t.Errorf("expect %d retry count, got %d", e, a) + } + if e, a := "valid", out.Data; e != a { + t.Errorf("expect %q output got %q", e, a) + } } func TestRequestRecoverTimeoutWithNilResponse(t *testing.T) { @@ -376,9 +445,15 @@ func TestRequestRecoverTimeoutWithNilResponse(t *testing.T) { out := &testData{} r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) err := r.Send() - assert.Nil(t, err) - assert.Equal(t, 1, int(r.RetryCount)) - assert.Equal(t, "valid", out.Data) + if err != nil { + t.Fatalf("expect no error, but got %v", err) + } + if e, a := 1, int(r.RetryCount); e != a { + t.Errorf("expect %d retry count, got %d", e, a) + } + if e, a := "valid", out.Data; e != a { + t.Errorf("expect %q output got %q", e, a) + } } func TestRequest_NoBody(t *testing.T) { @@ -438,3 +513,280 @@ func TestRequest_NoBody(t *testing.T) { } } } + +func TestIsSerializationErrorRetryable(t *testing.T) { + testCases := []struct { + err error + expected bool + }{ + { + err: awserr.New(request.ErrCodeSerialization, "foo error", nil), + expected: false, + }, + { + err: awserr.New("ErrFoo", "foo error", nil), + expected: false, + }, + { + err: nil, + expected: false, + }, + { + err: awserr.New(request.ErrCodeSerialization, "foo error", stubConnectionResetError), + expected: true, + }, + } + + for i, c := range testCases { + r := &request.Request{ + Error: c.err, + } + if r.IsErrorRetryable() != c.expected { + t.Errorf("Case %d: Expected %v, but received %v", i+1, c.expected, !c.expected) + } + } +} + +func TestWithLogLevel(t *testing.T) { + r := &request.Request{} + + opt := request.WithLogLevel(aws.LogDebugWithHTTPBody) + r.ApplyOptions(opt) + + if !r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) { + t.Errorf("expect log level to be set, but was not, %v", + r.Config.LogLevel.Value()) + } +} + +func TestWithGetResponseHeader(t *testing.T) { + r := &request.Request{} + + var val, val2 string + r.ApplyOptions( + request.WithGetResponseHeader("x-a-header", &val), + request.WithGetResponseHeader("x-second-header", &val2), + ) + + r.HTTPResponse = &http.Response{ + Header: func() http.Header { + h := http.Header{} + h.Set("x-a-header", "first") + h.Set("x-second-header", "second") + return h + }(), + } + r.Handlers.Complete.Run(r) + + if e, a := "first", val; e != a { + t.Errorf("expect %q header value got %q", e, a) + } + if e, a := "second", val2; e != a { + t.Errorf("expect %q header value got %q", e, a) + } +} + +func TestWithGetResponseHeaders(t *testing.T) { + r := &request.Request{} + + var headers http.Header + opt := request.WithGetResponseHeaders(&headers) + + r.ApplyOptions(opt) + + r.HTTPResponse = &http.Response{ + Header: func() http.Header { + h := http.Header{} + h.Set("x-a-header", "headerValue") + return h + }(), + } + r.Handlers.Complete.Run(r) + + if e, a := "headerValue", headers.Get("x-a-header"); e != a { + t.Errorf("expect %q header value got %q", e, a) + } +} + +type connResetCloser struct { +} + +func (rc *connResetCloser) Read(b []byte) (int, error) { + return 0, stubConnectionResetError +} + +func (rc *connResetCloser) Close() error { + return nil +} + +func TestSerializationErrConnectionReset(t *testing.T) { + count := 0 + handlers := request.Handlers{} + handlers.Send.PushBack(func(r *request.Request) { + count++ + r.HTTPResponse = &http.Response{} + r.HTTPResponse.Body = &connResetCloser{} + }) + + handlers.Sign.PushBackNamed(v4.SignRequestHandler) + handlers.Build.PushBackNamed(jsonrpc.BuildHandler) + handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler) + handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler) + handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler) + handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) + + op := &request.Operation{ + Name: "op", + HTTPMethod: "POST", + HTTPPath: "/", + } + + meta := metadata.ClientInfo{ + ServiceName: "fooService", + SigningName: "foo", + SigningRegion: "foo", + Endpoint: "localhost", + APIVersion: "2001-01-01", + JSONVersion: "1.1", + TargetPrefix: "Foo", + } + cfg := unit.Session.Config.Copy() + cfg.MaxRetries = aws.Int(5) + + req := request.New( + *cfg, + meta, + handlers, + client.DefaultRetryer{NumMaxRetries: 5}, + op, + &struct { + }{}, + &struct { + }{}, + ) + + osErr := stubConnectionResetError + req.ApplyOptions(request.WithResponseReadTimeout(time.Second)) + err := req.Send() + if err == nil { + t.Error("Expected rror 'SerializationError', but received nil") + } + if aerr, ok := err.(awserr.Error); ok && aerr.Code() != "SerializationError" { + t.Errorf("Expected 'SerializationError', but received %q", aerr.Code()) + } else if !ok { + t.Errorf("Expected 'awserr.Error', but received %v", reflect.TypeOf(err)) + } else if aerr.OrigErr().Error() != osErr.Error() { + t.Errorf("Expected %q, but received %q", osErr.Error(), aerr.OrigErr().Error()) + } + + if count != 6 { + t.Errorf("Expected '6', but received %d", count) + } +} + +type testRetryer struct { + shouldRetry bool +} + +func (d *testRetryer) MaxRetries() int { + return 3 +} + +// RetryRules returns the delay duration before retrying this request again +func (d *testRetryer) RetryRules(r *request.Request) time.Duration { + return time.Duration(time.Millisecond) +} + +func (d *testRetryer) ShouldRetry(r *request.Request) bool { + d.shouldRetry = true + if r.Retryable != nil { + return *r.Retryable + } + + if r.HTTPResponse.StatusCode >= 500 { + return true + } + return r.IsErrorRetryable() +} + +func TestEnforceShouldRetryCheck(t *testing.T) { + tp := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + ResponseHeaderTimeout: 1 * time.Millisecond, + } + + client := &http.Client{Transport: tp} + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + time.Sleep(5 * time.Millisecond) + })) + + retryer := &testRetryer{} + s := awstesting.NewClient(&aws.Config{ + Region: aws.String("mock-region"), + MaxRetries: aws.Int(0), + Endpoint: aws.String(server.URL), + DisableSSL: aws.Bool(true), + Retryer: retryer, + HTTPClient: client, + EnforceShouldRetryCheck: aws.Bool(true), + }) + + s.Handlers.Validate.Clear() + s.Handlers.Unmarshal.PushBack(unmarshal) + s.Handlers.UnmarshalError.PushBack(unmarshalError) + + out := &testData{} + r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) + err := r.Send() + if err == nil { + t.Fatalf("expect error, but got nil") + } + if e, a := 3, int(r.RetryCount); e != a { + t.Errorf("expect %d retry count, got %d", e, a) + } + if !retryer.shouldRetry { + t.Errorf("expect 'true' for ShouldRetry, but got %v", retryer.shouldRetry) + } +} + +type errReader struct { + err error +} + +func (reader *errReader) Read(b []byte) (int, error) { + return 0, reader.err +} + +func (reader *errReader) Close() error { + return nil +} + +func TestLoggerNotIgnoringErrors(t *testing.T) { + s := awstesting.NewClient(&aws.Config{ + Region: aws.String("mock-region"), + MaxRetries: aws.Int(0), + DisableSSL: aws.Bool(true), + LogLevel: aws.LogLevel(aws.LogDebugWithHTTPBody), + }) + + s.Handlers.Validate.Clear() + s.Handlers.Send.Clear() + s.Handlers.Send.PushBack(func(r *request.Request) { + r.HTTPResponse = &http.Response{StatusCode: 200, Body: &errReader{errors.New("Foo error")}} + }) + s.AddDebugHandlers() + + out := &testData{} + r := s.NewRequest(&request.Operation{Name: "Operation"}, nil, out) + err := r.Send() + if err == nil { + t.Error("expected error, but got nil") + } + + if aerr, ok := err.(awserr.Error); !ok { + t.Errorf("expected awserr.Error, but got different error, %v", err) + } else if aerr.Code() != request.ErrCodeRead { + t.Errorf("expected %q, but received %q", request.ErrCodeRead, aerr.Code()) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go index ebd60ccc4..7af81de2a 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go @@ -26,8 +26,10 @@ func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config { // retryableCodes is a collection of service response codes which are retry-able // without any further action. var retryableCodes = map[string]struct{}{ - "RequestError": {}, - "RequestTimeout": {}, + "RequestError": {}, + "RequestTimeout": {}, + ErrCodeResponseTimeout: {}, + "RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout } var throttleCodes = map[string]struct{}{ @@ -68,35 +70,85 @@ func isCodeExpiredCreds(code string) bool { return ok } +var validParentCodes = map[string]struct{}{ + ErrCodeSerialization: struct{}{}, + ErrCodeRead: struct{}{}, +} + +func isNestedErrorRetryable(parentErr awserr.Error) bool { + if parentErr == nil { + return false + } + + if _, ok := validParentCodes[parentErr.Code()]; !ok { + return false + } + + err := parentErr.OrigErr() + if err == nil { + return false + } + + if aerr, ok := err.(awserr.Error); ok { + return isCodeRetryable(aerr.Code()) + } + + return isErrConnectionReset(err) +} + // IsErrorRetryable returns whether the error is retryable, based on its Code. -// Returns false if the request has no Error set. -func (r *Request) IsErrorRetryable() bool { - if r.Error != nil { - if err, ok := r.Error.(awserr.Error); ok { - return isCodeRetryable(err.Code()) +// Returns false if error is nil. +func IsErrorRetryable(err error) bool { + if err != nil { + if aerr, ok := err.(awserr.Error); ok { + return isCodeRetryable(aerr.Code()) || isNestedErrorRetryable(aerr) } } return false } // IsErrorThrottle returns whether the error is to be throttled based on its code. -// Returns false if the request has no Error set -func (r *Request) IsErrorThrottle() bool { - if r.Error != nil { - if err, ok := r.Error.(awserr.Error); ok { - return isCodeThrottle(err.Code()) +// Returns false if error is nil. +func IsErrorThrottle(err error) bool { + if err != nil { + if aerr, ok := err.(awserr.Error); ok { + return isCodeThrottle(aerr.Code()) } } return false } -// IsErrorExpired returns whether the error code is a credential expiry error. -// Returns false if the request has no Error set. -func (r *Request) IsErrorExpired() bool { - if r.Error != nil { - if err, ok := r.Error.(awserr.Error); ok { - return isCodeExpiredCreds(err.Code()) +// IsErrorExpiredCreds returns whether the error code is a credential expiry error. +// Returns false if error is nil. +func IsErrorExpiredCreds(err error) bool { + if err != nil { + if aerr, ok := err.(awserr.Error); ok { + return isCodeExpiredCreds(aerr.Code()) } } return false } + +// IsErrorRetryable returns whether the error is retryable, based on its Code. +// Returns false if the request has no Error set. +// +// Alias for the utility function IsErrorRetryable +func (r *Request) IsErrorRetryable() bool { + return IsErrorRetryable(r.Error) +} + +// IsErrorThrottle returns whether the error is to be throttled based on its code. +// Returns false if the request has no Error set +// +// Alias for the utility function IsErrorThrottle +func (r *Request) IsErrorThrottle() bool { + return IsErrorThrottle(r.Error) +} + +// IsErrorExpired returns whether the error code is a credential expiry error. +// Returns false if the request has no Error set. +// +// Alias for the utility function IsErrorExpiredCreds +func (r *Request) IsErrorExpired() bool { + return IsErrorExpiredCreds(r.Error) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go new file mode 100644 index 000000000..09a44eb98 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go @@ -0,0 +1,94 @@ +package request + +import ( + "io" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +var timeoutErr = awserr.New( + ErrCodeResponseTimeout, + "read on body has reached the timeout limit", + nil, +) + +type readResult struct { + n int + err error +} + +// timeoutReadCloser will handle body reads that take too long. +// We will return a ErrReadTimeout error if a timeout occurs. +type timeoutReadCloser struct { + reader io.ReadCloser + duration time.Duration +} + +// Read will spin off a goroutine to call the reader's Read method. We will +// select on the timer's channel or the read's channel. Whoever completes first +// will be returned. +func (r *timeoutReadCloser) Read(b []byte) (int, error) { + timer := time.NewTimer(r.duration) + c := make(chan readResult, 1) + + go func() { + n, err := r.reader.Read(b) + timer.Stop() + c <- readResult{n: n, err: err} + }() + + select { + case data := <-c: + return data.n, data.err + case <-timer.C: + return 0, timeoutErr + } +} + +func (r *timeoutReadCloser) Close() error { + return r.reader.Close() +} + +const ( + // HandlerResponseTimeout is what we use to signify the name of the + // response timeout handler. + HandlerResponseTimeout = "ResponseTimeoutHandler" +) + +// adaptToResponseTimeoutError is a handler that will replace any top level error +// to a ErrCodeResponseTimeout, if its child is that. +func adaptToResponseTimeoutError(req *Request) { + if err, ok := req.Error.(awserr.Error); ok { + aerr, ok := err.OrigErr().(awserr.Error) + if ok && aerr.Code() == ErrCodeResponseTimeout { + req.Error = aerr + } + } +} + +// WithResponseReadTimeout is a request option that will wrap the body in a timeout read closer. +// This will allow for per read timeouts. If a timeout occurred, we will return the +// ErrCodeResponseTimeout. +// +// svc.PutObjectWithContext(ctx, params, request.WithTimeoutReadCloser(30 * time.Second) +func WithResponseReadTimeout(duration time.Duration) Option { + return func(r *Request) { + + var timeoutHandler = NamedHandler{ + HandlerResponseTimeout, + func(req *Request) { + req.HTTPResponse.Body = &timeoutReadCloser{ + reader: req.HTTPResponse.Body, + duration: duration, + } + }} + + // remove the handler so we are not stomping over any new durations. + r.Handlers.Send.RemoveByName(HandlerResponseTimeout) + r.Handlers.Send.PushBackNamed(timeoutHandler) + + r.Handlers.Unmarshal.PushBack(adaptToResponseTimeoutError) + r.Handlers.UnmarshalError.PushBack(adaptToResponseTimeoutError) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_benchmark_test.go b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_benchmark_test.go new file mode 100644 index 000000000..33e1b2d18 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_benchmark_test.go @@ -0,0 +1,76 @@ +package request_test + +import ( + "bytes" + "io/ioutil" + "net/http" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/awstesting/unit" + "github.com/aws/aws-sdk-go/private/protocol/jsonrpc" +) + +func BenchmarkTimeoutReadCloser(b *testing.B) { + resp := ` + { + "Bar": "qux" + } + ` + + handlers := request.Handlers{} + + handlers.Send.PushBack(func(r *request.Request) { + r.HTTPResponse = &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(bytes.NewBuffer([]byte(resp))), + } + }) + handlers.Sign.PushBackNamed(v4.SignRequestHandler) + handlers.Build.PushBackNamed(jsonrpc.BuildHandler) + handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler) + handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler) + handlers.UnmarshalError.PushBackNamed(jsonrpc.UnmarshalErrorHandler) + + op := &request.Operation{ + Name: "op", + HTTPMethod: "POST", + HTTPPath: "/", + } + + meta := metadata.ClientInfo{ + ServiceName: "fooService", + SigningName: "foo", + SigningRegion: "foo", + Endpoint: "localhost", + APIVersion: "2001-01-01", + JSONVersion: "1.1", + TargetPrefix: "Foo", + } + + req := request.New( + *unit.Session.Config, + meta, + handlers, + client.DefaultRetryer{NumMaxRetries: 5}, + op, + &struct { + Foo *string + }{}, + &struct { + Bar *string + }{}, + ) + + req.ApplyOptions(request.WithResponseReadTimeout(15 * time.Second)) + for i := 0; i < b.N; i++ { + err := req.Send() + if err != nil { + b.Errorf("Expected no error, but received %v", err) + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_test.go b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_test.go new file mode 100644 index 000000000..c814158da --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer_test.go @@ -0,0 +1,118 @@ +package request + +import ( + "bytes" + "io" + "io/ioutil" + "net/http" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" +) + +type testReader struct { + duration time.Duration + count int +} + +func (r *testReader) Read(b []byte) (int, error) { + if r.count > 0 { + r.count-- + return len(b), nil + } + time.Sleep(r.duration) + return 0, io.EOF +} + +func (r *testReader) Close() error { + return nil +} + +func TestTimeoutReadCloser(t *testing.T) { + reader := timeoutReadCloser{ + reader: &testReader{ + duration: time.Second, + count: 5, + }, + duration: time.Millisecond, + } + b := make([]byte, 100) + _, err := reader.Read(b) + if err != nil { + t.Log(err) + } +} + +func TestTimeoutReadCloserSameDuration(t *testing.T) { + reader := timeoutReadCloser{ + reader: &testReader{ + duration: time.Millisecond, + count: 5, + }, + duration: time.Millisecond, + } + b := make([]byte, 100) + _, err := reader.Read(b) + if err != nil { + t.Log(err) + } +} + +func TestWithResponseReadTimeout(t *testing.T) { + r := Request{ + HTTPResponse: &http.Response{ + Body: ioutil.NopCloser(bytes.NewReader(nil)), + }, + } + r.ApplyOptions(WithResponseReadTimeout(time.Second)) + err := r.Send() + if err != nil { + t.Error(err) + } + v, ok := r.HTTPResponse.Body.(*timeoutReadCloser) + if !ok { + t.Error("Expected the body to be a timeoutReadCloser") + } + if v.duration != time.Second { + t.Errorf("Expected %v, but receive %v\n", time.Second, v.duration) + } +} + +func TestAdaptToResponseTimeout(t *testing.T) { + testCases := []struct { + childErr error + r Request + expectedRootCode string + }{ + { + childErr: awserr.New(ErrCodeResponseTimeout, "timeout!", nil), + r: Request{ + Error: awserr.New("ErrTest", "FooBar", awserr.New(ErrCodeResponseTimeout, "timeout!", nil)), + }, + expectedRootCode: ErrCodeResponseTimeout, + }, + { + childErr: awserr.New(ErrCodeResponseTimeout+"1", "timeout!", nil), + r: Request{ + Error: awserr.New("ErrTest", "FooBar", awserr.New(ErrCodeResponseTimeout+"1", "timeout!", nil)), + }, + expectedRootCode: "ErrTest", + }, + { + r: Request{ + Error: awserr.New("ErrTest", "FooBar", nil), + }, + expectedRootCode: "ErrTest", + }, + } + + for i, c := range testCases { + adaptToResponseTimeoutError(&c.r) + if aerr, ok := c.r.Error.(awserr.Error); !ok { + t.Errorf("Case %d: Expected 'awserr', but received %v", i+1, c.r.Error) + } else if aerr.Code() != c.expectedRootCode { + t.Errorf("Case %d: Expected %q, but received %s", i+1, c.expectedRootCode, aerr.Code()) + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go b/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go new file mode 100644 index 000000000..854b0854a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go @@ -0,0 +1,287 @@ +package request + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/awsutil" +) + +// WaiterResourceNotReadyErrorCode is the error code returned by a waiter when +// the waiter's max attempts have been exhausted. +const WaiterResourceNotReadyErrorCode = "ResourceNotReady" + +// A WaiterOption is a function that will update the Waiter value's fields to +// configure the waiter. +type WaiterOption func(*Waiter) + +// WithWaiterMaxAttempts returns the maximum number of times the waiter should +// attempt to check the resource for the target state. +func WithWaiterMaxAttempts(max int) WaiterOption { + return func(w *Waiter) { + w.MaxAttempts = max + } +} + +// WaiterDelay will return a delay the waiter should pause between attempts to +// check the resource state. The passed in attempt is the number of times the +// Waiter has checked the resource state. +// +// Attempt is the number of attempts the Waiter has made checking the resource +// state. +type WaiterDelay func(attempt int) time.Duration + +// ConstantWaiterDelay returns a WaiterDelay that will always return a constant +// delay the waiter should use between attempts. It ignores the number of +// attempts made. +func ConstantWaiterDelay(delay time.Duration) WaiterDelay { + return func(attempt int) time.Duration { + return delay + } +} + +// WithWaiterDelay will set the Waiter to use the WaiterDelay passed in. +func WithWaiterDelay(delayer WaiterDelay) WaiterOption { + return func(w *Waiter) { + w.Delay = delayer + } +} + +// WithWaiterLogger returns a waiter option to set the logger a waiter +// should use to log warnings and errors to. +func WithWaiterLogger(logger aws.Logger) WaiterOption { + return func(w *Waiter) { + w.Logger = logger + } +} + +// WithWaiterRequestOptions returns a waiter option setting the request +// options for each request the waiter makes. Appends to waiter's request +// options already set. +func WithWaiterRequestOptions(opts ...Option) WaiterOption { + return func(w *Waiter) { + w.RequestOptions = append(w.RequestOptions, opts...) + } +} + +// A Waiter provides the functionality to performing blocking call which will +// wait for an resource state to be satisfied a service. +// +// This type should not be used directly. The API operations provided in the +// service packages prefixed with "WaitUntil" should be used instead. +type Waiter struct { + Name string + Acceptors []WaiterAcceptor + Logger aws.Logger + + MaxAttempts int + Delay WaiterDelay + + RequestOptions []Option + NewRequest func([]Option) (*Request, error) +} + +// ApplyOptions updates the waiter with the list of waiter options provided. +func (w *Waiter) ApplyOptions(opts ...WaiterOption) { + for _, fn := range opts { + fn(w) + } +} + +// WaiterState are states the waiter uses based on WaiterAcceptor definitions +// to identify if the resource state the waiter is waiting on has occurred. +type WaiterState int + +// String returns the string representation of the waiter state. +func (s WaiterState) String() string { + switch s { + case SuccessWaiterState: + return "success" + case FailureWaiterState: + return "failure" + case RetryWaiterState: + return "retry" + default: + return "unknown waiter state" + } +} + +// States the waiter acceptors will use to identify target resource states. +const ( + SuccessWaiterState WaiterState = iota // waiter successful + FailureWaiterState // waiter failed + RetryWaiterState // waiter needs to be retried +) + +// WaiterMatchMode is the mode that the waiter will use to match the WaiterAcceptor +// definition's Expected attribute. +type WaiterMatchMode int + +// Modes the waiter will use when inspecting API response to identify target +// resource states. +const ( + PathAllWaiterMatch WaiterMatchMode = iota // match on all paths + PathWaiterMatch // match on specific path + PathAnyWaiterMatch // match on any path + PathListWaiterMatch // match on list of paths + StatusWaiterMatch // match on status code + ErrorWaiterMatch // match on error +) + +// String returns the string representation of the waiter match mode. +func (m WaiterMatchMode) String() string { + switch m { + case PathAllWaiterMatch: + return "pathAll" + case PathWaiterMatch: + return "path" + case PathAnyWaiterMatch: + return "pathAny" + case PathListWaiterMatch: + return "pathList" + case StatusWaiterMatch: + return "status" + case ErrorWaiterMatch: + return "error" + default: + return "unknown waiter match mode" + } +} + +// WaitWithContext will make requests for the API operation using NewRequest to +// build API requests. The request's response will be compared against the +// Waiter's Acceptors to determine the successful state of the resource the +// waiter is inspecting. +// +// The passed in context must not be nil. If it is nil a panic will occur. The +// Context will be used to cancel the waiter's pending requests and retry delays. +// Use aws.BackgroundContext if no context is available. +// +// The waiter will continue until the target state defined by the Acceptors, +// or the max attempts expires. +// +// Will return the WaiterResourceNotReadyErrorCode error code if the waiter's +// retryer ShouldRetry returns false. This normally will happen when the max +// wait attempts expires. +func (w Waiter) WaitWithContext(ctx aws.Context) error { + + for attempt := 1; ; attempt++ { + req, err := w.NewRequest(w.RequestOptions) + if err != nil { + waiterLogf(w.Logger, "unable to create request %v", err) + return err + } + req.Handlers.Build.PushBack(MakeAddToUserAgentFreeFormHandler("Waiter")) + err = req.Send() + + // See if any of the acceptors match the request's response, or error + for _, a := range w.Acceptors { + if matched, matchErr := a.match(w.Name, w.Logger, req, err); matched { + return matchErr + } + } + + // The Waiter should only check the resource state MaxAttempts times + // This is here instead of in the for loop above to prevent delaying + // unnecessary when the waiter will not retry. + if attempt == w.MaxAttempts { + break + } + + // Delay to wait before inspecting the resource again + delay := w.Delay(attempt) + if sleepFn := req.Config.SleepDelay; sleepFn != nil { + // Support SleepDelay for backwards compatibility and testing + sleepFn(delay) + } else if err := aws.SleepWithContext(ctx, delay); err != nil { + return awserr.New(CanceledErrorCode, "waiter context canceled", err) + } + } + + return awserr.New(WaiterResourceNotReadyErrorCode, "exceeded wait attempts", nil) +} + +// A WaiterAcceptor provides the information needed to wait for an API operation +// to complete. +type WaiterAcceptor struct { + State WaiterState + Matcher WaiterMatchMode + Argument string + Expected interface{} +} + +// match returns if the acceptor found a match with the passed in request +// or error. True is returned if the acceptor made a match, error is returned +// if there was an error attempting to perform the match. +func (a *WaiterAcceptor) match(name string, l aws.Logger, req *Request, err error) (bool, error) { + result := false + var vals []interface{} + + switch a.Matcher { + case PathAllWaiterMatch, PathWaiterMatch: + // Require all matches to be equal for result to match + vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) + if len(vals) == 0 { + break + } + result = true + for _, val := range vals { + if !awsutil.DeepEqual(val, a.Expected) { + result = false + break + } + } + case PathAnyWaiterMatch: + // Only a single match needs to equal for the result to match + vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument) + for _, val := range vals { + if awsutil.DeepEqual(val, a.Expected) { + result = true + break + } + } + case PathListWaiterMatch: + // ignored matcher + case StatusWaiterMatch: + s := a.Expected.(int) + result = s == req.HTTPResponse.StatusCode + case ErrorWaiterMatch: + if aerr, ok := err.(awserr.Error); ok { + result = aerr.Code() == a.Expected.(string) + } + default: + waiterLogf(l, "WARNING: Waiter %s encountered unexpected matcher: %s", + name, a.Matcher) + } + + if !result { + // If there was no matching result found there is nothing more to do + // for this response, retry the request. + return false, nil + } + + switch a.State { + case SuccessWaiterState: + // waiter completed + return true, nil + case FailureWaiterState: + // Waiter failure state triggered + return true, awserr.New(WaiterResourceNotReadyErrorCode, + "failed waiting for successful resource state", err) + case RetryWaiterState: + // clear the error and retry the operation + return false, nil + default: + waiterLogf(l, "WARNING: Waiter %s encountered unexpected state: %s", + name, a.State) + return false, nil + } +} + +func waiterLogf(logger aws.Logger, msg string, args ...interface{}) { + if logger != nil { + logger.Log(fmt.Sprintf(msg, args...)) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/request/waiter_test.go b/vendor/github.com/aws/aws-sdk-go/aws/request/waiter_test.go new file mode 100644 index 000000000..f49901b97 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/request/waiter_test.go @@ -0,0 +1,636 @@ +package request_test + +import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "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/request" + "github.com/aws/aws-sdk-go/awstesting" + "github.com/aws/aws-sdk-go/awstesting/unit" + "github.com/aws/aws-sdk-go/service/s3" +) + +type mockClient struct { + *client.Client +} +type MockInput struct{} +type MockOutput struct { + States []*MockState +} +type MockState struct { + State *string +} + +func (c *mockClient) MockRequest(input *MockInput) (*request.Request, *MockOutput) { + op := &request.Operation{ + Name: "Mock", + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &MockInput{} + } + + output := &MockOutput{} + req := c.NewRequest(op, input, output) + req.Data = output + return req, output +} + +func BuildNewMockRequest(c *mockClient, in *MockInput) func([]request.Option) (*request.Request, error) { + return func(opts []request.Option) (*request.Request, error) { + req, _ := c.MockRequest(in) + req.ApplyOptions(opts...) + return req, nil + } +} + +func TestWaiterPathAll(t *testing.T) { + svc := &mockClient{Client: awstesting.NewClient(&aws.Config{ + Region: aws.String("mock-region"), + })} + svc.Handlers.Send.Clear() // mock sending + svc.Handlers.Unmarshal.Clear() + svc.Handlers.UnmarshalMeta.Clear() + svc.Handlers.ValidateResponse.Clear() + + reqNum := 0 + resps := []*MockOutput{ + { // Request 1 + States: []*MockState{ + {State: aws.String("pending")}, + {State: aws.String("pending")}, + }, + }, + { // Request 2 + States: []*MockState{ + {State: aws.String("running")}, + {State: aws.String("pending")}, + }, + }, + { // Request 3 + States: []*MockState{ + {State: aws.String("running")}, + {State: aws.String("running")}, + }, + }, + } + + numBuiltReq := 0 + svc.Handlers.Build.PushBack(func(r *request.Request) { + numBuiltReq++ + }) + svc.Handlers.Unmarshal.PushBack(func(r *request.Request) { + if reqNum >= len(resps) { + assert.Fail(t, "too many polling requests made") + return + } + r.Data = resps[reqNum] + reqNum++ + }) + + w := request.Waiter{ + MaxAttempts: 10, + Delay: request.ConstantWaiterDelay(0), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathAllWaiterMatch, + Argument: "States[].State", + Expected: "running", + }, + }, + NewRequest: BuildNewMockRequest(svc, &MockInput{}), + } + + err := w.WaitWithContext(aws.BackgroundContext()) + assert.NoError(t, err) + assert.Equal(t, 3, numBuiltReq) + assert.Equal(t, 3, reqNum) +} + +func TestWaiterPath(t *testing.T) { + svc := &mockClient{Client: awstesting.NewClient(&aws.Config{ + Region: aws.String("mock-region"), + })} + svc.Handlers.Send.Clear() // mock sending + svc.Handlers.Unmarshal.Clear() + svc.Handlers.UnmarshalMeta.Clear() + svc.Handlers.ValidateResponse.Clear() + + reqNum := 0 + resps := []*MockOutput{ + { // Request 1 + States: []*MockState{ + {State: aws.String("pending")}, + {State: aws.String("pending")}, + }, + }, + { // Request 2 + States: []*MockState{ + {State: aws.String("running")}, + {State: aws.String("pending")}, + }, + }, + { // Request 3 + States: []*MockState{ + {State: aws.String("running")}, + {State: aws.String("running")}, + }, + }, + } + + numBuiltReq := 0 + svc.Handlers.Build.PushBack(func(r *request.Request) { + numBuiltReq++ + }) + svc.Handlers.Unmarshal.PushBack(func(r *request.Request) { + if reqNum >= len(resps) { + assert.Fail(t, "too many polling requests made") + return + } + r.Data = resps[reqNum] + reqNum++ + }) + + w := request.Waiter{ + MaxAttempts: 10, + Delay: request.ConstantWaiterDelay(0), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathWaiterMatch, + Argument: "States[].State", + Expected: "running", + }, + }, + NewRequest: BuildNewMockRequest(svc, &MockInput{}), + } + + err := w.WaitWithContext(aws.BackgroundContext()) + assert.NoError(t, err) + assert.Equal(t, 3, numBuiltReq) + assert.Equal(t, 3, reqNum) +} + +func TestWaiterFailure(t *testing.T) { + svc := &mockClient{Client: awstesting.NewClient(&aws.Config{ + Region: aws.String("mock-region"), + })} + svc.Handlers.Send.Clear() // mock sending + svc.Handlers.Unmarshal.Clear() + svc.Handlers.UnmarshalMeta.Clear() + svc.Handlers.ValidateResponse.Clear() + + reqNum := 0 + resps := []*MockOutput{ + { // Request 1 + States: []*MockState{ + {State: aws.String("pending")}, + {State: aws.String("pending")}, + }, + }, + { // Request 2 + States: []*MockState{ + {State: aws.String("running")}, + {State: aws.String("pending")}, + }, + }, + { // Request 3 + States: []*MockState{ + {State: aws.String("running")}, + {State: aws.String("stopping")}, + }, + }, + } + + numBuiltReq := 0 + svc.Handlers.Build.PushBack(func(r *request.Request) { + numBuiltReq++ + }) + svc.Handlers.Unmarshal.PushBack(func(r *request.Request) { + if reqNum >= len(resps) { + assert.Fail(t, "too many polling requests made") + return + } + r.Data = resps[reqNum] + reqNum++ + }) + + w := request.Waiter{ + MaxAttempts: 10, + Delay: request.ConstantWaiterDelay(0), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathAllWaiterMatch, + Argument: "States[].State", + Expected: "running", + }, + { + State: request.FailureWaiterState, + Matcher: request.PathAnyWaiterMatch, + Argument: "States[].State", + Expected: "stopping", + }, + }, + NewRequest: BuildNewMockRequest(svc, &MockInput{}), + } + + err := w.WaitWithContext(aws.BackgroundContext()).(awserr.Error) + assert.Error(t, err) + assert.Equal(t, request.WaiterResourceNotReadyErrorCode, err.Code()) + assert.Equal(t, "failed waiting for successful resource state", err.Message()) + assert.Equal(t, 3, numBuiltReq) + assert.Equal(t, 3, reqNum) +} + +func TestWaiterError(t *testing.T) { + svc := &mockClient{Client: awstesting.NewClient(&aws.Config{ + Region: aws.String("mock-region"), + })} + svc.Handlers.Send.Clear() // mock sending + svc.Handlers.Unmarshal.Clear() + svc.Handlers.UnmarshalMeta.Clear() + svc.Handlers.UnmarshalError.Clear() + svc.Handlers.ValidateResponse.Clear() + + reqNum := 0 + resps := []*MockOutput{ + { // Request 1 + States: []*MockState{ + {State: aws.String("pending")}, + {State: aws.String("pending")}, + }, + }, + { // Request 1, error case retry + }, + { // Request 2, error case failure + }, + { // Request 3 + States: []*MockState{ + {State: aws.String("running")}, + {State: aws.String("running")}, + }, + }, + } + reqErrs := make([]error, len(resps)) + reqErrs[1] = awserr.New("MockException", "mock exception message", nil) + reqErrs[2] = awserr.New("FailureException", "mock failure exception message", nil) + + numBuiltReq := 0 + svc.Handlers.Build.PushBack(func(r *request.Request) { + numBuiltReq++ + }) + svc.Handlers.Send.PushBack(func(r *request.Request) { + code := 200 + if reqNum == 1 { + code = 400 + } + r.HTTPResponse = &http.Response{ + StatusCode: code, + Status: http.StatusText(code), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + }) + svc.Handlers.Unmarshal.PushBack(func(r *request.Request) { + if reqNum >= len(resps) { + assert.Fail(t, "too many polling requests made") + return + } + r.Data = resps[reqNum] + reqNum++ + }) + svc.Handlers.UnmarshalMeta.PushBack(func(r *request.Request) { + // If there was an error unmarshal error will be called instead of unmarshal + // need to increment count here also + if err := reqErrs[reqNum]; err != nil { + r.Error = err + reqNum++ + } + }) + + w := request.Waiter{ + MaxAttempts: 10, + Delay: request.ConstantWaiterDelay(0), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.PathAllWaiterMatch, + Argument: "States[].State", + Expected: "running", + }, + { + State: request.RetryWaiterState, + Matcher: request.ErrorWaiterMatch, + Argument: "", + Expected: "MockException", + }, + { + State: request.FailureWaiterState, + Matcher: request.ErrorWaiterMatch, + Argument: "", + Expected: "FailureException", + }, + }, + NewRequest: BuildNewMockRequest(svc, &MockInput{}), + } + + err := w.WaitWithContext(aws.BackgroundContext()) + if err == nil { + t.Fatalf("expected error, but did not get one") + } + aerr := err.(awserr.Error) + if e, a := request.WaiterResourceNotReadyErrorCode, aerr.Code(); e != a { + t.Errorf("expect %q error code, got %q", e, a) + } + if e, a := 3, numBuiltReq; e != a { + t.Errorf("expect %d built requests got %d", e, a) + } + if e, a := 3, reqNum; e != a { + t.Errorf("expect %d reqNum got %d", e, a) + } +} + +func TestWaiterStatus(t *testing.T) { + svc := &mockClient{Client: awstesting.NewClient(&aws.Config{ + Region: aws.String("mock-region"), + })} + svc.Handlers.Send.Clear() // mock sending + svc.Handlers.Unmarshal.Clear() + svc.Handlers.UnmarshalMeta.Clear() + svc.Handlers.ValidateResponse.Clear() + + reqNum := 0 + svc.Handlers.Build.PushBack(func(r *request.Request) { + reqNum++ + }) + svc.Handlers.Send.PushBack(func(r *request.Request) { + code := 200 + if reqNum == 3 { + code = 404 + r.Error = awserr.New("NotFound", "Not Found", nil) + } + r.HTTPResponse = &http.Response{ + StatusCode: code, + Status: http.StatusText(code), + Body: ioutil.NopCloser(bytes.NewReader([]byte{})), + } + }) + + w := request.Waiter{ + MaxAttempts: 10, + Delay: request.ConstantWaiterDelay(0), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.StatusWaiterMatch, + Argument: "", + Expected: 404, + }, + }, + NewRequest: BuildNewMockRequest(svc, &MockInput{}), + } + + err := w.WaitWithContext(aws.BackgroundContext()) + assert.NoError(t, err) + assert.Equal(t, 3, reqNum) +} + +func TestWaiter_ApplyOptions(t *testing.T) { + w := request.Waiter{} + + logger := aws.NewDefaultLogger() + + w.ApplyOptions( + request.WithWaiterLogger(logger), + request.WithWaiterRequestOptions(request.WithLogLevel(aws.LogDebug)), + request.WithWaiterMaxAttempts(2), + request.WithWaiterDelay(request.ConstantWaiterDelay(5*time.Second)), + ) + + if e, a := logger, w.Logger; e != a { + t.Errorf("expect logger to be set, and match, was not, %v, %v", e, a) + } + + if len(w.RequestOptions) != 1 { + t.Fatalf("expect request options to be set to only a single option, %v", w.RequestOptions) + } + r := request.Request{} + r.ApplyOptions(w.RequestOptions...) + if e, a := aws.LogDebug, r.Config.LogLevel.Value(); e != a { + t.Errorf("expect %v loglevel got %v", e, a) + } + + if e, a := 2, w.MaxAttempts; e != a { + t.Errorf("expect %d retryer max attempts, got %d", e, a) + } + if e, a := 5*time.Second, w.Delay(0); e != a { + t.Errorf("expect %d retryer delay, got %d", e, a) + } +} + +func TestWaiter_WithContextCanceled(t *testing.T) { + c := awstesting.NewClient() + + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} + reqCount := 0 + + w := request.Waiter{ + Name: "TestWaiter", + MaxAttempts: 10, + Delay: request.ConstantWaiterDelay(1 * time.Millisecond), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.StatusWaiterMatch, + Expected: 200, + }, + }, + Logger: aws.NewDefaultLogger(), + NewRequest: func(opts []request.Option) (*request.Request, error) { + req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + req.HTTPResponse = &http.Response{StatusCode: http.StatusNotFound} + req.Handlers.Clear() + req.Data = struct{}{} + req.Handlers.Send.PushBack(func(r *request.Request) { + if reqCount == 1 { + ctx.Error = fmt.Errorf("context canceled") + close(ctx.DoneCh) + } + reqCount++ + }) + + return req, nil + }, + } + + err := w.WaitWithContext(ctx) + + if err == nil { + t.Fatalf("expect waiter to be canceled.") + } + aerr := err.(awserr.Error) + if e, a := request.CanceledErrorCode, aerr.Code(); e != a { + t.Errorf("expect %q error code, got %q", e, a) + } + if e, a := 2, reqCount; e != a { + t.Errorf("expect %d requests, got %d", e, a) + } +} + +func TestWaiter_WithContext(t *testing.T) { + c := awstesting.NewClient() + + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} + reqCount := 0 + + statuses := []int{http.StatusNotFound, http.StatusOK} + + w := request.Waiter{ + Name: "TestWaiter", + MaxAttempts: 10, + Delay: request.ConstantWaiterDelay(1 * time.Millisecond), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.StatusWaiterMatch, + Expected: 200, + }, + }, + Logger: aws.NewDefaultLogger(), + NewRequest: func(opts []request.Option) (*request.Request, error) { + req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + req.HTTPResponse = &http.Response{StatusCode: statuses[reqCount]} + req.Handlers.Clear() + req.Data = struct{}{} + req.Handlers.Send.PushBack(func(r *request.Request) { + if reqCount == 1 { + ctx.Error = fmt.Errorf("context canceled") + close(ctx.DoneCh) + } + reqCount++ + }) + + return req, nil + }, + } + + err := w.WaitWithContext(ctx) + + if err != nil { + t.Fatalf("expect no error, got %v", err) + } + if e, a := 2, reqCount; e != a { + t.Errorf("expect %d requests, got %d", e, a) + } +} + +func TestWaiter_AttemptsExpires(t *testing.T) { + c := awstesting.NewClient() + + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} + reqCount := 0 + + w := request.Waiter{ + Name: "TestWaiter", + MaxAttempts: 2, + Delay: request.ConstantWaiterDelay(1 * time.Millisecond), + Acceptors: []request.WaiterAcceptor{ + { + State: request.SuccessWaiterState, + Matcher: request.StatusWaiterMatch, + Expected: 200, + }, + }, + Logger: aws.NewDefaultLogger(), + NewRequest: func(opts []request.Option) (*request.Request, error) { + req := c.NewRequest(&request.Operation{Name: "Operation"}, nil, nil) + req.HTTPResponse = &http.Response{StatusCode: http.StatusNotFound} + req.Handlers.Clear() + req.Data = struct{}{} + req.Handlers.Send.PushBack(func(r *request.Request) { + reqCount++ + }) + + return req, nil + }, + } + + err := w.WaitWithContext(ctx) + + if err == nil { + t.Fatalf("expect error did not get one") + } + aerr := err.(awserr.Error) + if e, a := request.WaiterResourceNotReadyErrorCode, aerr.Code(); e != a { + t.Errorf("expect %q error code, got %q", e, a) + } + if e, a := 2, reqCount; e != a { + t.Errorf("expect %d requests, got %d", e, a) + } +} + +func TestWaiterNilInput(t *testing.T) { + // Code generation doesn't have a great way to verify the code is correct + // other than being run via unit tests in the SDK. This should be fixed + // So code generation can be validated independently. + + client := s3.New(unit.Session) + client.Handlers.Validate.Clear() + client.Handlers.Send.Clear() // mock sending + client.Handlers.Send.PushBack(func(r *request.Request) { + r.HTTPResponse = &http.Response{ + StatusCode: http.StatusOK, + } + }) + client.Handlers.Unmarshal.Clear() + client.Handlers.UnmarshalMeta.Clear() + client.Handlers.ValidateResponse.Clear() + client.Config.SleepDelay = func(dur time.Duration) {} + + // Ensure waiters do not panic on nil input. It doesn't make sense to + // call a waiter without an input, Validation will + err := client.WaitUntilBucketExists(nil) + if err != nil { + t.Fatalf("expect no error, but got %v", err) + } +} + +func TestWaiterWithContextNilInput(t *testing.T) { + // Code generation doesn't have a great way to verify the code is correct + // other than being run via unit tests in the SDK. This should be fixed + // So code generation can be validated independently. + + client := s3.New(unit.Session) + client.Handlers.Validate.Clear() + client.Handlers.Send.Clear() // mock sending + client.Handlers.Send.PushBack(func(r *request.Request) { + r.HTTPResponse = &http.Response{ + StatusCode: http.StatusOK, + } + }) + client.Handlers.Unmarshal.Clear() + client.Handlers.UnmarshalMeta.Clear() + client.Handlers.ValidateResponse.Clear() + + // Ensure waiters do not panic on nil input + ctx := &awstesting.FakeContext{DoneCh: make(chan struct{})} + err := client.WaitUntilBucketExistsWithContext(ctx, nil, + request.WithWaiterDelay(request.ConstantWaiterDelay(0)), + request.WithWaiterMaxAttempts(1), + ) + if err != nil { + t.Fatalf("expect no error, but got %v", err) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/custom_ca_bundle_test.go b/vendor/github.com/aws/aws-sdk-go/aws/session/custom_ca_bundle_test.go new file mode 100644 index 000000000..8a5a3a04e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/custom_ca_bundle_test.go @@ -0,0 +1,319 @@ +package session + +import ( + "bytes" + "crypto/tls" + "io/ioutil" + "net" + "net/http" + "net/http/httptest" + "os" + "testing" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/stretchr/testify/assert" +) + +func createTLSServer(cert, key []byte, done <-chan struct{}) (*httptest.Server, error) { + c, err := tls.X509KeyPair(cert, key) + if err != nil { + return nil, err + } + + s := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })) + s.TLS = &tls.Config{ + Certificates: []tls.Certificate{c}, + } + s.TLS.BuildNameToCertificate() + s.StartTLS() + + go func() { + <-done + s.Close() + }() + + return s, nil +} + +func setupTestCAFile(b []byte) (string, error) { + bundleFile, err := ioutil.TempFile(os.TempDir(), "aws-sdk-go-session-test") + if err != nil { + return "", err + } + + _, err = bundleFile.Write(b) + if err != nil { + return "", err + } + + defer bundleFile.Close() + return bundleFile.Name(), nil +} + +func TestNewSession_WithCustomCABundle_Env(t *testing.T) { + oldEnv := initSessionTestEnv() + defer popEnv(oldEnv) + + done := make(chan struct{}) + server, err := createTLSServer(testTLSBundleCert, testTLSBundleKey, done) + assert.NoError(t, err) + + // Write bundle to file + caFilename, err := setupTestCAFile(testTLSBundleCA) + defer func() { + os.Remove(caFilename) + }() + assert.NoError(t, err) + + os.Setenv("AWS_CA_BUNDLE", caFilename) + + s, err := NewSession(&aws.Config{ + HTTPClient: &http.Client{}, + Endpoint: aws.String(server.URL), + Region: aws.String("mock-region"), + Credentials: credentials.AnonymousCredentials, + }) + assert.NoError(t, err) + assert.NotNil(t, s) + + req, _ := http.NewRequest("GET", *s.Config.Endpoint, nil) + resp, err := s.Config.HTTPClient.Do(req) + assert.NoError(t, err) + + assert.Equal(t, http.StatusOK, resp.StatusCode) +} + +func TestNewSession_WithCustomCABundle_EnvNotExists(t *testing.T) { + oldEnv := initSessionTestEnv() + defer popEnv(oldEnv) + + os.Setenv("AWS_CA_BUNDLE", "file-not-exists") + + s, err := NewSession() + assert.Error(t, err) + assert.Equal(t, "LoadCustomCABundleError", err.(awserr.Error).Code()) + assert.Nil(t, s) +} + +func TestNewSession_WithCustomCABundle_Option(t *testing.T) { + oldEnv := initSessionTestEnv() + defer popEnv(oldEnv) + + done := make(chan struct{}) + server, err := createTLSServer(testTLSBundleCert, testTLSBundleKey, done) + assert.NoError(t, err) + + s, err := NewSessionWithOptions(Options{ + Config: aws.Config{ + HTTPClient: &http.Client{}, + Endpoint: aws.String(server.URL), + Region: aws.String("mock-region"), + Credentials: credentials.AnonymousCredentials, + }, + CustomCABundle: bytes.NewReader(testTLSBundleCA), + }) + assert.NoError(t, err) + assert.NotNil(t, s) + + req, _ := http.NewRequest("GET", *s.Config.Endpoint, nil) + resp, err := s.Config.HTTPClient.Do(req) + assert.NoError(t, err) + + assert.Equal(t, http.StatusOK, resp.StatusCode) +} + +func TestNewSession_WithCustomCABundle_OptionPriority(t *testing.T) { + oldEnv := initSessionTestEnv() + defer popEnv(oldEnv) + + done := make(chan struct{}) + server, err := createTLSServer(testTLSBundleCert, testTLSBundleKey, done) + assert.NoError(t, err) + + os.Setenv("AWS_CA_BUNDLE", "file-not-exists") + + s, err := NewSessionWithOptions(Options{ + Config: aws.Config{ + HTTPClient: &http.Client{}, + Endpoint: aws.String(server.URL), + Region: aws.String("mock-region"), + Credentials: credentials.AnonymousCredentials, + }, + CustomCABundle: bytes.NewReader(testTLSBundleCA), + }) + assert.NoError(t, err) + assert.NotNil(t, s) + + req, _ := http.NewRequest("GET", *s.Config.Endpoint, nil) + resp, err := s.Config.HTTPClient.Do(req) + assert.NoError(t, err) + + assert.Equal(t, http.StatusOK, resp.StatusCode) +} + +type mockRoundTripper struct{} + +func (m *mockRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { + return nil, nil +} + +func TestNewSession_WithCustomCABundle_UnsupportedTransport(t *testing.T) { + oldEnv := initSessionTestEnv() + defer popEnv(oldEnv) + + s, err := NewSessionWithOptions(Options{ + Config: aws.Config{ + HTTPClient: &http.Client{ + Transport: &mockRoundTripper{}, + }, + }, + CustomCABundle: bytes.NewReader(testTLSBundleCA), + }) + assert.Error(t, err) + assert.Equal(t, "LoadCustomCABundleError", err.(awserr.Error).Code()) + assert.Contains(t, err.(awserr.Error).Message(), "transport unsupported type") + assert.Nil(t, s) +} + +func TestNewSession_WithCustomCABundle_TransportSet(t *testing.T) { + oldEnv := initSessionTestEnv() + defer popEnv(oldEnv) + + done := make(chan struct{}) + server, err := createTLSServer(testTLSBundleCert, testTLSBundleKey, done) + assert.NoError(t, err) + + s, err := NewSessionWithOptions(Options{ + Config: aws.Config{ + Endpoint: aws.String(server.URL), + Region: aws.String("mock-region"), + Credentials: credentials.AnonymousCredentials, + HTTPClient: &http.Client{ + Transport: &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).Dial, + TLSHandshakeTimeout: 2 * time.Second, + }, + }, + }, + CustomCABundle: bytes.NewReader(testTLSBundleCA), + }) + assert.NoError(t, err) + assert.NotNil(t, s) + + req, _ := http.NewRequest("GET", *s.Config.Endpoint, nil) + resp, err := s.Config.HTTPClient.Do(req) + assert.NoError(t, err) + + assert.Equal(t, http.StatusOK, resp.StatusCode) +} + +/* Cert generation steps +# Create the CA key +openssl genrsa -des3 -out ca.key 1024 + +# Create the CA Cert +openssl req -new -sha256 -x509 -days 3650 \ + -subj "/C=GO/ST=Gopher/O=Testing ROOT CA" \ + -key ca.key -out ca.crt + +# Create config +cat > csr_details.txt <<-EOF + +[req] +default_bits = 1024 +prompt = no +default_md = sha256 +req_extensions = SAN +distinguished_name = dn + +[ dn ] +C=GO +ST=Gopher +O=Testing Certificate +OU=Testing IP + +[SAN] +subjectAltName = IP:127.0.0.1 +EOF + +# Create certificate signing request +openssl req -new -sha256 -nodes -newkey rsa:1024 \ + -config <( cat csr_details.txt ) \ + -keyout ia.key -out ia.csr + +# Create a signed certificate +openssl x509 -req -days 3650 \ + -CAcreateserial \ + -extfile <( cat csr_details.txt ) \ + -extensions SAN \ + -CA ca.crt -CAkey ca.key -in ia.csr -out ia.crt + +# Verify +openssl req -noout -text -in ia.csr +openssl x509 -noout -text -in ia.crt +*/ +var ( + // ca.crt + testTLSBundleCA = []byte(`-----BEGIN CERTIFICATE----- +MIICiTCCAfKgAwIBAgIJAJ5X1olt05XjMA0GCSqGSIb3DQEBCwUAMDgxCzAJBgNV +BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD +QTAeFw0xNzAzMDkwMDAyMDZaFw0yNzAzMDcwMDAyMDZaMDgxCzAJBgNVBAYTAkdP +MQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBDQTCBnzAN +BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAw/8DN+t9XQR60jx42rsQ2WE2Dx85rb3n +GQxnKZZLNddsT8rDyxJNP18aFalbRbFlyln5fxWxZIblu9Xkm/HRhOpbSimSqo1y +uDx21NVZ1YsOvXpHby71jx3gPrrhSc/t/zikhi++6D/C6m1CiIGuiJ0GBiJxtrub +UBMXT0QtI2ECAwEAAaOBmjCBlzAdBgNVHQ4EFgQU8XG3X/YHBA6T04kdEkq6+4GV +YykwaAYDVR0jBGEwX4AU8XG3X/YHBA6T04kdEkq6+4GVYymhPKQ6MDgxCzAJBgNV +BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD +QYIJAJ5X1olt05XjMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAeILv +z49+uxmPcfOZzonuOloRcpdvyjiXblYxbzz6ch8GsE7Q886FTZbvwbgLhzdwSVgG +G8WHkodDUsymVepdqAamS3f8PdCUk8xIk9mop8LgaB9Ns0/TssxDvMr3sOD2Grb3 +xyWymTWMcj6uCiEBKtnUp4rPiefcvCRYZ17/hLE= +-----END CERTIFICATE----- +`) + + // ai.crt + testTLSBundleCert = []byte(`-----BEGIN CERTIFICATE----- +MIICGjCCAYOgAwIBAgIJAIIu+NOoxxM0MA0GCSqGSIb3DQEBBQUAMDgxCzAJBgNV +BAYTAkdPMQ8wDQYDVQQIEwZHb3BoZXIxGDAWBgNVBAoTD1Rlc3RpbmcgUk9PVCBD +QTAeFw0xNzAzMDkwMDAzMTRaFw0yNzAzMDcwMDAzMTRaMFExCzAJBgNVBAYTAkdP +MQ8wDQYDVQQIDAZHb3BoZXIxHDAaBgNVBAoME1Rlc3RpbmcgQ2VydGlmaWNhdGUx +EzARBgNVBAsMClRlc3RpbmcgSVAwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB +AN1hWHeioo/nASvbrjwCQzXCiWiEzGkw353NxsAB54/NqDL3LXNATtiSJu8kJBrm +Ah12IFLtWLGXjGjjYlHbQWnOR6awveeXnQZukJyRWh7m/Qlt9Ho0CgZE1U+832ac +5GWVldNxW1Lz4I+W9/ehzqe8I80RS6eLEKfUFXGiW+9RAgMBAAGjEzARMA8GA1Ud +EQQIMAaHBH8AAAEwDQYJKoZIhvcNAQEFBQADgYEAdF4WQHfVdPCbgv9sxgJjcR1H +Hgw9rZ47gO1IiIhzglnLXQ6QuemRiHeYFg4kjcYBk1DJguxzDTGnUwhUXOibAB+S +zssmrkdYYvn9aUhjc3XK3tjAoDpsPpeBeTBamuUKDHoH/dNRXxerZ8vu6uPR3Pgs +5v/KCV6IAEcvNyOXMPo= +-----END CERTIFICATE----- +`) + + // ai.key + testTLSBundleKey = []byte(`-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDdYVh3oqKP5wEr2648AkM1wolohMxpMN+dzcbAAeePzagy9y1z +QE7YkibvJCQa5gIddiBS7Vixl4xo42JR20FpzkemsL3nl50GbpCckVoe5v0JbfR6 +NAoGRNVPvN9mnORllZXTcVtS8+CPlvf3oc6nvCPNEUunixCn1BVxolvvUQIDAQAB +AoGBAMISrcirddGrlLZLLrKC1ULS2T0cdkqdQtwHYn4+7S5+/z42vMx1iumHLsSk +rVY7X41OWkX4trFxhvEIrc/O48bo2zw78P7flTxHy14uxXnllU8cLThE29SlUU7j +AVBNxJZMsXMlS/DowwD4CjFe+x4Pu9wZcReF2Z9ntzMpySABAkEA+iWoJCPE2JpS +y78q3HYYgpNY3gF3JqQ0SI/zTNkb3YyEIUffEYq0Y9pK13HjKtdsSuX4osTIhQkS ++UgRp6tCAQJBAOKPYTfQ2FX8ijgUpHZRuEAVaxASAS0UATiLgzXxLvOh/VC2at5x +wjOX6sD65pPz/0D8Qj52Cq6Q1TQ+377SDVECQAIy0od+yPweXxvrUjUd1JlRMjbB +TIrKZqs8mKbUQapw0bh5KTy+O1elU4MRPS3jNtBxtP25PQnuSnxmZcFTgAECQFzg +DiiFcsn9FuRagfkHExMiNJuH5feGxeFaP9WzI144v9GAllrOI6Bm3JNzx2ZLlg4b +20Qju8lIEj6yr6JYFaECQHM1VSojGRKpOl9Ox/R4yYSA9RV5Gyn00/aJNxVYyPD5 +i3acL2joQm2kLD/LO8paJ4+iQdRXCOMMIpjxSNjGQjQ= +-----END RSA PRIVATE KEY----- +`) +) diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go index d3dc8404e..2fe35e74d 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go @@ -23,7 +23,7 @@ additional config if the AWS_SDK_LOAD_CONFIG environment variable is set. Alternatively you can explicitly create a Session with shared config enabled. To do this you can use NewSessionWithOptions to configure how the Session will be created. Using the NewSessionWithOptions with SharedConfigState set to -SharedConfigEnabled will create the session as if the AWS_SDK_LOAD_CONFIG +SharedConfigEnable will create the session as if the AWS_SDK_LOAD_CONFIG environment variable was set. Creating Sessions @@ -45,16 +45,16 @@ region, and profile loaded from the environment and shared config automatically. Requires the AWS_PROFILE to be set, or "default" is used. // Create Session - sess, err := session.NewSession() + sess := session.Must(session.NewSession()) // Create a Session with a custom region - sess, err := session.NewSession(&aws.Config{Region: aws.String("us-east-1")}) + sess := session.Must(session.NewSession(&aws.Config{ + Region: aws.String("us-east-1"), + })) // Create a S3 client instance from a session - sess, err := session.NewSession() - if err != nil { - // Handle Session creation error - } + sess := session.Must(session.NewSession()) + svc := s3.New(sess) Create Session With Option Overrides @@ -67,23 +67,25 @@ Use NewSessionWithOptions when you want to provide the config profile, or override the shared config state (AWS_SDK_LOAD_CONFIG). // Equivalent to session.NewSession() - sess, err := session.NewSessionWithOptions(session.Options{}) + sess := session.Must(session.NewSessionWithOptions(session.Options{ + // Options + })) // Specify profile to load for the session's config - sess, err := session.NewSessionWithOptions(session.Options{ + sess := session.Must(session.NewSessionWithOptions(session.Options{ Profile: "profile_name", - }) + })) // Specify profile for config and region for requests - sess, err := session.NewSessionWithOptions(session.Options{ + sess := session.Must(session.NewSessionWithOptions(session.Options{ Config: aws.Config{Region: aws.String("us-east-1")}, Profile: "profile_name", - }) + })) // Force enable Shared Config support - sess, err := session.NewSessionWithOptions(session.Options{ - SharedConfigState: SharedConfigEnable, - }) + sess := session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + })) Adding Handlers @@ -93,7 +95,8 @@ handler logs every request and its payload made by a service client: // Create a session, and add additional handlers for all service // clients created with the Session to inherit. Adds logging handler. - sess, err := session.NewSession() + sess := session.Must(session.NewSession()) + sess.Handlers.Send.PushFront(func(r *request.Request) { // Log every request made and its payload logger.Println("Request: %s/%s, Payload: %s", @@ -138,15 +141,14 @@ the other two fields are also provided. Assume Role values allow you to configure the SDK to assume an IAM role using a set of credentials provided in a config file via the source_profile field. -Both "role_arn" and "source_profile" are required. The SDK does not support -assuming a role with MFA token Via the Session's constructor. You can use the -stscreds.AssumeRoleProvider credentials provider to specify custom -configuration and support for MFA. +Both "role_arn" and "source_profile" are required. The SDK supports assuming +a role with MFA token if the session option AssumeRoleTokenProvider +is set. role_arn = arn:aws:iam:::role/ source_profile = profile_with_creds external_id = 1234 - mfa_serial = not supported! + mfa_serial = role_session_name = session_name Region is the region the SDK should use for looking up AWS service endpoints @@ -154,6 +156,37 @@ and signing requests. region = us-east-1 +Assume Role with MFA token + +To create a session with support for assuming an IAM role with MFA set the +session option AssumeRoleTokenProvider to a function that will prompt for the +MFA token code when the SDK assumes the role and refreshes the role's credentials. +This allows you to configure the SDK via the shared config to assumea role +with MFA tokens. + +In order for the SDK to assume a role with MFA the SharedConfigState +session option must be set to SharedConfigEnable, or AWS_SDK_LOAD_CONFIG +environment variable set. + +The shared configuration instructs the SDK to assume an IAM role with MFA +when the mfa_serial configuration field is set in the shared config +(~/.aws/config) or shared credentials (~/.aws/credentials) file. + +If mfa_serial is set in the configuration, the SDK will assume the role, and +the AssumeRoleTokenProvider session option is not set an an error will +be returned when creating the session. + + sess := session.Must(session.NewSessionWithOptions(session.Options{ + AssumeRoleTokenProvider: stscreds.StdinTokenProvider, + })) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess) + +To setup assume role outside of a session see the stscrds.AssumeRoleProvider +documentation. + Environment Variables When a Session is created several environment variables can be set to adjust @@ -218,6 +251,24 @@ $HOME/.aws/config on Linux/Unix based systems, and AWS_CONFIG_FILE=$HOME/my_shared_config +Path to a custom Credentials Authority (CA) bundle PEM file that the SDK +will use instead of the default system's root CA bundle. Use this only +if you want to replace the CA bundle the SDK uses for TLS requests. + + AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle + +Enabling this option will attempt to merge the Transport into the SDK's HTTP +client. If the client's Transport is not a http.Transport an error will be +returned. If the Transport's TLS config is set this option will cause the SDK +to overwrite the Transport's TLS config's RootCAs value. If the CA bundle file +contains multiple certificates all of them will be loaded. + +The Session option CustomCABundle is also available when creating sessions +to also enable this feature. CustomCABundle session option field has priority +over the AWS_CA_BUNDLE environment variable, and will be used if both are set. +Setting a custom HTTPClient in the aws.Config options will override this setting. +To use this option and custom HTTP client, the HTTP client needs to be provided +when creating the session. Not the service client. */ package session diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go index d2f0c8448..e6278a782 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go @@ -75,6 +75,24 @@ type envConfig struct { // // AWS_CONFIG_FILE=$HOME/my_shared_config SharedConfigFile string + + // Sets the path to a custom Credentials Authroity (CA) Bundle PEM file + // that the SDK will use instead of the the system's root CA bundle. + // Only use this if you want to configure the SDK to use a custom set + // of CAs. + // + // Enabling this option will attempt to merge the Transport + // into the SDK's HTTP client. If the client's Transport is + // not a http.Transport an error will be returned. If the + // Transport's TLS config is set this option will cause the + // SDK to overwrite the Transport's TLS config's RootCAs value. + // + // Setting a custom HTTPClient in the aws.Config options will override this setting. + // To use this option and custom HTTP client, the HTTP client needs to be provided + // when creating the session. Not the service client. + // + // AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle + CustomCABundle string } var ( @@ -150,6 +168,8 @@ func envConfigLoad(enableSharedConfig bool) envConfig { cfg.SharedCredentialsFile = sharedCredentialsFilename() cfg.SharedConfigFile = sharedConfigFilename() + cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE") + return cfg } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config_test.go b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config_test.go index 5a6aa7d87..162a71054 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config_test.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config_test.go @@ -94,6 +94,7 @@ func TestLoadEnvConfig(t *testing.T) { cases := []struct { Env map[string]string Region, Profile string + CustomCABundle string UseSharedConfigCall bool }{ { @@ -182,6 +183,19 @@ func TestLoadEnvConfig(t *testing.T) { Region: "default_region", Profile: "default_profile", UseSharedConfigCall: true, }, + { + Env: map[string]string{ + "AWS_CA_BUNDLE": "custom_ca_bundle", + }, + CustomCABundle: "custom_ca_bundle", + }, + { + Env: map[string]string{ + "AWS_CA_BUNDLE": "custom_ca_bundle", + }, + CustomCABundle: "custom_ca_bundle", + UseSharedConfigCall: true, + }, } for _, c := range cases { @@ -200,6 +214,7 @@ func TestLoadEnvConfig(t *testing.T) { assert.Equal(t, c.Region, cfg.Region) assert.Equal(t, c.Profile, cfg.Profile) + assert.Equal(t, c.CustomCABundle, cfg.CustomCABundle) } } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go index 3d52fc20d..96c740d00 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go @@ -1,7 +1,13 @@ package session import ( + "crypto/tls" + "crypto/x509" "fmt" + "io" + "io/ioutil" + "net/http" + "os" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -52,7 +58,7 @@ func New(cfgs ...*aws.Config) *Session { envCfg := loadEnvConfig() if envCfg.EnableSharedConfig { - s, err := newSession(envCfg, cfgs...) + s, err := newSession(Options{}, envCfg, cfgs...) if err != nil { // Old session.New expected all errors to be discovered when // a request is made, and would report the errors then. This @@ -73,7 +79,7 @@ func New(cfgs ...*aws.Config) *Session { return s } - return oldNewSession(cfgs...) + return deprecatedNewSession(cfgs...) } // NewSession returns a new Session created from SDK defaults, config files, @@ -92,9 +98,10 @@ func New(cfgs ...*aws.Config) *Session { // control through code how the Session will be created. Such as specifying the // config profile, and controlling if shared config is enabled or not. func NewSession(cfgs ...*aws.Config) (*Session, error) { - envCfg := loadEnvConfig() + opts := Options{} + opts.Config.MergeIn(cfgs...) - return newSession(envCfg, cfgs...) + return NewSessionWithOptions(opts) } // SharedConfigState provides the ability to optionally override the state @@ -147,6 +154,41 @@ type Options struct { // will allow you to override the AWS_SDK_LOAD_CONFIG environment variable // and enable or disable the shared config functionality. SharedConfigState SharedConfigState + + // When the SDK's shared config is configured to assume a role with MFA + // this option is required in order to provide the mechanism that will + // retrieve the MFA token. There is no default value for this field. If + // it is not set an error will be returned when creating the session. + // + // This token provider will be called when ever the assumed role's + // credentials need to be refreshed. Within the context of service clients + // all sharing the same session the SDK will ensure calls to the token + // provider are atomic. When sharing a token provider across multiple + // sessions additional synchronization logic is needed to ensure the + // token providers do not introduce race conditions. It is recommend to + // share the session where possible. + // + // stscreds.StdinTokenProvider is a basic implementation that will prompt + // from stdin for the MFA token code. + // + // This field is only used if the shared configuration is enabled, and + // the config enables assume role wit MFA via the mfa_serial field. + AssumeRoleTokenProvider func() (string, error) + + // Reader for a custom Credentials Authority (CA) bundle in PEM format that + // the SDK will use instead of the default system's root CA bundle. Use this + // only if you want to replace the CA bundle the SDK uses for TLS requests. + // + // Enabling this option will attempt to merge the Transport into the SDK's HTTP + // client. If the client's Transport is not a http.Transport an error will be + // returned. If the Transport's TLS config is set this option will cause the SDK + // to overwrite the Transport's TLS config's RootCAs value. If the CA + // bundle reader contains multiple certificates all of them will be loaded. + // + // The Session option CustomCABundle is also available when creating sessions + // to also enable this feature. CustomCABundle session option field has priority + // over the AWS_CA_BUNDLE environment variable, and will be used if both are set. + CustomCABundle io.Reader } // NewSessionWithOptions returns a new Session created from SDK defaults, config files, @@ -161,23 +203,23 @@ type Options struct { // to be built with retrieving credentials with AssumeRole set in the config. // // // Equivalent to session.New -// sess, err := session.NewSessionWithOptions(session.Options{}) +// sess := session.Must(session.NewSessionWithOptions(session.Options{})) // // // Specify profile to load for the session's config -// sess, err := session.NewSessionWithOptions(session.Options{ +// sess := session.Must(session.NewSessionWithOptions(session.Options{ // Profile: "profile_name", -// }) +// })) // // // Specify profile for config and region for requests -// sess, err := session.NewSessionWithOptions(session.Options{ +// sess := session.Must(session.NewSessionWithOptions(session.Options{ // Config: aws.Config{Region: aws.String("us-east-1")}, // Profile: "profile_name", -// }) +// })) // // // Force enable Shared Config support -// sess, err := session.NewSessionWithOptions(session.Options{ +// sess := session.Must(session.NewSessionWithOptions(session.Options{ // SharedConfigState: SharedConfigEnable, -// }) +// })) func NewSessionWithOptions(opts Options) (*Session, error) { var envCfg envConfig if opts.SharedConfigState == SharedConfigEnable { @@ -197,7 +239,18 @@ func NewSessionWithOptions(opts Options) (*Session, error) { envCfg.EnableSharedConfig = true } - return newSession(envCfg, &opts.Config) + // Only use AWS_CA_BUNDLE if session option is not provided. + if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil { + f, err := os.Open(envCfg.CustomCABundle) + if err != nil { + return nil, awserr.New("LoadCustomCABundleError", + "failed to open custom CA bundle PEM file", err) + } + defer f.Close() + opts.CustomCABundle = f + } + + return newSession(opts, envCfg, &opts.Config) } // Must is a helper function to ensure the Session is valid and there was no @@ -215,7 +268,7 @@ func Must(sess *Session, err error) *Session { return sess } -func oldNewSession(cfgs ...*aws.Config) *Session { +func deprecatedNewSession(cfgs ...*aws.Config) *Session { cfg := defaults.Config() handlers := defaults.Handlers() @@ -242,7 +295,7 @@ func oldNewSession(cfgs ...*aws.Config) *Session { return s } -func newSession(envCfg envConfig, cfgs ...*aws.Config) (*Session, error) { +func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) { cfg := defaults.Config() handlers := defaults.Handlers() @@ -266,7 +319,9 @@ func newSession(envCfg envConfig, cfgs ...*aws.Config) (*Session, error) { return nil, err } - mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers) + if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil { + return nil, err + } s := &Session{ Config: cfg, @@ -275,10 +330,62 @@ func newSession(envCfg envConfig, cfgs ...*aws.Config) (*Session, error) { initHandlers(s) + // Setup HTTP client with custom cert bundle if enabled + if opts.CustomCABundle != nil { + if err := loadCustomCABundle(s, opts.CustomCABundle); err != nil { + return nil, err + } + } + return s, nil } -func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers) { +func loadCustomCABundle(s *Session, bundle io.Reader) error { + var t *http.Transport + switch v := s.Config.HTTPClient.Transport.(type) { + case *http.Transport: + t = v + default: + if s.Config.HTTPClient.Transport != nil { + return awserr.New("LoadCustomCABundleError", + "unable to load custom CA bundle, HTTPClient's transport unsupported type", nil) + } + } + if t == nil { + t = &http.Transport{} + } + + p, err := loadCertPool(bundle) + if err != nil { + return err + } + if t.TLSClientConfig == nil { + t.TLSClientConfig = &tls.Config{} + } + t.TLSClientConfig.RootCAs = p + + s.Config.HTTPClient.Transport = t + + return nil +} + +func loadCertPool(r io.Reader) (*x509.CertPool, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, awserr.New("LoadCustomCABundleError", + "failed to read custom CA bundle PEM file", err) + } + + p := x509.NewCertPool() + if !p.AppendCertsFromPEM(b) { + return nil, awserr.New("LoadCustomCABundleError", + "failed to load custom CA bundle PEM file", err) + } + + return p, nil +} + +func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers, sessOpts Options) error { // Merge in user provided configuration cfg.MergeIn(userCfg) @@ -302,6 +409,11 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg share cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds( sharedCfg.AssumeRoleSource.Creds, ) + if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil { + // AssumeRole Token provider is required if doing Assume Role + // with MFA. + return AssumeRoleTokenProviderNotSetError{} + } cfg.Credentials = stscreds.NewCredentials( &Session{ Config: &cfgCp, @@ -311,11 +423,16 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg share func(opt *stscreds.AssumeRoleProvider) { opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName + // Assume role with external ID if len(sharedCfg.AssumeRole.ExternalID) > 0 { opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID) } - // MFA not supported + // Assume role with MFA + if len(sharedCfg.AssumeRole.MFASerial) > 0 { + opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial) + opt.TokenProvider = sessOpts.AssumeRoleTokenProvider + } }, ) } else if len(sharedCfg.Creds.AccessKeyID) > 0 { @@ -336,6 +453,33 @@ func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg share }) } } + + return nil +} + +// AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the +// MFAToken option is not set when shared config is configured load assume a +// role with an MFA token. +type AssumeRoleTokenProviderNotSetError struct{} + +// Code is the short id of the error. +func (e AssumeRoleTokenProviderNotSetError) Code() string { + return "AssumeRoleTokenProviderNotSetError" +} + +// Message is the description of the error +func (e AssumeRoleTokenProviderNotSetError) Message() string { + return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.") +} + +// OrigErr is the underlying error that caused the failure. +func (e AssumeRoleTokenProviderNotSetError) OrigErr() error { + return nil +} + +// Error satisfies the error interface. +func (e AssumeRoleTokenProviderNotSetError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", nil) } type credProviderError struct { diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/session_test.go b/vendor/github.com/aws/aws-sdk-go/aws/session/session_test.go index 85d77b16e..877af02e5 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/session_test.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/session_test.go @@ -257,17 +257,7 @@ func TestNewSessionWithOptions_Overrides(t *testing.T) { } } -func TestSesisonAssumeRole(t *testing.T) { - oldEnv := initSessionTestEnv() - defer popEnv(oldEnv) - - os.Setenv("AWS_REGION", "us-east-1") - os.Setenv("AWS_SDK_LOAD_CONFIG", "1") - os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename) - os.Setenv("AWS_PROFILE", "assume_role_w_creds") - - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - const respMsg = ` +const assumeRoleRespMsg = ` @@ -286,7 +276,18 @@ func TestSesisonAssumeRole(t *testing.T) { ` - w.Write([]byte(fmt.Sprintf(respMsg, time.Now().Add(15*time.Minute).Format("2006-01-02T15:04:05Z")))) + +func TestSesisonAssumeRole(t *testing.T) { + oldEnv := initSessionTestEnv() + defer popEnv(oldEnv) + + os.Setenv("AWS_REGION", "us-east-1") + os.Setenv("AWS_SDK_LOAD_CONFIG", "1") + os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename) + os.Setenv("AWS_PROFILE", "assume_role_w_creds") + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(fmt.Sprintf(assumeRoleRespMsg, time.Now().Add(15*time.Minute).Format("2006-01-02T15:04:05Z")))) })) s, err := NewSession(&aws.Config{Endpoint: aws.String(server.URL), DisableSSL: aws.Bool(true)}) @@ -299,6 +300,65 @@ func TestSesisonAssumeRole(t *testing.T) { assert.Contains(t, creds.ProviderName, "AssumeRoleProvider") } +func TestSessionAssumeRole_WithMFA(t *testing.T) { + oldEnv := initSessionTestEnv() + defer popEnv(oldEnv) + + os.Setenv("AWS_REGION", "us-east-1") + os.Setenv("AWS_SDK_LOAD_CONFIG", "1") + os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename) + os.Setenv("AWS_PROFILE", "assume_role_w_creds") + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, r.FormValue("SerialNumber"), "0123456789") + assert.Equal(t, r.FormValue("TokenCode"), "tokencode") + + w.Write([]byte(fmt.Sprintf(assumeRoleRespMsg, time.Now().Add(15*time.Minute).Format("2006-01-02T15:04:05Z")))) + })) + + customProviderCalled := false + sess, err := NewSessionWithOptions(Options{ + Profile: "assume_role_w_mfa", + Config: aws.Config{ + Region: aws.String("us-east-1"), + Endpoint: aws.String(server.URL), + DisableSSL: aws.Bool(true), + }, + SharedConfigState: SharedConfigEnable, + AssumeRoleTokenProvider: func() (string, error) { + customProviderCalled = true + + return "tokencode", nil + }, + }) + assert.NoError(t, err) + + creds, err := sess.Config.Credentials.Get() + assert.NoError(t, err) + assert.True(t, customProviderCalled) + + assert.Equal(t, "AKID", creds.AccessKeyID) + assert.Equal(t, "SECRET", creds.SecretAccessKey) + assert.Equal(t, "SESSION_TOKEN", creds.SessionToken) + assert.Contains(t, creds.ProviderName, "AssumeRoleProvider") +} + +func TestSessionAssumeRole_WithMFA_NoTokenProvider(t *testing.T) { + oldEnv := initSessionTestEnv() + defer popEnv(oldEnv) + + os.Setenv("AWS_REGION", "us-east-1") + os.Setenv("AWS_SDK_LOAD_CONFIG", "1") + os.Setenv("AWS_SHARED_CREDENTIALS_FILE", testConfigFilename) + os.Setenv("AWS_PROFILE", "assume_role_w_creds") + + _, err := NewSessionWithOptions(Options{ + Profile: "assume_role_w_mfa", + SharedConfigState: SharedConfigEnable, + }) + assert.Equal(t, err, AssumeRoleTokenProviderNotSetError{}) +} + func TestSessionAssumeRole_DisableSharedConfig(t *testing.T) { // Backwards compatibility with Shared config disabled // assume role should not be built into the config. diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config_test.go b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config_test.go index 1a164d46d..3a07b8d97 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config_test.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config_test.go @@ -212,6 +212,16 @@ func TestLoadSharedConfigFromFile(t *testing.T) { }, }, }, + { + Profile: "assume_role_w_mfa", + Expected: sharedConfig{ + AssumeRole: assumeRoleConfig{ + RoleARN: "assume_role_role_arn", + SourceProfile: "complete_creds", + MFASerial: "0123456789", + }, + }, + }, { Profile: "does_not_exists", Err: SharedConfigProfileNotExistsError{Profile: "does_not_exists"}, diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/testdata/shared_config b/vendor/github.com/aws/aws-sdk-go/aws/session/testdata/shared_config index e41fe2137..8705608e1 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/session/testdata/shared_config +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/testdata/shared_config @@ -43,6 +43,11 @@ role_arn = partial_assume_role_role_arn role_arn = assume_role_role_arn source_profile = complete_creds +[assume_role_w_mfa] +role_arn = assume_role_role_arn +source_profile = complete_creds +mfa_serial = 0123456789 + [assume_role_invalid_source_profile] role_arn = assume_role_invalid_source_profile_role_arn source_profile = profile_not_exists diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go new file mode 100644 index 000000000..6aa2ed241 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go @@ -0,0 +1,7 @@ +package v4 + +// WithUnsignedPayload will enable and set the UnsignedPayload field to +// true of the signer. +func WithUnsignedPayload(v4 *Signer) { + v4.UnsignedPayload = true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go index 98bfe742b..434ac872d 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go @@ -194,6 +194,10 @@ type Signer struct { // This value should only be used for testing. If it is nil the default // time.Now will be used. currentTimeFn func() time.Time + + // UnsignedPayload will prevent signing of the payload. This will only + // work for services that have support for this. + UnsignedPayload bool } // NewSigner returns a Signer pointer configured with the credentials and optional @@ -227,6 +231,7 @@ type signingCtx struct { isPresign bool formattedTime string formattedShortTime string + unsignedPayload bool bodyDigest string signedHeaders string @@ -317,6 +322,7 @@ func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, regi ServiceName: service, Region: region, DisableURIPathEscaping: v4.DisableURIPathEscaping, + unsignedPayload: v4.UnsignedPayload, } for key := range ctx.Query { @@ -409,7 +415,18 @@ var SignRequestHandler = request.NamedHandler{ func SignSDKRequest(req *request.Request) { signSDKRequestWithCurrTime(req, time.Now) } -func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time) { + +// BuildNamedHandler will build a generic handler for signing. +func BuildNamedHandler(name string, opts ...func(*Signer)) request.NamedHandler { + return request.NamedHandler{ + Name: name, + Fn: func(req *request.Request) { + signSDKRequestWithCurrTime(req, time.Now, opts...) + }, + } +} + +func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time, opts ...func(*Signer)) { // If the request does not need to be signed ignore the signing of the // request if the AnonymousCredentials object is used. if req.Config.Credentials == credentials.AnonymousCredentials { @@ -441,6 +458,10 @@ func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time v4.DisableRequestBodyOverwrite = true }) + for _, opt := range opts { + opt(v4) + } + signingTime := req.Time if !req.LastSignedAt.IsZero() { signingTime = req.LastSignedAt @@ -634,14 +655,14 @@ func (ctx *signingCtx) buildSignature() { func (ctx *signingCtx) buildBodyDigest() { hash := ctx.Request.Header.Get("X-Amz-Content-Sha256") if hash == "" { - if ctx.isPresign && ctx.ServiceName == "s3" { + if ctx.unsignedPayload || (ctx.isPresign && ctx.ServiceName == "s3") { hash = "UNSIGNED-PAYLOAD" } else if ctx.Body == nil { hash = emptyStringSHA256 } else { hash = hex.EncodeToString(makeSha256Reader(ctx.Body)) } - if ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" { + if ctx.unsignedPayload || ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" { ctx.Request.Header.Set("X-Amz-Content-Sha256", hash) } } diff --git a/vendor/github.com/aws/aws-sdk-go/aws/url.go b/vendor/github.com/aws/aws-sdk-go/aws/url.go new file mode 100644 index 000000000..6192b2455 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/url.go @@ -0,0 +1,12 @@ +// +build go1.8 + +package aws + +import "net/url" + +// URLHostname will extract the Hostname without port from the URL value. +// +// Wrapper of net/url#URL.Hostname for backwards Go version compatibility. +func URLHostname(url *url.URL) string { + return url.Hostname() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go b/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go new file mode 100644 index 000000000..0210d2720 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go @@ -0,0 +1,29 @@ +// +build !go1.8 + +package aws + +import ( + "net/url" + "strings" +) + +// URLHostname will extract the Hostname without port from the URL value. +// +// Copy of Go 1.8's net/url#URL.Hostname functionality. +func URLHostname(url *url.URL) string { + return stripPort(url.Host) + +} + +// stripPort is copy of Go 1.8 url#URL.Hostname functionality. +// https://golang.org/src/net/url/url.go +func stripPort(hostport string) string { + colon := strings.IndexByte(hostport, ':') + if colon == -1 { + return hostport + } + if i := strings.IndexByte(hostport, ']'); i != -1 { + return strings.TrimPrefix(hostport[:i], "[") + } + return hostport[:colon] +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index 466b82003..ad47b5980 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.6.21" +const SDKVersion = "1.8.15" diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/assert.go b/vendor/github.com/aws/aws-sdk-go/awstesting/assert.go index 10ad72767..5494dc711 100644 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/assert.go +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/assert.go @@ -8,6 +8,7 @@ import ( "reflect" "regexp" "sort" + "strings" "testing" ) @@ -39,6 +40,8 @@ func AssertURL(t *testing.T, expect, actual string, msgAndArgs ...interface{}) b return AssertQuery(t, expectURL.Query().Encode(), actualURL.Query().Encode(), msgAndArgs...) } +var queryMapKey = regexp.MustCompile("(.*?)\\.[0-9]+\\.key") + // AssertQuery verifies the expect HTTP query string matches the actual. func AssertQuery(t *testing.T, expect, actual string, msgAndArgs ...interface{}) bool { expectQ, err := url.ParseQuery(expect) @@ -46,7 +49,7 @@ func AssertQuery(t *testing.T, expect, actual string, msgAndArgs ...interface{}) t.Errorf(errMsg("unable to parse expected Query", err, msgAndArgs)) return false } - actualQ, err := url.ParseQuery(expect) + actualQ, err := url.ParseQuery(actual) if err != nil { t.Errorf(errMsg("unable to parse actual Query", err, msgAndArgs)) return false @@ -57,11 +60,35 @@ func AssertQuery(t *testing.T, expect, actual string, msgAndArgs ...interface{}) return false } + keys := map[string][]string{} + for key, v := range expectQ { + if queryMapKey.Match([]byte(key)) { + submatch := queryMapKey.FindStringSubmatch(key) + keys[submatch[1]] = append(keys[submatch[1]], v...) + } + } + + for k, v := range keys { + // clear all keys that have prefix + for key := range expectQ { + if strings.HasPrefix(key, k) { + delete(expectQ, key) + } + } + + sort.Strings(v) + for i, value := range v { + expectQ[fmt.Sprintf("%s.%d.key", k, i+1)] = []string{value} + } + } + for k, expectQVals := range expectQ { sort.Strings(expectQVals) actualQVals := actualQ[k] sort.Strings(actualQVals) - equal(t, expectQVals, actualQVals, msgAndArgs...) + if !equal(t, expectQVals, actualQVals, msgAndArgs...) { + return false + } } return true diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/assert_test.go b/vendor/github.com/aws/aws-sdk-go/awstesting/assert_test.go index 45903a5d3..f72abfb20 100644 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/assert_test.go +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/assert_test.go @@ -62,3 +62,28 @@ func TestAssertXML(t *testing.T) { } } } + +func TestAssertQuery(t *testing.T) { + cases := []struct { + e, a string + asserts bool + }{ + { + e: `Action=OperationName&Version=2014-01-01&Foo=val1&Bar=val2`, + a: `Action=OperationName&Version=2014-01-01&Foo=val2&Bar=val3`, + asserts: false, + }, + { + e: `Action=OperationName&Version=2014-01-01&Foo=val1&Bar=val2`, + a: `Action=OperationName&Version=2014-01-01&Foo=val1&Bar=val2`, + asserts: true, + }, + } + + for i, c := range cases { + mockT := &testing.T{} + if awstesting.AssertQuery(mockT, c.e, c.a) != c.asserts { + t.Error("Assert Query result was not expected.", i) + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/cmd/bucket_cleanup/main.go b/vendor/github.com/aws/aws-sdk-go/awstesting/cmd/bucket_cleanup/main.go new file mode 100644 index 000000000..8425c39a6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/cmd/bucket_cleanup/main.go @@ -0,0 +1,94 @@ +// +build integration + +package main + +import ( + "fmt" + "os" + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/s3" +) + +// Searches the buckets of an account that match the prefix, and deletes +// those buckets, and all objects within. Before deleting will prompt user +// to confirm bucket should be deleted. Positive confirmation is required. +// +// Usage: +// go run deleteBuckets.go +func main() { + sess := session.Must(session.NewSession()) + + svc := s3.New(sess) + buckets, err := svc.ListBuckets(&s3.ListBucketsInput{}) + if err != nil { + panic(fmt.Sprintf("failed to list buckets, %v", err)) + } + + if len(os.Args) < 2 { + fmt.Fprintln(os.Stderr, "bucket prefix required") + os.Exit(1) + } + bucketPrefix := os.Args[1] + + var failed bool + for _, b := range buckets.Buckets { + bucket := aws.StringValue(b.Name) + + if !strings.HasPrefix(bucket, bucketPrefix) { + continue + } + + fmt.Printf("Delete bucket %q? [y/N]: ", bucket) + var v string + if _, err := fmt.Scanln(&v); err != nil || !(v == "Y" || v == "y") { + fmt.Println("\tSkipping") + continue + } + + fmt.Println("\tDeleting") + if err := deleteBucket(svc, bucket); err != nil { + fmt.Fprintf(os.Stderr, "failed to delete bucket %q, %v", bucket, err) + failed = true + } + } + + if failed { + os.Exit(1) + } +} + +func deleteBucket(svc *s3.S3, bucket string) error { + bucketName := &bucket + + objs, err := svc.ListObjects(&s3.ListObjectsInput{Bucket: bucketName}) + if err != nil { + return fmt.Errorf("failed to list bucket %q objects, %v", bucketName, err) + } + + for _, o := range objs.Contents { + svc.DeleteObject(&s3.DeleteObjectInput{Bucket: bucketName, Key: o.Key}) + } + + uploads, err := svc.ListMultipartUploads(&s3.ListMultipartUploadsInput{Bucket: bucketName}) + if err != nil { + return fmt.Errorf("failed to list bucket %q multipart objects, %v", bucketName, err) + } + + for _, u := range uploads.Uploads { + svc.AbortMultipartUpload(&s3.AbortMultipartUploadInput{ + Bucket: bucketName, + Key: u.Key, + UploadId: u.UploadId, + }) + } + + _, err = svc.DeleteBucket(&s3.DeleteBucketInput{Bucket: bucketName}) + if err != nil { + return fmt.Errorf("failed to delete bucket %q, %v", bucketName, err) + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/client.go b/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/client.go index 83632d1a3..eb16be6d8 100644 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/client.go +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/client.go @@ -16,7 +16,7 @@ func init() { gucumber.Before("@s3crypto", func() { sess := session.New((&aws.Config{ Region: aws.String("us-west-2"), - }).WithLogLevel(aws.LogDebugWithRequestRetries | aws.LogDebugWithRequestErrors)) + })) encryptionClient := s3crypto.NewEncryptionClient(sess, nil, func(c *s3crypto.EncryptionClient) { }) gucumber.World["encryptionClient"] = encryptionClient diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/s3_crypto.feature b/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/s3_crypto.feature index a7d433a9d..81abc1a53 100644 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/s3_crypto.feature +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/s3_crypto.feature @@ -2,17 +2,32 @@ @s3crypto @client Feature: S3 Integration Crypto Tests - Scenario: Get all plaintext fixtures for symmetric masterkey aes cbc - When I get all fixtures for "aes_gcm" from "aws-s3-shared-tests" - Then I decrypt each fixture against "Java" "version_2" - And I compare the decrypted ciphertext to the plaintext - Scenario: Uploading Go's SDK fixtures When I get all fixtures for "aes_gcm" from "aws-s3-shared-tests" Then I encrypt each fixture with "kms" "AWS_SDK_TEST_ALIAS" "us-west-2" and "aes_gcm" And upload "Go" data with folder "version_2" + Scenario: Uploading Go's SDK fixtures + When I get all fixtures for "aes_cbc" from "aws-s3-shared-tests" + Then I encrypt each fixture with "kms" "AWS_SDK_TEST_ALIAS" "us-west-2" and "aes_cbc" + And upload "Go" data with folder "version_2" + Scenario: Get all plaintext fixtures for symmetric masterkey aes gcm When I get all fixtures for "aes_gcm" from "aws-s3-shared-tests" Then I decrypt each fixture against "Go" "version_2" And I compare the decrypted ciphertext to the plaintext + + Scenario: Get all plaintext fixtures for symmetric masterkey aes cbc + When I get all fixtures for "aes_cbc" from "aws-s3-shared-tests" + Then I decrypt each fixture against "Go" "version_2" + And I compare the decrypted ciphertext to the plaintext + + Scenario: Get all plaintext fixtures for symmetric masterkey aes gcm + When I get all fixtures for "aes_gcm" from "aws-s3-shared-tests" + Then I decrypt each fixture against "Java" "version_2" + And I compare the decrypted ciphertext to the plaintext + + Scenario: Get all plaintext fixtures for symmetric masterkey aes cbc + When I get all fixtures for "aes_cbc" from "aws-s3-shared-tests" + Then I decrypt each fixture against "Java" "version_2" + And I compare the decrypted ciphertext to the plaintext diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/stepdef.go b/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/stepdef.go index b558d8a71..7d58e1939 100644 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/stepdef.go +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3crypto/stepdef.go @@ -75,14 +75,10 @@ func init() { } // We don't support wrap, so skip it - if *ctObj.Metadata["X-Amz-Wrap-Alg"] != "kms" { + if ctObj.Metadata["X-Amz-Wrap-Alg"] == nil || *ctObj.Metadata["X-Amz-Wrap-Alg"] != "kms" { continue } - //masterkeyB64 := ctObj.Metadata["Masterkey"] - //masterkey, err := base64.StdEncoding.DecodeString(*masterkeyB64) - //assert.NoError(T, err) - //s3CryptoClient.Config.MasterKey = masterkey ctObj, err = s3CryptoClient.GetObject(&s3.GetObjectInput{ Bucket: aws.String(bucket), Key: &cipherKey, @@ -94,12 +90,12 @@ func init() { assert.NoError(gucumber.T, err) ciphertexts[caseKey] = ciphertext } - gucumber.World["ciphertexts"] = ciphertexts + gucumber.World["decrypted"] = ciphertexts }) gucumber.And(`^I compare the decrypted ciphertext to the plaintext$`, func() { plaintexts := gucumber.World["plaintexts"].(map[string][]byte) - ciphertexts := gucumber.World["ciphertexts"].(map[string][]byte) + ciphertexts := gucumber.World["decrypted"].(map[string][]byte) for caseKey, ciphertext := range ciphertexts { assert.Equal(gucumber.T, len(plaintexts[caseKey]), len(ciphertext)) assert.True(gucumber.T, bytes.Equal(plaintexts[caseKey], ciphertext)) @@ -129,6 +125,8 @@ func init() { switch cek { case "aes_gcm": builder = s3crypto.AESGCMContentCipherBuilder(handler) + case "aes_cbc": + builder = s3crypto.AESCBCContentCipherBuilder(handler, s3crypto.AESCBCPadder) default: gucumber.T.Skip() } diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3manager/bucket_region_test.go b/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3manager/bucket_region_test.go new file mode 100644 index 000000000..823b2c1dc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3manager/bucket_region_test.go @@ -0,0 +1,27 @@ +// +build integration + +package s3manager + +import ( + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/awstesting/integration" + "github.com/aws/aws-sdk-go/service/s3/s3manager" +) + +func TestGetBucketRegion(t *testing.T) { + expectRegion := aws.StringValue(integration.Session.Config.Region) + + ctx := aws.BackgroundContext() + region, err := s3manager.GetBucketRegion(ctx, integration.Session, + aws.StringValue(bucketName), expectRegion) + + if err != nil { + t.Fatalf("expect no error, got %v", err) + } + + if e, a := expectRegion, region; e != a { + t.Errorf("expect %s bucket region, got %s", e, a) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3manager/integration_test.go b/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3manager/integration_test.go index 3a0dd600e..87536435e 100644 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3manager/integration_test.go +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/integration/customizations/s3/s3manager/integration_test.go @@ -1,6 +1,6 @@ // +build integration -// Package s3manager provides +// Package s3manager provides integration tests for the service/s3/s3manager package package s3manager import ( @@ -9,12 +9,13 @@ import ( "fmt" "io" "os" + "regexp" + "strings" "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/aws/request" "github.com/aws/aws-sdk-go/awstesting/integration" "github.com/aws/aws-sdk-go/service/s3" @@ -26,45 +27,64 @@ var integMD512MB = fmt.Sprintf("%x", md5.Sum(integBuf12MB)) var bucketName *string func TestMain(m *testing.M) { - setup() - defer teardown() // only called if we panic - result := m.Run() - teardown() - os.Exit(result) + if err := setup(); err != nil { + panic(fmt.Sprintf("failed to setup integration test, %v", err)) + } + + var result int + + defer func() { + if err := teardown(); err != nil { + fmt.Fprintf(os.Stderr, "teardown failed, %v", err) + } + if r := recover(); r != nil { + fmt.Println("S3Manager integration test hit a panic,", r) + result = 1 + } + os.Exit(result) + }() + + result = m.Run() } -func setup() { - // Create a bucket for testing +func setup() error { svc := s3.New(integration.Session) + + // Create a bucket for testing bucketName = aws.String( fmt.Sprintf("aws-sdk-go-integration-%d-%s", time.Now().Unix(), integration.UniqueID())) - for i := 0; i < 10; i++ { - _, err := svc.CreateBucket(&s3.CreateBucketInput{Bucket: bucketName}) - if err == nil { - break - } + _, err := svc.CreateBucket(&s3.CreateBucketInput{Bucket: bucketName}) + if err != nil { + return fmt.Errorf("failed to create bucket %q, %v", *bucketName, err) } - for { - _, err := svc.HeadBucket(&s3.HeadBucketInput{Bucket: bucketName}) - if err == nil { - break - } - time.Sleep(1 * time.Second) + err = svc.WaitUntilBucketExists(&s3.HeadBucketInput{Bucket: bucketName}) + if err != nil { + return fmt.Errorf("failed to wait for bucket %q to exist, %v", bucketName, err) } + + return nil } // Delete the bucket -func teardown() { +func teardown() error { svc := s3.New(integration.Session) - objs, _ := svc.ListObjects(&s3.ListObjectsInput{Bucket: bucketName}) + objs, err := svc.ListObjects(&s3.ListObjectsInput{Bucket: bucketName}) + if err != nil { + return fmt.Errorf("failed to list bucket %q objects, %v", bucketName, err) + } + for _, o := range objs.Contents { svc.DeleteObject(&s3.DeleteObjectInput{Bucket: bucketName, Key: o.Key}) } - uploads, _ := svc.ListMultipartUploads(&s3.ListMultipartUploadsInput{Bucket: bucketName}) + uploads, err := svc.ListMultipartUploads(&s3.ListMultipartUploadsInput{Bucket: bucketName}) + if err != nil { + return fmt.Errorf("failed to list bucket %q multipart objects, %v", bucketName, err) + } + for _, u := range uploads.Uploads { svc.AbortMultipartUpload(&s3.AbortMultipartUploadInput{ Bucket: bucketName, @@ -73,7 +93,12 @@ func teardown() { }) } - svc.DeleteBucket(&s3.DeleteBucketInput{Bucket: bucketName}) + _, err = svc.DeleteBucket(&s3.DeleteBucketInput{Bucket: bucketName}) + if err != nil { + return fmt.Errorf("failed to delete bucket %q, %v", bucketName, err) + } + + return nil } type dlwriter struct { @@ -106,8 +131,12 @@ func validate(t *testing.T, key string, md5value string) { w := newDLWriter(1024 * 1024 * 20) n, err := mgr.Download(w, params) - assert.NoError(t, err) - assert.Equal(t, md5value, fmt.Sprintf("%x", md5.Sum(w.buf[0:n]))) + if err != nil { + t.Fatalf("expect no error, got %v", err) + } + if e, a := md5value, fmt.Sprintf("%x", md5.Sum(w.buf[0:n])); e != a { + t.Errorf("expect %s md5 value, got %s", e, a) + } } func TestUploadConcurrently(t *testing.T) { @@ -119,9 +148,17 @@ func TestUploadConcurrently(t *testing.T) { Body: bytes.NewReader(integBuf12MB), }) - assert.NoError(t, err) - assert.NotEqual(t, "", out.UploadID) - assert.Regexp(t, `^https?://.+/`+key+`$`, out.Location) + if err != nil { + t.Fatalf("expect no error, got %v", err) + } + if len(out.UploadID) == 0 { + t.Errorf("expect upload ID but was empty") + } + + re := regexp.MustCompile(`^https?://.+/` + key + `$`) + if e, a := re.String(), out.Location; !re.MatchString(a) { + t.Errorf("expect %s to match URL regexp %q, did not", e, a) + } validate(t, key, integMD512MB) } @@ -149,15 +186,25 @@ func TestUploadFailCleanup(t *testing.T) { Key: &key, Body: bytes.NewReader(integBuf12MB), }) - assert.Error(t, err) - assert.NotContains(t, err.Error(), "MissingRegion") + if err == nil { + t.Fatalf("expect error, but did not get one") + } + + aerr := err.(awserr.Error) + if e, a := "MissingRegion", aerr.Code(); strings.Contains(a, e) { + t.Errorf("expect %q to not be in error code %q", e, a) + } + uploadID := "" - if merr, ok := err.(s3manager.MultiUploadFailure); ok { - uploadID = merr.UploadID() + merr := err.(s3manager.MultiUploadFailure) + if uploadID = merr.UploadID(); len(uploadID) == 0 { + t.Errorf("expect upload ID to not be empty, but was") } - assert.NotEmpty(t, uploadID) _, err = svc.ListParts(&s3.ListPartsInput{ - Bucket: bucketName, Key: &key, UploadId: &uploadID}) - assert.Error(t, err) + Bucket: bucketName, Key: &key, UploadId: &uploadID, + }) + if err == nil { + t.Errorf("expect error for list parts, but got none") + } } diff --git a/vendor/github.com/aws/aws-sdk-go/awstesting/util.go b/vendor/github.com/aws/aws-sdk-go/awstesting/util.go index 77c296e99..fde4dcc4a 100644 --- a/vendor/github.com/aws/aws-sdk-go/awstesting/util.go +++ b/vendor/github.com/aws/aws-sdk-go/awstesting/util.go @@ -2,6 +2,7 @@ package awstesting import ( "io" + "time" "github.com/aws/aws-sdk-go/private/util" ) @@ -65,3 +66,29 @@ func (r *ReadCloser) Close() error { func SortedKeys(m map[string]interface{}) []string { return util.SortedKeys(m) } + +// A FakeContext provides a simple stub implementation of a Context +type FakeContext struct { + Error error + DoneCh chan struct{} +} + +// Deadline always will return not set +func (c *FakeContext) Deadline() (deadline time.Time, ok bool) { + return time.Time{}, false +} + +// Done returns a read channel for listening to the Done event +func (c *FakeContext) Done() <-chan struct{} { + return c.DoneCh +} + +// Err returns the error, is nil if not set. +func (c *FakeContext) Err() error { + return c.Error +} + +// Value ignores the Value and always returns nil +func (c *FakeContext) Value(key interface{}) interface{} { + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/doc-src/aws-godoc/templates/godoc.html b/vendor/github.com/aws/aws-sdk-go/doc-src/aws-godoc/templates/godoc.html index ba90a442e..7d81f71d5 100644 --- a/vendor/github.com/aws/aws-sdk-go/doc-src/aws-godoc/templates/godoc.html +++ b/vendor/github.com/aws/aws-sdk-go/doc-src/aws-godoc/templates/godoc.html @@ -16,6 +16,18 @@ + + +