Compare commits
No commits in common. "modify_aws_cert" and "master" have entirely different histories.
modify_aws
...
master
@ -1,6 +1,3 @@
|
|||||||
access_key:
|
|
||||||
access_secret:
|
|
||||||
region: us-east-1
|
|
||||||
domains:
|
domains:
|
||||||
- name: domain.name
|
- name: domain.name
|
||||||
subdomain:
|
subdomain:
|
||||||
|
11
go.mod
11
go.mod
@ -1,11 +0,0 @@
|
|||||||
module git.trj.tw/golang/go-aws-dns
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/aws/aws-sdk-go v1.15.77
|
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
|
||||||
github.com/stretchr/testify v1.2.2 // indirect
|
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a // indirect
|
|
||||||
golang.org/x/text v0.3.0 // indirect
|
|
||||||
gopkg.in/yaml.v2 v2.2.1
|
|
||||||
)
|
|
18
go.sum
18
go.sum
@ -1,18 +0,0 @@
|
|||||||
github.com/aws/aws-sdk-go v1.15.77 h1:qlut2MDI5mRKllPC6grO5n9M8UhPQg1TIA9cYAkC/gc=
|
|
||||||
github.com/aws/aws-sdk-go v1.15.77/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
|
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8 h1:12VvqtR6Aowv3l/EQUlocDHW2Cp4G9WJVH7uyH8QFJE=
|
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
|
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
6
main.go
6
main.go
@ -38,9 +38,9 @@ type Domains struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
newR53()
|
||||||
config = setting.LoadConfig(confpath)
|
config = setting.LoadConfig(confpath)
|
||||||
fmt.Println(config)
|
fmt.Println(config)
|
||||||
newR53()
|
|
||||||
|
|
||||||
ip = getMyIP()
|
ip = getMyIP()
|
||||||
if ok, err := checkIP(ip); err != nil || !ok {
|
if ok, err := checkIP(ip); err != nil || !ok {
|
||||||
@ -87,8 +87,8 @@ func main() {
|
|||||||
|
|
||||||
func newR53() {
|
func newR53() {
|
||||||
sess, err := session.NewSession(&aws.Config{
|
sess, err := session.NewSession(&aws.Config{
|
||||||
Region: aws.String(config.Region),
|
Region: aws.String("us-east-2"),
|
||||||
Credentials: credentials.NewStaticCredentials(config.AccessKey, config.AccessSecret, ""),
|
Credentials: credentials.NewSharedCredentials("", "mtfos"),
|
||||||
})
|
})
|
||||||
|
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
|
@ -11,10 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
AccessKey string `yaml:"access_key"`
|
Domains []struct {
|
||||||
AccessSecret string `yaml:"access_secret"`
|
|
||||||
Region string `yaml:"region"`
|
|
||||||
Domains []struct {
|
|
||||||
Name string `yaml:"name"`
|
Name string `yaml:"name"`
|
||||||
Sub []string `yaml:"subdomain,flow"`
|
Sub []string `yaml:"subdomain,flow"`
|
||||||
} `yaml:"domains"`
|
} `yaml:"domains"`
|
||||||
|
202
vendor/github.com/aws/aws-sdk-go/LICENSE.txt
generated
vendored
202
vendor/github.com/aws/aws-sdk-go/LICENSE.txt
generated
vendored
@ -1,202 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
3
vendor/github.com/aws/aws-sdk-go/NOTICE.txt
generated
vendored
3
vendor/github.com/aws/aws-sdk-go/NOTICE.txt
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
AWS SDK for Go
|
|
||||||
Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
||||||
Copyright 2014-2015 Stripe, Inc.
|
|
145
vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go
generated
vendored
145
vendor/github.com/aws/aws-sdk-go/aws/awserr/error.go
generated
vendored
@ -1,145 +0,0 @@
|
|||||||
// Package awserr represents API error interface accessors for the SDK.
|
|
||||||
package awserr
|
|
||||||
|
|
||||||
// An Error wraps lower level errors with code, message and an original error.
|
|
||||||
// The underlying concrete error type may also satisfy other interfaces which
|
|
||||||
// can be to used to obtain more specific information about the error.
|
|
||||||
//
|
|
||||||
// Calling Error() or String() will always include the full information about
|
|
||||||
// an error based on its underlying type.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// output, err := s3manage.Upload(svc, input, opts)
|
|
||||||
// if err != nil {
|
|
||||||
// if awsErr, ok := err.(awserr.Error); ok {
|
|
||||||
// // Get error details
|
|
||||||
// log.Println("Error:", awsErr.Code(), awsErr.Message())
|
|
||||||
//
|
|
||||||
// // Prints out full error message, including original error if there was one.
|
|
||||||
// log.Println("Error:", awsErr.Error())
|
|
||||||
//
|
|
||||||
// // Get original error
|
|
||||||
// if origErr := awsErr.OrigErr(); origErr != nil {
|
|
||||||
// // operate on original error.
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// fmt.Println(err.Error())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
type Error interface {
|
|
||||||
// Satisfy the generic error interface.
|
|
||||||
error
|
|
||||||
|
|
||||||
// Returns the short phrase depicting the classification of the error.
|
|
||||||
Code() string
|
|
||||||
|
|
||||||
// Returns the error details message.
|
|
||||||
Message() string
|
|
||||||
|
|
||||||
// Returns the original error if one was set. Nil is returned if not set.
|
|
||||||
OrigErr() error
|
|
||||||
}
|
|
||||||
|
|
||||||
// BatchError is a batch of errors which also wraps lower level errors with
|
|
||||||
// code, message, and original errors. Calling Error() will include all errors
|
|
||||||
// that occurred in the batch.
|
|
||||||
//
|
|
||||||
// Deprecated: Replaced with BatchedErrors. Only defined for backwards
|
|
||||||
// compatibility.
|
|
||||||
type BatchError interface {
|
|
||||||
// Satisfy the generic error interface.
|
|
||||||
error
|
|
||||||
|
|
||||||
// Returns the short phrase depicting the classification of the error.
|
|
||||||
Code() string
|
|
||||||
|
|
||||||
// Returns the error details message.
|
|
||||||
Message() string
|
|
||||||
|
|
||||||
// Returns the original error if one was set. Nil is returned if not set.
|
|
||||||
OrigErrs() []error
|
|
||||||
}
|
|
||||||
|
|
||||||
// BatchedErrors is a batch of errors which also wraps lower level errors with
|
|
||||||
// code, message, and original errors. Calling Error() will include all errors
|
|
||||||
// that occurred in the batch.
|
|
||||||
//
|
|
||||||
// Replaces BatchError
|
|
||||||
type BatchedErrors interface {
|
|
||||||
// Satisfy the base Error interface.
|
|
||||||
Error
|
|
||||||
|
|
||||||
// Returns the original error if one was set. Nil is returned if not set.
|
|
||||||
OrigErrs() []error
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns an Error object described by the code, message, and origErr.
|
|
||||||
//
|
|
||||||
// If origErr satisfies the Error interface it will not be wrapped within a new
|
|
||||||
// Error object and will instead be returned.
|
|
||||||
func New(code, message string, origErr error) Error {
|
|
||||||
var errs []error
|
|
||||||
if origErr != nil {
|
|
||||||
errs = append(errs, origErr)
|
|
||||||
}
|
|
||||||
return newBaseError(code, message, errs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBatchError returns an BatchedErrors with a collection of errors as an
|
|
||||||
// array of errors.
|
|
||||||
func NewBatchError(code, message string, errs []error) BatchedErrors {
|
|
||||||
return newBaseError(code, message, errs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A RequestFailure is an interface to extract request failure information from
|
|
||||||
// an Error such as the request ID of the failed request returned by a service.
|
|
||||||
// RequestFailures may not always have a requestID value if the request failed
|
|
||||||
// prior to reaching the service such as a connection error.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// output, err := s3manage.Upload(svc, input, opts)
|
|
||||||
// if err != nil {
|
|
||||||
// if reqerr, ok := err.(RequestFailure); ok {
|
|
||||||
// log.Println("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID())
|
|
||||||
// } else {
|
|
||||||
// log.Println("Error:", err.Error())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Combined with awserr.Error:
|
|
||||||
//
|
|
||||||
// output, err := s3manage.Upload(svc, input, opts)
|
|
||||||
// if err != nil {
|
|
||||||
// if awsErr, ok := err.(awserr.Error); ok {
|
|
||||||
// // Generic AWS Error with Code, Message, and original error (if any)
|
|
||||||
// fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr())
|
|
||||||
//
|
|
||||||
// if reqErr, ok := err.(awserr.RequestFailure); ok {
|
|
||||||
// // A service error occurred
|
|
||||||
// fmt.Println(reqErr.StatusCode(), reqErr.RequestID())
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// fmt.Println(err.Error())
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
type RequestFailure interface {
|
|
||||||
Error
|
|
||||||
|
|
||||||
// The status code of the HTTP response.
|
|
||||||
StatusCode() int
|
|
||||||
|
|
||||||
// The request ID returned by the service for a request failure. This will
|
|
||||||
// be empty if no request ID is available such as the request failed due
|
|
||||||
// to a connection error.
|
|
||||||
RequestID() string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRequestFailure returns a new request error wrapper for the given Error
|
|
||||||
// provided.
|
|
||||||
func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure {
|
|
||||||
return newRequestError(err, statusCode, reqID)
|
|
||||||
}
|
|
194
vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go
generated
vendored
194
vendor/github.com/aws/aws-sdk-go/aws/awserr/types.go
generated
vendored
@ -1,194 +0,0 @@
|
|||||||
package awserr
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// SprintError returns a string of the formatted error code.
|
|
||||||
//
|
|
||||||
// Both extra and origErr are optional. If they are included their lines
|
|
||||||
// will be added, but if they are not included their lines will be ignored.
|
|
||||||
func SprintError(code, message, extra string, origErr error) string {
|
|
||||||
msg := fmt.Sprintf("%s: %s", code, message)
|
|
||||||
if extra != "" {
|
|
||||||
msg = fmt.Sprintf("%s\n\t%s", msg, extra)
|
|
||||||
}
|
|
||||||
if origErr != nil {
|
|
||||||
msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error())
|
|
||||||
}
|
|
||||||
return msg
|
|
||||||
}
|
|
||||||
|
|
||||||
// A baseError wraps the code and message which defines an error. It also
|
|
||||||
// can be used to wrap an original error object.
|
|
||||||
//
|
|
||||||
// Should be used as the root for errors satisfying the awserr.Error. Also
|
|
||||||
// for any error which does not fit into a specific error wrapper type.
|
|
||||||
type baseError struct {
|
|
||||||
// Classification of error
|
|
||||||
code string
|
|
||||||
|
|
||||||
// Detailed information about error
|
|
||||||
message string
|
|
||||||
|
|
||||||
// Optional original error this error is based off of. Allows building
|
|
||||||
// chained errors.
|
|
||||||
errs []error
|
|
||||||
}
|
|
||||||
|
|
||||||
// newBaseError returns an error object for the code, message, and errors.
|
|
||||||
//
|
|
||||||
// code is a short no whitespace phrase depicting the classification of
|
|
||||||
// the error that is being created.
|
|
||||||
//
|
|
||||||
// message is the free flow string containing detailed information about the
|
|
||||||
// error.
|
|
||||||
//
|
|
||||||
// origErrs is the error objects which will be nested under the new errors to
|
|
||||||
// be returned.
|
|
||||||
func newBaseError(code, message string, origErrs []error) *baseError {
|
|
||||||
b := &baseError{
|
|
||||||
code: code,
|
|
||||||
message: message,
|
|
||||||
errs: origErrs,
|
|
||||||
}
|
|
||||||
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns the string representation of the error.
|
|
||||||
//
|
|
||||||
// See ErrorWithExtra for formatting.
|
|
||||||
//
|
|
||||||
// Satisfies the error interface.
|
|
||||||
func (b baseError) Error() string {
|
|
||||||
size := len(b.errs)
|
|
||||||
if size > 0 {
|
|
||||||
return SprintError(b.code, b.message, "", errorList(b.errs))
|
|
||||||
}
|
|
||||||
|
|
||||||
return SprintError(b.code, b.message, "", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
// Alias for Error to satisfy the stringer interface.
|
|
||||||
func (b baseError) String() string {
|
|
||||||
return b.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code returns the short phrase depicting the classification of the error.
|
|
||||||
func (b baseError) Code() string {
|
|
||||||
return b.code
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message returns the error details message.
|
|
||||||
func (b baseError) Message() string {
|
|
||||||
return b.message
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErr returns the original error if one was set. Nil is returned if no
|
|
||||||
// error was set. This only returns the first element in the list. If the full
|
|
||||||
// list is needed, use BatchedErrors.
|
|
||||||
func (b baseError) OrigErr() error {
|
|
||||||
switch len(b.errs) {
|
|
||||||
case 0:
|
|
||||||
return nil
|
|
||||||
case 1:
|
|
||||||
return b.errs[0]
|
|
||||||
default:
|
|
||||||
if err, ok := b.errs[0].(Error); ok {
|
|
||||||
return NewBatchError(err.Code(), err.Message(), b.errs[1:])
|
|
||||||
}
|
|
||||||
return NewBatchError("BatchedErrors",
|
|
||||||
"multiple errors occurred", b.errs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErrs returns the original errors if one was set. An empty slice is
|
|
||||||
// returned if no error was set.
|
|
||||||
func (b baseError) OrigErrs() []error {
|
|
||||||
return b.errs
|
|
||||||
}
|
|
||||||
|
|
||||||
// So that the Error interface type can be included as an anonymous field
|
|
||||||
// in the requestError struct and not conflict with the error.Error() method.
|
|
||||||
type awsError Error
|
|
||||||
|
|
||||||
// A requestError wraps a request or service error.
|
|
||||||
//
|
|
||||||
// Composed of baseError for code, message, and original error.
|
|
||||||
type requestError struct {
|
|
||||||
awsError
|
|
||||||
statusCode int
|
|
||||||
requestID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// newRequestError returns a wrapped error with additional information for
|
|
||||||
// request status code, and service requestID.
|
|
||||||
//
|
|
||||||
// Should be used to wrap all request which involve service requests. Even if
|
|
||||||
// the request failed without a service response, but had an HTTP status code
|
|
||||||
// that may be meaningful.
|
|
||||||
//
|
|
||||||
// Also wraps original errors via the baseError.
|
|
||||||
func newRequestError(err Error, statusCode int, requestID string) *requestError {
|
|
||||||
return &requestError{
|
|
||||||
awsError: err,
|
|
||||||
statusCode: statusCode,
|
|
||||||
requestID: requestID,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns the string representation of the error.
|
|
||||||
// Satisfies the error interface.
|
|
||||||
func (r requestError) Error() string {
|
|
||||||
extra := fmt.Sprintf("status code: %d, request id: %s",
|
|
||||||
r.statusCode, r.requestID)
|
|
||||||
return SprintError(r.Code(), r.Message(), extra, r.OrigErr())
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
// Alias for Error to satisfy the stringer interface.
|
|
||||||
func (r requestError) String() string {
|
|
||||||
return r.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// StatusCode returns the wrapped status code for the error
|
|
||||||
func (r requestError) StatusCode() int {
|
|
||||||
return r.statusCode
|
|
||||||
}
|
|
||||||
|
|
||||||
// RequestID returns the wrapped requestID
|
|
||||||
func (r requestError) RequestID() string {
|
|
||||||
return r.requestID
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErrs returns the original errors if one was set. An empty slice is
|
|
||||||
// returned if no error was set.
|
|
||||||
func (r requestError) OrigErrs() []error {
|
|
||||||
if b, ok := r.awsError.(BatchedErrors); ok {
|
|
||||||
return b.OrigErrs()
|
|
||||||
}
|
|
||||||
return []error{r.OrigErr()}
|
|
||||||
}
|
|
||||||
|
|
||||||
// An error list that satisfies the golang interface
|
|
||||||
type errorList []error
|
|
||||||
|
|
||||||
// Error returns the string representation of the error.
|
|
||||||
//
|
|
||||||
// Satisfies the error interface.
|
|
||||||
func (e errorList) Error() string {
|
|
||||||
msg := ""
|
|
||||||
// How do we want to handle the array size being zero
|
|
||||||
if size := len(e); size > 0 {
|
|
||||||
for i := 0; i < size; i++ {
|
|
||||||
msg += fmt.Sprintf("%s", e[i].Error())
|
|
||||||
// We check the next index to see if it is within the slice.
|
|
||||||
// If it is, then we append a newline. We do this, because unit tests
|
|
||||||
// could be broken with the additional '\n'
|
|
||||||
if i+1 < size {
|
|
||||||
msg += "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return msg
|
|
||||||
}
|
|
108
vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
generated
vendored
108
vendor/github.com/aws/aws-sdk-go/aws/awsutil/copy.go
generated
vendored
@ -1,108 +0,0 @@
|
|||||||
package awsutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Copy deeply copies a src structure to dst. Useful for copying request and
|
|
||||||
// response structures.
|
|
||||||
//
|
|
||||||
// Can copy between structs of different type, but will only copy fields which
|
|
||||||
// are assignable, and exist in both structs. Fields which are not assignable,
|
|
||||||
// or do not exist in both structs are ignored.
|
|
||||||
func Copy(dst, src interface{}) {
|
|
||||||
dstval := reflect.ValueOf(dst)
|
|
||||||
if !dstval.IsValid() {
|
|
||||||
panic("Copy dst cannot be nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
rcopy(dstval, reflect.ValueOf(src), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CopyOf returns a copy of src while also allocating the memory for dst.
|
|
||||||
// src must be a pointer type or this operation will fail.
|
|
||||||
func CopyOf(src interface{}) (dst interface{}) {
|
|
||||||
dsti := reflect.New(reflect.TypeOf(src).Elem())
|
|
||||||
dst = dsti.Interface()
|
|
||||||
rcopy(dsti, reflect.ValueOf(src), true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// rcopy performs a recursive copy of values from the source to destination.
|
|
||||||
//
|
|
||||||
// root is used to skip certain aspects of the copy which are not valid
|
|
||||||
// for the root node of a object.
|
|
||||||
func rcopy(dst, src reflect.Value, root bool) {
|
|
||||||
if !src.IsValid() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch src.Kind() {
|
|
||||||
case reflect.Ptr:
|
|
||||||
if _, ok := src.Interface().(io.Reader); ok {
|
|
||||||
if dst.Kind() == reflect.Ptr && dst.Elem().CanSet() {
|
|
||||||
dst.Elem().Set(src)
|
|
||||||
} else if dst.CanSet() {
|
|
||||||
dst.Set(src)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
e := src.Type().Elem()
|
|
||||||
if dst.CanSet() && !src.IsNil() {
|
|
||||||
if _, ok := src.Interface().(*time.Time); !ok {
|
|
||||||
dst.Set(reflect.New(e))
|
|
||||||
} else {
|
|
||||||
tempValue := reflect.New(e)
|
|
||||||
tempValue.Elem().Set(src.Elem())
|
|
||||||
// Sets time.Time's unexported values
|
|
||||||
dst.Set(tempValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if src.Elem().IsValid() {
|
|
||||||
// Keep the current root state since the depth hasn't changed
|
|
||||||
rcopy(dst.Elem(), src.Elem(), root)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Struct:
|
|
||||||
t := dst.Type()
|
|
||||||
for i := 0; i < t.NumField(); i++ {
|
|
||||||
name := t.Field(i).Name
|
|
||||||
srcVal := src.FieldByName(name)
|
|
||||||
dstVal := dst.FieldByName(name)
|
|
||||||
if srcVal.IsValid() && dstVal.CanSet() {
|
|
||||||
rcopy(dstVal, srcVal, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case reflect.Slice:
|
|
||||||
if src.IsNil() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
s := reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
|
|
||||||
dst.Set(s)
|
|
||||||
for i := 0; i < src.Len(); i++ {
|
|
||||||
rcopy(dst.Index(i), src.Index(i), false)
|
|
||||||
}
|
|
||||||
case reflect.Map:
|
|
||||||
if src.IsNil() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
s := reflect.MakeMap(src.Type())
|
|
||||||
dst.Set(s)
|
|
||||||
for _, k := range src.MapKeys() {
|
|
||||||
v := src.MapIndex(k)
|
|
||||||
v2 := reflect.New(v.Type()).Elem()
|
|
||||||
rcopy(v2, v, false)
|
|
||||||
dst.SetMapIndex(k, v2)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// Assign the value if possible. If its not assignable, the value would
|
|
||||||
// need to be converted and the impact of that may be unexpected, or is
|
|
||||||
// not compatible with the dst type.
|
|
||||||
if src.Type().AssignableTo(dst.Type()) {
|
|
||||||
dst.Set(src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
27
vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
generated
vendored
27
vendor/github.com/aws/aws-sdk-go/aws/awsutil/equal.go
generated
vendored
@ -1,27 +0,0 @@
|
|||||||
package awsutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DeepEqual returns if the two values are deeply equal like reflect.DeepEqual.
|
|
||||||
// In addition to this, this method will also dereference the input values if
|
|
||||||
// possible so the DeepEqual performed will not fail if one parameter is a
|
|
||||||
// pointer and the other is not.
|
|
||||||
//
|
|
||||||
// DeepEqual will not perform indirection of nested values of the input parameters.
|
|
||||||
func DeepEqual(a, b interface{}) bool {
|
|
||||||
ra := reflect.Indirect(reflect.ValueOf(a))
|
|
||||||
rb := reflect.Indirect(reflect.ValueOf(b))
|
|
||||||
|
|
||||||
if raValid, rbValid := ra.IsValid(), rb.IsValid(); !raValid && !rbValid {
|
|
||||||
// If the elements are both nil, and of the same type the are equal
|
|
||||||
// If they are of different types they are not equal
|
|
||||||
return reflect.TypeOf(a) == reflect.TypeOf(b)
|
|
||||||
} else if raValid != rbValid {
|
|
||||||
// Both values must be valid to be equal
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return reflect.DeepEqual(ra.Interface(), rb.Interface())
|
|
||||||
}
|
|
222
vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
222
vendor/github.com/aws/aws-sdk-go/aws/awsutil/path_value.go
generated
vendored
@ -1,222 +0,0 @@
|
|||||||
package awsutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/jmespath/go-jmespath"
|
|
||||||
)
|
|
||||||
|
|
||||||
var indexRe = regexp.MustCompile(`(.+)\[(-?\d+)?\]$`)
|
|
||||||
|
|
||||||
// rValuesAtPath returns a slice of values found in value v. The values
|
|
||||||
// in v are explored recursively so all nested values are collected.
|
|
||||||
func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTerm bool) []reflect.Value {
|
|
||||||
pathparts := strings.Split(path, "||")
|
|
||||||
if len(pathparts) > 1 {
|
|
||||||
for _, pathpart := range pathparts {
|
|
||||||
vals := rValuesAtPath(v, pathpart, createPath, caseSensitive, nilTerm)
|
|
||||||
if len(vals) > 0 {
|
|
||||||
return vals
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
values := []reflect.Value{reflect.Indirect(reflect.ValueOf(v))}
|
|
||||||
components := strings.Split(path, ".")
|
|
||||||
for len(values) > 0 && len(components) > 0 {
|
|
||||||
var index *int64
|
|
||||||
var indexStar bool
|
|
||||||
c := strings.TrimSpace(components[0])
|
|
||||||
if c == "" { // no actual component, illegal syntax
|
|
||||||
return nil
|
|
||||||
} else if caseSensitive && c != "*" && strings.ToLower(c[0:1]) == c[0:1] {
|
|
||||||
// TODO normalize case for user
|
|
||||||
return nil // don't support unexported fields
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse this component
|
|
||||||
if m := indexRe.FindStringSubmatch(c); m != nil {
|
|
||||||
c = m[1]
|
|
||||||
if m[2] == "" {
|
|
||||||
index = nil
|
|
||||||
indexStar = true
|
|
||||||
} else {
|
|
||||||
i, _ := strconv.ParseInt(m[2], 10, 32)
|
|
||||||
index = &i
|
|
||||||
indexStar = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nextvals := []reflect.Value{}
|
|
||||||
for _, value := range values {
|
|
||||||
// pull component name out of struct member
|
|
||||||
if value.Kind() != reflect.Struct {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if c == "*" { // pull all members
|
|
||||||
for i := 0; i < value.NumField(); i++ {
|
|
||||||
if f := reflect.Indirect(value.Field(i)); f.IsValid() {
|
|
||||||
nextvals = append(nextvals, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
value = value.FieldByNameFunc(func(name string) bool {
|
|
||||||
if c == name {
|
|
||||||
return true
|
|
||||||
} else if !caseSensitive && strings.ToLower(name) == strings.ToLower(c) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
if nilTerm && value.Kind() == reflect.Ptr && len(components[1:]) == 0 {
|
|
||||||
if !value.IsNil() {
|
|
||||||
value.Set(reflect.Zero(value.Type()))
|
|
||||||
}
|
|
||||||
return []reflect.Value{value}
|
|
||||||
}
|
|
||||||
|
|
||||||
if createPath && value.Kind() == reflect.Ptr && value.IsNil() {
|
|
||||||
// TODO if the value is the terminus it should not be created
|
|
||||||
// if the value to be set to its position is nil.
|
|
||||||
value.Set(reflect.New(value.Type().Elem()))
|
|
||||||
value = value.Elem()
|
|
||||||
} else {
|
|
||||||
value = reflect.Indirect(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
|
|
||||||
if !createPath && value.IsNil() {
|
|
||||||
value = reflect.ValueOf(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if value.IsValid() {
|
|
||||||
nextvals = append(nextvals, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
values = nextvals
|
|
||||||
|
|
||||||
if indexStar || index != nil {
|
|
||||||
nextvals = []reflect.Value{}
|
|
||||||
for _, valItem := range values {
|
|
||||||
value := reflect.Indirect(valItem)
|
|
||||||
if value.Kind() != reflect.Slice {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if indexStar { // grab all indices
|
|
||||||
for i := 0; i < value.Len(); i++ {
|
|
||||||
idx := reflect.Indirect(value.Index(i))
|
|
||||||
if idx.IsValid() {
|
|
||||||
nextvals = append(nextvals, idx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// pull out index
|
|
||||||
i := int(*index)
|
|
||||||
if i >= value.Len() { // check out of bounds
|
|
||||||
if createPath {
|
|
||||||
// TODO resize slice
|
|
||||||
} else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else if i < 0 { // support negative indexing
|
|
||||||
i = value.Len() + i
|
|
||||||
}
|
|
||||||
value = reflect.Indirect(value.Index(i))
|
|
||||||
|
|
||||||
if value.Kind() == reflect.Slice || value.Kind() == reflect.Map {
|
|
||||||
if !createPath && value.IsNil() {
|
|
||||||
value = reflect.ValueOf(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if value.IsValid() {
|
|
||||||
nextvals = append(nextvals, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
values = nextvals
|
|
||||||
}
|
|
||||||
|
|
||||||
components = components[1:]
|
|
||||||
}
|
|
||||||
return values
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValuesAtPath returns a list of values at the case insensitive lexical
|
|
||||||
// path inside of a structure.
|
|
||||||
func ValuesAtPath(i interface{}, path string) ([]interface{}, error) {
|
|
||||||
result, err := jmespath.Search(path, i)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := reflect.ValueOf(result)
|
|
||||||
if !v.IsValid() || (v.Kind() == reflect.Ptr && v.IsNil()) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
if s, ok := result.([]interface{}); ok {
|
|
||||||
return s, err
|
|
||||||
}
|
|
||||||
if v.Kind() == reflect.Map && v.Len() == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
if v.Kind() == reflect.Slice {
|
|
||||||
out := make([]interface{}, v.Len())
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
out[i] = v.Index(i).Interface()
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return []interface{}{result}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetValueAtPath sets a value at the case insensitive lexical path inside
|
|
||||||
// of a structure.
|
|
||||||
func SetValueAtPath(i interface{}, path string, v interface{}) {
|
|
||||||
if rvals := rValuesAtPath(i, path, true, false, v == nil); rvals != nil {
|
|
||||||
for _, rval := range rvals {
|
|
||||||
if rval.Kind() == reflect.Ptr && rval.IsNil() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
setValue(rval, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setValue(dstVal reflect.Value, src interface{}) {
|
|
||||||
if dstVal.Kind() == reflect.Ptr {
|
|
||||||
dstVal = reflect.Indirect(dstVal)
|
|
||||||
}
|
|
||||||
srcVal := reflect.ValueOf(src)
|
|
||||||
|
|
||||||
if !srcVal.IsValid() { // src is literal nil
|
|
||||||
if dstVal.CanAddr() {
|
|
||||||
// Convert to pointer so that pointer's value can be nil'ed
|
|
||||||
// dstVal = dstVal.Addr()
|
|
||||||
}
|
|
||||||
dstVal.Set(reflect.Zero(dstVal.Type()))
|
|
||||||
|
|
||||||
} else if srcVal.Kind() == reflect.Ptr {
|
|
||||||
if srcVal.IsNil() {
|
|
||||||
srcVal = reflect.Zero(dstVal.Type())
|
|
||||||
} else {
|
|
||||||
srcVal = reflect.ValueOf(src).Elem()
|
|
||||||
}
|
|
||||||
dstVal.Set(srcVal)
|
|
||||||
} else {
|
|
||||||
dstVal.Set(srcVal)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
113
vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go
generated
vendored
113
vendor/github.com/aws/aws-sdk-go/aws/awsutil/prettify.go
generated
vendored
@ -1,113 +0,0 @@
|
|||||||
package awsutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Prettify returns the string representation of a value.
|
|
||||||
func Prettify(i interface{}) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
prettify(reflect.ValueOf(i), 0, &buf)
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// prettify will recursively walk value v to build a textual
|
|
||||||
// representation of the value.
|
|
||||||
func prettify(v reflect.Value, indent int, buf *bytes.Buffer) {
|
|
||||||
for v.Kind() == reflect.Ptr {
|
|
||||||
v = v.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
strtype := v.Type().String()
|
|
||||||
if strtype == "time.Time" {
|
|
||||||
fmt.Fprintf(buf, "%s", v.Interface())
|
|
||||||
break
|
|
||||||
} else if strings.HasPrefix(strtype, "io.") {
|
|
||||||
buf.WriteString("<buffer>")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("{\n")
|
|
||||||
|
|
||||||
names := []string{}
|
|
||||||
for i := 0; i < v.Type().NumField(); i++ {
|
|
||||||
name := v.Type().Field(i).Name
|
|
||||||
f := v.Field(i)
|
|
||||||
if name[0:1] == strings.ToLower(name[0:1]) {
|
|
||||||
continue // ignore unexported fields
|
|
||||||
}
|
|
||||||
if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice || f.Kind() == reflect.Map) && f.IsNil() {
|
|
||||||
continue // ignore unset fields
|
|
||||||
}
|
|
||||||
names = append(names, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, n := range names {
|
|
||||||
val := v.FieldByName(n)
|
|
||||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
|
||||||
buf.WriteString(n + ": ")
|
|
||||||
prettify(val, indent+2, buf)
|
|
||||||
|
|
||||||
if i < len(names)-1 {
|
|
||||||
buf.WriteString(",\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
|
||||||
case reflect.Slice:
|
|
||||||
strtype := v.Type().String()
|
|
||||||
if strtype == "[]uint8" {
|
|
||||||
fmt.Fprintf(buf, "<binary> len %d", v.Len())
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
nl, id, id2 := "", "", ""
|
|
||||||
if v.Len() > 3 {
|
|
||||||
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
|
|
||||||
}
|
|
||||||
buf.WriteString("[" + nl)
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
buf.WriteString(id2)
|
|
||||||
prettify(v.Index(i), indent+2, buf)
|
|
||||||
|
|
||||||
if i < v.Len()-1 {
|
|
||||||
buf.WriteString("," + nl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString(nl + id + "]")
|
|
||||||
case reflect.Map:
|
|
||||||
buf.WriteString("{\n")
|
|
||||||
|
|
||||||
for i, k := range v.MapKeys() {
|
|
||||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
|
||||||
buf.WriteString(k.String() + ": ")
|
|
||||||
prettify(v.MapIndex(k), indent+2, buf)
|
|
||||||
|
|
||||||
if i < v.Len()-1 {
|
|
||||||
buf.WriteString(",\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
|
||||||
default:
|
|
||||||
if !v.IsValid() {
|
|
||||||
fmt.Fprint(buf, "<invalid value>")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
format := "%v"
|
|
||||||
switch v.Interface().(type) {
|
|
||||||
case string:
|
|
||||||
format = "%q"
|
|
||||||
case io.ReadSeeker, io.Reader:
|
|
||||||
format = "buffer(%p)"
|
|
||||||
}
|
|
||||||
fmt.Fprintf(buf, format, v.Interface())
|
|
||||||
}
|
|
||||||
}
|
|
89
vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
generated
vendored
89
vendor/github.com/aws/aws-sdk-go/aws/awsutil/string_value.go
generated
vendored
@ -1,89 +0,0 @@
|
|||||||
package awsutil
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StringValue returns the string representation of a value.
|
|
||||||
func StringValue(i interface{}) string {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
stringValue(reflect.ValueOf(i), 0, &buf)
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringValue(v reflect.Value, indent int, buf *bytes.Buffer) {
|
|
||||||
for v.Kind() == reflect.Ptr {
|
|
||||||
v = v.Elem()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v.Kind() {
|
|
||||||
case reflect.Struct:
|
|
||||||
buf.WriteString("{\n")
|
|
||||||
|
|
||||||
names := []string{}
|
|
||||||
for i := 0; i < v.Type().NumField(); i++ {
|
|
||||||
name := v.Type().Field(i).Name
|
|
||||||
f := v.Field(i)
|
|
||||||
if name[0:1] == strings.ToLower(name[0:1]) {
|
|
||||||
continue // ignore unexported fields
|
|
||||||
}
|
|
||||||
if (f.Kind() == reflect.Ptr || f.Kind() == reflect.Slice) && f.IsNil() {
|
|
||||||
continue // ignore unset fields
|
|
||||||
}
|
|
||||||
names = append(names, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, n := range names {
|
|
||||||
val := v.FieldByName(n)
|
|
||||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
|
||||||
buf.WriteString(n + ": ")
|
|
||||||
stringValue(val, indent+2, buf)
|
|
||||||
|
|
||||||
if i < len(names)-1 {
|
|
||||||
buf.WriteString(",\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
|
||||||
case reflect.Slice:
|
|
||||||
nl, id, id2 := "", "", ""
|
|
||||||
if v.Len() > 3 {
|
|
||||||
nl, id, id2 = "\n", strings.Repeat(" ", indent), strings.Repeat(" ", indent+2)
|
|
||||||
}
|
|
||||||
buf.WriteString("[" + nl)
|
|
||||||
for i := 0; i < v.Len(); i++ {
|
|
||||||
buf.WriteString(id2)
|
|
||||||
stringValue(v.Index(i), indent+2, buf)
|
|
||||||
|
|
||||||
if i < v.Len()-1 {
|
|
||||||
buf.WriteString("," + nl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString(nl + id + "]")
|
|
||||||
case reflect.Map:
|
|
||||||
buf.WriteString("{\n")
|
|
||||||
|
|
||||||
for i, k := range v.MapKeys() {
|
|
||||||
buf.WriteString(strings.Repeat(" ", indent+2))
|
|
||||||
buf.WriteString(k.String() + ": ")
|
|
||||||
stringValue(v.MapIndex(k), indent+2, buf)
|
|
||||||
|
|
||||||
if i < v.Len()-1 {
|
|
||||||
buf.WriteString(",\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("\n" + strings.Repeat(" ", indent) + "}")
|
|
||||||
default:
|
|
||||||
format := "%v"
|
|
||||||
switch v.Interface().(type) {
|
|
||||||
case string:
|
|
||||||
format = "%q"
|
|
||||||
}
|
|
||||||
fmt.Fprintf(buf, format, v.Interface())
|
|
||||||
}
|
|
||||||
}
|
|
96
vendor/github.com/aws/aws-sdk-go/aws/client/client.go
generated
vendored
96
vendor/github.com/aws/aws-sdk-go/aws/client/client.go
generated
vendored
@ -1,96 +0,0 @@
|
|||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Config provides configuration to a service client instance.
|
|
||||||
type Config struct {
|
|
||||||
Config *aws.Config
|
|
||||||
Handlers request.Handlers
|
|
||||||
Endpoint string
|
|
||||||
SigningRegion string
|
|
||||||
SigningName string
|
|
||||||
|
|
||||||
// States that the signing name did not come from a modeled source but
|
|
||||||
// was derived based on other data. Used by service client constructors
|
|
||||||
// to determine if the signin name can be overriden based on metadata the
|
|
||||||
// service has.
|
|
||||||
SigningNameDerived bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfigProvider provides a generic way for a service client to receive
|
|
||||||
// the ClientConfig without circular dependencies.
|
|
||||||
type ConfigProvider interface {
|
|
||||||
ClientConfig(serviceName string, cfgs ...*aws.Config) Config
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfigNoResolveEndpointProvider same as ConfigProvider except it will not
|
|
||||||
// resolve the endpoint automatically. The service client's endpoint must be
|
|
||||||
// provided via the aws.Config.Endpoint field.
|
|
||||||
type ConfigNoResolveEndpointProvider interface {
|
|
||||||
ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) Config
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Client implements the base client request and response handling
|
|
||||||
// used by all service clients.
|
|
||||||
type Client struct {
|
|
||||||
request.Retryer
|
|
||||||
metadata.ClientInfo
|
|
||||||
|
|
||||||
Config aws.Config
|
|
||||||
Handlers request.Handlers
|
|
||||||
}
|
|
||||||
|
|
||||||
// New will return a pointer to a new initialized service client.
|
|
||||||
func New(cfg aws.Config, info metadata.ClientInfo, handlers request.Handlers, options ...func(*Client)) *Client {
|
|
||||||
svc := &Client{
|
|
||||||
Config: cfg,
|
|
||||||
ClientInfo: info,
|
|
||||||
Handlers: handlers.Copy(),
|
|
||||||
}
|
|
||||||
|
|
||||||
switch retryer, ok := cfg.Retryer.(request.Retryer); {
|
|
||||||
case ok:
|
|
||||||
svc.Retryer = retryer
|
|
||||||
case cfg.Retryer != nil && cfg.Logger != nil:
|
|
||||||
s := fmt.Sprintf("WARNING: %T does not implement request.Retryer; using DefaultRetryer instead", cfg.Retryer)
|
|
||||||
cfg.Logger.Log(s)
|
|
||||||
fallthrough
|
|
||||||
default:
|
|
||||||
maxRetries := aws.IntValue(cfg.MaxRetries)
|
|
||||||
if cfg.MaxRetries == nil || maxRetries == aws.UseServiceDefaultRetries {
|
|
||||||
maxRetries = 3
|
|
||||||
}
|
|
||||||
svc.Retryer = DefaultRetryer{NumMaxRetries: maxRetries}
|
|
||||||
}
|
|
||||||
|
|
||||||
svc.AddDebugHandlers()
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(svc)
|
|
||||||
}
|
|
||||||
|
|
||||||
return svc
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewRequest returns a new Request pointer for the service API
|
|
||||||
// operation and parameters.
|
|
||||||
func (c *Client) NewRequest(operation *request.Operation, params interface{}, data interface{}) *request.Request {
|
|
||||||
return request.New(c.Config, c.ClientInfo, c.Handlers, c.Retryer, operation, params, data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddDebugHandlers injects debug logging handlers into the service to log request
|
|
||||||
// debug information.
|
|
||||||
func (c *Client) AddDebugHandlers() {
|
|
||||||
if !c.Config.LogLevel.AtLeast(aws.LogDebug) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Handlers.Send.PushFrontNamed(LogHTTPRequestHandler)
|
|
||||||
c.Handlers.Send.PushBackNamed(LogHTTPResponseHandler)
|
|
||||||
}
|
|
116
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
116
vendor/github.com/aws/aws-sdk-go/aws/client/default_retryer.go
generated
vendored
@ -1,116 +0,0 @@
|
|||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkrand"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DefaultRetryer implements basic retry logic using exponential backoff for
|
|
||||||
// most services. If you want to implement custom retry logic, implement the
|
|
||||||
// request.Retryer interface or create a structure type that composes this
|
|
||||||
// struct and override the specific methods. For example, to override only
|
|
||||||
// the MaxRetries method:
|
|
||||||
//
|
|
||||||
// type retryer struct {
|
|
||||||
// client.DefaultRetryer
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // This implementation always has 100 max retries
|
|
||||||
// func (d retryer) MaxRetries() int { return 100 }
|
|
||||||
type DefaultRetryer struct {
|
|
||||||
NumMaxRetries int
|
|
||||||
}
|
|
||||||
|
|
||||||
// MaxRetries returns the number of maximum returns the service will use to make
|
|
||||||
// an individual API request.
|
|
||||||
func (d DefaultRetryer) MaxRetries() int {
|
|
||||||
return d.NumMaxRetries
|
|
||||||
}
|
|
||||||
|
|
||||||
// RetryRules returns the delay duration before retrying this request again
|
|
||||||
func (d DefaultRetryer) RetryRules(r *request.Request) time.Duration {
|
|
||||||
// Set the upper limit of delay in retrying at ~five minutes
|
|
||||||
minTime := 30
|
|
||||||
throttle := d.shouldThrottle(r)
|
|
||||||
if throttle {
|
|
||||||
if delay, ok := getRetryDelay(r); ok {
|
|
||||||
return delay
|
|
||||||
}
|
|
||||||
|
|
||||||
minTime = 500
|
|
||||||
}
|
|
||||||
|
|
||||||
retryCount := r.RetryCount
|
|
||||||
if throttle && retryCount > 8 {
|
|
||||||
retryCount = 8
|
|
||||||
} else if retryCount > 13 {
|
|
||||||
retryCount = 13
|
|
||||||
}
|
|
||||||
|
|
||||||
delay := (1 << uint(retryCount)) * (sdkrand.SeededRand.Intn(minTime) + minTime)
|
|
||||||
return time.Duration(delay) * time.Millisecond
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 && r.HTTPResponse.StatusCode != 501 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return r.IsErrorRetryable() || d.shouldThrottle(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ShouldThrottle returns true if the request should be throttled.
|
|
||||||
func (d DefaultRetryer) shouldThrottle(r *request.Request) bool {
|
|
||||||
switch r.HTTPResponse.StatusCode {
|
|
||||||
case 429:
|
|
||||||
case 502:
|
|
||||||
case 503:
|
|
||||||
case 504:
|
|
||||||
default:
|
|
||||||
return r.IsErrorThrottle()
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// This will look in the Retry-After header, RFC 7231, for how long
|
|
||||||
// it will wait before attempting another request
|
|
||||||
func getRetryDelay(r *request.Request) (time.Duration, bool) {
|
|
||||||
if !canUseRetryAfterHeader(r) {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
delayStr := r.HTTPResponse.Header.Get("Retry-After")
|
|
||||||
if len(delayStr) == 0 {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
delay, err := strconv.Atoi(delayStr)
|
|
||||||
if err != nil {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return time.Duration(delay) * time.Second, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Will look at the status code to see if the retry header pertains to
|
|
||||||
// the status code.
|
|
||||||
func canUseRetryAfterHeader(r *request.Request) bool {
|
|
||||||
switch r.HTTPResponse.StatusCode {
|
|
||||||
case 429:
|
|
||||||
case 503:
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
184
vendor/github.com/aws/aws-sdk-go/aws/client/logger.go
generated
vendored
184
vendor/github.com/aws/aws-sdk-go/aws/client/logger.go
generated
vendored
@ -1,184 +0,0 @@
|
|||||||
package client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http/httputil"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
const logReqMsg = `DEBUG: Request %s/%s Details:
|
|
||||||
---[ REQUEST POST-SIGN ]-----------------------------
|
|
||||||
%s
|
|
||||||
-----------------------------------------------------`
|
|
||||||
|
|
||||||
const logReqErrMsg = `DEBUG ERROR: Request %s/%s:
|
|
||||||
---[ REQUEST DUMP ERROR ]-----------------------------
|
|
||||||
%s
|
|
||||||
------------------------------------------------------`
|
|
||||||
|
|
||||||
type logWriter struct {
|
|
||||||
// Logger is what we will use to log the payload of a response.
|
|
||||||
Logger aws.Logger
|
|
||||||
// buf stores the contents of what has been read
|
|
||||||
buf *bytes.Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (logger *logWriter) Write(b []byte) (int, error) {
|
|
||||||
return logger.buf.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
type teeReaderCloser struct {
|
|
||||||
// io.Reader will be a tee reader that is used during logging.
|
|
||||||
// This structure will read from a body and write the contents to a logger.
|
|
||||||
io.Reader
|
|
||||||
// Source is used just to close when we are done reading.
|
|
||||||
Source io.ReadCloser
|
|
||||||
}
|
|
||||||
|
|
||||||
func (reader *teeReaderCloser) Close() error {
|
|
||||||
return reader.Source.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogHTTPRequestHandler is a SDK request handler to log the HTTP request sent
|
|
||||||
// to a service. Will include the HTTP request body if the LogLevel of the
|
|
||||||
// request matches LogDebugWithHTTPBody.
|
|
||||||
var LogHTTPRequestHandler = request.NamedHandler{
|
|
||||||
Name: "awssdk.client.LogRequest",
|
|
||||||
Fn: logRequest,
|
|
||||||
}
|
|
||||||
|
|
||||||
func logRequest(r *request.Request) {
|
|
||||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
|
||||||
bodySeekable := aws.IsReaderSeekable(r.Body)
|
|
||||||
|
|
||||||
b, err := httputil.DumpRequestOut(r.HTTPRequest, logBody)
|
|
||||||
if err != nil {
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if logBody {
|
|
||||||
if !bodySeekable {
|
|
||||||
r.SetReaderBody(aws.ReadSeekCloser(r.HTTPRequest.Body))
|
|
||||||
}
|
|
||||||
// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's
|
|
||||||
// Body as a NoOpCloser and will not be reset after read by the HTTP
|
|
||||||
// client reader.
|
|
||||||
r.ResetBody()
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogHTTPRequestHeaderHandler is a SDK request handler to log the HTTP request sent
|
|
||||||
// to a service. Will only log the HTTP request's headers. The request payload
|
|
||||||
// will not be read.
|
|
||||||
var LogHTTPRequestHeaderHandler = request.NamedHandler{
|
|
||||||
Name: "awssdk.client.LogRequestHeader",
|
|
||||||
Fn: logRequestHeader,
|
|
||||||
}
|
|
||||||
|
|
||||||
func logRequestHeader(r *request.Request) {
|
|
||||||
b, err := httputil.DumpRequestOut(r.HTTPRequest, false)
|
|
||||||
if err != nil {
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logReqMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
|
|
||||||
}
|
|
||||||
|
|
||||||
const logRespMsg = `DEBUG: Response %s/%s Details:
|
|
||||||
---[ RESPONSE ]--------------------------------------
|
|
||||||
%s
|
|
||||||
-----------------------------------------------------`
|
|
||||||
|
|
||||||
const logRespErrMsg = `DEBUG ERROR: Response %s/%s:
|
|
||||||
---[ RESPONSE DUMP ERROR ]-----------------------------
|
|
||||||
%s
|
|
||||||
-----------------------------------------------------`
|
|
||||||
|
|
||||||
// LogHTTPResponseHandler is a SDK request handler to log the HTTP response
|
|
||||||
// received from a service. Will include the HTTP response body if the LogLevel
|
|
||||||
// of the request matches LogDebugWithHTTPBody.
|
|
||||||
var LogHTTPResponseHandler = request.NamedHandler{
|
|
||||||
Name: "awssdk.client.LogResponse",
|
|
||||||
Fn: logResponse,
|
|
||||||
}
|
|
||||||
|
|
||||||
func logResponse(r *request.Request) {
|
|
||||||
lw := &logWriter{r.Config.Logger, bytes.NewBuffer(nil)}
|
|
||||||
|
|
||||||
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody)
|
|
||||||
if logBody {
|
|
||||||
r.HTTPResponse.Body = &teeReaderCloser{
|
|
||||||
Reader: io.TeeReader(r.HTTPResponse.Body, lw),
|
|
||||||
Source: r.HTTPResponse.Body,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handlerFn := func(req *request.Request) {
|
|
||||||
b, err := httputil.DumpResponse(req.HTTPResponse, false)
|
|
||||||
if err != nil {
|
|
||||||
lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
|
||||||
req.ClientInfo.ServiceName, req.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
lw.Logger.Log(fmt.Sprintf(logRespMsg,
|
|
||||||
req.ClientInfo.ServiceName, req.Operation.Name, string(b)))
|
|
||||||
|
|
||||||
if logBody {
|
|
||||||
b, err := ioutil.ReadAll(lw.buf)
|
|
||||||
if err != nil {
|
|
||||||
lw.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
|
||||||
req.ClientInfo.ServiceName, req.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
lw.Logger.Log(string(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handlerName = "awsdk.client.LogResponse.ResponseBody"
|
|
||||||
|
|
||||||
r.Handlers.Unmarshal.SetBackNamed(request.NamedHandler{
|
|
||||||
Name: handlerName, Fn: handlerFn,
|
|
||||||
})
|
|
||||||
r.Handlers.UnmarshalError.SetBackNamed(request.NamedHandler{
|
|
||||||
Name: handlerName, Fn: handlerFn,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// LogHTTPResponseHeaderHandler is a SDK request handler to log the HTTP
|
|
||||||
// response received from a service. Will only log the HTTP response's headers.
|
|
||||||
// The response payload will not be read.
|
|
||||||
var LogHTTPResponseHeaderHandler = request.NamedHandler{
|
|
||||||
Name: "awssdk.client.LogResponseHeader",
|
|
||||||
Fn: logResponseHeader,
|
|
||||||
}
|
|
||||||
|
|
||||||
func logResponseHeader(r *request.Request) {
|
|
||||||
if r.Config.Logger == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := httputil.DumpResponse(r.HTTPResponse, false)
|
|
||||||
if err != nil {
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf(logRespMsg,
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, string(b)))
|
|
||||||
}
|
|
13
vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
generated
vendored
13
vendor/github.com/aws/aws-sdk-go/aws/client/metadata/client_info.go
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
package metadata
|
|
||||||
|
|
||||||
// ClientInfo wraps immutable data from the client.Client structure.
|
|
||||||
type ClientInfo struct {
|
|
||||||
ServiceName string
|
|
||||||
ServiceID string
|
|
||||||
APIVersion string
|
|
||||||
Endpoint string
|
|
||||||
SigningName string
|
|
||||||
SigningRegion string
|
|
||||||
JSONVersion string
|
|
||||||
TargetPrefix string
|
|
||||||
}
|
|
518
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
518
vendor/github.com/aws/aws-sdk-go/aws/config.go
generated
vendored
@ -1,518 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
|
||||||
)
|
|
||||||
|
|
||||||
// UseServiceDefaultRetries instructs the config to use the service's own
|
|
||||||
// default number of retries. This will be the default action if
|
|
||||||
// Config.MaxRetries is nil also.
|
|
||||||
const UseServiceDefaultRetries = -1
|
|
||||||
|
|
||||||
// RequestRetryer is an alias for a type that implements the request.Retryer
|
|
||||||
// interface.
|
|
||||||
type RequestRetryer interface{}
|
|
||||||
|
|
||||||
// A Config provides service configuration for service clients. By default,
|
|
||||||
// all clients will use the defaults.DefaultConfig structure.
|
|
||||||
//
|
|
||||||
// // Create Session with MaxRetry configuration to be shared by multiple
|
|
||||||
// // service clients.
|
|
||||||
// sess := session.Must(session.NewSession(&aws.Config{
|
|
||||||
// MaxRetries: aws.Int(3),
|
|
||||||
// }))
|
|
||||||
//
|
|
||||||
// // Create S3 service client with a specific Region.
|
|
||||||
// svc := s3.New(sess, &aws.Config{
|
|
||||||
// Region: aws.String("us-west-2"),
|
|
||||||
// })
|
|
||||||
type Config struct {
|
|
||||||
// Enables verbose error printing of all credential chain errors.
|
|
||||||
// Should be used when wanting to see all errors while attempting to
|
|
||||||
// retrieve credentials.
|
|
||||||
CredentialsChainVerboseErrors *bool
|
|
||||||
|
|
||||||
// The credentials object to use when signing requests. Defaults to a
|
|
||||||
// chain of credential providers to search for credentials in environment
|
|
||||||
// variables, shared credential file, and EC2 Instance Roles.
|
|
||||||
Credentials *credentials.Credentials
|
|
||||||
|
|
||||||
// An optional endpoint URL (hostname only or fully qualified URI)
|
|
||||||
// that overrides the default generated endpoint for a client. Set this
|
|
||||||
// to `""` to use the default generated endpoint.
|
|
||||||
//
|
|
||||||
// Note: You must still provide a `Region` value when specifying an
|
|
||||||
// endpoint for a client.
|
|
||||||
Endpoint *string
|
|
||||||
|
|
||||||
// The resolver to use for looking up endpoints for AWS service clients
|
|
||||||
// to use based on region.
|
|
||||||
EndpointResolver endpoints.Resolver
|
|
||||||
|
|
||||||
// EnforceShouldRetryCheck is used in the AfterRetryHandler to always call
|
|
||||||
// ShouldRetry regardless of whether or not if request.Retryable is set.
|
|
||||||
// This will utilize ShouldRetry method of custom retryers. If EnforceShouldRetryCheck
|
|
||||||
// is not set, then ShouldRetry will only be called if request.Retryable is nil.
|
|
||||||
// Proper handling of the request.Retryable field is important when setting this field.
|
|
||||||
EnforceShouldRetryCheck *bool
|
|
||||||
|
|
||||||
// The region to send requests to. This parameter is required and must
|
|
||||||
// be configured globally or on a per-client basis unless otherwise
|
|
||||||
// noted. A full list of regions is found in the "Regions and Endpoints"
|
|
||||||
// document.
|
|
||||||
//
|
|
||||||
// See http://docs.aws.amazon.com/general/latest/gr/rande.html for AWS
|
|
||||||
// Regions and Endpoints.
|
|
||||||
Region *string
|
|
||||||
|
|
||||||
// Set this to `true` to disable SSL when sending requests. Defaults
|
|
||||||
// to `false`.
|
|
||||||
DisableSSL *bool
|
|
||||||
|
|
||||||
// The HTTP client to use when sending requests. Defaults to
|
|
||||||
// `http.DefaultClient`.
|
|
||||||
HTTPClient *http.Client
|
|
||||||
|
|
||||||
// An integer value representing the logging level. The default log level
|
|
||||||
// is zero (LogOff), which represents no logging. To enable logging set
|
|
||||||
// to a LogLevel Value.
|
|
||||||
LogLevel *LogLevelType
|
|
||||||
|
|
||||||
// The logger writer interface to write logging messages to. Defaults to
|
|
||||||
// standard out.
|
|
||||||
Logger Logger
|
|
||||||
|
|
||||||
// The maximum number of times that a request will be retried for failures.
|
|
||||||
// Defaults to -1, which defers the max retry setting to the service
|
|
||||||
// specific configuration.
|
|
||||||
MaxRetries *int
|
|
||||||
|
|
||||||
// Retryer guides how HTTP requests should be retried in case of
|
|
||||||
// recoverable failures.
|
|
||||||
//
|
|
||||||
// When nil or the value does not implement the request.Retryer interface,
|
|
||||||
// the client.DefaultRetryer will be used.
|
|
||||||
//
|
|
||||||
// When both Retryer and MaxRetries are non-nil, the former is used and
|
|
||||||
// the latter ignored.
|
|
||||||
//
|
|
||||||
// To set the Retryer field in a type-safe manner and with chaining, use
|
|
||||||
// the request.WithRetryer helper function:
|
|
||||||
//
|
|
||||||
// cfg := request.WithRetryer(aws.NewConfig(), myRetryer)
|
|
||||||
//
|
|
||||||
Retryer RequestRetryer
|
|
||||||
|
|
||||||
// Disables semantic parameter validation, which validates input for
|
|
||||||
// missing required fields and/or other semantic request input errors.
|
|
||||||
DisableParamValidation *bool
|
|
||||||
|
|
||||||
// Disables the computation of request and response checksums, e.g.,
|
|
||||||
// CRC32 checksums in Amazon DynamoDB.
|
|
||||||
DisableComputeChecksums *bool
|
|
||||||
|
|
||||||
// Set this to `true` to force the request to use path-style addressing,
|
|
||||||
// i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client
|
|
||||||
// will use virtual hosted bucket addressing when possible
|
|
||||||
// (`http://BUCKET.s3.amazonaws.com/KEY`).
|
|
||||||
//
|
|
||||||
// Note: This configuration option is specific to the Amazon S3 service.
|
|
||||||
//
|
|
||||||
// See http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html
|
|
||||||
// for Amazon S3: Virtual Hosting of Buckets
|
|
||||||
S3ForcePathStyle *bool
|
|
||||||
|
|
||||||
// Set this to `true` to disable the SDK adding the `Expect: 100-Continue`
|
|
||||||
// header to PUT requests over 2MB of content. 100-Continue instructs the
|
|
||||||
// HTTP client not to send the body until the service responds with a
|
|
||||||
// `continue` status. This is useful to prevent sending the request body
|
|
||||||
// until after the request is authenticated, and validated.
|
|
||||||
//
|
|
||||||
// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html
|
|
||||||
//
|
|
||||||
// 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s
|
|
||||||
// `ExpectContinueTimeout` for information on adjusting the continue wait
|
|
||||||
// timeout. https://golang.org/pkg/net/http/#Transport
|
|
||||||
//
|
|
||||||
// You should use this flag to disble 100-Continue if you experience issues
|
|
||||||
// with proxies or third party S3 compatible services.
|
|
||||||
S3Disable100Continue *bool
|
|
||||||
|
|
||||||
// Set this to `true` to enable S3 Accelerate feature. For all operations
|
|
||||||
// compatible with S3 Accelerate will use the accelerate endpoint for
|
|
||||||
// requests. Requests not compatible will fall back to normal S3 requests.
|
|
||||||
//
|
|
||||||
// The bucket must be enable for accelerate to be used with S3 client with
|
|
||||||
// accelerate enabled. If the bucket is not enabled for accelerate an error
|
|
||||||
// will be returned. The bucket name must be DNS compatible to also work
|
|
||||||
// with accelerate.
|
|
||||||
S3UseAccelerate *bool
|
|
||||||
|
|
||||||
// S3DisableContentMD5Validation config option is temporarily disabled,
|
|
||||||
// For S3 GetObject API calls, #1837.
|
|
||||||
//
|
|
||||||
// Set this to `true` to disable the S3 service client from automatically
|
|
||||||
// adding the ContentMD5 to S3 Object Put and Upload API calls. This option
|
|
||||||
// will also disable the SDK from performing object ContentMD5 validation
|
|
||||||
// on GetObject API calls.
|
|
||||||
S3DisableContentMD5Validation *bool
|
|
||||||
|
|
||||||
// Set this to `true` to disable the EC2Metadata client from overriding the
|
|
||||||
// default http.Client's Timeout. This is helpful if you do not want the
|
|
||||||
// EC2Metadata client to create a new http.Client. This options is only
|
|
||||||
// meaningful if you're not already using a custom HTTP client with the
|
|
||||||
// SDK. Enabled by default.
|
|
||||||
//
|
|
||||||
// Must be set and provided to the session.NewSession() in order to disable
|
|
||||||
// the EC2Metadata overriding the timeout for default credentials chain.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// sess := session.Must(session.NewSession(aws.NewConfig()
|
|
||||||
// .WithEC2MetadataDiableTimeoutOverride(true)))
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
//
|
|
||||||
EC2MetadataDisableTimeoutOverride *bool
|
|
||||||
|
|
||||||
// Instructs the endpoint to be generated for a service client to
|
|
||||||
// be the dual stack endpoint. The dual stack endpoint will support
|
|
||||||
// both IPv4 and IPv6 addressing.
|
|
||||||
//
|
|
||||||
// Setting this for a service which does not support dual stack will fail
|
|
||||||
// to make requets. It is not recommended to set this value on the session
|
|
||||||
// as it will apply to all service clients created with the session. Even
|
|
||||||
// services which don't support dual stack endpoints.
|
|
||||||
//
|
|
||||||
// If the Endpoint config value is also provided the UseDualStack flag
|
|
||||||
// will be ignored.
|
|
||||||
//
|
|
||||||
// Only supported with.
|
|
||||||
//
|
|
||||||
// sess := session.Must(session.NewSession())
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess, &aws.Config{
|
|
||||||
// UseDualStack: aws.Bool(true),
|
|
||||||
// })
|
|
||||||
UseDualStack *bool
|
|
||||||
|
|
||||||
// SleepDelay is an override for the func the SDK will call when sleeping
|
|
||||||
// during the lifecycle of a request. Specifically this will be used for
|
|
||||||
// request delays. This value should only be used for testing. To adjust
|
|
||||||
// the delay of a request see the aws/client.DefaultRetryer and
|
|
||||||
// aws/request.Retryer.
|
|
||||||
//
|
|
||||||
// SleepDelay will prevent any Context from being used for canceling retry
|
|
||||||
// delay of an API operation. It is recommended to not use SleepDelay at all
|
|
||||||
// and specify a Retryer instead.
|
|
||||||
SleepDelay func(time.Duration)
|
|
||||||
|
|
||||||
// DisableRestProtocolURICleaning will not clean the URL path when making rest protocol requests.
|
|
||||||
// Will default to false. This would only be used for empty directory names in s3 requests.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// sess := session.Must(session.NewSession(&aws.Config{
|
|
||||||
// DisableRestProtocolURICleaning: aws.Bool(true),
|
|
||||||
// }))
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
// out, err := svc.GetObject(&s3.GetObjectInput {
|
|
||||||
// Bucket: aws.String("bucketname"),
|
|
||||||
// Key: aws.String("//foo//bar//moo"),
|
|
||||||
// })
|
|
||||||
DisableRestProtocolURICleaning *bool
|
|
||||||
|
|
||||||
// EnableEndpointDiscovery will allow for endpoint discovery on operations that
|
|
||||||
// have the definition in its model. By default, endpoint discovery is off.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// sess := session.Must(session.NewSession(&aws.Config{
|
|
||||||
// EnableEndpointDiscovery: aws.Bool(true),
|
|
||||||
// }))
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
// out, err := svc.GetObject(&s3.GetObjectInput {
|
|
||||||
// Bucket: aws.String("bucketname"),
|
|
||||||
// Key: aws.String("/foo/bar/moo"),
|
|
||||||
// })
|
|
||||||
EnableEndpointDiscovery *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewConfig returns a new Config pointer that can be chained with builder
|
|
||||||
// methods to set multiple configuration values inline without using pointers.
|
|
||||||
//
|
|
||||||
// // Create Session with MaxRetry configuration to be shared by multiple
|
|
||||||
// // service clients.
|
|
||||||
// sess := session.Must(session.NewSession(aws.NewConfig().
|
|
||||||
// WithMaxRetries(3),
|
|
||||||
// ))
|
|
||||||
//
|
|
||||||
// // Create S3 service client with a specific Region.
|
|
||||||
// svc := s3.New(sess, aws.NewConfig().
|
|
||||||
// WithRegion("us-west-2"),
|
|
||||||
// )
|
|
||||||
func NewConfig() *Config {
|
|
||||||
return &Config{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCredentialsChainVerboseErrors sets a config verbose errors boolean and returning
|
|
||||||
// a Config pointer.
|
|
||||||
func (c *Config) WithCredentialsChainVerboseErrors(verboseErrs bool) *Config {
|
|
||||||
c.CredentialsChainVerboseErrors = &verboseErrs
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithCredentials sets a config Credentials value returning a Config pointer
|
|
||||||
// for chaining.
|
|
||||||
func (c *Config) WithCredentials(creds *credentials.Credentials) *Config {
|
|
||||||
c.Credentials = creds
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEndpoint sets a config Endpoint value returning a Config pointer for
|
|
||||||
// chaining.
|
|
||||||
func (c *Config) WithEndpoint(endpoint string) *Config {
|
|
||||||
c.Endpoint = &endpoint
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEndpointResolver sets a config EndpointResolver value returning a
|
|
||||||
// Config pointer for chaining.
|
|
||||||
func (c *Config) WithEndpointResolver(resolver endpoints.Resolver) *Config {
|
|
||||||
c.EndpointResolver = resolver
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithRegion sets a config Region value returning a Config pointer for
|
|
||||||
// chaining.
|
|
||||||
func (c *Config) WithRegion(region string) *Config {
|
|
||||||
c.Region = ®ion
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDisableSSL sets a config DisableSSL value returning a Config pointer
|
|
||||||
// for chaining.
|
|
||||||
func (c *Config) WithDisableSSL(disable bool) *Config {
|
|
||||||
c.DisableSSL = &disable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithHTTPClient sets a config HTTPClient value returning a Config pointer
|
|
||||||
// for chaining.
|
|
||||||
func (c *Config) WithHTTPClient(client *http.Client) *Config {
|
|
||||||
c.HTTPClient = client
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithMaxRetries sets a config MaxRetries value returning a Config pointer
|
|
||||||
// for chaining.
|
|
||||||
func (c *Config) WithMaxRetries(max int) *Config {
|
|
||||||
c.MaxRetries = &max
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDisableParamValidation sets a config DisableParamValidation value
|
|
||||||
// returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithDisableParamValidation(disable bool) *Config {
|
|
||||||
c.DisableParamValidation = &disable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithDisableComputeChecksums sets a config DisableComputeChecksums value
|
|
||||||
// returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithDisableComputeChecksums(disable bool) *Config {
|
|
||||||
c.DisableComputeChecksums = &disable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithLogLevel sets a config LogLevel value returning a Config pointer for
|
|
||||||
// chaining.
|
|
||||||
func (c *Config) WithLogLevel(level LogLevelType) *Config {
|
|
||||||
c.LogLevel = &level
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithLogger sets a config Logger value returning a Config pointer for
|
|
||||||
// chaining.
|
|
||||||
func (c *Config) WithLogger(logger Logger) *Config {
|
|
||||||
c.Logger = logger
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithS3ForcePathStyle sets a config S3ForcePathStyle value returning a Config
|
|
||||||
// pointer for chaining.
|
|
||||||
func (c *Config) WithS3ForcePathStyle(force bool) *Config {
|
|
||||||
c.S3ForcePathStyle = &force
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithS3Disable100Continue sets a config S3Disable100Continue value returning
|
|
||||||
// a Config pointer for chaining.
|
|
||||||
func (c *Config) WithS3Disable100Continue(disable bool) *Config {
|
|
||||||
c.S3Disable100Continue = &disable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithS3UseAccelerate sets a config S3UseAccelerate value returning a Config
|
|
||||||
// pointer for chaining.
|
|
||||||
func (c *Config) WithS3UseAccelerate(enable bool) *Config {
|
|
||||||
c.S3UseAccelerate = &enable
|
|
||||||
return c
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithS3DisableContentMD5Validation sets a config
|
|
||||||
// S3DisableContentMD5Validation value returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithS3DisableContentMD5Validation(enable bool) *Config {
|
|
||||||
c.S3DisableContentMD5Validation = &enable
|
|
||||||
return c
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithUseDualStack sets a config UseDualStack value returning a Config
|
|
||||||
// pointer for chaining.
|
|
||||||
func (c *Config) WithUseDualStack(enable bool) *Config {
|
|
||||||
c.UseDualStack = &enable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value
|
|
||||||
// returning a Config pointer for chaining.
|
|
||||||
func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
|
|
||||||
c.EC2MetadataDisableTimeoutOverride = &enable
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithSleepDelay overrides the function used to sleep while waiting for the
|
|
||||||
// next retry. Defaults to time.Sleep.
|
|
||||||
func (c *Config) WithSleepDelay(fn func(time.Duration)) *Config {
|
|
||||||
c.SleepDelay = fn
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithEndpointDiscovery will set whether or not to use endpoint discovery.
|
|
||||||
func (c *Config) WithEndpointDiscovery(t bool) *Config {
|
|
||||||
c.EnableEndpointDiscovery = &t
|
|
||||||
return c
|
|
||||||
}
|
|
||||||
|
|
||||||
// MergeIn merges the passed in configs into the existing config object.
|
|
||||||
func (c *Config) MergeIn(cfgs ...*Config) {
|
|
||||||
for _, other := range cfgs {
|
|
||||||
mergeInConfig(c, other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func mergeInConfig(dst *Config, other *Config) {
|
|
||||||
if other == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.CredentialsChainVerboseErrors != nil {
|
|
||||||
dst.CredentialsChainVerboseErrors = other.CredentialsChainVerboseErrors
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.Credentials != nil {
|
|
||||||
dst.Credentials = other.Credentials
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.Endpoint != nil {
|
|
||||||
dst.Endpoint = other.Endpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.EndpointResolver != nil {
|
|
||||||
dst.EndpointResolver = other.EndpointResolver
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.Region != nil {
|
|
||||||
dst.Region = other.Region
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.DisableSSL != nil {
|
|
||||||
dst.DisableSSL = other.DisableSSL
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.HTTPClient != nil {
|
|
||||||
dst.HTTPClient = other.HTTPClient
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.LogLevel != nil {
|
|
||||||
dst.LogLevel = other.LogLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.Logger != nil {
|
|
||||||
dst.Logger = other.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.MaxRetries != nil {
|
|
||||||
dst.MaxRetries = other.MaxRetries
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.Retryer != nil {
|
|
||||||
dst.Retryer = other.Retryer
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.DisableParamValidation != nil {
|
|
||||||
dst.DisableParamValidation = other.DisableParamValidation
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.DisableComputeChecksums != nil {
|
|
||||||
dst.DisableComputeChecksums = other.DisableComputeChecksums
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.S3ForcePathStyle != nil {
|
|
||||||
dst.S3ForcePathStyle = other.S3ForcePathStyle
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.S3Disable100Continue != nil {
|
|
||||||
dst.S3Disable100Continue = other.S3Disable100Continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.S3UseAccelerate != nil {
|
|
||||||
dst.S3UseAccelerate = other.S3UseAccelerate
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.S3DisableContentMD5Validation != nil {
|
|
||||||
dst.S3DisableContentMD5Validation = other.S3DisableContentMD5Validation
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.UseDualStack != nil {
|
|
||||||
dst.UseDualStack = other.UseDualStack
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.EC2MetadataDisableTimeoutOverride != nil {
|
|
||||||
dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.SleepDelay != nil {
|
|
||||||
dst.SleepDelay = other.SleepDelay
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.DisableRestProtocolURICleaning != nil {
|
|
||||||
dst.DisableRestProtocolURICleaning = other.DisableRestProtocolURICleaning
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.EnforceShouldRetryCheck != nil {
|
|
||||||
dst.EnforceShouldRetryCheck = other.EnforceShouldRetryCheck
|
|
||||||
}
|
|
||||||
|
|
||||||
if other.EnableEndpointDiscovery != nil {
|
|
||||||
dst.EnableEndpointDiscovery = other.EnableEndpointDiscovery
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy will return a shallow copy of the Config object. If any additional
|
|
||||||
// configurations are provided they will be merged into the new config returned.
|
|
||||||
func (c *Config) Copy(cfgs ...*Config) *Config {
|
|
||||||
dst := &Config{}
|
|
||||||
dst.MergeIn(c)
|
|
||||||
|
|
||||||
for _, cfg := range cfgs {
|
|
||||||
dst.MergeIn(cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst
|
|
||||||
}
|
|
71
vendor/github.com/aws/aws-sdk-go/aws/context.go
generated
vendored
71
vendor/github.com/aws/aws-sdk-go/aws/context.go
generated
vendored
@ -1,71 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Context is an copy of the Go v1.7 stdlib's context.Context interface.
|
|
||||||
// It is represented as a SDK interface to enable you to use the "WithContext"
|
|
||||||
// API methods with Go v1.6 and a Context type such as golang.org/x/net/context.
|
|
||||||
//
|
|
||||||
// See https://golang.org/pkg/context on how to use contexts.
|
|
||||||
type Context interface {
|
|
||||||
// Deadline returns the time when work done on behalf of this context
|
|
||||||
// should be canceled. Deadline returns ok==false when no deadline is
|
|
||||||
// set. Successive calls to Deadline return the same results.
|
|
||||||
Deadline() (deadline time.Time, ok bool)
|
|
||||||
|
|
||||||
// Done returns a channel that's closed when work done on behalf of this
|
|
||||||
// context should be canceled. Done may return nil if this context can
|
|
||||||
// never be canceled. Successive calls to Done return the same value.
|
|
||||||
Done() <-chan struct{}
|
|
||||||
|
|
||||||
// Err returns a non-nil error value after Done is closed. Err returns
|
|
||||||
// Canceled if the context was canceled or DeadlineExceeded if the
|
|
||||||
// context's deadline passed. No other values for Err are defined.
|
|
||||||
// After Done is closed, successive calls to Err return the same value.
|
|
||||||
Err() error
|
|
||||||
|
|
||||||
// Value returns the value associated with this context for key, or nil
|
|
||||||
// if no value is associated with key. Successive calls to Value with
|
|
||||||
// the same key returns the same result.
|
|
||||||
//
|
|
||||||
// Use context values only for request-scoped data that transits
|
|
||||||
// processes and API boundaries, not for passing optional parameters to
|
|
||||||
// functions.
|
|
||||||
Value(key interface{}) interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// BackgroundContext returns a context that will never be canceled, has no
|
|
||||||
// values, and no deadline. This context is used by the SDK to provide
|
|
||||||
// backwards compatibility with non-context API operations and functionality.
|
|
||||||
//
|
|
||||||
// Go 1.6 and before:
|
|
||||||
// This context function is equivalent to context.Background in the Go stdlib.
|
|
||||||
//
|
|
||||||
// Go 1.7 and later:
|
|
||||||
// The context returned will be the value returned by context.Background()
|
|
||||||
//
|
|
||||||
// See https://golang.org/pkg/context for more information on Contexts.
|
|
||||||
func BackgroundContext() Context {
|
|
||||||
return backgroundCtx
|
|
||||||
}
|
|
||||||
|
|
||||||
// SleepWithContext will wait for the timer duration to expire, or the context
|
|
||||||
// is canceled. Which ever happens first. If the context is canceled the Context's
|
|
||||||
// error will be returned.
|
|
||||||
//
|
|
||||||
// Expects Context to always return a non-nil error if the Done channel is closed.
|
|
||||||
func SleepWithContext(ctx Context, dur time.Duration) error {
|
|
||||||
t := time.NewTimer(dur)
|
|
||||||
defer t.Stop()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-t.C:
|
|
||||||
break
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
41
vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go
generated
vendored
41
vendor/github.com/aws/aws-sdk-go/aws/context_1_6.go
generated
vendored
@ -1,41 +0,0 @@
|
|||||||
// +build !go1.7
|
|
||||||
|
|
||||||
package aws
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
// An emptyCtx is a copy of the Go 1.7 context.emptyCtx type. This is copied to
|
|
||||||
// provide a 1.6 and 1.5 safe version of context that is compatible with Go
|
|
||||||
// 1.7's Context.
|
|
||||||
//
|
|
||||||
// An emptyCtx is never canceled, has no values, and has no deadline. It is not
|
|
||||||
// struct{}, since vars of this type must have distinct addresses.
|
|
||||||
type emptyCtx int
|
|
||||||
|
|
||||||
func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*emptyCtx) Done() <-chan struct{} {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*emptyCtx) Err() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*emptyCtx) Value(key interface{}) interface{} {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *emptyCtx) String() string {
|
|
||||||
switch e {
|
|
||||||
case backgroundCtx:
|
|
||||||
return "aws.BackgroundContext"
|
|
||||||
}
|
|
||||||
return "unknown empty Context"
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
backgroundCtx = new(emptyCtx)
|
|
||||||
)
|
|
9
vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go
generated
vendored
9
vendor/github.com/aws/aws-sdk-go/aws/context_1_7.go
generated
vendored
@ -1,9 +0,0 @@
|
|||||||
// +build go1.7
|
|
||||||
|
|
||||||
package aws
|
|
||||||
|
|
||||||
import "context"
|
|
||||||
|
|
||||||
var (
|
|
||||||
backgroundCtx = context.Background()
|
|
||||||
)
|
|
387
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
387
vendor/github.com/aws/aws-sdk-go/aws/convert_types.go
generated
vendored
@ -1,387 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
import "time"
|
|
||||||
|
|
||||||
// String returns a pointer to the string value passed in.
|
|
||||||
func String(v string) *string {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringValue returns the value of the string pointer passed in or
|
|
||||||
// "" if the pointer is nil.
|
|
||||||
func StringValue(v *string) string {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringSlice converts a slice of string values into a slice of
|
|
||||||
// string pointers
|
|
||||||
func StringSlice(src []string) []*string {
|
|
||||||
dst := make([]*string, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringValueSlice converts a slice of string pointers into a slice of
|
|
||||||
// string values
|
|
||||||
func StringValueSlice(src []*string) []string {
|
|
||||||
dst := make([]string, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringMap converts a string map of string values into a string
|
|
||||||
// map of string pointers
|
|
||||||
func StringMap(src map[string]string) map[string]*string {
|
|
||||||
dst := make(map[string]*string)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringValueMap converts a string map of string pointers into a string
|
|
||||||
// map of string values
|
|
||||||
func StringValueMap(src map[string]*string) map[string]string {
|
|
||||||
dst := make(map[string]string)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bool returns a pointer to the bool value passed in.
|
|
||||||
func Bool(v bool) *bool {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolValue returns the value of the bool pointer passed in or
|
|
||||||
// false if the pointer is nil.
|
|
||||||
func BoolValue(v *bool) bool {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolSlice converts a slice of bool values into a slice of
|
|
||||||
// bool pointers
|
|
||||||
func BoolSlice(src []bool) []*bool {
|
|
||||||
dst := make([]*bool, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolValueSlice converts a slice of bool pointers into a slice of
|
|
||||||
// bool values
|
|
||||||
func BoolValueSlice(src []*bool) []bool {
|
|
||||||
dst := make([]bool, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolMap converts a string map of bool values into a string
|
|
||||||
// map of bool pointers
|
|
||||||
func BoolMap(src map[string]bool) map[string]*bool {
|
|
||||||
dst := make(map[string]*bool)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolValueMap converts a string map of bool pointers into a string
|
|
||||||
// map of bool values
|
|
||||||
func BoolValueMap(src map[string]*bool) map[string]bool {
|
|
||||||
dst := make(map[string]bool)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int returns a pointer to the int value passed in.
|
|
||||||
func Int(v int) *int {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntValue returns the value of the int pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func IntValue(v *int) int {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntSlice converts a slice of int values into a slice of
|
|
||||||
// int pointers
|
|
||||||
func IntSlice(src []int) []*int {
|
|
||||||
dst := make([]*int, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntValueSlice converts a slice of int pointers into a slice of
|
|
||||||
// int values
|
|
||||||
func IntValueSlice(src []*int) []int {
|
|
||||||
dst := make([]int, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntMap converts a string map of int values into a string
|
|
||||||
// map of int pointers
|
|
||||||
func IntMap(src map[string]int) map[string]*int {
|
|
||||||
dst := make(map[string]*int)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntValueMap converts a string map of int pointers into a string
|
|
||||||
// map of int values
|
|
||||||
func IntValueMap(src map[string]*int) map[string]int {
|
|
||||||
dst := make(map[string]int)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64 returns a pointer to the int64 value passed in.
|
|
||||||
func Int64(v int64) *int64 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64Value returns the value of the int64 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Int64Value(v *int64) int64 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64Slice converts a slice of int64 values into a slice of
|
|
||||||
// int64 pointers
|
|
||||||
func Int64Slice(src []int64) []*int64 {
|
|
||||||
dst := make([]*int64, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64ValueSlice converts a slice of int64 pointers into a slice of
|
|
||||||
// int64 values
|
|
||||||
func Int64ValueSlice(src []*int64) []int64 {
|
|
||||||
dst := make([]int64, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64Map converts a string map of int64 values into a string
|
|
||||||
// map of int64 pointers
|
|
||||||
func Int64Map(src map[string]int64) map[string]*int64 {
|
|
||||||
dst := make(map[string]*int64)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Int64ValueMap converts a string map of int64 pointers into a string
|
|
||||||
// map of int64 values
|
|
||||||
func Int64ValueMap(src map[string]*int64) map[string]int64 {
|
|
||||||
dst := make(map[string]int64)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64 returns a pointer to the float64 value passed in.
|
|
||||||
func Float64(v float64) *float64 {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Value returns the value of the float64 pointer passed in or
|
|
||||||
// 0 if the pointer is nil.
|
|
||||||
func Float64Value(v *float64) float64 {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Slice converts a slice of float64 values into a slice of
|
|
||||||
// float64 pointers
|
|
||||||
func Float64Slice(src []float64) []*float64 {
|
|
||||||
dst := make([]*float64, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64ValueSlice converts a slice of float64 pointers into a slice of
|
|
||||||
// float64 values
|
|
||||||
func Float64ValueSlice(src []*float64) []float64 {
|
|
||||||
dst := make([]float64, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64Map converts a string map of float64 values into a string
|
|
||||||
// map of float64 pointers
|
|
||||||
func Float64Map(src map[string]float64) map[string]*float64 {
|
|
||||||
dst := make(map[string]*float64)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64ValueMap converts a string map of float64 pointers into a string
|
|
||||||
// map of float64 values
|
|
||||||
func Float64ValueMap(src map[string]*float64) map[string]float64 {
|
|
||||||
dst := make(map[string]float64)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// Time returns a pointer to the time.Time value passed in.
|
|
||||||
func Time(v time.Time) *time.Time {
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeValue returns the value of the time.Time pointer passed in or
|
|
||||||
// time.Time{} if the pointer is nil.
|
|
||||||
func TimeValue(v *time.Time) time.Time {
|
|
||||||
if v != nil {
|
|
||||||
return *v
|
|
||||||
}
|
|
||||||
return time.Time{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SecondsTimeValue converts an int64 pointer to a time.Time value
|
|
||||||
// representing seconds since Epoch or time.Time{} if the pointer is nil.
|
|
||||||
func SecondsTimeValue(v *int64) time.Time {
|
|
||||||
if v != nil {
|
|
||||||
return time.Unix((*v / 1000), 0)
|
|
||||||
}
|
|
||||||
return time.Time{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MillisecondsTimeValue converts an int64 pointer to a time.Time value
|
|
||||||
// representing milliseconds sinch Epoch or time.Time{} if the pointer is nil.
|
|
||||||
func MillisecondsTimeValue(v *int64) time.Time {
|
|
||||||
if v != nil {
|
|
||||||
return time.Unix(0, (*v * 1000000))
|
|
||||||
}
|
|
||||||
return time.Time{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeUnixMilli returns a Unix timestamp in milliseconds from "January 1, 1970 UTC".
|
|
||||||
// The result is undefined if the Unix time cannot be represented by an int64.
|
|
||||||
// Which includes calling TimeUnixMilli on a zero Time is undefined.
|
|
||||||
//
|
|
||||||
// This utility is useful for service API's such as CloudWatch Logs which require
|
|
||||||
// their unix time values to be in milliseconds.
|
|
||||||
//
|
|
||||||
// See Go stdlib https://golang.org/pkg/time/#Time.UnixNano for more information.
|
|
||||||
func TimeUnixMilli(t time.Time) int64 {
|
|
||||||
return t.UnixNano() / int64(time.Millisecond/time.Nanosecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeSlice converts a slice of time.Time values into a slice of
|
|
||||||
// time.Time pointers
|
|
||||||
func TimeSlice(src []time.Time) []*time.Time {
|
|
||||||
dst := make([]*time.Time, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
dst[i] = &(src[i])
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeValueSlice converts a slice of time.Time pointers into a slice of
|
|
||||||
// time.Time values
|
|
||||||
func TimeValueSlice(src []*time.Time) []time.Time {
|
|
||||||
dst := make([]time.Time, len(src))
|
|
||||||
for i := 0; i < len(src); i++ {
|
|
||||||
if src[i] != nil {
|
|
||||||
dst[i] = *(src[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeMap converts a string map of time.Time values into a string
|
|
||||||
// map of time.Time pointers
|
|
||||||
func TimeMap(src map[string]time.Time) map[string]*time.Time {
|
|
||||||
dst := make(map[string]*time.Time)
|
|
||||||
for k, val := range src {
|
|
||||||
v := val
|
|
||||||
dst[k] = &v
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimeValueMap converts a string map of time.Time pointers into a string
|
|
||||||
// map of time.Time values
|
|
||||||
func TimeValueMap(src map[string]*time.Time) map[string]time.Time {
|
|
||||||
dst := make(map[string]time.Time)
|
|
||||||
for k, val := range src {
|
|
||||||
if val != nil {
|
|
||||||
dst[k] = *val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dst
|
|
||||||
}
|
|
228
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
generated
vendored
228
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/handlers.go
generated
vendored
@ -1,228 +0,0 @@
|
|||||||
package corehandlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"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/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Interface for matching types which also have a Len method.
|
|
||||||
type lener interface {
|
|
||||||
Len() int
|
|
||||||
}
|
|
||||||
|
|
||||||
// BuildContentLengthHandler builds the content length of a request based on the body,
|
|
||||||
// or will use the HTTPRequest.Header's "Content-Length" if defined. If unable
|
|
||||||
// to determine request body length and no "Content-Length" was specified it will panic.
|
|
||||||
//
|
|
||||||
// The Content-Length will only be added to the request if the length of the body
|
|
||||||
// is greater than 0. If the body is empty or the current `Content-Length`
|
|
||||||
// header is <= 0, the header will also be stripped.
|
|
||||||
var BuildContentLengthHandler = request.NamedHandler{Name: "core.BuildContentLengthHandler", Fn: func(r *request.Request) {
|
|
||||||
var length int64
|
|
||||||
|
|
||||||
if slength := r.HTTPRequest.Header.Get("Content-Length"); slength != "" {
|
|
||||||
length, _ = strconv.ParseInt(slength, 10, 64)
|
|
||||||
} else {
|
|
||||||
if r.Body != nil {
|
|
||||||
var err error
|
|
||||||
length, err = aws.SeekerLen(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
r.Error = awserr.New(request.ErrCodeSerialization, "failed to get request body's length", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if length > 0 {
|
|
||||||
r.HTTPRequest.ContentLength = length
|
|
||||||
r.HTTPRequest.Header.Set("Content-Length", fmt.Sprintf("%d", length))
|
|
||||||
} else {
|
|
||||||
r.HTTPRequest.ContentLength = 0
|
|
||||||
r.HTTPRequest.Header.Del("Content-Length")
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
var reStatusCode = regexp.MustCompile(`^(\d{3})`)
|
|
||||||
|
|
||||||
// ValidateReqSigHandler is a request handler to ensure that the request's
|
|
||||||
// signature doesn't expire before it is sent. This can happen when a request
|
|
||||||
// is built and signed significantly before it is sent. Or significant delays
|
|
||||||
// occur when retrying requests that would cause the signature to expire.
|
|
||||||
var ValidateReqSigHandler = request.NamedHandler{
|
|
||||||
Name: "core.ValidateReqSigHandler",
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
// Unsigned requests are not signed
|
|
||||||
if r.Config.Credentials == credentials.AnonymousCredentials {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
signedTime := r.Time
|
|
||||||
if !r.LastSignedAt.IsZero() {
|
|
||||||
signedTime = r.LastSignedAt
|
|
||||||
}
|
|
||||||
|
|
||||||
// 10 minutes to allow for some clock skew/delays in transmission.
|
|
||||||
// Would be improved with aws/aws-sdk-go#423
|
|
||||||
if signedTime.Add(10 * time.Minute).After(time.Now()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("request expired, resigning")
|
|
||||||
r.Sign()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendHandler is a request handler to send service request using HTTP client.
|
|
||||||
var SendHandler = request.NamedHandler{
|
|
||||||
Name: "core.SendHandler",
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
sender := sendFollowRedirects
|
|
||||||
if r.DisableFollowRedirects {
|
|
||||||
sender = sendWithoutFollowRedirects
|
|
||||||
}
|
|
||||||
|
|
||||||
if request.NoBody == r.HTTPRequest.Body {
|
|
||||||
// Strip off the request body if the NoBody reader was used as a
|
|
||||||
// place holder for a request body. This prevents the SDK from
|
|
||||||
// making requests with a request body when it would be invalid
|
|
||||||
// to do so.
|
|
||||||
//
|
|
||||||
// Use a shallow copy of the http.Request to ensure the race condition
|
|
||||||
// of transport on Body will not trigger
|
|
||||||
reqOrig, reqCopy := r.HTTPRequest, *r.HTTPRequest
|
|
||||||
reqCopy.Body = nil
|
|
||||||
r.HTTPRequest = &reqCopy
|
|
||||||
defer func() {
|
|
||||||
r.HTTPRequest = reqOrig
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
r.HTTPResponse, err = sender(r)
|
|
||||||
if err != nil {
|
|
||||||
handleSendError(r, err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendFollowRedirects(r *request.Request) (*http.Response, error) {
|
|
||||||
return r.Config.HTTPClient.Do(r.HTTPRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendWithoutFollowRedirects(r *request.Request) (*http.Response, error) {
|
|
||||||
transport := r.Config.HTTPClient.Transport
|
|
||||||
if transport == nil {
|
|
||||||
transport = http.DefaultTransport
|
|
||||||
}
|
|
||||||
|
|
||||||
return transport.RoundTrip(r.HTTPRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleSendError(r *request.Request, err error) {
|
|
||||||
// Prevent leaking if an HTTPResponse was returned. Clean up
|
|
||||||
// the body.
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
r.HTTPResponse.Body.Close()
|
|
||||||
}
|
|
||||||
// Capture the case where url.Error is returned for error processing
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
if r.HTTPResponse.StatusCode == 0 || r.HTTPResponse.StatusCode >= 300 {
|
|
||||||
// this may be replaced by an UnmarshalError handler
|
|
||||||
r.Error = awserr.New("UnknownError", "unknown error", nil)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
// AfterRetryHandler performs final checks to determine if the request should
|
|
||||||
// be retried and how long to delay.
|
|
||||||
var AfterRetryHandler = request.NamedHandler{Name: "core.AfterRetryHandler", Fn: func(r *request.Request) {
|
|
||||||
// If one of the other handlers already set the retry state
|
|
||||||
// we don't want to override it based on the service's state
|
|
||||||
if r.Retryable == nil || aws.BoolValue(r.Config.EnforceShouldRetryCheck) {
|
|
||||||
r.Retryable = aws.Bool(r.ShouldRetry(r))
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.WillRetry() {
|
|
||||||
r.RetryDelay = r.RetryRules(r)
|
|
||||||
|
|
||||||
if sleepFn := r.Config.SleepDelay; sleepFn != nil {
|
|
||||||
// Support SleepDelay for backwards compatibility and testing
|
|
||||||
sleepFn(r.RetryDelay)
|
|
||||||
} else if err := aws.SleepWithContext(r.Context(), r.RetryDelay); err != nil {
|
|
||||||
r.Error = awserr.New(request.CanceledErrorCode,
|
|
||||||
"request context canceled", err)
|
|
||||||
r.Retryable = aws.Bool(false)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// when the expired token exception occurs the credentials
|
|
||||||
// need to be expired locally so that the next request to
|
|
||||||
// get credentials will trigger a credentials refresh.
|
|
||||||
if r.IsErrorExpired() {
|
|
||||||
r.Config.Credentials.Expire()
|
|
||||||
}
|
|
||||||
|
|
||||||
r.RetryCount++
|
|
||||||
r.Error = nil
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
// ValidateEndpointHandler is a request handler to validate a request had the
|
|
||||||
// appropriate Region and Endpoint set. Will set r.Error if the endpoint or
|
|
||||||
// region is not valid.
|
|
||||||
var ValidateEndpointHandler = request.NamedHandler{Name: "core.ValidateEndpointHandler", Fn: func(r *request.Request) {
|
|
||||||
if r.ClientInfo.SigningRegion == "" && aws.StringValue(r.Config.Region) == "" {
|
|
||||||
r.Error = aws.ErrMissingRegion
|
|
||||||
} else if r.ClientInfo.Endpoint == "" {
|
|
||||||
r.Error = aws.ErrMissingEndpoint
|
|
||||||
}
|
|
||||||
}}
|
|
17
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
generated
vendored
17
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/param_validator.go
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
package corehandlers
|
|
||||||
|
|
||||||
import "github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
|
|
||||||
// ValidateParametersHandler is a request handler to validate the input parameters.
|
|
||||||
// Validating parameters only has meaning if done prior to the request being sent.
|
|
||||||
var ValidateParametersHandler = request.NamedHandler{Name: "core.ValidateParametersHandler", Fn: func(r *request.Request) {
|
|
||||||
if !r.ParamsFilled() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := r.Params.(request.Validator); ok {
|
|
||||||
if err := v.Validate(); err != nil {
|
|
||||||
r.Error = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
37
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go
generated
vendored
37
vendor/github.com/aws/aws-sdk-go/aws/corehandlers/user_agent.go
generated
vendored
@ -1,37 +0,0 @@
|
|||||||
package corehandlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SDKVersionUserAgentHandler is a request handler for adding the SDK Version
|
|
||||||
// to the user agent.
|
|
||||||
var SDKVersionUserAgentHandler = request.NamedHandler{
|
|
||||||
Name: "core.SDKVersionUserAgentHandler",
|
|
||||||
Fn: request.MakeAddToUserAgentHandler(aws.SDKName, aws.SDKVersion,
|
|
||||||
runtime.Version(), runtime.GOOS, runtime.GOARCH),
|
|
||||||
}
|
|
||||||
|
|
||||||
const execEnvVar = `AWS_EXECUTION_ENV`
|
|
||||||
const execEnvUAKey = `exec_env`
|
|
||||||
|
|
||||||
// AddHostExecEnvUserAgentHander is a request handler appending the SDK's
|
|
||||||
// execution environment to the user agent.
|
|
||||||
//
|
|
||||||
// If the environment variable AWS_EXECUTION_ENV is set, its value will be
|
|
||||||
// appended to the user agent string.
|
|
||||||
var AddHostExecEnvUserAgentHander = request.NamedHandler{
|
|
||||||
Name: "core.AddHostExecEnvUserAgentHander",
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
v := os.Getenv(execEnvVar)
|
|
||||||
if len(v) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
request.AddToUserAgent(r, execEnvUAKey+"/"+v)
|
|
||||||
},
|
|
||||||
}
|
|
100
vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
100
vendor/github.com/aws/aws-sdk-go/aws/credentials/chain_provider.go
generated
vendored
@ -1,100 +0,0 @@
|
|||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrNoValidProvidersFoundInChain Is returned when there are no valid
|
|
||||||
// providers in the ChainProvider.
|
|
||||||
//
|
|
||||||
// This has been deprecated. For verbose error messaging set
|
|
||||||
// aws.Config.CredentialsChainVerboseErrors to true.
|
|
||||||
ErrNoValidProvidersFoundInChain = awserr.New("NoCredentialProviders",
|
|
||||||
`no valid providers in chain. Deprecated.
|
|
||||||
For verbose messaging see aws.Config.CredentialsChainVerboseErrors`,
|
|
||||||
nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// A ChainProvider will search for a provider which returns credentials
|
|
||||||
// and cache that provider until Retrieve is called again.
|
|
||||||
//
|
|
||||||
// The ChainProvider provides a way of chaining multiple providers together
|
|
||||||
// which will pick the first available using priority order of the Providers
|
|
||||||
// in the list.
|
|
||||||
//
|
|
||||||
// If none of the Providers retrieve valid credentials Value, ChainProvider's
|
|
||||||
// Retrieve() will return the error ErrNoValidProvidersFoundInChain.
|
|
||||||
//
|
|
||||||
// If a Provider is found which returns valid credentials Value ChainProvider
|
|
||||||
// will cache that Provider for all calls to IsExpired(), until Retrieve is
|
|
||||||
// called again.
|
|
||||||
//
|
|
||||||
// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider.
|
|
||||||
// In this example EnvProvider will first check if any credentials are available
|
|
||||||
// via the environment variables. If there are none ChainProvider will check
|
|
||||||
// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider
|
|
||||||
// does not return any credentials ChainProvider will return the error
|
|
||||||
// ErrNoValidProvidersFoundInChain
|
|
||||||
//
|
|
||||||
// creds := credentials.NewChainCredentials(
|
|
||||||
// []credentials.Provider{
|
|
||||||
// &credentials.EnvProvider{},
|
|
||||||
// &ec2rolecreds.EC2RoleProvider{
|
|
||||||
// Client: ec2metadata.New(sess),
|
|
||||||
// },
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// // Usage of ChainCredentials with aws.Config
|
|
||||||
// svc := ec2.New(session.Must(session.NewSession(&aws.Config{
|
|
||||||
// Credentials: creds,
|
|
||||||
// })))
|
|
||||||
//
|
|
||||||
type ChainProvider struct {
|
|
||||||
Providers []Provider
|
|
||||||
curr Provider
|
|
||||||
VerboseErrors bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewChainCredentials returns a pointer to a new Credentials object
|
|
||||||
// wrapping a chain of providers.
|
|
||||||
func NewChainCredentials(providers []Provider) *Credentials {
|
|
||||||
return NewCredentials(&ChainProvider{
|
|
||||||
Providers: append([]Provider{}, providers...),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve returns the credentials value or error if no provider returned
|
|
||||||
// without error.
|
|
||||||
//
|
|
||||||
// If a provider is found it will be cached and any calls to IsExpired()
|
|
||||||
// will return the expired state of the cached provider.
|
|
||||||
func (c *ChainProvider) Retrieve() (Value, error) {
|
|
||||||
var errs []error
|
|
||||||
for _, p := range c.Providers {
|
|
||||||
creds, err := p.Retrieve()
|
|
||||||
if err == nil {
|
|
||||||
c.curr = p
|
|
||||||
return creds, nil
|
|
||||||
}
|
|
||||||
errs = append(errs, err)
|
|
||||||
}
|
|
||||||
c.curr = nil
|
|
||||||
|
|
||||||
var err error
|
|
||||||
err = ErrNoValidProvidersFoundInChain
|
|
||||||
if c.VerboseErrors {
|
|
||||||
err = awserr.NewBatchError("NoCredentialProviders", "no valid providers in chain", errs)
|
|
||||||
}
|
|
||||||
return Value{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired will returned the expired state of the currently cached provider
|
|
||||||
// if there is one. If there is no current provider, true will be returned.
|
|
||||||
func (c *ChainProvider) IsExpired() bool {
|
|
||||||
if c.curr != nil {
|
|
||||||
return c.curr.IsExpired()
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
257
vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
257
vendor/github.com/aws/aws-sdk-go/aws/credentials/credentials.go
generated
vendored
@ -1,257 +0,0 @@
|
|||||||
// Package credentials provides credential retrieval and management
|
|
||||||
//
|
|
||||||
// The Credentials is the primary method of getting access to and managing
|
|
||||||
// credentials Values. Using dependency injection retrieval of the credential
|
|
||||||
// values is handled by a object which satisfies the Provider interface.
|
|
||||||
//
|
|
||||||
// By default the Credentials.Get() will cache the successful result of a
|
|
||||||
// Provider's Retrieve() until Provider.IsExpired() returns true. At which
|
|
||||||
// point Credentials will call Provider's Retrieve() to get new credential Value.
|
|
||||||
//
|
|
||||||
// The Provider is responsible for determining when credentials Value have expired.
|
|
||||||
// It is also important to note that Credentials will always call Retrieve the
|
|
||||||
// first time Credentials.Get() is called.
|
|
||||||
//
|
|
||||||
// Example of using the environment variable credentials.
|
|
||||||
//
|
|
||||||
// creds := credentials.NewEnvCredentials()
|
|
||||||
//
|
|
||||||
// // Retrieve the credentials value
|
|
||||||
// credValue, err := creds.Get()
|
|
||||||
// if err != nil {
|
|
||||||
// // handle error
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Example of forcing credentials to expire and be refreshed on the next Get().
|
|
||||||
// This may be helpful to proactively expire credentials and refresh them sooner
|
|
||||||
// than they would naturally expire on their own.
|
|
||||||
//
|
|
||||||
// creds := credentials.NewCredentials(&ec2rolecreds.EC2RoleProvider{})
|
|
||||||
// creds.Expire()
|
|
||||||
// credsValue, err := creds.Get()
|
|
||||||
// // New credentials will be retrieved instead of from cache.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Custom Provider
|
|
||||||
//
|
|
||||||
// Each Provider built into this package also provides a helper method to generate
|
|
||||||
// a Credentials pointer setup with the provider. To use a custom Provider just
|
|
||||||
// create a type which satisfies the Provider interface and pass it to the
|
|
||||||
// NewCredentials method.
|
|
||||||
//
|
|
||||||
// type MyProvider struct{}
|
|
||||||
// func (m *MyProvider) Retrieve() (Value, error) {...}
|
|
||||||
// func (m *MyProvider) IsExpired() bool {...}
|
|
||||||
//
|
|
||||||
// creds := credentials.NewCredentials(&MyProvider{})
|
|
||||||
// credValue, err := creds.Get()
|
|
||||||
//
|
|
||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// AnonymousCredentials is an empty Credential object that can be used as
|
|
||||||
// dummy placeholder credentials for requests that do not need signed.
|
|
||||||
//
|
|
||||||
// This Credentials can be used to configure a service to not sign requests
|
|
||||||
// when making service API calls. For example, when accessing public
|
|
||||||
// s3 buckets.
|
|
||||||
//
|
|
||||||
// svc := s3.New(session.Must(session.NewSession(&aws.Config{
|
|
||||||
// Credentials: credentials.AnonymousCredentials,
|
|
||||||
// })))
|
|
||||||
// // Access public S3 buckets.
|
|
||||||
var AnonymousCredentials = NewStaticCredentials("", "", "")
|
|
||||||
|
|
||||||
// A Value is the AWS credentials value for individual credential fields.
|
|
||||||
type Value struct {
|
|
||||||
// AWS Access key ID
|
|
||||||
AccessKeyID string
|
|
||||||
|
|
||||||
// AWS Secret Access Key
|
|
||||||
SecretAccessKey string
|
|
||||||
|
|
||||||
// AWS Session Token
|
|
||||||
SessionToken string
|
|
||||||
|
|
||||||
// Provider used to get credentials
|
|
||||||
ProviderName string
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Provider is the interface for any component which will provide credentials
|
|
||||||
// Value. A provider is required to manage its own Expired state, and what to
|
|
||||||
// be expired means.
|
|
||||||
//
|
|
||||||
// The Provider should not need to implement its own mutexes, because
|
|
||||||
// that will be managed by Credentials.
|
|
||||||
type Provider interface {
|
|
||||||
// Retrieve returns nil if it successfully retrieved the value.
|
|
||||||
// Error is returned if the value were not obtainable, or empty.
|
|
||||||
Retrieve() (Value, error)
|
|
||||||
|
|
||||||
// IsExpired returns if the credentials are no longer valid, and need
|
|
||||||
// to be retrieved.
|
|
||||||
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.
|
|
||||||
//
|
|
||||||
// The best method to use this struct is as an anonymous field within the
|
|
||||||
// provider's struct.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// type EC2RoleProvider struct {
|
|
||||||
// Expiry
|
|
||||||
// ...
|
|
||||||
// }
|
|
||||||
type Expiry struct {
|
|
||||||
// The date/time when to expire on
|
|
||||||
expiration time.Time
|
|
||||||
|
|
||||||
// If set will be used by IsExpired to determine the current time.
|
|
||||||
// Defaults to time.Now if CurrentTime is not set. Available for testing
|
|
||||||
// to be able to mock out the current time.
|
|
||||||
CurrentTime func() time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetExpiration sets the expiration IsExpired will check when called.
|
|
||||||
//
|
|
||||||
// If window is greater than 0 the expiration time will be reduced by the
|
|
||||||
// window value.
|
|
||||||
//
|
|
||||||
// Using a window is helpful to trigger credentials to expire sooner than
|
|
||||||
// the expiration time given to ensure no requests are made with expired
|
|
||||||
// tokens.
|
|
||||||
func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) {
|
|
||||||
e.expiration = expiration
|
|
||||||
if window > 0 {
|
|
||||||
e.expiration = e.expiration.Add(-window)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns if the credentials are expired.
|
|
||||||
func (e *Expiry) IsExpired() bool {
|
|
||||||
curTime := e.CurrentTime
|
|
||||||
if curTime == nil {
|
|
||||||
curTime = time.Now
|
|
||||||
}
|
|
||||||
return e.expiration.Before(curTime())
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Credentials provides concurrency safe retrieval of AWS credentials Value.
|
|
||||||
// Credentials will cache the credentials value until they expire. Once the value
|
|
||||||
// expires the next Get will attempt to retrieve valid credentials.
|
|
||||||
//
|
|
||||||
// Credentials is safe to use across multiple goroutines and will manage the
|
|
||||||
// synchronous state so the Providers do not need to implement their own
|
|
||||||
// synchronization.
|
|
||||||
//
|
|
||||||
// The first Credentials.Get() will always call Provider.Retrieve() to get the
|
|
||||||
// first instance of the credentials Value. All calls to Get() after that
|
|
||||||
// will return the cached credentials Value until IsExpired() returns true.
|
|
||||||
type Credentials struct {
|
|
||||||
creds Value
|
|
||||||
forceRefresh bool
|
|
||||||
|
|
||||||
m sync.RWMutex
|
|
||||||
|
|
||||||
provider Provider
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentials returns a pointer to a new Credentials with the provider set.
|
|
||||||
func NewCredentials(provider Provider) *Credentials {
|
|
||||||
return &Credentials{
|
|
||||||
provider: provider,
|
|
||||||
forceRefresh: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the credentials value, or error if the credentials Value failed
|
|
||||||
// to be retrieved.
|
|
||||||
//
|
|
||||||
// Will return the cached credentials Value if it has not expired. If the
|
|
||||||
// credentials Value has expired the Provider's Retrieve() will be called
|
|
||||||
// to refresh the credentials.
|
|
||||||
//
|
|
||||||
// If Credentials.Expire() was called the credentials Value will be force
|
|
||||||
// expired, and the next call to Get() will cause them to be refreshed.
|
|
||||||
func (c *Credentials) Get() (Value, error) {
|
|
||||||
// Check the cached credentials first with just the read lock.
|
|
||||||
c.m.RLock()
|
|
||||||
if !c.isExpired() {
|
|
||||||
creds := c.creds
|
|
||||||
c.m.RUnlock()
|
|
||||||
return creds, nil
|
|
||||||
}
|
|
||||||
c.m.RUnlock()
|
|
||||||
|
|
||||||
// Credentials are expired need to retrieve the credentials taking the full
|
|
||||||
// lock.
|
|
||||||
c.m.Lock()
|
|
||||||
defer c.m.Unlock()
|
|
||||||
|
|
||||||
if c.isExpired() {
|
|
||||||
creds, err := c.provider.Retrieve()
|
|
||||||
if err != nil {
|
|
||||||
return Value{}, err
|
|
||||||
}
|
|
||||||
c.creds = creds
|
|
||||||
c.forceRefresh = false
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.creds, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expire expires the credentials and forces them to be retrieved on the
|
|
||||||
// next call to Get().
|
|
||||||
//
|
|
||||||
// This will override the Provider's expired state, and force Credentials
|
|
||||||
// to call the Provider's Retrieve().
|
|
||||||
func (c *Credentials) Expire() {
|
|
||||||
c.m.Lock()
|
|
||||||
defer c.m.Unlock()
|
|
||||||
|
|
||||||
c.forceRefresh = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns if the credentials are no longer valid, and need
|
|
||||||
// to be retrieved.
|
|
||||||
//
|
|
||||||
// If the Credentials were forced to be expired with Expire() this will
|
|
||||||
// reflect that override.
|
|
||||||
func (c *Credentials) IsExpired() bool {
|
|
||||||
c.m.RLock()
|
|
||||||
defer c.m.RUnlock()
|
|
||||||
|
|
||||||
return c.isExpired()
|
|
||||||
}
|
|
||||||
|
|
||||||
// isExpired helper method wrapping the definition of expired credentials.
|
|
||||||
func (c *Credentials) isExpired() bool {
|
|
||||||
return c.forceRefresh || c.provider.IsExpired()
|
|
||||||
}
|
|
178
vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
generated
vendored
178
vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go
generated
vendored
@ -1,178 +0,0 @@
|
|||||||
package ec2rolecreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"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/aws/ec2metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkuri"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProviderName provides a name of EC2Role provider
|
|
||||||
const ProviderName = "EC2RoleProvider"
|
|
||||||
|
|
||||||
// A EC2RoleProvider retrieves credentials from the EC2 service, and keeps track if
|
|
||||||
// those credentials are expired.
|
|
||||||
//
|
|
||||||
// Example how to configure the EC2RoleProvider with custom http Client, Endpoint
|
|
||||||
// or ExpiryWindow
|
|
||||||
//
|
|
||||||
// p := &ec2rolecreds.EC2RoleProvider{
|
|
||||||
// // Pass in a custom timeout to be used when requesting
|
|
||||||
// // IAM EC2 Role credentials.
|
|
||||||
// Client: ec2metadata.New(sess, aws.Config{
|
|
||||||
// HTTPClient: &http.Client{Timeout: 10 * time.Second},
|
|
||||||
// }),
|
|
||||||
//
|
|
||||||
// // Do not use early expiry of credentials. If a non zero value is
|
|
||||||
// // specified the credentials will be expired early
|
|
||||||
// ExpiryWindow: 0,
|
|
||||||
// }
|
|
||||||
type EC2RoleProvider struct {
|
|
||||||
credentials.Expiry
|
|
||||||
|
|
||||||
// Required EC2Metadata client to use when connecting to EC2 metadata service.
|
|
||||||
Client *ec2metadata.EC2Metadata
|
|
||||||
|
|
||||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
|
||||||
// the credentials actually expiring. This is beneficial so race conditions
|
|
||||||
// with expiring credentials do not cause request to fail unexpectedly
|
|
||||||
// due to ExpiredTokenException exceptions.
|
|
||||||
//
|
|
||||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
|
||||||
// 10 seconds before the credentials are actually expired.
|
|
||||||
//
|
|
||||||
// If ExpiryWindow is 0 or less it will be ignored.
|
|
||||||
ExpiryWindow time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentials returns a pointer to a new Credentials object wrapping
|
|
||||||
// the EC2RoleProvider. Takes a ConfigProvider to create a EC2Metadata client.
|
|
||||||
// The ConfigProvider is satisfied by the session.Session type.
|
|
||||||
func NewCredentials(c client.ConfigProvider, options ...func(*EC2RoleProvider)) *credentials.Credentials {
|
|
||||||
p := &EC2RoleProvider{
|
|
||||||
Client: ec2metadata.New(c),
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping
|
|
||||||
// the EC2RoleProvider. Takes a EC2Metadata client to use when connecting to EC2
|
|
||||||
// metadata service.
|
|
||||||
func NewCredentialsWithClient(client *ec2metadata.EC2Metadata, options ...func(*EC2RoleProvider)) *credentials.Credentials {
|
|
||||||
p := &EC2RoleProvider{
|
|
||||||
Client: client,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve retrieves credentials from the EC2 service.
|
|
||||||
// Error will be returned if the request fails, or unable to extract
|
|
||||||
// the desired credentials.
|
|
||||||
func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) {
|
|
||||||
credsList, err := requestCredList(m.Client)
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(credsList) == 0 {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, awserr.New("EmptyEC2RoleList", "empty EC2 Role list", nil)
|
|
||||||
}
|
|
||||||
credsName := credsList[0]
|
|
||||||
|
|
||||||
roleCreds, err := requestCred(m.Client, credsName)
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
m.SetExpiration(roleCreds.Expiration, m.ExpiryWindow)
|
|
||||||
|
|
||||||
return credentials.Value{
|
|
||||||
AccessKeyID: roleCreds.AccessKeyID,
|
|
||||||
SecretAccessKey: roleCreds.SecretAccessKey,
|
|
||||||
SessionToken: roleCreds.Token,
|
|
||||||
ProviderName: ProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// A ec2RoleCredRespBody provides the shape for unmarshaling credential
|
|
||||||
// request responses.
|
|
||||||
type ec2RoleCredRespBody struct {
|
|
||||||
// Success State
|
|
||||||
Expiration time.Time
|
|
||||||
AccessKeyID string
|
|
||||||
SecretAccessKey string
|
|
||||||
Token string
|
|
||||||
|
|
||||||
// Error state
|
|
||||||
Code string
|
|
||||||
Message string
|
|
||||||
}
|
|
||||||
|
|
||||||
const iamSecurityCredsPath = "iam/security-credentials/"
|
|
||||||
|
|
||||||
// requestCredList requests a list of credentials from the EC2 service.
|
|
||||||
// If there are no credentials, or there is an error making or receiving the request
|
|
||||||
func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) {
|
|
||||||
resp, err := client.GetMetadata(iamSecurityCredsPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, awserr.New("EC2RoleRequestError", "no EC2 instance role found", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
credsList := []string{}
|
|
||||||
s := bufio.NewScanner(strings.NewReader(resp))
|
|
||||||
for s.Scan() {
|
|
||||||
credsList = append(credsList, s.Text())
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.Err(); err != nil {
|
|
||||||
return nil, awserr.New("SerializationError", "failed to read EC2 instance role from metadata service", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credsList, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// requestCred requests the credentials for a specific credentials from the EC2 service.
|
|
||||||
//
|
|
||||||
// If the credentials cannot be found, or there is an error reading the response
|
|
||||||
// and error will be returned.
|
|
||||||
func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) {
|
|
||||||
resp, err := client.GetMetadata(sdkuri.PathJoin(iamSecurityCredsPath, credsName))
|
|
||||||
if err != nil {
|
|
||||||
return ec2RoleCredRespBody{},
|
|
||||||
awserr.New("EC2RoleRequestError",
|
|
||||||
fmt.Sprintf("failed to get %s EC2 instance role credentials", credsName),
|
|
||||||
err)
|
|
||||||
}
|
|
||||||
|
|
||||||
respCreds := ec2RoleCredRespBody{}
|
|
||||||
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil {
|
|
||||||
return ec2RoleCredRespBody{},
|
|
||||||
awserr.New("SerializationError",
|
|
||||||
fmt.Sprintf("failed to decode %s EC2 instance role credentials", credsName),
|
|
||||||
err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if respCreds.Code != "Success" {
|
|
||||||
// If an error code was returned something failed requesting the role.
|
|
||||||
return ec2RoleCredRespBody{}, awserr.New(respCreds.Code, respCreds.Message, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return respCreds, nil
|
|
||||||
}
|
|
198
vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go
generated
vendored
198
vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go
generated
vendored
@ -1,198 +0,0 @@
|
|||||||
// Package endpointcreds provides support for retrieving credentials from an
|
|
||||||
// arbitrary HTTP endpoint.
|
|
||||||
//
|
|
||||||
// The credentials endpoint Provider can receive both static and refreshable
|
|
||||||
// credentials that will expire. Credentials are static when an "Expiration"
|
|
||||||
// value is not provided in the endpoint's response.
|
|
||||||
//
|
|
||||||
// Static credentials will never expire once they have been retrieved. The format
|
|
||||||
// of the static credentials response:
|
|
||||||
// {
|
|
||||||
// "AccessKeyId" : "MUA...",
|
|
||||||
// "SecretAccessKey" : "/7PC5om....",
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration
|
|
||||||
// value in the response. The format of the refreshable credentials response:
|
|
||||||
// {
|
|
||||||
// "AccessKeyId" : "MUA...",
|
|
||||||
// "SecretAccessKey" : "/7PC5om....",
|
|
||||||
// "Token" : "AQoDY....=",
|
|
||||||
// "Expiration" : "2016-02-25T06:03:31Z"
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Errors should be returned in the following format and only returned with 400
|
|
||||||
// or 500 HTTP status codes.
|
|
||||||
// {
|
|
||||||
// "code": "ErrorCode",
|
|
||||||
// "message": "Helpful error message."
|
|
||||||
// }
|
|
||||||
package endpointcreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProviderName is the name of the credentials provider.
|
|
||||||
const ProviderName = `CredentialsEndpointProvider`
|
|
||||||
|
|
||||||
// Provider satisfies the credentials.Provider interface, and is a client to
|
|
||||||
// retrieve credentials from an arbitrary endpoint.
|
|
||||||
type Provider struct {
|
|
||||||
staticCreds bool
|
|
||||||
credentials.Expiry
|
|
||||||
|
|
||||||
// Requires a AWS Client to make HTTP requests to the endpoint with.
|
|
||||||
// the Endpoint the request will be made to is provided by the aws.Config's
|
|
||||||
// Endpoint value.
|
|
||||||
Client *client.Client
|
|
||||||
|
|
||||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
|
||||||
// the credentials actually expiring. This is beneficial so race conditions
|
|
||||||
// with expiring credentials do not cause request to fail unexpectedly
|
|
||||||
// due to ExpiredTokenException exceptions.
|
|
||||||
//
|
|
||||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
|
||||||
// 10 seconds before the credentials are actually expired.
|
|
||||||
//
|
|
||||||
// If ExpiryWindow is 0 or less it will be ignored.
|
|
||||||
ExpiryWindow time.Duration
|
|
||||||
|
|
||||||
// Optional authorization token value if set will be used as the value of
|
|
||||||
// the Authorization header of the endpoint credential request.
|
|
||||||
AuthorizationToken string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewProviderClient returns a credentials Provider for retrieving AWS credentials
|
|
||||||
// from arbitrary endpoint.
|
|
||||||
func NewProviderClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) credentials.Provider {
|
|
||||||
p := &Provider{
|
|
||||||
Client: client.New(
|
|
||||||
cfg,
|
|
||||||
metadata.ClientInfo{
|
|
||||||
ServiceName: "CredentialsEndpoint",
|
|
||||||
Endpoint: endpoint,
|
|
||||||
},
|
|
||||||
handlers,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Client.Handlers.Unmarshal.PushBack(unmarshalHandler)
|
|
||||||
p.Client.Handlers.UnmarshalError.PushBack(unmarshalError)
|
|
||||||
p.Client.Handlers.Validate.Clear()
|
|
||||||
p.Client.Handlers.Validate.PushBack(validateEndpointHandler)
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentialsClient returns a Credentials wrapper for retrieving credentials
|
|
||||||
// from an arbitrary endpoint concurrently. The client will request the
|
|
||||||
func NewCredentialsClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) *credentials.Credentials {
|
|
||||||
return credentials.NewCredentials(NewProviderClient(cfg, handlers, endpoint, options...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns true if the credentials retrieved are expired, or not yet
|
|
||||||
// retrieved.
|
|
||||||
func (p *Provider) IsExpired() bool {
|
|
||||||
if p.staticCreds {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return p.Expiry.IsExpired()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve will attempt to request the credentials from the endpoint the Provider
|
|
||||||
// was configured for. And error will be returned if the retrieval fails.
|
|
||||||
func (p *Provider) Retrieve() (credentials.Value, error) {
|
|
||||||
resp, err := p.getCredentials()
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName},
|
|
||||||
awserr.New("CredentialsEndpointError", "failed to load credentials", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.Expiration != nil {
|
|
||||||
p.SetExpiration(*resp.Expiration, p.ExpiryWindow)
|
|
||||||
} else {
|
|
||||||
p.staticCreds = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.Value{
|
|
||||||
AccessKeyID: resp.AccessKeyID,
|
|
||||||
SecretAccessKey: resp.SecretAccessKey,
|
|
||||||
SessionToken: resp.Token,
|
|
||||||
ProviderName: ProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type getCredentialsOutput struct {
|
|
||||||
Expiration *time.Time
|
|
||||||
AccessKeyID string
|
|
||||||
SecretAccessKey string
|
|
||||||
Token string
|
|
||||||
}
|
|
||||||
|
|
||||||
type errorOutput struct {
|
|
||||||
Code string `json:"code"`
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Provider) getCredentials() (*getCredentialsOutput, error) {
|
|
||||||
op := &request.Operation{
|
|
||||||
Name: "GetCredentials",
|
|
||||||
HTTPMethod: "GET",
|
|
||||||
}
|
|
||||||
|
|
||||||
out := &getCredentialsOutput{}
|
|
||||||
req := p.Client.NewRequest(op, nil, out)
|
|
||||||
req.HTTPRequest.Header.Set("Accept", "application/json")
|
|
||||||
if authToken := p.AuthorizationToken; len(authToken) != 0 {
|
|
||||||
req.HTTPRequest.Header.Set("Authorization", authToken)
|
|
||||||
}
|
|
||||||
|
|
||||||
return out, req.Send()
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateEndpointHandler(r *request.Request) {
|
|
||||||
if len(r.ClientInfo.Endpoint) == 0 {
|
|
||||||
r.Error = aws.ErrMissingEndpoint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalHandler(r *request.Request) {
|
|
||||||
defer r.HTTPResponse.Body.Close()
|
|
||||||
|
|
||||||
out := r.Data.(*getCredentialsOutput)
|
|
||||||
if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil {
|
|
||||||
r.Error = awserr.New("SerializationError",
|
|
||||||
"failed to decode endpoint credentials",
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalError(r *request.Request) {
|
|
||||||
defer r.HTTPResponse.Body.Close()
|
|
||||||
|
|
||||||
var errOut errorOutput
|
|
||||||
if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&errOut); err != nil {
|
|
||||||
r.Error = awserr.New("SerializationError",
|
|
||||||
"failed to decode endpoint credentials",
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response body format is not consistent between metadata endpoints.
|
|
||||||
// Grab the error message as a string and include that as the source error
|
|
||||||
r.Error = awserr.New(errOut.Code, errOut.Message, nil)
|
|
||||||
}
|
|
74
vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
74
vendor/github.com/aws/aws-sdk-go/aws/credentials/env_provider.go
generated
vendored
@ -1,74 +0,0 @@
|
|||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// EnvProviderName provides a name of Env provider
|
|
||||||
const EnvProviderName = "EnvProvider"
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrAccessKeyIDNotFound is returned when the AWS Access Key ID can't be
|
|
||||||
// found in the process's environment.
|
|
||||||
ErrAccessKeyIDNotFound = awserr.New("EnvAccessKeyNotFound", "AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY not found in environment", nil)
|
|
||||||
|
|
||||||
// ErrSecretAccessKeyNotFound is returned when the AWS Secret Access Key
|
|
||||||
// can't be found in the process's environment.
|
|
||||||
ErrSecretAccessKeyNotFound = awserr.New("EnvSecretNotFound", "AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY not found in environment", nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// A EnvProvider retrieves credentials from the environment variables of the
|
|
||||||
// running process. Environment credentials never expire.
|
|
||||||
//
|
|
||||||
// Environment variables used:
|
|
||||||
//
|
|
||||||
// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY
|
|
||||||
//
|
|
||||||
// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
|
|
||||||
type EnvProvider struct {
|
|
||||||
retrieved bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEnvCredentials returns a pointer to a new Credentials object
|
|
||||||
// wrapping the environment variable provider.
|
|
||||||
func NewEnvCredentials() *Credentials {
|
|
||||||
return NewCredentials(&EnvProvider{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve retrieves the keys from the environment.
|
|
||||||
func (e *EnvProvider) Retrieve() (Value, error) {
|
|
||||||
e.retrieved = false
|
|
||||||
|
|
||||||
id := os.Getenv("AWS_ACCESS_KEY_ID")
|
|
||||||
if id == "" {
|
|
||||||
id = os.Getenv("AWS_ACCESS_KEY")
|
|
||||||
}
|
|
||||||
|
|
||||||
secret := os.Getenv("AWS_SECRET_ACCESS_KEY")
|
|
||||||
if secret == "" {
|
|
||||||
secret = os.Getenv("AWS_SECRET_KEY")
|
|
||||||
}
|
|
||||||
|
|
||||||
if id == "" {
|
|
||||||
return Value{ProviderName: EnvProviderName}, ErrAccessKeyIDNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
if secret == "" {
|
|
||||||
return Value{ProviderName: EnvProviderName}, ErrSecretAccessKeyNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
e.retrieved = true
|
|
||||||
return Value{
|
|
||||||
AccessKeyID: id,
|
|
||||||
SecretAccessKey: secret,
|
|
||||||
SessionToken: os.Getenv("AWS_SESSION_TOKEN"),
|
|
||||||
ProviderName: EnvProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns if the credentials have been retrieved.
|
|
||||||
func (e *EnvProvider) IsExpired() bool {
|
|
||||||
return !e.retrieved
|
|
||||||
}
|
|
12
vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini
generated
vendored
12
vendor/github.com/aws/aws-sdk-go/aws/credentials/example.ini
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
[default]
|
|
||||||
aws_access_key_id = accessKey
|
|
||||||
aws_secret_access_key = secret
|
|
||||||
aws_session_token = token
|
|
||||||
|
|
||||||
[no_token]
|
|
||||||
aws_access_key_id = accessKey
|
|
||||||
aws_secret_access_key = secret
|
|
||||||
|
|
||||||
[with_colon]
|
|
||||||
aws_access_key_id: accessKey
|
|
||||||
aws_secret_access_key: secret
|
|
150
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
150
vendor/github.com/aws/aws-sdk-go/aws/credentials/shared_credentials_provider.go
generated
vendored
@ -1,150 +0,0 @@
|
|||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/ini"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SharedCredsProviderName provides a name of SharedCreds provider
|
|
||||||
const SharedCredsProviderName = "SharedCredentialsProvider"
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrSharedCredentialsHomeNotFound is emitted when the user directory cannot be found.
|
|
||||||
ErrSharedCredentialsHomeNotFound = awserr.New("UserHomeNotFound", "user home directory not found.", nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// A SharedCredentialsProvider retrieves credentials from the current user's home
|
|
||||||
// directory, and keeps track if those credentials are expired.
|
|
||||||
//
|
|
||||||
// Profile ini file example: $HOME/.aws/credentials
|
|
||||||
type SharedCredentialsProvider struct {
|
|
||||||
// Path to the shared credentials file.
|
|
||||||
//
|
|
||||||
// If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the
|
|
||||||
// env value is empty will default to current user's home directory.
|
|
||||||
// Linux/OSX: "$HOME/.aws/credentials"
|
|
||||||
// Windows: "%USERPROFILE%\.aws\credentials"
|
|
||||||
Filename string
|
|
||||||
|
|
||||||
// AWS Profile to extract credentials from the shared credentials file. If empty
|
|
||||||
// will default to environment variable "AWS_PROFILE" or "default" if
|
|
||||||
// environment variable is also not set.
|
|
||||||
Profile string
|
|
||||||
|
|
||||||
// retrieved states if the credentials have been successfully retrieved.
|
|
||||||
retrieved bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSharedCredentials returns a pointer to a new Credentials object
|
|
||||||
// wrapping the Profile file provider.
|
|
||||||
func NewSharedCredentials(filename, profile string) *Credentials {
|
|
||||||
return NewCredentials(&SharedCredentialsProvider{
|
|
||||||
Filename: filename,
|
|
||||||
Profile: profile,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve reads and extracts the shared credentials from the current
|
|
||||||
// users home directory.
|
|
||||||
func (p *SharedCredentialsProvider) Retrieve() (Value, error) {
|
|
||||||
p.retrieved = false
|
|
||||||
|
|
||||||
filename, err := p.filename()
|
|
||||||
if err != nil {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
creds, err := loadProfile(filename, p.profile())
|
|
||||||
if err != nil {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
p.retrieved = true
|
|
||||||
return creds, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns if the shared credentials have expired.
|
|
||||||
func (p *SharedCredentialsProvider) IsExpired() bool {
|
|
||||||
return !p.retrieved
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadProfiles loads from the file pointed to by shared credentials filename for profile.
|
|
||||||
// The credentials retrieved from the profile will be returned or error. Error will be
|
|
||||||
// returned if it fails to read from the file, or the data is invalid.
|
|
||||||
func loadProfile(filename, profile string) (Value, error) {
|
|
||||||
config, err := ini.OpenFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to load shared credentials file", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
iniProfile, ok := config.GetSection(profile)
|
|
||||||
if !ok {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsLoad", "failed to get profile", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
id := iniProfile.String("aws_access_key_id")
|
|
||||||
if len(id) == 0 {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsAccessKey",
|
|
||||||
fmt.Sprintf("shared credentials %s in %s did not contain aws_access_key_id", profile, filename),
|
|
||||||
nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
secret := iniProfile.String("aws_secret_access_key")
|
|
||||||
if len(secret) == 0 {
|
|
||||||
return Value{ProviderName: SharedCredsProviderName}, awserr.New("SharedCredsSecret",
|
|
||||||
fmt.Sprintf("shared credentials %s in %s did not contain aws_secret_access_key", profile, filename),
|
|
||||||
nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default to empty string if not found
|
|
||||||
token := iniProfile.String("aws_session_token")
|
|
||||||
|
|
||||||
return Value{
|
|
||||||
AccessKeyID: id,
|
|
||||||
SecretAccessKey: secret,
|
|
||||||
SessionToken: token,
|
|
||||||
ProviderName: SharedCredsProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// filename returns the filename to use to read AWS shared credentials.
|
|
||||||
//
|
|
||||||
// Will return an error if the user's home directory path cannot be found.
|
|
||||||
func (p *SharedCredentialsProvider) filename() (string, error) {
|
|
||||||
if len(p.Filename) != 0 {
|
|
||||||
return p.Filename, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(p.Filename) != 0 {
|
|
||||||
return p.Filename, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if home := shareddefaults.UserHomeDir(); len(home) == 0 {
|
|
||||||
// Backwards compatibility of home directly not found error being returned.
|
|
||||||
// This error is too verbose, failure when opening the file would of been
|
|
||||||
// a better error to return.
|
|
||||||
return "", ErrSharedCredentialsHomeNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
p.Filename = shareddefaults.SharedCredentialsFilename()
|
|
||||||
|
|
||||||
return p.Filename, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// profile returns the AWS shared credentials profile. If empty will read
|
|
||||||
// environment variable "AWS_PROFILE". If that is not set profile will
|
|
||||||
// return "default".
|
|
||||||
func (p *SharedCredentialsProvider) profile() string {
|
|
||||||
if p.Profile == "" {
|
|
||||||
p.Profile = os.Getenv("AWS_PROFILE")
|
|
||||||
}
|
|
||||||
if p.Profile == "" {
|
|
||||||
p.Profile = "default"
|
|
||||||
}
|
|
||||||
|
|
||||||
return p.Profile
|
|
||||||
}
|
|
55
vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
55
vendor/github.com/aws/aws-sdk-go/aws/credentials/static_provider.go
generated
vendored
@ -1,55 +0,0 @@
|
|||||||
package credentials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StaticProviderName provides a name of Static provider
|
|
||||||
const StaticProviderName = "StaticProvider"
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrStaticCredentialsEmpty is emitted when static credentials are empty.
|
|
||||||
ErrStaticCredentialsEmpty = awserr.New("EmptyStaticCreds", "static credentials are empty", nil)
|
|
||||||
)
|
|
||||||
|
|
||||||
// A StaticProvider is a set of credentials which are set programmatically,
|
|
||||||
// and will never expire.
|
|
||||||
type StaticProvider struct {
|
|
||||||
Value
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewStaticCredentials returns a pointer to a new Credentials object
|
|
||||||
// wrapping a static credentials value provider.
|
|
||||||
func NewStaticCredentials(id, secret, token string) *Credentials {
|
|
||||||
return NewCredentials(&StaticProvider{Value: Value{
|
|
||||||
AccessKeyID: id,
|
|
||||||
SecretAccessKey: secret,
|
|
||||||
SessionToken: token,
|
|
||||||
}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewStaticCredentialsFromCreds returns a pointer to a new Credentials object
|
|
||||||
// wrapping the static credentials value provide. Same as NewStaticCredentials
|
|
||||||
// but takes the creds Value instead of individual fields
|
|
||||||
func NewStaticCredentialsFromCreds(creds Value) *Credentials {
|
|
||||||
return NewCredentials(&StaticProvider{Value: creds})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve returns the credentials or error if the credentials are invalid.
|
|
||||||
func (s *StaticProvider) Retrieve() (Value, error) {
|
|
||||||
if s.AccessKeyID == "" || s.SecretAccessKey == "" {
|
|
||||||
return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(s.Value.ProviderName) == 0 {
|
|
||||||
s.Value.ProviderName = StaticProviderName
|
|
||||||
}
|
|
||||||
return s.Value, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsExpired returns if the credentials are expired.
|
|
||||||
//
|
|
||||||
// For StaticProvider, the credentials never expired.
|
|
||||||
func (s *StaticProvider) IsExpired() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
298
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
298
vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go
generated
vendored
@ -1,298 +0,0 @@
|
|||||||
/*
|
|
||||||
Package stscreds are credential Providers to retrieve STS AWS credentials.
|
|
||||||
|
|
||||||
STS provides multiple ways to retrieve credentials which can be used when making
|
|
||||||
future AWS service API operation calls.
|
|
||||||
|
|
||||||
The SDK will ensure that per instance of credentials.Credentials all requests
|
|
||||||
to refresh the credentials will be synchronized. But, the SDK is unable to
|
|
||||||
ensure synchronous usage of the AssumeRoleProvider if the value is shared
|
|
||||||
between multiple Credentials, Sessions or service clients.
|
|
||||||
|
|
||||||
Assume Role
|
|
||||||
|
|
||||||
To assume an IAM role using STS with the SDK you can create a new Credentials
|
|
||||||
with the SDKs's stscreds package.
|
|
||||||
|
|
||||||
// Initial credentials loaded from SDK's default credential chain. Such as
|
|
||||||
// the environment, shared credentials (~/.aws/credentials), or EC2 Instance
|
|
||||||
// Role. These credentials will be used to to make the STS Assume Role API.
|
|
||||||
sess := session.Must(session.NewSession())
|
|
||||||
|
|
||||||
// Create the credentials from AssumeRoleProvider to assume the role
|
|
||||||
// referenced by the "myRoleARN" ARN.
|
|
||||||
creds := stscreds.NewCredentials(sess, "myRoleArn")
|
|
||||||
|
|
||||||
// Create service client value configured for credentials
|
|
||||||
// from assumed role.
|
|
||||||
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
|
||||||
|
|
||||||
Assume Role with static MFA Token
|
|
||||||
|
|
||||||
To assume an IAM role with a MFA token you can either specify a MFA token code
|
|
||||||
directly or provide a function to prompt the user each time the credentials
|
|
||||||
need to refresh the role's credentials. Specifying the TokenCode should be used
|
|
||||||
for short lived operations that will not need to be refreshed, and when you do
|
|
||||||
not want to have direct control over the user provides their MFA token.
|
|
||||||
|
|
||||||
With TokenCode the AssumeRoleProvider will be not be able to refresh the role's
|
|
||||||
credentials.
|
|
||||||
|
|
||||||
// Create the credentials from AssumeRoleProvider to assume the role
|
|
||||||
// referenced by the "myRoleARN" ARN using the MFA token code provided.
|
|
||||||
creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) {
|
|
||||||
p.SerialNumber = aws.String("myTokenSerialNumber")
|
|
||||||
p.TokenCode = aws.String("00000000")
|
|
||||||
})
|
|
||||||
|
|
||||||
// Create service client value configured for credentials
|
|
||||||
// from assumed role.
|
|
||||||
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
|
||||||
|
|
||||||
Assume Role with MFA Token Provider
|
|
||||||
|
|
||||||
To assume an IAM role with MFA for longer running tasks where the credentials
|
|
||||||
may need to be refreshed setting the TokenProvider field of AssumeRoleProvider
|
|
||||||
will allow the credential provider to prompt for new MFA token code when the
|
|
||||||
role's credentials need to be refreshed.
|
|
||||||
|
|
||||||
The StdinTokenProvider function is available to prompt on stdin to retrieve
|
|
||||||
the MFA token code from the user. You can also implement custom prompts by
|
|
||||||
satisfing the TokenProvider function signature.
|
|
||||||
|
|
||||||
Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will
|
|
||||||
have undesirable results as the StdinTokenProvider will not be synchronized. A
|
|
||||||
single Credentials with an AssumeRoleProvider can be shared safely.
|
|
||||||
|
|
||||||
// Create the credentials from AssumeRoleProvider to assume the role
|
|
||||||
// referenced by the "myRoleARN" ARN. Prompting for MFA token from stdin.
|
|
||||||
creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) {
|
|
||||||
p.SerialNumber = aws.String("myTokenSerialNumber")
|
|
||||||
p.TokenProvider = stscreds.StdinTokenProvider
|
|
||||||
})
|
|
||||||
|
|
||||||
// Create service client value configured for credentials
|
|
||||||
// from assumed role.
|
|
||||||
svc := s3.New(sess, &aws.Config{Credentials: creds})
|
|
||||||
|
|
||||||
*/
|
|
||||||
package stscreds
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/service/sts"
|
|
||||||
)
|
|
||||||
|
|
||||||
// StdinTokenProvider will prompt on stdout and read from stdin for a string value.
|
|
||||||
// An error is returned if reading from stdin fails.
|
|
||||||
//
|
|
||||||
// Use this function go read MFA tokens from stdin. The function makes no attempt
|
|
||||||
// to make atomic prompts from stdin across multiple gorouties.
|
|
||||||
//
|
|
||||||
// Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will
|
|
||||||
// have undesirable results as the StdinTokenProvider will not be synchronized. A
|
|
||||||
// single Credentials with an AssumeRoleProvider can be shared safely
|
|
||||||
//
|
|
||||||
// Will wait forever until something is provided on the stdin.
|
|
||||||
func StdinTokenProvider() (string, error) {
|
|
||||||
var v string
|
|
||||||
fmt.Printf("Assume Role MFA token code: ")
|
|
||||||
_, err := fmt.Scanln(&v)
|
|
||||||
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProviderName provides a name of AssumeRole provider
|
|
||||||
const ProviderName = "AssumeRoleProvider"
|
|
||||||
|
|
||||||
// AssumeRoler represents the minimal subset of the STS client API used by this provider.
|
|
||||||
type AssumeRoler interface {
|
|
||||||
AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultDuration is the default amount of time in minutes that the credentials
|
|
||||||
// will be valid for.
|
|
||||||
var DefaultDuration = time.Duration(15) * time.Minute
|
|
||||||
|
|
||||||
// AssumeRoleProvider retrieves temporary credentials from the STS service, and
|
|
||||||
// keeps track of their expiration time.
|
|
||||||
//
|
|
||||||
// This credential provider will be used by the SDKs default credential change
|
|
||||||
// when shared configuration is enabled, and the shared config or shared credentials
|
|
||||||
// file configure assume role. See Session docs for how to do this.
|
|
||||||
//
|
|
||||||
// AssumeRoleProvider does not provide any synchronization and it is not safe
|
|
||||||
// to share this value across multiple Credentials, Sessions, or service clients
|
|
||||||
// without also sharing the same Credentials instance.
|
|
||||||
type AssumeRoleProvider struct {
|
|
||||||
credentials.Expiry
|
|
||||||
|
|
||||||
// STS client to make assume role request with.
|
|
||||||
Client AssumeRoler
|
|
||||||
|
|
||||||
// Role to be assumed.
|
|
||||||
RoleARN string
|
|
||||||
|
|
||||||
// Session name, if you wish to reuse the credentials elsewhere.
|
|
||||||
RoleSessionName string
|
|
||||||
|
|
||||||
// Expiry duration of the STS credentials. Defaults to 15 minutes if not set.
|
|
||||||
Duration time.Duration
|
|
||||||
|
|
||||||
// Optional ExternalID to pass along, defaults to nil if not set.
|
|
||||||
ExternalID *string
|
|
||||||
|
|
||||||
// The policy plain text must be 2048 bytes or shorter. However, an internal
|
|
||||||
// conversion compresses it into a packed binary format with a separate limit.
|
|
||||||
// The PackedPolicySize response element indicates by percentage how close to
|
|
||||||
// the upper size limit the policy is, with 100% equaling the maximum allowed
|
|
||||||
// size.
|
|
||||||
Policy *string
|
|
||||||
|
|
||||||
// The identification number of the MFA device that is associated with the user
|
|
||||||
// who is making the AssumeRole call. Specify this value if the trust policy
|
|
||||||
// of the role being assumed includes a condition that requires MFA authentication.
|
|
||||||
// The value is either the serial number for a hardware device (such as GAHT12345678)
|
|
||||||
// or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user).
|
|
||||||
SerialNumber *string
|
|
||||||
|
|
||||||
// The value provided by the MFA device, if the trust policy of the role being
|
|
||||||
// assumed requires MFA (that is, if the policy includes a condition that tests
|
|
||||||
// for MFA). If the role being assumed requires MFA and if the TokenCode value
|
|
||||||
// is missing or expired, the AssumeRole call returns an "access denied" error.
|
|
||||||
//
|
|
||||||
// If SerialNumber is set and neither TokenCode nor TokenProvider are also
|
|
||||||
// set an error will be returned.
|
|
||||||
TokenCode *string
|
|
||||||
|
|
||||||
// Async method of providing MFA token code for assuming an IAM role with MFA.
|
|
||||||
// The value returned by the function will be used as the TokenCode in the Retrieve
|
|
||||||
// call. See StdinTokenProvider for a provider that prompts and reads from stdin.
|
|
||||||
//
|
|
||||||
// This token provider will be called when ever the assumed role's
|
|
||||||
// credentials need to be refreshed when SerialNumber is also set and
|
|
||||||
// TokenCode is not set.
|
|
||||||
//
|
|
||||||
// If both TokenCode and TokenProvider is set, TokenProvider will be used and
|
|
||||||
// TokenCode is ignored.
|
|
||||||
TokenProvider func() (string, error)
|
|
||||||
|
|
||||||
// ExpiryWindow will allow the credentials to trigger refreshing prior to
|
|
||||||
// the credentials actually expiring. This is beneficial so race conditions
|
|
||||||
// with expiring credentials do not cause request to fail unexpectedly
|
|
||||||
// due to ExpiredTokenException exceptions.
|
|
||||||
//
|
|
||||||
// So a ExpiryWindow of 10s would cause calls to IsExpired() to return true
|
|
||||||
// 10 seconds before the credentials are actually expired.
|
|
||||||
//
|
|
||||||
// If ExpiryWindow is 0 or less it will be ignored.
|
|
||||||
ExpiryWindow time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentials returns a pointer to a new Credentials object wrapping the
|
|
||||||
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
|
||||||
// role will be named after a nanosecond timestamp of this operation.
|
|
||||||
//
|
|
||||||
// Takes a Config provider to create the STS client. The ConfigProvider is
|
|
||||||
// satisfied by the session.Session type.
|
|
||||||
//
|
|
||||||
// It is safe to share the returned Credentials with multiple Sessions and
|
|
||||||
// service clients. All access to the credentials and refreshing them
|
|
||||||
// will be synchronized.
|
|
||||||
func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
|
||||||
p := &AssumeRoleProvider{
|
|
||||||
Client: sts.New(c),
|
|
||||||
RoleARN: roleARN,
|
|
||||||
Duration: DefaultDuration,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the
|
|
||||||
// AssumeRoleProvider. The credentials will expire every 15 minutes and the
|
|
||||||
// role will be named after a nanosecond timestamp of this operation.
|
|
||||||
//
|
|
||||||
// Takes an AssumeRoler which can be satisfied by the STS client.
|
|
||||||
//
|
|
||||||
// It is safe to share the returned Credentials with multiple Sessions and
|
|
||||||
// service clients. All access to the credentials and refreshing them
|
|
||||||
// will be synchronized.
|
|
||||||
func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
|
||||||
p := &AssumeRoleProvider{
|
|
||||||
Client: svc,
|
|
||||||
RoleARN: roleARN,
|
|
||||||
Duration: DefaultDuration,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials.NewCredentials(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve generates a new set of temporary credentials using STS.
|
|
||||||
func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
|
|
||||||
|
|
||||||
// Apply defaults where parameters are not set.
|
|
||||||
if p.RoleSessionName == "" {
|
|
||||||
// Try to work out a role name that will hopefully end up unique.
|
|
||||||
p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano())
|
|
||||||
}
|
|
||||||
if p.Duration == 0 {
|
|
||||||
// Expire as often as AWS permits.
|
|
||||||
p.Duration = DefaultDuration
|
|
||||||
}
|
|
||||||
input := &sts.AssumeRoleInput{
|
|
||||||
DurationSeconds: aws.Int64(int64(p.Duration / time.Second)),
|
|
||||||
RoleArn: aws.String(p.RoleARN),
|
|
||||||
RoleSessionName: aws.String(p.RoleSessionName),
|
|
||||||
ExternalId: p.ExternalID,
|
|
||||||
}
|
|
||||||
if p.Policy != nil {
|
|
||||||
input.Policy = p.Policy
|
|
||||||
}
|
|
||||||
if p.SerialNumber != nil {
|
|
||||||
if p.TokenCode != nil {
|
|
||||||
input.SerialNumber = p.SerialNumber
|
|
||||||
input.TokenCode = p.TokenCode
|
|
||||||
} else if p.TokenProvider != nil {
|
|
||||||
input.SerialNumber = p.SerialNumber
|
|
||||||
code, err := p.TokenProvider()
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, err
|
|
||||||
}
|
|
||||||
input.TokenCode = aws.String(code)
|
|
||||||
} else {
|
|
||||||
return credentials.Value{ProviderName: ProviderName},
|
|
||||||
awserr.New("AssumeRoleTokenNotAvailable",
|
|
||||||
"assume role with MFA enabled, but neither TokenCode nor TokenProvider are set", nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
roleOutput, err := p.Client.AssumeRole(input)
|
|
||||||
if err != nil {
|
|
||||||
return credentials.Value{ProviderName: ProviderName}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// We will proactively generate new credentials before they expire.
|
|
||||||
p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow)
|
|
||||||
|
|
||||||
return credentials.Value{
|
|
||||||
AccessKeyID: *roleOutput.Credentials.AccessKeyId,
|
|
||||||
SecretAccessKey: *roleOutput.Credentials.SecretAccessKey,
|
|
||||||
SessionToken: *roleOutput.Credentials.SessionToken,
|
|
||||||
ProviderName: ProviderName,
|
|
||||||
}, nil
|
|
||||||
}
|
|
46
vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go
generated
vendored
46
vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go
generated
vendored
@ -1,46 +0,0 @@
|
|||||||
// Package csm provides Client Side Monitoring (CSM) which enables sending metrics
|
|
||||||
// via UDP connection. Using the Start function will enable the reporting of
|
|
||||||
// metrics on a given port. If Start is called, with different parameters, again,
|
|
||||||
// a panic will occur.
|
|
||||||
//
|
|
||||||
// Pause can be called to pause any metrics publishing on a given port. Sessions
|
|
||||||
// that have had their handlers modified via InjectHandlers may still be used.
|
|
||||||
// However, the handlers will act as a no-op meaning no metrics will be published.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// r, err := csm.Start("clientID", ":31000")
|
|
||||||
// if err != nil {
|
|
||||||
// panic(fmt.Errorf("failed starting CSM: %v", err))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// sess, err := session.NewSession(&aws.Config{})
|
|
||||||
// if err != nil {
|
|
||||||
// panic(fmt.Errorf("failed loading session: %v", err))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// r.InjectHandlers(&sess.Handlers)
|
|
||||||
//
|
|
||||||
// client := s3.New(sess)
|
|
||||||
// resp, err := client.GetObject(&s3.GetObjectInput{
|
|
||||||
// Bucket: aws.String("bucket"),
|
|
||||||
// Key: aws.String("key"),
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// // Will pause monitoring
|
|
||||||
// r.Pause()
|
|
||||||
// resp, err = client.GetObject(&s3.GetObjectInput{
|
|
||||||
// Bucket: aws.String("bucket"),
|
|
||||||
// Key: aws.String("key"),
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// // Resume monitoring
|
|
||||||
// r.Continue()
|
|
||||||
//
|
|
||||||
// Start returns a Reporter that is used to enable or disable monitoring. If
|
|
||||||
// access to the Reporter is required later, calling Get will return the Reporter
|
|
||||||
// singleton.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// r := csm.Get()
|
|
||||||
// r.Continue()
|
|
||||||
package csm
|
|
67
vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go
generated
vendored
67
vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go
generated
vendored
@ -1,67 +0,0 @@
|
|||||||
package csm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
lock sync.Mutex
|
|
||||||
)
|
|
||||||
|
|
||||||
// Client side metric handler names
|
|
||||||
const (
|
|
||||||
APICallMetricHandlerName = "awscsm.SendAPICallMetric"
|
|
||||||
APICallAttemptMetricHandlerName = "awscsm.SendAPICallAttemptMetric"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Start will start the a long running go routine to capture
|
|
||||||
// client side metrics. Calling start multiple time will only
|
|
||||||
// start the metric listener once and will panic if a different
|
|
||||||
// client ID or port is passed in.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// r, err := csm.Start("clientID", "127.0.0.1:8094")
|
|
||||||
// if err != nil {
|
|
||||||
// panic(fmt.Errorf("expected no error, but received %v", err))
|
|
||||||
// }
|
|
||||||
// sess := session.NewSession()
|
|
||||||
// r.InjectHandlers(sess.Handlers)
|
|
||||||
//
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
// out, err := svc.GetObject(&s3.GetObjectInput{
|
|
||||||
// Bucket: aws.String("bucket"),
|
|
||||||
// Key: aws.String("key"),
|
|
||||||
// })
|
|
||||||
func Start(clientID string, url string) (*Reporter, error) {
|
|
||||||
lock.Lock()
|
|
||||||
defer lock.Unlock()
|
|
||||||
|
|
||||||
if sender == nil {
|
|
||||||
sender = newReporter(clientID, url)
|
|
||||||
} else {
|
|
||||||
if sender.clientID != clientID {
|
|
||||||
panic(fmt.Errorf("inconsistent client IDs. %q was expected, but received %q", sender.clientID, clientID))
|
|
||||||
}
|
|
||||||
|
|
||||||
if sender.url != url {
|
|
||||||
panic(fmt.Errorf("inconsistent URLs. %q was expected, but received %q", sender.url, url))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := connect(url); err != nil {
|
|
||||||
sender = nil
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return sender, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get will return a reporter if one exists, if one does not exist, nil will
|
|
||||||
// be returned.
|
|
||||||
func Get() *Reporter {
|
|
||||||
lock.Lock()
|
|
||||||
defer lock.Unlock()
|
|
||||||
|
|
||||||
return sender
|
|
||||||
}
|
|
53
vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go
generated
vendored
53
vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go
generated
vendored
@ -1,53 +0,0 @@
|
|||||||
package csm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type metricTime time.Time
|
|
||||||
|
|
||||||
func (t metricTime) MarshalJSON() ([]byte, error) {
|
|
||||||
ns := time.Duration(time.Time(t).UnixNano())
|
|
||||||
return []byte(strconv.FormatInt(int64(ns/time.Millisecond), 10)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type metric struct {
|
|
||||||
ClientID *string `json:"ClientId,omitempty"`
|
|
||||||
API *string `json:"Api,omitempty"`
|
|
||||||
Service *string `json:"Service,omitempty"`
|
|
||||||
Timestamp *metricTime `json:"Timestamp,omitempty"`
|
|
||||||
Type *string `json:"Type,omitempty"`
|
|
||||||
Version *int `json:"Version,omitempty"`
|
|
||||||
|
|
||||||
AttemptCount *int `json:"AttemptCount,omitempty"`
|
|
||||||
Latency *int `json:"Latency,omitempty"`
|
|
||||||
|
|
||||||
Fqdn *string `json:"Fqdn,omitempty"`
|
|
||||||
UserAgent *string `json:"UserAgent,omitempty"`
|
|
||||||
AttemptLatency *int `json:"AttemptLatency,omitempty"`
|
|
||||||
|
|
||||||
SessionToken *string `json:"SessionToken,omitempty"`
|
|
||||||
Region *string `json:"Region,omitempty"`
|
|
||||||
AccessKey *string `json:"AccessKey,omitempty"`
|
|
||||||
HTTPStatusCode *int `json:"HttpStatusCode,omitempty"`
|
|
||||||
XAmzID2 *string `json:"XAmzId2,omitempty"`
|
|
||||||
XAmzRequestID *string `json:"XAmznRequestId,omitempty"`
|
|
||||||
|
|
||||||
AWSException *string `json:"AwsException,omitempty"`
|
|
||||||
AWSExceptionMessage *string `json:"AwsExceptionMessage,omitempty"`
|
|
||||||
SDKException *string `json:"SdkException,omitempty"`
|
|
||||||
SDKExceptionMessage *string `json:"SdkExceptionMessage,omitempty"`
|
|
||||||
|
|
||||||
DestinationIP *string `json:"DestinationIp,omitempty"`
|
|
||||||
ConnectionReused *int `json:"ConnectionReused,omitempty"`
|
|
||||||
|
|
||||||
AcquireConnectionLatency *int `json:"AcquireConnectionLatency,omitempty"`
|
|
||||||
ConnectLatency *int `json:"ConnectLatency,omitempty"`
|
|
||||||
RequestLatency *int `json:"RequestLatency,omitempty"`
|
|
||||||
DNSLatency *int `json:"DnsLatency,omitempty"`
|
|
||||||
TCPLatency *int `json:"TcpLatency,omitempty"`
|
|
||||||
SSLLatency *int `json:"SslLatency,omitempty"`
|
|
||||||
|
|
||||||
MaxRetriesExceeded *int `json:"MaxRetriesExceeded,omitempty"`
|
|
||||||
}
|
|
54
vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go
generated
vendored
54
vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go
generated
vendored
@ -1,54 +0,0 @@
|
|||||||
package csm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync/atomic"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
runningEnum = iota
|
|
||||||
pausedEnum
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// MetricsChannelSize of metrics to hold in the channel
|
|
||||||
MetricsChannelSize = 100
|
|
||||||
)
|
|
||||||
|
|
||||||
type metricChan struct {
|
|
||||||
ch chan metric
|
|
||||||
paused int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func newMetricChan(size int) metricChan {
|
|
||||||
return metricChan{
|
|
||||||
ch: make(chan metric, size),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ch *metricChan) Pause() {
|
|
||||||
atomic.StoreInt64(&ch.paused, pausedEnum)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ch *metricChan) Continue() {
|
|
||||||
atomic.StoreInt64(&ch.paused, runningEnum)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ch *metricChan) IsPaused() bool {
|
|
||||||
v := atomic.LoadInt64(&ch.paused)
|
|
||||||
return v == pausedEnum
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push will push metrics to the metric channel if the channel
|
|
||||||
// is not paused
|
|
||||||
func (ch *metricChan) Push(m metric) bool {
|
|
||||||
if ch.IsPaused() {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case ch.ch <- m:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
242
vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go
generated
vendored
242
vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go
generated
vendored
@ -1,242 +0,0 @@
|
|||||||
package csm
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DefaultPort is used when no port is specified
|
|
||||||
DefaultPort = "31000"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Reporter will gather metrics of API requests made and
|
|
||||||
// send those metrics to the CSM endpoint.
|
|
||||||
type Reporter struct {
|
|
||||||
clientID string
|
|
||||||
url string
|
|
||||||
conn net.Conn
|
|
||||||
metricsCh metricChan
|
|
||||||
done chan struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
sender *Reporter
|
|
||||||
)
|
|
||||||
|
|
||||||
func connect(url string) error {
|
|
||||||
const network = "udp"
|
|
||||||
if err := sender.connect(network, url); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if sender.done == nil {
|
|
||||||
sender.done = make(chan struct{})
|
|
||||||
go sender.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newReporter(clientID, url string) *Reporter {
|
|
||||||
return &Reporter{
|
|
||||||
clientID: clientID,
|
|
||||||
url: url,
|
|
||||||
metricsCh: newMetricChan(MetricsChannelSize),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rep *Reporter) sendAPICallAttemptMetric(r *request.Request) {
|
|
||||||
if rep == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now()
|
|
||||||
creds, _ := r.Config.Credentials.Get()
|
|
||||||
|
|
||||||
m := metric{
|
|
||||||
ClientID: aws.String(rep.clientID),
|
|
||||||
API: aws.String(r.Operation.Name),
|
|
||||||
Service: aws.String(r.ClientInfo.ServiceID),
|
|
||||||
Timestamp: (*metricTime)(&now),
|
|
||||||
UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")),
|
|
||||||
Region: r.Config.Region,
|
|
||||||
Type: aws.String("ApiCallAttempt"),
|
|
||||||
Version: aws.Int(1),
|
|
||||||
|
|
||||||
XAmzRequestID: aws.String(r.RequestID),
|
|
||||||
|
|
||||||
AttemptCount: aws.Int(r.RetryCount + 1),
|
|
||||||
AttemptLatency: aws.Int(int(now.Sub(r.AttemptTime).Nanoseconds() / int64(time.Millisecond))),
|
|
||||||
AccessKey: aws.String(creds.AccessKeyID),
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.HTTPResponse != nil {
|
|
||||||
m.HTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Error != nil {
|
|
||||||
if awserr, ok := r.Error.(awserr.Error); ok {
|
|
||||||
setError(&m, awserr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.metricsCh.Push(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setError(m *metric, err awserr.Error) {
|
|
||||||
msg := err.Error()
|
|
||||||
code := err.Code()
|
|
||||||
|
|
||||||
switch code {
|
|
||||||
case "RequestError",
|
|
||||||
"SerializationError",
|
|
||||||
request.CanceledErrorCode:
|
|
||||||
m.SDKException = &code
|
|
||||||
m.SDKExceptionMessage = &msg
|
|
||||||
default:
|
|
||||||
m.AWSException = &code
|
|
||||||
m.AWSExceptionMessage = &msg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rep *Reporter) sendAPICallMetric(r *request.Request) {
|
|
||||||
if rep == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
now := time.Now()
|
|
||||||
m := metric{
|
|
||||||
ClientID: aws.String(rep.clientID),
|
|
||||||
API: aws.String(r.Operation.Name),
|
|
||||||
Service: aws.String(r.ClientInfo.ServiceID),
|
|
||||||
Timestamp: (*metricTime)(&now),
|
|
||||||
Type: aws.String("ApiCall"),
|
|
||||||
AttemptCount: aws.Int(r.RetryCount + 1),
|
|
||||||
Region: r.Config.Region,
|
|
||||||
Latency: aws.Int(int(time.Now().Sub(r.Time) / time.Millisecond)),
|
|
||||||
XAmzRequestID: aws.String(r.RequestID),
|
|
||||||
MaxRetriesExceeded: aws.Int(boolIntValue(r.RetryCount >= r.MaxRetries())),
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Probably want to figure something out for logging dropped
|
|
||||||
// metrics
|
|
||||||
rep.metricsCh.Push(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rep *Reporter) connect(network, url string) error {
|
|
||||||
if rep.conn != nil {
|
|
||||||
rep.conn.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := net.Dial(network, url)
|
|
||||||
if err != nil {
|
|
||||||
return awserr.New("UDPError", "Could not connect", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.conn = conn
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rep *Reporter) close() {
|
|
||||||
if rep.done != nil {
|
|
||||||
close(rep.done)
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.metricsCh.Pause()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rep *Reporter) start() {
|
|
||||||
defer func() {
|
|
||||||
rep.metricsCh.Pause()
|
|
||||||
}()
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-rep.done:
|
|
||||||
rep.done = nil
|
|
||||||
return
|
|
||||||
case m := <-rep.metricsCh.ch:
|
|
||||||
// TODO: What to do with this error? Probably should just log
|
|
||||||
b, err := json.Marshal(m)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.conn.Write(b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pause will pause the metric channel preventing any new metrics from
|
|
||||||
// being added.
|
|
||||||
func (rep *Reporter) Pause() {
|
|
||||||
lock.Lock()
|
|
||||||
defer lock.Unlock()
|
|
||||||
|
|
||||||
if rep == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continue will reopen the metric channel and allow for monitoring
|
|
||||||
// to be resumed.
|
|
||||||
func (rep *Reporter) Continue() {
|
|
||||||
lock.Lock()
|
|
||||||
defer lock.Unlock()
|
|
||||||
if rep == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if !rep.metricsCh.IsPaused() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
rep.metricsCh.Continue()
|
|
||||||
}
|
|
||||||
|
|
||||||
// InjectHandlers will will enable client side metrics and inject the proper
|
|
||||||
// handlers to handle how metrics are sent.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// // Start must be called in order to inject the correct handlers
|
|
||||||
// r, err := csm.Start("clientID", "127.0.0.1:8094")
|
|
||||||
// if err != nil {
|
|
||||||
// panic(fmt.Errorf("expected no error, but received %v", err))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// sess := session.NewSession()
|
|
||||||
// r.InjectHandlers(&sess.Handlers)
|
|
||||||
//
|
|
||||||
// // create a new service client with our client side metric session
|
|
||||||
// svc := s3.New(sess)
|
|
||||||
func (rep *Reporter) InjectHandlers(handlers *request.Handlers) {
|
|
||||||
if rep == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
apiCallHandler := request.NamedHandler{Name: APICallMetricHandlerName, Fn: rep.sendAPICallMetric}
|
|
||||||
apiCallAttemptHandler := request.NamedHandler{Name: APICallAttemptMetricHandlerName, Fn: rep.sendAPICallAttemptMetric}
|
|
||||||
|
|
||||||
handlers.Complete.PushFrontNamed(apiCallHandler)
|
|
||||||
handlers.Complete.PushFrontNamed(apiCallAttemptHandler)
|
|
||||||
|
|
||||||
handlers.AfterRetry.PushFrontNamed(apiCallAttemptHandler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// boolIntValue return 1 for true and 0 for false.
|
|
||||||
func boolIntValue(b bool) int {
|
|
||||||
if b {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
207
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
207
vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go
generated
vendored
@ -1,207 +0,0 @@
|
|||||||
// Package defaults is a collection of helpers to retrieve the SDK's default
|
|
||||||
// configuration and handlers.
|
|
||||||
//
|
|
||||||
// Generally this package shouldn't be used directly, but session.Session
|
|
||||||
// instead. This package is useful when you need to reset the defaults
|
|
||||||
// of a session or service client to the SDK defaults before setting
|
|
||||||
// additional parameters.
|
|
||||||
package defaults
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"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"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials/endpointcreds"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Defaults provides a collection of default values for SDK clients.
|
|
||||||
type Defaults struct {
|
|
||||||
Config *aws.Config
|
|
||||||
Handlers request.Handlers
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns the SDK's default values with Config and handlers pre-configured.
|
|
||||||
func Get() Defaults {
|
|
||||||
cfg := Config()
|
|
||||||
handlers := Handlers()
|
|
||||||
cfg.Credentials = CredChain(cfg, handlers)
|
|
||||||
|
|
||||||
return Defaults{
|
|
||||||
Config: cfg,
|
|
||||||
Handlers: handlers,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Config returns the default configuration without credentials.
|
|
||||||
// To retrieve a config with credentials also included use
|
|
||||||
// `defaults.Get().Config` instead.
|
|
||||||
//
|
|
||||||
// Generally you shouldn't need to use this method directly, but
|
|
||||||
// is available if you need to reset the configuration of an
|
|
||||||
// existing service client or session.
|
|
||||||
func Config() *aws.Config {
|
|
||||||
return aws.NewConfig().
|
|
||||||
WithCredentials(credentials.AnonymousCredentials).
|
|
||||||
WithRegion(os.Getenv("AWS_REGION")).
|
|
||||||
WithHTTPClient(http.DefaultClient).
|
|
||||||
WithMaxRetries(aws.UseServiceDefaultRetries).
|
|
||||||
WithLogger(aws.NewDefaultLogger()).
|
|
||||||
WithLogLevel(aws.LogOff).
|
|
||||||
WithEndpointResolver(endpoints.DefaultResolver())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handlers returns the default request handlers.
|
|
||||||
//
|
|
||||||
// Generally you shouldn't need to use this method directly, but
|
|
||||||
// is available if you need to reset the request handlers of an
|
|
||||||
// existing service client or session.
|
|
||||||
func Handlers() request.Handlers {
|
|
||||||
var handlers request.Handlers
|
|
||||||
|
|
||||||
handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
|
|
||||||
handlers.Validate.AfterEachFn = request.HandlerListStopOnError
|
|
||||||
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler)
|
|
||||||
handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHander)
|
|
||||||
handlers.Build.AfterEachFn = request.HandlerListStopOnError
|
|
||||||
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler)
|
|
||||||
handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler)
|
|
||||||
handlers.Send.PushBackNamed(corehandlers.SendHandler)
|
|
||||||
handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
|
|
||||||
handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler)
|
|
||||||
|
|
||||||
return handlers
|
|
||||||
}
|
|
||||||
|
|
||||||
// CredChain returns the default credential chain.
|
|
||||||
//
|
|
||||||
// Generally you shouldn't need to use this method directly, but
|
|
||||||
// is available if you need to reset the credentials of an
|
|
||||||
// existing service client or session's Config.
|
|
||||||
func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
|
|
||||||
return credentials.NewCredentials(&credentials.ChainProvider{
|
|
||||||
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
|
|
||||||
Providers: CredProviders(cfg, handlers),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// CredProviders returns the slice of providers used in
|
|
||||||
// the default credential chain.
|
|
||||||
//
|
|
||||||
// For applications that need to use some other provider (for example use
|
|
||||||
// different environment variables for legacy reasons) but still fall back
|
|
||||||
// on the default chain of providers. This allows that default chaint to be
|
|
||||||
// automatically updated
|
|
||||||
func CredProviders(cfg *aws.Config, handlers request.Handlers) []credentials.Provider {
|
|
||||||
return []credentials.Provider{
|
|
||||||
&credentials.EnvProvider{},
|
|
||||||
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
|
|
||||||
RemoteCredProvider(*cfg, handlers),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
httpProviderAuthorizationEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN"
|
|
||||||
httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
|
|
||||||
)
|
|
||||||
|
|
||||||
// RemoteCredProvider returns a credentials provider for the default remote
|
|
||||||
// endpoints such as EC2 or ECS Roles.
|
|
||||||
func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
|
|
||||||
if u := os.Getenv(httpProviderEnvVar); len(u) > 0 {
|
|
||||||
return localHTTPCredProvider(cfg, handlers, u)
|
|
||||||
}
|
|
||||||
|
|
||||||
if uri := os.Getenv(shareddefaults.ECSCredsProviderEnvVar); len(uri) > 0 {
|
|
||||||
u := fmt.Sprintf("%s%s", shareddefaults.ECSContainerCredentialsURI, uri)
|
|
||||||
return httpCredProvider(cfg, handlers, u)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ec2RoleProvider(cfg, handlers)
|
|
||||||
}
|
|
||||||
|
|
||||||
var lookupHostFn = net.LookupHost
|
|
||||||
|
|
||||||
func isLoopbackHost(host string) (bool, error) {
|
|
||||||
ip := net.ParseIP(host)
|
|
||||||
if ip != nil {
|
|
||||||
return ip.IsLoopback(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Host is not an ip, perform lookup
|
|
||||||
addrs, err := lookupHostFn(host)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
for _, addr := range addrs {
|
|
||||||
if !net.ParseIP(addr).IsLoopback() {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
|
|
||||||
var errMsg string
|
|
||||||
|
|
||||||
parsed, err := url.Parse(u)
|
|
||||||
if err != nil {
|
|
||||||
errMsg = fmt.Sprintf("invalid URL, %v", err)
|
|
||||||
} else {
|
|
||||||
host := aws.URLHostname(parsed)
|
|
||||||
if len(host) == 0 {
|
|
||||||
errMsg = "unable to parse host from local HTTP cred provider URL"
|
|
||||||
} else if isLoopback, loopbackErr := isLoopbackHost(host); loopbackErr != nil {
|
|
||||||
errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, loopbackErr)
|
|
||||||
} else if !isLoopback {
|
|
||||||
errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback hosts are allowed.", host)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(errMsg) > 0 {
|
|
||||||
if cfg.Logger != nil {
|
|
||||||
cfg.Logger.Log("Ignoring, HTTP credential provider", errMsg, err)
|
|
||||||
}
|
|
||||||
return credentials.ErrorProvider{
|
|
||||||
Err: awserr.New("CredentialsEndpointError", errMsg, err),
|
|
||||||
ProviderName: endpointcreds.ProviderName,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return httpCredProvider(cfg, handlers, u)
|
|
||||||
}
|
|
||||||
|
|
||||||
func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider {
|
|
||||||
return endpointcreds.NewProviderClient(cfg, handlers, u,
|
|
||||||
func(p *endpointcreds.Provider) {
|
|
||||||
p.ExpiryWindow = 5 * time.Minute
|
|
||||||
p.AuthorizationToken = os.Getenv(httpProviderAuthorizationEnvVar)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
|
|
||||||
resolver := cfg.EndpointResolver
|
|
||||||
if resolver == nil {
|
|
||||||
resolver = endpoints.DefaultResolver()
|
|
||||||
}
|
|
||||||
|
|
||||||
e, _ := resolver.EndpointFor(endpoints.Ec2metadataServiceID, "")
|
|
||||||
return &ec2rolecreds.EC2RoleProvider{
|
|
||||||
Client: ec2metadata.NewClient(cfg, handlers, e.URL, e.SigningRegion),
|
|
||||||
ExpiryWindow: 5 * time.Minute,
|
|
||||||
}
|
|
||||||
}
|
|
27
vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go
generated
vendored
27
vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go
generated
vendored
@ -1,27 +0,0 @@
|
|||||||
package defaults
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SharedCredentialsFilename returns the SDK's default file path
|
|
||||||
// for the shared credentials file.
|
|
||||||
//
|
|
||||||
// Builds the shared config file path based on the OS's platform.
|
|
||||||
//
|
|
||||||
// - Linux/Unix: $HOME/.aws/credentials
|
|
||||||
// - Windows: %USERPROFILE%\.aws\credentials
|
|
||||||
func SharedCredentialsFilename() string {
|
|
||||||
return shareddefaults.SharedCredentialsFilename()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SharedConfigFilename returns the SDK's default file path for
|
|
||||||
// the shared config file.
|
|
||||||
//
|
|
||||||
// Builds the shared config file path based on the OS's platform.
|
|
||||||
//
|
|
||||||
// - Linux/Unix: $HOME/.aws/config
|
|
||||||
// - Windows: %USERPROFILE%\.aws\config
|
|
||||||
func SharedConfigFilename() string {
|
|
||||||
return shareddefaults.SharedConfigFilename()
|
|
||||||
}
|
|
56
vendor/github.com/aws/aws-sdk-go/aws/doc.go
generated
vendored
56
vendor/github.com/aws/aws-sdk-go/aws/doc.go
generated
vendored
@ -1,56 +0,0 @@
|
|||||||
// Package aws provides the core SDK's utilities and shared types. Use this package's
|
|
||||||
// utilities to simplify setting and reading API operations parameters.
|
|
||||||
//
|
|
||||||
// Value and Pointer Conversion Utilities
|
|
||||||
//
|
|
||||||
// This package includes a helper conversion utility for each scalar type the SDK's
|
|
||||||
// API use. These utilities make getting a pointer of the scalar, and dereferencing
|
|
||||||
// a pointer easier.
|
|
||||||
//
|
|
||||||
// Each conversion utility comes in two forms. Value to Pointer and Pointer to Value.
|
|
||||||
// The Pointer to value will safely dereference the pointer and return its value.
|
|
||||||
// If the pointer was nil, the scalar's zero value will be returned.
|
|
||||||
//
|
|
||||||
// The value to pointer functions will be named after the scalar type. So get a
|
|
||||||
// *string from a string value use the "String" function. This makes it easy to
|
|
||||||
// to get pointer of a literal string value, because getting the address of a
|
|
||||||
// literal requires assigning the value to a variable first.
|
|
||||||
//
|
|
||||||
// var strPtr *string
|
|
||||||
//
|
|
||||||
// // Without the SDK's conversion functions
|
|
||||||
// str := "my string"
|
|
||||||
// strPtr = &str
|
|
||||||
//
|
|
||||||
// // With the SDK's conversion functions
|
|
||||||
// strPtr = aws.String("my string")
|
|
||||||
//
|
|
||||||
// // Convert *string to string value
|
|
||||||
// str = aws.StringValue(strPtr)
|
|
||||||
//
|
|
||||||
// In addition to scalars the aws package also includes conversion utilities for
|
|
||||||
// map and slice for commonly types used in API parameters. The map and slice
|
|
||||||
// conversion functions use similar naming pattern as the scalar conversion
|
|
||||||
// functions.
|
|
||||||
//
|
|
||||||
// var strPtrs []*string
|
|
||||||
// var strs []string = []string{"Go", "Gophers", "Go"}
|
|
||||||
//
|
|
||||||
// // Convert []string to []*string
|
|
||||||
// strPtrs = aws.StringSlice(strs)
|
|
||||||
//
|
|
||||||
// // Convert []*string to []string
|
|
||||||
// strs = aws.StringValueSlice(strPtrs)
|
|
||||||
//
|
|
||||||
// SDK Default HTTP Client
|
|
||||||
//
|
|
||||||
// The SDK will use the http.DefaultClient if a HTTP client is not provided to
|
|
||||||
// the SDK's Session, or service client constructor. This means that if the
|
|
||||||
// http.DefaultClient is modified by other components of your application the
|
|
||||||
// modifications will be picked up by the SDK as well.
|
|
||||||
//
|
|
||||||
// In some cases this might be intended, but it is a better practice to create
|
|
||||||
// a custom HTTP Client to share explicitly through your application. You can
|
|
||||||
// configure the SDK to use the custom HTTP Client by setting the HTTPClient
|
|
||||||
// value of the SDK's Config type when creating a Session or service client.
|
|
||||||
package aws
|
|
162
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
generated
vendored
162
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/api.go
generated
vendored
@ -1,162 +0,0 @@
|
|||||||
package ec2metadata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkuri"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetMetadata uses the path provided to request information from the EC2
|
|
||||||
// instance metdata service. The content will be returned as a string, or
|
|
||||||
// error if the request failed.
|
|
||||||
func (c *EC2Metadata) GetMetadata(p string) (string, error) {
|
|
||||||
op := &request.Operation{
|
|
||||||
Name: "GetMetadata",
|
|
||||||
HTTPMethod: "GET",
|
|
||||||
HTTPPath: sdkuri.PathJoin("/meta-data", p),
|
|
||||||
}
|
|
||||||
|
|
||||||
output := &metadataOutput{}
|
|
||||||
req := c.NewRequest(op, nil, output)
|
|
||||||
|
|
||||||
return output.Content, req.Send()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUserData returns the userdata that was configured for the service. If
|
|
||||||
// there is no user-data setup for the EC2 instance a "NotFoundError" error
|
|
||||||
// code will be returned.
|
|
||||||
func (c *EC2Metadata) GetUserData() (string, error) {
|
|
||||||
op := &request.Operation{
|
|
||||||
Name: "GetUserData",
|
|
||||||
HTTPMethod: "GET",
|
|
||||||
HTTPPath: "/user-data",
|
|
||||||
}
|
|
||||||
|
|
||||||
output := &metadataOutput{}
|
|
||||||
req := c.NewRequest(op, nil, output)
|
|
||||||
req.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
|
|
||||||
if r.HTTPResponse.StatusCode == http.StatusNotFound {
|
|
||||||
r.Error = awserr.New("NotFoundError", "user-data not found", r.Error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return output.Content, req.Send()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetDynamicData uses the path provided to request information from the EC2
|
|
||||||
// instance metadata service for dynamic data. The content will be returned
|
|
||||||
// as a string, or error if the request failed.
|
|
||||||
func (c *EC2Metadata) GetDynamicData(p string) (string, error) {
|
|
||||||
op := &request.Operation{
|
|
||||||
Name: "GetDynamicData",
|
|
||||||
HTTPMethod: "GET",
|
|
||||||
HTTPPath: sdkuri.PathJoin("/dynamic", p),
|
|
||||||
}
|
|
||||||
|
|
||||||
output := &metadataOutput{}
|
|
||||||
req := c.NewRequest(op, nil, output)
|
|
||||||
|
|
||||||
return output.Content, req.Send()
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetInstanceIdentityDocument retrieves an identity document describing an
|
|
||||||
// instance. Error is returned if the request fails or is unable to parse
|
|
||||||
// the response.
|
|
||||||
func (c *EC2Metadata) GetInstanceIdentityDocument() (EC2InstanceIdentityDocument, error) {
|
|
||||||
resp, err := c.GetDynamicData("instance-identity/document")
|
|
||||||
if err != nil {
|
|
||||||
return EC2InstanceIdentityDocument{},
|
|
||||||
awserr.New("EC2MetadataRequestError",
|
|
||||||
"failed to get EC2 instance identity document", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
doc := EC2InstanceIdentityDocument{}
|
|
||||||
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&doc); err != nil {
|
|
||||||
return EC2InstanceIdentityDocument{},
|
|
||||||
awserr.New("SerializationError",
|
|
||||||
"failed to decode EC2 instance identity document", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return doc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IAMInfo retrieves IAM info from the metadata API
|
|
||||||
func (c *EC2Metadata) IAMInfo() (EC2IAMInfo, error) {
|
|
||||||
resp, err := c.GetMetadata("iam/info")
|
|
||||||
if err != nil {
|
|
||||||
return EC2IAMInfo{},
|
|
||||||
awserr.New("EC2MetadataRequestError",
|
|
||||||
"failed to get EC2 IAM info", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
info := EC2IAMInfo{}
|
|
||||||
if err := json.NewDecoder(strings.NewReader(resp)).Decode(&info); err != nil {
|
|
||||||
return EC2IAMInfo{},
|
|
||||||
awserr.New("SerializationError",
|
|
||||||
"failed to decode EC2 IAM info", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if info.Code != "Success" {
|
|
||||||
errMsg := fmt.Sprintf("failed to get EC2 IAM Info (%s)", info.Code)
|
|
||||||
return EC2IAMInfo{},
|
|
||||||
awserr.New("EC2MetadataError", errMsg, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
return info, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Region returns the region the instance is running in.
|
|
||||||
func (c *EC2Metadata) Region() (string, error) {
|
|
||||||
resp, err := c.GetMetadata("placement/availability-zone")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns region without the suffix. Eg: us-west-2a becomes us-west-2
|
|
||||||
return resp[:len(resp)-1], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Available returns if the application has access to the EC2 Metadata service.
|
|
||||||
// Can be used to determine if application is running within an EC2 Instance and
|
|
||||||
// the metadata service is available.
|
|
||||||
func (c *EC2Metadata) Available() bool {
|
|
||||||
if _, err := c.GetMetadata("instance-id"); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// An EC2IAMInfo provides the shape for unmarshaling
|
|
||||||
// an IAM info from the metadata API
|
|
||||||
type EC2IAMInfo struct {
|
|
||||||
Code string
|
|
||||||
LastUpdated time.Time
|
|
||||||
InstanceProfileArn string
|
|
||||||
InstanceProfileID string
|
|
||||||
}
|
|
||||||
|
|
||||||
// An EC2InstanceIdentityDocument provides the shape for unmarshaling
|
|
||||||
// an instance identity document
|
|
||||||
type EC2InstanceIdentityDocument struct {
|
|
||||||
DevpayProductCodes []string `json:"devpayProductCodes"`
|
|
||||||
AvailabilityZone string `json:"availabilityZone"`
|
|
||||||
PrivateIP string `json:"privateIp"`
|
|
||||||
Version string `json:"version"`
|
|
||||||
Region string `json:"region"`
|
|
||||||
InstanceID string `json:"instanceId"`
|
|
||||||
BillingProducts []string `json:"billingProducts"`
|
|
||||||
InstanceType string `json:"instanceType"`
|
|
||||||
AccountID string `json:"accountId"`
|
|
||||||
PendingTime time.Time `json:"pendingTime"`
|
|
||||||
ImageID string `json:"imageId"`
|
|
||||||
KernelID string `json:"kernelId"`
|
|
||||||
RamdiskID string `json:"ramdiskId"`
|
|
||||||
Architecture string `json:"architecture"`
|
|
||||||
}
|
|
149
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
generated
vendored
149
vendor/github.com/aws/aws-sdk-go/aws/ec2metadata/service.go
generated
vendored
@ -1,149 +0,0 @@
|
|||||||
// Package ec2metadata provides the client for making API calls to the
|
|
||||||
// EC2 Metadata service.
|
|
||||||
//
|
|
||||||
// This package's client can be disabled completely by setting the environment
|
|
||||||
// variable "AWS_EC2_METADATA_DISABLED=true". This environment variable set to
|
|
||||||
// true instructs the SDK to disable the EC2 Metadata client. The client cannot
|
|
||||||
// be used while the environemnt variable is set to true, (case insensitive).
|
|
||||||
package ec2metadata
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ServiceName is the name of the service.
|
|
||||||
const ServiceName = "ec2metadata"
|
|
||||||
const disableServiceEnvVar = "AWS_EC2_METADATA_DISABLED"
|
|
||||||
|
|
||||||
// A EC2Metadata is an EC2 Metadata service Client.
|
|
||||||
type EC2Metadata struct {
|
|
||||||
*client.Client
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new instance of the EC2Metadata client with a session.
|
|
||||||
// This client is safe to use across multiple goroutines.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// // Create a EC2Metadata client from just a session.
|
|
||||||
// svc := ec2metadata.New(mySession)
|
|
||||||
//
|
|
||||||
// // Create a EC2Metadata client with additional configuration
|
|
||||||
// svc := ec2metadata.New(mySession, aws.NewConfig().WithLogLevel(aws.LogDebugHTTPBody))
|
|
||||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *EC2Metadata {
|
|
||||||
c := p.ClientConfig(ServiceName, cfgs...)
|
|
||||||
return NewClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClient returns a new EC2Metadata client. Should be used to create
|
|
||||||
// a client when not using a session. Generally using just New with a session
|
|
||||||
// is preferred.
|
|
||||||
//
|
|
||||||
// If an unmodified HTTP client is provided from the stdlib default, or no client
|
|
||||||
// the EC2RoleProvider's EC2Metadata HTTP client's timeout will be shortened.
|
|
||||||
// To disable this set Config.EC2MetadataDisableTimeoutOverride to false. Enabled by default.
|
|
||||||
func NewClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string, opts ...func(*client.Client)) *EC2Metadata {
|
|
||||||
if !aws.BoolValue(cfg.EC2MetadataDisableTimeoutOverride) && httpClientZero(cfg.HTTPClient) {
|
|
||||||
// If the http client is unmodified and this feature is not disabled
|
|
||||||
// set custom timeouts for EC2Metadata requests.
|
|
||||||
cfg.HTTPClient = &http.Client{
|
|
||||||
// use a shorter timeout than default because the metadata
|
|
||||||
// service is local if it is running, and to fail faster
|
|
||||||
// if not running on an ec2 instance.
|
|
||||||
Timeout: 5 * time.Second,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
svc := &EC2Metadata{
|
|
||||||
Client: client.New(
|
|
||||||
cfg,
|
|
||||||
metadata.ClientInfo{
|
|
||||||
ServiceName: ServiceName,
|
|
||||||
ServiceID: ServiceName,
|
|
||||||
Endpoint: endpoint,
|
|
||||||
APIVersion: "latest",
|
|
||||||
},
|
|
||||||
handlers,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
svc.Handlers.Unmarshal.PushBack(unmarshalHandler)
|
|
||||||
svc.Handlers.UnmarshalError.PushBack(unmarshalError)
|
|
||||||
svc.Handlers.Validate.Clear()
|
|
||||||
svc.Handlers.Validate.PushBack(validateEndpointHandler)
|
|
||||||
|
|
||||||
// Disable the EC2 Metadata service if the environment variable is set.
|
|
||||||
// This shortcirctes the service's functionality to always fail to send
|
|
||||||
// requests.
|
|
||||||
if strings.ToLower(os.Getenv(disableServiceEnvVar)) == "true" {
|
|
||||||
svc.Handlers.Send.SwapNamed(request.NamedHandler{
|
|
||||||
Name: corehandlers.SendHandler.Name,
|
|
||||||
Fn: func(r *request.Request) {
|
|
||||||
r.Error = awserr.New(
|
|
||||||
request.CanceledErrorCode,
|
|
||||||
"EC2 IMDS access disabled via "+disableServiceEnvVar+" env var",
|
|
||||||
nil)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add additional options to the service config
|
|
||||||
for _, option := range opts {
|
|
||||||
option(svc.Client)
|
|
||||||
}
|
|
||||||
|
|
||||||
return svc
|
|
||||||
}
|
|
||||||
|
|
||||||
func httpClientZero(c *http.Client) bool {
|
|
||||||
return c == nil || (c.Transport == nil && c.CheckRedirect == nil && c.Jar == nil && c.Timeout == 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
type metadataOutput struct {
|
|
||||||
Content string
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalHandler(r *request.Request) {
|
|
||||||
defer r.HTTPResponse.Body.Close()
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
|
|
||||||
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata respose", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if data, ok := r.Data.(*metadataOutput); ok {
|
|
||||||
data.Content = b.String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func unmarshalError(r *request.Request) {
|
|
||||||
defer r.HTTPResponse.Body.Close()
|
|
||||||
b := &bytes.Buffer{}
|
|
||||||
if _, err := io.Copy(b, r.HTTPResponse.Body); err != nil {
|
|
||||||
r.Error = awserr.New("SerializationError", "unable to unmarshal EC2 metadata error respose", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Response body format is not consistent between metadata endpoints.
|
|
||||||
// Grab the error message as a string and include that as the source error
|
|
||||||
r.Error = awserr.New("EC2MetadataError", "failed to make EC2Metadata request", errors.New(b.String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func validateEndpointHandler(r *request.Request) {
|
|
||||||
if r.ClientInfo.Endpoint == "" {
|
|
||||||
r.Error = aws.ErrMissingEndpoint
|
|
||||||
}
|
|
||||||
}
|
|
160
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
generated
vendored
160
vendor/github.com/aws/aws-sdk-go/aws/endpoints/decode.go
generated
vendored
@ -1,160 +0,0 @@
|
|||||||
package endpoints
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
type modelDefinition map[string]json.RawMessage
|
|
||||||
|
|
||||||
// A DecodeModelOptions are the options for how the endpoints model definition
|
|
||||||
// are decoded.
|
|
||||||
type DecodeModelOptions struct {
|
|
||||||
SkipCustomizations bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set combines all of the option functions together.
|
|
||||||
func (d *DecodeModelOptions) Set(optFns ...func(*DecodeModelOptions)) {
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeModel unmarshals a Regions and Endpoint model definition file into
|
|
||||||
// a endpoint Resolver. If the file format is not supported, or an error occurs
|
|
||||||
// when unmarshaling the model an error will be returned.
|
|
||||||
//
|
|
||||||
// Casting the return value of this func to a EnumPartitions will
|
|
||||||
// allow you to get a list of the partitions in the order the endpoints
|
|
||||||
// will be resolved in.
|
|
||||||
//
|
|
||||||
// resolver, err := endpoints.DecodeModel(reader)
|
|
||||||
//
|
|
||||||
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
|
|
||||||
// for _, p := range partitions {
|
|
||||||
// // ... inspect partitions
|
|
||||||
// }
|
|
||||||
func DecodeModel(r io.Reader, optFns ...func(*DecodeModelOptions)) (Resolver, error) {
|
|
||||||
var opts DecodeModelOptions
|
|
||||||
opts.Set(optFns...)
|
|
||||||
|
|
||||||
// Get the version of the partition file to determine what
|
|
||||||
// unmarshaling model to use.
|
|
||||||
modelDef := modelDefinition{}
|
|
||||||
if err := json.NewDecoder(r).Decode(&modelDef); err != nil {
|
|
||||||
return nil, newDecodeModelError("failed to decode endpoints model", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var version string
|
|
||||||
if b, ok := modelDef["version"]; ok {
|
|
||||||
version = string(b)
|
|
||||||
} else {
|
|
||||||
return nil, newDecodeModelError("endpoints version not found in model", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
if version == "3" {
|
|
||||||
return decodeV3Endpoints(modelDef, opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, newDecodeModelError(
|
|
||||||
fmt.Sprintf("endpoints version %s, not supported", version), nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeV3Endpoints(modelDef modelDefinition, opts DecodeModelOptions) (Resolver, error) {
|
|
||||||
b, ok := modelDef["partitions"]
|
|
||||||
if !ok {
|
|
||||||
return nil, newDecodeModelError("endpoints model missing partitions", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
ps := partitions{}
|
|
||||||
if err := json.Unmarshal(b, &ps); err != nil {
|
|
||||||
return nil, newDecodeModelError("failed to decode endpoints model", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.SkipCustomizations {
|
|
||||||
return ps, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Customization
|
|
||||||
for i := 0; i < len(ps); i++ {
|
|
||||||
p := &ps[i]
|
|
||||||
custAddEC2Metadata(p)
|
|
||||||
custAddS3DualStack(p)
|
|
||||||
custRmIotDataService(p)
|
|
||||||
custFixAppAutoscalingChina(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ps, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func custAddS3DualStack(p *partition) {
|
|
||||||
if p.ID != "aws" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
custAddDualstack(p, "s3")
|
|
||||||
custAddDualstack(p, "s3-control")
|
|
||||||
}
|
|
||||||
|
|
||||||
func custAddDualstack(p *partition, svcName string) {
|
|
||||||
s, ok := p.Services[svcName]
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Defaults.HasDualStack = boxedTrue
|
|
||||||
s.Defaults.DualStackHostname = "{service}.dualstack.{region}.{dnsSuffix}"
|
|
||||||
|
|
||||||
p.Services[svcName] = s
|
|
||||||
}
|
|
||||||
|
|
||||||
func custAddEC2Metadata(p *partition) {
|
|
||||||
p.Services["ec2metadata"] = service{
|
|
||||||
IsRegionalized: boxedFalse,
|
|
||||||
PartitionEndpoint: "aws-global",
|
|
||||||
Endpoints: endpoints{
|
|
||||||
"aws-global": endpoint{
|
|
||||||
Hostname: "169.254.169.254/latest",
|
|
||||||
Protocols: []string{"http"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func custRmIotDataService(p *partition) {
|
|
||||||
delete(p.Services, "data.iot")
|
|
||||||
}
|
|
||||||
|
|
||||||
func custFixAppAutoscalingChina(p *partition) {
|
|
||||||
if p.ID != "aws-cn" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const serviceName = "application-autoscaling"
|
|
||||||
s, ok := p.Services[serviceName]
|
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const expectHostname = `autoscaling.{region}.amazonaws.com`
|
|
||||||
if e, a := s.Defaults.Hostname, expectHostname; e != a {
|
|
||||||
fmt.Printf("custFixAppAutoscalingChina: ignoring customization, expected %s, got %s\n", e, a)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Defaults.Hostname = expectHostname + ".cn"
|
|
||||||
p.Services[serviceName] = s
|
|
||||||
}
|
|
||||||
|
|
||||||
type decodeModelError struct {
|
|
||||||
awsError
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDecodeModelError(msg string, err error) decodeModelError {
|
|
||||||
return decodeModelError{
|
|
||||||
awsError: awserr.New("DecodeEndpointsModelError", msg, err),
|
|
||||||
}
|
|
||||||
}
|
|
3736
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
3736
vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
generated
vendored
File diff suppressed because it is too large
Load Diff
66
vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go
generated
vendored
66
vendor/github.com/aws/aws-sdk-go/aws/endpoints/doc.go
generated
vendored
@ -1,66 +0,0 @@
|
|||||||
// Package endpoints provides the types and functionality for defining regions
|
|
||||||
// and endpoints, as well as querying those definitions.
|
|
||||||
//
|
|
||||||
// The SDK's Regions and Endpoints metadata is code generated into the endpoints
|
|
||||||
// package, and is accessible via the DefaultResolver function. This function
|
|
||||||
// returns a endpoint Resolver will search the metadata and build an associated
|
|
||||||
// endpoint if one is found. The default resolver will search all partitions
|
|
||||||
// known by the SDK. e.g AWS Standard (aws), AWS China (aws-cn), and
|
|
||||||
// AWS GovCloud (US) (aws-us-gov).
|
|
||||||
// .
|
|
||||||
//
|
|
||||||
// Enumerating Regions and Endpoint Metadata
|
|
||||||
//
|
|
||||||
// Casting the Resolver returned by DefaultResolver to a EnumPartitions interface
|
|
||||||
// will allow you to get access to the list of underlying Partitions with the
|
|
||||||
// Partitions method. This is helpful if you want to limit the SDK's endpoint
|
|
||||||
// resolving to a single partition, or enumerate regions, services, and endpoints
|
|
||||||
// in the partition.
|
|
||||||
//
|
|
||||||
// resolver := endpoints.DefaultResolver()
|
|
||||||
// partitions := resolver.(endpoints.EnumPartitions).Partitions()
|
|
||||||
//
|
|
||||||
// for _, p := range partitions {
|
|
||||||
// fmt.Println("Regions for", p.ID())
|
|
||||||
// for id, _ := range p.Regions() {
|
|
||||||
// fmt.Println("*", id)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fmt.Println("Services for", p.ID())
|
|
||||||
// for id, _ := range p.Services() {
|
|
||||||
// fmt.Println("*", id)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Using Custom Endpoints
|
|
||||||
//
|
|
||||||
// The endpoints package also gives you the ability to use your own logic how
|
|
||||||
// endpoints are resolved. This is a great way to define a custom endpoint
|
|
||||||
// for select services, without passing that logic down through your code.
|
|
||||||
//
|
|
||||||
// If a type implements the Resolver interface it can be used to resolve
|
|
||||||
// endpoints. To use this with the SDK's Session and Config set the value
|
|
||||||
// of the type to the EndpointsResolver field of aws.Config when initializing
|
|
||||||
// the session, or service client.
|
|
||||||
//
|
|
||||||
// In addition the ResolverFunc is a wrapper for a func matching the signature
|
|
||||||
// of Resolver.EndpointFor, converting it to a type that satisfies the
|
|
||||||
// Resolver interface.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// myCustomResolver := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
|
|
||||||
// if service == endpoints.S3ServiceID {
|
|
||||||
// return endpoints.ResolvedEndpoint{
|
|
||||||
// URL: "s3.custom.endpoint.com",
|
|
||||||
// SigningRegion: "custom-signing-region",
|
|
||||||
// }, nil
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return endpoints.DefaultResolver().EndpointFor(service, region, optFns...)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// sess := session.Must(session.NewSession(&aws.Config{
|
|
||||||
// Region: aws.String("us-west-2"),
|
|
||||||
// EndpointResolver: endpoints.ResolverFunc(myCustomResolver),
|
|
||||||
// }))
|
|
||||||
package endpoints
|
|
449
vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
generated
vendored
449
vendor/github.com/aws/aws-sdk-go/aws/endpoints/endpoints.go
generated
vendored
@ -1,449 +0,0 @@
|
|||||||
package endpoints
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Options provide the configuration needed to direct how the
|
|
||||||
// endpoints will be resolved.
|
|
||||||
type Options struct {
|
|
||||||
// DisableSSL forces the endpoint to be resolved as HTTP.
|
|
||||||
// instead of HTTPS if the service supports it.
|
|
||||||
DisableSSL bool
|
|
||||||
|
|
||||||
// Sets the resolver to resolve the endpoint as a dualstack endpoint
|
|
||||||
// for the service. If dualstack support for a service is not known and
|
|
||||||
// StrictMatching is not enabled a dualstack endpoint for the service will
|
|
||||||
// be returned. This endpoint may not be valid. If StrictMatching is
|
|
||||||
// enabled only services that are known to support dualstack will return
|
|
||||||
// dualstack endpoints.
|
|
||||||
UseDualStack bool
|
|
||||||
|
|
||||||
// Enables strict matching of services and regions resolved endpoints.
|
|
||||||
// If the partition doesn't enumerate the exact service and region an
|
|
||||||
// error will be returned. This option will prevent returning endpoints
|
|
||||||
// that look valid, but may not resolve to any real endpoint.
|
|
||||||
StrictMatching bool
|
|
||||||
|
|
||||||
// Enables resolving a service endpoint based on the region provided if the
|
|
||||||
// service does not exist. The service endpoint ID will be used as the service
|
|
||||||
// domain name prefix. By default the endpoint resolver requires the service
|
|
||||||
// to be known when resolving endpoints.
|
|
||||||
//
|
|
||||||
// If resolving an endpoint on the partition list the provided region will
|
|
||||||
// be used to determine which partition's domain name pattern to the service
|
|
||||||
// endpoint ID with. If both the service and region are unkonwn and resolving
|
|
||||||
// the endpoint on partition list an UnknownEndpointError error will be returned.
|
|
||||||
//
|
|
||||||
// If resolving and endpoint on a partition specific resolver that partition's
|
|
||||||
// domain name pattern will be used with the service endpoint ID. If both
|
|
||||||
// region and service do not exist when resolving an endpoint on a specific
|
|
||||||
// partition the partition's domain pattern will be used to combine the
|
|
||||||
// endpoint and region together.
|
|
||||||
//
|
|
||||||
// This option is ignored if StrictMatching is enabled.
|
|
||||||
ResolveUnknownService bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set combines all of the option functions together.
|
|
||||||
func (o *Options) Set(optFns ...func(*Options)) {
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(o)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DisableSSLOption sets the DisableSSL options. Can be used as a functional
|
|
||||||
// option when resolving endpoints.
|
|
||||||
func DisableSSLOption(o *Options) {
|
|
||||||
o.DisableSSL = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// UseDualStackOption sets the UseDualStack option. Can be used as a functional
|
|
||||||
// option when resolving endpoints.
|
|
||||||
func UseDualStackOption(o *Options) {
|
|
||||||
o.UseDualStack = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// StrictMatchingOption sets the StrictMatching option. Can be used as a functional
|
|
||||||
// option when resolving endpoints.
|
|
||||||
func StrictMatchingOption(o *Options) {
|
|
||||||
o.StrictMatching = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResolveUnknownServiceOption sets the ResolveUnknownService option. Can be used
|
|
||||||
// as a functional option when resolving endpoints.
|
|
||||||
func ResolveUnknownServiceOption(o *Options) {
|
|
||||||
o.ResolveUnknownService = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Resolver provides the interface for functionality to resolve endpoints.
|
|
||||||
// The build in Partition and DefaultResolver return value satisfy this interface.
|
|
||||||
type Resolver interface {
|
|
||||||
EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResolverFunc is a helper utility that wraps a function so it satisfies the
|
|
||||||
// Resolver interface. This is useful when you want to add additional endpoint
|
|
||||||
// resolving logic, or stub out specific endpoints with custom values.
|
|
||||||
type ResolverFunc func(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error)
|
|
||||||
|
|
||||||
// EndpointFor wraps the ResolverFunc function to satisfy the Resolver interface.
|
|
||||||
func (fn ResolverFunc) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
return fn(service, region, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
var schemeRE = regexp.MustCompile("^([^:]+)://")
|
|
||||||
|
|
||||||
// AddScheme adds the HTTP or HTTPS schemes to a endpoint URL if there is no
|
|
||||||
// scheme. If disableSSL is true HTTP will set HTTP instead of the default HTTPS.
|
|
||||||
//
|
|
||||||
// If disableSSL is set, it will only set the URL's scheme if the URL does not
|
|
||||||
// contain a scheme.
|
|
||||||
func AddScheme(endpoint string, disableSSL bool) string {
|
|
||||||
if !schemeRE.MatchString(endpoint) {
|
|
||||||
scheme := "https"
|
|
||||||
if disableSSL {
|
|
||||||
scheme = "http"
|
|
||||||
}
|
|
||||||
endpoint = fmt.Sprintf("%s://%s", scheme, endpoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
return endpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
// EnumPartitions a provides a way to retrieve the underlying partitions that
|
|
||||||
// make up the SDK's default Resolver, or any resolver decoded from a model
|
|
||||||
// file.
|
|
||||||
//
|
|
||||||
// Use this interface with DefaultResolver and DecodeModels to get the list of
|
|
||||||
// Partitions.
|
|
||||||
type EnumPartitions interface {
|
|
||||||
Partitions() []Partition
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegionsForService returns a map of regions for the partition and service.
|
|
||||||
// If either the partition or service does not exist false will be returned
|
|
||||||
// as the second parameter.
|
|
||||||
//
|
|
||||||
// This example shows how to get the regions for DynamoDB in the AWS partition.
|
|
||||||
// rs, exists := endpoints.RegionsForService(endpoints.DefaultPartitions(), endpoints.AwsPartitionID, endpoints.DynamodbServiceID)
|
|
||||||
//
|
|
||||||
// This is equivalent to using the partition directly.
|
|
||||||
// rs := endpoints.AwsPartition().Services()[endpoints.DynamodbServiceID].Regions()
|
|
||||||
func RegionsForService(ps []Partition, partitionID, serviceID string) (map[string]Region, bool) {
|
|
||||||
for _, p := range ps {
|
|
||||||
if p.ID() != partitionID {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, ok := p.p.Services[serviceID]; !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
s := Service{
|
|
||||||
id: serviceID,
|
|
||||||
p: p.p,
|
|
||||||
}
|
|
||||||
return s.Regions(), true
|
|
||||||
}
|
|
||||||
|
|
||||||
return map[string]Region{}, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// PartitionForRegion returns the first partition which includes the region
|
|
||||||
// passed in. This includes both known regions and regions which match
|
|
||||||
// a pattern supported by the partition which may include regions that are
|
|
||||||
// not explicitly known by the partition. Use the Regions method of the
|
|
||||||
// returned Partition if explicit support is needed.
|
|
||||||
func PartitionForRegion(ps []Partition, regionID string) (Partition, bool) {
|
|
||||||
for _, p := range ps {
|
|
||||||
if _, ok := p.p.Regions[regionID]; ok || p.p.RegionRegex.MatchString(regionID) {
|
|
||||||
return p, true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Partition{}, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Partition provides the ability to enumerate the partition's regions
|
|
||||||
// and services.
|
|
||||||
type Partition struct {
|
|
||||||
id string
|
|
||||||
p *partition
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the identifier of the partition.
|
|
||||||
func (p Partition) ID() string { return p.id }
|
|
||||||
|
|
||||||
// EndpointFor attempts to resolve the endpoint based on service and region.
|
|
||||||
// See Options for information on configuring how the endpoint is resolved.
|
|
||||||
//
|
|
||||||
// If the service cannot be found in the metadata the UnknownServiceError
|
|
||||||
// error will be returned. This validation will occur regardless if
|
|
||||||
// StrictMatching is enabled. To enable resolving unknown services set the
|
|
||||||
// "ResolveUnknownService" option to true. When StrictMatching is disabled
|
|
||||||
// this option allows the partition resolver to resolve a endpoint based on
|
|
||||||
// the service endpoint ID provided.
|
|
||||||
//
|
|
||||||
// When resolving endpoints you can choose to enable StrictMatching. This will
|
|
||||||
// require the provided service and region to be known by the partition.
|
|
||||||
// If the endpoint cannot be strictly resolved an error will be returned. This
|
|
||||||
// mode is useful to ensure the endpoint resolved is valid. Without
|
|
||||||
// StrictMatching enabled the endpoint returned my look valid but may not work.
|
|
||||||
// StrictMatching requires the SDK to be updated if you want to take advantage
|
|
||||||
// of new regions and services expansions.
|
|
||||||
//
|
|
||||||
// Errors that can be returned.
|
|
||||||
// * UnknownServiceError
|
|
||||||
// * UnknownEndpointError
|
|
||||||
func (p Partition) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
return p.p.EndpointFor(service, region, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regions returns a map of Regions indexed by their ID. This is useful for
|
|
||||||
// enumerating over the regions in a partition.
|
|
||||||
func (p Partition) Regions() map[string]Region {
|
|
||||||
rs := map[string]Region{}
|
|
||||||
for id, r := range p.p.Regions {
|
|
||||||
rs[id] = Region{
|
|
||||||
id: id,
|
|
||||||
desc: r.Description,
|
|
||||||
p: p.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
// Services returns a map of Service indexed by their ID. This is useful for
|
|
||||||
// enumerating over the services in a partition.
|
|
||||||
func (p Partition) Services() map[string]Service {
|
|
||||||
ss := map[string]Service{}
|
|
||||||
for id := range p.p.Services {
|
|
||||||
ss[id] = Service{
|
|
||||||
id: id,
|
|
||||||
p: p.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Region provides information about a region, and ability to resolve an
|
|
||||||
// endpoint from the context of a region, given a service.
|
|
||||||
type Region struct {
|
|
||||||
id, desc string
|
|
||||||
p *partition
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the region's identifier.
|
|
||||||
func (r Region) ID() string { return r.id }
|
|
||||||
|
|
||||||
// Description returns the region's description. The region description
|
|
||||||
// is free text, it can be empty, and it may change between SDK releases.
|
|
||||||
func (r Region) Description() string { return r.desc }
|
|
||||||
|
|
||||||
// ResolveEndpoint resolves an endpoint from the context of the region given
|
|
||||||
// a service. See Partition.EndpointFor for usage and errors that can be returned.
|
|
||||||
func (r Region) ResolveEndpoint(service string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
return r.p.EndpointFor(service, r.id, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Services returns a list of all services that are known to be in this region.
|
|
||||||
func (r Region) Services() map[string]Service {
|
|
||||||
ss := map[string]Service{}
|
|
||||||
for id, s := range r.p.Services {
|
|
||||||
if _, ok := s.Endpoints[r.id]; ok {
|
|
||||||
ss[id] = Service{
|
|
||||||
id: id,
|
|
||||||
p: r.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ss
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Service provides information about a service, and ability to resolve an
|
|
||||||
// endpoint from the context of a service, given a region.
|
|
||||||
type Service struct {
|
|
||||||
id string
|
|
||||||
p *partition
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the identifier for the service.
|
|
||||||
func (s Service) ID() string { return s.id }
|
|
||||||
|
|
||||||
// ResolveEndpoint resolves an endpoint from the context of a service given
|
|
||||||
// a region. See Partition.EndpointFor for usage and errors that can be returned.
|
|
||||||
func (s Service) ResolveEndpoint(region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
return s.p.EndpointFor(s.id, region, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Regions returns a map of Regions that the service is present in.
|
|
||||||
//
|
|
||||||
// A region is the AWS region the service exists in. Whereas a Endpoint is
|
|
||||||
// an URL that can be resolved to a instance of a service.
|
|
||||||
func (s Service) Regions() map[string]Region {
|
|
||||||
rs := map[string]Region{}
|
|
||||||
for id := range s.p.Services[s.id].Endpoints {
|
|
||||||
if r, ok := s.p.Regions[id]; ok {
|
|
||||||
rs[id] = Region{
|
|
||||||
id: id,
|
|
||||||
desc: r.Description,
|
|
||||||
p: s.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rs
|
|
||||||
}
|
|
||||||
|
|
||||||
// Endpoints returns a map of Endpoints indexed by their ID for all known
|
|
||||||
// endpoints for a service.
|
|
||||||
//
|
|
||||||
// A region is the AWS region the service exists in. Whereas a Endpoint is
|
|
||||||
// an URL that can be resolved to a instance of a service.
|
|
||||||
func (s Service) Endpoints() map[string]Endpoint {
|
|
||||||
es := map[string]Endpoint{}
|
|
||||||
for id := range s.p.Services[s.id].Endpoints {
|
|
||||||
es[id] = Endpoint{
|
|
||||||
id: id,
|
|
||||||
serviceID: s.id,
|
|
||||||
p: s.p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return es
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Endpoint provides information about endpoints, and provides the ability
|
|
||||||
// to resolve that endpoint for the service, and the region the endpoint
|
|
||||||
// represents.
|
|
||||||
type Endpoint struct {
|
|
||||||
id string
|
|
||||||
serviceID string
|
|
||||||
p *partition
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the identifier for an endpoint.
|
|
||||||
func (e Endpoint) ID() string { return e.id }
|
|
||||||
|
|
||||||
// ServiceID returns the identifier the endpoint belongs to.
|
|
||||||
func (e Endpoint) ServiceID() string { return e.serviceID }
|
|
||||||
|
|
||||||
// ResolveEndpoint resolves an endpoint from the context of a service and
|
|
||||||
// region the endpoint represents. See Partition.EndpointFor for usage and
|
|
||||||
// errors that can be returned.
|
|
||||||
func (e Endpoint) ResolveEndpoint(opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
return e.p.EndpointFor(e.serviceID, e.id, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A ResolvedEndpoint is an endpoint that has been resolved based on a partition
|
|
||||||
// service, and region.
|
|
||||||
type ResolvedEndpoint struct {
|
|
||||||
// The endpoint URL
|
|
||||||
URL string
|
|
||||||
|
|
||||||
// The region that should be used for signing requests.
|
|
||||||
SigningRegion string
|
|
||||||
|
|
||||||
// The service name that should be used for signing requests.
|
|
||||||
SigningName string
|
|
||||||
|
|
||||||
// States that the signing name for this endpoint was derived from metadata
|
|
||||||
// passed in, but was not explicitly modeled.
|
|
||||||
SigningNameDerived bool
|
|
||||||
|
|
||||||
// The signing method that should be used for signing requests.
|
|
||||||
SigningMethod string
|
|
||||||
}
|
|
||||||
|
|
||||||
// So that the Error interface type can be included as an anonymous field
|
|
||||||
// in the requestError struct and not conflict with the error.Error() method.
|
|
||||||
type awsError awserr.Error
|
|
||||||
|
|
||||||
// A EndpointNotFoundError is returned when in StrictMatching mode, and the
|
|
||||||
// endpoint for the service and region cannot be found in any of the partitions.
|
|
||||||
type EndpointNotFoundError struct {
|
|
||||||
awsError
|
|
||||||
Partition string
|
|
||||||
Service string
|
|
||||||
Region string
|
|
||||||
}
|
|
||||||
|
|
||||||
// A UnknownServiceError is returned when the service does not resolve to an
|
|
||||||
// endpoint. Includes a list of all known services for the partition. Returned
|
|
||||||
// when a partition does not support the service.
|
|
||||||
type UnknownServiceError struct {
|
|
||||||
awsError
|
|
||||||
Partition string
|
|
||||||
Service string
|
|
||||||
Known []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUnknownServiceError builds and returns UnknownServiceError.
|
|
||||||
func NewUnknownServiceError(p, s string, known []string) UnknownServiceError {
|
|
||||||
return UnknownServiceError{
|
|
||||||
awsError: awserr.New("UnknownServiceError",
|
|
||||||
"could not resolve endpoint for unknown service", nil),
|
|
||||||
Partition: p,
|
|
||||||
Service: s,
|
|
||||||
Known: known,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
func (e UnknownServiceError) Error() string {
|
|
||||||
extra := fmt.Sprintf("partition: %q, service: %q",
|
|
||||||
e.Partition, e.Service)
|
|
||||||
if len(e.Known) > 0 {
|
|
||||||
extra += fmt.Sprintf(", known: %v", e.Known)
|
|
||||||
}
|
|
||||||
return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
func (e UnknownServiceError) String() string {
|
|
||||||
return e.Error()
|
|
||||||
}
|
|
||||||
|
|
||||||
// A UnknownEndpointError is returned when in StrictMatching mode and the
|
|
||||||
// service is valid, but the region does not resolve to an endpoint. Includes
|
|
||||||
// a list of all known endpoints for the service.
|
|
||||||
type UnknownEndpointError struct {
|
|
||||||
awsError
|
|
||||||
Partition string
|
|
||||||
Service string
|
|
||||||
Region string
|
|
||||||
Known []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUnknownEndpointError builds and returns UnknownEndpointError.
|
|
||||||
func NewUnknownEndpointError(p, s, r string, known []string) UnknownEndpointError {
|
|
||||||
return UnknownEndpointError{
|
|
||||||
awsError: awserr.New("UnknownEndpointError",
|
|
||||||
"could not resolve endpoint", nil),
|
|
||||||
Partition: p,
|
|
||||||
Service: s,
|
|
||||||
Region: r,
|
|
||||||
Known: known,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
func (e UnknownEndpointError) Error() string {
|
|
||||||
extra := fmt.Sprintf("partition: %q, service: %q, region: %q",
|
|
||||||
e.Partition, e.Service, e.Region)
|
|
||||||
if len(e.Known) > 0 {
|
|
||||||
extra += fmt.Sprintf(", known: %v", e.Known)
|
|
||||||
}
|
|
||||||
return awserr.SprintError(e.Code(), e.Message(), extra, e.OrigErr())
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the error.
|
|
||||||
func (e UnknownEndpointError) String() string {
|
|
||||||
return e.Error()
|
|
||||||
}
|
|
307
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go
generated
vendored
307
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model.go
generated
vendored
@ -1,307 +0,0 @@
|
|||||||
package endpoints
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type partitions []partition
|
|
||||||
|
|
||||||
func (ps partitions) EndpointFor(service, region string, opts ...func(*Options)) (ResolvedEndpoint, error) {
|
|
||||||
var opt Options
|
|
||||||
opt.Set(opts...)
|
|
||||||
|
|
||||||
for i := 0; i < len(ps); i++ {
|
|
||||||
if !ps[i].canResolveEndpoint(service, region, opt.StrictMatching) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
return ps[i].EndpointFor(service, region, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If loose matching fallback to first partition format to use
|
|
||||||
// when resolving the endpoint.
|
|
||||||
if !opt.StrictMatching && len(ps) > 0 {
|
|
||||||
return ps[0].EndpointFor(service, region, opts...)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResolvedEndpoint{}, NewUnknownEndpointError("all partitions", service, region, []string{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Partitions satisfies the EnumPartitions interface and returns a list
|
|
||||||
// of Partitions representing each partition represented in the SDK's
|
|
||||||
// endpoints model.
|
|
||||||
func (ps partitions) Partitions() []Partition {
|
|
||||||
parts := make([]Partition, 0, len(ps))
|
|
||||||
for i := 0; i < len(ps); i++ {
|
|
||||||
parts = append(parts, ps[i].Partition())
|
|
||||||
}
|
|
||||||
|
|
||||||
return parts
|
|
||||||
}
|
|
||||||
|
|
||||||
type partition struct {
|
|
||||||
ID string `json:"partition"`
|
|
||||||
Name string `json:"partitionName"`
|
|
||||||
DNSSuffix string `json:"dnsSuffix"`
|
|
||||||
RegionRegex regionRegex `json:"regionRegex"`
|
|
||||||
Defaults endpoint `json:"defaults"`
|
|
||||||
Regions regions `json:"regions"`
|
|
||||||
Services services `json:"services"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p partition) Partition() Partition {
|
|
||||||
return Partition{
|
|
||||||
id: p.ID,
|
|
||||||
p: &p,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p partition) canResolveEndpoint(service, region string, strictMatch bool) bool {
|
|
||||||
s, hasService := p.Services[service]
|
|
||||||
_, hasEndpoint := s.Endpoints[region]
|
|
||||||
|
|
||||||
if hasEndpoint && hasService {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if strictMatch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return p.RegionRegex.MatchString(region)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p partition) EndpointFor(service, region string, opts ...func(*Options)) (resolved ResolvedEndpoint, err error) {
|
|
||||||
var opt Options
|
|
||||||
opt.Set(opts...)
|
|
||||||
|
|
||||||
s, hasService := p.Services[service]
|
|
||||||
if !(hasService || opt.ResolveUnknownService) {
|
|
||||||
// Only return error if the resolver will not fallback to creating
|
|
||||||
// endpoint based on service endpoint ID passed in.
|
|
||||||
return resolved, NewUnknownServiceError(p.ID, service, serviceList(p.Services))
|
|
||||||
}
|
|
||||||
|
|
||||||
e, hasEndpoint := s.endpointForRegion(region)
|
|
||||||
if !hasEndpoint && opt.StrictMatching {
|
|
||||||
return resolved, NewUnknownEndpointError(p.ID, service, region, endpointList(s.Endpoints))
|
|
||||||
}
|
|
||||||
|
|
||||||
defs := []endpoint{p.Defaults, s.Defaults}
|
|
||||||
return e.resolve(service, region, p.DNSSuffix, defs, opt), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func serviceList(ss services) []string {
|
|
||||||
list := make([]string, 0, len(ss))
|
|
||||||
for k := range ss {
|
|
||||||
list = append(list, k)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
func endpointList(es endpoints) []string {
|
|
||||||
list := make([]string, 0, len(es))
|
|
||||||
for k := range es {
|
|
||||||
list = append(list, k)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|
||||||
type regionRegex struct {
|
|
||||||
*regexp.Regexp
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rr *regionRegex) UnmarshalJSON(b []byte) (err error) {
|
|
||||||
// Strip leading and trailing quotes
|
|
||||||
regex, err := strconv.Unquote(string(b))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to strip quotes from regex, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
rr.Regexp, err = regexp.Compile(regex)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to unmarshal region regex, %v", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type regions map[string]region
|
|
||||||
|
|
||||||
type region struct {
|
|
||||||
Description string `json:"description"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type services map[string]service
|
|
||||||
|
|
||||||
type service struct {
|
|
||||||
PartitionEndpoint string `json:"partitionEndpoint"`
|
|
||||||
IsRegionalized boxedBool `json:"isRegionalized,omitempty"`
|
|
||||||
Defaults endpoint `json:"defaults"`
|
|
||||||
Endpoints endpoints `json:"endpoints"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *service) endpointForRegion(region string) (endpoint, bool) {
|
|
||||||
if s.IsRegionalized == boxedFalse {
|
|
||||||
return s.Endpoints[s.PartitionEndpoint], region == s.PartitionEndpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
if e, ok := s.Endpoints[region]; ok {
|
|
||||||
return e, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unable to find any matching endpoint, return
|
|
||||||
// blank that will be used for generic endpoint creation.
|
|
||||||
return endpoint{}, false
|
|
||||||
}
|
|
||||||
|
|
||||||
type endpoints map[string]endpoint
|
|
||||||
|
|
||||||
type endpoint struct {
|
|
||||||
Hostname string `json:"hostname"`
|
|
||||||
Protocols []string `json:"protocols"`
|
|
||||||
CredentialScope credentialScope `json:"credentialScope"`
|
|
||||||
|
|
||||||
// Custom fields not modeled
|
|
||||||
HasDualStack boxedBool `json:"-"`
|
|
||||||
DualStackHostname string `json:"-"`
|
|
||||||
|
|
||||||
// Signature Version not used
|
|
||||||
SignatureVersions []string `json:"signatureVersions"`
|
|
||||||
|
|
||||||
// SSLCommonName not used.
|
|
||||||
SSLCommonName string `json:"sslCommonName"`
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
defaultProtocol = "https"
|
|
||||||
defaultSigner = "v4"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
protocolPriority = []string{"https", "http"}
|
|
||||||
signerPriority = []string{"v4", "v2"}
|
|
||||||
)
|
|
||||||
|
|
||||||
func getByPriority(s []string, p []string, def string) string {
|
|
||||||
if len(s) == 0 {
|
|
||||||
return def
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < len(p); i++ {
|
|
||||||
for j := 0; j < len(s); j++ {
|
|
||||||
if s[j] == p[i] {
|
|
||||||
return s[j]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return s[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e endpoint) resolve(service, region, dnsSuffix string, defs []endpoint, opts Options) ResolvedEndpoint {
|
|
||||||
var merged endpoint
|
|
||||||
for _, def := range defs {
|
|
||||||
merged.mergeIn(def)
|
|
||||||
}
|
|
||||||
merged.mergeIn(e)
|
|
||||||
e = merged
|
|
||||||
|
|
||||||
hostname := e.Hostname
|
|
||||||
|
|
||||||
// Offset the hostname for dualstack if enabled
|
|
||||||
if opts.UseDualStack && e.HasDualStack == boxedTrue {
|
|
||||||
hostname = e.DualStackHostname
|
|
||||||
}
|
|
||||||
|
|
||||||
u := strings.Replace(hostname, "{service}", service, 1)
|
|
||||||
u = strings.Replace(u, "{region}", region, 1)
|
|
||||||
u = strings.Replace(u, "{dnsSuffix}", dnsSuffix, 1)
|
|
||||||
|
|
||||||
scheme := getEndpointScheme(e.Protocols, opts.DisableSSL)
|
|
||||||
u = fmt.Sprintf("%s://%s", scheme, u)
|
|
||||||
|
|
||||||
signingRegion := e.CredentialScope.Region
|
|
||||||
if len(signingRegion) == 0 {
|
|
||||||
signingRegion = region
|
|
||||||
}
|
|
||||||
|
|
||||||
signingName := e.CredentialScope.Service
|
|
||||||
var signingNameDerived bool
|
|
||||||
if len(signingName) == 0 {
|
|
||||||
signingName = service
|
|
||||||
signingNameDerived = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return ResolvedEndpoint{
|
|
||||||
URL: u,
|
|
||||||
SigningRegion: signingRegion,
|
|
||||||
SigningName: signingName,
|
|
||||||
SigningNameDerived: signingNameDerived,
|
|
||||||
SigningMethod: getByPriority(e.SignatureVersions, signerPriority, defaultSigner),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getEndpointScheme(protocols []string, disableSSL bool) string {
|
|
||||||
if disableSSL {
|
|
||||||
return "http"
|
|
||||||
}
|
|
||||||
|
|
||||||
return getByPriority(protocols, protocolPriority, defaultProtocol)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *endpoint) mergeIn(other endpoint) {
|
|
||||||
if len(other.Hostname) > 0 {
|
|
||||||
e.Hostname = other.Hostname
|
|
||||||
}
|
|
||||||
if len(other.Protocols) > 0 {
|
|
||||||
e.Protocols = other.Protocols
|
|
||||||
}
|
|
||||||
if len(other.SignatureVersions) > 0 {
|
|
||||||
e.SignatureVersions = other.SignatureVersions
|
|
||||||
}
|
|
||||||
if len(other.CredentialScope.Region) > 0 {
|
|
||||||
e.CredentialScope.Region = other.CredentialScope.Region
|
|
||||||
}
|
|
||||||
if len(other.CredentialScope.Service) > 0 {
|
|
||||||
e.CredentialScope.Service = other.CredentialScope.Service
|
|
||||||
}
|
|
||||||
if len(other.SSLCommonName) > 0 {
|
|
||||||
e.SSLCommonName = other.SSLCommonName
|
|
||||||
}
|
|
||||||
if other.HasDualStack != boxedBoolUnset {
|
|
||||||
e.HasDualStack = other.HasDualStack
|
|
||||||
}
|
|
||||||
if len(other.DualStackHostname) > 0 {
|
|
||||||
e.DualStackHostname = other.DualStackHostname
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type credentialScope struct {
|
|
||||||
Region string `json:"region"`
|
|
||||||
Service string `json:"service"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type boxedBool int
|
|
||||||
|
|
||||||
func (b *boxedBool) UnmarshalJSON(buf []byte) error {
|
|
||||||
v, err := strconv.ParseBool(string(buf))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if v {
|
|
||||||
*b = boxedTrue
|
|
||||||
} else {
|
|
||||||
*b = boxedFalse
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
boxedBoolUnset boxedBool = iota
|
|
||||||
boxedFalse
|
|
||||||
boxedTrue
|
|
||||||
)
|
|
337
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go
generated
vendored
337
vendor/github.com/aws/aws-sdk-go/aws/endpoints/v3model_codegen.go
generated
vendored
@ -1,337 +0,0 @@
|
|||||||
// +build codegen
|
|
||||||
|
|
||||||
package endpoints
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"text/template"
|
|
||||||
"unicode"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A CodeGenOptions are the options for code generating the endpoints into
|
|
||||||
// Go code from the endpoints model definition.
|
|
||||||
type CodeGenOptions struct {
|
|
||||||
// Options for how the model will be decoded.
|
|
||||||
DecodeModelOptions DecodeModelOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set combines all of the option functions together
|
|
||||||
func (d *CodeGenOptions) Set(optFns ...func(*CodeGenOptions)) {
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(d)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// CodeGenModel given a endpoints model file will decode it and attempt to
|
|
||||||
// generate Go code from the model definition. Error will be returned if
|
|
||||||
// the code is unable to be generated, or decoded.
|
|
||||||
func CodeGenModel(modelFile io.Reader, outFile io.Writer, optFns ...func(*CodeGenOptions)) error {
|
|
||||||
var opts CodeGenOptions
|
|
||||||
opts.Set(optFns...)
|
|
||||||
|
|
||||||
resolver, err := DecodeModel(modelFile, func(d *DecodeModelOptions) {
|
|
||||||
*d = opts.DecodeModelOptions
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpl := template.Must(template.New("tmpl").Funcs(funcMap).Parse(v3Tmpl))
|
|
||||||
if err := tmpl.ExecuteTemplate(outFile, "defaults", resolver); err != nil {
|
|
||||||
return fmt.Errorf("failed to execute template, %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func toSymbol(v string) string {
|
|
||||||
out := []rune{}
|
|
||||||
for _, c := range strings.Title(v) {
|
|
||||||
if !(unicode.IsNumber(c) || unicode.IsLetter(c)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
out = append(out, c)
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
func quoteString(v string) string {
|
|
||||||
return fmt.Sprintf("%q", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func regionConstName(p, r string) string {
|
|
||||||
return toSymbol(p) + toSymbol(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
func partitionGetter(id string) string {
|
|
||||||
return fmt.Sprintf("%sPartition", toSymbol(id))
|
|
||||||
}
|
|
||||||
|
|
||||||
func partitionVarName(id string) string {
|
|
||||||
return fmt.Sprintf("%sPartition", strings.ToLower(toSymbol(id)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func listPartitionNames(ps partitions) string {
|
|
||||||
names := []string{}
|
|
||||||
switch len(ps) {
|
|
||||||
case 1:
|
|
||||||
return ps[0].Name
|
|
||||||
case 2:
|
|
||||||
return fmt.Sprintf("%s and %s", ps[0].Name, ps[1].Name)
|
|
||||||
default:
|
|
||||||
for i, p := range ps {
|
|
||||||
if i == len(ps)-1 {
|
|
||||||
names = append(names, "and "+p.Name)
|
|
||||||
} else {
|
|
||||||
names = append(names, p.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strings.Join(names, ", ")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func boxedBoolIfSet(msg string, v boxedBool) string {
|
|
||||||
switch v {
|
|
||||||
case boxedTrue:
|
|
||||||
return fmt.Sprintf(msg, "boxedTrue")
|
|
||||||
case boxedFalse:
|
|
||||||
return fmt.Sprintf(msg, "boxedFalse")
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringIfSet(msg, v string) string {
|
|
||||||
if len(v) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf(msg, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringSliceIfSet(msg string, vs []string) string {
|
|
||||||
if len(vs) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
names := []string{}
|
|
||||||
for _, v := range vs {
|
|
||||||
names = append(names, `"`+v+`"`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf(msg, strings.Join(names, ","))
|
|
||||||
}
|
|
||||||
|
|
||||||
func endpointIsSet(v endpoint) bool {
|
|
||||||
return !reflect.DeepEqual(v, endpoint{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func serviceSet(ps partitions) map[string]struct{} {
|
|
||||||
set := map[string]struct{}{}
|
|
||||||
for _, p := range ps {
|
|
||||||
for id := range p.Services {
|
|
||||||
set[id] = struct{}{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return set
|
|
||||||
}
|
|
||||||
|
|
||||||
var funcMap = template.FuncMap{
|
|
||||||
"ToSymbol": toSymbol,
|
|
||||||
"QuoteString": quoteString,
|
|
||||||
"RegionConst": regionConstName,
|
|
||||||
"PartitionGetter": partitionGetter,
|
|
||||||
"PartitionVarName": partitionVarName,
|
|
||||||
"ListPartitionNames": listPartitionNames,
|
|
||||||
"BoxedBoolIfSet": boxedBoolIfSet,
|
|
||||||
"StringIfSet": stringIfSet,
|
|
||||||
"StringSliceIfSet": stringSliceIfSet,
|
|
||||||
"EndpointIsSet": endpointIsSet,
|
|
||||||
"ServicesSet": serviceSet,
|
|
||||||
}
|
|
||||||
|
|
||||||
const v3Tmpl = `
|
|
||||||
{{ define "defaults" -}}
|
|
||||||
// Code generated by aws/endpoints/v3model_codegen.go. DO NOT EDIT.
|
|
||||||
|
|
||||||
package endpoints
|
|
||||||
|
|
||||||
import (
|
|
||||||
"regexp"
|
|
||||||
)
|
|
||||||
|
|
||||||
{{ template "partition consts" . }}
|
|
||||||
|
|
||||||
{{ range $_, $partition := . }}
|
|
||||||
{{ template "partition region consts" $partition }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ template "service consts" . }}
|
|
||||||
|
|
||||||
{{ template "endpoint resolvers" . }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "partition consts" }}
|
|
||||||
// Partition identifiers
|
|
||||||
const (
|
|
||||||
{{ range $_, $p := . -}}
|
|
||||||
{{ ToSymbol $p.ID }}PartitionID = {{ QuoteString $p.ID }} // {{ $p.Name }} partition.
|
|
||||||
{{ end -}}
|
|
||||||
)
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "partition region consts" }}
|
|
||||||
// {{ .Name }} partition's regions.
|
|
||||||
const (
|
|
||||||
{{ range $id, $region := .Regions -}}
|
|
||||||
{{ ToSymbol $id }}RegionID = {{ QuoteString $id }} // {{ $region.Description }}.
|
|
||||||
{{ end -}}
|
|
||||||
)
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "service consts" }}
|
|
||||||
// Service identifiers
|
|
||||||
const (
|
|
||||||
{{ $serviceSet := ServicesSet . -}}
|
|
||||||
{{ range $id, $_ := $serviceSet -}}
|
|
||||||
{{ ToSymbol $id }}ServiceID = {{ QuoteString $id }} // {{ ToSymbol $id }}.
|
|
||||||
{{ end -}}
|
|
||||||
)
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "endpoint resolvers" }}
|
|
||||||
// DefaultResolver returns an Endpoint resolver that will be able
|
|
||||||
// to resolve endpoints for: {{ ListPartitionNames . }}.
|
|
||||||
//
|
|
||||||
// Use DefaultPartitions() to get the list of the default partitions.
|
|
||||||
func DefaultResolver() Resolver {
|
|
||||||
return defaultPartitions
|
|
||||||
}
|
|
||||||
|
|
||||||
// DefaultPartitions returns a list of the partitions the SDK is bundled
|
|
||||||
// with. The available partitions are: {{ ListPartitionNames . }}.
|
|
||||||
//
|
|
||||||
// partitions := endpoints.DefaultPartitions
|
|
||||||
// for _, p := range partitions {
|
|
||||||
// // ... inspect partitions
|
|
||||||
// }
|
|
||||||
func DefaultPartitions() []Partition {
|
|
||||||
return defaultPartitions.Partitions()
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultPartitions = partitions{
|
|
||||||
{{ range $_, $partition := . -}}
|
|
||||||
{{ PartitionVarName $partition.ID }},
|
|
||||||
{{ end }}
|
|
||||||
}
|
|
||||||
|
|
||||||
{{ range $_, $partition := . -}}
|
|
||||||
{{ $name := PartitionGetter $partition.ID -}}
|
|
||||||
// {{ $name }} returns the Resolver for {{ $partition.Name }}.
|
|
||||||
func {{ $name }}() Partition {
|
|
||||||
return {{ PartitionVarName $partition.ID }}.Partition()
|
|
||||||
}
|
|
||||||
var {{ PartitionVarName $partition.ID }} = {{ template "gocode Partition" $partition }}
|
|
||||||
{{ end }}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ define "default partitions" }}
|
|
||||||
func DefaultPartitions() []Partition {
|
|
||||||
return []partition{
|
|
||||||
{{ range $_, $partition := . -}}
|
|
||||||
// {{ ToSymbol $partition.ID}}Partition(),
|
|
||||||
{{ end }}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ define "gocode Partition" -}}
|
|
||||||
partition{
|
|
||||||
{{ StringIfSet "ID: %q,\n" .ID -}}
|
|
||||||
{{ StringIfSet "Name: %q,\n" .Name -}}
|
|
||||||
{{ StringIfSet "DNSSuffix: %q,\n" .DNSSuffix -}}
|
|
||||||
RegionRegex: {{ template "gocode RegionRegex" .RegionRegex }},
|
|
||||||
{{ if EndpointIsSet .Defaults -}}
|
|
||||||
Defaults: {{ template "gocode Endpoint" .Defaults }},
|
|
||||||
{{- end }}
|
|
||||||
Regions: {{ template "gocode Regions" .Regions }},
|
|
||||||
Services: {{ template "gocode Services" .Services }},
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode RegionRegex" -}}
|
|
||||||
regionRegex{
|
|
||||||
Regexp: func() *regexp.Regexp{
|
|
||||||
reg, _ := regexp.Compile({{ QuoteString .Regexp.String }})
|
|
||||||
return reg
|
|
||||||
}(),
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Regions" -}}
|
|
||||||
regions{
|
|
||||||
{{ range $id, $region := . -}}
|
|
||||||
"{{ $id }}": {{ template "gocode Region" $region }},
|
|
||||||
{{ end -}}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Region" -}}
|
|
||||||
region{
|
|
||||||
{{ StringIfSet "Description: %q,\n" .Description -}}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Services" -}}
|
|
||||||
services{
|
|
||||||
{{ range $id, $service := . -}}
|
|
||||||
"{{ $id }}": {{ template "gocode Service" $service }},
|
|
||||||
{{ end }}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Service" -}}
|
|
||||||
service{
|
|
||||||
{{ StringIfSet "PartitionEndpoint: %q,\n" .PartitionEndpoint -}}
|
|
||||||
{{ BoxedBoolIfSet "IsRegionalized: %s,\n" .IsRegionalized -}}
|
|
||||||
{{ if EndpointIsSet .Defaults -}}
|
|
||||||
Defaults: {{ template "gocode Endpoint" .Defaults -}},
|
|
||||||
{{- end }}
|
|
||||||
{{ if .Endpoints -}}
|
|
||||||
Endpoints: {{ template "gocode Endpoints" .Endpoints }},
|
|
||||||
{{- end }}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Endpoints" -}}
|
|
||||||
endpoints{
|
|
||||||
{{ range $id, $endpoint := . -}}
|
|
||||||
"{{ $id }}": {{ template "gocode Endpoint" $endpoint }},
|
|
||||||
{{ end }}
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{ define "gocode Endpoint" -}}
|
|
||||||
endpoint{
|
|
||||||
{{ StringIfSet "Hostname: %q,\n" .Hostname -}}
|
|
||||||
{{ StringIfSet "SSLCommonName: %q,\n" .SSLCommonName -}}
|
|
||||||
{{ StringSliceIfSet "Protocols: []string{%s},\n" .Protocols -}}
|
|
||||||
{{ StringSliceIfSet "SignatureVersions: []string{%s},\n" .SignatureVersions -}}
|
|
||||||
{{ if or .CredentialScope.Region .CredentialScope.Service -}}
|
|
||||||
CredentialScope: credentialScope{
|
|
||||||
{{ StringIfSet "Region: %q,\n" .CredentialScope.Region -}}
|
|
||||||
{{ StringIfSet "Service: %q,\n" .CredentialScope.Service -}}
|
|
||||||
},
|
|
||||||
{{- end }}
|
|
||||||
{{ BoxedBoolIfSet "HasDualStack: %s,\n" .HasDualStack -}}
|
|
||||||
{{ StringIfSet "DualStackHostname: %q,\n" .DualStackHostname -}}
|
|
||||||
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
`
|
|
13
vendor/github.com/aws/aws-sdk-go/aws/errors.go
generated
vendored
13
vendor/github.com/aws/aws-sdk-go/aws/errors.go
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
import "github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrMissingRegion is an error that is returned if region configuration is
|
|
||||||
// not found.
|
|
||||||
ErrMissingRegion = awserr.New("MissingRegion", "could not find region configuration", nil)
|
|
||||||
|
|
||||||
// ErrMissingEndpoint is an error that is returned if an endpoint cannot be
|
|
||||||
// resolved for a service.
|
|
||||||
ErrMissingEndpoint = awserr.New("MissingEndpoint", "'Endpoint' configuration is required for this service", nil)
|
|
||||||
)
|
|
12
vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go
generated
vendored
12
vendor/github.com/aws/aws-sdk-go/aws/jsonvalue.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
// JSONValue is a representation of a grab bag type that will be marshaled
|
|
||||||
// into a json string. This type can be used just like any other map.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// values := aws.JSONValue{
|
|
||||||
// "Foo": "Bar",
|
|
||||||
// }
|
|
||||||
// values["Baz"] = "Qux"
|
|
||||||
type JSONValue map[string]interface{}
|
|
118
vendor/github.com/aws/aws-sdk-go/aws/logger.go
generated
vendored
118
vendor/github.com/aws/aws-sdk-go/aws/logger.go
generated
vendored
@ -1,118 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A LogLevelType defines the level logging should be performed at. Used to instruct
|
|
||||||
// the SDK which statements should be logged.
|
|
||||||
type LogLevelType uint
|
|
||||||
|
|
||||||
// LogLevel returns the pointer to a LogLevel. Should be used to workaround
|
|
||||||
// not being able to take the address of a non-composite literal.
|
|
||||||
func LogLevel(l LogLevelType) *LogLevelType {
|
|
||||||
return &l
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value returns the LogLevel value or the default value LogOff if the LogLevel
|
|
||||||
// is nil. Safe to use on nil value LogLevelTypes.
|
|
||||||
func (l *LogLevelType) Value() LogLevelType {
|
|
||||||
if l != nil {
|
|
||||||
return *l
|
|
||||||
}
|
|
||||||
return LogOff
|
|
||||||
}
|
|
||||||
|
|
||||||
// Matches returns true if the v LogLevel is enabled by this LogLevel. Should be
|
|
||||||
// used with logging sub levels. Is safe to use on nil value LogLevelTypes. If
|
|
||||||
// LogLevel is nil, will default to LogOff comparison.
|
|
||||||
func (l *LogLevelType) Matches(v LogLevelType) bool {
|
|
||||||
c := l.Value()
|
|
||||||
return c&v == v
|
|
||||||
}
|
|
||||||
|
|
||||||
// AtLeast returns true if this LogLevel is at least high enough to satisfies v.
|
|
||||||
// Is safe to use on nil value LogLevelTypes. If LogLevel is nil, will default
|
|
||||||
// to LogOff comparison.
|
|
||||||
func (l *LogLevelType) AtLeast(v LogLevelType) bool {
|
|
||||||
c := l.Value()
|
|
||||||
return c >= v
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
// LogOff states that no logging should be performed by the SDK. This is the
|
|
||||||
// default state of the SDK, and should be use to disable all logging.
|
|
||||||
LogOff LogLevelType = iota * 0x1000
|
|
||||||
|
|
||||||
// LogDebug state that debug output should be logged by the SDK. This should
|
|
||||||
// be used to inspect request made and responses received.
|
|
||||||
LogDebug
|
|
||||||
)
|
|
||||||
|
|
||||||
// Debug Logging Sub Levels
|
|
||||||
const (
|
|
||||||
// LogDebugWithSigning states that the SDK should log request signing and
|
|
||||||
// presigning events. This should be used to log the signing details of
|
|
||||||
// requests for debugging. Will also enable LogDebug.
|
|
||||||
LogDebugWithSigning LogLevelType = LogDebug | (1 << iota)
|
|
||||||
|
|
||||||
// LogDebugWithHTTPBody states the SDK should log HTTP request and response
|
|
||||||
// HTTP bodys in addition to the headers and path. This should be used to
|
|
||||||
// see the body content of requests and responses made while using the SDK
|
|
||||||
// Will also enable LogDebug.
|
|
||||||
LogDebugWithHTTPBody
|
|
||||||
|
|
||||||
// LogDebugWithRequestRetries states the SDK should log when service requests will
|
|
||||||
// be retried. This should be used to log when you want to log when service
|
|
||||||
// requests are being retried. Will also enable LogDebug.
|
|
||||||
LogDebugWithRequestRetries
|
|
||||||
|
|
||||||
// LogDebugWithRequestErrors states the SDK should log when service requests fail
|
|
||||||
// to build, send, validate, or unmarshal.
|
|
||||||
LogDebugWithRequestErrors
|
|
||||||
|
|
||||||
// LogDebugWithEventStreamBody states the SDK should log EventStream
|
|
||||||
// request and response bodys. This should be used to log the EventStream
|
|
||||||
// wire unmarshaled message content of requests and responses made while
|
|
||||||
// using the SDK Will also enable LogDebug.
|
|
||||||
LogDebugWithEventStreamBody
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Logger is a minimalistic interface for the SDK to log messages to. Should
|
|
||||||
// be used to provide custom logging writers for the SDK to use.
|
|
||||||
type Logger interface {
|
|
||||||
Log(...interface{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// A LoggerFunc is a convenience type to convert a function taking a variadic
|
|
||||||
// list of arguments and wrap it so the Logger interface can be used.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// s3.New(sess, &aws.Config{Logger: aws.LoggerFunc(func(args ...interface{}) {
|
|
||||||
// fmt.Fprintln(os.Stdout, args...)
|
|
||||||
// })})
|
|
||||||
type LoggerFunc func(...interface{})
|
|
||||||
|
|
||||||
// Log calls the wrapped function with the arguments provided
|
|
||||||
func (f LoggerFunc) Log(args ...interface{}) {
|
|
||||||
f(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDefaultLogger returns a Logger which will write log messages to stdout, and
|
|
||||||
// use same formatting runes as the stdlib log.Logger
|
|
||||||
func NewDefaultLogger() Logger {
|
|
||||||
return &defaultLogger{
|
|
||||||
logger: log.New(os.Stdout, "", log.LstdFlags),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A defaultLogger provides a minimalistic logger satisfying the Logger interface.
|
|
||||||
type defaultLogger struct {
|
|
||||||
logger *log.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log logs the parameters to the stdlib logger. See log.Println.
|
|
||||||
func (l defaultLogger) Log(args ...interface{}) {
|
|
||||||
l.logger.Println(args...)
|
|
||||||
}
|
|
19
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go
generated
vendored
19
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error.go
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
// +build !appengine,!plan9
|
|
||||||
|
|
||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func isErrConnectionReset(err error) bool {
|
|
||||||
if opErr, ok := err.(*net.OpError); ok {
|
|
||||||
if sysErr, ok := opErr.Err.(*os.SyscallError); ok {
|
|
||||||
return sysErr.Err == syscall.ECONNRESET
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
11
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other.go
generated
vendored
11
vendor/github.com/aws/aws-sdk-go/aws/request/connection_reset_error_other.go
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
// +build appengine plan9
|
|
||||||
|
|
||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func isErrConnectionReset(err error) bool {
|
|
||||||
return strings.Contains(err.Error(), "connection reset")
|
|
||||||
}
|
|
274
vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go
generated
vendored
274
vendor/github.com/aws/aws-sdk-go/aws/request/handlers.go
generated
vendored
@ -1,274 +0,0 @@
|
|||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Handlers provides a collection of request handlers for various
|
|
||||||
// stages of handling requests.
|
|
||||||
type Handlers struct {
|
|
||||||
Validate HandlerList
|
|
||||||
Build HandlerList
|
|
||||||
Sign HandlerList
|
|
||||||
Send HandlerList
|
|
||||||
ValidateResponse HandlerList
|
|
||||||
Unmarshal HandlerList
|
|
||||||
UnmarshalStream HandlerList
|
|
||||||
UnmarshalMeta HandlerList
|
|
||||||
UnmarshalError HandlerList
|
|
||||||
Retry HandlerList
|
|
||||||
AfterRetry HandlerList
|
|
||||||
Complete HandlerList
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy returns of this handler's lists.
|
|
||||||
func (h *Handlers) Copy() Handlers {
|
|
||||||
return Handlers{
|
|
||||||
Validate: h.Validate.copy(),
|
|
||||||
Build: h.Build.copy(),
|
|
||||||
Sign: h.Sign.copy(),
|
|
||||||
Send: h.Send.copy(),
|
|
||||||
ValidateResponse: h.ValidateResponse.copy(),
|
|
||||||
Unmarshal: h.Unmarshal.copy(),
|
|
||||||
UnmarshalStream: h.UnmarshalStream.copy(),
|
|
||||||
UnmarshalError: h.UnmarshalError.copy(),
|
|
||||||
UnmarshalMeta: h.UnmarshalMeta.copy(),
|
|
||||||
Retry: h.Retry.copy(),
|
|
||||||
AfterRetry: h.AfterRetry.copy(),
|
|
||||||
Complete: h.Complete.copy(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear removes callback functions for all handlers
|
|
||||||
func (h *Handlers) Clear() {
|
|
||||||
h.Validate.Clear()
|
|
||||||
h.Build.Clear()
|
|
||||||
h.Send.Clear()
|
|
||||||
h.Sign.Clear()
|
|
||||||
h.Unmarshal.Clear()
|
|
||||||
h.UnmarshalStream.Clear()
|
|
||||||
h.UnmarshalMeta.Clear()
|
|
||||||
h.UnmarshalError.Clear()
|
|
||||||
h.ValidateResponse.Clear()
|
|
||||||
h.Retry.Clear()
|
|
||||||
h.AfterRetry.Clear()
|
|
||||||
h.Complete.Clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
// A HandlerListRunItem represents an entry in the HandlerList which
|
|
||||||
// is being run.
|
|
||||||
type HandlerListRunItem struct {
|
|
||||||
Index int
|
|
||||||
Handler NamedHandler
|
|
||||||
Request *Request
|
|
||||||
}
|
|
||||||
|
|
||||||
// A HandlerList manages zero or more handlers in a list.
|
|
||||||
type HandlerList struct {
|
|
||||||
list []NamedHandler
|
|
||||||
|
|
||||||
// Called after each request handler in the list is called. If set
|
|
||||||
// and the func returns true the HandlerList will continue to iterate
|
|
||||||
// over the request handlers. If false is returned the HandlerList
|
|
||||||
// will stop iterating.
|
|
||||||
//
|
|
||||||
// Should be used if extra logic to be performed between each handler
|
|
||||||
// in the list. This can be used to terminate a list's iteration
|
|
||||||
// based on a condition such as error like, HandlerListStopOnError.
|
|
||||||
// Or for logging like HandlerListLogItem.
|
|
||||||
AfterEachFn func(item HandlerListRunItem) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// A NamedHandler is a struct that contains a name and function callback.
|
|
||||||
type NamedHandler struct {
|
|
||||||
Name string
|
|
||||||
Fn func(*Request)
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy creates a copy of the handler list.
|
|
||||||
func (l *HandlerList) copy() HandlerList {
|
|
||||||
n := HandlerList{
|
|
||||||
AfterEachFn: l.AfterEachFn,
|
|
||||||
}
|
|
||||||
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 = l.list[0:0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len returns the number of handlers in the list.
|
|
||||||
func (l *HandlerList) Len() int {
|
|
||||||
return len(l.list)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushBack pushes handler f to the back of the handler list.
|
|
||||||
func (l *HandlerList) PushBack(f func(*Request)) {
|
|
||||||
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) {
|
|
||||||
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) {
|
|
||||||
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--
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SwapNamed will swap out any existing handlers with the same name as the
|
|
||||||
// passed in NamedHandler returning true if handlers were swapped. False is
|
|
||||||
// returned otherwise.
|
|
||||||
func (l *HandlerList) SwapNamed(n NamedHandler) (swapped bool) {
|
|
||||||
for i := 0; i < len(l.list); i++ {
|
|
||||||
if l.list[i].Name == n.Name {
|
|
||||||
l.list[i].Fn = n.Fn
|
|
||||||
swapped = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return swapped
|
|
||||||
}
|
|
||||||
|
|
||||||
// Swap will swap out all handlers matching the name passed in. The matched
|
|
||||||
// handlers will be swapped in. True is returned if the handlers were swapped.
|
|
||||||
func (l *HandlerList) Swap(name string, replace NamedHandler) bool {
|
|
||||||
var swapped bool
|
|
||||||
|
|
||||||
for i := 0; i < len(l.list); i++ {
|
|
||||||
if l.list[i].Name == name {
|
|
||||||
l.list[i] = replace
|
|
||||||
swapped = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return swapped
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBackNamed will replace the named handler if it exists in the handler list.
|
|
||||||
// If the handler does not exist the handler will be added to the end of the list.
|
|
||||||
func (l *HandlerList) SetBackNamed(n NamedHandler) {
|
|
||||||
if !l.SwapNamed(n) {
|
|
||||||
l.PushBackNamed(n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFrontNamed will replace the named handler if it exists in the handler list.
|
|
||||||
// If the handler does not exist the handler will be added to the beginning of
|
|
||||||
// the list.
|
|
||||||
func (l *HandlerList) SetFrontNamed(n NamedHandler) {
|
|
||||||
if !l.SwapNamed(n) {
|
|
||||||
l.PushFrontNamed(n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run executes all handlers in the list with a given request object.
|
|
||||||
func (l *HandlerList) Run(r *Request) {
|
|
||||||
for i, h := range l.list {
|
|
||||||
h.Fn(r)
|
|
||||||
item := HandlerListRunItem{
|
|
||||||
Index: i, Handler: h, Request: r,
|
|
||||||
}
|
|
||||||
if l.AfterEachFn != nil && !l.AfterEachFn(item) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandlerListLogItem logs the request handler and the state of the
|
|
||||||
// request's Error value. Always returns true to continue iterating
|
|
||||||
// request handlers in a HandlerList.
|
|
||||||
func HandlerListLogItem(item HandlerListRunItem) bool {
|
|
||||||
if item.Request.Config.Logger == nil {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
item.Request.Config.Logger.Log("DEBUG: RequestHandler",
|
|
||||||
item.Index, item.Handler.Name, item.Request.Error)
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandlerListStopOnError returns false to stop the HandlerList iterating
|
|
||||||
// over request handlers if Request.Error is not nil. True otherwise
|
|
||||||
// to continue iterating.
|
|
||||||
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.
|
|
||||||
// "name/version (extra0; extra1; ...)"
|
|
||||||
// The user agent part will be concatenated with this current request's user agent string.
|
|
||||||
func MakeAddToUserAgentHandler(name, version string, extra ...string) func(*Request) {
|
|
||||||
ua := fmt.Sprintf("%s/%s", name, version)
|
|
||||||
if len(extra) > 0 {
|
|
||||||
ua += fmt.Sprintf(" (%s)", strings.Join(extra, "; "))
|
|
||||||
}
|
|
||||||
return func(r *Request) {
|
|
||||||
AddToUserAgent(r, ua)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MakeAddToUserAgentFreeFormHandler adds the input to the User-Agent request header.
|
|
||||||
// The input string will be concatenated with the current request's user agent string.
|
|
||||||
func MakeAddToUserAgentFreeFormHandler(s string) func(*Request) {
|
|
||||||
return func(r *Request) {
|
|
||||||
AddToUserAgent(r, s)
|
|
||||||
}
|
|
||||||
}
|
|
24
vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go
generated
vendored
24
vendor/github.com/aws/aws-sdk-go/aws/request/http_request.go
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
)
|
|
||||||
|
|
||||||
func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request {
|
|
||||||
req := new(http.Request)
|
|
||||||
*req = *r
|
|
||||||
req.URL = &url.URL{}
|
|
||||||
*req.URL = *r.URL
|
|
||||||
req.Body = body
|
|
||||||
|
|
||||||
req.Header = http.Header{}
|
|
||||||
for k, v := range r.Header {
|
|
||||||
for _, vv := range v {
|
|
||||||
req.Header.Add(k, vv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return req
|
|
||||||
}
|
|
60
vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go
generated
vendored
60
vendor/github.com/aws/aws-sdk-go/aws/request/offset_reader.go
generated
vendored
@ -1,60 +0,0 @@
|
|||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkio"
|
|
||||||
)
|
|
||||||
|
|
||||||
// offsetReader is a thread-safe io.ReadCloser to prevent racing
|
|
||||||
// with retrying requests
|
|
||||||
type offsetReader struct {
|
|
||||||
buf io.ReadSeeker
|
|
||||||
lock sync.Mutex
|
|
||||||
closed bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader {
|
|
||||||
reader := &offsetReader{}
|
|
||||||
buf.Seek(offset, sdkio.SeekStart)
|
|
||||||
|
|
||||||
reader.buf = buf
|
|
||||||
return reader
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close will close the instance of the offset reader's access to
|
|
||||||
// the underlying io.ReadSeeker.
|
|
||||||
func (o *offsetReader) Close() error {
|
|
||||||
o.lock.Lock()
|
|
||||||
defer o.lock.Unlock()
|
|
||||||
o.closed = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read is a thread-safe read of the underlying io.ReadSeeker
|
|
||||||
func (o *offsetReader) Read(p []byte) (int, error) {
|
|
||||||
o.lock.Lock()
|
|
||||||
defer o.lock.Unlock()
|
|
||||||
|
|
||||||
if o.closed {
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
return o.buf.Read(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek is a thread-safe seeking operation.
|
|
||||||
func (o *offsetReader) Seek(offset int64, whence int) (int64, error) {
|
|
||||||
o.lock.Lock()
|
|
||||||
defer o.lock.Unlock()
|
|
||||||
|
|
||||||
return o.buf.Seek(offset, whence)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloseAndCopy will return a new offsetReader with a copy of the old buffer
|
|
||||||
// and close the old buffer.
|
|
||||||
func (o *offsetReader) CloseAndCopy(offset int64) *offsetReader {
|
|
||||||
o.Close()
|
|
||||||
return newOffsetReader(o.buf, offset)
|
|
||||||
}
|
|
661
vendor/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
661
vendor/github.com/aws/aws-sdk-go/aws/request/request.go
generated
vendored
@ -1,661 +0,0 @@
|
|||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"reflect"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkio"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ErrCodeSerialization is the serialization error code that is received
|
|
||||||
// during protocol unmarshaling.
|
|
||||||
ErrCodeSerialization = "SerializationError"
|
|
||||||
|
|
||||||
// ErrCodeRead is an error that is returned during HTTP reads.
|
|
||||||
ErrCodeRead = "ReadError"
|
|
||||||
|
|
||||||
// ErrCodeResponseTimeout is the connection timeout error that is received
|
|
||||||
// during body reads.
|
|
||||||
ErrCodeResponseTimeout = "ResponseTimeout"
|
|
||||||
|
|
||||||
// ErrCodeInvalidPresignExpire is returned when the expire time provided to
|
|
||||||
// presign is invalid
|
|
||||||
ErrCodeInvalidPresignExpire = "InvalidPresignExpireError"
|
|
||||||
|
|
||||||
// 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
|
|
||||||
ClientInfo metadata.ClientInfo
|
|
||||||
Handlers Handlers
|
|
||||||
|
|
||||||
Retryer
|
|
||||||
AttemptTime time.Time
|
|
||||||
Time time.Time
|
|
||||||
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
|
|
||||||
|
|
||||||
// A value greater than 0 instructs the request to be signed as Presigned URL
|
|
||||||
// You should not set this field directly. Instead use Request's
|
|
||||||
// Presign or PresignRequest methods.
|
|
||||||
ExpireTime time.Duration
|
|
||||||
|
|
||||||
context aws.Context
|
|
||||||
|
|
||||||
built bool
|
|
||||||
|
|
||||||
// Need to persist an intermediate body between the input Body and HTTP
|
|
||||||
// request body because the HTTP Client's transport can maintain a reference
|
|
||||||
// to the HTTP request's body after the client has returned. This value is
|
|
||||||
// safe to use concurrently and wrap the input Body for each HTTP request.
|
|
||||||
safeBody *offsetReader
|
|
||||||
}
|
|
||||||
|
|
||||||
// An Operation is the service API operation to be made.
|
|
||||||
type Operation struct {
|
|
||||||
Name string
|
|
||||||
HTTPMethod string
|
|
||||||
HTTPPath string
|
|
||||||
*Paginator
|
|
||||||
|
|
||||||
BeforePresignFn func(r *Request) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// New returns a new Request pointer for the service API
|
|
||||||
// operation and parameters.
|
|
||||||
//
|
|
||||||
// Params is any value of input parameters to be the request payload.
|
|
||||||
// Data is pointer value to an object which the request's response
|
|
||||||
// payload will be deserialized to.
|
|
||||||
func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers,
|
|
||||||
retryer Retryer, operation *Operation, params interface{}, data interface{}) *Request {
|
|
||||||
|
|
||||||
method := operation.HTTPMethod
|
|
||||||
if method == "" {
|
|
||||||
method = "POST"
|
|
||||||
}
|
|
||||||
|
|
||||||
httpReq, _ := http.NewRequest(method, "", nil)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
httpReq.URL, err = url.Parse(clientInfo.Endpoint + operation.HTTPPath)
|
|
||||||
if err != nil {
|
|
||||||
httpReq.URL = &url.URL{}
|
|
||||||
err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
SanitizeHostForHeader(httpReq)
|
|
||||||
|
|
||||||
r := &Request{
|
|
||||||
Config: cfg,
|
|
||||||
ClientInfo: clientInfo,
|
|
||||||
Handlers: handlers.Copy(),
|
|
||||||
|
|
||||||
Retryer: retryer,
|
|
||||||
AttemptTime: time.Now(),
|
|
||||||
Time: time.Now(),
|
|
||||||
ExpireTime: 0,
|
|
||||||
Operation: operation,
|
|
||||||
HTTPRequest: httpReq,
|
|
||||||
Body: nil,
|
|
||||||
Params: params,
|
|
||||||
Error: err,
|
|
||||||
Data: data,
|
|
||||||
}
|
|
||||||
r.SetBufferBody([]byte{})
|
|
||||||
|
|
||||||
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 {
|
|
||||||
if !aws.IsReaderSeekable(r.Body) && r.HTTPRequest.Body != NoBody {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return r.Error != nil && aws.BoolValue(r.Retryable) && r.RetryCount < r.MaxRetries()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParamsFilled returns if the request's parameters have been populated
|
|
||||||
// and the parameters are valid. False is returned if no parameters are
|
|
||||||
// provided or invalid.
|
|
||||||
func (r *Request) ParamsFilled() bool {
|
|
||||||
return r.Params != nil && reflect.ValueOf(r.Params).Elem().IsValid()
|
|
||||||
}
|
|
||||||
|
|
||||||
// DataFilled returns true if the request's data for response deserialization
|
|
||||||
// target has been set and is a valid. False is returned if data is not
|
|
||||||
// set, or is invalid.
|
|
||||||
func (r *Request) DataFilled() bool {
|
|
||||||
return r.Data != nil && reflect.ValueOf(r.Data).Elem().IsValid()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBufferBody will set the request's body bytes that will be sent to
|
|
||||||
// the service API.
|
|
||||||
func (r *Request) SetBufferBody(buf []byte) {
|
|
||||||
r.SetReaderBody(bytes.NewReader(buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetStringBody sets the body of the request to be backed by a string.
|
|
||||||
func (r *Request) SetStringBody(s string) {
|
|
||||||
r.SetReaderBody(strings.NewReader(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetReaderBody will set the request's body reader.
|
|
||||||
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
|
||||||
r.Body = reader
|
|
||||||
r.BodyStart, _ = reader.Seek(0, sdkio.SeekCurrent) // Get the Bodies current offset.
|
|
||||||
r.ResetBody()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Presign returns the request's signed URL. Error will be returned
|
|
||||||
// if the signing fails. The expire parameter is only used for presigned Amazon
|
|
||||||
// S3 API requests. All other AWS services will use a fixed expriation
|
|
||||||
// time of 15 minutes.
|
|
||||||
//
|
|
||||||
// It is invalid to create a presigned URL with a expire duration 0 or less. An
|
|
||||||
// error is returned if expire duration is 0 or less.
|
|
||||||
func (r *Request) Presign(expire time.Duration) (string, error) {
|
|
||||||
r = r.copy()
|
|
||||||
|
|
||||||
// Presign requires all headers be hoisted. There is no way to retrieve
|
|
||||||
// the signed headers not hoisted without this. Making the presigned URL
|
|
||||||
// useless.
|
|
||||||
r.NotHoist = false
|
|
||||||
|
|
||||||
u, _, err := getPresignedURL(r, expire)
|
|
||||||
return u, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// PresignRequest behaves just like presign, with the addition of returning a
|
|
||||||
// set of headers that were signed. The expire parameter is only used for
|
|
||||||
// presigned Amazon S3 API requests. All other AWS services will use a fixed
|
|
||||||
// expriation time of 15 minutes.
|
|
||||||
//
|
|
||||||
// It is invalid to create a presigned URL with a expire duration 0 or less. An
|
|
||||||
// error is returned if expire duration is 0 or less.
|
|
||||||
//
|
|
||||||
// Returns the URL string for the API operation with signature in the query string,
|
|
||||||
// and the HTTP headers that were included in the signature. These headers must
|
|
||||||
// be included in any HTTP request made with the presigned URL.
|
|
||||||
//
|
|
||||||
// To prevent hoisting any headers to the query string set NotHoist to true on
|
|
||||||
// this Request value prior to calling PresignRequest.
|
|
||||||
func (r *Request) PresignRequest(expire time.Duration) (string, http.Header, error) {
|
|
||||||
r = r.copy()
|
|
||||||
return getPresignedURL(r, expire)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsPresigned returns true if the request represents a presigned API url.
|
|
||||||
func (r *Request) IsPresigned() bool {
|
|
||||||
return r.ExpireTime != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func getPresignedURL(r *Request, expire time.Duration) (string, http.Header, error) {
|
|
||||||
if expire <= 0 {
|
|
||||||
return "", nil, awserr.New(
|
|
||||||
ErrCodeInvalidPresignExpire,
|
|
||||||
"presigned URL requires an expire duration greater than 0",
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
r.ExpireTime = expire
|
|
||||||
|
|
||||||
if r.Operation.BeforePresignFn != nil {
|
|
||||||
if err := r.Operation.BeforePresignFn(r); err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := r.Sign(); err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.HTTPRequest.URL.String(), r.SignedHeaderVals, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func debugLogReqError(r *Request, stage string, retrying bool, err error) {
|
|
||||||
if !r.Config.LogLevel.Matches(aws.LogDebugWithRequestErrors) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
retryStr := "not retrying"
|
|
||||||
if retrying {
|
|
||||||
retryStr = "will retry"
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf("DEBUG: %s %s/%s failed, %s, error %v",
|
|
||||||
stage, r.ClientInfo.ServiceName, r.Operation.Name, retryStr, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build will build the request's object so it can be signed and sent
|
|
||||||
// to the service. Build will also validate all the request's parameters.
|
|
||||||
// Any additional build Handlers set on this request will be run
|
|
||||||
// in the order they were set.
|
|
||||||
//
|
|
||||||
// The request will only be built once. Multiple calls to build will have
|
|
||||||
// no effect.
|
|
||||||
//
|
|
||||||
// If any Validate or Build errors occur the build will stop and the error
|
|
||||||
// which occurred will be returned.
|
|
||||||
func (r *Request) Build() error {
|
|
||||||
if !r.built {
|
|
||||||
r.Handlers.Validate.Run(r)
|
|
||||||
if r.Error != nil {
|
|
||||||
debugLogReqError(r, "Validate Request", false, r.Error)
|
|
||||||
return r.Error
|
|
||||||
}
|
|
||||||
r.Handlers.Build.Run(r)
|
|
||||||
if r.Error != nil {
|
|
||||||
debugLogReqError(r, "Build Request", false, r.Error)
|
|
||||||
return r.Error
|
|
||||||
}
|
|
||||||
r.built = true
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign will sign the request, returning error if errors are encountered.
|
|
||||||
//
|
|
||||||
// Sign will build the request prior to signing. All Sign Handlers will
|
|
||||||
// be executed in the order they were set.
|
|
||||||
func (r *Request) Sign() error {
|
|
||||||
r.Build()
|
|
||||||
if r.Error != nil {
|
|
||||||
debugLogReqError(r, "Build Request", false, r.Error)
|
|
||||||
return r.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Handlers.Sign.Run(r)
|
|
||||||
return r.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Request) getNextRequestBody() (io.ReadCloser, error) {
|
|
||||||
if r.safeBody != nil {
|
|
||||||
r.safeBody.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
r.safeBody = newOffsetReader(r.Body, r.BodyStart)
|
|
||||||
|
|
||||||
// Go 1.8 tightened and clarified the rules code needs to use when building
|
|
||||||
// requests with the http package. Go 1.8 removed the automatic detection
|
|
||||||
// of if the Request.Body was empty, or actually had bytes in it. The SDK
|
|
||||||
// always sets the Request.Body even if it is empty and should not actually
|
|
||||||
// be sent. This is incorrect.
|
|
||||||
//
|
|
||||||
// Go 1.8 did add a http.NoBody value that the SDK can use to tell the http
|
|
||||||
// client that the request really should be sent without a body. The
|
|
||||||
// Request.Body cannot be set to nil, which is preferable, because the
|
|
||||||
// field is exported and could introduce nil pointer dereferences for users
|
|
||||||
// of the SDK if they used that field.
|
|
||||||
//
|
|
||||||
// Related golang/go#18257
|
|
||||||
l, err := aws.SeekerLen(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, awserr.New(ErrCodeSerialization, "failed to compute request body size", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var body io.ReadCloser
|
|
||||||
if l == 0 {
|
|
||||||
body = NoBody
|
|
||||||
} else if l > 0 {
|
|
||||||
body = r.safeBody
|
|
||||||
} else {
|
|
||||||
// Hack to prevent sending bodies for methods where the body
|
|
||||||
// should be ignored by the server. Sending bodies on these
|
|
||||||
// methods without an associated ContentLength will cause the
|
|
||||||
// request to socket timeout because the server does not handle
|
|
||||||
// Transfer-Encoding: chunked bodies for these methods.
|
|
||||||
//
|
|
||||||
// This would only happen if a aws.ReaderSeekerCloser was used with
|
|
||||||
// a io.Reader that was not also an io.Seeker, or did not implement
|
|
||||||
// Len() method.
|
|
||||||
switch r.Operation.HTTPMethod {
|
|
||||||
case "GET", "HEAD", "DELETE":
|
|
||||||
body = NoBody
|
|
||||||
default:
|
|
||||||
body = r.safeBody
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return body, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetBody will return an io.ReadSeeker of the Request's underlying
|
|
||||||
// input body with a concurrency safe wrapper.
|
|
||||||
func (r *Request) GetBody() io.ReadSeeker {
|
|
||||||
return r.safeBody
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send will send the request, returning error if errors are encountered.
|
|
||||||
//
|
|
||||||
// Send will sign the request prior to sending. All Send Handlers will
|
|
||||||
// be executed in the order they were set.
|
|
||||||
//
|
|
||||||
// Canceling a request is non-deterministic. If a request has been canceled,
|
|
||||||
// then the transport will choose, randomly, one of the state channels during
|
|
||||||
// reads or getting the connection.
|
|
||||||
//
|
|
||||||
// readLoop() and getConn(req *Request, cm connectMethod)
|
|
||||||
// https://github.com/golang/go/blob/master/src/net/http/transport.go
|
|
||||||
//
|
|
||||||
// Send will not close the request.Request's body.
|
|
||||||
func (r *Request) Send() error {
|
|
||||||
defer func() {
|
|
||||||
// Regardless of success or failure of the request trigger the Complete
|
|
||||||
// request handlers.
|
|
||||||
r.Handlers.Complete.Run(r)
|
|
||||||
}()
|
|
||||||
|
|
||||||
for {
|
|
||||||
r.AttemptTime = time.Now()
|
|
||||||
if aws.BoolValue(r.Retryable) {
|
|
||||||
if r.Config.LogLevel.Matches(aws.LogDebugWithRequestRetries) {
|
|
||||||
r.Config.Logger.Log(fmt.Sprintf("DEBUG: Retrying Request %s/%s, attempt %d",
|
|
||||||
r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount))
|
|
||||||
}
|
|
||||||
|
|
||||||
// The previous http.Request will have a reference to the r.Body
|
|
||||||
// and the HTTP Client's Transport may still be reading from
|
|
||||||
// the request's body even though the Client's Do returned.
|
|
||||||
r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil)
|
|
||||||
r.ResetBody()
|
|
||||||
|
|
||||||
// Closing response body to ensure that no response body is leaked
|
|
||||||
// between retry attempts.
|
|
||||||
if r.HTTPResponse != nil && r.HTTPResponse.Body != nil {
|
|
||||||
r.HTTPResponse.Body.Close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Sign()
|
|
||||||
if r.Error != nil {
|
|
||||||
return r.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Retryable = nil
|
|
||||||
|
|
||||||
r.Handlers.Send.Run(r)
|
|
||||||
if r.Error != nil {
|
|
||||||
if !shouldRetryCancel(r) {
|
|
||||||
return r.Error
|
|
||||||
}
|
|
||||||
|
|
||||||
err := r.Error
|
|
||||||
r.Handlers.Retry.Run(r)
|
|
||||||
r.Handlers.AfterRetry.Run(r)
|
|
||||||
if r.Error != nil {
|
|
||||||
debugLogReqError(r, "Send Request", false, err)
|
|
||||||
return r.Error
|
|
||||||
}
|
|
||||||
debugLogReqError(r, "Send Request", true, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
r.Handlers.UnmarshalMeta.Run(r)
|
|
||||||
r.Handlers.ValidateResponse.Run(r)
|
|
||||||
if r.Error != nil {
|
|
||||||
r.Handlers.UnmarshalError.Run(r)
|
|
||||||
err := r.Error
|
|
||||||
|
|
||||||
r.Handlers.Retry.Run(r)
|
|
||||||
r.Handlers.AfterRetry.Run(r)
|
|
||||||
if r.Error != nil {
|
|
||||||
debugLogReqError(r, "Validate Response", false, err)
|
|
||||||
return r.Error
|
|
||||||
}
|
|
||||||
debugLogReqError(r, "Validate Response", true, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
r.Handlers.Unmarshal.Run(r)
|
|
||||||
if r.Error != nil {
|
|
||||||
err := r.Error
|
|
||||||
r.Handlers.Retry.Run(r)
|
|
||||||
r.Handlers.AfterRetry.Run(r)
|
|
||||||
if r.Error != nil {
|
|
||||||
debugLogReqError(r, "Unmarshal Response", false, err)
|
|
||||||
return r.Error
|
|
||||||
}
|
|
||||||
debugLogReqError(r, "Unmarshal Response", true, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy will copy a request which will allow for local manipulation of the
|
|
||||||
// request.
|
|
||||||
func (r *Request) copy() *Request {
|
|
||||||
req := &Request{}
|
|
||||||
*req = *r
|
|
||||||
req.Handlers = r.Handlers.Copy()
|
|
||||||
op := *r.Operation
|
|
||||||
req.Operation = &op
|
|
||||||
return req
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddToUserAgent adds the string to the end of the request's current user agent.
|
|
||||||
func AddToUserAgent(r *Request, s string) {
|
|
||||||
curUA := r.HTTPRequest.Header.Get("User-Agent")
|
|
||||||
if len(curUA) > 0 {
|
|
||||||
s = curUA + " " + s
|
|
||||||
}
|
|
||||||
r.HTTPRequest.Header.Set("User-Agent", s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func shouldRetryCancel(r *Request) bool {
|
|
||||||
awsErr, ok := r.Error.(awserr.Error)
|
|
||||||
timeoutErr := false
|
|
||||||
errStr := r.Error.Error()
|
|
||||||
if ok {
|
|
||||||
if awsErr.Code() == CanceledErrorCode {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
err := awsErr.OrigErr()
|
|
||||||
netErr, netOK := err.(net.Error)
|
|
||||||
timeoutErr = netOK && netErr.Temporary()
|
|
||||||
if urlErr, ok := err.(*url.Error); !timeoutErr && ok {
|
|
||||||
errStr = urlErr.Err.Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There can be two types of canceled errors here.
|
|
||||||
// The first being a net.Error and the other being an error.
|
|
||||||
// If the request was timed out, we want to continue the retry
|
|
||||||
// process. Otherwise, return the canceled error.
|
|
||||||
return timeoutErr ||
|
|
||||||
(errStr != "net/http: request canceled" &&
|
|
||||||
errStr != "net/http: request canceled while waiting for connection")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// SanitizeHostForHeader removes default port from host and updates request.Host
|
|
||||||
func SanitizeHostForHeader(r *http.Request) {
|
|
||||||
host := getHost(r)
|
|
||||||
port := portOnly(host)
|
|
||||||
if port != "" && isDefaultPort(r.URL.Scheme, port) {
|
|
||||||
r.Host = stripPort(host)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns host from request
|
|
||||||
func getHost(r *http.Request) string {
|
|
||||||
if r.Host != "" {
|
|
||||||
return r.Host
|
|
||||||
}
|
|
||||||
|
|
||||||
return r.URL.Host
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hostname returns u.Host, without any port number.
|
|
||||||
//
|
|
||||||
// If Host is an IPv6 literal with a port number, Hostname returns the
|
|
||||||
// IPv6 literal without the square brackets. IPv6 literals may include
|
|
||||||
// a zone identifier.
|
|
||||||
//
|
|
||||||
// Copied from the Go 1.8 standard library (net/url)
|
|
||||||
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]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Port returns the port part of u.Host, without the leading colon.
|
|
||||||
// If u.Host doesn't contain a port, Port returns an empty string.
|
|
||||||
//
|
|
||||||
// Copied from the Go 1.8 standard library (net/url)
|
|
||||||
func portOnly(hostport string) string {
|
|
||||||
colon := strings.IndexByte(hostport, ':')
|
|
||||||
if colon == -1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if i := strings.Index(hostport, "]:"); i != -1 {
|
|
||||||
return hostport[i+len("]:"):]
|
|
||||||
}
|
|
||||||
if strings.Contains(hostport, "]") {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return hostport[colon+len(":"):]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if the specified URI is using the standard port
|
|
||||||
// (i.e. port 80 for HTTP URIs or 443 for HTTPS URIs)
|
|
||||||
func isDefaultPort(scheme, port string) bool {
|
|
||||||
if port == "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
lowerCaseScheme := strings.ToLower(scheme)
|
|
||||||
if (lowerCaseScheme == "http" && port == "80") || (lowerCaseScheme == "https" && port == "443") {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
39
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go
generated
vendored
39
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_7.go
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
// +build !go1.8
|
|
||||||
|
|
||||||
package request
|
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
// NoBody is an io.ReadCloser with no bytes. Read always returns EOF
|
|
||||||
// and Close always returns nil. It can be used in an outgoing client
|
|
||||||
// request to explicitly signal that a request has zero bytes.
|
|
||||||
// An alternative, however, is to simply set Request.Body to nil.
|
|
||||||
//
|
|
||||||
// Copy of Go 1.8 NoBody type from net/http/http.go
|
|
||||||
type noBody struct{}
|
|
||||||
|
|
||||||
func (noBody) Read([]byte) (int, error) { return 0, io.EOF }
|
|
||||||
func (noBody) Close() error { return nil }
|
|
||||||
func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil }
|
|
||||||
|
|
||||||
// NoBody is an empty reader that will trigger the Go HTTP client to not include
|
|
||||||
// and body in the HTTP request.
|
|
||||||
var NoBody = noBody{}
|
|
||||||
|
|
||||||
// ResetBody rewinds the request body back to its starting position, and
|
|
||||||
// sets the HTTP Request body reference. When the body is read prior
|
|
||||||
// to being sent in the HTTP request it will need to be rewound.
|
|
||||||
//
|
|
||||||
// ResetBody will automatically be called by the SDK's build handler, but if
|
|
||||||
// the request is being used directly ResetBody must be called before the request
|
|
||||||
// is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically
|
|
||||||
// call ResetBody.
|
|
||||||
func (r *Request) ResetBody() {
|
|
||||||
body, err := r.getNextRequestBody()
|
|
||||||
if err != nil {
|
|
||||||
r.Error = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r.HTTPRequest.Body = body
|
|
||||||
}
|
|
33
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go
generated
vendored
33
vendor/github.com/aws/aws-sdk-go/aws/request/request_1_8.go
generated
vendored
@ -1,33 +0,0 @@
|
|||||||
// +build go1.8
|
|
||||||
|
|
||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NoBody is a http.NoBody reader instructing Go HTTP client to not include
|
|
||||||
// and body in the HTTP request.
|
|
||||||
var NoBody = http.NoBody
|
|
||||||
|
|
||||||
// ResetBody rewinds the request body back to its starting position, and
|
|
||||||
// sets the HTTP Request body reference. When the body is read prior
|
|
||||||
// to being sent in the HTTP request it will need to be rewound.
|
|
||||||
//
|
|
||||||
// ResetBody will automatically be called by the SDK's build handler, but if
|
|
||||||
// the request is being used directly ResetBody must be called before the request
|
|
||||||
// is Sent. SetStringBody, SetBufferBody, and SetReaderBody will automatically
|
|
||||||
// call ResetBody.
|
|
||||||
//
|
|
||||||
// Will also set the Go 1.8's http.Request.GetBody member to allow retrying
|
|
||||||
// PUT/POST redirects.
|
|
||||||
func (r *Request) ResetBody() {
|
|
||||||
body, err := r.getNextRequestBody()
|
|
||||||
if err != nil {
|
|
||||||
r.Error = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
r.HTTPRequest.Body = body
|
|
||||||
r.HTTPRequest.GetBody = r.getNextRequestBody
|
|
||||||
}
|
|
14
vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go
generated
vendored
14
vendor/github.com/aws/aws-sdk-go/aws/request/request_context.go
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
// +build go1.7
|
|
||||||
|
|
||||||
package request
|
|
||||||
|
|
||||||
import "github.com/aws/aws-sdk-go/aws"
|
|
||||||
|
|
||||||
// setContext updates the Request to use the passed in context for cancellation.
|
|
||||||
// Context will also be used for request retry delay.
|
|
||||||
//
|
|
||||||
// Creates shallow copy of the http.Request with the WithContext method.
|
|
||||||
func setRequestContext(r *Request, ctx aws.Context) {
|
|
||||||
r.context = ctx
|
|
||||||
r.HTTPRequest = r.HTTPRequest.WithContext(ctx)
|
|
||||||
}
|
|
14
vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go
generated
vendored
14
vendor/github.com/aws/aws-sdk-go/aws/request/request_context_1_6.go
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
// +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()
|
|
||||||
}
|
|
264
vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
generated
vendored
264
vendor/github.com/aws/aws-sdk-go/aws/request/request_pagination.go
generated
vendored
@ -1,264 +0,0 @@
|
|||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"sync/atomic"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
// EndPageOnSameToken, when enabled, will allow the paginator to stop on
|
|
||||||
// token that are the same as its previous tokens.
|
|
||||||
EndPageOnSameToken bool
|
|
||||||
|
|
||||||
started bool
|
|
||||||
prevTokens []interface{}
|
|
||||||
nextTokens []interface{}
|
|
||||||
|
|
||||||
err error
|
|
||||||
curPage interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 {
|
|
||||||
if !p.started {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
hasNextPage := len(p.nextTokens) != 0
|
|
||||||
if p.EndPageOnSameToken {
|
|
||||||
return hasNextPage && !awsutil.DeepEqual(p.nextTokens, p.prevTokens)
|
|
||||||
}
|
|
||||||
return hasNextPage
|
|
||||||
}
|
|
||||||
|
|
||||||
// Err returns the error Pagination encountered when retrieving the next page.
|
|
||||||
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.prevTokens = p.nextTokens
|
|
||||||
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 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v := tr[0].(type) {
|
|
||||||
case *bool:
|
|
||||||
if !aws.BoolValue(v) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
case bool:
|
|
||||||
if v == false {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tokens := []interface{}{}
|
|
||||||
tokenAdded := false
|
|
||||||
for _, outToken := range r.Operation.OutputTokens {
|
|
||||||
vs, _ := awsutil.ValuesAtPath(r.Data, outToken)
|
|
||||||
if len(vs) == 0 {
|
|
||||||
tokens = append(tokens, nil)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
v := vs[0]
|
|
||||||
|
|
||||||
switch tv := v.(type) {
|
|
||||||
case *string:
|
|
||||||
if len(aws.StringValue(tv)) == 0 {
|
|
||||||
tokens = append(tokens, nil)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
case string:
|
|
||||||
if len(tv) == 0 {
|
|
||||||
tokens = append(tokens, nil)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenAdded = true
|
|
||||||
tokens = append(tokens, v)
|
|
||||||
}
|
|
||||||
if !tokenAdded {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
data := reflect.New(reflect.TypeOf(r.Data).Elem()).Interface()
|
|
||||||
nr := New(r.Config, r.ClientInfo, r.Handlers, r.Retryer, r.Operation, awsutil.CopyOf(r.Params), data)
|
|
||||||
for i, intok := range nr.Operation.InputTokens {
|
|
||||||
awsutil.SetValueAtPath(nr.Params, intok, tokens[i])
|
|
||||||
}
|
|
||||||
return nr
|
|
||||||
}
|
|
||||||
|
|
||||||
// EachPage iterates over each page of a paginated request object. The fn
|
|
||||||
// parameter should be a function with the following sample signature:
|
|
||||||
//
|
|
||||||
// func(page *T, lastPage bool) bool {
|
|
||||||
// return true // return false to stop iterating
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Where "T" is the structure type matching the output structure of the given
|
|
||||||
// operation. For example, a request object generated by
|
|
||||||
// DynamoDB.ListTablesRequest() would expect to see dynamodb.ListTablesOutput
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
if getNextPage := fn(page.Data, !page.HasNextPage()); !getNextPage {
|
|
||||||
return page.Error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
161
vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
generated
vendored
161
vendor/github.com/aws/aws-sdk-go/aws/request/retryer.go
generated
vendored
@ -1,161 +0,0 @@
|
|||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Retryer is an interface to control retry logic for a given service.
|
|
||||||
// The default implementation used by most services is the client.DefaultRetryer
|
|
||||||
// structure, which contains basic retry logic using exponential backoff.
|
|
||||||
type Retryer interface {
|
|
||||||
RetryRules(*Request) time.Duration
|
|
||||||
ShouldRetry(*Request) bool
|
|
||||||
MaxRetries() int
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithRetryer sets a config Retryer value to the given Config returning it
|
|
||||||
// for chaining.
|
|
||||||
func WithRetryer(cfg *aws.Config, retryer Retryer) *aws.Config {
|
|
||||||
cfg.Retryer = retryer
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
// retryableCodes is a collection of service response codes which are retry-able
|
|
||||||
// without any further action.
|
|
||||||
var retryableCodes = map[string]struct{}{
|
|
||||||
"RequestError": {},
|
|
||||||
"RequestTimeout": {},
|
|
||||||
ErrCodeResponseTimeout: {},
|
|
||||||
"RequestTimeoutException": {}, // Glacier's flavor of RequestTimeout
|
|
||||||
}
|
|
||||||
|
|
||||||
var throttleCodes = map[string]struct{}{
|
|
||||||
"ProvisionedThroughputExceededException": {},
|
|
||||||
"Throttling": {},
|
|
||||||
"ThrottlingException": {},
|
|
||||||
"RequestLimitExceeded": {},
|
|
||||||
"RequestThrottled": {},
|
|
||||||
"TooManyRequestsException": {}, // Lambda functions
|
|
||||||
"PriorRequestNotComplete": {}, // Route53
|
|
||||||
}
|
|
||||||
|
|
||||||
// credsExpiredCodes is a collection of error codes which signify the credentials
|
|
||||||
// need to be refreshed. Expired tokens require refreshing of credentials, and
|
|
||||||
// resigning before the request can be retried.
|
|
||||||
var credsExpiredCodes = map[string]struct{}{
|
|
||||||
"ExpiredToken": {},
|
|
||||||
"ExpiredTokenException": {},
|
|
||||||
"RequestExpired": {}, // EC2 Only
|
|
||||||
}
|
|
||||||
|
|
||||||
func isCodeThrottle(code string) bool {
|
|
||||||
_, ok := throttleCodes[code]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
func isCodeRetryable(code string) bool {
|
|
||||||
if _, ok := retryableCodes[code]; ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return isCodeExpiredCreds(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func isCodeExpiredCreds(code string) bool {
|
|
||||||
_, ok := credsExpiredCodes[code]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
var validParentCodes = map[string]struct{}{
|
|
||||||
ErrCodeSerialization: {},
|
|
||||||
ErrCodeRead: {},
|
|
||||||
}
|
|
||||||
|
|
||||||
type temporaryError interface {
|
|
||||||
Temporary() bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func isNestedErrorRetryable(parentErr awserr.Error) bool {
|
|
||||||
if parentErr == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := validParentCodes[parentErr.Code()]; !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
err := parentErr.OrigErr()
|
|
||||||
if err == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if aerr, ok := err.(awserr.Error); ok {
|
|
||||||
return isCodeRetryable(aerr.Code())
|
|
||||||
}
|
|
||||||
|
|
||||||
if t, ok := err.(temporaryError); ok {
|
|
||||||
return t.Temporary() || isErrConnectionReset(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return isErrConnectionReset(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErrorRetryable returns whether the error is retryable, based on its Code.
|
|
||||||
// Returns false if error is nil.
|
|
||||||
func IsErrorRetryable(err error) bool {
|
|
||||||
if err != nil {
|
|
||||||
if aerr, ok := err.(awserr.Error); ok {
|
|
||||||
return isCodeRetryable(aerr.Code()) || isNestedErrorRetryable(aerr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErrorThrottle returns whether the error is to be throttled based on its code.
|
|
||||||
// Returns false if error is nil.
|
|
||||||
func IsErrorThrottle(err error) bool {
|
|
||||||
if err != nil {
|
|
||||||
if aerr, ok := err.(awserr.Error); ok {
|
|
||||||
return isCodeThrottle(aerr.Code())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErrorExpiredCreds returns whether the error code is a credential expiry error.
|
|
||||||
// Returns false if error is nil.
|
|
||||||
func IsErrorExpiredCreds(err error) bool {
|
|
||||||
if err != nil {
|
|
||||||
if aerr, ok := err.(awserr.Error); ok {
|
|
||||||
return isCodeExpiredCreds(aerr.Code())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErrorRetryable returns whether the error is retryable, based on its Code.
|
|
||||||
// Returns false if the request has no Error set.
|
|
||||||
//
|
|
||||||
// Alias for the utility function IsErrorRetryable
|
|
||||||
func (r *Request) IsErrorRetryable() bool {
|
|
||||||
return IsErrorRetryable(r.Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErrorThrottle returns whether the error is to be throttled based on its code.
|
|
||||||
// Returns false if the request has no Error set
|
|
||||||
//
|
|
||||||
// Alias for the utility function IsErrorThrottle
|
|
||||||
func (r *Request) IsErrorThrottle() bool {
|
|
||||||
return IsErrorThrottle(r.Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsErrorExpired returns whether the error code is a credential expiry error.
|
|
||||||
// Returns false if the request has no Error set.
|
|
||||||
//
|
|
||||||
// Alias for the utility function IsErrorExpiredCreds
|
|
||||||
func (r *Request) IsErrorExpired() bool {
|
|
||||||
return IsErrorExpiredCreds(r.Error)
|
|
||||||
}
|
|
94
vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go
generated
vendored
94
vendor/github.com/aws/aws-sdk-go/aws/request/timeout_read_closer.go
generated
vendored
@ -1,94 +0,0 @@
|
|||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
261
vendor/github.com/aws/aws-sdk-go/aws/request/validation.go
generated
vendored
261
vendor/github.com/aws/aws-sdk-go/aws/request/validation.go
generated
vendored
@ -1,261 +0,0 @@
|
|||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// InvalidParameterErrCode is the error code for invalid parameters errors
|
|
||||||
InvalidParameterErrCode = "InvalidParameter"
|
|
||||||
// ParamRequiredErrCode is the error code for required parameter errors
|
|
||||||
ParamRequiredErrCode = "ParamRequiredError"
|
|
||||||
// ParamMinValueErrCode is the error code for fields with too low of a
|
|
||||||
// number value.
|
|
||||||
ParamMinValueErrCode = "ParamMinValueError"
|
|
||||||
// ParamMinLenErrCode is the error code for fields without enough elements.
|
|
||||||
ParamMinLenErrCode = "ParamMinLenError"
|
|
||||||
|
|
||||||
// ParamFormatErrCode is the error code for a field with invalid
|
|
||||||
// format or characters.
|
|
||||||
ParamFormatErrCode = "ParamFormatInvalidError"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Validator provides a way for types to perform validation logic on their
|
|
||||||
// input values that external code can use to determine if a type's values
|
|
||||||
// are valid.
|
|
||||||
type Validator interface {
|
|
||||||
Validate() error
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ErrInvalidParams provides wrapping of invalid parameter errors found when
|
|
||||||
// validating API operation input parameters.
|
|
||||||
type ErrInvalidParams struct {
|
|
||||||
// Context is the base context of the invalid parameter group.
|
|
||||||
Context string
|
|
||||||
errs []ErrInvalidParam
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add adds a new invalid parameter error to the collection of invalid
|
|
||||||
// parameters. The context of the invalid parameter will be updated to reflect
|
|
||||||
// this collection.
|
|
||||||
func (e *ErrInvalidParams) Add(err ErrInvalidParam) {
|
|
||||||
err.SetContext(e.Context)
|
|
||||||
e.errs = append(e.errs, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddNested adds the invalid parameter errors from another ErrInvalidParams
|
|
||||||
// value into this collection. The nested errors will have their nested context
|
|
||||||
// updated and base context to reflect the merging.
|
|
||||||
//
|
|
||||||
// Use for nested validations errors.
|
|
||||||
func (e *ErrInvalidParams) AddNested(nestedCtx string, nested ErrInvalidParams) {
|
|
||||||
for _, err := range nested.errs {
|
|
||||||
err.SetContext(e.Context)
|
|
||||||
err.AddNestedContext(nestedCtx)
|
|
||||||
e.errs = append(e.errs, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len returns the number of invalid parameter errors
|
|
||||||
func (e ErrInvalidParams) Len() int {
|
|
||||||
return len(e.errs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code returns the code of the error
|
|
||||||
func (e ErrInvalidParams) Code() string {
|
|
||||||
return InvalidParameterErrCode
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message returns the message of the error
|
|
||||||
func (e ErrInvalidParams) Message() string {
|
|
||||||
return fmt.Sprintf("%d validation error(s) found.", len(e.errs))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns the string formatted form of the invalid parameters.
|
|
||||||
func (e ErrInvalidParams) Error() string {
|
|
||||||
w := &bytes.Buffer{}
|
|
||||||
fmt.Fprintf(w, "%s: %s\n", e.Code(), e.Message())
|
|
||||||
|
|
||||||
for _, err := range e.errs {
|
|
||||||
fmt.Fprintf(w, "- %s\n", err.Message())
|
|
||||||
}
|
|
||||||
|
|
||||||
return w.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErr returns the invalid parameters as a awserr.BatchedErrors value
|
|
||||||
func (e ErrInvalidParams) OrigErr() error {
|
|
||||||
return awserr.NewBatchError(
|
|
||||||
InvalidParameterErrCode, e.Message(), e.OrigErrs())
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErrs returns a slice of the invalid parameters
|
|
||||||
func (e ErrInvalidParams) OrigErrs() []error {
|
|
||||||
errs := make([]error, len(e.errs))
|
|
||||||
for i := 0; i < len(errs); i++ {
|
|
||||||
errs[i] = e.errs[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
return errs
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ErrInvalidParam represents an invalid parameter error type.
|
|
||||||
type ErrInvalidParam interface {
|
|
||||||
awserr.Error
|
|
||||||
|
|
||||||
// Field name the error occurred on.
|
|
||||||
Field() string
|
|
||||||
|
|
||||||
// SetContext updates the context of the error.
|
|
||||||
SetContext(string)
|
|
||||||
|
|
||||||
// AddNestedContext updates the error's context to include a nested level.
|
|
||||||
AddNestedContext(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
type errInvalidParam struct {
|
|
||||||
context string
|
|
||||||
nestedContext string
|
|
||||||
field string
|
|
||||||
code string
|
|
||||||
msg string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code returns the error code for the type of invalid parameter.
|
|
||||||
func (e *errInvalidParam) Code() string {
|
|
||||||
return e.code
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message returns the reason the parameter was invalid, and its context.
|
|
||||||
func (e *errInvalidParam) Message() string {
|
|
||||||
return fmt.Sprintf("%s, %s.", e.msg, e.Field())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error returns the string version of the invalid parameter error.
|
|
||||||
func (e *errInvalidParam) Error() string {
|
|
||||||
return fmt.Sprintf("%s: %s", e.code, e.Message())
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErr returns nil, Implemented for awserr.Error interface.
|
|
||||||
func (e *errInvalidParam) OrigErr() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field Returns the field and context the error occurred.
|
|
||||||
func (e *errInvalidParam) Field() string {
|
|
||||||
field := e.context
|
|
||||||
if len(field) > 0 {
|
|
||||||
field += "."
|
|
||||||
}
|
|
||||||
if len(e.nestedContext) > 0 {
|
|
||||||
field += fmt.Sprintf("%s.", e.nestedContext)
|
|
||||||
}
|
|
||||||
field += e.field
|
|
||||||
|
|
||||||
return field
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetContext updates the base context of the error.
|
|
||||||
func (e *errInvalidParam) SetContext(ctx string) {
|
|
||||||
e.context = ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddNestedContext prepends a context to the field's path.
|
|
||||||
func (e *errInvalidParam) AddNestedContext(ctx string) {
|
|
||||||
if len(e.nestedContext) == 0 {
|
|
||||||
e.nestedContext = ctx
|
|
||||||
} else {
|
|
||||||
e.nestedContext = fmt.Sprintf("%s.%s", ctx, e.nestedContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ErrParamRequired represents an required parameter error.
|
|
||||||
type ErrParamRequired struct {
|
|
||||||
errInvalidParam
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewErrParamRequired creates a new required parameter error.
|
|
||||||
func NewErrParamRequired(field string) *ErrParamRequired {
|
|
||||||
return &ErrParamRequired{
|
|
||||||
errInvalidParam{
|
|
||||||
code: ParamRequiredErrCode,
|
|
||||||
field: field,
|
|
||||||
msg: fmt.Sprintf("missing required field"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ErrParamMinValue represents a minimum value parameter error.
|
|
||||||
type ErrParamMinValue struct {
|
|
||||||
errInvalidParam
|
|
||||||
min float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewErrParamMinValue creates a new minimum value parameter error.
|
|
||||||
func NewErrParamMinValue(field string, min float64) *ErrParamMinValue {
|
|
||||||
return &ErrParamMinValue{
|
|
||||||
errInvalidParam: errInvalidParam{
|
|
||||||
code: ParamMinValueErrCode,
|
|
||||||
field: field,
|
|
||||||
msg: fmt.Sprintf("minimum field value of %v", min),
|
|
||||||
},
|
|
||||||
min: min,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MinValue returns the field's require minimum value.
|
|
||||||
//
|
|
||||||
// float64 is returned for both int and float min values.
|
|
||||||
func (e *ErrParamMinValue) MinValue() float64 {
|
|
||||||
return e.min
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ErrParamMinLen represents a minimum length parameter error.
|
|
||||||
type ErrParamMinLen struct {
|
|
||||||
errInvalidParam
|
|
||||||
min int
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewErrParamMinLen creates a new minimum length parameter error.
|
|
||||||
func NewErrParamMinLen(field string, min int) *ErrParamMinLen {
|
|
||||||
return &ErrParamMinLen{
|
|
||||||
errInvalidParam: errInvalidParam{
|
|
||||||
code: ParamMinLenErrCode,
|
|
||||||
field: field,
|
|
||||||
msg: fmt.Sprintf("minimum field size of %v", min),
|
|
||||||
},
|
|
||||||
min: min,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MinLen returns the field's required minimum length.
|
|
||||||
func (e *ErrParamMinLen) MinLen() int {
|
|
||||||
return e.min
|
|
||||||
}
|
|
||||||
|
|
||||||
// An ErrParamFormat represents a invalid format parameter error.
|
|
||||||
type ErrParamFormat struct {
|
|
||||||
errInvalidParam
|
|
||||||
format string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewErrParamFormat creates a new invalid format parameter error.
|
|
||||||
func NewErrParamFormat(field string, format, value string) *ErrParamFormat {
|
|
||||||
return &ErrParamFormat{
|
|
||||||
errInvalidParam: errInvalidParam{
|
|
||||||
code: ParamFormatErrCode,
|
|
||||||
field: field,
|
|
||||||
msg: fmt.Sprintf("format %v, %v", format, value),
|
|
||||||
},
|
|
||||||
format: format,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format returns the field's required format.
|
|
||||||
func (e *ErrParamFormat) Format() string {
|
|
||||||
return e.format
|
|
||||||
}
|
|
295
vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go
generated
vendored
295
vendor/github.com/aws/aws-sdk-go/aws/request/waiter.go
generated
vendored
@ -1,295 +0,0 @@
|
|||||||
package request
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awsutil"
|
|
||||||
)
|
|
||||||
|
|
||||||
// WaiterResourceNotReadyErrorCode is the error code returned by a waiter when
|
|
||||||
// the waiter's max attempts have been exhausted.
|
|
||||||
const WaiterResourceNotReadyErrorCode = "ResourceNotReady"
|
|
||||||
|
|
||||||
// A WaiterOption is a function that will update the Waiter value's fields to
|
|
||||||
// configure the waiter.
|
|
||||||
type WaiterOption func(*Waiter)
|
|
||||||
|
|
||||||
// WithWaiterMaxAttempts returns the maximum number of times the waiter should
|
|
||||||
// attempt to check the resource for the target state.
|
|
||||||
func WithWaiterMaxAttempts(max int) WaiterOption {
|
|
||||||
return func(w *Waiter) {
|
|
||||||
w.MaxAttempts = max
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WaiterDelay will return a delay the waiter should pause between attempts to
|
|
||||||
// check the resource state. The passed in attempt is the number of times the
|
|
||||||
// Waiter has checked the resource state.
|
|
||||||
//
|
|
||||||
// Attempt is the number of attempts the Waiter has made checking the resource
|
|
||||||
// state.
|
|
||||||
type WaiterDelay func(attempt int) time.Duration
|
|
||||||
|
|
||||||
// ConstantWaiterDelay returns a WaiterDelay that will always return a constant
|
|
||||||
// delay the waiter should use between attempts. It ignores the number of
|
|
||||||
// attempts made.
|
|
||||||
func ConstantWaiterDelay(delay time.Duration) WaiterDelay {
|
|
||||||
return func(attempt int) time.Duration {
|
|
||||||
return delay
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithWaiterDelay will set the Waiter to use the WaiterDelay passed in.
|
|
||||||
func WithWaiterDelay(delayer WaiterDelay) WaiterOption {
|
|
||||||
return func(w *Waiter) {
|
|
||||||
w.Delay = delayer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithWaiterLogger returns a waiter option to set the logger a waiter
|
|
||||||
// should use to log warnings and errors to.
|
|
||||||
func WithWaiterLogger(logger aws.Logger) WaiterOption {
|
|
||||||
return func(w *Waiter) {
|
|
||||||
w.Logger = logger
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithWaiterRequestOptions returns a waiter option setting the request
|
|
||||||
// options for each request the waiter makes. Appends to waiter's request
|
|
||||||
// options already set.
|
|
||||||
func WithWaiterRequestOptions(opts ...Option) WaiterOption {
|
|
||||||
return func(w *Waiter) {
|
|
||||||
w.RequestOptions = append(w.RequestOptions, opts...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Waiter provides the functionality to perform a blocking call which will
|
|
||||||
// wait for a resource state to be satisfied by a service.
|
|
||||||
//
|
|
||||||
// This type should not be used directly. The API operations provided in the
|
|
||||||
// service packages prefixed with "WaitUntil" should be used instead.
|
|
||||||
type Waiter struct {
|
|
||||||
Name string
|
|
||||||
Acceptors []WaiterAcceptor
|
|
||||||
Logger aws.Logger
|
|
||||||
|
|
||||||
MaxAttempts int
|
|
||||||
Delay WaiterDelay
|
|
||||||
|
|
||||||
RequestOptions []Option
|
|
||||||
NewRequest func([]Option) (*Request, error)
|
|
||||||
SleepWithContext func(aws.Context, time.Duration) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// ApplyOptions updates the waiter with the list of waiter options provided.
|
|
||||||
func (w *Waiter) ApplyOptions(opts ...WaiterOption) {
|
|
||||||
for _, fn := range opts {
|
|
||||||
fn(w)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WaiterState are states the waiter uses based on WaiterAcceptor definitions
|
|
||||||
// to identify if the resource state the waiter is waiting on has occurred.
|
|
||||||
type WaiterState int
|
|
||||||
|
|
||||||
// String returns the string representation of the waiter state.
|
|
||||||
func (s WaiterState) String() string {
|
|
||||||
switch s {
|
|
||||||
case SuccessWaiterState:
|
|
||||||
return "success"
|
|
||||||
case FailureWaiterState:
|
|
||||||
return "failure"
|
|
||||||
case RetryWaiterState:
|
|
||||||
return "retry"
|
|
||||||
default:
|
|
||||||
return "unknown waiter state"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// States the waiter acceptors will use to identify target resource states.
|
|
||||||
const (
|
|
||||||
SuccessWaiterState WaiterState = iota // waiter successful
|
|
||||||
FailureWaiterState // waiter failed
|
|
||||||
RetryWaiterState // waiter needs to be retried
|
|
||||||
)
|
|
||||||
|
|
||||||
// WaiterMatchMode is the mode that the waiter will use to match the WaiterAcceptor
|
|
||||||
// definition's Expected attribute.
|
|
||||||
type WaiterMatchMode int
|
|
||||||
|
|
||||||
// Modes the waiter will use when inspecting API response to identify target
|
|
||||||
// resource states.
|
|
||||||
const (
|
|
||||||
PathAllWaiterMatch WaiterMatchMode = iota // match on all paths
|
|
||||||
PathWaiterMatch // match on specific path
|
|
||||||
PathAnyWaiterMatch // match on any path
|
|
||||||
PathListWaiterMatch // match on list of paths
|
|
||||||
StatusWaiterMatch // match on status code
|
|
||||||
ErrorWaiterMatch // match on error
|
|
||||||
)
|
|
||||||
|
|
||||||
// String returns the string representation of the waiter match mode.
|
|
||||||
func (m WaiterMatchMode) String() string {
|
|
||||||
switch m {
|
|
||||||
case PathAllWaiterMatch:
|
|
||||||
return "pathAll"
|
|
||||||
case PathWaiterMatch:
|
|
||||||
return "path"
|
|
||||||
case PathAnyWaiterMatch:
|
|
||||||
return "pathAny"
|
|
||||||
case PathListWaiterMatch:
|
|
||||||
return "pathList"
|
|
||||||
case StatusWaiterMatch:
|
|
||||||
return "status"
|
|
||||||
case ErrorWaiterMatch:
|
|
||||||
return "error"
|
|
||||||
default:
|
|
||||||
return "unknown waiter match mode"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WaitWithContext will make requests for the API operation using NewRequest to
|
|
||||||
// build API requests. The request's response will be compared against the
|
|
||||||
// Waiter's Acceptors to determine the successful state of the resource the
|
|
||||||
// waiter is inspecting.
|
|
||||||
//
|
|
||||||
// The passed in context must not be nil. If it is nil a panic will occur. The
|
|
||||||
// Context will be used to cancel the waiter's pending requests and retry delays.
|
|
||||||
// Use aws.BackgroundContext if no context is available.
|
|
||||||
//
|
|
||||||
// The waiter will continue until the target state defined by the Acceptors,
|
|
||||||
// or the max attempts expires.
|
|
||||||
//
|
|
||||||
// Will return the WaiterResourceNotReadyErrorCode error code if the waiter's
|
|
||||||
// retryer ShouldRetry returns false. This normally will happen when the max
|
|
||||||
// wait attempts expires.
|
|
||||||
func (w Waiter) WaitWithContext(ctx aws.Context) error {
|
|
||||||
|
|
||||||
for attempt := 1; ; attempt++ {
|
|
||||||
req, err := w.NewRequest(w.RequestOptions)
|
|
||||||
if err != nil {
|
|
||||||
waiterLogf(w.Logger, "unable to create request %v", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
req.Handlers.Build.PushBack(MakeAddToUserAgentFreeFormHandler("Waiter"))
|
|
||||||
err = req.Send()
|
|
||||||
|
|
||||||
// See if any of the acceptors match the request's response, or error
|
|
||||||
for _, a := range w.Acceptors {
|
|
||||||
if matched, matchErr := a.match(w.Name, w.Logger, req, err); matched {
|
|
||||||
return matchErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Waiter should only check the resource state MaxAttempts times
|
|
||||||
// This is here instead of in the for loop above to prevent delaying
|
|
||||||
// unnecessary when the waiter will not retry.
|
|
||||||
if attempt == w.MaxAttempts {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delay to wait before inspecting the resource again
|
|
||||||
delay := w.Delay(attempt)
|
|
||||||
if sleepFn := req.Config.SleepDelay; sleepFn != nil {
|
|
||||||
// Support SleepDelay for backwards compatibility and testing
|
|
||||||
sleepFn(delay)
|
|
||||||
} else {
|
|
||||||
sleepCtxFn := w.SleepWithContext
|
|
||||||
if sleepCtxFn == nil {
|
|
||||||
sleepCtxFn = aws.SleepWithContext
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := sleepCtxFn(ctx, delay); err != nil {
|
|
||||||
return awserr.New(CanceledErrorCode, "waiter context canceled", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return awserr.New(WaiterResourceNotReadyErrorCode, "exceeded wait attempts", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
// A WaiterAcceptor provides the information needed to wait for an API operation
|
|
||||||
// to complete.
|
|
||||||
type WaiterAcceptor struct {
|
|
||||||
State WaiterState
|
|
||||||
Matcher WaiterMatchMode
|
|
||||||
Argument string
|
|
||||||
Expected interface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// match returns if the acceptor found a match with the passed in request
|
|
||||||
// or error. True is returned if the acceptor made a match, error is returned
|
|
||||||
// if there was an error attempting to perform the match.
|
|
||||||
func (a *WaiterAcceptor) match(name string, l aws.Logger, req *Request, err error) (bool, error) {
|
|
||||||
result := false
|
|
||||||
var vals []interface{}
|
|
||||||
|
|
||||||
switch a.Matcher {
|
|
||||||
case PathAllWaiterMatch, PathWaiterMatch:
|
|
||||||
// Require all matches to be equal for result to match
|
|
||||||
vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument)
|
|
||||||
if len(vals) == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
result = true
|
|
||||||
for _, val := range vals {
|
|
||||||
if !awsutil.DeepEqual(val, a.Expected) {
|
|
||||||
result = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case PathAnyWaiterMatch:
|
|
||||||
// Only a single match needs to equal for the result to match
|
|
||||||
vals, _ = awsutil.ValuesAtPath(req.Data, a.Argument)
|
|
||||||
for _, val := range vals {
|
|
||||||
if awsutil.DeepEqual(val, a.Expected) {
|
|
||||||
result = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case PathListWaiterMatch:
|
|
||||||
// ignored matcher
|
|
||||||
case StatusWaiterMatch:
|
|
||||||
s := a.Expected.(int)
|
|
||||||
result = s == req.HTTPResponse.StatusCode
|
|
||||||
case ErrorWaiterMatch:
|
|
||||||
if aerr, ok := err.(awserr.Error); ok {
|
|
||||||
result = aerr.Code() == a.Expected.(string)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
waiterLogf(l, "WARNING: Waiter %s encountered unexpected matcher: %s",
|
|
||||||
name, a.Matcher)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !result {
|
|
||||||
// If there was no matching result found there is nothing more to do
|
|
||||||
// for this response, retry the request.
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch a.State {
|
|
||||||
case SuccessWaiterState:
|
|
||||||
// waiter completed
|
|
||||||
return true, nil
|
|
||||||
case FailureWaiterState:
|
|
||||||
// Waiter failure state triggered
|
|
||||||
return true, awserr.New(WaiterResourceNotReadyErrorCode,
|
|
||||||
"failed waiting for successful resource state", err)
|
|
||||||
case RetryWaiterState:
|
|
||||||
// clear the error and retry the operation
|
|
||||||
return false, nil
|
|
||||||
default:
|
|
||||||
waiterLogf(l, "WARNING: Waiter %s encountered unexpected state: %s",
|
|
||||||
name, a.State)
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func waiterLogf(logger aws.Logger, msg string, args ...interface{}) {
|
|
||||||
if logger != nil {
|
|
||||||
logger.Log(fmt.Sprintf(msg, args...))
|
|
||||||
}
|
|
||||||
}
|
|
273
vendor/github.com/aws/aws-sdk-go/aws/session/doc.go
generated
vendored
273
vendor/github.com/aws/aws-sdk-go/aws/session/doc.go
generated
vendored
@ -1,273 +0,0 @@
|
|||||||
/*
|
|
||||||
Package session provides configuration for the SDK's service clients.
|
|
||||||
|
|
||||||
Sessions can be shared across all service clients that share the same base
|
|
||||||
configuration. The Session is built from the SDK's default configuration and
|
|
||||||
request handlers.
|
|
||||||
|
|
||||||
Sessions should be cached when possible, because creating a new Session will
|
|
||||||
load all configuration values from the environment, and config files each time
|
|
||||||
the Session is created. Sharing the Session value across all of your service
|
|
||||||
clients will ensure the configuration is loaded the fewest number of times possible.
|
|
||||||
|
|
||||||
Concurrency
|
|
||||||
|
|
||||||
Sessions are safe to use concurrently as long as the Session is not being
|
|
||||||
modified. The SDK will not modify the Session once the Session has been created.
|
|
||||||
Creating service clients concurrently from a shared Session is safe.
|
|
||||||
|
|
||||||
Sessions from Shared Config
|
|
||||||
|
|
||||||
Sessions can be created using the method above that will only load the
|
|
||||||
additional config if the AWS_SDK_LOAD_CONFIG environment variable is set.
|
|
||||||
Alternatively you can explicitly create a Session with shared config enabled.
|
|
||||||
To do this you can use NewSessionWithOptions to configure how the Session will
|
|
||||||
be created. Using the NewSessionWithOptions with SharedConfigState set to
|
|
||||||
SharedConfigEnable will create the session as if the AWS_SDK_LOAD_CONFIG
|
|
||||||
environment variable was set.
|
|
||||||
|
|
||||||
Creating Sessions
|
|
||||||
|
|
||||||
When creating Sessions optional aws.Config values can be passed in that will
|
|
||||||
override the default, or loaded config values the Session is being created
|
|
||||||
with. This allows you to provide additional, or case based, configuration
|
|
||||||
as needed.
|
|
||||||
|
|
||||||
By default NewSession will only load credentials from the shared credentials
|
|
||||||
file (~/.aws/credentials). If the AWS_SDK_LOAD_CONFIG environment variable is
|
|
||||||
set to a truthy value the Session will be created from the configuration
|
|
||||||
values from the shared config (~/.aws/config) and shared credentials
|
|
||||||
(~/.aws/credentials) files. See the section Sessions from Shared Config for
|
|
||||||
more information.
|
|
||||||
|
|
||||||
Create a Session with the default config and request handlers. With credentials
|
|
||||||
region, and profile loaded from the environment and shared config automatically.
|
|
||||||
Requires the AWS_PROFILE to be set, or "default" is used.
|
|
||||||
|
|
||||||
// Create Session
|
|
||||||
sess := session.Must(session.NewSession())
|
|
||||||
|
|
||||||
// Create a Session with a custom region
|
|
||||||
sess := session.Must(session.NewSession(&aws.Config{
|
|
||||||
Region: aws.String("us-east-1"),
|
|
||||||
}))
|
|
||||||
|
|
||||||
// Create a S3 client instance from a session
|
|
||||||
sess := session.Must(session.NewSession())
|
|
||||||
|
|
||||||
svc := s3.New(sess)
|
|
||||||
|
|
||||||
Create Session With Option Overrides
|
|
||||||
|
|
||||||
In addition to NewSession, Sessions can be created using NewSessionWithOptions.
|
|
||||||
This func allows you to control and override how the Session will be created
|
|
||||||
through code instead of being driven by environment variables only.
|
|
||||||
|
|
||||||
Use NewSessionWithOptions when you want to provide the config profile, or
|
|
||||||
override the shared config state (AWS_SDK_LOAD_CONFIG).
|
|
||||||
|
|
||||||
// Equivalent to session.NewSession()
|
|
||||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
|
||||||
// Options
|
|
||||||
}))
|
|
||||||
|
|
||||||
// Specify profile to load for the session's config
|
|
||||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
|
||||||
Profile: "profile_name",
|
|
||||||
}))
|
|
||||||
|
|
||||||
// Specify profile for config and region for requests
|
|
||||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
|
||||||
Config: aws.Config{Region: aws.String("us-east-1")},
|
|
||||||
Profile: "profile_name",
|
|
||||||
}))
|
|
||||||
|
|
||||||
// Force enable Shared Config support
|
|
||||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
|
||||||
SharedConfigState: session.SharedConfigEnable,
|
|
||||||
}))
|
|
||||||
|
|
||||||
Adding Handlers
|
|
||||||
|
|
||||||
You can add handlers to a session for processing HTTP requests. All service
|
|
||||||
clients that use the session inherit the handlers. For example, the following
|
|
||||||
handler logs every request and its payload made by a service client:
|
|
||||||
|
|
||||||
// Create a session, and add additional handlers for all service
|
|
||||||
// clients created with the Session to inherit. Adds logging handler.
|
|
||||||
sess := session.Must(session.NewSession())
|
|
||||||
|
|
||||||
sess.Handlers.Send.PushFront(func(r *request.Request) {
|
|
||||||
// Log every request made and its payload
|
|
||||||
logger.Println("Request: %s/%s, Payload: %s",
|
|
||||||
r.ClientInfo.ServiceName, r.Operation, r.Params)
|
|
||||||
})
|
|
||||||
|
|
||||||
Deprecated "New" function
|
|
||||||
|
|
||||||
The New session function has been deprecated because it does not provide good
|
|
||||||
way to return errors that occur when loading the configuration files and values.
|
|
||||||
Because of this, NewSession was created so errors can be retrieved when
|
|
||||||
creating a session fails.
|
|
||||||
|
|
||||||
Shared Config Fields
|
|
||||||
|
|
||||||
By default the SDK will only load the shared credentials file's (~/.aws/credentials)
|
|
||||||
credentials values, and all other config is provided by the environment variables,
|
|
||||||
SDK defaults, and user provided aws.Config values.
|
|
||||||
|
|
||||||
If the AWS_SDK_LOAD_CONFIG environment variable is set, or SharedConfigEnable
|
|
||||||
option is used to create the Session the full shared config values will be
|
|
||||||
loaded. This includes credentials, region, and support for assume role. In
|
|
||||||
addition the Session will load its configuration from both the shared config
|
|
||||||
file (~/.aws/config) and shared credentials file (~/.aws/credentials). Both
|
|
||||||
files have the same format.
|
|
||||||
|
|
||||||
If both config files are present the configuration from both files will be
|
|
||||||
read. The Session will be created from configuration values from the shared
|
|
||||||
credentials file (~/.aws/credentials) over those in the shared config file (~/.aws/config).
|
|
||||||
|
|
||||||
Credentials are the values the SDK should use for authenticating requests with
|
|
||||||
AWS Services. They are from a configuration file will need to include both
|
|
||||||
aws_access_key_id and aws_secret_access_key must be provided together in the
|
|
||||||
same file to be considered valid. The values will be ignored if not a complete
|
|
||||||
group. aws_session_token is an optional field that can be provided if both of
|
|
||||||
the other two fields are also provided.
|
|
||||||
|
|
||||||
aws_access_key_id = AKID
|
|
||||||
aws_secret_access_key = SECRET
|
|
||||||
aws_session_token = TOKEN
|
|
||||||
|
|
||||||
Assume Role values allow you to configure the SDK to assume an IAM role using
|
|
||||||
a set of credentials provided in a config file via the source_profile field.
|
|
||||||
Both "role_arn" and "source_profile" are required. The SDK supports assuming
|
|
||||||
a role with MFA token if the session option AssumeRoleTokenProvider
|
|
||||||
is set.
|
|
||||||
|
|
||||||
role_arn = arn:aws:iam::<account_number>:role/<role_name>
|
|
||||||
source_profile = profile_with_creds
|
|
||||||
external_id = 1234
|
|
||||||
mfa_serial = <serial or mfa arn>
|
|
||||||
role_session_name = session_name
|
|
||||||
|
|
||||||
Region is the region the SDK should use for looking up AWS service endpoints
|
|
||||||
and signing requests.
|
|
||||||
|
|
||||||
region = us-east-1
|
|
||||||
|
|
||||||
Assume Role with MFA token
|
|
||||||
|
|
||||||
To create a session with support for assuming an IAM role with MFA set the
|
|
||||||
session option AssumeRoleTokenProvider to a function that will prompt for the
|
|
||||||
MFA token code when the SDK assumes the role and refreshes the role's credentials.
|
|
||||||
This allows you to configure the SDK via the shared config to assumea role
|
|
||||||
with MFA tokens.
|
|
||||||
|
|
||||||
In order for the SDK to assume a role with MFA the SharedConfigState
|
|
||||||
session option must be set to SharedConfigEnable, or AWS_SDK_LOAD_CONFIG
|
|
||||||
environment variable set.
|
|
||||||
|
|
||||||
The shared configuration instructs the SDK to assume an IAM role with MFA
|
|
||||||
when the mfa_serial configuration field is set in the shared config
|
|
||||||
(~/.aws/config) or shared credentials (~/.aws/credentials) file.
|
|
||||||
|
|
||||||
If mfa_serial is set in the configuration, the SDK will assume the role, and
|
|
||||||
the AssumeRoleTokenProvider session option is not set an an error will
|
|
||||||
be returned when creating the session.
|
|
||||||
|
|
||||||
sess := session.Must(session.NewSessionWithOptions(session.Options{
|
|
||||||
AssumeRoleTokenProvider: stscreds.StdinTokenProvider,
|
|
||||||
}))
|
|
||||||
|
|
||||||
// Create service client value configured for credentials
|
|
||||||
// from assumed role.
|
|
||||||
svc := s3.New(sess)
|
|
||||||
|
|
||||||
To setup assume role outside of a session see the stscrds.AssumeRoleProvider
|
|
||||||
documentation.
|
|
||||||
|
|
||||||
Environment Variables
|
|
||||||
|
|
||||||
When a Session is created several environment variables can be set to adjust
|
|
||||||
how the SDK functions, and what configuration data it loads when creating
|
|
||||||
Sessions. All environment values are optional, but some values like credentials
|
|
||||||
require multiple of the values to set or the partial values will be ignored.
|
|
||||||
All environment variable values are strings unless otherwise noted.
|
|
||||||
|
|
||||||
Environment configuration values. If set both Access Key ID and Secret Access
|
|
||||||
Key must be provided. Session Token and optionally also be provided, but is
|
|
||||||
not required.
|
|
||||||
|
|
||||||
# Access Key ID
|
|
||||||
AWS_ACCESS_KEY_ID=AKID
|
|
||||||
AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set.
|
|
||||||
|
|
||||||
# Secret Access Key
|
|
||||||
AWS_SECRET_ACCESS_KEY=SECRET
|
|
||||||
AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set.
|
|
||||||
|
|
||||||
# Session Token
|
|
||||||
AWS_SESSION_TOKEN=TOKEN
|
|
||||||
|
|
||||||
Region value will instruct the SDK where to make service API requests to. If is
|
|
||||||
not provided in the environment the region must be provided before a service
|
|
||||||
client request is made.
|
|
||||||
|
|
||||||
AWS_REGION=us-east-1
|
|
||||||
|
|
||||||
# AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set,
|
|
||||||
# and AWS_REGION is not also set.
|
|
||||||
AWS_DEFAULT_REGION=us-east-1
|
|
||||||
|
|
||||||
Profile name the SDK should load use when loading shared config from the
|
|
||||||
configuration files. If not provided "default" will be used as the profile name.
|
|
||||||
|
|
||||||
AWS_PROFILE=my_profile
|
|
||||||
|
|
||||||
# AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set,
|
|
||||||
# and AWS_PROFILE is not also set.
|
|
||||||
AWS_DEFAULT_PROFILE=my_profile
|
|
||||||
|
|
||||||
SDK load config instructs the SDK to load the shared config in addition to
|
|
||||||
shared credentials. This also expands the configuration loaded so the shared
|
|
||||||
credentials will have parity with the shared config file. This also enables
|
|
||||||
Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE
|
|
||||||
env values as well.
|
|
||||||
|
|
||||||
AWS_SDK_LOAD_CONFIG=1
|
|
||||||
|
|
||||||
Shared credentials file path can be set to instruct the SDK to use an alternative
|
|
||||||
file for the shared credentials. If not set the file will be loaded from
|
|
||||||
$HOME/.aws/credentials on Linux/Unix based systems, and
|
|
||||||
%USERPROFILE%\.aws\credentials on Windows.
|
|
||||||
|
|
||||||
AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials
|
|
||||||
|
|
||||||
Shared config file path can be set to instruct the SDK to use an alternative
|
|
||||||
file for the shared config. If not set the file will be loaded from
|
|
||||||
$HOME/.aws/config on Linux/Unix based systems, and
|
|
||||||
%USERPROFILE%\.aws\config on Windows.
|
|
||||||
|
|
||||||
AWS_CONFIG_FILE=$HOME/my_shared_config
|
|
||||||
|
|
||||||
Path to a custom Credentials Authority (CA) bundle PEM file that the SDK
|
|
||||||
will use instead of the default system's root CA bundle. Use this only
|
|
||||||
if you want to replace the CA bundle the SDK uses for TLS requests.
|
|
||||||
|
|
||||||
AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle
|
|
||||||
|
|
||||||
Enabling this option will attempt to merge the Transport into the SDK's HTTP
|
|
||||||
client. If the client's Transport is not a http.Transport an error will be
|
|
||||||
returned. If the Transport's TLS config is set this option will cause the SDK
|
|
||||||
to overwrite the Transport's TLS config's RootCAs value. If the CA bundle file
|
|
||||||
contains multiple certificates all of them will be loaded.
|
|
||||||
|
|
||||||
The Session option CustomCABundle is also available when creating sessions
|
|
||||||
to also enable this feature. CustomCABundle session option field has priority
|
|
||||||
over the AWS_CA_BUNDLE environment variable, and will be used if both are set.
|
|
||||||
|
|
||||||
Setting a custom HTTPClient in the aws.Config options will override this setting.
|
|
||||||
To use this option and custom HTTP client, the HTTP client needs to be provided
|
|
||||||
when creating the session. Not the service client.
|
|
||||||
*/
|
|
||||||
package session
|
|
236
vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
generated
vendored
236
vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go
generated
vendored
@ -1,236 +0,0 @@
|
|||||||
package session
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
|
||||||
)
|
|
||||||
|
|
||||||
// EnvProviderName provides a name of the provider when config is loaded from environment.
|
|
||||||
const EnvProviderName = "EnvConfigCredentials"
|
|
||||||
|
|
||||||
// envConfig is a collection of environment values the SDK will read
|
|
||||||
// setup config from. All environment values are optional. But some values
|
|
||||||
// such as credentials require multiple values to be complete or the values
|
|
||||||
// will be ignored.
|
|
||||||
type envConfig struct {
|
|
||||||
// Environment configuration values. If set both Access Key ID and Secret Access
|
|
||||||
// Key must be provided. Session Token and optionally also be provided, but is
|
|
||||||
// not required.
|
|
||||||
//
|
|
||||||
// # Access Key ID
|
|
||||||
// AWS_ACCESS_KEY_ID=AKID
|
|
||||||
// AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set.
|
|
||||||
//
|
|
||||||
// # Secret Access Key
|
|
||||||
// AWS_SECRET_ACCESS_KEY=SECRET
|
|
||||||
// AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set.
|
|
||||||
//
|
|
||||||
// # Session Token
|
|
||||||
// AWS_SESSION_TOKEN=TOKEN
|
|
||||||
Creds credentials.Value
|
|
||||||
|
|
||||||
// Region value will instruct the SDK where to make service API requests to. If is
|
|
||||||
// not provided in the environment the region must be provided before a service
|
|
||||||
// client request is made.
|
|
||||||
//
|
|
||||||
// AWS_REGION=us-east-1
|
|
||||||
//
|
|
||||||
// # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set,
|
|
||||||
// # and AWS_REGION is not also set.
|
|
||||||
// AWS_DEFAULT_REGION=us-east-1
|
|
||||||
Region string
|
|
||||||
|
|
||||||
// Profile name the SDK should load use when loading shared configuration from the
|
|
||||||
// shared configuration files. If not provided "default" will be used as the
|
|
||||||
// profile name.
|
|
||||||
//
|
|
||||||
// AWS_PROFILE=my_profile
|
|
||||||
//
|
|
||||||
// # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set,
|
|
||||||
// # and AWS_PROFILE is not also set.
|
|
||||||
// AWS_DEFAULT_PROFILE=my_profile
|
|
||||||
Profile string
|
|
||||||
|
|
||||||
// SDK load config instructs the SDK to load the shared config in addition to
|
|
||||||
// shared credentials. This also expands the configuration loaded from the shared
|
|
||||||
// credentials to have parity with the shared config file. This also enables
|
|
||||||
// Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE
|
|
||||||
// env values as well.
|
|
||||||
//
|
|
||||||
// AWS_SDK_LOAD_CONFIG=1
|
|
||||||
EnableSharedConfig bool
|
|
||||||
|
|
||||||
// Shared credentials file path can be set to instruct the SDK to use an alternate
|
|
||||||
// file for the shared credentials. If not set the file will be loaded from
|
|
||||||
// $HOME/.aws/credentials on Linux/Unix based systems, and
|
|
||||||
// %USERPROFILE%\.aws\credentials on Windows.
|
|
||||||
//
|
|
||||||
// AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials
|
|
||||||
SharedCredentialsFile string
|
|
||||||
|
|
||||||
// Shared config file path can be set to instruct the SDK to use an alternate
|
|
||||||
// file for the shared config. If not set the file will be loaded from
|
|
||||||
// $HOME/.aws/config on Linux/Unix based systems, and
|
|
||||||
// %USERPROFILE%\.aws\config on Windows.
|
|
||||||
//
|
|
||||||
// AWS_CONFIG_FILE=$HOME/my_shared_config
|
|
||||||
SharedConfigFile string
|
|
||||||
|
|
||||||
// Sets the path to a custom Credentials Authroity (CA) Bundle PEM file
|
|
||||||
// that the SDK will use instead of the system's root CA bundle.
|
|
||||||
// Only use this if you want to configure the SDK to use a custom set
|
|
||||||
// of CAs.
|
|
||||||
//
|
|
||||||
// Enabling this option will attempt to merge the Transport
|
|
||||||
// into the SDK's HTTP client. If the client's Transport is
|
|
||||||
// not a http.Transport an error will be returned. If the
|
|
||||||
// Transport's TLS config is set this option will cause the
|
|
||||||
// SDK to overwrite the Transport's TLS config's RootCAs value.
|
|
||||||
//
|
|
||||||
// Setting a custom HTTPClient in the aws.Config options will override this setting.
|
|
||||||
// To use this option and custom HTTP client, the HTTP client needs to be provided
|
|
||||||
// when creating the session. Not the service client.
|
|
||||||
//
|
|
||||||
// AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle
|
|
||||||
CustomCABundle string
|
|
||||||
|
|
||||||
csmEnabled string
|
|
||||||
CSMEnabled bool
|
|
||||||
CSMPort string
|
|
||||||
CSMClientID string
|
|
||||||
|
|
||||||
enableEndpointDiscovery string
|
|
||||||
// Enables endpoint discovery via environment variables.
|
|
||||||
//
|
|
||||||
// AWS_ENABLE_ENDPOINT_DISCOVERY=true
|
|
||||||
EnableEndpointDiscovery *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
csmEnabledEnvKey = []string{
|
|
||||||
"AWS_CSM_ENABLED",
|
|
||||||
}
|
|
||||||
csmPortEnvKey = []string{
|
|
||||||
"AWS_CSM_PORT",
|
|
||||||
}
|
|
||||||
csmClientIDEnvKey = []string{
|
|
||||||
"AWS_CSM_CLIENT_ID",
|
|
||||||
}
|
|
||||||
credAccessEnvKey = []string{
|
|
||||||
"AWS_ACCESS_KEY_ID",
|
|
||||||
"AWS_ACCESS_KEY",
|
|
||||||
}
|
|
||||||
credSecretEnvKey = []string{
|
|
||||||
"AWS_SECRET_ACCESS_KEY",
|
|
||||||
"AWS_SECRET_KEY",
|
|
||||||
}
|
|
||||||
credSessionEnvKey = []string{
|
|
||||||
"AWS_SESSION_TOKEN",
|
|
||||||
}
|
|
||||||
|
|
||||||
enableEndpointDiscoveryEnvKey = []string{
|
|
||||||
"AWS_ENABLE_ENDPOINT_DISCOVERY",
|
|
||||||
}
|
|
||||||
|
|
||||||
regionEnvKeys = []string{
|
|
||||||
"AWS_REGION",
|
|
||||||
"AWS_DEFAULT_REGION", // Only read if AWS_SDK_LOAD_CONFIG is also set
|
|
||||||
}
|
|
||||||
profileEnvKeys = []string{
|
|
||||||
"AWS_PROFILE",
|
|
||||||
"AWS_DEFAULT_PROFILE", // Only read if AWS_SDK_LOAD_CONFIG is also set
|
|
||||||
}
|
|
||||||
sharedCredsFileEnvKey = []string{
|
|
||||||
"AWS_SHARED_CREDENTIALS_FILE",
|
|
||||||
}
|
|
||||||
sharedConfigFileEnvKey = []string{
|
|
||||||
"AWS_CONFIG_FILE",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// loadEnvConfig retrieves the SDK's environment configuration.
|
|
||||||
// See `envConfig` for the values that will be retrieved.
|
|
||||||
//
|
|
||||||
// If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value
|
|
||||||
// the shared SDK config will be loaded in addition to the SDK's specific
|
|
||||||
// configuration values.
|
|
||||||
func loadEnvConfig() envConfig {
|
|
||||||
enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG"))
|
|
||||||
return envConfigLoad(enableSharedConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadEnvSharedConfig retrieves the SDK's environment configuration, and the
|
|
||||||
// SDK shared config. See `envConfig` for the values that will be retrieved.
|
|
||||||
//
|
|
||||||
// Loads the shared configuration in addition to the SDK's specific configuration.
|
|
||||||
// This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG`
|
|
||||||
// environment variable is set.
|
|
||||||
func loadSharedEnvConfig() envConfig {
|
|
||||||
return envConfigLoad(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func envConfigLoad(enableSharedConfig bool) envConfig {
|
|
||||||
cfg := envConfig{}
|
|
||||||
|
|
||||||
cfg.EnableSharedConfig = enableSharedConfig
|
|
||||||
|
|
||||||
setFromEnvVal(&cfg.Creds.AccessKeyID, credAccessEnvKey)
|
|
||||||
setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey)
|
|
||||||
setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey)
|
|
||||||
|
|
||||||
// CSM environment variables
|
|
||||||
setFromEnvVal(&cfg.csmEnabled, csmEnabledEnvKey)
|
|
||||||
setFromEnvVal(&cfg.CSMPort, csmPortEnvKey)
|
|
||||||
setFromEnvVal(&cfg.CSMClientID, csmClientIDEnvKey)
|
|
||||||
cfg.CSMEnabled = len(cfg.csmEnabled) > 0
|
|
||||||
|
|
||||||
// Require logical grouping of credentials
|
|
||||||
if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 {
|
|
||||||
cfg.Creds = credentials.Value{}
|
|
||||||
} else {
|
|
||||||
cfg.Creds.ProviderName = EnvProviderName
|
|
||||||
}
|
|
||||||
|
|
||||||
regionKeys := regionEnvKeys
|
|
||||||
profileKeys := profileEnvKeys
|
|
||||||
if !cfg.EnableSharedConfig {
|
|
||||||
regionKeys = regionKeys[:1]
|
|
||||||
profileKeys = profileKeys[:1]
|
|
||||||
}
|
|
||||||
|
|
||||||
setFromEnvVal(&cfg.Region, regionKeys)
|
|
||||||
setFromEnvVal(&cfg.Profile, profileKeys)
|
|
||||||
|
|
||||||
// endpoint discovery is in reference to it being enabled.
|
|
||||||
setFromEnvVal(&cfg.enableEndpointDiscovery, enableEndpointDiscoveryEnvKey)
|
|
||||||
if len(cfg.enableEndpointDiscovery) > 0 {
|
|
||||||
cfg.EnableEndpointDiscovery = aws.Bool(cfg.enableEndpointDiscovery != "false")
|
|
||||||
}
|
|
||||||
|
|
||||||
setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey)
|
|
||||||
setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey)
|
|
||||||
|
|
||||||
if len(cfg.SharedCredentialsFile) == 0 {
|
|
||||||
cfg.SharedCredentialsFile = defaults.SharedCredentialsFilename()
|
|
||||||
}
|
|
||||||
if len(cfg.SharedConfigFile) == 0 {
|
|
||||||
cfg.SharedConfigFile = defaults.SharedConfigFilename()
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE")
|
|
||||||
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
func setFromEnvVal(dst *string, keys []string) {
|
|
||||||
for _, k := range keys {
|
|
||||||
if v := os.Getenv(k); len(v) > 0 {
|
|
||||||
*dst = v
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
711
vendor/github.com/aws/aws-sdk-go/aws/session/session.go
generated
vendored
711
vendor/github.com/aws/aws-sdk-go/aws/session/session.go
generated
vendored
@ -1,711 +0,0 @@
|
|||||||
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"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/client"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/corehandlers"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials/stscreds"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/csm"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/defaults"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/shareddefaults"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ErrCodeSharedConfig represents an error that occurs in the shared
|
|
||||||
// configuration logic
|
|
||||||
ErrCodeSharedConfig = "SharedConfigErr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ErrSharedConfigSourceCollision will be returned if a section contains both
|
|
||||||
// source_profile and credential_source
|
|
||||||
var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only source profile or credential source can be specified, not both", nil)
|
|
||||||
|
|
||||||
// ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment
|
|
||||||
// variables are empty and Environment was set as the credential source
|
|
||||||
var ErrSharedConfigECSContainerEnvVarEmpty = awserr.New(ErrCodeSharedConfig, "EcsContainer was specified as the credential_source, but 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' was not set", nil)
|
|
||||||
|
|
||||||
// ErrSharedConfigInvalidCredSource will be returned if an invalid credential source was provided
|
|
||||||
var ErrSharedConfigInvalidCredSource = awserr.New(ErrCodeSharedConfig, "credential source values must be EcsContainer, Ec2InstanceMetadata, or Environment", nil)
|
|
||||||
|
|
||||||
// A Session provides a central location to create service clients from and
|
|
||||||
// store configurations and request handlers for those services.
|
|
||||||
//
|
|
||||||
// Sessions are safe to create service clients concurrently, but it is not safe
|
|
||||||
// to mutate the Session concurrently.
|
|
||||||
//
|
|
||||||
// The Session satisfies the service client's client.ConfigProvider.
|
|
||||||
type Session struct {
|
|
||||||
Config *aws.Config
|
|
||||||
Handlers request.Handlers
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new instance of the handlers merging in the provided configs
|
|
||||||
// on top of the SDK's default configurations. Once the Session is created it
|
|
||||||
// can be mutated to modify the Config or Handlers. The Session is safe to be
|
|
||||||
// read concurrently, but it should not be written to concurrently.
|
|
||||||
//
|
|
||||||
// If the AWS_SDK_LOAD_CONFIG environment is set to a truthy value, the New
|
|
||||||
// method could now encounter an error when loading the configuration. When
|
|
||||||
// The environment variable is set, and an error occurs, New will return a
|
|
||||||
// session that will fail all requests reporting the error that occurred while
|
|
||||||
// loading the session. Use NewSession to get the error when creating the
|
|
||||||
// session.
|
|
||||||
//
|
|
||||||
// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
|
|
||||||
// the shared config file (~/.aws/config) will also be loaded, in addition to
|
|
||||||
// the shared credentials file (~/.aws/credentials). Values set in both the
|
|
||||||
// shared config, and shared credentials will be taken from the shared
|
|
||||||
// credentials file.
|
|
||||||
//
|
|
||||||
// Deprecated: Use NewSession functions to create sessions instead. NewSession
|
|
||||||
// has the same functionality as New except an error can be returned when the
|
|
||||||
// func is called instead of waiting to receive an error until a request is made.
|
|
||||||
func New(cfgs ...*aws.Config) *Session {
|
|
||||||
// load initial config from environment
|
|
||||||
envCfg := loadEnvConfig()
|
|
||||||
|
|
||||||
if envCfg.EnableSharedConfig {
|
|
||||||
var cfg aws.Config
|
|
||||||
cfg.MergeIn(cfgs...)
|
|
||||||
s, err := NewSessionWithOptions(Options{
|
|
||||||
Config: cfg,
|
|
||||||
SharedConfigState: SharedConfigEnable,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
// Old session.New expected all errors to be discovered when
|
|
||||||
// a request is made, and would report the errors then. This
|
|
||||||
// needs to be replicated if an error occurs while creating
|
|
||||||
// the session.
|
|
||||||
msg := "failed to create session with AWS_SDK_LOAD_CONFIG enabled. " +
|
|
||||||
"Use session.NewSession to handle errors occurring during session creation."
|
|
||||||
|
|
||||||
// Session creation failed, need to report the error and prevent
|
|
||||||
// any requests from succeeding.
|
|
||||||
s = &Session{Config: defaults.Config()}
|
|
||||||
s.Config.MergeIn(cfgs...)
|
|
||||||
s.Config.Logger.Log("ERROR:", msg, "Error:", err)
|
|
||||||
s.Handlers.Validate.PushBack(func(r *request.Request) {
|
|
||||||
r.Error = err
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
s := deprecatedNewSession(cfgs...)
|
|
||||||
if envCfg.CSMEnabled {
|
|
||||||
enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger)
|
|
||||||
}
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSession returns a new Session created from SDK defaults, config files,
|
|
||||||
// environment, and user provided config files. Once the Session is created
|
|
||||||
// it can be mutated to modify the Config or Handlers. The Session is safe to
|
|
||||||
// be read concurrently, but it should not be written to concurrently.
|
|
||||||
//
|
|
||||||
// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
|
|
||||||
// the shared config file (~/.aws/config) will also be loaded in addition to
|
|
||||||
// the shared credentials file (~/.aws/credentials). Values set in both the
|
|
||||||
// shared config, and shared credentials will be taken from the shared
|
|
||||||
// credentials file. Enabling the Shared Config will also allow the Session
|
|
||||||
// to be built with retrieving credentials with AssumeRole set in the config.
|
|
||||||
//
|
|
||||||
// See the NewSessionWithOptions func for information on how to override or
|
|
||||||
// control through code how the Session will be created. Such as specifying the
|
|
||||||
// config profile, and controlling if shared config is enabled or not.
|
|
||||||
func NewSession(cfgs ...*aws.Config) (*Session, error) {
|
|
||||||
opts := Options{}
|
|
||||||
opts.Config.MergeIn(cfgs...)
|
|
||||||
|
|
||||||
return NewSessionWithOptions(opts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SharedConfigState provides the ability to optionally override the state
|
|
||||||
// of the session's creation based on the shared config being enabled or
|
|
||||||
// disabled.
|
|
||||||
type SharedConfigState int
|
|
||||||
|
|
||||||
const (
|
|
||||||
// SharedConfigStateFromEnv does not override any state of the
|
|
||||||
// AWS_SDK_LOAD_CONFIG env var. It is the default value of the
|
|
||||||
// SharedConfigState type.
|
|
||||||
SharedConfigStateFromEnv SharedConfigState = iota
|
|
||||||
|
|
||||||
// SharedConfigDisable overrides the AWS_SDK_LOAD_CONFIG env var value
|
|
||||||
// and disables the shared config functionality.
|
|
||||||
SharedConfigDisable
|
|
||||||
|
|
||||||
// SharedConfigEnable overrides the AWS_SDK_LOAD_CONFIG env var value
|
|
||||||
// and enables the shared config functionality.
|
|
||||||
SharedConfigEnable
|
|
||||||
)
|
|
||||||
|
|
||||||
// Options provides the means to control how a Session is created and what
|
|
||||||
// configuration values will be loaded.
|
|
||||||
//
|
|
||||||
type Options struct {
|
|
||||||
// Provides config values for the SDK to use when creating service clients
|
|
||||||
// and making API requests to services. Any value set in with this field
|
|
||||||
// will override the associated value provided by the SDK defaults,
|
|
||||||
// environment or config files where relevant.
|
|
||||||
//
|
|
||||||
// If not set, configuration values from from SDK defaults, environment,
|
|
||||||
// config will be used.
|
|
||||||
Config aws.Config
|
|
||||||
|
|
||||||
// Overrides the config profile the Session should be created from. If not
|
|
||||||
// set the value of the environment variable will be loaded (AWS_PROFILE,
|
|
||||||
// or AWS_DEFAULT_PROFILE if the Shared Config is enabled).
|
|
||||||
//
|
|
||||||
// If not set and environment variables are not set the "default"
|
|
||||||
// (DefaultSharedConfigProfile) will be used as the profile to load the
|
|
||||||
// session config from.
|
|
||||||
Profile string
|
|
||||||
|
|
||||||
// Instructs how the Session will be created based on the AWS_SDK_LOAD_CONFIG
|
|
||||||
// environment variable. By default a Session will be created using the
|
|
||||||
// value provided by the AWS_SDK_LOAD_CONFIG environment variable.
|
|
||||||
//
|
|
||||||
// Setting this value to SharedConfigEnable or SharedConfigDisable
|
|
||||||
// will allow you to override the AWS_SDK_LOAD_CONFIG environment variable
|
|
||||||
// and enable or disable the shared config functionality.
|
|
||||||
SharedConfigState SharedConfigState
|
|
||||||
|
|
||||||
// Ordered list of files the session will load configuration from.
|
|
||||||
// It will override environment variable AWS_SHARED_CREDENTIALS_FILE, AWS_CONFIG_FILE.
|
|
||||||
SharedConfigFiles []string
|
|
||||||
|
|
||||||
// When the SDK's shared config is configured to assume a role with MFA
|
|
||||||
// this option is required in order to provide the mechanism that will
|
|
||||||
// retrieve the MFA token. There is no default value for this field. If
|
|
||||||
// it is not set an error will be returned when creating the session.
|
|
||||||
//
|
|
||||||
// This token provider will be called when ever the assumed role's
|
|
||||||
// credentials need to be refreshed. Within the context of service clients
|
|
||||||
// all sharing the same session the SDK will ensure calls to the token
|
|
||||||
// provider are atomic. When sharing a token provider across multiple
|
|
||||||
// sessions additional synchronization logic is needed to ensure the
|
|
||||||
// token providers do not introduce race conditions. It is recommend to
|
|
||||||
// share the session where possible.
|
|
||||||
//
|
|
||||||
// stscreds.StdinTokenProvider is a basic implementation that will prompt
|
|
||||||
// from stdin for the MFA token code.
|
|
||||||
//
|
|
||||||
// This field is only used if the shared configuration is enabled, and
|
|
||||||
// the config enables assume role wit MFA via the mfa_serial field.
|
|
||||||
AssumeRoleTokenProvider func() (string, error)
|
|
||||||
|
|
||||||
// Reader for a custom Credentials Authority (CA) bundle in PEM format that
|
|
||||||
// the SDK will use instead of the default system's root CA bundle. Use this
|
|
||||||
// only if you want to replace the CA bundle the SDK uses for TLS requests.
|
|
||||||
//
|
|
||||||
// Enabling this option will attempt to merge the Transport into the SDK's HTTP
|
|
||||||
// client. If the client's Transport is not a http.Transport an error will be
|
|
||||||
// returned. If the Transport's TLS config is set this option will cause the SDK
|
|
||||||
// to overwrite the Transport's TLS config's RootCAs value. If the CA
|
|
||||||
// bundle reader contains multiple certificates all of them will be loaded.
|
|
||||||
//
|
|
||||||
// The Session option CustomCABundle is also available when creating sessions
|
|
||||||
// to also enable this feature. CustomCABundle session option field has priority
|
|
||||||
// over the AWS_CA_BUNDLE environment variable, and will be used if both are set.
|
|
||||||
CustomCABundle io.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSessionWithOptions returns a new Session created from SDK defaults, config files,
|
|
||||||
// environment, and user provided config files. This func uses the Options
|
|
||||||
// values to configure how the Session is created.
|
|
||||||
//
|
|
||||||
// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value
|
|
||||||
// the shared config file (~/.aws/config) will also be loaded in addition to
|
|
||||||
// the shared credentials file (~/.aws/credentials). Values set in both the
|
|
||||||
// shared config, and shared credentials will be taken from the shared
|
|
||||||
// credentials file. Enabling the Shared Config will also allow the Session
|
|
||||||
// to be built with retrieving credentials with AssumeRole set in the config.
|
|
||||||
//
|
|
||||||
// // Equivalent to session.New
|
|
||||||
// sess := session.Must(session.NewSessionWithOptions(session.Options{}))
|
|
||||||
//
|
|
||||||
// // Specify profile to load for the session's config
|
|
||||||
// sess := session.Must(session.NewSessionWithOptions(session.Options{
|
|
||||||
// Profile: "profile_name",
|
|
||||||
// }))
|
|
||||||
//
|
|
||||||
// // Specify profile for config and region for requests
|
|
||||||
// sess := session.Must(session.NewSessionWithOptions(session.Options{
|
|
||||||
// Config: aws.Config{Region: aws.String("us-east-1")},
|
|
||||||
// Profile: "profile_name",
|
|
||||||
// }))
|
|
||||||
//
|
|
||||||
// // Force enable Shared Config support
|
|
||||||
// sess := session.Must(session.NewSessionWithOptions(session.Options{
|
|
||||||
// SharedConfigState: session.SharedConfigEnable,
|
|
||||||
// }))
|
|
||||||
func NewSessionWithOptions(opts Options) (*Session, error) {
|
|
||||||
var envCfg envConfig
|
|
||||||
if opts.SharedConfigState == SharedConfigEnable {
|
|
||||||
envCfg = loadSharedEnvConfig()
|
|
||||||
} else {
|
|
||||||
envCfg = loadEnvConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(opts.Profile) > 0 {
|
|
||||||
envCfg.Profile = opts.Profile
|
|
||||||
}
|
|
||||||
|
|
||||||
switch opts.SharedConfigState {
|
|
||||||
case SharedConfigDisable:
|
|
||||||
envCfg.EnableSharedConfig = false
|
|
||||||
case SharedConfigEnable:
|
|
||||||
envCfg.EnableSharedConfig = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only use AWS_CA_BUNDLE if session option is not provided.
|
|
||||||
if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil {
|
|
||||||
f, err := os.Open(envCfg.CustomCABundle)
|
|
||||||
if err != nil {
|
|
||||||
return nil, awserr.New("LoadCustomCABundleError",
|
|
||||||
"failed to open custom CA bundle PEM file", err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
opts.CustomCABundle = f
|
|
||||||
}
|
|
||||||
|
|
||||||
return newSession(opts, envCfg, &opts.Config)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must is a helper function to ensure the Session is valid and there was no
|
|
||||||
// error when calling a NewSession function.
|
|
||||||
//
|
|
||||||
// This helper is intended to be used in variable initialization to load the
|
|
||||||
// Session and configuration at startup. Such as:
|
|
||||||
//
|
|
||||||
// var sess = session.Must(session.NewSession())
|
|
||||||
func Must(sess *Session, err error) *Session {
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return sess
|
|
||||||
}
|
|
||||||
|
|
||||||
func deprecatedNewSession(cfgs ...*aws.Config) *Session {
|
|
||||||
cfg := defaults.Config()
|
|
||||||
handlers := defaults.Handlers()
|
|
||||||
|
|
||||||
// Apply the passed in configs so the configuration can be applied to the
|
|
||||||
// default credential chain
|
|
||||||
cfg.MergeIn(cfgs...)
|
|
||||||
if cfg.EndpointResolver == nil {
|
|
||||||
// An endpoint resolver is required for a session to be able to provide
|
|
||||||
// endpoints for service client configurations.
|
|
||||||
cfg.EndpointResolver = endpoints.DefaultResolver()
|
|
||||||
}
|
|
||||||
cfg.Credentials = defaults.CredChain(cfg, handlers)
|
|
||||||
|
|
||||||
// Reapply any passed in configs to override credentials if set
|
|
||||||
cfg.MergeIn(cfgs...)
|
|
||||||
|
|
||||||
s := &Session{
|
|
||||||
Config: cfg,
|
|
||||||
Handlers: handlers,
|
|
||||||
}
|
|
||||||
|
|
||||||
initHandlers(s)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func enableCSM(handlers *request.Handlers, clientID string, port string, logger aws.Logger) {
|
|
||||||
logger.Log("Enabling CSM")
|
|
||||||
if len(port) == 0 {
|
|
||||||
port = csm.DefaultPort
|
|
||||||
}
|
|
||||||
|
|
||||||
r, err := csm.Start(clientID, "127.0.0.1:"+port)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
r.InjectHandlers(handlers)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) {
|
|
||||||
cfg := defaults.Config()
|
|
||||||
handlers := defaults.Handlers()
|
|
||||||
|
|
||||||
// Get a merged version of the user provided config to determine if
|
|
||||||
// credentials were.
|
|
||||||
userCfg := &aws.Config{}
|
|
||||||
userCfg.MergeIn(cfgs...)
|
|
||||||
|
|
||||||
// Ordered config files will be loaded in with later files overwriting
|
|
||||||
// previous config file values.
|
|
||||||
var cfgFiles []string
|
|
||||||
if opts.SharedConfigFiles != nil {
|
|
||||||
cfgFiles = opts.SharedConfigFiles
|
|
||||||
} else {
|
|
||||||
cfgFiles = []string{envCfg.SharedConfigFile, envCfg.SharedCredentialsFile}
|
|
||||||
if !envCfg.EnableSharedConfig {
|
|
||||||
// The shared config file (~/.aws/config) is only loaded if instructed
|
|
||||||
// to load via the envConfig.EnableSharedConfig (AWS_SDK_LOAD_CONFIG).
|
|
||||||
cfgFiles = cfgFiles[1:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load additional config from file(s)
|
|
||||||
sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
s := &Session{
|
|
||||||
Config: cfg,
|
|
||||||
Handlers: handlers,
|
|
||||||
}
|
|
||||||
|
|
||||||
initHandlers(s)
|
|
||||||
if envCfg.CSMEnabled {
|
|
||||||
enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup HTTP client with custom cert bundle if enabled
|
|
||||||
if opts.CustomCABundle != nil {
|
|
||||||
if err := loadCustomCABundle(s, opts.CustomCABundle); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadCustomCABundle(s *Session, bundle io.Reader) error {
|
|
||||||
var t *http.Transport
|
|
||||||
switch v := s.Config.HTTPClient.Transport.(type) {
|
|
||||||
case *http.Transport:
|
|
||||||
t = v
|
|
||||||
default:
|
|
||||||
if s.Config.HTTPClient.Transport != nil {
|
|
||||||
return awserr.New("LoadCustomCABundleError",
|
|
||||||
"unable to load custom CA bundle, HTTPClient's transport unsupported type", nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if t == nil {
|
|
||||||
t = &http.Transport{}
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := loadCertPool(bundle)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if t.TLSClientConfig == nil {
|
|
||||||
t.TLSClientConfig = &tls.Config{}
|
|
||||||
}
|
|
||||||
t.TLSClientConfig.RootCAs = p
|
|
||||||
|
|
||||||
s.Config.HTTPClient.Transport = t
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadCertPool(r io.Reader) (*x509.CertPool, error) {
|
|
||||||
b, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, awserr.New("LoadCustomCABundleError",
|
|
||||||
"failed to read custom CA bundle PEM file", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
p := x509.NewCertPool()
|
|
||||||
if !p.AppendCertsFromPEM(b) {
|
|
||||||
return nil, awserr.New("LoadCustomCABundleError",
|
|
||||||
"failed to load custom CA bundle PEM file", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return p, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers, sessOpts Options) error {
|
|
||||||
// Merge in user provided configuration
|
|
||||||
cfg.MergeIn(userCfg)
|
|
||||||
|
|
||||||
// Region if not already set by user
|
|
||||||
if len(aws.StringValue(cfg.Region)) == 0 {
|
|
||||||
if len(envCfg.Region) > 0 {
|
|
||||||
cfg.WithRegion(envCfg.Region)
|
|
||||||
} else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 {
|
|
||||||
cfg.WithRegion(sharedCfg.Region)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if aws.BoolValue(envCfg.EnableEndpointDiscovery) {
|
|
||||||
if envCfg.EnableEndpointDiscovery != nil {
|
|
||||||
cfg.WithEndpointDiscovery(*envCfg.EnableEndpointDiscovery)
|
|
||||||
} else if envCfg.EnableSharedConfig && sharedCfg.EnableEndpointDiscovery != nil {
|
|
||||||
cfg.WithEndpointDiscovery(*sharedCfg.EnableEndpointDiscovery)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure credentials if not already set
|
|
||||||
if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
|
|
||||||
|
|
||||||
// inspect the profile to see if a credential source has been specified.
|
|
||||||
if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.CredentialSource) > 0 {
|
|
||||||
|
|
||||||
// if both credential_source and source_profile have been set, return an error
|
|
||||||
// as this is undefined behavior.
|
|
||||||
if len(sharedCfg.AssumeRole.SourceProfile) > 0 {
|
|
||||||
return ErrSharedConfigSourceCollision
|
|
||||||
}
|
|
||||||
|
|
||||||
// valid credential source values
|
|
||||||
const (
|
|
||||||
credSourceEc2Metadata = "Ec2InstanceMetadata"
|
|
||||||
credSourceEnvironment = "Environment"
|
|
||||||
credSourceECSContainer = "EcsContainer"
|
|
||||||
)
|
|
||||||
|
|
||||||
switch sharedCfg.AssumeRole.CredentialSource {
|
|
||||||
case credSourceEc2Metadata:
|
|
||||||
cfgCp := *cfg
|
|
||||||
p := defaults.RemoteCredProvider(cfgCp, handlers)
|
|
||||||
cfgCp.Credentials = credentials.NewCredentials(p)
|
|
||||||
|
|
||||||
if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
|
|
||||||
// AssumeRole Token provider is required if doing Assume Role
|
|
||||||
// with MFA.
|
|
||||||
return AssumeRoleTokenProviderNotSetError{}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.Credentials = assumeRoleCredentials(cfgCp, handlers, sharedCfg, sessOpts)
|
|
||||||
case credSourceEnvironment:
|
|
||||||
cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
|
|
||||||
envCfg.Creds,
|
|
||||||
)
|
|
||||||
case credSourceECSContainer:
|
|
||||||
if len(os.Getenv(shareddefaults.ECSCredsProviderEnvVar)) == 0 {
|
|
||||||
return ErrSharedConfigECSContainerEnvVarEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
cfgCp := *cfg
|
|
||||||
p := defaults.RemoteCredProvider(cfgCp, handlers)
|
|
||||||
creds := credentials.NewCredentials(p)
|
|
||||||
|
|
||||||
cfg.Credentials = creds
|
|
||||||
default:
|
|
||||||
return ErrSharedConfigInvalidCredSource
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(envCfg.Creds.AccessKeyID) > 0 {
|
|
||||||
cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
|
|
||||||
envCfg.Creds,
|
|
||||||
)
|
|
||||||
} else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil {
|
|
||||||
cfgCp := *cfg
|
|
||||||
cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds(
|
|
||||||
sharedCfg.AssumeRoleSource.Creds,
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil {
|
|
||||||
// AssumeRole Token provider is required if doing Assume Role
|
|
||||||
// with MFA.
|
|
||||||
return AssumeRoleTokenProviderNotSetError{}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.Credentials = assumeRoleCredentials(cfgCp, handlers, sharedCfg, sessOpts)
|
|
||||||
} else if len(sharedCfg.Creds.AccessKeyID) > 0 {
|
|
||||||
cfg.Credentials = credentials.NewStaticCredentialsFromCreds(
|
|
||||||
sharedCfg.Creds,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// Fallback to default credentials provider, include mock errors
|
|
||||||
// for the credential chain so user can identify why credentials
|
|
||||||
// failed to be retrieved.
|
|
||||||
cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{
|
|
||||||
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors),
|
|
||||||
Providers: []credentials.Provider{
|
|
||||||
&credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)},
|
|
||||||
&credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)},
|
|
||||||
defaults.RemoteCredProvider(*cfg, handlers),
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func assumeRoleCredentials(cfg aws.Config, handlers request.Handlers, sharedCfg sharedConfig, sessOpts Options) *credentials.Credentials {
|
|
||||||
return stscreds.NewCredentials(
|
|
||||||
&Session{
|
|
||||||
Config: &cfg,
|
|
||||||
Handlers: handlers.Copy(),
|
|
||||||
},
|
|
||||||
sharedCfg.AssumeRole.RoleARN,
|
|
||||||
func(opt *stscreds.AssumeRoleProvider) {
|
|
||||||
opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName
|
|
||||||
|
|
||||||
// Assume role with external ID
|
|
||||||
if len(sharedCfg.AssumeRole.ExternalID) > 0 {
|
|
||||||
opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assume role with MFA
|
|
||||||
if len(sharedCfg.AssumeRole.MFASerial) > 0 {
|
|
||||||
opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial)
|
|
||||||
opt.TokenProvider = sessOpts.AssumeRoleTokenProvider
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the
|
|
||||||
// MFAToken option is not set when shared config is configured load assume a
|
|
||||||
// role with an MFA token.
|
|
||||||
type AssumeRoleTokenProviderNotSetError struct{}
|
|
||||||
|
|
||||||
// Code is the short id of the error.
|
|
||||||
func (e AssumeRoleTokenProviderNotSetError) Code() string {
|
|
||||||
return "AssumeRoleTokenProviderNotSetError"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message is the description of the error
|
|
||||||
func (e AssumeRoleTokenProviderNotSetError) Message() string {
|
|
||||||
return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErr is the underlying error that caused the failure.
|
|
||||||
func (e AssumeRoleTokenProviderNotSetError) OrigErr() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error satisfies the error interface.
|
|
||||||
func (e AssumeRoleTokenProviderNotSetError) Error() string {
|
|
||||||
return awserr.SprintError(e.Code(), e.Message(), "", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
type credProviderError struct {
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
var emptyCreds = credentials.Value{}
|
|
||||||
|
|
||||||
func (c credProviderError) Retrieve() (credentials.Value, error) {
|
|
||||||
return credentials.Value{}, c.Err
|
|
||||||
}
|
|
||||||
func (c credProviderError) IsExpired() bool {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func initHandlers(s *Session) {
|
|
||||||
// Add the Validate parameter handler if it is not disabled.
|
|
||||||
s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler)
|
|
||||||
if !aws.BoolValue(s.Config.DisableParamValidation) {
|
|
||||||
s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy creates and returns a copy of the current Session, coping the config
|
|
||||||
// and handlers. If any additional configs are provided they will be merged
|
|
||||||
// on top of the Session's copied config.
|
|
||||||
//
|
|
||||||
// // Create a copy of the current Session, configured for the us-west-2 region.
|
|
||||||
// sess.Copy(&aws.Config{Region: aws.String("us-west-2")})
|
|
||||||
func (s *Session) Copy(cfgs ...*aws.Config) *Session {
|
|
||||||
newSession := &Session{
|
|
||||||
Config: s.Config.Copy(cfgs...),
|
|
||||||
Handlers: s.Handlers.Copy(),
|
|
||||||
}
|
|
||||||
|
|
||||||
initHandlers(newSession)
|
|
||||||
|
|
||||||
return newSession
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientConfig satisfies the client.ConfigProvider interface and is used to
|
|
||||||
// configure the service client instances. Passing the Session to the service
|
|
||||||
// client's constructor (New) will use this method to configure the client.
|
|
||||||
func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
|
|
||||||
// Backwards compatibility, the error will be eaten if user calls ClientConfig
|
|
||||||
// directly. All SDK services will use ClientconfigWithError.
|
|
||||||
cfg, _ := s.clientConfigWithErr(serviceName, cfgs...)
|
|
||||||
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (client.Config, error) {
|
|
||||||
s = s.Copy(cfgs...)
|
|
||||||
|
|
||||||
var resolved endpoints.ResolvedEndpoint
|
|
||||||
var err error
|
|
||||||
|
|
||||||
region := aws.StringValue(s.Config.Region)
|
|
||||||
|
|
||||||
if endpoint := aws.StringValue(s.Config.Endpoint); len(endpoint) != 0 {
|
|
||||||
resolved.URL = endpoints.AddScheme(endpoint, aws.BoolValue(s.Config.DisableSSL))
|
|
||||||
resolved.SigningRegion = region
|
|
||||||
} else {
|
|
||||||
resolved, err = s.Config.EndpointResolver.EndpointFor(
|
|
||||||
serviceName, region,
|
|
||||||
func(opt *endpoints.Options) {
|
|
||||||
opt.DisableSSL = aws.BoolValue(s.Config.DisableSSL)
|
|
||||||
opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack)
|
|
||||||
|
|
||||||
// Support the condition where the service is modeled but its
|
|
||||||
// endpoint metadata is not available.
|
|
||||||
opt.ResolveUnknownService = true
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return client.Config{
|
|
||||||
Config: s.Config,
|
|
||||||
Handlers: s.Handlers,
|
|
||||||
Endpoint: resolved.URL,
|
|
||||||
SigningRegion: resolved.SigningRegion,
|
|
||||||
SigningNameDerived: resolved.SigningNameDerived,
|
|
||||||
SigningName: resolved.SigningName,
|
|
||||||
}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientConfigNoResolveEndpoint is the same as ClientConfig with the exception
|
|
||||||
// that the EndpointResolver will not be used to resolve the endpoint. The only
|
|
||||||
// endpoint set must come from the aws.Config.Endpoint field.
|
|
||||||
func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Config {
|
|
||||||
s = s.Copy(cfgs...)
|
|
||||||
|
|
||||||
var resolved endpoints.ResolvedEndpoint
|
|
||||||
|
|
||||||
region := aws.StringValue(s.Config.Region)
|
|
||||||
|
|
||||||
if ep := aws.StringValue(s.Config.Endpoint); len(ep) > 0 {
|
|
||||||
resolved.URL = endpoints.AddScheme(ep, aws.BoolValue(s.Config.DisableSSL))
|
|
||||||
resolved.SigningRegion = region
|
|
||||||
}
|
|
||||||
|
|
||||||
return client.Config{
|
|
||||||
Config: s.Config,
|
|
||||||
Handlers: s.Handlers,
|
|
||||||
Endpoint: resolved.URL,
|
|
||||||
SigningRegion: resolved.SigningRegion,
|
|
||||||
SigningNameDerived: resolved.SigningNameDerived,
|
|
||||||
SigningName: resolved.SigningName,
|
|
||||||
}
|
|
||||||
}
|
|
319
vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
generated
vendored
319
vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go
generated
vendored
@ -1,319 +0,0 @@
|
|||||||
package session
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/internal/ini"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Static Credentials group
|
|
||||||
accessKeyIDKey = `aws_access_key_id` // group required
|
|
||||||
secretAccessKey = `aws_secret_access_key` // group required
|
|
||||||
sessionTokenKey = `aws_session_token` // optional
|
|
||||||
|
|
||||||
// Assume Role Credentials group
|
|
||||||
roleArnKey = `role_arn` // group required
|
|
||||||
sourceProfileKey = `source_profile` // group required (or credential_source)
|
|
||||||
credentialSourceKey = `credential_source` // group required (or source_profile)
|
|
||||||
externalIDKey = `external_id` // optional
|
|
||||||
mfaSerialKey = `mfa_serial` // optional
|
|
||||||
roleSessionNameKey = `role_session_name` // optional
|
|
||||||
|
|
||||||
// Additional Config fields
|
|
||||||
regionKey = `region`
|
|
||||||
|
|
||||||
// endpoint discovery group
|
|
||||||
enableEndpointDiscoveryKey = `endpoint_discovery_enabled` // optional
|
|
||||||
|
|
||||||
// DefaultSharedConfigProfile is the default profile to be used when
|
|
||||||
// loading configuration from the config files if another profile name
|
|
||||||
// is not provided.
|
|
||||||
DefaultSharedConfigProfile = `default`
|
|
||||||
)
|
|
||||||
|
|
||||||
type assumeRoleConfig struct {
|
|
||||||
RoleARN string
|
|
||||||
SourceProfile string
|
|
||||||
CredentialSource string
|
|
||||||
ExternalID string
|
|
||||||
MFASerial string
|
|
||||||
RoleSessionName string
|
|
||||||
}
|
|
||||||
|
|
||||||
// sharedConfig represents the configuration fields of the SDK config files.
|
|
||||||
type sharedConfig struct {
|
|
||||||
// Credentials values from the config file. Both aws_access_key_id
|
|
||||||
// and aws_secret_access_key must be provided together in the same file
|
|
||||||
// to be considered valid. The values will be ignored if not a complete group.
|
|
||||||
// aws_session_token is an optional field that can be provided if both of the
|
|
||||||
// other two fields are also provided.
|
|
||||||
//
|
|
||||||
// aws_access_key_id
|
|
||||||
// aws_secret_access_key
|
|
||||||
// aws_session_token
|
|
||||||
Creds credentials.Value
|
|
||||||
|
|
||||||
AssumeRole assumeRoleConfig
|
|
||||||
AssumeRoleSource *sharedConfig
|
|
||||||
|
|
||||||
// Region is the region the SDK should use for looking up AWS service endpoints
|
|
||||||
// and signing requests.
|
|
||||||
//
|
|
||||||
// region
|
|
||||||
Region string
|
|
||||||
|
|
||||||
// EnableEndpointDiscovery can be enabled in the shared config by setting
|
|
||||||
// endpoint_discovery_enabled to true
|
|
||||||
//
|
|
||||||
// endpoint_discovery_enabled = true
|
|
||||||
EnableEndpointDiscovery *bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type sharedConfigFile struct {
|
|
||||||
Filename string
|
|
||||||
IniData ini.Sections
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadSharedConfig retrieves the configuration from the list of files
|
|
||||||
// using the profile provided. The order the files are listed will determine
|
|
||||||
// precedence. Values in subsequent files will overwrite values defined in
|
|
||||||
// earlier files.
|
|
||||||
//
|
|
||||||
// For example, given two files A and B. Both define credentials. If the order
|
|
||||||
// of the files are A then B, B's credential values will be used instead of A's.
|
|
||||||
//
|
|
||||||
// See sharedConfig.setFromFile for information how the config files
|
|
||||||
// will be loaded.
|
|
||||||
func loadSharedConfig(profile string, filenames []string) (sharedConfig, error) {
|
|
||||||
if len(profile) == 0 {
|
|
||||||
profile = DefaultSharedConfigProfile
|
|
||||||
}
|
|
||||||
|
|
||||||
files, err := loadSharedConfigIniFiles(filenames)
|
|
||||||
if err != nil {
|
|
||||||
return sharedConfig{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := sharedConfig{}
|
|
||||||
if err = cfg.setFromIniFiles(profile, files); err != nil {
|
|
||||||
return sharedConfig{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.AssumeRole.SourceProfile) > 0 {
|
|
||||||
if err := cfg.setAssumeRoleSource(profile, files); err != nil {
|
|
||||||
return sharedConfig{}, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cfg, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) {
|
|
||||||
files := make([]sharedConfigFile, 0, len(filenames))
|
|
||||||
|
|
||||||
for _, filename := range filenames {
|
|
||||||
sections, err := ini.OpenFile(filename)
|
|
||||||
if aerr, ok := err.(awserr.Error); ok && aerr.Code() == ini.ErrCodeUnableToReadFile {
|
|
||||||
// Skip files which can't be opened and read for whatever reason
|
|
||||||
continue
|
|
||||||
} else if err != nil {
|
|
||||||
return nil, SharedConfigLoadError{Filename: filename, Err: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
files = append(files, sharedConfigFile{
|
|
||||||
Filename: filename, IniData: sections,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return files, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error {
|
|
||||||
var assumeRoleSrc sharedConfig
|
|
||||||
|
|
||||||
if len(cfg.AssumeRole.CredentialSource) > 0 {
|
|
||||||
// setAssumeRoleSource is only called when source_profile is found.
|
|
||||||
// If both source_profile and credential_source are set, then
|
|
||||||
// ErrSharedConfigSourceCollision will be returned
|
|
||||||
return ErrSharedConfigSourceCollision
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiple level assume role chains are not support
|
|
||||||
if cfg.AssumeRole.SourceProfile == origProfile {
|
|
||||||
assumeRoleSrc = *cfg
|
|
||||||
assumeRoleSrc.AssumeRole = assumeRoleConfig{}
|
|
||||||
} else {
|
|
||||||
err := assumeRoleSrc.setFromIniFiles(cfg.AssumeRole.SourceProfile, files)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(assumeRoleSrc.Creds.AccessKeyID) == 0 {
|
|
||||||
return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.AssumeRoleSource = &assumeRoleSrc
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cfg *sharedConfig) setFromIniFiles(profile string, files []sharedConfigFile) error {
|
|
||||||
// Trim files from the list that don't exist.
|
|
||||||
for _, f := range files {
|
|
||||||
if err := cfg.setFromIniFile(profile, f); err != nil {
|
|
||||||
if _, ok := err.(SharedConfigProfileNotExistsError); ok {
|
|
||||||
// Ignore proviles missings
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// setFromFile loads the configuration from the file using
|
|
||||||
// the profile provided. A sharedConfig pointer type value is used so that
|
|
||||||
// multiple config file loadings can be chained.
|
|
||||||
//
|
|
||||||
// Only loads complete logically grouped values, and will not set fields in cfg
|
|
||||||
// for incomplete grouped values in the config. Such as credentials. For example
|
|
||||||
// if a config file only includes aws_access_key_id but no aws_secret_access_key
|
|
||||||
// the aws_access_key_id will be ignored.
|
|
||||||
func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error {
|
|
||||||
section, ok := file.IniData.GetSection(profile)
|
|
||||||
if !ok {
|
|
||||||
// Fallback to to alternate profile name: profile <name>
|
|
||||||
section, ok = file.IniData.GetSection(fmt.Sprintf("profile %s", profile))
|
|
||||||
if !ok {
|
|
||||||
return SharedConfigProfileNotExistsError{Profile: profile, Err: nil}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shared Credentials
|
|
||||||
akid := section.String(accessKeyIDKey)
|
|
||||||
secret := section.String(secretAccessKey)
|
|
||||||
if len(akid) > 0 && len(secret) > 0 {
|
|
||||||
cfg.Creds = credentials.Value{
|
|
||||||
AccessKeyID: akid,
|
|
||||||
SecretAccessKey: secret,
|
|
||||||
SessionToken: section.String(sessionTokenKey),
|
|
||||||
ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assume Role
|
|
||||||
roleArn := section.String(roleArnKey)
|
|
||||||
srcProfile := section.String(sourceProfileKey)
|
|
||||||
credentialSource := section.String(credentialSourceKey)
|
|
||||||
hasSource := len(srcProfile) > 0 || len(credentialSource) > 0
|
|
||||||
if len(roleArn) > 0 && hasSource {
|
|
||||||
cfg.AssumeRole = assumeRoleConfig{
|
|
||||||
RoleARN: roleArn,
|
|
||||||
SourceProfile: srcProfile,
|
|
||||||
CredentialSource: credentialSource,
|
|
||||||
ExternalID: section.String(externalIDKey),
|
|
||||||
MFASerial: section.String(mfaSerialKey),
|
|
||||||
RoleSessionName: section.String(roleSessionNameKey),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Region
|
|
||||||
if v := section.String(regionKey); len(v) > 0 {
|
|
||||||
cfg.Region = v
|
|
||||||
}
|
|
||||||
|
|
||||||
// Endpoint discovery
|
|
||||||
if section.Has(enableEndpointDiscoveryKey) {
|
|
||||||
v := section.Bool(enableEndpointDiscoveryKey)
|
|
||||||
cfg.EnableEndpointDiscovery = &v
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SharedConfigLoadError is an error for the shared config file failed to load.
|
|
||||||
type SharedConfigLoadError struct {
|
|
||||||
Filename string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code is the short id of the error.
|
|
||||||
func (e SharedConfigLoadError) Code() string {
|
|
||||||
return "SharedConfigLoadError"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message is the description of the error
|
|
||||||
func (e SharedConfigLoadError) Message() string {
|
|
||||||
return fmt.Sprintf("failed to load config file, %s", e.Filename)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErr is the underlying error that caused the failure.
|
|
||||||
func (e SharedConfigLoadError) OrigErr() error {
|
|
||||||
return e.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error satisfies the error interface.
|
|
||||||
func (e SharedConfigLoadError) Error() string {
|
|
||||||
return awserr.SprintError(e.Code(), e.Message(), "", e.Err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SharedConfigProfileNotExistsError is an error for the shared config when
|
|
||||||
// the profile was not find in the config file.
|
|
||||||
type SharedConfigProfileNotExistsError struct {
|
|
||||||
Profile string
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code is the short id of the error.
|
|
||||||
func (e SharedConfigProfileNotExistsError) Code() string {
|
|
||||||
return "SharedConfigProfileNotExistsError"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message is the description of the error
|
|
||||||
func (e SharedConfigProfileNotExistsError) Message() string {
|
|
||||||
return fmt.Sprintf("failed to get profile, %s", e.Profile)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErr is the underlying error that caused the failure.
|
|
||||||
func (e SharedConfigProfileNotExistsError) OrigErr() error {
|
|
||||||
return e.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error satisfies the error interface.
|
|
||||||
func (e SharedConfigProfileNotExistsError) Error() string {
|
|
||||||
return awserr.SprintError(e.Code(), e.Message(), "", e.Err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SharedConfigAssumeRoleError is an error for the shared config when the
|
|
||||||
// profile contains assume role information, but that information is invalid
|
|
||||||
// or not complete.
|
|
||||||
type SharedConfigAssumeRoleError struct {
|
|
||||||
RoleARN string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code is the short id of the error.
|
|
||||||
func (e SharedConfigAssumeRoleError) Code() string {
|
|
||||||
return "SharedConfigAssumeRoleError"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message is the description of the error
|
|
||||||
func (e SharedConfigAssumeRoleError) Message() string {
|
|
||||||
return fmt.Sprintf("failed to load assume role for %s, source profile has no shared credentials",
|
|
||||||
e.RoleARN)
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigErr is the underlying error that caused the failure.
|
|
||||||
func (e SharedConfigAssumeRoleError) OrigErr() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error satisfies the error interface.
|
|
||||||
func (e SharedConfigAssumeRoleError) Error() string {
|
|
||||||
return awserr.SprintError(e.Code(), e.Message(), "", nil)
|
|
||||||
}
|
|
82
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go
generated
vendored
82
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go
generated
vendored
@ -1,82 +0,0 @@
|
|||||||
package v4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// validator houses a set of rule needed for validation of a
|
|
||||||
// string value
|
|
||||||
type rules []rule
|
|
||||||
|
|
||||||
// rule interface allows for more flexible rules and just simply
|
|
||||||
// checks whether or not a value adheres to that rule
|
|
||||||
type rule interface {
|
|
||||||
IsValid(value string) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsValid will iterate through all rules and see if any rules
|
|
||||||
// apply to the value and supports nested rules
|
|
||||||
func (r rules) IsValid(value string) bool {
|
|
||||||
for _, rule := range r {
|
|
||||||
if rule.IsValid(value) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// mapRule generic rule for maps
|
|
||||||
type mapRule map[string]struct{}
|
|
||||||
|
|
||||||
// IsValid for the map rule satisfies whether it exists in the map
|
|
||||||
func (m mapRule) IsValid(value string) bool {
|
|
||||||
_, ok := m[value]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// whitelist is a generic rule for whitelisting
|
|
||||||
type whitelist struct {
|
|
||||||
rule
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsValid for whitelist checks if the value is within the whitelist
|
|
||||||
func (w whitelist) IsValid(value string) bool {
|
|
||||||
return w.rule.IsValid(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// blacklist is a generic rule for blacklisting
|
|
||||||
type blacklist struct {
|
|
||||||
rule
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsValid for whitelist checks if the value is within the whitelist
|
|
||||||
func (b blacklist) IsValid(value string) bool {
|
|
||||||
return !b.rule.IsValid(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
type patterns []string
|
|
||||||
|
|
||||||
// IsValid for patterns checks each pattern and returns if a match has
|
|
||||||
// been found
|
|
||||||
func (p patterns) IsValid(value string) bool {
|
|
||||||
for _, pattern := range p {
|
|
||||||
if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// inclusiveRules rules allow for rules to depend on one another
|
|
||||||
type inclusiveRules []rule
|
|
||||||
|
|
||||||
// IsValid will return true if all rules are true
|
|
||||||
func (r inclusiveRules) IsValid(value string) bool {
|
|
||||||
for _, rule := range r {
|
|
||||||
if !rule.IsValid(value) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
7
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go
generated
vendored
7
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go
generated
vendored
@ -1,7 +0,0 @@
|
|||||||
package v4
|
|
||||||
|
|
||||||
// WithUnsignedPayload will enable and set the UnsignedPayload field to
|
|
||||||
// true of the signer.
|
|
||||||
func WithUnsignedPayload(v4 *Signer) {
|
|
||||||
v4.UnsignedPayload = true
|
|
||||||
}
|
|
24
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go
generated
vendored
24
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
// +build go1.5
|
|
||||||
|
|
||||||
package v4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getURIPath(u *url.URL) string {
|
|
||||||
var uri string
|
|
||||||
|
|
||||||
if len(u.Opaque) > 0 {
|
|
||||||
uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/")
|
|
||||||
} else {
|
|
||||||
uri = u.EscapedPath()
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(uri) == 0 {
|
|
||||||
uri = "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
return uri
|
|
||||||
}
|
|
797
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
generated
vendored
797
vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go
generated
vendored
@ -1,797 +0,0 @@
|
|||||||
// Package v4 implements signing for AWS V4 signer
|
|
||||||
//
|
|
||||||
// Provides request signing for request that need to be signed with
|
|
||||||
// AWS V4 Signatures.
|
|
||||||
//
|
|
||||||
// Standalone Signer
|
|
||||||
//
|
|
||||||
// Generally using the signer outside of the SDK should not require any additional
|
|
||||||
// logic when using Go v1.5 or higher. The signer does this by taking advantage
|
|
||||||
// of the URL.EscapedPath method. If your request URI requires additional escaping
|
|
||||||
// you many need to use the URL.Opaque to define what the raw URI should be sent
|
|
||||||
// to the service as.
|
|
||||||
//
|
|
||||||
// The signer will first check the URL.Opaque field, and use its value if set.
|
|
||||||
// The signer does require the URL.Opaque field to be set in the form of:
|
|
||||||
//
|
|
||||||
// "//<hostname>/<path>"
|
|
||||||
//
|
|
||||||
// // e.g.
|
|
||||||
// "//example.com/some/path"
|
|
||||||
//
|
|
||||||
// The leading "//" and hostname are required or the URL.Opaque escaping will
|
|
||||||
// not work correctly.
|
|
||||||
//
|
|
||||||
// If URL.Opaque is not set the signer will fallback to the URL.EscapedPath()
|
|
||||||
// method and using the returned value. If you're using Go v1.4 you must set
|
|
||||||
// URL.Opaque if the URI path needs escaping. If URL.Opaque is not set with
|
|
||||||
// Go v1.5 the signer will fallback to URL.Path.
|
|
||||||
//
|
|
||||||
// AWS v4 signature validation requires that the canonical string's URI path
|
|
||||||
// element must be the URI escaped form of the HTTP request's path.
|
|
||||||
// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
|
|
||||||
//
|
|
||||||
// The Go HTTP client will perform escaping automatically on the request. Some
|
|
||||||
// of these escaping may cause signature validation errors because the HTTP
|
|
||||||
// request differs from the URI path or query that the signature was generated.
|
|
||||||
// https://golang.org/pkg/net/url/#URL.EscapedPath
|
|
||||||
//
|
|
||||||
// Because of this, it is recommended that when using the signer outside of the
|
|
||||||
// SDK that explicitly escaping the request prior to being signed is preferable,
|
|
||||||
// and will help prevent signature validation errors. This can be done by setting
|
|
||||||
// the URL.Opaque or URL.RawPath. The SDK will use URL.Opaque first and then
|
|
||||||
// call URL.EscapedPath() if Opaque is not set.
|
|
||||||
//
|
|
||||||
// If signing a request intended for HTTP2 server, and you're using Go 1.6.2
|
|
||||||
// through 1.7.4 you should use the URL.RawPath as the pre-escaped form of the
|
|
||||||
// request URL. https://github.com/golang/go/issues/16847 points to a bug in
|
|
||||||
// Go pre 1.8 that fails to make HTTP2 requests using absolute URL in the HTTP
|
|
||||||
// message. URL.Opaque generally will force Go to make requests with absolute URL.
|
|
||||||
// URL.RawPath does not do this, but RawPath must be a valid escaping of Path
|
|
||||||
// or url.EscapedPath will ignore the RawPath escaping.
|
|
||||||
//
|
|
||||||
// Test `TestStandaloneSign` provides a complete example of using the signer
|
|
||||||
// outside of the SDK and pre-escaping the URI path.
|
|
||||||
package v4
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/hmac"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"sort"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
|
||||||
"github.com/aws/aws-sdk-go/aws/request"
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkio"
|
|
||||||
"github.com/aws/aws-sdk-go/private/protocol/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
authHeaderPrefix = "AWS4-HMAC-SHA256"
|
|
||||||
timeFormat = "20060102T150405Z"
|
|
||||||
shortTimeFormat = "20060102"
|
|
||||||
|
|
||||||
// emptyStringSHA256 is a SHA256 of an empty string
|
|
||||||
emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`
|
|
||||||
)
|
|
||||||
|
|
||||||
var ignoredHeaders = rules{
|
|
||||||
blacklist{
|
|
||||||
mapRule{
|
|
||||||
"Authorization": struct{}{},
|
|
||||||
"User-Agent": struct{}{},
|
|
||||||
"X-Amzn-Trace-Id": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// requiredSignedHeaders is a whitelist for build canonical headers.
|
|
||||||
var requiredSignedHeaders = rules{
|
|
||||||
whitelist{
|
|
||||||
mapRule{
|
|
||||||
"Cache-Control": struct{}{},
|
|
||||||
"Content-Disposition": struct{}{},
|
|
||||||
"Content-Encoding": struct{}{},
|
|
||||||
"Content-Language": struct{}{},
|
|
||||||
"Content-Md5": struct{}{},
|
|
||||||
"Content-Type": struct{}{},
|
|
||||||
"Expires": struct{}{},
|
|
||||||
"If-Match": struct{}{},
|
|
||||||
"If-Modified-Since": struct{}{},
|
|
||||||
"If-None-Match": struct{}{},
|
|
||||||
"If-Unmodified-Since": struct{}{},
|
|
||||||
"Range": struct{}{},
|
|
||||||
"X-Amz-Acl": struct{}{},
|
|
||||||
"X-Amz-Copy-Source": struct{}{},
|
|
||||||
"X-Amz-Copy-Source-If-Match": struct{}{},
|
|
||||||
"X-Amz-Copy-Source-If-Modified-Since": struct{}{},
|
|
||||||
"X-Amz-Copy-Source-If-None-Match": struct{}{},
|
|
||||||
"X-Amz-Copy-Source-If-Unmodified-Since": struct{}{},
|
|
||||||
"X-Amz-Copy-Source-Range": struct{}{},
|
|
||||||
"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
|
||||||
"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{},
|
|
||||||
"X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
|
||||||
"X-Amz-Grant-Full-control": struct{}{},
|
|
||||||
"X-Amz-Grant-Read": struct{}{},
|
|
||||||
"X-Amz-Grant-Read-Acp": struct{}{},
|
|
||||||
"X-Amz-Grant-Write": struct{}{},
|
|
||||||
"X-Amz-Grant-Write-Acp": struct{}{},
|
|
||||||
"X-Amz-Metadata-Directive": struct{}{},
|
|
||||||
"X-Amz-Mfa": struct{}{},
|
|
||||||
"X-Amz-Request-Payer": struct{}{},
|
|
||||||
"X-Amz-Server-Side-Encryption": struct{}{},
|
|
||||||
"X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{},
|
|
||||||
"X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
|
||||||
"X-Amz-Server-Side-Encryption-Customer-Key": struct{}{},
|
|
||||||
"X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
|
||||||
"X-Amz-Storage-Class": struct{}{},
|
|
||||||
"X-Amz-Tagging": struct{}{},
|
|
||||||
"X-Amz-Website-Redirect-Location": struct{}{},
|
|
||||||
"X-Amz-Content-Sha256": struct{}{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
patterns{"X-Amz-Meta-"},
|
|
||||||
}
|
|
||||||
|
|
||||||
// allowedHoisting is a whitelist for build query headers. The boolean value
|
|
||||||
// represents whether or not it is a pattern.
|
|
||||||
var allowedQueryHoisting = inclusiveRules{
|
|
||||||
blacklist{requiredSignedHeaders},
|
|
||||||
patterns{"X-Amz-"},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signer applies AWS v4 signing to given request. Use this to sign requests
|
|
||||||
// that need to be signed with AWS V4 Signatures.
|
|
||||||
type Signer struct {
|
|
||||||
// The authentication credentials the request will be signed against.
|
|
||||||
// This value must be set to sign requests.
|
|
||||||
Credentials *credentials.Credentials
|
|
||||||
|
|
||||||
// Sets the log level the signer should use when reporting information to
|
|
||||||
// the logger. If the logger is nil nothing will be logged. See
|
|
||||||
// aws.LogLevelType for more information on available logging levels
|
|
||||||
//
|
|
||||||
// By default nothing will be logged.
|
|
||||||
Debug aws.LogLevelType
|
|
||||||
|
|
||||||
// The logger loging information will be written to. If there the logger
|
|
||||||
// is nil, nothing will be logged.
|
|
||||||
Logger aws.Logger
|
|
||||||
|
|
||||||
// Disables the Signer's moving HTTP header key/value pairs from the HTTP
|
|
||||||
// request header to the request's query string. This is most commonly used
|
|
||||||
// with pre-signed requests preventing headers from being added to the
|
|
||||||
// request's query string.
|
|
||||||
DisableHeaderHoisting bool
|
|
||||||
|
|
||||||
// Disables the automatic escaping of the URI path of the request for the
|
|
||||||
// siganture's canonical string's path. For services that do not need additional
|
|
||||||
// escaping then use this to disable the signer escaping the path.
|
|
||||||
//
|
|
||||||
// S3 is an example of a service that does not need additional escaping.
|
|
||||||
//
|
|
||||||
// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
|
|
||||||
DisableURIPathEscaping bool
|
|
||||||
|
|
||||||
// Disales the automatical setting of the HTTP request's Body field with the
|
|
||||||
// io.ReadSeeker passed in to the signer. This is useful if you're using a
|
|
||||||
// custom wrapper around the body for the io.ReadSeeker and want to preserve
|
|
||||||
// the Body value on the Request.Body.
|
|
||||||
//
|
|
||||||
// This does run the risk of signing a request with a body that will not be
|
|
||||||
// sent in the request. Need to ensure that the underlying data of the Body
|
|
||||||
// values are the same.
|
|
||||||
DisableRequestBodyOverwrite bool
|
|
||||||
|
|
||||||
// currentTimeFn returns the time value which represents the current time.
|
|
||||||
// This value should only be used for testing. If it is nil the default
|
|
||||||
// time.Now will be used.
|
|
||||||
currentTimeFn func() time.Time
|
|
||||||
|
|
||||||
// UnsignedPayload will prevent signing of the payload. This will only
|
|
||||||
// work for services that have support for this.
|
|
||||||
UnsignedPayload bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSigner returns a Signer pointer configured with the credentials and optional
|
|
||||||
// option values provided. If not options are provided the Signer will use its
|
|
||||||
// default configuration.
|
|
||||||
func NewSigner(credentials *credentials.Credentials, options ...func(*Signer)) *Signer {
|
|
||||||
v4 := &Signer{
|
|
||||||
Credentials: credentials,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, option := range options {
|
|
||||||
option(v4)
|
|
||||||
}
|
|
||||||
|
|
||||||
return v4
|
|
||||||
}
|
|
||||||
|
|
||||||
type signingCtx struct {
|
|
||||||
ServiceName string
|
|
||||||
Region string
|
|
||||||
Request *http.Request
|
|
||||||
Body io.ReadSeeker
|
|
||||||
Query url.Values
|
|
||||||
Time time.Time
|
|
||||||
ExpireTime time.Duration
|
|
||||||
SignedHeaderVals http.Header
|
|
||||||
|
|
||||||
DisableURIPathEscaping bool
|
|
||||||
|
|
||||||
credValues credentials.Value
|
|
||||||
isPresign bool
|
|
||||||
formattedTime string
|
|
||||||
formattedShortTime string
|
|
||||||
unsignedPayload bool
|
|
||||||
|
|
||||||
bodyDigest string
|
|
||||||
signedHeaders string
|
|
||||||
canonicalHeaders string
|
|
||||||
canonicalString string
|
|
||||||
credentialString string
|
|
||||||
stringToSign string
|
|
||||||
signature string
|
|
||||||
authorization string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign signs AWS v4 requests with the provided body, service name, region the
|
|
||||||
// request is made to, and time the request is signed at. The signTime allows
|
|
||||||
// you to specify that a request is signed for the future, and cannot be
|
|
||||||
// used until then.
|
|
||||||
//
|
|
||||||
// Returns a list of HTTP headers that were included in the signature or an
|
|
||||||
// error if signing the request failed. Generally for signed requests this value
|
|
||||||
// is not needed as the full request context will be captured by the http.Request
|
|
||||||
// value. It is included for reference though.
|
|
||||||
//
|
|
||||||
// Sign will set the request's Body to be the `body` parameter passed in. If
|
|
||||||
// the body is not already an io.ReadCloser, it will be wrapped within one. If
|
|
||||||
// a `nil` body parameter passed to Sign, the request's Body field will be
|
|
||||||
// also set to nil. Its important to note that this functionality will not
|
|
||||||
// change the request's ContentLength of the request.
|
|
||||||
//
|
|
||||||
// Sign differs from Presign in that it will sign the request using HTTP
|
|
||||||
// header values. This type of signing is intended for http.Request values that
|
|
||||||
// will not be shared, or are shared in a way the header values on the request
|
|
||||||
// will not be lost.
|
|
||||||
//
|
|
||||||
// The requests body is an io.ReadSeeker so the SHA256 of the body can be
|
|
||||||
// generated. To bypass the signer computing the hash you can set the
|
|
||||||
// "X-Amz-Content-Sha256" header with a precomputed value. The signer will
|
|
||||||
// only compute the hash if the request header value is empty.
|
|
||||||
func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) {
|
|
||||||
return v4.signWithBody(r, body, service, region, 0, false, signTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Presign signs AWS v4 requests with the provided body, service name, region
|
|
||||||
// the request is made to, and time the request is signed at. The signTime
|
|
||||||
// allows you to specify that a request is signed for the future, and cannot
|
|
||||||
// be used until then.
|
|
||||||
//
|
|
||||||
// Returns a list of HTTP headers that were included in the signature or an
|
|
||||||
// error if signing the request failed. For presigned requests these headers
|
|
||||||
// and their values must be included on the HTTP request when it is made. This
|
|
||||||
// is helpful to know what header values need to be shared with the party the
|
|
||||||
// presigned request will be distributed to.
|
|
||||||
//
|
|
||||||
// Presign differs from Sign in that it will sign the request using query string
|
|
||||||
// instead of header values. This allows you to share the Presigned Request's
|
|
||||||
// URL with third parties, or distribute it throughout your system with minimal
|
|
||||||
// dependencies.
|
|
||||||
//
|
|
||||||
// Presign also takes an exp value which is the duration the
|
|
||||||
// signed request will be valid after the signing time. This is allows you to
|
|
||||||
// set when the request will expire.
|
|
||||||
//
|
|
||||||
// The requests body is an io.ReadSeeker so the SHA256 of the body can be
|
|
||||||
// generated. To bypass the signer computing the hash you can set the
|
|
||||||
// "X-Amz-Content-Sha256" header with a precomputed value. The signer will
|
|
||||||
// only compute the hash if the request header value is empty.
|
|
||||||
//
|
|
||||||
// Presigning a S3 request will not compute the body's SHA256 hash by default.
|
|
||||||
// This is done due to the general use case for S3 presigned URLs is to share
|
|
||||||
// PUT/GET capabilities. If you would like to include the body's SHA256 in the
|
|
||||||
// presigned request's signature you can set the "X-Amz-Content-Sha256"
|
|
||||||
// HTTP header and that will be included in the request's signature.
|
|
||||||
func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
|
|
||||||
return v4.signWithBody(r, body, service, region, exp, true, signTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, isPresign bool, signTime time.Time) (http.Header, error) {
|
|
||||||
currentTimeFn := v4.currentTimeFn
|
|
||||||
if currentTimeFn == nil {
|
|
||||||
currentTimeFn = time.Now
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := &signingCtx{
|
|
||||||
Request: r,
|
|
||||||
Body: body,
|
|
||||||
Query: r.URL.Query(),
|
|
||||||
Time: signTime,
|
|
||||||
ExpireTime: exp,
|
|
||||||
isPresign: isPresign,
|
|
||||||
ServiceName: service,
|
|
||||||
Region: region,
|
|
||||||
DisableURIPathEscaping: v4.DisableURIPathEscaping,
|
|
||||||
unsignedPayload: v4.UnsignedPayload,
|
|
||||||
}
|
|
||||||
|
|
||||||
for key := range ctx.Query {
|
|
||||||
sort.Strings(ctx.Query[key])
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.isRequestSigned() {
|
|
||||||
ctx.Time = currentTimeFn()
|
|
||||||
ctx.handlePresignRemoval()
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
ctx.credValues, err = v4.Credentials.Get()
|
|
||||||
if err != nil {
|
|
||||||
return http.Header{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.sanitizeHostForHeader()
|
|
||||||
ctx.assignAmzQueryValues()
|
|
||||||
if err := ctx.build(v4.DisableHeaderHoisting); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the request is not presigned the body should be attached to it. This
|
|
||||||
// prevents the confusion of wanting to send a signed request without
|
|
||||||
// the body the request was signed for attached.
|
|
||||||
if !(v4.DisableRequestBodyOverwrite || ctx.isPresign) {
|
|
||||||
var reader io.ReadCloser
|
|
||||||
if body != nil {
|
|
||||||
var ok bool
|
|
||||||
if reader, ok = body.(io.ReadCloser); !ok {
|
|
||||||
reader = ioutil.NopCloser(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r.Body = reader
|
|
||||||
}
|
|
||||||
|
|
||||||
if v4.Debug.Matches(aws.LogDebugWithSigning) {
|
|
||||||
v4.logSigningInfo(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx.SignedHeaderVals, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *signingCtx) sanitizeHostForHeader() {
|
|
||||||
request.SanitizeHostForHeader(ctx.Request)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *signingCtx) handlePresignRemoval() {
|
|
||||||
if !ctx.isPresign {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// The credentials have expired for this request. The current signing
|
|
||||||
// is invalid, and needs to be request because the request will fail.
|
|
||||||
ctx.removePresign()
|
|
||||||
|
|
||||||
// Update the request's query string to ensure the values stays in
|
|
||||||
// sync in the case retrieving the new credentials fails.
|
|
||||||
ctx.Request.URL.RawQuery = ctx.Query.Encode()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *signingCtx) assignAmzQueryValues() {
|
|
||||||
if ctx.isPresign {
|
|
||||||
ctx.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
|
|
||||||
if ctx.credValues.SessionToken != "" {
|
|
||||||
ctx.Query.Set("X-Amz-Security-Token", ctx.credValues.SessionToken)
|
|
||||||
} else {
|
|
||||||
ctx.Query.Del("X-Amz-Security-Token")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctx.credValues.SessionToken != "" {
|
|
||||||
ctx.Request.Header.Set("X-Amz-Security-Token", ctx.credValues.SessionToken)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SignRequestHandler is a named request handler the SDK will use to sign
|
|
||||||
// service client request with using the V4 signature.
|
|
||||||
var SignRequestHandler = request.NamedHandler{
|
|
||||||
Name: "v4.SignRequestHandler", Fn: SignSDKRequest,
|
|
||||||
}
|
|
||||||
|
|
||||||
// SignSDKRequest signs an AWS request with the V4 signature. This
|
|
||||||
// request handler should only be used with the SDK's built in service client's
|
|
||||||
// API operation requests.
|
|
||||||
//
|
|
||||||
// This function should not be used on its on its own, but in conjunction with
|
|
||||||
// an AWS service client's API operation call. To sign a standalone request
|
|
||||||
// not created by a service client's API operation method use the "Sign" or
|
|
||||||
// "Presign" functions of the "Signer" type.
|
|
||||||
//
|
|
||||||
// If the credentials of the request's config are set to
|
|
||||||
// credentials.AnonymousCredentials the request will not be signed.
|
|
||||||
func SignSDKRequest(req *request.Request) {
|
|
||||||
signSDKRequestWithCurrTime(req, time.Now)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BuildNamedHandler will build a generic handler for signing.
|
|
||||||
func BuildNamedHandler(name string, opts ...func(*Signer)) request.NamedHandler {
|
|
||||||
return request.NamedHandler{
|
|
||||||
Name: name,
|
|
||||||
Fn: func(req *request.Request) {
|
|
||||||
signSDKRequestWithCurrTime(req, time.Now, opts...)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time, opts ...func(*Signer)) {
|
|
||||||
// If the request does not need to be signed ignore the signing of the
|
|
||||||
// request if the AnonymousCredentials object is used.
|
|
||||||
if req.Config.Credentials == credentials.AnonymousCredentials {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
region := req.ClientInfo.SigningRegion
|
|
||||||
if region == "" {
|
|
||||||
region = aws.StringValue(req.Config.Region)
|
|
||||||
}
|
|
||||||
|
|
||||||
name := req.ClientInfo.SigningName
|
|
||||||
if name == "" {
|
|
||||||
name = req.ClientInfo.ServiceName
|
|
||||||
}
|
|
||||||
|
|
||||||
v4 := NewSigner(req.Config.Credentials, func(v4 *Signer) {
|
|
||||||
v4.Debug = req.Config.LogLevel.Value()
|
|
||||||
v4.Logger = req.Config.Logger
|
|
||||||
v4.DisableHeaderHoisting = req.NotHoist
|
|
||||||
v4.currentTimeFn = curTimeFn
|
|
||||||
if name == "s3" {
|
|
||||||
// S3 service should not have any escaping applied
|
|
||||||
v4.DisableURIPathEscaping = true
|
|
||||||
}
|
|
||||||
// Prevents setting the HTTPRequest's Body. Since the Body could be
|
|
||||||
// wrapped in a custom io.Closer that we do not want to be stompped
|
|
||||||
// on top of by the signer.
|
|
||||||
v4.DisableRequestBodyOverwrite = true
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, opt := range opts {
|
|
||||||
opt(v4)
|
|
||||||
}
|
|
||||||
|
|
||||||
signingTime := req.Time
|
|
||||||
if !req.LastSignedAt.IsZero() {
|
|
||||||
signingTime = req.LastSignedAt
|
|
||||||
}
|
|
||||||
|
|
||||||
signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(),
|
|
||||||
name, region, req.ExpireTime, req.ExpireTime > 0, signingTime,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
req.Error = err
|
|
||||||
req.SignedHeaderVals = nil
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
req.SignedHeaderVals = signedHeaders
|
|
||||||
req.LastSignedAt = curTimeFn()
|
|
||||||
}
|
|
||||||
|
|
||||||
const logSignInfoMsg = `DEBUG: Request Signature:
|
|
||||||
---[ CANONICAL STRING ]-----------------------------
|
|
||||||
%s
|
|
||||||
---[ STRING TO SIGN ]--------------------------------
|
|
||||||
%s%s
|
|
||||||
-----------------------------------------------------`
|
|
||||||
const logSignedURLMsg = `
|
|
||||||
---[ SIGNED URL ]------------------------------------
|
|
||||||
%s`
|
|
||||||
|
|
||||||
func (v4 *Signer) logSigningInfo(ctx *signingCtx) {
|
|
||||||
signedURLMsg := ""
|
|
||||||
if ctx.isPresign {
|
|
||||||
signedURLMsg = fmt.Sprintf(logSignedURLMsg, ctx.Request.URL.String())
|
|
||||||
}
|
|
||||||
msg := fmt.Sprintf(logSignInfoMsg, ctx.canonicalString, ctx.stringToSign, signedURLMsg)
|
|
||||||
v4.Logger.Log(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *signingCtx) build(disableHeaderHoisting bool) error {
|
|
||||||
ctx.buildTime() // no depends
|
|
||||||
ctx.buildCredentialString() // no depends
|
|
||||||
|
|
||||||
if err := ctx.buildBodyDigest(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
unsignedHeaders := ctx.Request.Header
|
|
||||||
if ctx.isPresign {
|
|
||||||
if !disableHeaderHoisting {
|
|
||||||
urlValues := url.Values{}
|
|
||||||
urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends
|
|
||||||
for k := range urlValues {
|
|
||||||
ctx.Query[k] = urlValues[k]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders)
|
|
||||||
ctx.buildCanonicalString() // depends on canon headers / signed headers
|
|
||||||
ctx.buildStringToSign() // depends on canon string
|
|
||||||
ctx.buildSignature() // depends on string to sign
|
|
||||||
|
|
||||||
if ctx.isPresign {
|
|
||||||
ctx.Request.URL.RawQuery += "&X-Amz-Signature=" + ctx.signature
|
|
||||||
} else {
|
|
||||||
parts := []string{
|
|
||||||
authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString,
|
|
||||||
"SignedHeaders=" + ctx.signedHeaders,
|
|
||||||
"Signature=" + ctx.signature,
|
|
||||||
}
|
|
||||||
ctx.Request.Header.Set("Authorization", strings.Join(parts, ", "))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *signingCtx) buildTime() {
|
|
||||||
ctx.formattedTime = ctx.Time.UTC().Format(timeFormat)
|
|
||||||
ctx.formattedShortTime = ctx.Time.UTC().Format(shortTimeFormat)
|
|
||||||
|
|
||||||
if ctx.isPresign {
|
|
||||||
duration := int64(ctx.ExpireTime / time.Second)
|
|
||||||
ctx.Query.Set("X-Amz-Date", ctx.formattedTime)
|
|
||||||
ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
|
|
||||||
} else {
|
|
||||||
ctx.Request.Header.Set("X-Amz-Date", ctx.formattedTime)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *signingCtx) buildCredentialString() {
|
|
||||||
ctx.credentialString = strings.Join([]string{
|
|
||||||
ctx.formattedShortTime,
|
|
||||||
ctx.Region,
|
|
||||||
ctx.ServiceName,
|
|
||||||
"aws4_request",
|
|
||||||
}, "/")
|
|
||||||
|
|
||||||
if ctx.isPresign {
|
|
||||||
ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func buildQuery(r rule, header http.Header) (url.Values, http.Header) {
|
|
||||||
query := url.Values{}
|
|
||||||
unsignedHeaders := http.Header{}
|
|
||||||
for k, h := range header {
|
|
||||||
if r.IsValid(k) {
|
|
||||||
query[k] = h
|
|
||||||
} else {
|
|
||||||
unsignedHeaders[k] = h
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return query, unsignedHeaders
|
|
||||||
}
|
|
||||||
func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) {
|
|
||||||
var headers []string
|
|
||||||
headers = append(headers, "host")
|
|
||||||
for k, v := range header {
|
|
||||||
canonicalKey := http.CanonicalHeaderKey(k)
|
|
||||||
if !r.IsValid(canonicalKey) {
|
|
||||||
continue // ignored header
|
|
||||||
}
|
|
||||||
if ctx.SignedHeaderVals == nil {
|
|
||||||
ctx.SignedHeaderVals = make(http.Header)
|
|
||||||
}
|
|
||||||
|
|
||||||
lowerCaseKey := strings.ToLower(k)
|
|
||||||
if _, ok := ctx.SignedHeaderVals[lowerCaseKey]; ok {
|
|
||||||
// include additional values
|
|
||||||
ctx.SignedHeaderVals[lowerCaseKey] = append(ctx.SignedHeaderVals[lowerCaseKey], v...)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
headers = append(headers, lowerCaseKey)
|
|
||||||
ctx.SignedHeaderVals[lowerCaseKey] = v
|
|
||||||
}
|
|
||||||
sort.Strings(headers)
|
|
||||||
|
|
||||||
ctx.signedHeaders = strings.Join(headers, ";")
|
|
||||||
|
|
||||||
if ctx.isPresign {
|
|
||||||
ctx.Query.Set("X-Amz-SignedHeaders", ctx.signedHeaders)
|
|
||||||
}
|
|
||||||
|
|
||||||
headerValues := make([]string, len(headers))
|
|
||||||
for i, k := range headers {
|
|
||||||
if k == "host" {
|
|
||||||
if ctx.Request.Host != "" {
|
|
||||||
headerValues[i] = "host:" + ctx.Request.Host
|
|
||||||
} else {
|
|
||||||
headerValues[i] = "host:" + ctx.Request.URL.Host
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
headerValues[i] = k + ":" +
|
|
||||||
strings.Join(ctx.SignedHeaderVals[k], ",")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stripExcessSpaces(headerValues)
|
|
||||||
ctx.canonicalHeaders = strings.Join(headerValues, "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *signingCtx) buildCanonicalString() {
|
|
||||||
ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1)
|
|
||||||
|
|
||||||
uri := getURIPath(ctx.Request.URL)
|
|
||||||
|
|
||||||
if !ctx.DisableURIPathEscaping {
|
|
||||||
uri = rest.EscapePath(uri, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.canonicalString = strings.Join([]string{
|
|
||||||
ctx.Request.Method,
|
|
||||||
uri,
|
|
||||||
ctx.Request.URL.RawQuery,
|
|
||||||
ctx.canonicalHeaders + "\n",
|
|
||||||
ctx.signedHeaders,
|
|
||||||
ctx.bodyDigest,
|
|
||||||
}, "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *signingCtx) buildStringToSign() {
|
|
||||||
ctx.stringToSign = strings.Join([]string{
|
|
||||||
authHeaderPrefix,
|
|
||||||
ctx.formattedTime,
|
|
||||||
ctx.credentialString,
|
|
||||||
hex.EncodeToString(makeSha256([]byte(ctx.canonicalString))),
|
|
||||||
}, "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *signingCtx) buildSignature() {
|
|
||||||
secret := ctx.credValues.SecretAccessKey
|
|
||||||
date := makeHmac([]byte("AWS4"+secret), []byte(ctx.formattedShortTime))
|
|
||||||
region := makeHmac(date, []byte(ctx.Region))
|
|
||||||
service := makeHmac(region, []byte(ctx.ServiceName))
|
|
||||||
credentials := makeHmac(service, []byte("aws4_request"))
|
|
||||||
signature := makeHmac(credentials, []byte(ctx.stringToSign))
|
|
||||||
ctx.signature = hex.EncodeToString(signature)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctx *signingCtx) buildBodyDigest() error {
|
|
||||||
hash := ctx.Request.Header.Get("X-Amz-Content-Sha256")
|
|
||||||
if hash == "" {
|
|
||||||
includeSHA256Header := ctx.unsignedPayload ||
|
|
||||||
ctx.ServiceName == "s3" ||
|
|
||||||
ctx.ServiceName == "glacier"
|
|
||||||
|
|
||||||
s3Presign := ctx.isPresign && ctx.ServiceName == "s3"
|
|
||||||
|
|
||||||
if ctx.unsignedPayload || s3Presign {
|
|
||||||
hash = "UNSIGNED-PAYLOAD"
|
|
||||||
includeSHA256Header = !s3Presign
|
|
||||||
} else if ctx.Body == nil {
|
|
||||||
hash = emptyStringSHA256
|
|
||||||
} else {
|
|
||||||
if !aws.IsReaderSeekable(ctx.Body) {
|
|
||||||
return fmt.Errorf("cannot use unseekable request body %T, for signed request with body", ctx.Body)
|
|
||||||
}
|
|
||||||
hash = hex.EncodeToString(makeSha256Reader(ctx.Body))
|
|
||||||
}
|
|
||||||
|
|
||||||
if includeSHA256Header {
|
|
||||||
ctx.Request.Header.Set("X-Amz-Content-Sha256", hash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.bodyDigest = hash
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// isRequestSigned returns if the request is currently signed or presigned
|
|
||||||
func (ctx *signingCtx) isRequestSigned() bool {
|
|
||||||
if ctx.isPresign && ctx.Query.Get("X-Amz-Signature") != "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if ctx.Request.Header.Get("Authorization") != "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// unsign removes signing flags for both signed and presigned requests.
|
|
||||||
func (ctx *signingCtx) removePresign() {
|
|
||||||
ctx.Query.Del("X-Amz-Algorithm")
|
|
||||||
ctx.Query.Del("X-Amz-Signature")
|
|
||||||
ctx.Query.Del("X-Amz-Security-Token")
|
|
||||||
ctx.Query.Del("X-Amz-Date")
|
|
||||||
ctx.Query.Del("X-Amz-Expires")
|
|
||||||
ctx.Query.Del("X-Amz-Credential")
|
|
||||||
ctx.Query.Del("X-Amz-SignedHeaders")
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeHmac(key []byte, data []byte) []byte {
|
|
||||||
hash := hmac.New(sha256.New, key)
|
|
||||||
hash.Write(data)
|
|
||||||
return hash.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeSha256(data []byte) []byte {
|
|
||||||
hash := sha256.New()
|
|
||||||
hash.Write(data)
|
|
||||||
return hash.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeSha256Reader(reader io.ReadSeeker) []byte {
|
|
||||||
hash := sha256.New()
|
|
||||||
start, _ := reader.Seek(0, sdkio.SeekCurrent)
|
|
||||||
defer reader.Seek(start, sdkio.SeekStart)
|
|
||||||
|
|
||||||
// Use CopyN to avoid allocating the 32KB buffer in io.Copy for bodies
|
|
||||||
// smaller than 32KB. Fall back to io.Copy if we fail to determine the size.
|
|
||||||
size, err := aws.SeekerLen(reader)
|
|
||||||
if err != nil {
|
|
||||||
io.Copy(hash, reader)
|
|
||||||
} else {
|
|
||||||
io.CopyN(hash, reader, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash.Sum(nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
const doubleSpace = " "
|
|
||||||
|
|
||||||
// stripExcessSpaces will rewrite the passed in slice's string values to not
|
|
||||||
// contain muliple side-by-side spaces.
|
|
||||||
func stripExcessSpaces(vals []string) {
|
|
||||||
var j, k, l, m, spaces int
|
|
||||||
for i, str := range vals {
|
|
||||||
// Trim trailing spaces
|
|
||||||
for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trim leading spaces
|
|
||||||
for k = 0; k < j && str[k] == ' '; k++ {
|
|
||||||
}
|
|
||||||
str = str[k : j+1]
|
|
||||||
|
|
||||||
// Strip multiple spaces.
|
|
||||||
j = strings.Index(str, doubleSpace)
|
|
||||||
if j < 0 {
|
|
||||||
vals[i] = str
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := []byte(str)
|
|
||||||
for k, m, l = j, j, len(buf); k < l; k++ {
|
|
||||||
if buf[k] == ' ' {
|
|
||||||
if spaces == 0 {
|
|
||||||
// First space.
|
|
||||||
buf[m] = buf[k]
|
|
||||||
m++
|
|
||||||
}
|
|
||||||
spaces++
|
|
||||||
} else {
|
|
||||||
// End of multiple spaces.
|
|
||||||
spaces = 0
|
|
||||||
buf[m] = buf[k]
|
|
||||||
m++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vals[i] = string(buf[:m])
|
|
||||||
}
|
|
||||||
}
|
|
201
vendor/github.com/aws/aws-sdk-go/aws/types.go
generated
vendored
201
vendor/github.com/aws/aws-sdk-go/aws/types.go
generated
vendored
@ -1,201 +0,0 @@
|
|||||||
package aws
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/internal/sdkio"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ReadSeekCloser wraps a io.Reader returning a ReaderSeekerCloser. Should
|
|
||||||
// only be used with an io.Reader that is also an io.Seeker. Doing so may
|
|
||||||
// cause request signature errors, or request body's not sent for GET, HEAD
|
|
||||||
// and DELETE HTTP methods.
|
|
||||||
//
|
|
||||||
// Deprecated: Should only be used with io.ReadSeeker. If using for
|
|
||||||
// S3 PutObject to stream content use s3manager.Uploader instead.
|
|
||||||
func ReadSeekCloser(r io.Reader) ReaderSeekerCloser {
|
|
||||||
return ReaderSeekerCloser{r}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReaderSeekerCloser represents a reader that can also delegate io.Seeker and
|
|
||||||
// io.Closer interfaces to the underlying object if they are available.
|
|
||||||
type ReaderSeekerCloser struct {
|
|
||||||
r io.Reader
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsReaderSeekable returns if the underlying reader type can be seeked. A
|
|
||||||
// io.Reader might not actually be seekable if it is the ReaderSeekerCloser
|
|
||||||
// type.
|
|
||||||
func IsReaderSeekable(r io.Reader) bool {
|
|
||||||
switch v := r.(type) {
|
|
||||||
case ReaderSeekerCloser:
|
|
||||||
return v.IsSeeker()
|
|
||||||
case *ReaderSeekerCloser:
|
|
||||||
return v.IsSeeker()
|
|
||||||
case io.ReadSeeker:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read reads from the reader up to size of p. The number of bytes read, and
|
|
||||||
// error if it occurred will be returned.
|
|
||||||
//
|
|
||||||
// If the reader is not an io.Reader zero bytes read, and nil error will be returned.
|
|
||||||
//
|
|
||||||
// Performs the same functionality as io.Reader Read
|
|
||||||
func (r ReaderSeekerCloser) Read(p []byte) (int, error) {
|
|
||||||
switch t := r.r.(type) {
|
|
||||||
case io.Reader:
|
|
||||||
return t.Read(p)
|
|
||||||
}
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek sets the offset for the next Read to offset, interpreted according to
|
|
||||||
// whence: 0 means relative to the origin of the file, 1 means relative to the
|
|
||||||
// current offset, and 2 means relative to the end. Seek returns the new offset
|
|
||||||
// and an error, if any.
|
|
||||||
//
|
|
||||||
// If the ReaderSeekerCloser is not an io.Seeker nothing will be done.
|
|
||||||
func (r ReaderSeekerCloser) Seek(offset int64, whence int) (int64, error) {
|
|
||||||
switch t := r.r.(type) {
|
|
||||||
case io.Seeker:
|
|
||||||
return t.Seek(offset, whence)
|
|
||||||
}
|
|
||||||
return int64(0), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSeeker returns if the underlying reader is also a seeker.
|
|
||||||
func (r ReaderSeekerCloser) IsSeeker() bool {
|
|
||||||
_, ok := r.r.(io.Seeker)
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasLen returns the length of the underlying reader if the value implements
|
|
||||||
// the Len() int method.
|
|
||||||
func (r ReaderSeekerCloser) HasLen() (int, bool) {
|
|
||||||
type lenner interface {
|
|
||||||
Len() int
|
|
||||||
}
|
|
||||||
|
|
||||||
if lr, ok := r.r.(lenner); ok {
|
|
||||||
return lr.Len(), true
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLen returns the length of the bytes remaining in the underlying reader.
|
|
||||||
// Checks first for Len(), then io.Seeker to determine the size of the
|
|
||||||
// underlying reader.
|
|
||||||
//
|
|
||||||
// Will return -1 if the length cannot be determined.
|
|
||||||
func (r ReaderSeekerCloser) GetLen() (int64, error) {
|
|
||||||
if l, ok := r.HasLen(); ok {
|
|
||||||
return int64(l), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if s, ok := r.r.(io.Seeker); ok {
|
|
||||||
return seekerLen(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SeekerLen attempts to get the number of bytes remaining at the seeker's
|
|
||||||
// current position. Returns the number of bytes remaining or error.
|
|
||||||
func SeekerLen(s io.Seeker) (int64, error) {
|
|
||||||
// Determine if the seeker is actually seekable. ReaderSeekerCloser
|
|
||||||
// hides the fact that a io.Readers might not actually be seekable.
|
|
||||||
switch v := s.(type) {
|
|
||||||
case ReaderSeekerCloser:
|
|
||||||
return v.GetLen()
|
|
||||||
case *ReaderSeekerCloser:
|
|
||||||
return v.GetLen()
|
|
||||||
}
|
|
||||||
|
|
||||||
return seekerLen(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func seekerLen(s io.Seeker) (int64, error) {
|
|
||||||
curOffset, err := s.Seek(0, sdkio.SeekCurrent)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
endOffset, err := s.Seek(0, sdkio.SeekEnd)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = s.Seek(curOffset, sdkio.SeekStart)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return endOffset - curOffset, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the ReaderSeekerCloser.
|
|
||||||
//
|
|
||||||
// If the ReaderSeekerCloser is not an io.Closer nothing will be done.
|
|
||||||
func (r ReaderSeekerCloser) Close() error {
|
|
||||||
switch t := r.r.(type) {
|
|
||||||
case io.Closer:
|
|
||||||
return t.Close()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// A WriteAtBuffer provides a in memory buffer supporting the io.WriterAt interface
|
|
||||||
// Can be used with the s3manager.Downloader to download content to a buffer
|
|
||||||
// in memory. Safe to use concurrently.
|
|
||||||
type WriteAtBuffer struct {
|
|
||||||
buf []byte
|
|
||||||
m sync.Mutex
|
|
||||||
|
|
||||||
// GrowthCoeff defines the growth rate of the internal buffer. By
|
|
||||||
// default, the growth rate is 1, where expanding the internal
|
|
||||||
// buffer will allocate only enough capacity to fit the new expected
|
|
||||||
// length.
|
|
||||||
GrowthCoeff float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewWriteAtBuffer creates a WriteAtBuffer with an internal buffer
|
|
||||||
// provided by buf.
|
|
||||||
func NewWriteAtBuffer(buf []byte) *WriteAtBuffer {
|
|
||||||
return &WriteAtBuffer{buf: buf}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WriteAt writes a slice of bytes to a buffer starting at the position provided
|
|
||||||
// The number of bytes written will be returned, or error. Can overwrite previous
|
|
||||||
// written slices if the write ats overlap.
|
|
||||||
func (b *WriteAtBuffer) WriteAt(p []byte, pos int64) (n int, err error) {
|
|
||||||
pLen := len(p)
|
|
||||||
expLen := pos + int64(pLen)
|
|
||||||
b.m.Lock()
|
|
||||||
defer b.m.Unlock()
|
|
||||||
if int64(len(b.buf)) < expLen {
|
|
||||||
if int64(cap(b.buf)) < expLen {
|
|
||||||
if b.GrowthCoeff < 1 {
|
|
||||||
b.GrowthCoeff = 1
|
|
||||||
}
|
|
||||||
newBuf := make([]byte, expLen, int64(b.GrowthCoeff*float64(expLen)))
|
|
||||||
copy(newBuf, b.buf)
|
|
||||||
b.buf = newBuf
|
|
||||||
}
|
|
||||||
b.buf = b.buf[:expLen]
|
|
||||||
}
|
|
||||||
copy(b.buf[pos:], p)
|
|
||||||
return pLen, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes returns a slice of bytes written to the buffer.
|
|
||||||
func (b *WriteAtBuffer) Bytes() []byte {
|
|
||||||
b.m.Lock()
|
|
||||||
defer b.m.Unlock()
|
|
||||||
return b.buf
|
|
||||||
}
|
|
12
vendor/github.com/aws/aws-sdk-go/aws/url.go
generated
vendored
12
vendor/github.com/aws/aws-sdk-go/aws/url.go
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
// +build go1.8
|
|
||||||
|
|
||||||
package aws
|
|
||||||
|
|
||||||
import "net/url"
|
|
||||||
|
|
||||||
// URLHostname will extract the Hostname without port from the URL value.
|
|
||||||
//
|
|
||||||
// Wrapper of net/url#URL.Hostname for backwards Go version compatibility.
|
|
||||||
func URLHostname(url *url.URL) string {
|
|
||||||
return url.Hostname()
|
|
||||||
}
|
|
29
vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go
generated
vendored
29
vendor/github.com/aws/aws-sdk-go/aws/url_1_7.go
generated
vendored
@ -1,29 +0,0 @@
|
|||||||
// +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]
|
|
||||||
}
|
|
8
vendor/github.com/aws/aws-sdk-go/aws/version.go
generated
vendored
8
vendor/github.com/aws/aws-sdk-go/aws/version.go
generated
vendored
@ -1,8 +0,0 @@
|
|||||||
// Package aws provides core functionality for making requests to AWS services.
|
|
||||||
package aws
|
|
||||||
|
|
||||||
// SDKName is the name of this AWS SDK
|
|
||||||
const SDKName = "aws-sdk-go"
|
|
||||||
|
|
||||||
// SDKVersion is the version of this SDK
|
|
||||||
const SDKVersion = "1.15.77"
|
|
120
vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go
generated
vendored
120
vendor/github.com/aws/aws-sdk-go/internal/ini/ast.go
generated
vendored
@ -1,120 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
// ASTKind represents different states in the parse table
|
|
||||||
// and the type of AST that is being constructed
|
|
||||||
type ASTKind int
|
|
||||||
|
|
||||||
// ASTKind* is used in the parse table to transition between
|
|
||||||
// the different states
|
|
||||||
const (
|
|
||||||
ASTKindNone = ASTKind(iota)
|
|
||||||
ASTKindStart
|
|
||||||
ASTKindExpr
|
|
||||||
ASTKindEqualExpr
|
|
||||||
ASTKindStatement
|
|
||||||
ASTKindSkipStatement
|
|
||||||
ASTKindExprStatement
|
|
||||||
ASTKindSectionStatement
|
|
||||||
ASTKindNestedSectionStatement
|
|
||||||
ASTKindCompletedNestedSectionStatement
|
|
||||||
ASTKindCommentStatement
|
|
||||||
ASTKindCompletedSectionStatement
|
|
||||||
)
|
|
||||||
|
|
||||||
func (k ASTKind) String() string {
|
|
||||||
switch k {
|
|
||||||
case ASTKindNone:
|
|
||||||
return "none"
|
|
||||||
case ASTKindStart:
|
|
||||||
return "start"
|
|
||||||
case ASTKindExpr:
|
|
||||||
return "expr"
|
|
||||||
case ASTKindStatement:
|
|
||||||
return "stmt"
|
|
||||||
case ASTKindSectionStatement:
|
|
||||||
return "section_stmt"
|
|
||||||
case ASTKindExprStatement:
|
|
||||||
return "expr_stmt"
|
|
||||||
case ASTKindCommentStatement:
|
|
||||||
return "comment"
|
|
||||||
case ASTKindNestedSectionStatement:
|
|
||||||
return "nested_section_stmt"
|
|
||||||
case ASTKindCompletedSectionStatement:
|
|
||||||
return "completed_stmt"
|
|
||||||
case ASTKindSkipStatement:
|
|
||||||
return "skip"
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AST interface allows us to determine what kind of node we
|
|
||||||
// are on and casting may not need to be necessary.
|
|
||||||
//
|
|
||||||
// The root is always the first node in Children
|
|
||||||
type AST struct {
|
|
||||||
Kind ASTKind
|
|
||||||
Root Token
|
|
||||||
RootToken bool
|
|
||||||
Children []AST
|
|
||||||
}
|
|
||||||
|
|
||||||
func newAST(kind ASTKind, root AST, children ...AST) AST {
|
|
||||||
return AST{
|
|
||||||
Kind: kind,
|
|
||||||
Children: append([]AST{root}, children...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newASTWithRootToken(kind ASTKind, root Token, children ...AST) AST {
|
|
||||||
return AST{
|
|
||||||
Kind: kind,
|
|
||||||
Root: root,
|
|
||||||
RootToken: true,
|
|
||||||
Children: children,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendChild will append to the list of children an AST has.
|
|
||||||
func (a *AST) AppendChild(child AST) {
|
|
||||||
a.Children = append(a.Children, child)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRoot will return the root AST which can be the first entry
|
|
||||||
// in the children list or a token.
|
|
||||||
func (a *AST) GetRoot() AST {
|
|
||||||
if a.RootToken {
|
|
||||||
return *a
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(a.Children) == 0 {
|
|
||||||
return AST{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Children[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetChildren will return the current AST's list of children
|
|
||||||
func (a *AST) GetChildren() []AST {
|
|
||||||
if len(a.Children) == 0 {
|
|
||||||
return []AST{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if a.RootToken {
|
|
||||||
return a.Children
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.Children[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetChildren will set and override all children of the AST.
|
|
||||||
func (a *AST) SetChildren(children []AST) {
|
|
||||||
if a.RootToken {
|
|
||||||
a.Children = children
|
|
||||||
} else {
|
|
||||||
a.Children = append(a.Children[:1], children...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start is used to indicate the starting state of the parse table.
|
|
||||||
var Start = newAST(ASTKindStart, AST{})
|
|
11
vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go
generated
vendored
11
vendor/github.com/aws/aws-sdk-go/internal/ini/comma_token.go
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
var commaRunes = []rune(",")
|
|
||||||
|
|
||||||
func isComma(b rune) bool {
|
|
||||||
return b == ','
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCommaToken() Token {
|
|
||||||
return newToken(TokenComma, commaRunes, NoneType)
|
|
||||||
}
|
|
35
vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go
generated
vendored
35
vendor/github.com/aws/aws-sdk-go/internal/ini/comment_token.go
generated
vendored
@ -1,35 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
// isComment will return whether or not the next byte(s) is a
|
|
||||||
// comment.
|
|
||||||
func isComment(b []rune) bool {
|
|
||||||
if len(b) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
switch b[0] {
|
|
||||||
case ';':
|
|
||||||
return true
|
|
||||||
case '#':
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// newCommentToken will create a comment token and
|
|
||||||
// return how many bytes were read.
|
|
||||||
func newCommentToken(b []rune) (Token, int, error) {
|
|
||||||
i := 0
|
|
||||||
for ; i < len(b); i++ {
|
|
||||||
if b[i] == '\n' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(b)-i > 2 && b[i] == '\r' && b[i+1] == '\n' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newToken(TokenComment, b[:i], NoneType), i, nil
|
|
||||||
}
|
|
29
vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go
generated
vendored
29
vendor/github.com/aws/aws-sdk-go/internal/ini/doc.go
generated
vendored
@ -1,29 +0,0 @@
|
|||||||
// Package ini is an LL(1) parser for configuration files.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
// sections, err := ini.OpenFile("/path/to/file")
|
|
||||||
// if err != nil {
|
|
||||||
// panic(err)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// profile := "foo"
|
|
||||||
// section, ok := sections.GetSection(profile)
|
|
||||||
// if !ok {
|
|
||||||
// fmt.Printf("section %q could not be found", profile)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Below is the BNF that describes this parser
|
|
||||||
// Grammar:
|
|
||||||
// stmt -> value stmt'
|
|
||||||
// stmt' -> epsilon | op stmt
|
|
||||||
// value -> number | string | boolean | quoted_string
|
|
||||||
//
|
|
||||||
// section -> [ section'
|
|
||||||
// section' -> value section_close
|
|
||||||
// section_close -> ]
|
|
||||||
//
|
|
||||||
// SkipState will skip (NL WS)+
|
|
||||||
//
|
|
||||||
// comment -> # comment' | ; comment'
|
|
||||||
// comment' -> epsilon | value
|
|
||||||
package ini
|
|
4
vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go
generated
vendored
4
vendor/github.com/aws/aws-sdk-go/internal/ini/empty_token.go
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
// emptyToken is used to satisfy the Token interface
|
|
||||||
var emptyToken = newToken(TokenNone, []rune{}, NoneType)
|
|
24
vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go
generated
vendored
24
vendor/github.com/aws/aws-sdk-go/internal/ini/expression.go
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
// newExpression will return an expression AST.
|
|
||||||
// Expr represents an expression
|
|
||||||
//
|
|
||||||
// grammar:
|
|
||||||
// expr -> string | number
|
|
||||||
func newExpression(tok Token) AST {
|
|
||||||
return newASTWithRootToken(ASTKindExpr, tok)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newEqualExpr(left AST, tok Token) AST {
|
|
||||||
return newASTWithRootToken(ASTKindEqualExpr, tok, left)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EqualExprKey will return a LHS value in the equal expr
|
|
||||||
func EqualExprKey(ast AST) string {
|
|
||||||
children := ast.GetChildren()
|
|
||||||
if len(children) == 0 || ast.Kind != ASTKindEqualExpr {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(children[0].Root.Raw())
|
|
||||||
}
|
|
17
vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go
generated
vendored
17
vendor/github.com/aws/aws-sdk-go/internal/ini/fuzz.go
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
// +build gofuzz
|
|
||||||
|
|
||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Fuzz(data []byte) int {
|
|
||||||
b := bytes.NewReader(data)
|
|
||||||
|
|
||||||
if _, err := Parse(b); err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
51
vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go
generated
vendored
51
vendor/github.com/aws/aws-sdk-go/internal/ini/ini.go
generated
vendored
@ -1,51 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
// OpenFile takes a path to a given file, and will open and parse
|
|
||||||
// that file.
|
|
||||||
func OpenFile(path string) (Sections, error) {
|
|
||||||
f, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
return Sections{}, awserr.New(ErrCodeUnableToReadFile, "unable to open file", err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
return Parse(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse will parse the given file using the shared config
|
|
||||||
// visitor.
|
|
||||||
func Parse(f io.Reader) (Sections, error) {
|
|
||||||
tree, err := ParseAST(f)
|
|
||||||
if err != nil {
|
|
||||||
return Sections{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := NewDefaultVisitor()
|
|
||||||
if err = Walk(tree, v); err != nil {
|
|
||||||
return Sections{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.Sections, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseBytes will parse the given bytes and return the parsed sections.
|
|
||||||
func ParseBytes(b []byte) (Sections, error) {
|
|
||||||
tree, err := ParseASTBytes(b)
|
|
||||||
if err != nil {
|
|
||||||
return Sections{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := NewDefaultVisitor()
|
|
||||||
if err = Walk(tree, v); err != nil {
|
|
||||||
return Sections{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.Sections, nil
|
|
||||||
}
|
|
165
vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go
generated
vendored
165
vendor/github.com/aws/aws-sdk-go/internal/ini/ini_lexer.go
generated
vendored
@ -1,165 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ErrCodeUnableToReadFile is used when a file is failed to be
|
|
||||||
// opened or read from.
|
|
||||||
ErrCodeUnableToReadFile = "FailedRead"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TokenType represents the various different tokens types
|
|
||||||
type TokenType int
|
|
||||||
|
|
||||||
func (t TokenType) String() string {
|
|
||||||
switch t {
|
|
||||||
case TokenNone:
|
|
||||||
return "none"
|
|
||||||
case TokenLit:
|
|
||||||
return "literal"
|
|
||||||
case TokenSep:
|
|
||||||
return "sep"
|
|
||||||
case TokenOp:
|
|
||||||
return "op"
|
|
||||||
case TokenWS:
|
|
||||||
return "ws"
|
|
||||||
case TokenNL:
|
|
||||||
return "newline"
|
|
||||||
case TokenComment:
|
|
||||||
return "comment"
|
|
||||||
case TokenComma:
|
|
||||||
return "comma"
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TokenType enums
|
|
||||||
const (
|
|
||||||
TokenNone = TokenType(iota)
|
|
||||||
TokenLit
|
|
||||||
TokenSep
|
|
||||||
TokenComma
|
|
||||||
TokenOp
|
|
||||||
TokenWS
|
|
||||||
TokenNL
|
|
||||||
TokenComment
|
|
||||||
)
|
|
||||||
|
|
||||||
type iniLexer struct{}
|
|
||||||
|
|
||||||
// Tokenize will return a list of tokens during lexical analysis of the
|
|
||||||
// io.Reader.
|
|
||||||
func (l *iniLexer) Tokenize(r io.Reader) ([]Token, error) {
|
|
||||||
b, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, awserr.New(ErrCodeUnableToReadFile, "unable to read file", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return l.tokenize(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *iniLexer) tokenize(b []byte) ([]Token, error) {
|
|
||||||
runes := bytes.Runes(b)
|
|
||||||
var err error
|
|
||||||
n := 0
|
|
||||||
tokenAmount := countTokens(runes)
|
|
||||||
tokens := make([]Token, tokenAmount)
|
|
||||||
count := 0
|
|
||||||
|
|
||||||
for len(runes) > 0 && count < tokenAmount {
|
|
||||||
switch {
|
|
||||||
case isWhitespace(runes[0]):
|
|
||||||
tokens[count], n, err = newWSToken(runes)
|
|
||||||
case isComma(runes[0]):
|
|
||||||
tokens[count], n = newCommaToken(), 1
|
|
||||||
case isComment(runes):
|
|
||||||
tokens[count], n, err = newCommentToken(runes)
|
|
||||||
case isNewline(runes):
|
|
||||||
tokens[count], n, err = newNewlineToken(runes)
|
|
||||||
case isSep(runes):
|
|
||||||
tokens[count], n, err = newSepToken(runes)
|
|
||||||
case isOp(runes):
|
|
||||||
tokens[count], n, err = newOpToken(runes)
|
|
||||||
default:
|
|
||||||
tokens[count], n, err = newLitToken(runes)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
count++
|
|
||||||
|
|
||||||
runes = runes[n:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return tokens[:count], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func countTokens(runes []rune) int {
|
|
||||||
count, n := 0, 0
|
|
||||||
var err error
|
|
||||||
|
|
||||||
for len(runes) > 0 {
|
|
||||||
switch {
|
|
||||||
case isWhitespace(runes[0]):
|
|
||||||
_, n, err = newWSToken(runes)
|
|
||||||
case isComma(runes[0]):
|
|
||||||
_, n = newCommaToken(), 1
|
|
||||||
case isComment(runes):
|
|
||||||
_, n, err = newCommentToken(runes)
|
|
||||||
case isNewline(runes):
|
|
||||||
_, n, err = newNewlineToken(runes)
|
|
||||||
case isSep(runes):
|
|
||||||
_, n, err = newSepToken(runes)
|
|
||||||
case isOp(runes):
|
|
||||||
_, n, err = newOpToken(runes)
|
|
||||||
default:
|
|
||||||
_, n, err = newLitToken(runes)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
count++
|
|
||||||
runes = runes[n:]
|
|
||||||
}
|
|
||||||
|
|
||||||
return count + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// Token indicates a metadata about a given value.
|
|
||||||
type Token struct {
|
|
||||||
t TokenType
|
|
||||||
ValueType ValueType
|
|
||||||
base int
|
|
||||||
raw []rune
|
|
||||||
}
|
|
||||||
|
|
||||||
var emptyValue = Value{}
|
|
||||||
|
|
||||||
func newToken(t TokenType, raw []rune, v ValueType) Token {
|
|
||||||
return Token{
|
|
||||||
t: t,
|
|
||||||
raw: raw,
|
|
||||||
ValueType: v,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Raw return the raw runes that were consumed
|
|
||||||
func (tok Token) Raw() []rune {
|
|
||||||
return tok.raw
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type returns the token type
|
|
||||||
func (tok Token) Type() TokenType {
|
|
||||||
return tok.t
|
|
||||||
}
|
|
348
vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go
generated
vendored
348
vendor/github.com/aws/aws-sdk-go/internal/ini/ini_parser.go
generated
vendored
@ -1,348 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// State enums for the parse table
|
|
||||||
const (
|
|
||||||
InvalidState = iota
|
|
||||||
// stmt -> value stmt'
|
|
||||||
StatementState
|
|
||||||
// stmt' -> MarkComplete | op stmt
|
|
||||||
StatementPrimeState
|
|
||||||
// value -> number | string | boolean | quoted_string
|
|
||||||
ValueState
|
|
||||||
// section -> [ section'
|
|
||||||
OpenScopeState
|
|
||||||
// section' -> value section_close
|
|
||||||
SectionState
|
|
||||||
// section_close -> ]
|
|
||||||
CloseScopeState
|
|
||||||
// SkipState will skip (NL WS)+
|
|
||||||
SkipState
|
|
||||||
// SkipTokenState will skip any token and push the previous
|
|
||||||
// state onto the stack.
|
|
||||||
SkipTokenState
|
|
||||||
// comment -> # comment' | ; comment'
|
|
||||||
// comment' -> MarkComplete | value
|
|
||||||
CommentState
|
|
||||||
// MarkComplete state will complete statements and move that
|
|
||||||
// to the completed AST list
|
|
||||||
MarkCompleteState
|
|
||||||
// TerminalState signifies that the tokens have been fully parsed
|
|
||||||
TerminalState
|
|
||||||
)
|
|
||||||
|
|
||||||
// parseTable is a state machine to dictate the grammar above.
|
|
||||||
var parseTable = map[ASTKind]map[TokenType]int{
|
|
||||||
ASTKindStart: map[TokenType]int{
|
|
||||||
TokenLit: StatementState,
|
|
||||||
TokenSep: OpenScopeState,
|
|
||||||
TokenWS: SkipTokenState,
|
|
||||||
TokenNL: SkipTokenState,
|
|
||||||
TokenComment: CommentState,
|
|
||||||
TokenNone: TerminalState,
|
|
||||||
},
|
|
||||||
ASTKindCommentStatement: map[TokenType]int{
|
|
||||||
TokenLit: StatementState,
|
|
||||||
TokenSep: OpenScopeState,
|
|
||||||
TokenWS: SkipTokenState,
|
|
||||||
TokenNL: SkipTokenState,
|
|
||||||
TokenComment: CommentState,
|
|
||||||
TokenNone: MarkCompleteState,
|
|
||||||
},
|
|
||||||
ASTKindExpr: map[TokenType]int{
|
|
||||||
TokenOp: StatementPrimeState,
|
|
||||||
TokenLit: ValueState,
|
|
||||||
TokenSep: OpenScopeState,
|
|
||||||
TokenWS: ValueState,
|
|
||||||
TokenNL: SkipState,
|
|
||||||
TokenComment: CommentState,
|
|
||||||
TokenNone: MarkCompleteState,
|
|
||||||
},
|
|
||||||
ASTKindEqualExpr: map[TokenType]int{
|
|
||||||
TokenLit: ValueState,
|
|
||||||
TokenWS: SkipTokenState,
|
|
||||||
TokenNL: SkipState,
|
|
||||||
},
|
|
||||||
ASTKindStatement: map[TokenType]int{
|
|
||||||
TokenLit: SectionState,
|
|
||||||
TokenSep: CloseScopeState,
|
|
||||||
TokenWS: SkipTokenState,
|
|
||||||
TokenNL: SkipTokenState,
|
|
||||||
TokenComment: CommentState,
|
|
||||||
TokenNone: MarkCompleteState,
|
|
||||||
},
|
|
||||||
ASTKindExprStatement: map[TokenType]int{
|
|
||||||
TokenLit: ValueState,
|
|
||||||
TokenSep: OpenScopeState,
|
|
||||||
TokenOp: ValueState,
|
|
||||||
TokenWS: ValueState,
|
|
||||||
TokenNL: MarkCompleteState,
|
|
||||||
TokenComment: CommentState,
|
|
||||||
TokenNone: TerminalState,
|
|
||||||
TokenComma: SkipState,
|
|
||||||
},
|
|
||||||
ASTKindSectionStatement: map[TokenType]int{
|
|
||||||
TokenLit: SectionState,
|
|
||||||
TokenOp: SectionState,
|
|
||||||
TokenSep: CloseScopeState,
|
|
||||||
TokenWS: SectionState,
|
|
||||||
TokenNL: SkipTokenState,
|
|
||||||
},
|
|
||||||
ASTKindCompletedSectionStatement: map[TokenType]int{
|
|
||||||
TokenWS: SkipTokenState,
|
|
||||||
TokenNL: SkipTokenState,
|
|
||||||
TokenLit: StatementState,
|
|
||||||
TokenSep: OpenScopeState,
|
|
||||||
TokenComment: CommentState,
|
|
||||||
TokenNone: MarkCompleteState,
|
|
||||||
},
|
|
||||||
ASTKindSkipStatement: map[TokenType]int{
|
|
||||||
TokenLit: StatementState,
|
|
||||||
TokenSep: OpenScopeState,
|
|
||||||
TokenWS: SkipTokenState,
|
|
||||||
TokenNL: SkipTokenState,
|
|
||||||
TokenComment: CommentState,
|
|
||||||
TokenNone: TerminalState,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseAST will parse input from an io.Reader using
|
|
||||||
// an LL(1) parser.
|
|
||||||
func ParseAST(r io.Reader) ([]AST, error) {
|
|
||||||
lexer := iniLexer{}
|
|
||||||
tokens, err := lexer.Tokenize(r)
|
|
||||||
if err != nil {
|
|
||||||
return []AST{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return parse(tokens)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseASTBytes will parse input from a byte slice using
|
|
||||||
// an LL(1) parser.
|
|
||||||
func ParseASTBytes(b []byte) ([]AST, error) {
|
|
||||||
lexer := iniLexer{}
|
|
||||||
tokens, err := lexer.tokenize(b)
|
|
||||||
if err != nil {
|
|
||||||
return []AST{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return parse(tokens)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parse(tokens []Token) ([]AST, error) {
|
|
||||||
start := Start
|
|
||||||
stack := newParseStack(3, len(tokens))
|
|
||||||
|
|
||||||
stack.Push(start)
|
|
||||||
s := newSkipper()
|
|
||||||
|
|
||||||
loop:
|
|
||||||
for stack.Len() > 0 {
|
|
||||||
k := stack.Pop()
|
|
||||||
|
|
||||||
var tok Token
|
|
||||||
if len(tokens) == 0 {
|
|
||||||
// this occurs when all the tokens have been processed
|
|
||||||
// but reduction of what's left on the stack needs to
|
|
||||||
// occur.
|
|
||||||
tok = emptyToken
|
|
||||||
} else {
|
|
||||||
tok = tokens[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
step := parseTable[k.Kind][tok.Type()]
|
|
||||||
if s.ShouldSkip(tok) {
|
|
||||||
// being in a skip state with no tokens will break out of
|
|
||||||
// the parse loop since there is nothing left to process.
|
|
||||||
if len(tokens) == 0 {
|
|
||||||
break loop
|
|
||||||
}
|
|
||||||
|
|
||||||
step = SkipTokenState
|
|
||||||
}
|
|
||||||
|
|
||||||
switch step {
|
|
||||||
case TerminalState:
|
|
||||||
// Finished parsing. Push what should be the last
|
|
||||||
// statement to the stack. If there is anything left
|
|
||||||
// on the stack, an error in parsing has occurred.
|
|
||||||
if k.Kind != ASTKindStart {
|
|
||||||
stack.MarkComplete(k)
|
|
||||||
}
|
|
||||||
break loop
|
|
||||||
case SkipTokenState:
|
|
||||||
// When skipping a token, the previous state was popped off the stack.
|
|
||||||
// To maintain the correct state, the previous state will be pushed
|
|
||||||
// onto the stack.
|
|
||||||
stack.Push(k)
|
|
||||||
case StatementState:
|
|
||||||
if k.Kind != ASTKindStart {
|
|
||||||
stack.MarkComplete(k)
|
|
||||||
}
|
|
||||||
expr := newExpression(tok)
|
|
||||||
stack.Push(expr)
|
|
||||||
case StatementPrimeState:
|
|
||||||
if tok.Type() != TokenOp {
|
|
||||||
stack.MarkComplete(k)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if k.Kind != ASTKindExpr {
|
|
||||||
return nil, NewParseError(
|
|
||||||
fmt.Sprintf("invalid expression: expected Expr type, but found %T type", k),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
k = trimSpaces(k)
|
|
||||||
expr := newEqualExpr(k, tok)
|
|
||||||
stack.Push(expr)
|
|
||||||
case ValueState:
|
|
||||||
// ValueState requires the previous state to either be an equal expression
|
|
||||||
// or an expression statement.
|
|
||||||
//
|
|
||||||
// This grammar occurs when the RHS is a number, word, or quoted string.
|
|
||||||
// equal_expr -> lit op equal_expr'
|
|
||||||
// equal_expr' -> number | string | quoted_string
|
|
||||||
// quoted_string -> " quoted_string'
|
|
||||||
// quoted_string' -> string quoted_string_end
|
|
||||||
// quoted_string_end -> "
|
|
||||||
//
|
|
||||||
// otherwise
|
|
||||||
// expr_stmt -> equal_expr (expr_stmt')*
|
|
||||||
// expr_stmt' -> ws S | op S | MarkComplete
|
|
||||||
// S -> equal_expr' expr_stmt'
|
|
||||||
switch k.Kind {
|
|
||||||
case ASTKindEqualExpr:
|
|
||||||
// assiging a value to some key
|
|
||||||
k.AppendChild(newExpression(tok))
|
|
||||||
stack.Push(newExprStatement(k))
|
|
||||||
case ASTKindExpr:
|
|
||||||
k.Root.raw = append(k.Root.raw, tok.Raw()...)
|
|
||||||
stack.Push(k)
|
|
||||||
case ASTKindExprStatement:
|
|
||||||
root := k.GetRoot()
|
|
||||||
children := root.GetChildren()
|
|
||||||
if len(children) == 0 {
|
|
||||||
return nil, NewParseError(
|
|
||||||
fmt.Sprintf("invalid expression: AST contains no children %s", k.Kind),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
rhs := children[len(children)-1]
|
|
||||||
|
|
||||||
if rhs.Root.ValueType != QuotedStringType {
|
|
||||||
rhs.Root.ValueType = StringType
|
|
||||||
rhs.Root.raw = append(rhs.Root.raw, tok.Raw()...)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
children[len(children)-1] = rhs
|
|
||||||
k.SetChildren(children)
|
|
||||||
|
|
||||||
stack.Push(k)
|
|
||||||
}
|
|
||||||
case OpenScopeState:
|
|
||||||
if !runeCompare(tok.Raw(), openBrace) {
|
|
||||||
return nil, NewParseError("expected '['")
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt := newStatement()
|
|
||||||
stack.Push(stmt)
|
|
||||||
case CloseScopeState:
|
|
||||||
if !runeCompare(tok.Raw(), closeBrace) {
|
|
||||||
return nil, NewParseError("expected ']'")
|
|
||||||
}
|
|
||||||
|
|
||||||
k = trimSpaces(k)
|
|
||||||
stack.Push(newCompletedSectionStatement(k))
|
|
||||||
case SectionState:
|
|
||||||
var stmt AST
|
|
||||||
|
|
||||||
switch k.Kind {
|
|
||||||
case ASTKindStatement:
|
|
||||||
// If there are multiple literals inside of a scope declaration,
|
|
||||||
// then the current token's raw value will be appended to the Name.
|
|
||||||
//
|
|
||||||
// This handles cases like [ profile default ]
|
|
||||||
//
|
|
||||||
// k will represent a SectionStatement with the children representing
|
|
||||||
// the label of the section
|
|
||||||
stmt = newSectionStatement(tok)
|
|
||||||
case ASTKindSectionStatement:
|
|
||||||
k.Root.raw = append(k.Root.raw, tok.Raw()...)
|
|
||||||
stmt = k
|
|
||||||
default:
|
|
||||||
return nil, NewParseError(
|
|
||||||
fmt.Sprintf("invalid statement: expected statement: %v", k.Kind),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
stack.Push(stmt)
|
|
||||||
case MarkCompleteState:
|
|
||||||
if k.Kind != ASTKindStart {
|
|
||||||
stack.MarkComplete(k)
|
|
||||||
}
|
|
||||||
|
|
||||||
if stack.Len() == 0 {
|
|
||||||
stack.Push(start)
|
|
||||||
}
|
|
||||||
case SkipState:
|
|
||||||
stack.Push(newSkipStatement(k))
|
|
||||||
s.Skip()
|
|
||||||
case CommentState:
|
|
||||||
if k.Kind == ASTKindStart {
|
|
||||||
stack.Push(k)
|
|
||||||
} else {
|
|
||||||
stack.MarkComplete(k)
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt := newCommentStatement(tok)
|
|
||||||
stack.Push(stmt)
|
|
||||||
default:
|
|
||||||
return nil, NewParseError(fmt.Sprintf("invalid state with ASTKind %v and TokenType %v", k, tok))
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(tokens) > 0 {
|
|
||||||
tokens = tokens[1:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this occurs when a statement has not been completed
|
|
||||||
if stack.top > 1 {
|
|
||||||
return nil, NewParseError(fmt.Sprintf("incomplete expression: %v", stack.container))
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns a sublist which exludes the start symbol
|
|
||||||
return stack.List(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// trimSpaces will trim spaces on the left and right hand side of
|
|
||||||
// the literal.
|
|
||||||
func trimSpaces(k AST) AST {
|
|
||||||
// trim left hand side of spaces
|
|
||||||
for i := 0; i < len(k.Root.raw); i++ {
|
|
||||||
if !isWhitespace(k.Root.raw[i]) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
k.Root.raw = k.Root.raw[1:]
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
|
|
||||||
// trim right hand side of spaces
|
|
||||||
for i := len(k.Root.raw) - 1; i > 0; i-- {
|
|
||||||
if !isWhitespace(k.Root.raw[i]) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
k.Root.raw = k.Root.raw[:len(k.Root.raw)-1]
|
|
||||||
i--
|
|
||||||
}
|
|
||||||
|
|
||||||
return k
|
|
||||||
}
|
|
324
vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go
generated
vendored
324
vendor/github.com/aws/aws-sdk-go/internal/ini/literal_tokens.go
generated
vendored
@ -1,324 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
runesTrue = []rune("true")
|
|
||||||
runesFalse = []rune("false")
|
|
||||||
)
|
|
||||||
|
|
||||||
var literalValues = [][]rune{
|
|
||||||
runesTrue,
|
|
||||||
runesFalse,
|
|
||||||
}
|
|
||||||
|
|
||||||
func isBoolValue(b []rune) bool {
|
|
||||||
for _, lv := range literalValues {
|
|
||||||
if isLitValue(lv, b) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func isLitValue(want, have []rune) bool {
|
|
||||||
if len(have) < len(want) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < len(want); i++ {
|
|
||||||
if want[i] != have[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// isNumberValue will return whether not the leading characters in
|
|
||||||
// a byte slice is a number. A number is delimited by whitespace or
|
|
||||||
// the newline token.
|
|
||||||
//
|
|
||||||
// A number is defined to be in a binary, octal, decimal (int | float), hex format,
|
|
||||||
// or in scientific notation.
|
|
||||||
func isNumberValue(b []rune) bool {
|
|
||||||
negativeIndex := 0
|
|
||||||
helper := numberHelper{}
|
|
||||||
needDigit := false
|
|
||||||
|
|
||||||
for i := 0; i < len(b); i++ {
|
|
||||||
negativeIndex++
|
|
||||||
|
|
||||||
switch b[i] {
|
|
||||||
case '-':
|
|
||||||
if helper.IsNegative() || negativeIndex != 1 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
helper.Determine(b[i])
|
|
||||||
needDigit = true
|
|
||||||
continue
|
|
||||||
case 'e', 'E':
|
|
||||||
if err := helper.Determine(b[i]); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
negativeIndex = 0
|
|
||||||
needDigit = true
|
|
||||||
continue
|
|
||||||
case 'b':
|
|
||||||
if helper.numberFormat == hex {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
case 'o', 'x':
|
|
||||||
needDigit = true
|
|
||||||
if i == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
fallthrough
|
|
||||||
case '.':
|
|
||||||
if err := helper.Determine(b[i]); err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
needDigit = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if i > 0 && (isNewline(b[i:]) || isWhitespace(b[i])) {
|
|
||||||
return !needDigit
|
|
||||||
}
|
|
||||||
|
|
||||||
if !helper.CorrectByte(b[i]) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
needDigit = false
|
|
||||||
}
|
|
||||||
|
|
||||||
return !needDigit
|
|
||||||
}
|
|
||||||
|
|
||||||
func isValid(b []rune) (bool, int, error) {
|
|
||||||
if len(b) == 0 {
|
|
||||||
// TODO: should probably return an error
|
|
||||||
return false, 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return isValidRune(b[0]), 1, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isValidRune(r rune) bool {
|
|
||||||
return r != ':' && r != '=' && r != '[' && r != ']' && r != ' ' && r != '\n'
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValueType is an enum that will signify what type
|
|
||||||
// the Value is
|
|
||||||
type ValueType int
|
|
||||||
|
|
||||||
func (v ValueType) String() string {
|
|
||||||
switch v {
|
|
||||||
case NoneType:
|
|
||||||
return "NONE"
|
|
||||||
case DecimalType:
|
|
||||||
return "FLOAT"
|
|
||||||
case IntegerType:
|
|
||||||
return "INT"
|
|
||||||
case StringType:
|
|
||||||
return "STRING"
|
|
||||||
case BoolType:
|
|
||||||
return "BOOL"
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValueType enums
|
|
||||||
const (
|
|
||||||
NoneType = ValueType(iota)
|
|
||||||
DecimalType
|
|
||||||
IntegerType
|
|
||||||
StringType
|
|
||||||
QuotedStringType
|
|
||||||
BoolType
|
|
||||||
)
|
|
||||||
|
|
||||||
// Value is a union container
|
|
||||||
type Value struct {
|
|
||||||
Type ValueType
|
|
||||||
raw []rune
|
|
||||||
|
|
||||||
integer int64
|
|
||||||
decimal float64
|
|
||||||
boolean bool
|
|
||||||
str string
|
|
||||||
}
|
|
||||||
|
|
||||||
func newValue(t ValueType, base int, raw []rune) (Value, error) {
|
|
||||||
v := Value{
|
|
||||||
Type: t,
|
|
||||||
raw: raw,
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
|
|
||||||
switch t {
|
|
||||||
case DecimalType:
|
|
||||||
v.decimal, err = strconv.ParseFloat(string(raw), 64)
|
|
||||||
case IntegerType:
|
|
||||||
if base != 10 {
|
|
||||||
raw = raw[2:]
|
|
||||||
}
|
|
||||||
|
|
||||||
v.integer, err = strconv.ParseInt(string(raw), base, 64)
|
|
||||||
case StringType:
|
|
||||||
v.str = string(raw)
|
|
||||||
case QuotedStringType:
|
|
||||||
v.str = string(raw[1 : len(raw)-1])
|
|
||||||
case BoolType:
|
|
||||||
v.boolean = runeCompare(v.raw, runesTrue)
|
|
||||||
}
|
|
||||||
|
|
||||||
// issue 2253
|
|
||||||
//
|
|
||||||
// if the value trying to be parsed is too large, then we will use
|
|
||||||
// the 'StringType' and raw value instead.
|
|
||||||
if nerr, ok := err.(*strconv.NumError); ok && nerr.Err == strconv.ErrRange {
|
|
||||||
v.Type = StringType
|
|
||||||
v.str = string(raw)
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append will append values and change the type to a string
|
|
||||||
// type.
|
|
||||||
func (v *Value) Append(tok Token) {
|
|
||||||
r := tok.Raw()
|
|
||||||
if v.Type != QuotedStringType {
|
|
||||||
v.Type = StringType
|
|
||||||
r = tok.raw[1 : len(tok.raw)-1]
|
|
||||||
}
|
|
||||||
if tok.Type() != TokenLit {
|
|
||||||
v.raw = append(v.raw, tok.Raw()...)
|
|
||||||
} else {
|
|
||||||
v.raw = append(v.raw, r...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v Value) String() string {
|
|
||||||
switch v.Type {
|
|
||||||
case DecimalType:
|
|
||||||
return fmt.Sprintf("decimal: %f", v.decimal)
|
|
||||||
case IntegerType:
|
|
||||||
return fmt.Sprintf("integer: %d", v.integer)
|
|
||||||
case StringType:
|
|
||||||
return fmt.Sprintf("string: %s", string(v.raw))
|
|
||||||
case QuotedStringType:
|
|
||||||
return fmt.Sprintf("quoted string: %s", string(v.raw))
|
|
||||||
case BoolType:
|
|
||||||
return fmt.Sprintf("bool: %t", v.boolean)
|
|
||||||
default:
|
|
||||||
return "union not set"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newLitToken(b []rune) (Token, int, error) {
|
|
||||||
n := 0
|
|
||||||
var err error
|
|
||||||
|
|
||||||
token := Token{}
|
|
||||||
if b[0] == '"' {
|
|
||||||
n, err = getStringValue(b)
|
|
||||||
if err != nil {
|
|
||||||
return token, n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
token = newToken(TokenLit, b[:n], QuotedStringType)
|
|
||||||
} else if isNumberValue(b) {
|
|
||||||
var base int
|
|
||||||
base, n, err = getNumericalValue(b)
|
|
||||||
if err != nil {
|
|
||||||
return token, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
value := b[:n]
|
|
||||||
vType := IntegerType
|
|
||||||
if contains(value, '.') || hasExponent(value) {
|
|
||||||
vType = DecimalType
|
|
||||||
}
|
|
||||||
token = newToken(TokenLit, value, vType)
|
|
||||||
token.base = base
|
|
||||||
} else if isBoolValue(b) {
|
|
||||||
n, err = getBoolValue(b)
|
|
||||||
|
|
||||||
token = newToken(TokenLit, b[:n], BoolType)
|
|
||||||
} else {
|
|
||||||
n, err = getValue(b)
|
|
||||||
token = newToken(TokenLit, b[:n], StringType)
|
|
||||||
}
|
|
||||||
|
|
||||||
return token, n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntValue returns an integer value
|
|
||||||
func (v Value) IntValue() int64 {
|
|
||||||
return v.integer
|
|
||||||
}
|
|
||||||
|
|
||||||
// FloatValue returns a float value
|
|
||||||
func (v Value) FloatValue() float64 {
|
|
||||||
return v.decimal
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolValue returns a bool value
|
|
||||||
func (v Value) BoolValue() bool {
|
|
||||||
return v.boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
func isTrimmable(r rune) bool {
|
|
||||||
switch r {
|
|
||||||
case '\n', ' ':
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringValue returns the string value
|
|
||||||
func (v Value) StringValue() string {
|
|
||||||
switch v.Type {
|
|
||||||
case StringType:
|
|
||||||
return strings.TrimFunc(string(v.raw), isTrimmable)
|
|
||||||
case QuotedStringType:
|
|
||||||
// preserve all characters in the quotes
|
|
||||||
return string(removeEscapedCharacters(v.raw[1 : len(v.raw)-1]))
|
|
||||||
default:
|
|
||||||
return strings.TrimFunc(string(v.raw), isTrimmable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func contains(runes []rune, c rune) bool {
|
|
||||||
for i := 0; i < len(runes); i++ {
|
|
||||||
if runes[i] == c {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func runeCompare(v1 []rune, v2 []rune) bool {
|
|
||||||
if len(v1) != len(v2) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0; i < len(v1); i++ {
|
|
||||||
if v1[i] != v2[i] {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
30
vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go
generated
vendored
30
vendor/github.com/aws/aws-sdk-go/internal/ini/newline_token.go
generated
vendored
@ -1,30 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
func isNewline(b []rune) bool {
|
|
||||||
if len(b) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if b[0] == '\n' {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(b) < 2 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return b[0] == '\r' && b[1] == '\n'
|
|
||||||
}
|
|
||||||
|
|
||||||
func newNewlineToken(b []rune) (Token, int, error) {
|
|
||||||
i := 1
|
|
||||||
if b[0] == '\r' && isNewline(b[1:]) {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
if !isNewline([]rune(b[:i])) {
|
|
||||||
return emptyToken, 0, NewParseError("invalid new line token")
|
|
||||||
}
|
|
||||||
|
|
||||||
return newToken(TokenNL, b[:i], NoneType), i, nil
|
|
||||||
}
|
|
152
vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go
generated
vendored
152
vendor/github.com/aws/aws-sdk-go/internal/ini/number_helper.go
generated
vendored
@ -1,152 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
none = numberFormat(iota)
|
|
||||||
binary
|
|
||||||
octal
|
|
||||||
decimal
|
|
||||||
hex
|
|
||||||
exponent
|
|
||||||
)
|
|
||||||
|
|
||||||
type numberFormat int
|
|
||||||
|
|
||||||
// numberHelper is used to dictate what format a number is in
|
|
||||||
// and what to do for negative values. Since -1e-4 is a valid
|
|
||||||
// number, we cannot just simply check for duplicate negatives.
|
|
||||||
type numberHelper struct {
|
|
||||||
numberFormat numberFormat
|
|
||||||
|
|
||||||
negative bool
|
|
||||||
negativeExponent bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b numberHelper) Exists() bool {
|
|
||||||
return b.numberFormat != none
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b numberHelper) IsNegative() bool {
|
|
||||||
return b.negative || b.negativeExponent
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *numberHelper) Determine(c rune) error {
|
|
||||||
if b.Exists() {
|
|
||||||
return NewParseError(fmt.Sprintf("multiple number formats: 0%v", string(c)))
|
|
||||||
}
|
|
||||||
|
|
||||||
switch c {
|
|
||||||
case 'b':
|
|
||||||
b.numberFormat = binary
|
|
||||||
case 'o':
|
|
||||||
b.numberFormat = octal
|
|
||||||
case 'x':
|
|
||||||
b.numberFormat = hex
|
|
||||||
case 'e', 'E':
|
|
||||||
b.numberFormat = exponent
|
|
||||||
case '-':
|
|
||||||
if b.numberFormat != exponent {
|
|
||||||
b.negative = true
|
|
||||||
} else {
|
|
||||||
b.negativeExponent = true
|
|
||||||
}
|
|
||||||
case '.':
|
|
||||||
b.numberFormat = decimal
|
|
||||||
default:
|
|
||||||
return NewParseError(fmt.Sprintf("invalid number character: %v", string(c)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b numberHelper) CorrectByte(c rune) bool {
|
|
||||||
switch {
|
|
||||||
case b.numberFormat == binary:
|
|
||||||
if !isBinaryByte(c) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case b.numberFormat == octal:
|
|
||||||
if !isOctalByte(c) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case b.numberFormat == hex:
|
|
||||||
if !isHexByte(c) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case b.numberFormat == decimal:
|
|
||||||
if !isDigit(c) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case b.numberFormat == exponent:
|
|
||||||
if !isDigit(c) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case b.negativeExponent:
|
|
||||||
if !isDigit(c) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case b.negative:
|
|
||||||
if !isDigit(c) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
if !isDigit(c) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b numberHelper) Base() int {
|
|
||||||
switch b.numberFormat {
|
|
||||||
case binary:
|
|
||||||
return 2
|
|
||||||
case octal:
|
|
||||||
return 8
|
|
||||||
case hex:
|
|
||||||
return 16
|
|
||||||
default:
|
|
||||||
return 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b numberHelper) String() string {
|
|
||||||
buf := bytes.Buffer{}
|
|
||||||
i := 0
|
|
||||||
|
|
||||||
switch b.numberFormat {
|
|
||||||
case binary:
|
|
||||||
i++
|
|
||||||
buf.WriteString(strconv.Itoa(i) + ": binary format\n")
|
|
||||||
case octal:
|
|
||||||
i++
|
|
||||||
buf.WriteString(strconv.Itoa(i) + ": octal format\n")
|
|
||||||
case hex:
|
|
||||||
i++
|
|
||||||
buf.WriteString(strconv.Itoa(i) + ": hex format\n")
|
|
||||||
case exponent:
|
|
||||||
i++
|
|
||||||
buf.WriteString(strconv.Itoa(i) + ": exponent format\n")
|
|
||||||
default:
|
|
||||||
i++
|
|
||||||
buf.WriteString(strconv.Itoa(i) + ": integer format\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.negative {
|
|
||||||
i++
|
|
||||||
buf.WriteString(strconv.Itoa(i) + ": negative format\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.negativeExponent {
|
|
||||||
i++
|
|
||||||
buf.WriteString(strconv.Itoa(i) + ": negative exponent format\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
39
vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go
generated
vendored
39
vendor/github.com/aws/aws-sdk-go/internal/ini/op_tokens.go
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
equalOp = []rune("=")
|
|
||||||
equalColonOp = []rune(":")
|
|
||||||
)
|
|
||||||
|
|
||||||
func isOp(b []rune) bool {
|
|
||||||
if len(b) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
switch b[0] {
|
|
||||||
case '=':
|
|
||||||
return true
|
|
||||||
case ':':
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newOpToken(b []rune) (Token, int, error) {
|
|
||||||
tok := Token{}
|
|
||||||
|
|
||||||
switch b[0] {
|
|
||||||
case '=':
|
|
||||||
tok = newToken(TokenOp, equalOp, NoneType)
|
|
||||||
case ':':
|
|
||||||
tok = newToken(TokenOp, equalColonOp, NoneType)
|
|
||||||
default:
|
|
||||||
return tok, 0, NewParseError(fmt.Sprintf("unexpected op type, %v", b[0]))
|
|
||||||
}
|
|
||||||
return tok, 1, nil
|
|
||||||
}
|
|
43
vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go
generated
vendored
43
vendor/github.com/aws/aws-sdk-go/internal/ini/parse_error.go
generated
vendored
@ -1,43 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ErrCodeParseError is returned when a parsing error
|
|
||||||
// has occurred.
|
|
||||||
ErrCodeParseError = "INIParseError"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ParseError is an error which is returned during any part of
|
|
||||||
// the parsing process.
|
|
||||||
type ParseError struct {
|
|
||||||
msg string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewParseError will return a new ParseError where message
|
|
||||||
// is the description of the error.
|
|
||||||
func NewParseError(message string) *ParseError {
|
|
||||||
return &ParseError{
|
|
||||||
msg: message,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Code will return the ErrCodeParseError
|
|
||||||
func (err *ParseError) Code() string {
|
|
||||||
return ErrCodeParseError
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message returns the error's message
|
|
||||||
func (err *ParseError) Message() string {
|
|
||||||
return err.msg
|
|
||||||
}
|
|
||||||
|
|
||||||
// OrigError return nothing since there will never be any
|
|
||||||
// original error.
|
|
||||||
func (err *ParseError) OrigError() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (err *ParseError) Error() string {
|
|
||||||
return fmt.Sprintf("%s: %s", err.Code(), err.Message())
|
|
||||||
}
|
|
60
vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go
generated
vendored
60
vendor/github.com/aws/aws-sdk-go/internal/ini/parse_stack.go
generated
vendored
@ -1,60 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ParseStack is a stack that contains a container, the stack portion,
|
|
||||||
// and the list which is the list of ASTs that have been successfully
|
|
||||||
// parsed.
|
|
||||||
type ParseStack struct {
|
|
||||||
top int
|
|
||||||
container []AST
|
|
||||||
list []AST
|
|
||||||
index int
|
|
||||||
}
|
|
||||||
|
|
||||||
func newParseStack(sizeContainer, sizeList int) ParseStack {
|
|
||||||
return ParseStack{
|
|
||||||
container: make([]AST, sizeContainer),
|
|
||||||
list: make([]AST, sizeList),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pop will return and truncate the last container element.
|
|
||||||
func (s *ParseStack) Pop() AST {
|
|
||||||
s.top--
|
|
||||||
return s.container[s.top]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Push will add the new AST to the container
|
|
||||||
func (s *ParseStack) Push(ast AST) {
|
|
||||||
s.container[s.top] = ast
|
|
||||||
s.top++
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarkComplete will append the AST to the list of completed statements
|
|
||||||
func (s *ParseStack) MarkComplete(ast AST) {
|
|
||||||
s.list[s.index] = ast
|
|
||||||
s.index++
|
|
||||||
}
|
|
||||||
|
|
||||||
// List will return the completed statements
|
|
||||||
func (s ParseStack) List() []AST {
|
|
||||||
return s.list[:s.index]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Len will return the length of the container
|
|
||||||
func (s *ParseStack) Len() int {
|
|
||||||
return s.top
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s ParseStack) String() string {
|
|
||||||
buf := bytes.Buffer{}
|
|
||||||
for i, node := range s.list {
|
|
||||||
buf.WriteString(fmt.Sprintf("%d: %v\n", i+1, node))
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
41
vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go
generated
vendored
41
vendor/github.com/aws/aws-sdk-go/internal/ini/sep_tokens.go
generated
vendored
@ -1,41 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
emptyRunes = []rune{}
|
|
||||||
)
|
|
||||||
|
|
||||||
func isSep(b []rune) bool {
|
|
||||||
if len(b) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
switch b[0] {
|
|
||||||
case '[', ']':
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
openBrace = []rune("[")
|
|
||||||
closeBrace = []rune("]")
|
|
||||||
)
|
|
||||||
|
|
||||||
func newSepToken(b []rune) (Token, int, error) {
|
|
||||||
tok := Token{}
|
|
||||||
|
|
||||||
switch b[0] {
|
|
||||||
case '[':
|
|
||||||
tok = newToken(TokenSep, openBrace, NoneType)
|
|
||||||
case ']':
|
|
||||||
tok = newToken(TokenSep, closeBrace, NoneType)
|
|
||||||
default:
|
|
||||||
return tok, 0, NewParseError(fmt.Sprintf("unexpected sep type, %v", b[0]))
|
|
||||||
}
|
|
||||||
return tok, 1, nil
|
|
||||||
}
|
|
45
vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go
generated
vendored
45
vendor/github.com/aws/aws-sdk-go/internal/ini/skipper.go
generated
vendored
@ -1,45 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
// skipper is used to skip certain blocks of an ini file.
|
|
||||||
// Currently skipper is used to skip nested blocks of ini
|
|
||||||
// files. See example below
|
|
||||||
//
|
|
||||||
// [ foo ]
|
|
||||||
// nested = ; this section will be skipped
|
|
||||||
// a=b
|
|
||||||
// c=d
|
|
||||||
// bar=baz ; this will be included
|
|
||||||
type skipper struct {
|
|
||||||
shouldSkip bool
|
|
||||||
TokenSet bool
|
|
||||||
prevTok Token
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSkipper() skipper {
|
|
||||||
return skipper{
|
|
||||||
prevTok: emptyToken,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *skipper) ShouldSkip(tok Token) bool {
|
|
||||||
if s.shouldSkip &&
|
|
||||||
s.prevTok.Type() == TokenNL &&
|
|
||||||
tok.Type() != TokenWS {
|
|
||||||
|
|
||||||
s.Continue()
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
s.prevTok = tok
|
|
||||||
|
|
||||||
return s.shouldSkip
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *skipper) Skip() {
|
|
||||||
s.shouldSkip = true
|
|
||||||
s.prevTok = emptyToken
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *skipper) Continue() {
|
|
||||||
s.shouldSkip = false
|
|
||||||
s.prevTok = emptyToken
|
|
||||||
}
|
|
35
vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go
generated
vendored
35
vendor/github.com/aws/aws-sdk-go/internal/ini/statement.go
generated
vendored
@ -1,35 +0,0 @@
|
|||||||
package ini
|
|
||||||
|
|
||||||
// Statement is an empty AST mostly used for transitioning states.
|
|
||||||
func newStatement() AST {
|
|
||||||
return newAST(ASTKindStatement, AST{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// SectionStatement represents a section AST
|
|
||||||
func newSectionStatement(tok Token) AST {
|
|
||||||
return newASTWithRootToken(ASTKindSectionStatement, tok)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExprStatement represents a completed expression AST
|
|
||||||
func newExprStatement(ast AST) AST {
|
|
||||||
return newAST(ASTKindExprStatement, ast)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommentStatement represents a comment in the ini defintion.
|
|
||||||
//
|
|
||||||
// grammar:
|
|
||||||
// comment -> #comment' | ;comment'
|
|
||||||
// comment' -> epsilon | value
|
|
||||||
func newCommentStatement(tok Token) AST {
|
|
||||||
return newAST(ASTKindCommentStatement, newExpression(tok))
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompletedSectionStatement represents a completed section
|
|
||||||
func newCompletedSectionStatement(ast AST) AST {
|
|
||||||
return newAST(ASTKindCompletedSectionStatement, ast)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SkipStatement is used to skip whole statements
|
|
||||||
func newSkipStatement(ast AST) AST {
|
|
||||||
return newAST(ASTKindSkipStatement, ast)
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user