Signed-off-by: Laura Frank <ljfrank@gmail.com>
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
| ... | ... |
@@ -127,7 +127,7 @@ clone git github.com/tinylib/msgp 75ee40d2601edf122ef667e2a07d600d4c44490c |
| 127 | 127 |
clone git gopkg.in/fsnotify.v1 v1.2.11 |
| 128 | 128 |
|
| 129 | 129 |
# awslogs deps |
| 130 |
-clone git github.com/aws/aws-sdk-go v1.1.30 |
|
| 130 |
+clone git github.com/aws/aws-sdk-go v1.4.22 |
|
| 131 | 131 |
clone git github.com/go-ini/ini 060d7da055ba6ec5ea7a31f116332fe5efa04ce0 |
| 132 | 132 |
clone git github.com/jmespath/go-jmespath 0b12d6b521d83fc7f755e7cfc1b1fbdd35a01a74 |
| 133 | 133 |
|
| ... | ... |
@@ -44,7 +44,7 @@ type Error interface {
|
| 44 | 44 |
|
| 45 | 45 |
// BatchError is a batch of errors which also wraps lower level errors with |
| 46 | 46 |
// code, message, and original errors. Calling Error() will include all errors |
| 47 |
-// that occured in the batch. |
|
| 47 |
+// that occurred in the batch. |
|
| 48 | 48 |
// |
| 49 | 49 |
// Deprecated: Replaced with BatchedErrors. Only defined for backwards |
| 50 | 50 |
// compatibility. |
| ... | ... |
@@ -64,7 +64,7 @@ type BatchError interface {
|
| 64 | 64 |
|
| 65 | 65 |
// BatchedErrors is a batch of errors which also wraps lower level errors with |
| 66 | 66 |
// code, message, and original errors. Calling Error() will include all errors |
| 67 |
-// that occured in the batch. |
|
| 67 |
+// that occurred in the batch. |
|
| 68 | 68 |
// |
| 69 | 69 |
// Replaces BatchError |
| 70 | 70 |
type BatchedErrors interface {
|
| ... | ... |
@@ -3,6 +3,7 @@ package awsutil |
| 3 | 3 |
import ( |
| 4 | 4 |
"io" |
| 5 | 5 |
"reflect" |
| 6 |
+ "time" |
|
| 6 | 7 |
) |
| 7 | 8 |
|
| 8 | 9 |
// Copy deeply copies a src structure to dst. Useful for copying request and |
| ... | ... |
@@ -49,7 +50,14 @@ func rcopy(dst, src reflect.Value, root bool) {
|
| 49 | 49 |
} else {
|
| 50 | 50 |
e := src.Type().Elem() |
| 51 | 51 |
if dst.CanSet() && !src.IsNil() {
|
| 52 |
- dst.Set(reflect.New(e)) |
|
| 52 |
+ if _, ok := src.Interface().(*time.Time); !ok {
|
|
| 53 |
+ dst.Set(reflect.New(e)) |
|
| 54 |
+ } else {
|
|
| 55 |
+ tempValue := reflect.New(e) |
|
| 56 |
+ tempValue.Elem().Set(src.Elem()) |
|
| 57 |
+ // Sets time.Time's unexported values |
|
| 58 |
+ dst.Set(tempValue) |
|
| 59 |
+ } |
|
| 53 | 60 |
} |
| 54 | 61 |
if src.Elem().IsValid() {
|
| 55 | 62 |
// Keep the current root state since the depth hasn't changed |
| ... | ... |
@@ -106,8 +106,8 @@ func rValuesAtPath(v interface{}, path string, createPath, caseSensitive, nilTer
|
| 106 | 106 |
|
| 107 | 107 |
if indexStar || index != nil {
|
| 108 | 108 |
nextvals = []reflect.Value{}
|
| 109 |
- for _, value := range values {
|
|
| 110 |
- value := reflect.Indirect(value) |
|
| 109 |
+ for _, valItem := range values {
|
|
| 110 |
+ value := reflect.Indirect(valItem) |
|
| 111 | 111 |
if value.Kind() != reflect.Slice {
|
| 112 | 112 |
continue |
| 113 | 113 |
} |
| ... | ... |
@@ -2,7 +2,6 @@ package client |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "io/ioutil" |
|
| 6 | 5 |
"net/http/httputil" |
| 7 | 6 |
|
| 8 | 7 |
"github.com/aws/aws-sdk-go/aws" |
| ... | ... |
@@ -87,16 +86,24 @@ const logReqMsg = `DEBUG: Request %s/%s Details: |
| 87 | 87 |
%s |
| 88 | 88 |
-----------------------------------------------------` |
| 89 | 89 |
|
| 90 |
+const logReqErrMsg = `DEBUG ERROR: Request %s/%s: |
|
| 91 |
+---[ REQUEST DUMP ERROR ]----------------------------- |
|
| 92 |
+%s |
|
| 93 |
+-----------------------------------------------------` |
|
| 94 |
+ |
|
| 90 | 95 |
func logRequest(r *request.Request) {
|
| 91 | 96 |
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) |
| 92 |
- dumpedBody, _ := httputil.DumpRequestOut(r.HTTPRequest, logBody) |
|
| 97 |
+ dumpedBody, err := httputil.DumpRequestOut(r.HTTPRequest, logBody) |
|
| 98 |
+ if err != nil {
|
|
| 99 |
+ r.Config.Logger.Log(fmt.Sprintf(logReqErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) |
|
| 100 |
+ return |
|
| 101 |
+ } |
|
| 93 | 102 |
|
| 94 | 103 |
if logBody {
|
| 95 | 104 |
// Reset the request body because dumpRequest will re-wrap the r.HTTPRequest's |
| 96 | 105 |
// Body as a NoOpCloser and will not be reset after read by the HTTP |
| 97 | 106 |
// client reader. |
| 98 |
- r.Body.Seek(r.BodyStart, 0) |
|
| 99 |
- r.HTTPRequest.Body = ioutil.NopCloser(r.Body) |
|
| 107 |
+ r.ResetBody() |
|
| 100 | 108 |
} |
| 101 | 109 |
|
| 102 | 110 |
r.Config.Logger.Log(fmt.Sprintf(logReqMsg, r.ClientInfo.ServiceName, r.Operation.Name, string(dumpedBody))) |
| ... | ... |
@@ -107,11 +114,21 @@ const logRespMsg = `DEBUG: Response %s/%s Details: |
| 107 | 107 |
%s |
| 108 | 108 |
-----------------------------------------------------` |
| 109 | 109 |
|
| 110 |
+const logRespErrMsg = `DEBUG ERROR: Response %s/%s: |
|
| 111 |
+---[ RESPONSE DUMP ERROR ]----------------------------- |
|
| 112 |
+%s |
|
| 113 |
+-----------------------------------------------------` |
|
| 114 |
+ |
|
| 110 | 115 |
func logResponse(r *request.Request) {
|
| 111 | 116 |
var msg = "no response data" |
| 112 | 117 |
if r.HTTPResponse != nil {
|
| 113 | 118 |
logBody := r.Config.LogLevel.Matches(aws.LogDebugWithHTTPBody) |
| 114 |
- dumpedBody, _ := httputil.DumpResponse(r.HTTPResponse, logBody) |
|
| 119 |
+ dumpedBody, err := httputil.DumpResponse(r.HTTPResponse, logBody) |
|
| 120 |
+ if err != nil {
|
|
| 121 |
+ r.Config.Logger.Log(fmt.Sprintf(logRespErrMsg, r.ClientInfo.ServiceName, r.Operation.Name, err)) |
|
| 122 |
+ return |
|
| 123 |
+ } |
|
| 124 |
+ |
|
| 115 | 125 |
msg = string(dumpedBody) |
| 116 | 126 |
} else if r.Error != nil {
|
| 117 | 127 |
msg = r.Error.Error() |
| ... | ... |
@@ -7,24 +7,36 @@ import ( |
| 7 | 7 |
"github.com/aws/aws-sdk-go/aws/credentials" |
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 |
-// UseServiceDefaultRetries instructs the config to use the service's own default |
|
| 11 |
-// number of retries. This will be the default action if Config.MaxRetries |
|
| 12 |
-// is nil also. |
|
| 10 |
+// UseServiceDefaultRetries instructs the config to use the service's own |
|
| 11 |
+// default number of retries. This will be the default action if |
|
| 12 |
+// Config.MaxRetries is nil also. |
|
| 13 | 13 |
const UseServiceDefaultRetries = -1 |
| 14 | 14 |
|
| 15 |
-// RequestRetryer is an alias for a type that implements the request.Retryer interface. |
|
| 15 |
+// RequestRetryer is an alias for a type that implements the request.Retryer |
|
| 16 |
+// interface. |
|
| 16 | 17 |
type RequestRetryer interface{}
|
| 17 | 18 |
|
| 18 | 19 |
// A Config provides service configuration for service clients. By default, |
| 19 |
-// all clients will use the {defaults.DefaultConfig} structure.
|
|
| 20 |
+// all clients will use the defaults.DefaultConfig tructure. |
|
| 21 |
+// |
|
| 22 |
+// // Create Session with MaxRetry configuration to be shared by multiple |
|
| 23 |
+// // service clients. |
|
| 24 |
+// sess, err := session.NewSession(&aws.Config{
|
|
| 25 |
+// MaxRetries: aws.Int(3), |
|
| 26 |
+// }) |
|
| 27 |
+// |
|
| 28 |
+// // Create S3 service client with a specific Region. |
|
| 29 |
+// svc := s3.New(sess, &aws.Config{
|
|
| 30 |
+// Region: aws.String("us-west-2"),
|
|
| 31 |
+// }) |
|
| 20 | 32 |
type Config struct {
|
| 21 | 33 |
// Enables verbose error printing of all credential chain errors. |
| 22 |
- // Should be used when wanting to see all errors while attempting to retreive |
|
| 23 |
- // credentials. |
|
| 34 |
+ // Should be used when wanting to see all errors while attempting to |
|
| 35 |
+ // retrieve credentials. |
|
| 24 | 36 |
CredentialsChainVerboseErrors *bool |
| 25 | 37 |
|
| 26 |
- // The credentials object to use when signing requests. Defaults to |
|
| 27 |
- // a chain of credential providers to search for credentials in environment |
|
| 38 |
+ // The credentials object to use when signing requests. Defaults to a |
|
| 39 |
+ // chain of credential providers to search for credentials in environment |
|
| 28 | 40 |
// variables, shared credential file, and EC2 Instance Roles. |
| 29 | 41 |
Credentials *credentials.Credentials |
| 30 | 42 |
|
| ... | ... |
@@ -63,11 +75,12 @@ type Config struct {
|
| 63 | 63 |
Logger Logger |
| 64 | 64 |
|
| 65 | 65 |
// The maximum number of times that a request will be retried for failures. |
| 66 |
- // Defaults to -1, which defers the max retry setting to the service specific |
|
| 67 |
- // configuration. |
|
| 66 |
+ // Defaults to -1, which defers the max retry setting to the service |
|
| 67 |
+ // specific configuration. |
|
| 68 | 68 |
MaxRetries *int |
| 69 | 69 |
|
| 70 |
- // Retryer guides how HTTP requests should be retried in case of recoverable failures. |
|
| 70 |
+ // Retryer guides how HTTP requests should be retried in case of |
|
| 71 |
+ // recoverable failures. |
|
| 71 | 72 |
// |
| 72 | 73 |
// When nil or the value does not implement the request.Retryer interface, |
| 73 | 74 |
// the request.DefaultRetryer will be used. |
| ... | ... |
@@ -82,8 +95,8 @@ type Config struct {
|
| 82 | 82 |
// |
| 83 | 83 |
Retryer RequestRetryer |
| 84 | 84 |
|
| 85 |
- // Disables semantic parameter validation, which validates input for missing |
|
| 86 |
- // required fields and/or other semantic request input errors. |
|
| 85 |
+ // Disables semantic parameter validation, which validates input for |
|
| 86 |
+ // missing required fields and/or other semantic request input errors. |
|
| 87 | 87 |
DisableParamValidation *bool |
| 88 | 88 |
|
| 89 | 89 |
// Disables the computation of request and response checksums, e.g., |
| ... | ... |
@@ -91,8 +104,8 @@ type Config struct {
|
| 91 | 91 |
DisableComputeChecksums *bool |
| 92 | 92 |
|
| 93 | 93 |
// Set this to `true` to force the request to use path-style addressing, |
| 94 |
- // i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client will |
|
| 95 |
- // use virtual hosted bucket addressing when possible |
|
| 94 |
+ // i.e., `http://s3.amazonaws.com/BUCKET/KEY`. By default, the S3 client |
|
| 95 |
+ // will use virtual hosted bucket addressing when possible |
|
| 96 | 96 |
// (`http://BUCKET.s3.amazonaws.com/KEY`). |
| 97 | 97 |
// |
| 98 | 98 |
// @note This configuration option is specific to the Amazon S3 service. |
| ... | ... |
@@ -109,44 +122,81 @@ type Config struct {
|
| 109 | 109 |
// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html |
| 110 | 110 |
// |
| 111 | 111 |
// 100-Continue is only enabled for Go 1.6 and above. See `http.Transport`'s |
| 112 |
- // `ExpectContinueTimeout` for information on adjusting the continue wait timeout. |
|
| 113 |
- // https://golang.org/pkg/net/http/#Transport |
|
| 112 |
+ // `ExpectContinueTimeout` for information on adjusting the continue wait |
|
| 113 |
+ // timeout. https://golang.org/pkg/net/http/#Transport |
|
| 114 | 114 |
// |
| 115 |
- // You should use this flag to disble 100-Continue if you experiance issues |
|
| 116 |
- // with proxies or thrid party S3 compatible services. |
|
| 115 |
+ // You should use this flag to disble 100-Continue if you experience issues |
|
| 116 |
+ // with proxies or third party S3 compatible services. |
|
| 117 | 117 |
S3Disable100Continue *bool |
| 118 | 118 |
|
| 119 |
- // Set this to `true` to enable S3 Accelerate feature. For all operations compatible |
|
| 120 |
- // with S3 Accelerate will use the accelerate endpoint for requests. Requests not compatible |
|
| 121 |
- // will fall back to normal S3 requests. |
|
| 119 |
+ // Set this to `true` to enable S3 Accelerate feature. For all operations |
|
| 120 |
+ // compatible with S3 Accelerate will use the accelerate endpoint for |
|
| 121 |
+ // requests. Requests not compatible will fall back to normal S3 requests. |
|
| 122 | 122 |
// |
| 123 |
- // The bucket must be enable for accelerate to be used with S3 client with accelerate |
|
| 124 |
- // enabled. If the bucket is not enabled for accelerate an error will be returned. |
|
| 125 |
- // The bucket name must be DNS compatible to also work with accelerate. |
|
| 123 |
+ // The bucket must be enable for accelerate to be used with S3 client with |
|
| 124 |
+ // accelerate enabled. If the bucket is not enabled for accelerate an error |
|
| 125 |
+ // will be returned. The bucket name must be DNS compatible to also work |
|
| 126 |
+ // with accelerate. |
|
| 126 | 127 |
S3UseAccelerate *bool |
| 127 | 128 |
|
| 128 | 129 |
// Set this to `true` to disable the EC2Metadata client from overriding the |
| 129 |
- // default http.Client's Timeout. This is helpful if you do not want the EC2Metadata |
|
| 130 |
- // client to create a new http.Client. This options is only meaningful if you're not |
|
| 131 |
- // already using a custom HTTP client with the SDK. Enabled by default. |
|
| 130 |
+ // default http.Client's Timeout. This is helpful if you do not want the |
|
| 131 |
+ // EC2Metadata client to create a new http.Client. This options is only |
|
| 132 |
+ // meaningful if you're not already using a custom HTTP client with the |
|
| 133 |
+ // SDK. Enabled by default. |
|
| 132 | 134 |
// |
| 133 |
- // Must be set and provided to the session.New() in order to disable the EC2Metadata |
|
| 134 |
- // overriding the timeout for default credentials chain. |
|
| 135 |
+ // Must be set and provided to the session.NewSession() in order to disable |
|
| 136 |
+ // the EC2Metadata overriding the timeout for default credentials chain. |
|
| 135 | 137 |
// |
| 136 | 138 |
// Example: |
| 137 |
- // sess := session.New(aws.NewConfig().WithEC2MetadataDiableTimeoutOverride(true)) |
|
| 139 |
+ // sess, err := session.NewSession(aws.NewConfig().WithEC2MetadataDiableTimeoutOverride(true)) |
|
| 140 |
+ // |
|
| 138 | 141 |
// svc := s3.New(sess) |
| 139 | 142 |
// |
| 140 | 143 |
EC2MetadataDisableTimeoutOverride *bool |
| 141 | 144 |
|
| 145 |
+ // Instructs the endpiont to be generated for a service client to |
|
| 146 |
+ // be the dual stack endpoint. The dual stack endpoint will support |
|
| 147 |
+ // both IPv4 and IPv6 addressing. |
|
| 148 |
+ // |
|
| 149 |
+ // Setting this for a service which does not support dual stack will fail |
|
| 150 |
+ // to make requets. It is not recommended to set this value on the session |
|
| 151 |
+ // as it will apply to all service clients created with the session. Even |
|
| 152 |
+ // services which don't support dual stack endpoints. |
|
| 153 |
+ // |
|
| 154 |
+ // If the Endpoint config value is also provided the UseDualStack flag |
|
| 155 |
+ // will be ignored. |
|
| 156 |
+ // |
|
| 157 |
+ // Only supported with. |
|
| 158 |
+ // |
|
| 159 |
+ // sess, err := session.NewSession() |
|
| 160 |
+ // |
|
| 161 |
+ // svc := s3.New(sess, &aws.Config{
|
|
| 162 |
+ // UseDualStack: aws.Bool(true), |
|
| 163 |
+ // }) |
|
| 164 |
+ UseDualStack *bool |
|
| 165 |
+ |
|
| 166 |
+ // SleepDelay is an override for the func the SDK will call when sleeping |
|
| 167 |
+ // during the lifecycle of a request. Specifically this will be used for |
|
| 168 |
+ // request delays. This value should only be used for testing. To adjust |
|
| 169 |
+ // the delay of a request see the aws/client.DefaultRetryer and |
|
| 170 |
+ // aws/request.Retryer. |
|
| 142 | 171 |
SleepDelay func(time.Duration) |
| 143 | 172 |
} |
| 144 | 173 |
|
| 145 |
-// NewConfig returns a new Config pointer that can be chained with builder methods to |
|
| 146 |
-// set multiple configuration values inline without using pointers. |
|
| 174 |
+// NewConfig returns a new Config pointer that can be chained with builder |
|
| 175 |
+// methods to set multiple configuration values inline without using pointers. |
|
| 147 | 176 |
// |
| 148 |
-// svc := s3.New(aws.NewConfig().WithRegion("us-west-2").WithMaxRetries(10))
|
|
| 177 |
+// // Create Session with MaxRetry configuration to be shared by multiple |
|
| 178 |
+// // service clients. |
|
| 179 |
+// sess, err := session.NewSession(aws.NewConfig(). |
|
| 180 |
+// WithMaxRetries(3), |
|
| 181 |
+// ) |
|
| 149 | 182 |
// |
| 183 |
+// // Create S3 service client with a specific Region. |
|
| 184 |
+// svc := s3.New(sess, aws.NewConfig(). |
|
| 185 |
+// WithRegion("us-west-2"),
|
|
| 186 |
+// ) |
|
| 150 | 187 |
func NewConfig() *Config {
|
| 151 | 188 |
return &Config{}
|
| 152 | 189 |
} |
| ... | ... |
@@ -249,6 +299,13 @@ func (c *Config) WithS3UseAccelerate(enable bool) *Config {
|
| 249 | 249 |
return c |
| 250 | 250 |
} |
| 251 | 251 |
|
| 252 |
+// WithUseDualStack sets a config UseDualStack value returning a Config |
|
| 253 |
+// pointer for chaining. |
|
| 254 |
+func (c *Config) WithUseDualStack(enable bool) *Config {
|
|
| 255 |
+ c.UseDualStack = &enable |
|
| 256 |
+ return c |
|
| 257 |
+} |
|
| 258 |
+ |
|
| 252 | 259 |
// WithEC2MetadataDisableTimeoutOverride sets a config EC2MetadataDisableTimeoutOverride value |
| 253 | 260 |
// returning a Config pointer for chaining. |
| 254 | 261 |
func (c *Config) WithEC2MetadataDisableTimeoutOverride(enable bool) *Config {
|
| ... | ... |
@@ -335,6 +392,10 @@ func mergeInConfig(dst *Config, other *Config) {
|
| 335 | 335 |
dst.S3UseAccelerate = other.S3UseAccelerate |
| 336 | 336 |
} |
| 337 | 337 |
|
| 338 |
+ if other.UseDualStack != nil {
|
|
| 339 |
+ dst.UseDualStack = other.UseDualStack |
|
| 340 |
+ } |
|
| 341 |
+ |
|
| 338 | 342 |
if other.EC2MetadataDisableTimeoutOverride != nil {
|
| 339 | 343 |
dst.EC2MetadataDisableTimeoutOverride = other.EC2MetadataDisableTimeoutOverride |
| 340 | 344 |
} |
| ... | ... |
@@ -2,7 +2,7 @@ package aws |
| 2 | 2 |
|
| 3 | 3 |
import "time" |
| 4 | 4 |
|
| 5 |
-// String returns a pointer to of the string value passed in. |
|
| 5 |
+// String returns a pointer to the string value passed in. |
|
| 6 | 6 |
func String(v string) *string {
|
| 7 | 7 |
return &v |
| 8 | 8 |
} |
| ... | ... |
@@ -61,7 +61,7 @@ func StringValueMap(src map[string]*string) map[string]string {
|
| 61 | 61 |
return dst |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 |
-// Bool returns a pointer to of the bool value passed in. |
|
| 64 |
+// Bool returns a pointer to the bool value passed in. |
|
| 65 | 65 |
func Bool(v bool) *bool {
|
| 66 | 66 |
return &v |
| 67 | 67 |
} |
| ... | ... |
@@ -120,7 +120,7 @@ func BoolValueMap(src map[string]*bool) map[string]bool {
|
| 120 | 120 |
return dst |
| 121 | 121 |
} |
| 122 | 122 |
|
| 123 |
-// Int returns a pointer to of the int value passed in. |
|
| 123 |
+// Int returns a pointer to the int value passed in. |
|
| 124 | 124 |
func Int(v int) *int {
|
| 125 | 125 |
return &v |
| 126 | 126 |
} |
| ... | ... |
@@ -179,7 +179,7 @@ func IntValueMap(src map[string]*int) map[string]int {
|
| 179 | 179 |
return dst |
| 180 | 180 |
} |
| 181 | 181 |
|
| 182 |
-// Int64 returns a pointer to of the int64 value passed in. |
|
| 182 |
+// Int64 returns a pointer to the int64 value passed in. |
|
| 183 | 183 |
func Int64(v int64) *int64 {
|
| 184 | 184 |
return &v |
| 185 | 185 |
} |
| ... | ... |
@@ -238,7 +238,7 @@ func Int64ValueMap(src map[string]*int64) map[string]int64 {
|
| 238 | 238 |
return dst |
| 239 | 239 |
} |
| 240 | 240 |
|
| 241 |
-// Float64 returns a pointer to of the float64 value passed in. |
|
| 241 |
+// Float64 returns a pointer to the float64 value passed in. |
|
| 242 | 242 |
func Float64(v float64) *float64 {
|
| 243 | 243 |
return &v |
| 244 | 244 |
} |
| ... | ... |
@@ -297,7 +297,7 @@ func Float64ValueMap(src map[string]*float64) map[string]float64 {
|
| 297 | 297 |
return dst |
| 298 | 298 |
} |
| 299 | 299 |
|
| 300 |
-// Time returns a pointer to of the time.Time value passed in. |
|
| 300 |
+// Time returns a pointer to the time.Time value passed in. |
|
| 301 | 301 |
func Time(v time.Time) *time.Time {
|
| 302 | 302 |
return &v |
| 303 | 303 |
} |
| ... | ... |
@@ -10,9 +10,11 @@ import ( |
| 10 | 10 |
"regexp" |
| 11 | 11 |
"runtime" |
| 12 | 12 |
"strconv" |
| 13 |
+ "time" |
|
| 13 | 14 |
|
| 14 | 15 |
"github.com/aws/aws-sdk-go/aws" |
| 15 | 16 |
"github.com/aws/aws-sdk-go/aws/awserr" |
| 17 |
+ "github.com/aws/aws-sdk-go/aws/credentials" |
|
| 16 | 18 |
"github.com/aws/aws-sdk-go/aws/request" |
| 17 | 19 |
) |
| 18 | 20 |
|
| ... | ... |
@@ -67,6 +69,34 @@ var SDKVersionUserAgentHandler = request.NamedHandler{
|
| 67 | 67 |
|
| 68 | 68 |
var reStatusCode = regexp.MustCompile(`^(\d{3})`)
|
| 69 | 69 |
|
| 70 |
+// ValidateReqSigHandler is a request handler to ensure that the request's |
|
| 71 |
+// signature doesn't expire before it is sent. This can happen when a request |
|
| 72 |
+// is built and signed signficantly before it is sent. Or signficant delays |
|
| 73 |
+// occur whne retrying requests that would cause the signature to expire. |
|
| 74 |
+var ValidateReqSigHandler = request.NamedHandler{
|
|
| 75 |
+ Name: "core.ValidateReqSigHandler", |
|
| 76 |
+ Fn: func(r *request.Request) {
|
|
| 77 |
+ // Unsigned requests are not signed |
|
| 78 |
+ if r.Config.Credentials == credentials.AnonymousCredentials {
|
|
| 79 |
+ return |
|
| 80 |
+ } |
|
| 81 |
+ |
|
| 82 |
+ signedTime := r.Time |
|
| 83 |
+ if !r.LastSignedAt.IsZero() {
|
|
| 84 |
+ signedTime = r.LastSignedAt |
|
| 85 |
+ } |
|
| 86 |
+ |
|
| 87 |
+ // 10 minutes to allow for some clock skew/delays in transmission. |
|
| 88 |
+ // Would be improved with aws/aws-sdk-go#423 |
|
| 89 |
+ if signedTime.Add(10 * time.Minute).After(time.Now()) {
|
|
| 90 |
+ return |
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 93 |
+ fmt.Println("request expired, resigning")
|
|
| 94 |
+ r.Sign() |
|
| 95 |
+ }, |
|
| 96 |
+} |
|
| 97 |
+ |
|
| 70 | 98 |
// SendHandler is a request handler to send service request using HTTP client. |
| 71 | 99 |
var SendHandler = request.NamedHandler{Name: "core.SendHandler", Fn: func(r *request.Request) {
|
| 72 | 100 |
var err error |
| ... | ... |
@@ -34,7 +34,7 @@ var ( |
| 34 | 34 |
// |
| 35 | 35 |
// Example of ChainProvider to be used with an EnvProvider and EC2RoleProvider. |
| 36 | 36 |
// In this example EnvProvider will first check if any credentials are available |
| 37 |
-// vai the environment variables. If there are none ChainProvider will check |
|
| 37 |
+// via the environment variables. If there are none ChainProvider will check |
|
| 38 | 38 |
// the next Provider in the list, EC2RoleProvider in this case. If EC2RoleProvider |
| 39 | 39 |
// does not return any credentials ChainProvider will return the error |
| 40 | 40 |
// ErrNoValidProvidersFoundInChain |
| 41 | 41 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,191 @@ |
| 0 |
+// Package endpointcreds provides support for retrieving credentials from an |
|
| 1 |
+// arbitrary HTTP endpoint. |
|
| 2 |
+// |
|
| 3 |
+// The credentials endpoint Provider can receive both static and refreshable |
|
| 4 |
+// credentials that will expire. Credentials are static when an "Expiration" |
|
| 5 |
+// value is not provided in the endpoint's response. |
|
| 6 |
+// |
|
| 7 |
+// Static credentials will never expire once they have been retrieved. The format |
|
| 8 |
+// of the static credentials response: |
|
| 9 |
+// {
|
|
| 10 |
+// "AccessKeyId" : "MUA...", |
|
| 11 |
+// "SecretAccessKey" : "/7PC5om....", |
|
| 12 |
+// } |
|
| 13 |
+// |
|
| 14 |
+// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration |
|
| 15 |
+// value in the response. The format of the refreshable credentials response: |
|
| 16 |
+// {
|
|
| 17 |
+// "AccessKeyId" : "MUA...", |
|
| 18 |
+// "SecretAccessKey" : "/7PC5om....", |
|
| 19 |
+// "Token" : "AQoDY....=", |
|
| 20 |
+// "Expiration" : "2016-02-25T06:03:31Z" |
|
| 21 |
+// } |
|
| 22 |
+// |
|
| 23 |
+// Errors should be returned in the following format and only returned with 400 |
|
| 24 |
+// or 500 HTTP status codes. |
|
| 25 |
+// {
|
|
| 26 |
+// "code": "ErrorCode", |
|
| 27 |
+// "message": "Helpful error message." |
|
| 28 |
+// } |
|
| 29 |
+package endpointcreds |
|
| 30 |
+ |
|
| 31 |
+import ( |
|
| 32 |
+ "encoding/json" |
|
| 33 |
+ "time" |
|
| 34 |
+ |
|
| 35 |
+ "github.com/aws/aws-sdk-go/aws" |
|
| 36 |
+ "github.com/aws/aws-sdk-go/aws/awserr" |
|
| 37 |
+ "github.com/aws/aws-sdk-go/aws/client" |
|
| 38 |
+ "github.com/aws/aws-sdk-go/aws/client/metadata" |
|
| 39 |
+ "github.com/aws/aws-sdk-go/aws/credentials" |
|
| 40 |
+ "github.com/aws/aws-sdk-go/aws/request" |
|
| 41 |
+) |
|
| 42 |
+ |
|
| 43 |
+// ProviderName is the name of the credentials provider. |
|
| 44 |
+const ProviderName = `CredentialsEndpointProvider` |
|
| 45 |
+ |
|
| 46 |
+// Provider satisfies the credentials.Provider interface, and is a client to |
|
| 47 |
+// retrieve credentials from an arbitrary endpoint. |
|
| 48 |
+type Provider struct {
|
|
| 49 |
+ staticCreds bool |
|
| 50 |
+ credentials.Expiry |
|
| 51 |
+ |
|
| 52 |
+ // Requires a AWS Client to make HTTP requests to the endpoint with. |
|
| 53 |
+ // the Endpoint the request will be made to is provided by the aws.Config's |
|
| 54 |
+ // Endpoint value. |
|
| 55 |
+ Client *client.Client |
|
| 56 |
+ |
|
| 57 |
+ // ExpiryWindow will allow the credentials to trigger refreshing prior to |
|
| 58 |
+ // the credentials actually expiring. This is beneficial so race conditions |
|
| 59 |
+ // with expiring credentials do not cause request to fail unexpectedly |
|
| 60 |
+ // due to ExpiredTokenException exceptions. |
|
| 61 |
+ // |
|
| 62 |
+ // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true |
|
| 63 |
+ // 10 seconds before the credentials are actually expired. |
|
| 64 |
+ // |
|
| 65 |
+ // If ExpiryWindow is 0 or less it will be ignored. |
|
| 66 |
+ ExpiryWindow time.Duration |
|
| 67 |
+} |
|
| 68 |
+ |
|
| 69 |
+// NewProviderClient returns a credentials Provider for retrieving AWS credentials |
|
| 70 |
+// from arbitrary endpoint. |
|
| 71 |
+func NewProviderClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) credentials.Provider {
|
|
| 72 |
+ p := &Provider{
|
|
| 73 |
+ Client: client.New( |
|
| 74 |
+ cfg, |
|
| 75 |
+ metadata.ClientInfo{
|
|
| 76 |
+ ServiceName: "CredentialsEndpoint", |
|
| 77 |
+ Endpoint: endpoint, |
|
| 78 |
+ }, |
|
| 79 |
+ handlers, |
|
| 80 |
+ ), |
|
| 81 |
+ } |
|
| 82 |
+ |
|
| 83 |
+ p.Client.Handlers.Unmarshal.PushBack(unmarshalHandler) |
|
| 84 |
+ p.Client.Handlers.UnmarshalError.PushBack(unmarshalError) |
|
| 85 |
+ p.Client.Handlers.Validate.Clear() |
|
| 86 |
+ p.Client.Handlers.Validate.PushBack(validateEndpointHandler) |
|
| 87 |
+ |
|
| 88 |
+ for _, option := range options {
|
|
| 89 |
+ option(p) |
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ return p |
|
| 93 |
+} |
|
| 94 |
+ |
|
| 95 |
+// NewCredentialsClient returns a Credentials wrapper for retrieving credentials |
|
| 96 |
+// from an arbitrary endpoint concurrently. The client will request the |
|
| 97 |
+func NewCredentialsClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) *credentials.Credentials {
|
|
| 98 |
+ return credentials.NewCredentials(NewProviderClient(cfg, handlers, endpoint, options...)) |
|
| 99 |
+} |
|
| 100 |
+ |
|
| 101 |
+// IsExpired returns true if the credentials retrieved are expired, or not yet |
|
| 102 |
+// retrieved. |
|
| 103 |
+func (p *Provider) IsExpired() bool {
|
|
| 104 |
+ if p.staticCreds {
|
|
| 105 |
+ return false |
|
| 106 |
+ } |
|
| 107 |
+ return p.Expiry.IsExpired() |
|
| 108 |
+} |
|
| 109 |
+ |
|
| 110 |
+// Retrieve will attempt to request the credentials from the endpoint the Provider |
|
| 111 |
+// was configured for. And error will be returned if the retrieval fails. |
|
| 112 |
+func (p *Provider) Retrieve() (credentials.Value, error) {
|
|
| 113 |
+ resp, err := p.getCredentials() |
|
| 114 |
+ if err != nil {
|
|
| 115 |
+ return credentials.Value{ProviderName: ProviderName},
|
|
| 116 |
+ awserr.New("CredentialsEndpointError", "failed to load credentials", err)
|
|
| 117 |
+ } |
|
| 118 |
+ |
|
| 119 |
+ if resp.Expiration != nil {
|
|
| 120 |
+ p.SetExpiration(*resp.Expiration, p.ExpiryWindow) |
|
| 121 |
+ } else {
|
|
| 122 |
+ p.staticCreds = true |
|
| 123 |
+ } |
|
| 124 |
+ |
|
| 125 |
+ return credentials.Value{
|
|
| 126 |
+ AccessKeyID: resp.AccessKeyID, |
|
| 127 |
+ SecretAccessKey: resp.SecretAccessKey, |
|
| 128 |
+ SessionToken: resp.Token, |
|
| 129 |
+ ProviderName: ProviderName, |
|
| 130 |
+ }, nil |
|
| 131 |
+} |
|
| 132 |
+ |
|
| 133 |
+type getCredentialsOutput struct {
|
|
| 134 |
+ Expiration *time.Time |
|
| 135 |
+ AccessKeyID string |
|
| 136 |
+ SecretAccessKey string |
|
| 137 |
+ Token string |
|
| 138 |
+} |
|
| 139 |
+ |
|
| 140 |
+type errorOutput struct {
|
|
| 141 |
+ Code string `json:"code"` |
|
| 142 |
+ Message string `json:"message"` |
|
| 143 |
+} |
|
| 144 |
+ |
|
| 145 |
+func (p *Provider) getCredentials() (*getCredentialsOutput, error) {
|
|
| 146 |
+ op := &request.Operation{
|
|
| 147 |
+ Name: "GetCredentials", |
|
| 148 |
+ HTTPMethod: "GET", |
|
| 149 |
+ } |
|
| 150 |
+ |
|
| 151 |
+ out := &getCredentialsOutput{}
|
|
| 152 |
+ req := p.Client.NewRequest(op, nil, out) |
|
| 153 |
+ req.HTTPRequest.Header.Set("Accept", "application/json")
|
|
| 154 |
+ |
|
| 155 |
+ return out, req.Send() |
|
| 156 |
+} |
|
| 157 |
+ |
|
| 158 |
+func validateEndpointHandler(r *request.Request) {
|
|
| 159 |
+ if len(r.ClientInfo.Endpoint) == 0 {
|
|
| 160 |
+ r.Error = aws.ErrMissingEndpoint |
|
| 161 |
+ } |
|
| 162 |
+} |
|
| 163 |
+ |
|
| 164 |
+func unmarshalHandler(r *request.Request) {
|
|
| 165 |
+ defer r.HTTPResponse.Body.Close() |
|
| 166 |
+ |
|
| 167 |
+ out := r.Data.(*getCredentialsOutput) |
|
| 168 |
+ if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil {
|
|
| 169 |
+ r.Error = awserr.New("SerializationError",
|
|
| 170 |
+ "failed to decode endpoint credentials", |
|
| 171 |
+ err, |
|
| 172 |
+ ) |
|
| 173 |
+ } |
|
| 174 |
+} |
|
| 175 |
+ |
|
| 176 |
+func unmarshalError(r *request.Request) {
|
|
| 177 |
+ defer r.HTTPResponse.Body.Close() |
|
| 178 |
+ |
|
| 179 |
+ var errOut errorOutput |
|
| 180 |
+ if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&errOut); err != nil {
|
|
| 181 |
+ r.Error = awserr.New("SerializationError",
|
|
| 182 |
+ "failed to decode endpoint credentials", |
|
| 183 |
+ err, |
|
| 184 |
+ ) |
|
| 185 |
+ } |
|
| 186 |
+ |
|
| 187 |
+ // Response body format is not consistent between metadata endpoints. |
|
| 188 |
+ // Grab the error message as a string and include that as the source error |
|
| 189 |
+ r.Error = awserr.New(errOut.Code, errOut.Message, nil) |
|
| 190 |
+} |
| ... | ... |
@@ -30,13 +30,22 @@ func NewStaticCredentials(id, secret, token string) *Credentials {
|
| 30 | 30 |
}}) |
| 31 | 31 |
} |
| 32 | 32 |
|
| 33 |
+// NewStaticCredentialsFromCreds returns a pointer to a new Credentials object |
|
| 34 |
+// wrapping the static credentials value provide. Same as NewStaticCredentials |
|
| 35 |
+// but takes the creds Value instead of individual fields |
|
| 36 |
+func NewStaticCredentialsFromCreds(creds Value) *Credentials {
|
|
| 37 |
+ return NewCredentials(&StaticProvider{Value: creds})
|
|
| 38 |
+} |
|
| 39 |
+ |
|
| 33 | 40 |
// Retrieve returns the credentials or error if the credentials are invalid. |
| 34 | 41 |
func (s *StaticProvider) Retrieve() (Value, error) {
|
| 35 | 42 |
if s.AccessKeyID == "" || s.SecretAccessKey == "" {
|
| 36 | 43 |
return Value{ProviderName: StaticProviderName}, ErrStaticCredentialsEmpty
|
| 37 | 44 |
} |
| 38 | 45 |
|
| 39 |
- s.Value.ProviderName = StaticProviderName |
|
| 46 |
+ if len(s.Value.ProviderName) == 0 {
|
|
| 47 |
+ s.Value.ProviderName = StaticProviderName |
|
| 48 |
+ } |
|
| 40 | 49 |
return s.Value, nil |
| 41 | 50 |
} |
| 42 | 51 |
|
| 43 | 52 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,161 @@ |
| 0 |
+// Package stscreds are credential Providers to retrieve STS AWS credentials. |
|
| 1 |
+// |
|
| 2 |
+// STS provides multiple ways to retrieve credentials which can be used when making |
|
| 3 |
+// future AWS service API operation calls. |
|
| 4 |
+package stscreds |
|
| 5 |
+ |
|
| 6 |
+import ( |
|
| 7 |
+ "fmt" |
|
| 8 |
+ "time" |
|
| 9 |
+ |
|
| 10 |
+ "github.com/aws/aws-sdk-go/aws" |
|
| 11 |
+ "github.com/aws/aws-sdk-go/aws/client" |
|
| 12 |
+ "github.com/aws/aws-sdk-go/aws/credentials" |
|
| 13 |
+ "github.com/aws/aws-sdk-go/service/sts" |
|
| 14 |
+) |
|
| 15 |
+ |
|
| 16 |
+// ProviderName provides a name of AssumeRole provider |
|
| 17 |
+const ProviderName = "AssumeRoleProvider" |
|
| 18 |
+ |
|
| 19 |
+// AssumeRoler represents the minimal subset of the STS client API used by this provider. |
|
| 20 |
+type AssumeRoler interface {
|
|
| 21 |
+ AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) |
|
| 22 |
+} |
|
| 23 |
+ |
|
| 24 |
+// DefaultDuration is the default amount of time in minutes that the credentials |
|
| 25 |
+// will be valid for. |
|
| 26 |
+var DefaultDuration = time.Duration(15) * time.Minute |
|
| 27 |
+ |
|
| 28 |
+// AssumeRoleProvider retrieves temporary credentials from the STS service, and |
|
| 29 |
+// keeps track of their expiration time. This provider must be used explicitly, |
|
| 30 |
+// as it is not included in the credentials chain. |
|
| 31 |
+type AssumeRoleProvider struct {
|
|
| 32 |
+ credentials.Expiry |
|
| 33 |
+ |
|
| 34 |
+ // STS client to make assume role request with. |
|
| 35 |
+ Client AssumeRoler |
|
| 36 |
+ |
|
| 37 |
+ // Role to be assumed. |
|
| 38 |
+ RoleARN string |
|
| 39 |
+ |
|
| 40 |
+ // Session name, if you wish to reuse the credentials elsewhere. |
|
| 41 |
+ RoleSessionName string |
|
| 42 |
+ |
|
| 43 |
+ // Expiry duration of the STS credentials. Defaults to 15 minutes if not set. |
|
| 44 |
+ Duration time.Duration |
|
| 45 |
+ |
|
| 46 |
+ // Optional ExternalID to pass along, defaults to nil if not set. |
|
| 47 |
+ ExternalID *string |
|
| 48 |
+ |
|
| 49 |
+ // The policy plain text must be 2048 bytes or shorter. However, an internal |
|
| 50 |
+ // conversion compresses it into a packed binary format with a separate limit. |
|
| 51 |
+ // The PackedPolicySize response element indicates by percentage how close to |
|
| 52 |
+ // the upper size limit the policy is, with 100% equaling the maximum allowed |
|
| 53 |
+ // size. |
|
| 54 |
+ Policy *string |
|
| 55 |
+ |
|
| 56 |
+ // The identification number of the MFA device that is associated with the user |
|
| 57 |
+ // who is making the AssumeRole call. Specify this value if the trust policy |
|
| 58 |
+ // of the role being assumed includes a condition that requires MFA authentication. |
|
| 59 |
+ // The value is either the serial number for a hardware device (such as GAHT12345678) |
|
| 60 |
+ // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). |
|
| 61 |
+ SerialNumber *string |
|
| 62 |
+ |
|
| 63 |
+ // The value provided by the MFA device, if the trust policy of the role being |
|
| 64 |
+ // assumed requires MFA (that is, if the policy includes a condition that tests |
|
| 65 |
+ // for MFA). If the role being assumed requires MFA and if the TokenCode value |
|
| 66 |
+ // is missing or expired, the AssumeRole call returns an "access denied" error. |
|
| 67 |
+ TokenCode *string |
|
| 68 |
+ |
|
| 69 |
+ // ExpiryWindow will allow the credentials to trigger refreshing prior to |
|
| 70 |
+ // the credentials actually expiring. This is beneficial so race conditions |
|
| 71 |
+ // with expiring credentials do not cause request to fail unexpectedly |
|
| 72 |
+ // due to ExpiredTokenException exceptions. |
|
| 73 |
+ // |
|
| 74 |
+ // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true |
|
| 75 |
+ // 10 seconds before the credentials are actually expired. |
|
| 76 |
+ // |
|
| 77 |
+ // If ExpiryWindow is 0 or less it will be ignored. |
|
| 78 |
+ ExpiryWindow time.Duration |
|
| 79 |
+} |
|
| 80 |
+ |
|
| 81 |
+// NewCredentials returns a pointer to a new Credentials object wrapping the |
|
| 82 |
+// AssumeRoleProvider. The credentials will expire every 15 minutes and the |
|
| 83 |
+// role will be named after a nanosecond timestamp of this operation. |
|
| 84 |
+// |
|
| 85 |
+// Takes a Config provider to create the STS client. The ConfigProvider is |
|
| 86 |
+// satisfied by the session.Session type. |
|
| 87 |
+func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
|
| 88 |
+ p := &AssumeRoleProvider{
|
|
| 89 |
+ Client: sts.New(c), |
|
| 90 |
+ RoleARN: roleARN, |
|
| 91 |
+ Duration: DefaultDuration, |
|
| 92 |
+ } |
|
| 93 |
+ |
|
| 94 |
+ for _, option := range options {
|
|
| 95 |
+ option(p) |
|
| 96 |
+ } |
|
| 97 |
+ |
|
| 98 |
+ return credentials.NewCredentials(p) |
|
| 99 |
+} |
|
| 100 |
+ |
|
| 101 |
+// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the |
|
| 102 |
+// AssumeRoleProvider. The credentials will expire every 15 minutes and the |
|
| 103 |
+// role will be named after a nanosecond timestamp of this operation. |
|
| 104 |
+// |
|
| 105 |
+// Takes an AssumeRoler which can be satisfiede by the STS client. |
|
| 106 |
+func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials {
|
|
| 107 |
+ p := &AssumeRoleProvider{
|
|
| 108 |
+ Client: svc, |
|
| 109 |
+ RoleARN: roleARN, |
|
| 110 |
+ Duration: DefaultDuration, |
|
| 111 |
+ } |
|
| 112 |
+ |
|
| 113 |
+ for _, option := range options {
|
|
| 114 |
+ option(p) |
|
| 115 |
+ } |
|
| 116 |
+ |
|
| 117 |
+ return credentials.NewCredentials(p) |
|
| 118 |
+} |
|
| 119 |
+ |
|
| 120 |
+// Retrieve generates a new set of temporary credentials using STS. |
|
| 121 |
+func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) {
|
|
| 122 |
+ |
|
| 123 |
+ // Apply defaults where parameters are not set. |
|
| 124 |
+ if p.RoleSessionName == "" {
|
|
| 125 |
+ // Try to work out a role name that will hopefully end up unique. |
|
| 126 |
+ p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano())
|
|
| 127 |
+ } |
|
| 128 |
+ if p.Duration == 0 {
|
|
| 129 |
+ // Expire as often as AWS permits. |
|
| 130 |
+ p.Duration = DefaultDuration |
|
| 131 |
+ } |
|
| 132 |
+ input := &sts.AssumeRoleInput{
|
|
| 133 |
+ DurationSeconds: aws.Int64(int64(p.Duration / time.Second)), |
|
| 134 |
+ RoleArn: aws.String(p.RoleARN), |
|
| 135 |
+ RoleSessionName: aws.String(p.RoleSessionName), |
|
| 136 |
+ ExternalId: p.ExternalID, |
|
| 137 |
+ } |
|
| 138 |
+ if p.Policy != nil {
|
|
| 139 |
+ input.Policy = p.Policy |
|
| 140 |
+ } |
|
| 141 |
+ if p.SerialNumber != nil && p.TokenCode != nil {
|
|
| 142 |
+ input.SerialNumber = p.SerialNumber |
|
| 143 |
+ input.TokenCode = p.TokenCode |
|
| 144 |
+ } |
|
| 145 |
+ roleOutput, err := p.Client.AssumeRole(input) |
|
| 146 |
+ |
|
| 147 |
+ if err != nil {
|
|
| 148 |
+ return credentials.Value{ProviderName: ProviderName}, err
|
|
| 149 |
+ } |
|
| 150 |
+ |
|
| 151 |
+ // We will proactively generate new credentials before they expire. |
|
| 152 |
+ p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow) |
|
| 153 |
+ |
|
| 154 |
+ return credentials.Value{
|
|
| 155 |
+ AccessKeyID: *roleOutput.Credentials.AccessKeyId, |
|
| 156 |
+ SecretAccessKey: *roleOutput.Credentials.SecretAccessKey, |
|
| 157 |
+ SessionToken: *roleOutput.Credentials.SessionToken, |
|
| 158 |
+ ProviderName: ProviderName, |
|
| 159 |
+ }, nil |
|
| 160 |
+} |
| ... | ... |
@@ -8,6 +8,7 @@ |
| 8 | 8 |
package defaults |
| 9 | 9 |
|
| 10 | 10 |
import ( |
| 11 |
+ "fmt" |
|
| 11 | 12 |
"net/http" |
| 12 | 13 |
"os" |
| 13 | 14 |
"time" |
| ... | ... |
@@ -16,6 +17,7 @@ import ( |
| 16 | 16 |
"github.com/aws/aws-sdk-go/aws/corehandlers" |
| 17 | 17 |
"github.com/aws/aws-sdk-go/aws/credentials" |
| 18 | 18 |
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" |
| 19 |
+ "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds" |
|
| 19 | 20 |
"github.com/aws/aws-sdk-go/aws/ec2metadata" |
| 20 | 21 |
"github.com/aws/aws-sdk-go/aws/request" |
| 21 | 22 |
"github.com/aws/aws-sdk-go/private/endpoints" |
| ... | ... |
@@ -70,6 +72,7 @@ func Handlers() request.Handlers {
|
| 70 | 70 |
handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler) |
| 71 | 71 |
handlers.Build.AfterEachFn = request.HandlerListStopOnError |
| 72 | 72 |
handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler) |
| 73 |
+ handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler) |
|
| 73 | 74 |
handlers.Send.PushBackNamed(corehandlers.SendHandler) |
| 74 | 75 |
handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) |
| 75 | 76 |
handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler) |
| ... | ... |
@@ -83,16 +86,45 @@ func Handlers() request.Handlers {
|
| 83 | 83 |
// is available if you need to reset the credentials of an |
| 84 | 84 |
// existing service client or session's Config. |
| 85 | 85 |
func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials {
|
| 86 |
- endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, *cfg.Region, true) |
|
| 87 |
- |
|
| 88 | 86 |
return credentials.NewCredentials(&credentials.ChainProvider{
|
| 89 | 87 |
VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), |
| 90 | 88 |
Providers: []credentials.Provider{
|
| 91 | 89 |
&credentials.EnvProvider{},
|
| 92 | 90 |
&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
|
| 93 |
- &ec2rolecreds.EC2RoleProvider{
|
|
| 94 |
- Client: ec2metadata.NewClient(*cfg, handlers, endpoint, signingRegion), |
|
| 95 |
- ExpiryWindow: 5 * time.Minute, |
|
| 96 |
- }, |
|
| 97 |
- }}) |
|
| 91 |
+ RemoteCredProvider(*cfg, handlers), |
|
| 92 |
+ }, |
|
| 93 |
+ }) |
|
| 94 |
+} |
|
| 95 |
+ |
|
| 96 |
+// RemoteCredProvider returns a credenitials provider for the default remote |
|
| 97 |
+// endpoints such as EC2 or ECS Roles. |
|
| 98 |
+func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
|
|
| 99 |
+ ecsCredURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI")
|
|
| 100 |
+ |
|
| 101 |
+ if len(ecsCredURI) > 0 {
|
|
| 102 |
+ return ecsCredProvider(cfg, handlers, ecsCredURI) |
|
| 103 |
+ } |
|
| 104 |
+ |
|
| 105 |
+ return ec2RoleProvider(cfg, handlers) |
|
| 106 |
+} |
|
| 107 |
+ |
|
| 108 |
+func ecsCredProvider(cfg aws.Config, handlers request.Handlers, uri string) credentials.Provider {
|
|
| 109 |
+ const host = `169.254.170.2` |
|
| 110 |
+ |
|
| 111 |
+ return endpointcreds.NewProviderClient(cfg, handlers, |
|
| 112 |
+ fmt.Sprintf("http://%s%s", host, uri),
|
|
| 113 |
+ func(p *endpointcreds.Provider) {
|
|
| 114 |
+ p.ExpiryWindow = 5 * time.Minute |
|
| 115 |
+ }, |
|
| 116 |
+ ) |
|
| 117 |
+} |
|
| 118 |
+ |
|
| 119 |
+func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider {
|
|
| 120 |
+ endpoint, signingRegion := endpoints.EndpointForRegion(ec2metadata.ServiceName, |
|
| 121 |
+ aws.StringValue(cfg.Region), true, false) |
|
| 122 |
+ |
|
| 123 |
+ return &ec2rolecreds.EC2RoleProvider{
|
|
| 124 |
+ Client: ec2metadata.NewClient(cfg, handlers, endpoint, signingRegion), |
|
| 125 |
+ ExpiryWindow: 5 * time.Minute, |
|
| 126 |
+ } |
|
| 98 | 127 |
} |
| ... | ... |
@@ -3,6 +3,7 @@ package ec2metadata |
| 3 | 3 |
import ( |
| 4 | 4 |
"encoding/json" |
| 5 | 5 |
"fmt" |
| 6 |
+ "net/http" |
|
| 6 | 7 |
"path" |
| 7 | 8 |
"strings" |
| 8 | 9 |
"time" |
| ... | ... |
@@ -27,6 +28,27 @@ func (c *EC2Metadata) GetMetadata(p string) (string, error) {
|
| 27 | 27 |
return output.Content, req.Send() |
| 28 | 28 |
} |
| 29 | 29 |
|
| 30 |
+// GetUserData returns the userdata that was configured for the service. If |
|
| 31 |
+// there is no user-data setup for the EC2 instance a "NotFoundError" error |
|
| 32 |
+// code will be returned. |
|
| 33 |
+func (c *EC2Metadata) GetUserData() (string, error) {
|
|
| 34 |
+ op := &request.Operation{
|
|
| 35 |
+ Name: "GetUserData", |
|
| 36 |
+ HTTPMethod: "GET", |
|
| 37 |
+ HTTPPath: path.Join("/", "user-data"),
|
|
| 38 |
+ } |
|
| 39 |
+ |
|
| 40 |
+ output := &metadataOutput{}
|
|
| 41 |
+ req := c.NewRequest(op, nil, output) |
|
| 42 |
+ req.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
|
|
| 43 |
+ if r.HTTPResponse.StatusCode == http.StatusNotFound {
|
|
| 44 |
+ r.Error = awserr.New("NotFoundError", "user-data not found", r.Error)
|
|
| 45 |
+ } |
|
| 46 |
+ }) |
|
| 47 |
+ |
|
| 48 |
+ return output.Content, req.Send() |
|
| 49 |
+} |
|
| 50 |
+ |
|
| 30 | 51 |
// GetDynamicData uses the path provided to request information from the EC2 |
| 31 | 52 |
// instance metadata service for dynamic data. The content will be returned |
| 32 | 53 |
// as a string, or error if the request failed. |
| ... | ... |
@@ -1,5 +1,3 @@ |
| 1 |
-// +build go1.5 |
|
| 2 |
- |
|
| 3 | 1 |
package request |
| 4 | 2 |
|
| 5 | 3 |
import ( |
| ... | ... |
@@ -9,20 +7,13 @@ import ( |
| 9 | 9 |
) |
| 10 | 10 |
|
| 11 | 11 |
func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request {
|
| 12 |
- req := &http.Request{
|
|
| 13 |
- URL: &url.URL{},
|
|
| 14 |
- Header: http.Header{},
|
|
| 15 |
- Close: r.Close, |
|
| 16 |
- Body: body, |
|
| 17 |
- Host: r.Host, |
|
| 18 |
- Method: r.Method, |
|
| 19 |
- Proto: r.Proto, |
|
| 20 |
- ContentLength: r.ContentLength, |
|
| 21 |
- // Cancel will be deprecated in 1.7 and will be replaced with Context |
|
| 22 |
- Cancel: r.Cancel, |
|
| 23 |
- } |
|
| 24 |
- |
|
| 12 |
+ req := new(http.Request) |
|
| 13 |
+ *req = *r |
|
| 14 |
+ req.URL = &url.URL{}
|
|
| 25 | 15 |
*req.URL = *r.URL |
| 16 |
+ req.Body = body |
|
| 17 |
+ |
|
| 18 |
+ req.Header = http.Header{}
|
|
| 26 | 19 |
for k, v := range r.Header {
|
| 27 | 20 |
for _, vv := range v {
|
| 28 | 21 |
req.Header.Add(k, vv) |
| 29 | 22 |
deleted file mode 100644 |
| ... | ... |
@@ -1,31 +0,0 @@ |
| 1 |
-// +build !go1.5 |
|
| 2 |
- |
|
| 3 |
-package request |
|
| 4 |
- |
|
| 5 |
-import ( |
|
| 6 |
- "io" |
|
| 7 |
- "net/http" |
|
| 8 |
- "net/url" |
|
| 9 |
-) |
|
| 10 |
- |
|
| 11 |
-func copyHTTPRequest(r *http.Request, body io.ReadCloser) *http.Request {
|
|
| 12 |
- req := &http.Request{
|
|
| 13 |
- URL: &url.URL{},
|
|
| 14 |
- Header: http.Header{},
|
|
| 15 |
- Close: r.Close, |
|
| 16 |
- Body: body, |
|
| 17 |
- Host: r.Host, |
|
| 18 |
- Method: r.Method, |
|
| 19 |
- Proto: r.Proto, |
|
| 20 |
- ContentLength: r.ContentLength, |
|
| 21 |
- } |
|
| 22 |
- |
|
| 23 |
- *req.URL = *r.URL |
|
| 24 |
- for k, v := range r.Header {
|
|
| 25 |
- for _, vv := range v {
|
|
| 26 |
- req.Header.Add(k, vv) |
|
| 27 |
- } |
|
| 28 |
- } |
|
| 29 |
- |
|
| 30 |
- return req |
|
| 31 |
-} |
| ... | ... |
@@ -9,7 +9,7 @@ import ( |
| 9 | 9 |
// with retrying requests |
| 10 | 10 |
type offsetReader struct {
|
| 11 | 11 |
buf io.ReadSeeker |
| 12 |
- lock sync.RWMutex |
|
| 12 |
+ lock sync.Mutex |
|
| 13 | 13 |
closed bool |
| 14 | 14 |
} |
| 15 | 15 |
|
| ... | ... |
@@ -21,7 +21,8 @@ func newOffsetReader(buf io.ReadSeeker, offset int64) *offsetReader {
|
| 21 | 21 |
return reader |
| 22 | 22 |
} |
| 23 | 23 |
|
| 24 |
-// Close is a thread-safe close. Uses the write lock. |
|
| 24 |
+// Close will close the instance of the offset reader's access to |
|
| 25 |
+// the underlying io.ReadSeeker. |
|
| 25 | 26 |
func (o *offsetReader) Close() error {
|
| 26 | 27 |
o.lock.Lock() |
| 27 | 28 |
defer o.lock.Unlock() |
| ... | ... |
@@ -29,10 +30,10 @@ func (o *offsetReader) Close() error {
|
| 29 | 29 |
return nil |
| 30 | 30 |
} |
| 31 | 31 |
|
| 32 |
-// Read is a thread-safe read using a read lock. |
|
| 32 |
+// Read is a thread-safe read of the underlying io.ReadSeeker |
|
| 33 | 33 |
func (o *offsetReader) Read(p []byte) (int, error) {
|
| 34 |
- o.lock.RLock() |
|
| 35 |
- defer o.lock.RUnlock() |
|
| 34 |
+ o.lock.Lock() |
|
| 35 |
+ defer o.lock.Unlock() |
|
| 36 | 36 |
|
| 37 | 37 |
if o.closed {
|
| 38 | 38 |
return 0, io.EOF |
| ... | ... |
@@ -41,6 +42,14 @@ func (o *offsetReader) Read(p []byte) (int, error) {
|
| 41 | 41 |
return o.buf.Read(p) |
| 42 | 42 |
} |
| 43 | 43 |
|
| 44 |
+// Seek is a thread-safe seeking operation. |
|
| 45 |
+func (o *offsetReader) Seek(offset int64, whence int) (int64, error) {
|
|
| 46 |
+ o.lock.Lock() |
|
| 47 |
+ defer o.lock.Unlock() |
|
| 48 |
+ |
|
| 49 |
+ return o.buf.Seek(offset, whence) |
|
| 50 |
+} |
|
| 51 |
+ |
|
| 44 | 52 |
// CloseAndCopy will return a new offsetReader with a copy of the old buffer |
| 45 | 53 |
// and close the old buffer. |
| 46 | 54 |
func (o *offsetReader) CloseAndCopy(offset int64) *offsetReader {
|
| ... | ... |
@@ -4,7 +4,6 @@ import ( |
| 4 | 4 |
"bytes" |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"io" |
| 7 |
- "io/ioutil" |
|
| 8 | 7 |
"net/http" |
| 9 | 8 |
"net/url" |
| 10 | 9 |
"reflect" |
| ... | ... |
@@ -39,8 +38,15 @@ type Request struct {
|
| 39 | 39 |
RetryDelay time.Duration |
| 40 | 40 |
NotHoist bool |
| 41 | 41 |
SignedHeaderVals http.Header |
| 42 |
+ LastSignedAt time.Time |
|
| 42 | 43 |
|
| 43 | 44 |
built bool |
| 45 |
+ |
|
| 46 |
+ // Need to persist an intermideant body betweend the input Body and HTTP |
|
| 47 |
+ // request body because the HTTP Client's transport can maintain a reference |
|
| 48 |
+ // to the HTTP request's body after the client has returned. This value is |
|
| 49 |
+ // safe to use concurrently and rewraps the input Body for each HTTP request. |
|
| 50 |
+ safeBody *offsetReader |
|
| 44 | 51 |
} |
| 45 | 52 |
|
| 46 | 53 |
// An Operation is the service API operation to be made. |
| ... | ... |
@@ -72,15 +78,11 @@ func New(cfg aws.Config, clientInfo metadata.ClientInfo, handlers Handlers, |
| 72 | 72 |
if method == "" {
|
| 73 | 73 |
method = "POST" |
| 74 | 74 |
} |
| 75 |
- p := operation.HTTPPath |
|
| 76 |
- if p == "" {
|
|
| 77 |
- p = "/" |
|
| 78 |
- } |
|
| 79 | 75 |
|
| 80 | 76 |
httpReq, _ := http.NewRequest(method, "", nil) |
| 81 | 77 |
|
| 82 | 78 |
var err error |
| 83 |
- httpReq.URL, err = url.Parse(clientInfo.Endpoint + p) |
|
| 79 |
+ httpReq.URL, err = url.Parse(clientInfo.Endpoint + operation.HTTPPath) |
|
| 84 | 80 |
if err != nil {
|
| 85 | 81 |
httpReq.URL = &url.URL{}
|
| 86 | 82 |
err = awserr.New("InvalidEndpointURL", "invalid endpoint uri", err)
|
| ... | ... |
@@ -138,8 +140,8 @@ func (r *Request) SetStringBody(s string) {
|
| 138 | 138 |
|
| 139 | 139 |
// SetReaderBody will set the request's body reader. |
| 140 | 140 |
func (r *Request) SetReaderBody(reader io.ReadSeeker) {
|
| 141 |
- r.HTTPRequest.Body = newOffsetReader(reader, 0) |
|
| 142 | 141 |
r.Body = reader |
| 142 |
+ r.ResetBody() |
|
| 143 | 143 |
} |
| 144 | 144 |
|
| 145 | 145 |
// Presign returns the request's signed URL. Error will be returned |
| ... | ... |
@@ -208,7 +210,7 @@ func (r *Request) Build() error {
|
| 208 | 208 |
return r.Error |
| 209 | 209 |
} |
| 210 | 210 |
|
| 211 |
-// Sign will sign the request retuning error if errors are encountered. |
|
| 211 |
+// Sign will sign the request returning error if errors are encountered. |
|
| 212 | 212 |
// |
| 213 | 213 |
// Send will build the request prior to signing. All Sign Handlers will |
| 214 | 214 |
// be executed in the order they were set. |
| ... | ... |
@@ -223,6 +225,24 @@ func (r *Request) Sign() error {
|
| 223 | 223 |
return r.Error |
| 224 | 224 |
} |
| 225 | 225 |
|
| 226 |
+// ResetBody rewinds the request body backto its starting position, and |
|
| 227 |
+// set's the HTTP Request body reference. When the body is read prior |
|
| 228 |
+// to being sent in the HTTP request it will need to be rewound. |
|
| 229 |
+func (r *Request) ResetBody() {
|
|
| 230 |
+ if r.safeBody != nil {
|
|
| 231 |
+ r.safeBody.Close() |
|
| 232 |
+ } |
|
| 233 |
+ |
|
| 234 |
+ r.safeBody = newOffsetReader(r.Body, r.BodyStart) |
|
| 235 |
+ r.HTTPRequest.Body = r.safeBody |
|
| 236 |
+} |
|
| 237 |
+ |
|
| 238 |
+// GetBody will return an io.ReadSeeker of the Request's underlying |
|
| 239 |
+// input body with a concurrency safe wrapper. |
|
| 240 |
+func (r *Request) GetBody() io.ReadSeeker {
|
|
| 241 |
+ return r.safeBody |
|
| 242 |
+} |
|
| 243 |
+ |
|
| 226 | 244 |
// Send will send the request returning error if errors are encountered. |
| 227 | 245 |
// |
| 228 | 246 |
// Send will sign the request prior to sending. All Send Handlers will |
| ... | ... |
@@ -234,6 +254,8 @@ func (r *Request) Sign() error {
|
| 234 | 234 |
// |
| 235 | 235 |
// readLoop() and getConn(req *Request, cm connectMethod) |
| 236 | 236 |
// https://github.com/golang/go/blob/master/src/net/http/transport.go |
| 237 |
+// |
|
| 238 |
+// Send will not close the request.Request's body. |
|
| 237 | 239 |
func (r *Request) Send() error {
|
| 238 | 240 |
for {
|
| 239 | 241 |
if aws.BoolValue(r.Retryable) {
|
| ... | ... |
@@ -242,21 +264,15 @@ func (r *Request) Send() error {
|
| 242 | 242 |
r.ClientInfo.ServiceName, r.Operation.Name, r.RetryCount)) |
| 243 | 243 |
} |
| 244 | 244 |
|
| 245 |
- var body io.ReadCloser |
|
| 246 |
- if reader, ok := r.HTTPRequest.Body.(*offsetReader); ok {
|
|
| 247 |
- body = reader.CloseAndCopy(r.BodyStart) |
|
| 248 |
- } else {
|
|
| 249 |
- if r.Config.Logger != nil {
|
|
| 250 |
- r.Config.Logger.Log("Request body type has been overwritten. May cause race conditions")
|
|
| 251 |
- } |
|
| 252 |
- r.Body.Seek(r.BodyStart, 0) |
|
| 253 |
- body = ioutil.NopCloser(r.Body) |
|
| 254 |
- } |
|
| 245 |
+ // The previous http.Request will have a reference to the r.Body |
|
| 246 |
+ // and the HTTP Client's Transport may still be reading from |
|
| 247 |
+ // the request's body even though the Client's Do returned. |
|
| 248 |
+ r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, nil) |
|
| 249 |
+ r.ResetBody() |
|
| 255 | 250 |
|
| 256 |
- r.HTTPRequest = copyHTTPRequest(r.HTTPRequest, body) |
|
| 251 |
+ // Closing response body to ensure that no response body is leaked |
|
| 252 |
+ // between retry attempts. |
|
| 257 | 253 |
if r.HTTPResponse != nil && r.HTTPResponse.Body != nil {
|
| 258 |
- // Closing response body. Since we are setting a new request to send off, this |
|
| 259 |
- // response will get squashed and leaked. |
|
| 260 | 254 |
r.HTTPResponse.Body.Close() |
| 261 | 255 |
} |
| 262 | 256 |
} |
| ... | ... |
@@ -284,7 +300,6 @@ func (r *Request) Send() error {
|
| 284 | 284 |
debugLogReqError(r, "Send Request", true, err) |
| 285 | 285 |
continue |
| 286 | 286 |
} |
| 287 |
- |
|
| 288 | 287 |
r.Handlers.UnmarshalMeta.Run(r) |
| 289 | 288 |
r.Handlers.ValidateResponse.Run(r) |
| 290 | 289 |
if r.Error != nil {
|
| 291 | 290 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,223 @@ |
| 0 |
+/* |
|
| 1 |
+Package session provides configuration for the SDK's service clients. |
|
| 2 |
+ |
|
| 3 |
+Sessions can be shared across all service clients that share the same base |
|
| 4 |
+configuration. The Session is built from the SDK's default configuration and |
|
| 5 |
+request handlers. |
|
| 6 |
+ |
|
| 7 |
+Sessions should be cached when possible, because creating a new Session will |
|
| 8 |
+load all configuration values from the environment, and config files each time |
|
| 9 |
+the Session is created. Sharing the Session value across all of your service |
|
| 10 |
+clients will ensure the configuration is loaded the fewest number of times possible. |
|
| 11 |
+ |
|
| 12 |
+Concurrency |
|
| 13 |
+ |
|
| 14 |
+Sessions are safe to use concurrently as long as the Session is not being |
|
| 15 |
+modified. The SDK will not modify the Session once the Session has been created. |
|
| 16 |
+Creating service clients concurrently from a shared Session is safe. |
|
| 17 |
+ |
|
| 18 |
+Sessions from Shared Config |
|
| 19 |
+ |
|
| 20 |
+Sessions can be created using the method above that will only load the |
|
| 21 |
+additional config if the AWS_SDK_LOAD_CONFIG environment variable is set. |
|
| 22 |
+Alternatively you can explicitly create a Session with shared config enabled. |
|
| 23 |
+To do this you can use NewSessionWithOptions to configure how the Session will |
|
| 24 |
+be created. Using the NewSessionWithOptions with SharedConfigState set to |
|
| 25 |
+SharedConfigEnabled will create the session as if the AWS_SDK_LOAD_CONFIG |
|
| 26 |
+environment variable was set. |
|
| 27 |
+ |
|
| 28 |
+Creating Sessions |
|
| 29 |
+ |
|
| 30 |
+When creating Sessions optional aws.Config values can be passed in that will |
|
| 31 |
+override the default, or loaded config values the Session is being created |
|
| 32 |
+with. This allows you to provide additional, or case based, configuration |
|
| 33 |
+as needed. |
|
| 34 |
+ |
|
| 35 |
+By default NewSession will only load credentials from the shared credentials |
|
| 36 |
+file (~/.aws/credentials). If the AWS_SDK_LOAD_CONFIG environment variable is |
|
| 37 |
+set to a truthy value the Session will be created from the configuration |
|
| 38 |
+values from the shared config (~/.aws/config) and shared credentials |
|
| 39 |
+(~/.aws/credentials) files. See the section Sessions from Shared Config for |
|
| 40 |
+more information. |
|
| 41 |
+ |
|
| 42 |
+Create a Session with the default config and request handlers. With credentials |
|
| 43 |
+region, and profile loaded from the environment and shared config automatically. |
|
| 44 |
+Requires the AWS_PROFILE to be set, or "default" is used. |
|
| 45 |
+ |
|
| 46 |
+ // Create Session |
|
| 47 |
+ sess, err := session.NewSession() |
|
| 48 |
+ |
|
| 49 |
+ // Create a Session with a custom region |
|
| 50 |
+ sess, err := session.NewSession(&aws.Config{Region: aws.String("us-east-1")})
|
|
| 51 |
+ |
|
| 52 |
+ // Create a S3 client instance from a session |
|
| 53 |
+ sess, err := session.NewSession() |
|
| 54 |
+ if err != nil {
|
|
| 55 |
+ // Handle Session creation error |
|
| 56 |
+ } |
|
| 57 |
+ svc := s3.New(sess) |
|
| 58 |
+ |
|
| 59 |
+Create Session With Option Overrides |
|
| 60 |
+ |
|
| 61 |
+In addition to NewSession, Sessions can be created using NewSessionWithOptions. |
|
| 62 |
+This func allows you to control and override how the Session will be created |
|
| 63 |
+through code instead of being driven by environment variables only. |
|
| 64 |
+ |
|
| 65 |
+Use NewSessionWithOptions when you want to provide the config profile, or |
|
| 66 |
+override the shared config state (AWS_SDK_LOAD_CONFIG). |
|
| 67 |
+ |
|
| 68 |
+ // Equivalent to session.NewSession() |
|
| 69 |
+ sess, err := session.NewSessionWithOptions(session.Options{})
|
|
| 70 |
+ |
|
| 71 |
+ // Specify profile to load for the session's config |
|
| 72 |
+ sess, err := session.NewSessionWithOptions(session.Options{
|
|
| 73 |
+ Profile: "profile_name", |
|
| 74 |
+ }) |
|
| 75 |
+ |
|
| 76 |
+ // Specify profile for config and region for requests |
|
| 77 |
+ sess, err := session.NewSessionWithOptions(session.Options{
|
|
| 78 |
+ Config: aws.Config{Region: aws.String("us-east-1")},
|
|
| 79 |
+ Profile: "profile_name", |
|
| 80 |
+ }) |
|
| 81 |
+ |
|
| 82 |
+ // Force enable Shared Config support |
|
| 83 |
+ sess, err := session.NewSessionWithOptions(session.Options{
|
|
| 84 |
+ SharedConfigState: SharedConfigEnable, |
|
| 85 |
+ }) |
|
| 86 |
+ |
|
| 87 |
+Adding Handlers |
|
| 88 |
+ |
|
| 89 |
+You can add handlers to a session for processing HTTP requests. All service |
|
| 90 |
+clients that use the session inherit the handlers. For example, the following |
|
| 91 |
+handler logs every request and its payload made by a service client: |
|
| 92 |
+ |
|
| 93 |
+ // Create a session, and add additional handlers for all service |
|
| 94 |
+ // clients created with the Session to inherit. Adds logging handler. |
|
| 95 |
+ sess, err := session.NewSession() |
|
| 96 |
+ sess.Handlers.Send.PushFront(func(r *request.Request) {
|
|
| 97 |
+ // Log every request made and its payload |
|
| 98 |
+ logger.Println("Request: %s/%s, Payload: %s",
|
|
| 99 |
+ r.ClientInfo.ServiceName, r.Operation, r.Params) |
|
| 100 |
+ }) |
|
| 101 |
+ |
|
| 102 |
+Deprecated "New" function |
|
| 103 |
+ |
|
| 104 |
+The New session function has been deprecated because it does not provide good |
|
| 105 |
+way to return errors that occur when loading the configuration files and values. |
|
| 106 |
+Because of this, NewSession was created so errors can be retrieved when |
|
| 107 |
+creating a session fails. |
|
| 108 |
+ |
|
| 109 |
+Shared Config Fields |
|
| 110 |
+ |
|
| 111 |
+By default the SDK will only load the shared credentials file's (~/.aws/credentials) |
|
| 112 |
+credentials values, and all other config is provided by the environment variables, |
|
| 113 |
+SDK defaults, and user provided aws.Config values. |
|
| 114 |
+ |
|
| 115 |
+If the AWS_SDK_LOAD_CONFIG environment variable is set, or SharedConfigEnable |
|
| 116 |
+option is used to create the Session the full shared config values will be |
|
| 117 |
+loaded. This includes credentials, region, and support for assume role. In |
|
| 118 |
+addition the Session will load its configuration from both the shared config |
|
| 119 |
+file (~/.aws/config) and shared credentials file (~/.aws/credentials). Both |
|
| 120 |
+files have the same format. |
|
| 121 |
+ |
|
| 122 |
+If both config files are present the configuration from both files will be |
|
| 123 |
+read. The Session will be created from configuration values from the shared |
|
| 124 |
+credentials file (~/.aws/credentials) over those in the shared credentials |
|
| 125 |
+file (~/.aws/config). |
|
| 126 |
+ |
|
| 127 |
+Credentials are the values the SDK should use for authenticating requests with |
|
| 128 |
+AWS Services. They arfrom a configuration file will need to include both |
|
| 129 |
+aws_access_key_id and aws_secret_access_key must be provided together in the |
|
| 130 |
+same file to be considered valid. The values will be ignored if not a complete |
|
| 131 |
+group. aws_session_token is an optional field that can be provided if both of |
|
| 132 |
+the other two fields are also provided. |
|
| 133 |
+ |
|
| 134 |
+ aws_access_key_id = AKID |
|
| 135 |
+ aws_secret_access_key = SECRET |
|
| 136 |
+ aws_session_token = TOKEN |
|
| 137 |
+ |
|
| 138 |
+Assume Role values allow you to configure the SDK to assume an IAM role using |
|
| 139 |
+a set of credentials provided in a config file via the source_profile field. |
|
| 140 |
+Both "role_arn" and "source_profile" are required. The SDK does not support |
|
| 141 |
+assuming a role with MFA token Via the Session's constructor. You can use the |
|
| 142 |
+stscreds.AssumeRoleProvider credentials provider to specify custom |
|
| 143 |
+configuration and support for MFA. |
|
| 144 |
+ |
|
| 145 |
+ role_arn = arn:aws:iam::<account_number>:role/<role_name> |
|
| 146 |
+ source_profile = profile_with_creds |
|
| 147 |
+ external_id = 1234 |
|
| 148 |
+ mfa_serial = not supported! |
|
| 149 |
+ role_session_name = session_name |
|
| 150 |
+ |
|
| 151 |
+Region is the region the SDK should use for looking up AWS service endpoints |
|
| 152 |
+and signing requests. |
|
| 153 |
+ |
|
| 154 |
+ region = us-east-1 |
|
| 155 |
+ |
|
| 156 |
+Environment Variables |
|
| 157 |
+ |
|
| 158 |
+When a Session is created several environment variables can be set to adjust |
|
| 159 |
+how the SDK functions, and what configuration data it loads when creating |
|
| 160 |
+Sessions. All environment values are optional, but some values like credentials |
|
| 161 |
+require multiple of the values to set or the partial values will be ignored. |
|
| 162 |
+All environment variable values are strings unless otherwise noted. |
|
| 163 |
+ |
|
| 164 |
+Environment configuration values. If set both Access Key ID and Secret Access |
|
| 165 |
+Key must be provided. Session Token and optionally also be provided, but is |
|
| 166 |
+not required. |
|
| 167 |
+ |
|
| 168 |
+ # Access Key ID |
|
| 169 |
+ AWS_ACCESS_KEY_ID=AKID |
|
| 170 |
+ AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. |
|
| 171 |
+ |
|
| 172 |
+ # Secret Access Key |
|
| 173 |
+ AWS_SECRET_ACCESS_KEY=SECRET |
|
| 174 |
+ AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. |
|
| 175 |
+ |
|
| 176 |
+ # Session Token |
|
| 177 |
+ AWS_SESSION_TOKEN=TOKEN |
|
| 178 |
+ |
|
| 179 |
+Region value will instruct the SDK where to make service API requests to. If is |
|
| 180 |
+not provided in the environment the region must be provided before a service |
|
| 181 |
+client request is made. |
|
| 182 |
+ |
|
| 183 |
+ AWS_REGION=us-east-1 |
|
| 184 |
+ |
|
| 185 |
+ # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set, |
|
| 186 |
+ # and AWS_REGION is not also set. |
|
| 187 |
+ AWS_DEFAULT_REGION=us-east-1 |
|
| 188 |
+ |
|
| 189 |
+Profile name the SDK should load use when loading shared config from the |
|
| 190 |
+configuration files. If not provided "default" will be used as the profile name. |
|
| 191 |
+ |
|
| 192 |
+ AWS_PROFILE=my_profile |
|
| 193 |
+ |
|
| 194 |
+ # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set, |
|
| 195 |
+ # and AWS_PROFILE is not also set. |
|
| 196 |
+ AWS_DEFAULT_PROFILE=my_profile |
|
| 197 |
+ |
|
| 198 |
+SDK load config instructs the SDK to load the shared config in addition to |
|
| 199 |
+shared credentials. This also expands the configuration loaded so the shared |
|
| 200 |
+credentials will have parity with the shared config file. This also enables |
|
| 201 |
+Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE |
|
| 202 |
+env values as well. |
|
| 203 |
+ |
|
| 204 |
+ AWS_SDK_LOAD_CONFIG=1 |
|
| 205 |
+ |
|
| 206 |
+Shared credentials file path can be set to instruct the SDK to use an alternative |
|
| 207 |
+file for the shared credentials. If not set the file will be loaded from |
|
| 208 |
+$HOME/.aws/credentials on Linux/Unix based systems, and |
|
| 209 |
+%USERPROFILE%\.aws\credentials on Windows. |
|
| 210 |
+ |
|
| 211 |
+ AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials |
|
| 212 |
+ |
|
| 213 |
+Shared config file path can be set to instruct the SDK to use an alternative |
|
| 214 |
+file for the shared config. If not set the file will be loaded from |
|
| 215 |
+$HOME/.aws/config on Linux/Unix based systems, and |
|
| 216 |
+%USERPROFILE%\.aws\config on Windows. |
|
| 217 |
+ |
|
| 218 |
+ AWS_CONFIG_FILE=$HOME/my_shared_config |
|
| 219 |
+ |
|
| 220 |
+ |
|
| 221 |
+*/ |
|
| 222 |
+package session |
| 0 | 223 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,188 @@ |
| 0 |
+package session |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "os" |
|
| 4 |
+ "path/filepath" |
|
| 5 |
+ "strconv" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/aws/aws-sdk-go/aws/credentials" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+// envConfig is a collection of environment values the SDK will read |
|
| 11 |
+// setup config from. All environment values are optional. But some values |
|
| 12 |
+// such as credentials require multiple values to be complete or the values |
|
| 13 |
+// will be ignored. |
|
| 14 |
+type envConfig struct {
|
|
| 15 |
+ // Environment configuration values. If set both Access Key ID and Secret Access |
|
| 16 |
+ // Key must be provided. Session Token and optionally also be provided, but is |
|
| 17 |
+ // not required. |
|
| 18 |
+ // |
|
| 19 |
+ // # Access Key ID |
|
| 20 |
+ // AWS_ACCESS_KEY_ID=AKID |
|
| 21 |
+ // AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. |
|
| 22 |
+ // |
|
| 23 |
+ // # Secret Access Key |
|
| 24 |
+ // AWS_SECRET_ACCESS_KEY=SECRET |
|
| 25 |
+ // AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. |
|
| 26 |
+ // |
|
| 27 |
+ // # Session Token |
|
| 28 |
+ // AWS_SESSION_TOKEN=TOKEN |
|
| 29 |
+ Creds credentials.Value |
|
| 30 |
+ |
|
| 31 |
+ // Region value will instruct the SDK where to make service API requests to. If is |
|
| 32 |
+ // not provided in the environment the region must be provided before a service |
|
| 33 |
+ // client request is made. |
|
| 34 |
+ // |
|
| 35 |
+ // AWS_REGION=us-east-1 |
|
| 36 |
+ // |
|
| 37 |
+ // # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set, |
|
| 38 |
+ // # and AWS_REGION is not also set. |
|
| 39 |
+ // AWS_DEFAULT_REGION=us-east-1 |
|
| 40 |
+ Region string |
|
| 41 |
+ |
|
| 42 |
+ // Profile name the SDK should load use when loading shared configuration from the |
|
| 43 |
+ // shared configuration files. If not provided "default" will be used as the |
|
| 44 |
+ // profile name. |
|
| 45 |
+ // |
|
| 46 |
+ // AWS_PROFILE=my_profile |
|
| 47 |
+ // |
|
| 48 |
+ // # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set, |
|
| 49 |
+ // # and AWS_PROFILE is not also set. |
|
| 50 |
+ // AWS_DEFAULT_PROFILE=my_profile |
|
| 51 |
+ Profile string |
|
| 52 |
+ |
|
| 53 |
+ // SDK load config instructs the SDK to load the shared config in addition to |
|
| 54 |
+ // shared credentials. This also expands the configuration loaded from the shared |
|
| 55 |
+ // credentials to have parity with the shared config file. This also enables |
|
| 56 |
+ // Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE |
|
| 57 |
+ // env values as well. |
|
| 58 |
+ // |
|
| 59 |
+ // AWS_SDK_LOAD_CONFIG=1 |
|
| 60 |
+ EnableSharedConfig bool |
|
| 61 |
+ |
|
| 62 |
+ // Shared credentials file path can be set to instruct the SDK to use an alternate |
|
| 63 |
+ // file for the shared credentials. If not set the file will be loaded from |
|
| 64 |
+ // $HOME/.aws/credentials on Linux/Unix based systems, and |
|
| 65 |
+ // %USERPROFILE%\.aws\credentials on Windows. |
|
| 66 |
+ // |
|
| 67 |
+ // AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials |
|
| 68 |
+ SharedCredentialsFile string |
|
| 69 |
+ |
|
| 70 |
+ // Shared config file path can be set to instruct the SDK to use an alternate |
|
| 71 |
+ // file for the shared config. If not set the file will be loaded from |
|
| 72 |
+ // $HOME/.aws/config on Linux/Unix based systems, and |
|
| 73 |
+ // %USERPROFILE%\.aws\config on Windows. |
|
| 74 |
+ // |
|
| 75 |
+ // AWS_CONFIG_FILE=$HOME/my_shared_config |
|
| 76 |
+ SharedConfigFile string |
|
| 77 |
+} |
|
| 78 |
+ |
|
| 79 |
+var ( |
|
| 80 |
+ credAccessEnvKey = []string{
|
|
| 81 |
+ "AWS_ACCESS_KEY_ID", |
|
| 82 |
+ "AWS_ACCESS_KEY", |
|
| 83 |
+ } |
|
| 84 |
+ credSecretEnvKey = []string{
|
|
| 85 |
+ "AWS_SECRET_ACCESS_KEY", |
|
| 86 |
+ "AWS_SECRET_KEY", |
|
| 87 |
+ } |
|
| 88 |
+ credSessionEnvKey = []string{
|
|
| 89 |
+ "AWS_SESSION_TOKEN", |
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ regionEnvKeys = []string{
|
|
| 93 |
+ "AWS_REGION", |
|
| 94 |
+ "AWS_DEFAULT_REGION", // Only read if AWS_SDK_LOAD_CONFIG is also set |
|
| 95 |
+ } |
|
| 96 |
+ profileEnvKeys = []string{
|
|
| 97 |
+ "AWS_PROFILE", |
|
| 98 |
+ "AWS_DEFAULT_PROFILE", // Only read if AWS_SDK_LOAD_CONFIG is also set |
|
| 99 |
+ } |
|
| 100 |
+) |
|
| 101 |
+ |
|
| 102 |
+// loadEnvConfig retrieves the SDK's environment configuration. |
|
| 103 |
+// See `envConfig` for the values that will be retrieved. |
|
| 104 |
+// |
|
| 105 |
+// If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value |
|
| 106 |
+// the shared SDK config will be loaded in addition to the SDK's specific |
|
| 107 |
+// configuration values. |
|
| 108 |
+func loadEnvConfig() envConfig {
|
|
| 109 |
+ enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG"))
|
|
| 110 |
+ return envConfigLoad(enableSharedConfig) |
|
| 111 |
+} |
|
| 112 |
+ |
|
| 113 |
+// loadEnvSharedConfig retrieves the SDK's environment configuration, and the |
|
| 114 |
+// SDK shared config. See `envConfig` for the values that will be retrieved. |
|
| 115 |
+// |
|
| 116 |
+// Loads the shared configuration in addition to the SDK's specific configuration. |
|
| 117 |
+// This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG` |
|
| 118 |
+// environment variable is set. |
|
| 119 |
+func loadSharedEnvConfig() envConfig {
|
|
| 120 |
+ return envConfigLoad(true) |
|
| 121 |
+} |
|
| 122 |
+ |
|
| 123 |
+func envConfigLoad(enableSharedConfig bool) envConfig {
|
|
| 124 |
+ cfg := envConfig{}
|
|
| 125 |
+ |
|
| 126 |
+ cfg.EnableSharedConfig = enableSharedConfig |
|
| 127 |
+ |
|
| 128 |
+ setFromEnvVal(&cfg.Creds.AccessKeyID, credAccessEnvKey) |
|
| 129 |
+ setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey) |
|
| 130 |
+ setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey) |
|
| 131 |
+ |
|
| 132 |
+ // Require logical grouping of credentials |
|
| 133 |
+ if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 {
|
|
| 134 |
+ cfg.Creds = credentials.Value{}
|
|
| 135 |
+ } else {
|
|
| 136 |
+ cfg.Creds.ProviderName = "EnvConfigCredentials" |
|
| 137 |
+ } |
|
| 138 |
+ |
|
| 139 |
+ regionKeys := regionEnvKeys |
|
| 140 |
+ profileKeys := profileEnvKeys |
|
| 141 |
+ if !cfg.EnableSharedConfig {
|
|
| 142 |
+ regionKeys = regionKeys[:1] |
|
| 143 |
+ profileKeys = profileKeys[:1] |
|
| 144 |
+ } |
|
| 145 |
+ |
|
| 146 |
+ setFromEnvVal(&cfg.Region, regionKeys) |
|
| 147 |
+ setFromEnvVal(&cfg.Profile, profileKeys) |
|
| 148 |
+ |
|
| 149 |
+ cfg.SharedCredentialsFile = sharedCredentialsFilename() |
|
| 150 |
+ cfg.SharedConfigFile = sharedConfigFilename() |
|
| 151 |
+ |
|
| 152 |
+ return cfg |
|
| 153 |
+} |
|
| 154 |
+ |
|
| 155 |
+func setFromEnvVal(dst *string, keys []string) {
|
|
| 156 |
+ for _, k := range keys {
|
|
| 157 |
+ if v := os.Getenv(k); len(v) > 0 {
|
|
| 158 |
+ *dst = v |
|
| 159 |
+ break |
|
| 160 |
+ } |
|
| 161 |
+ } |
|
| 162 |
+} |
|
| 163 |
+ |
|
| 164 |
+func sharedCredentialsFilename() string {
|
|
| 165 |
+ if name := os.Getenv("AWS_SHARED_CREDENTIALS_FILE"); len(name) > 0 {
|
|
| 166 |
+ return name |
|
| 167 |
+ } |
|
| 168 |
+ |
|
| 169 |
+ return filepath.Join(userHomeDir(), ".aws", "credentials") |
|
| 170 |
+} |
|
| 171 |
+ |
|
| 172 |
+func sharedConfigFilename() string {
|
|
| 173 |
+ if name := os.Getenv("AWS_CONFIG_FILE"); len(name) > 0 {
|
|
| 174 |
+ return name |
|
| 175 |
+ } |
|
| 176 |
+ |
|
| 177 |
+ return filepath.Join(userHomeDir(), ".aws", "config") |
|
| 178 |
+} |
|
| 179 |
+ |
|
| 180 |
+func userHomeDir() string {
|
|
| 181 |
+ homeDir := os.Getenv("HOME") // *nix
|
|
| 182 |
+ if len(homeDir) == 0 { // windows
|
|
| 183 |
+ homeDir = os.Getenv("USERPROFILE")
|
|
| 184 |
+ } |
|
| 185 |
+ |
|
| 186 |
+ return homeDir |
|
| 187 |
+} |
| ... | ... |
@@ -1,17 +1,14 @@ |
| 1 |
-// Package session provides a way to create service clients with shared configuration |
|
| 2 |
-// and handlers. |
|
| 3 |
-// |
|
| 4 |
-// Generally this package should be used instead of the `defaults` package. |
|
| 5 |
-// |
|
| 6 |
-// A session should be used to share configurations and request handlers between multiple |
|
| 7 |
-// service clients. When service clients need specific configuration aws.Config can be |
|
| 8 |
-// used to provide additional configuration directly to the service client. |
|
| 9 | 1 |
package session |
| 10 | 2 |
|
| 11 | 3 |
import ( |
| 4 |
+ "fmt" |
|
| 5 |
+ |
|
| 12 | 6 |
"github.com/aws/aws-sdk-go/aws" |
| 7 |
+ "github.com/aws/aws-sdk-go/aws/awserr" |
|
| 13 | 8 |
"github.com/aws/aws-sdk-go/aws/client" |
| 14 | 9 |
"github.com/aws/aws-sdk-go/aws/corehandlers" |
| 10 |
+ "github.com/aws/aws-sdk-go/aws/credentials" |
|
| 11 |
+ "github.com/aws/aws-sdk-go/aws/credentials/stscreds" |
|
| 15 | 12 |
"github.com/aws/aws-sdk-go/aws/defaults" |
| 16 | 13 |
"github.com/aws/aws-sdk-go/aws/request" |
| 17 | 14 |
"github.com/aws/aws-sdk-go/private/endpoints" |
| ... | ... |
@@ -21,36 +18,204 @@ import ( |
| 21 | 21 |
// store configurations and request handlers for those services. |
| 22 | 22 |
// |
| 23 | 23 |
// Sessions are safe to create service clients concurrently, but it is not safe |
| 24 |
-// to mutate the session concurrently. |
|
| 24 |
+// to mutate the Session concurrently. |
|
| 25 |
+// |
|
| 26 |
+// The Session satisfies the service client's client.ClientConfigProvider. |
|
| 25 | 27 |
type Session struct {
|
| 26 | 28 |
Config *aws.Config |
| 27 | 29 |
Handlers request.Handlers |
| 28 | 30 |
} |
| 29 | 31 |
|
| 30 |
-// New creates a new instance of the handlers merging in the provided Configs |
|
| 31 |
-// on top of the SDK's default configurations. Once the session is created it |
|
| 32 |
-// can be mutated to modify Configs or Handlers. The session is safe to be read |
|
| 33 |
-// concurrently, but it should not be written to concurrently. |
|
| 32 |
+// New creates a new instance of the handlers merging in the provided configs |
|
| 33 |
+// on top of the SDK's default configurations. Once the Session is created it |
|
| 34 |
+// can be mutated to modify the Config or Handlers. The Session is safe to be |
|
| 35 |
+// read concurrently, but it should not be written to concurrently. |
|
| 36 |
+// |
|
| 37 |
+// If the AWS_SDK_LOAD_CONFIG environment is set to a truthy value, the New |
|
| 38 |
+// method could now encounter an error when loading the configuration. When |
|
| 39 |
+// The environment variable is set, and an error occurs, New will return a |
|
| 40 |
+// session that will fail all requests reporting the error that occured while |
|
| 41 |
+// loading the session. Use NewSession to get the error when creating the |
|
| 42 |
+// session. |
|
| 43 |
+// |
|
| 44 |
+// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value |
|
| 45 |
+// the shared config file (~/.aws/config) will also be loaded, in addition to |
|
| 46 |
+// the shared credentials file (~/.aws/config). Values set in both the |
|
| 47 |
+// shared config, and shared credentials will be taken from the shared |
|
| 48 |
+// credentials file. |
|
| 49 |
+// |
|
| 50 |
+// Deprecated: Use NewSession functiions to create sessions instead. NewSession |
|
| 51 |
+// has the same functionality as New except an error can be returned when the |
|
| 52 |
+// func is called instead of waiting to receive an error until a request is made. |
|
| 53 |
+func New(cfgs ...*aws.Config) *Session {
|
|
| 54 |
+ // load initial config from environment |
|
| 55 |
+ envCfg := loadEnvConfig() |
|
| 56 |
+ |
|
| 57 |
+ if envCfg.EnableSharedConfig {
|
|
| 58 |
+ s, err := newSession(envCfg, cfgs...) |
|
| 59 |
+ if err != nil {
|
|
| 60 |
+ // Old session.New expected all errors to be discovered when |
|
| 61 |
+ // a request is made, and would report the errors then. This |
|
| 62 |
+ // needs to be replicated if an error occurs while creating |
|
| 63 |
+ // the session. |
|
| 64 |
+ msg := "failed to create session with AWS_SDK_LOAD_CONFIG enabled. " + |
|
| 65 |
+ "Use session.NewSession to handle errors occuring during session creation." |
|
| 66 |
+ |
|
| 67 |
+ // Session creation failed, need to report the error and prevent |
|
| 68 |
+ // any requests from succeeding. |
|
| 69 |
+ s = &Session{Config: defaults.Config()}
|
|
| 70 |
+ s.Config.MergeIn(cfgs...) |
|
| 71 |
+ s.Config.Logger.Log("ERROR:", msg, "Error:", err)
|
|
| 72 |
+ s.Handlers.Validate.PushBack(func(r *request.Request) {
|
|
| 73 |
+ r.Error = err |
|
| 74 |
+ }) |
|
| 75 |
+ } |
|
| 76 |
+ return s |
|
| 77 |
+ } |
|
| 78 |
+ |
|
| 79 |
+ return oldNewSession(cfgs...) |
|
| 80 |
+} |
|
| 81 |
+ |
|
| 82 |
+// NewSession returns a new Session created from SDK defaults, config files, |
|
| 83 |
+// environment, and user provided config files. Once the Session is created |
|
| 84 |
+// it can be mutated to modify the Config or Handlers. The Session is safe to |
|
| 85 |
+// be read concurrently, but it should not be written to concurrently. |
|
| 86 |
+// |
|
| 87 |
+// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value |
|
| 88 |
+// the shared config file (~/.aws/config) will also be loaded in addition to |
|
| 89 |
+// the shared credentials file (~/.aws/config). Values set in both the |
|
| 90 |
+// shared config, and shared credentials will be taken from the shared |
|
| 91 |
+// credentials file. Enabling the Shared Config will also allow the Session |
|
| 92 |
+// to be built with retrieving credentials with AssumeRole set in the config. |
|
| 93 |
+// |
|
| 94 |
+// See the NewSessionWithOptions func for information on how to override or |
|
| 95 |
+// control through code how the Session will be created. Such as specifing the |
|
| 96 |
+// config profile, and controlling if shared config is enabled or not. |
|
| 97 |
+func NewSession(cfgs ...*aws.Config) (*Session, error) {
|
|
| 98 |
+ envCfg := loadEnvConfig() |
|
| 99 |
+ |
|
| 100 |
+ return newSession(envCfg, cfgs...) |
|
| 101 |
+} |
|
| 102 |
+ |
|
| 103 |
+// SharedConfigState provides the ability to optionally override the state |
|
| 104 |
+// of the session's creation based on the shared config being enabled or |
|
| 105 |
+// disabled. |
|
| 106 |
+type SharedConfigState int |
|
| 107 |
+ |
|
| 108 |
+const ( |
|
| 109 |
+ // SharedConfigStateFromEnv does not override any state of the |
|
| 110 |
+ // AWS_SDK_LOAD_CONFIG env var. It is the default value of the |
|
| 111 |
+ // SharedConfigState type. |
|
| 112 |
+ SharedConfigStateFromEnv SharedConfigState = iota |
|
| 113 |
+ |
|
| 114 |
+ // SharedConfigDisable overrides the AWS_SDK_LOAD_CONFIG env var value |
|
| 115 |
+ // and disables the shared config functionality. |
|
| 116 |
+ SharedConfigDisable |
|
| 117 |
+ |
|
| 118 |
+ // SharedConfigEnable overrides the AWS_SDK_LOAD_CONFIG env var value |
|
| 119 |
+ // and enables the shared config functionality. |
|
| 120 |
+ SharedConfigEnable |
|
| 121 |
+) |
|
| 122 |
+ |
|
| 123 |
+// Options provides the means to control how a Session is created and what |
|
| 124 |
+// configuration values will be loaded. |
|
| 125 |
+// |
|
| 126 |
+type Options struct {
|
|
| 127 |
+ // Provides config values for the SDK to use when creating service clients |
|
| 128 |
+ // and making API requests to services. Any value set in with this field |
|
| 129 |
+ // will override the associated value provided by the SDK defaults, |
|
| 130 |
+ // environment or config files where relevent. |
|
| 131 |
+ // |
|
| 132 |
+ // If not set, configuration values from from SDK defaults, environment, |
|
| 133 |
+ // config will be used. |
|
| 134 |
+ Config aws.Config |
|
| 135 |
+ |
|
| 136 |
+ // Overrides the config profile the Session should be created from. If not |
|
| 137 |
+ // set the value of the environment variable will be loaded (AWS_PROFILE, |
|
| 138 |
+ // or AWS_DEFAULT_PROFILE if the Shared Config is enabled). |
|
| 139 |
+ // |
|
| 140 |
+ // If not set and environment variables are not set the "default" |
|
| 141 |
+ // (DefaultSharedConfigProfile) will be used as the profile to load the |
|
| 142 |
+ // session config from. |
|
| 143 |
+ Profile string |
|
| 144 |
+ |
|
| 145 |
+ // Instructs how the Session will be created based on the AWS_SDK_LOAD_CONFIG |
|
| 146 |
+ // environment variable. By default a Session will be created using the |
|
| 147 |
+ // value provided by the AWS_SDK_LOAD_CONFIG environment variable. |
|
| 148 |
+ // |
|
| 149 |
+ // Setting this value to SharedConfigEnable or SharedConfigDisable |
|
| 150 |
+ // will allow you to override the AWS_SDK_LOAD_CONFIG environment variable |
|
| 151 |
+ // and enable or disable the shared config functionality. |
|
| 152 |
+ SharedConfigState SharedConfigState |
|
| 153 |
+} |
|
| 154 |
+ |
|
| 155 |
+// NewSessionWithOptions returns a new Session created from SDK defaults, config files, |
|
| 156 |
+// environment, and user provided config files. This func uses the Options |
|
| 157 |
+// values to configure how the Session is created. |
|
| 34 | 158 |
// |
| 35 |
-// Example: |
|
| 36 |
-// // Create a session with the default config and request handlers. |
|
| 37 |
-// sess := session.New() |
|
| 159 |
+// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value |
|
| 160 |
+// the shared config file (~/.aws/config) will also be loaded in addition to |
|
| 161 |
+// the shared credentials file (~/.aws/config). Values set in both the |
|
| 162 |
+// shared config, and shared credentials will be taken from the shared |
|
| 163 |
+// credentials file. Enabling the Shared Config will also allow the Session |
|
| 164 |
+// to be built with retrieving credentials with AssumeRole set in the config. |
|
| 38 | 165 |
// |
| 39 |
-// // Create a session with a custom region |
|
| 40 |
-// sess := session.New(&aws.Config{Region: aws.String("us-east-1")})
|
|
| 166 |
+// // Equivalent to session.New |
|
| 167 |
+// sess, err := session.NewSessionWithOptions(session.Options{})
|
|
| 41 | 168 |
// |
| 42 |
-// // Create a session, and add additional handlers for all service |
|
| 43 |
-// // clients created with the session to inherit. Adds logging handler. |
|
| 44 |
-// sess := session.New() |
|
| 45 |
-// sess.Handlers.Send.PushFront(func(r *request.Request) {
|
|
| 46 |
-// // Log every request made and its payload |
|
| 47 |
-// logger.Println("Request: %s/%s, Payload: %s", r.ClientInfo.ServiceName, r.Operation, r.Params)
|
|
| 169 |
+// // Specify profile to load for the session's config |
|
| 170 |
+// sess, err := session.NewSessionWithOptions(session.Options{
|
|
| 171 |
+// Profile: "profile_name", |
|
| 48 | 172 |
// }) |
| 49 | 173 |
// |
| 50 |
-// // Create a S3 client instance from a session |
|
| 51 |
-// sess := session.New() |
|
| 52 |
-// svc := s3.New(sess) |
|
| 53 |
-func New(cfgs ...*aws.Config) *Session {
|
|
| 174 |
+// // Specify profile for config and region for requests |
|
| 175 |
+// sess, err := session.NewSessionWithOptions(session.Options{
|
|
| 176 |
+// Config: aws.Config{Region: aws.String("us-east-1")},
|
|
| 177 |
+// Profile: "profile_name", |
|
| 178 |
+// }) |
|
| 179 |
+// |
|
| 180 |
+// // Force enable Shared Config support |
|
| 181 |
+// sess, err := session.NewSessionWithOptions(session.Options{
|
|
| 182 |
+// SharedConfigState: SharedConfigEnable, |
|
| 183 |
+// }) |
|
| 184 |
+func NewSessionWithOptions(opts Options) (*Session, error) {
|
|
| 185 |
+ var envCfg envConfig |
|
| 186 |
+ if opts.SharedConfigState == SharedConfigEnable {
|
|
| 187 |
+ envCfg = loadSharedEnvConfig() |
|
| 188 |
+ } else {
|
|
| 189 |
+ envCfg = loadEnvConfig() |
|
| 190 |
+ } |
|
| 191 |
+ |
|
| 192 |
+ if len(opts.Profile) > 0 {
|
|
| 193 |
+ envCfg.Profile = opts.Profile |
|
| 194 |
+ } |
|
| 195 |
+ |
|
| 196 |
+ switch opts.SharedConfigState {
|
|
| 197 |
+ case SharedConfigDisable: |
|
| 198 |
+ envCfg.EnableSharedConfig = false |
|
| 199 |
+ case SharedConfigEnable: |
|
| 200 |
+ envCfg.EnableSharedConfig = true |
|
| 201 |
+ } |
|
| 202 |
+ |
|
| 203 |
+ return newSession(envCfg, &opts.Config) |
|
| 204 |
+} |
|
| 205 |
+ |
|
| 206 |
+// Must is a helper function to ensure the Session is valid and there was no |
|
| 207 |
+// error when calling a NewSession function. |
|
| 208 |
+// |
|
| 209 |
+// This helper is intended to be used in variable initialization to load the |
|
| 210 |
+// Session and configuration at startup. Such as: |
|
| 211 |
+// |
|
| 212 |
+// var sess = session.Must(session.NewSession()) |
|
| 213 |
+func Must(sess *Session, err error) *Session {
|
|
| 214 |
+ if err != nil {
|
|
| 215 |
+ panic(err) |
|
| 216 |
+ } |
|
| 217 |
+ |
|
| 218 |
+ return sess |
|
| 219 |
+} |
|
| 220 |
+ |
|
| 221 |
+func oldNewSession(cfgs ...*aws.Config) *Session {
|
|
| 54 | 222 |
cfg := defaults.Config() |
| 55 | 223 |
handlers := defaults.Handlers() |
| 56 | 224 |
|
| ... | ... |
@@ -72,6 +237,115 @@ func New(cfgs ...*aws.Config) *Session {
|
| 72 | 72 |
return s |
| 73 | 73 |
} |
| 74 | 74 |
|
| 75 |
+func newSession(envCfg envConfig, cfgs ...*aws.Config) (*Session, error) {
|
|
| 76 |
+ cfg := defaults.Config() |
|
| 77 |
+ handlers := defaults.Handlers() |
|
| 78 |
+ |
|
| 79 |
+ // Get a merged version of the user provided config to determine if |
|
| 80 |
+ // credentials were. |
|
| 81 |
+ userCfg := &aws.Config{}
|
|
| 82 |
+ userCfg.MergeIn(cfgs...) |
|
| 83 |
+ |
|
| 84 |
+ // Order config files will be loaded in with later files overwriting |
|
| 85 |
+ // previous config file values. |
|
| 86 |
+ cfgFiles := []string{envCfg.SharedConfigFile, envCfg.SharedCredentialsFile}
|
|
| 87 |
+ if !envCfg.EnableSharedConfig {
|
|
| 88 |
+ // The shared config file (~/.aws/config) is only loaded if instructed |
|
| 89 |
+ // to load via the envConfig.EnableSharedConfig (AWS_SDK_LOAD_CONFIG). |
|
| 90 |
+ cfgFiles = cfgFiles[1:] |
|
| 91 |
+ } |
|
| 92 |
+ |
|
| 93 |
+ // Load additional config from file(s) |
|
| 94 |
+ sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles) |
|
| 95 |
+ if err != nil {
|
|
| 96 |
+ return nil, err |
|
| 97 |
+ } |
|
| 98 |
+ |
|
| 99 |
+ mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers) |
|
| 100 |
+ |
|
| 101 |
+ s := &Session{
|
|
| 102 |
+ Config: cfg, |
|
| 103 |
+ Handlers: handlers, |
|
| 104 |
+ } |
|
| 105 |
+ |
|
| 106 |
+ initHandlers(s) |
|
| 107 |
+ |
|
| 108 |
+ return s, nil |
|
| 109 |
+} |
|
| 110 |
+ |
|
| 111 |
+func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers) {
|
|
| 112 |
+ // Merge in user provided configuration |
|
| 113 |
+ cfg.MergeIn(userCfg) |
|
| 114 |
+ |
|
| 115 |
+ // Region if not already set by user |
|
| 116 |
+ if len(aws.StringValue(cfg.Region)) == 0 {
|
|
| 117 |
+ if len(envCfg.Region) > 0 {
|
|
| 118 |
+ cfg.WithRegion(envCfg.Region) |
|
| 119 |
+ } else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 {
|
|
| 120 |
+ cfg.WithRegion(sharedCfg.Region) |
|
| 121 |
+ } |
|
| 122 |
+ } |
|
| 123 |
+ |
|
| 124 |
+ // Configure credentials if not already set |
|
| 125 |
+ if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil {
|
|
| 126 |
+ if len(envCfg.Creds.AccessKeyID) > 0 {
|
|
| 127 |
+ cfg.Credentials = credentials.NewStaticCredentialsFromCreds( |
|
| 128 |
+ envCfg.Creds, |
|
| 129 |
+ ) |
|
| 130 |
+ } else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil {
|
|
| 131 |
+ cfgCp := *cfg |
|
| 132 |
+ cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds( |
|
| 133 |
+ sharedCfg.AssumeRoleSource.Creds, |
|
| 134 |
+ ) |
|
| 135 |
+ cfg.Credentials = stscreds.NewCredentials( |
|
| 136 |
+ &Session{
|
|
| 137 |
+ Config: &cfgCp, |
|
| 138 |
+ Handlers: handlers.Copy(), |
|
| 139 |
+ }, |
|
| 140 |
+ sharedCfg.AssumeRole.RoleARN, |
|
| 141 |
+ func(opt *stscreds.AssumeRoleProvider) {
|
|
| 142 |
+ opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName |
|
| 143 |
+ |
|
| 144 |
+ if len(sharedCfg.AssumeRole.ExternalID) > 0 {
|
|
| 145 |
+ opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID) |
|
| 146 |
+ } |
|
| 147 |
+ |
|
| 148 |
+ // MFA not supported |
|
| 149 |
+ }, |
|
| 150 |
+ ) |
|
| 151 |
+ } else if len(sharedCfg.Creds.AccessKeyID) > 0 {
|
|
| 152 |
+ cfg.Credentials = credentials.NewStaticCredentialsFromCreds( |
|
| 153 |
+ sharedCfg.Creds, |
|
| 154 |
+ ) |
|
| 155 |
+ } else {
|
|
| 156 |
+ // Fallback to default credentials provider, include mock errors |
|
| 157 |
+ // for the credential chain so user can identify why credentials |
|
| 158 |
+ // failed to be retrieved. |
|
| 159 |
+ cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{
|
|
| 160 |
+ VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), |
|
| 161 |
+ Providers: []credentials.Provider{
|
|
| 162 |
+ &credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)},
|
|
| 163 |
+ &credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)},
|
|
| 164 |
+ defaults.RemoteCredProvider(*cfg, handlers), |
|
| 165 |
+ }, |
|
| 166 |
+ }) |
|
| 167 |
+ } |
|
| 168 |
+ } |
|
| 169 |
+} |
|
| 170 |
+ |
|
| 171 |
+type credProviderError struct {
|
|
| 172 |
+ Err error |
|
| 173 |
+} |
|
| 174 |
+ |
|
| 175 |
+var emptyCreds = credentials.Value{}
|
|
| 176 |
+ |
|
| 177 |
+func (c credProviderError) Retrieve() (credentials.Value, error) {
|
|
| 178 |
+ return credentials.Value{}, c.Err
|
|
| 179 |
+} |
|
| 180 |
+func (c credProviderError) IsExpired() bool {
|
|
| 181 |
+ return true |
|
| 182 |
+} |
|
| 183 |
+ |
|
| 75 | 184 |
func initHandlers(s *Session) {
|
| 76 | 185 |
// Add the Validate parameter handler if it is not disabled. |
| 77 | 186 |
s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler) |
| ... | ... |
@@ -80,12 +354,11 @@ func initHandlers(s *Session) {
|
| 80 | 80 |
} |
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 |
-// Copy creates and returns a copy of the current session, coping the config |
|
| 83 |
+// Copy creates and returns a copy of the current Session, coping the config |
|
| 84 | 84 |
// and handlers. If any additional configs are provided they will be merged |
| 85 |
-// on top of the session's copied config. |
|
| 85 |
+// on top of the Session's copied config. |
|
| 86 | 86 |
// |
| 87 |
-// Example: |
|
| 88 |
-// // Create a copy of the current session, configured for the us-west-2 region. |
|
| 87 |
+// // Create a copy of the current Session, configured for the us-west-2 region. |
|
| 89 | 88 |
// sess.Copy(&aws.Config{Region: aws.String("us-west-2")})
|
| 90 | 89 |
func (s *Session) Copy(cfgs ...*aws.Config) *Session {
|
| 91 | 90 |
newSession := &Session{
|
| ... | ... |
@@ -101,15 +374,15 @@ func (s *Session) Copy(cfgs ...*aws.Config) *Session {
|
| 101 | 101 |
// ClientConfig satisfies the client.ConfigProvider interface and is used to |
| 102 | 102 |
// configure the service client instances. Passing the Session to the service |
| 103 | 103 |
// client's constructor (New) will use this method to configure the client. |
| 104 |
-// |
|
| 105 |
-// Example: |
|
| 106 |
-// sess := session.New() |
|
| 107 |
-// s3.New(sess) |
|
| 108 | 104 |
func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config {
|
| 109 | 105 |
s = s.Copy(cfgs...) |
| 110 | 106 |
endpoint, signingRegion := endpoints.NormalizeEndpoint( |
| 111 |
- aws.StringValue(s.Config.Endpoint), serviceName, |
|
| 112 |
- aws.StringValue(s.Config.Region), aws.BoolValue(s.Config.DisableSSL)) |
|
| 107 |
+ aws.StringValue(s.Config.Endpoint), |
|
| 108 |
+ serviceName, |
|
| 109 |
+ aws.StringValue(s.Config.Region), |
|
| 110 |
+ aws.BoolValue(s.Config.DisableSSL), |
|
| 111 |
+ aws.BoolValue(s.Config.UseDualStack), |
|
| 112 |
+ ) |
|
| 113 | 113 |
|
| 114 | 114 |
return client.Config{
|
| 115 | 115 |
Config: s.Config, |
| 116 | 116 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,295 @@ |
| 0 |
+package session |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "io/ioutil" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/aws/aws-sdk-go/aws/awserr" |
|
| 7 |
+ "github.com/aws/aws-sdk-go/aws/credentials" |
|
| 8 |
+ "github.com/go-ini/ini" |
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+const ( |
|
| 12 |
+ // Static Credentials group |
|
| 13 |
+ accessKeyIDKey = `aws_access_key_id` // group required |
|
| 14 |
+ secretAccessKey = `aws_secret_access_key` // group required |
|
| 15 |
+ sessionTokenKey = `aws_session_token` // optional |
|
| 16 |
+ |
|
| 17 |
+ // Assume Role Credentials group |
|
| 18 |
+ roleArnKey = `role_arn` // group required |
|
| 19 |
+ sourceProfileKey = `source_profile` // group required |
|
| 20 |
+ externalIDKey = `external_id` // optional |
|
| 21 |
+ mfaSerialKey = `mfa_serial` // optional |
|
| 22 |
+ roleSessionNameKey = `role_session_name` // optional |
|
| 23 |
+ |
|
| 24 |
+ // Additional Config fields |
|
| 25 |
+ regionKey = `region` |
|
| 26 |
+ |
|
| 27 |
+ // DefaultSharedConfigProfile is the default profile to be used when |
|
| 28 |
+ // loading configuration from the config files if another profile name |
|
| 29 |
+ // is not provided. |
|
| 30 |
+ DefaultSharedConfigProfile = `default` |
|
| 31 |
+) |
|
| 32 |
+ |
|
| 33 |
+type assumeRoleConfig struct {
|
|
| 34 |
+ RoleARN string |
|
| 35 |
+ SourceProfile string |
|
| 36 |
+ ExternalID string |
|
| 37 |
+ MFASerial string |
|
| 38 |
+ RoleSessionName string |
|
| 39 |
+} |
|
| 40 |
+ |
|
| 41 |
+// sharedConfig represents the configuration fields of the SDK config files. |
|
| 42 |
+type sharedConfig struct {
|
|
| 43 |
+ // Credentials values from the config file. Both aws_access_key_id |
|
| 44 |
+ // and aws_secret_access_key must be provided together in the same file |
|
| 45 |
+ // to be considered valid. The values will be ignored if not a complete group. |
|
| 46 |
+ // aws_session_token is an optional field that can be provided if both of the |
|
| 47 |
+ // other two fields are also provided. |
|
| 48 |
+ // |
|
| 49 |
+ // aws_access_key_id |
|
| 50 |
+ // aws_secret_access_key |
|
| 51 |
+ // aws_session_token |
|
| 52 |
+ Creds credentials.Value |
|
| 53 |
+ |
|
| 54 |
+ AssumeRole assumeRoleConfig |
|
| 55 |
+ AssumeRoleSource *sharedConfig |
|
| 56 |
+ |
|
| 57 |
+ // Region is the region the SDK should use for looking up AWS service endpoints |
|
| 58 |
+ // and signing requests. |
|
| 59 |
+ // |
|
| 60 |
+ // region |
|
| 61 |
+ Region string |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+type sharedConfigFile struct {
|
|
| 65 |
+ Filename string |
|
| 66 |
+ IniData *ini.File |
|
| 67 |
+} |
|
| 68 |
+ |
|
| 69 |
+// loadSharedConfig retrieves the configuration from the list of files |
|
| 70 |
+// using the profile provided. The order the files are listed will determine |
|
| 71 |
+// precedence. Values in subsequent files will overwrite values defined in |
|
| 72 |
+// earlier files. |
|
| 73 |
+// |
|
| 74 |
+// For example, given two files A and B. Both define credentials. If the order |
|
| 75 |
+// of the files are A then B, B's credential values will be used instead of A's. |
|
| 76 |
+// |
|
| 77 |
+// See sharedConfig.setFromFile for information how the config files |
|
| 78 |
+// will be loaded. |
|
| 79 |
+func loadSharedConfig(profile string, filenames []string) (sharedConfig, error) {
|
|
| 80 |
+ if len(profile) == 0 {
|
|
| 81 |
+ profile = DefaultSharedConfigProfile |
|
| 82 |
+ } |
|
| 83 |
+ |
|
| 84 |
+ files, err := loadSharedConfigIniFiles(filenames) |
|
| 85 |
+ if err != nil {
|
|
| 86 |
+ return sharedConfig{}, err
|
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ cfg := sharedConfig{}
|
|
| 90 |
+ if err = cfg.setFromIniFiles(profile, files); err != nil {
|
|
| 91 |
+ return sharedConfig{}, err
|
|
| 92 |
+ } |
|
| 93 |
+ |
|
| 94 |
+ if len(cfg.AssumeRole.SourceProfile) > 0 {
|
|
| 95 |
+ if err := cfg.setAssumeRoleSource(profile, files); err != nil {
|
|
| 96 |
+ return sharedConfig{}, err
|
|
| 97 |
+ } |
|
| 98 |
+ } |
|
| 99 |
+ |
|
| 100 |
+ return cfg, nil |
|
| 101 |
+} |
|
| 102 |
+ |
|
| 103 |
+func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) {
|
|
| 104 |
+ files := make([]sharedConfigFile, 0, len(filenames)) |
|
| 105 |
+ |
|
| 106 |
+ for _, filename := range filenames {
|
|
| 107 |
+ b, err := ioutil.ReadFile(filename) |
|
| 108 |
+ if err != nil {
|
|
| 109 |
+ // Skip files which can't be opened and read for whatever reason |
|
| 110 |
+ continue |
|
| 111 |
+ } |
|
| 112 |
+ |
|
| 113 |
+ f, err := ini.Load(b) |
|
| 114 |
+ if err != nil {
|
|
| 115 |
+ return nil, SharedConfigLoadError{Filename: filename}
|
|
| 116 |
+ } |
|
| 117 |
+ |
|
| 118 |
+ files = append(files, sharedConfigFile{
|
|
| 119 |
+ Filename: filename, IniData: f, |
|
| 120 |
+ }) |
|
| 121 |
+ } |
|
| 122 |
+ |
|
| 123 |
+ return files, nil |
|
| 124 |
+} |
|
| 125 |
+ |
|
| 126 |
+func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error {
|
|
| 127 |
+ var assumeRoleSrc sharedConfig |
|
| 128 |
+ |
|
| 129 |
+ // Multiple level assume role chains are not support |
|
| 130 |
+ if cfg.AssumeRole.SourceProfile == origProfile {
|
|
| 131 |
+ assumeRoleSrc = *cfg |
|
| 132 |
+ assumeRoleSrc.AssumeRole = assumeRoleConfig{}
|
|
| 133 |
+ } else {
|
|
| 134 |
+ err := assumeRoleSrc.setFromIniFiles(cfg.AssumeRole.SourceProfile, files) |
|
| 135 |
+ if err != nil {
|
|
| 136 |
+ return err |
|
| 137 |
+ } |
|
| 138 |
+ } |
|
| 139 |
+ |
|
| 140 |
+ if len(assumeRoleSrc.Creds.AccessKeyID) == 0 {
|
|
| 141 |
+ return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN}
|
|
| 142 |
+ } |
|
| 143 |
+ |
|
| 144 |
+ cfg.AssumeRoleSource = &assumeRoleSrc |
|
| 145 |
+ |
|
| 146 |
+ return nil |
|
| 147 |
+} |
|
| 148 |
+ |
|
| 149 |
+func (cfg *sharedConfig) setFromIniFiles(profile string, files []sharedConfigFile) error {
|
|
| 150 |
+ // Trim files from the list that don't exist. |
|
| 151 |
+ for _, f := range files {
|
|
| 152 |
+ if err := cfg.setFromIniFile(profile, f); err != nil {
|
|
| 153 |
+ if _, ok := err.(SharedConfigProfileNotExistsError); ok {
|
|
| 154 |
+ // Ignore proviles missings |
|
| 155 |
+ continue |
|
| 156 |
+ } |
|
| 157 |
+ return err |
|
| 158 |
+ } |
|
| 159 |
+ } |
|
| 160 |
+ |
|
| 161 |
+ return nil |
|
| 162 |
+} |
|
| 163 |
+ |
|
| 164 |
+// setFromFile loads the configuration from the file using |
|
| 165 |
+// the profile provided. A sharedConfig pointer type value is used so that |
|
| 166 |
+// multiple config file loadings can be chained. |
|
| 167 |
+// |
|
| 168 |
+// Only loads complete logically grouped values, and will not set fields in cfg |
|
| 169 |
+// for incomplete grouped values in the config. Such as credentials. For example |
|
| 170 |
+// if a config file only includes aws_access_key_id but no aws_secret_access_key |
|
| 171 |
+// the aws_access_key_id will be ignored. |
|
| 172 |
+func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error {
|
|
| 173 |
+ section, err := file.IniData.GetSection(profile) |
|
| 174 |
+ if err != nil {
|
|
| 175 |
+ // Fallback to to alternate profile name: profile <name> |
|
| 176 |
+ section, err = file.IniData.GetSection(fmt.Sprintf("profile %s", profile))
|
|
| 177 |
+ if err != nil {
|
|
| 178 |
+ return SharedConfigProfileNotExistsError{Profile: profile, Err: err}
|
|
| 179 |
+ } |
|
| 180 |
+ } |
|
| 181 |
+ |
|
| 182 |
+ // Shared Credentials |
|
| 183 |
+ akid := section.Key(accessKeyIDKey).String() |
|
| 184 |
+ secret := section.Key(secretAccessKey).String() |
|
| 185 |
+ if len(akid) > 0 && len(secret) > 0 {
|
|
| 186 |
+ cfg.Creds = credentials.Value{
|
|
| 187 |
+ AccessKeyID: akid, |
|
| 188 |
+ SecretAccessKey: secret, |
|
| 189 |
+ SessionToken: section.Key(sessionTokenKey).String(), |
|
| 190 |
+ ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename),
|
|
| 191 |
+ } |
|
| 192 |
+ } |
|
| 193 |
+ |
|
| 194 |
+ // Assume Role |
|
| 195 |
+ roleArn := section.Key(roleArnKey).String() |
|
| 196 |
+ srcProfile := section.Key(sourceProfileKey).String() |
|
| 197 |
+ if len(roleArn) > 0 && len(srcProfile) > 0 {
|
|
| 198 |
+ cfg.AssumeRole = assumeRoleConfig{
|
|
| 199 |
+ RoleARN: roleArn, |
|
| 200 |
+ SourceProfile: srcProfile, |
|
| 201 |
+ ExternalID: section.Key(externalIDKey).String(), |
|
| 202 |
+ MFASerial: section.Key(mfaSerialKey).String(), |
|
| 203 |
+ RoleSessionName: section.Key(roleSessionNameKey).String(), |
|
| 204 |
+ } |
|
| 205 |
+ } |
|
| 206 |
+ |
|
| 207 |
+ // Region |
|
| 208 |
+ if v := section.Key(regionKey).String(); len(v) > 0 {
|
|
| 209 |
+ cfg.Region = v |
|
| 210 |
+ } |
|
| 211 |
+ |
|
| 212 |
+ return nil |
|
| 213 |
+} |
|
| 214 |
+ |
|
| 215 |
+// SharedConfigLoadError is an error for the shared config file failed to load. |
|
| 216 |
+type SharedConfigLoadError struct {
|
|
| 217 |
+ Filename string |
|
| 218 |
+ Err error |
|
| 219 |
+} |
|
| 220 |
+ |
|
| 221 |
+// Code is the short id of the error. |
|
| 222 |
+func (e SharedConfigLoadError) Code() string {
|
|
| 223 |
+ return "SharedConfigLoadError" |
|
| 224 |
+} |
|
| 225 |
+ |
|
| 226 |
+// Message is the description of the error |
|
| 227 |
+func (e SharedConfigLoadError) Message() string {
|
|
| 228 |
+ return fmt.Sprintf("failed to load config file, %s", e.Filename)
|
|
| 229 |
+} |
|
| 230 |
+ |
|
| 231 |
+// OrigErr is the underlying error that caused the failure. |
|
| 232 |
+func (e SharedConfigLoadError) OrigErr() error {
|
|
| 233 |
+ return e.Err |
|
| 234 |
+} |
|
| 235 |
+ |
|
| 236 |
+// Error satisfies the error interface. |
|
| 237 |
+func (e SharedConfigLoadError) Error() string {
|
|
| 238 |
+ return awserr.SprintError(e.Code(), e.Message(), "", e.Err) |
|
| 239 |
+} |
|
| 240 |
+ |
|
| 241 |
+// SharedConfigProfileNotExistsError is an error for the shared config when |
|
| 242 |
+// the profile was not find in the config file. |
|
| 243 |
+type SharedConfigProfileNotExistsError struct {
|
|
| 244 |
+ Profile string |
|
| 245 |
+ Err error |
|
| 246 |
+} |
|
| 247 |
+ |
|
| 248 |
+// Code is the short id of the error. |
|
| 249 |
+func (e SharedConfigProfileNotExistsError) Code() string {
|
|
| 250 |
+ return "SharedConfigProfileNotExistsError" |
|
| 251 |
+} |
|
| 252 |
+ |
|
| 253 |
+// Message is the description of the error |
|
| 254 |
+func (e SharedConfigProfileNotExistsError) Message() string {
|
|
| 255 |
+ return fmt.Sprintf("failed to get profile, %s", e.Profile)
|
|
| 256 |
+} |
|
| 257 |
+ |
|
| 258 |
+// OrigErr is the underlying error that caused the failure. |
|
| 259 |
+func (e SharedConfigProfileNotExistsError) OrigErr() error {
|
|
| 260 |
+ return e.Err |
|
| 261 |
+} |
|
| 262 |
+ |
|
| 263 |
+// Error satisfies the error interface. |
|
| 264 |
+func (e SharedConfigProfileNotExistsError) Error() string {
|
|
| 265 |
+ return awserr.SprintError(e.Code(), e.Message(), "", e.Err) |
|
| 266 |
+} |
|
| 267 |
+ |
|
| 268 |
+// SharedConfigAssumeRoleError is an error for the shared config when the |
|
| 269 |
+// profile contains assume role information, but that information is invalid |
|
| 270 |
+// or not complete. |
|
| 271 |
+type SharedConfigAssumeRoleError struct {
|
|
| 272 |
+ RoleARN string |
|
| 273 |
+} |
|
| 274 |
+ |
|
| 275 |
+// Code is the short id of the error. |
|
| 276 |
+func (e SharedConfigAssumeRoleError) Code() string {
|
|
| 277 |
+ return "SharedConfigAssumeRoleError" |
|
| 278 |
+} |
|
| 279 |
+ |
|
| 280 |
+// Message is the description of the error |
|
| 281 |
+func (e SharedConfigAssumeRoleError) Message() string {
|
|
| 282 |
+ return fmt.Sprintf("failed to load assume role for %s, source profile has no shared credentials",
|
|
| 283 |
+ e.RoleARN) |
|
| 284 |
+} |
|
| 285 |
+ |
|
| 286 |
+// OrigErr is the underlying error that caused the failure. |
|
| 287 |
+func (e SharedConfigAssumeRoleError) OrigErr() error {
|
|
| 288 |
+ return nil |
|
| 289 |
+} |
|
| 290 |
+ |
|
| 291 |
+// Error satisfies the error interface. |
|
| 292 |
+func (e SharedConfigAssumeRoleError) Error() string {
|
|
| 293 |
+ return awserr.SprintError(e.Code(), e.Message(), "", nil) |
|
| 294 |
+} |
| 0 | 295 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,82 @@ |
| 0 |
+package v4 |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "net/http" |
|
| 4 |
+ "strings" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+// validator houses a set of rule needed for validation of a |
|
| 8 |
+// string value |
|
| 9 |
+type rules []rule |
|
| 10 |
+ |
|
| 11 |
+// rule interface allows for more flexible rules and just simply |
|
| 12 |
+// checks whether or not a value adheres to that rule |
|
| 13 |
+type rule interface {
|
|
| 14 |
+ IsValid(value string) bool |
|
| 15 |
+} |
|
| 16 |
+ |
|
| 17 |
+// IsValid will iterate through all rules and see if any rules |
|
| 18 |
+// apply to the value and supports nested rules |
|
| 19 |
+func (r rules) IsValid(value string) bool {
|
|
| 20 |
+ for _, rule := range r {
|
|
| 21 |
+ if rule.IsValid(value) {
|
|
| 22 |
+ return true |
|
| 23 |
+ } |
|
| 24 |
+ } |
|
| 25 |
+ return false |
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+// mapRule generic rule for maps |
|
| 29 |
+type mapRule map[string]struct{}
|
|
| 30 |
+ |
|
| 31 |
+// IsValid for the map rule satisfies whether it exists in the map |
|
| 32 |
+func (m mapRule) IsValid(value string) bool {
|
|
| 33 |
+ _, ok := m[value] |
|
| 34 |
+ return ok |
|
| 35 |
+} |
|
| 36 |
+ |
|
| 37 |
+// whitelist is a generic rule for whitelisting |
|
| 38 |
+type whitelist struct {
|
|
| 39 |
+ rule |
|
| 40 |
+} |
|
| 41 |
+ |
|
| 42 |
+// IsValid for whitelist checks if the value is within the whitelist |
|
| 43 |
+func (w whitelist) IsValid(value string) bool {
|
|
| 44 |
+ return w.rule.IsValid(value) |
|
| 45 |
+} |
|
| 46 |
+ |
|
| 47 |
+// blacklist is a generic rule for blacklisting |
|
| 48 |
+type blacklist struct {
|
|
| 49 |
+ rule |
|
| 50 |
+} |
|
| 51 |
+ |
|
| 52 |
+// IsValid for whitelist checks if the value is within the whitelist |
|
| 53 |
+func (b blacklist) IsValid(value string) bool {
|
|
| 54 |
+ return !b.rule.IsValid(value) |
|
| 55 |
+} |
|
| 56 |
+ |
|
| 57 |
+type patterns []string |
|
| 58 |
+ |
|
| 59 |
+// IsValid for patterns checks each pattern and returns if a match has |
|
| 60 |
+// been found |
|
| 61 |
+func (p patterns) IsValid(value string) bool {
|
|
| 62 |
+ for _, pattern := range p {
|
|
| 63 |
+ if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) {
|
|
| 64 |
+ return true |
|
| 65 |
+ } |
|
| 66 |
+ } |
|
| 67 |
+ return false |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+// inclusiveRules rules allow for rules to depend on one another |
|
| 71 |
+type inclusiveRules []rule |
|
| 72 |
+ |
|
| 73 |
+// IsValid will return true if all rules are true |
|
| 74 |
+func (r inclusiveRules) IsValid(value string) bool {
|
|
| 75 |
+ for _, rule := range r {
|
|
| 76 |
+ if !rule.IsValid(value) {
|
|
| 77 |
+ return false |
|
| 78 |
+ } |
|
| 79 |
+ } |
|
| 80 |
+ return true |
|
| 81 |
+} |
| 0 | 82 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,24 @@ |
| 0 |
+// +build go1.5 |
|
| 1 |
+ |
|
| 2 |
+package v4 |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "net/url" |
|
| 6 |
+ "strings" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+func getURIPath(u *url.URL) string {
|
|
| 10 |
+ var uri string |
|
| 11 |
+ |
|
| 12 |
+ if len(u.Opaque) > 0 {
|
|
| 13 |
+ uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/") |
|
| 14 |
+ } else {
|
|
| 15 |
+ uri = u.EscapedPath() |
|
| 16 |
+ } |
|
| 17 |
+ |
|
| 18 |
+ if len(uri) == 0 {
|
|
| 19 |
+ uri = "/" |
|
| 20 |
+ } |
|
| 21 |
+ |
|
| 22 |
+ return uri |
|
| 23 |
+} |
| 0 | 24 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,24 @@ |
| 0 |
+// +build !go1.5 |
|
| 1 |
+ |
|
| 2 |
+package v4 |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "net/url" |
|
| 6 |
+ "strings" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+func getURIPath(u *url.URL) string {
|
|
| 10 |
+ var uri string |
|
| 11 |
+ |
|
| 12 |
+ if len(u.Opaque) > 0 {
|
|
| 13 |
+ uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/") |
|
| 14 |
+ } else {
|
|
| 15 |
+ uri = u.Path |
|
| 16 |
+ } |
|
| 17 |
+ |
|
| 18 |
+ if len(uri) == 0 {
|
|
| 19 |
+ uri = "/" |
|
| 20 |
+ } |
|
| 21 |
+ |
|
| 22 |
+ return uri |
|
| 23 |
+} |
| 0 | 24 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,713 @@ |
| 0 |
+// Package v4 implements signing for AWS V4 signer |
|
| 1 |
+// |
|
| 2 |
+// Provides request signing for request that need to be signed with |
|
| 3 |
+// AWS V4 Signatures. |
|
| 4 |
+// |
|
| 5 |
+// Standalone Signer |
|
| 6 |
+// |
|
| 7 |
+// Generally using the signer outside of the SDK should not require any additional |
|
| 8 |
+// logic when using Go v1.5 or higher. The signer does this by taking advantage |
|
| 9 |
+// of the URL.EscapedPath method. If your request URI requires additional escaping |
|
| 10 |
+// you many need to use the URL.Opaque to define what the raw URI should be sent |
|
| 11 |
+// to the service as. |
|
| 12 |
+// |
|
| 13 |
+// The signer will first check the URL.Opaque field, and use its value if set. |
|
| 14 |
+// The signer does require the URL.Opaque field to be set in the form of: |
|
| 15 |
+// |
|
| 16 |
+// "//<hostname>/<path>" |
|
| 17 |
+// |
|
| 18 |
+// // e.g. |
|
| 19 |
+// "//example.com/some/path" |
|
| 20 |
+// |
|
| 21 |
+// The leading "//" and hostname are required or the URL.Opaque escaping will |
|
| 22 |
+// not work correctly. |
|
| 23 |
+// |
|
| 24 |
+// If URL.Opaque is not set the signer will fallback to the URL.EscapedPath() |
|
| 25 |
+// method and using the returned value. If you're using Go v1.4 you must set |
|
| 26 |
+// URL.Opaque if the URI path needs escaping. If URL.Opaque is not set with |
|
| 27 |
+// Go v1.5 the signer will fallback to URL.Path. |
|
| 28 |
+// |
|
| 29 |
+// AWS v4 signature validation requires that the canonical string's URI path |
|
| 30 |
+// element must be the URI escaped form of the HTTP request's path. |
|
| 31 |
+// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html |
|
| 32 |
+// |
|
| 33 |
+// The Go HTTP client will perform escaping automatically on the request. Some |
|
| 34 |
+// of these escaping may cause signature validation errors because the HTTP |
|
| 35 |
+// request differs from the URI path or query that the signature was generated. |
|
| 36 |
+// https://golang.org/pkg/net/url/#URL.EscapedPath |
|
| 37 |
+// |
|
| 38 |
+// Because of this, it is recommended that when using the signer outside of the |
|
| 39 |
+// SDK that explicitly escaping the request prior to being signed is preferable, |
|
| 40 |
+// and will help prevent signature validation errors. This can be done by setting |
|
| 41 |
+// the URL.Opaque or URL.RawPath. The SDK will use URL.Opaque first and then |
|
| 42 |
+// call URL.EscapedPath() if Opaque is not set. |
|
| 43 |
+// |
|
| 44 |
+// Test `TestStandaloneSign` provides a complete example of using the signer |
|
| 45 |
+// outside of the SDK and pre-escaping the URI path. |
|
| 46 |
+package v4 |
|
| 47 |
+ |
|
| 48 |
+import ( |
|
| 49 |
+ "bytes" |
|
| 50 |
+ "crypto/hmac" |
|
| 51 |
+ "crypto/sha256" |
|
| 52 |
+ "encoding/hex" |
|
| 53 |
+ "fmt" |
|
| 54 |
+ "io" |
|
| 55 |
+ "io/ioutil" |
|
| 56 |
+ "net/http" |
|
| 57 |
+ "net/url" |
|
| 58 |
+ "sort" |
|
| 59 |
+ "strconv" |
|
| 60 |
+ "strings" |
|
| 61 |
+ "time" |
|
| 62 |
+ |
|
| 63 |
+ "github.com/aws/aws-sdk-go/aws" |
|
| 64 |
+ "github.com/aws/aws-sdk-go/aws/credentials" |
|
| 65 |
+ "github.com/aws/aws-sdk-go/aws/request" |
|
| 66 |
+ "github.com/aws/aws-sdk-go/private/protocol/rest" |
|
| 67 |
+) |
|
| 68 |
+ |
|
| 69 |
+const ( |
|
| 70 |
+ authHeaderPrefix = "AWS4-HMAC-SHA256" |
|
| 71 |
+ timeFormat = "20060102T150405Z" |
|
| 72 |
+ shortTimeFormat = "20060102" |
|
| 73 |
+ |
|
| 74 |
+ // emptyStringSHA256 is a SHA256 of an empty string |
|
| 75 |
+ emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` |
|
| 76 |
+) |
|
| 77 |
+ |
|
| 78 |
+var ignoredHeaders = rules{
|
|
| 79 |
+ blacklist{
|
|
| 80 |
+ mapRule{
|
|
| 81 |
+ "Authorization": struct{}{},
|
|
| 82 |
+ "User-Agent": struct{}{},
|
|
| 83 |
+ }, |
|
| 84 |
+ }, |
|
| 85 |
+} |
|
| 86 |
+ |
|
| 87 |
+// requiredSignedHeaders is a whitelist for build canonical headers. |
|
| 88 |
+var requiredSignedHeaders = rules{
|
|
| 89 |
+ whitelist{
|
|
| 90 |
+ mapRule{
|
|
| 91 |
+ "Cache-Control": struct{}{},
|
|
| 92 |
+ "Content-Disposition": struct{}{},
|
|
| 93 |
+ "Content-Encoding": struct{}{},
|
|
| 94 |
+ "Content-Language": struct{}{},
|
|
| 95 |
+ "Content-Md5": struct{}{},
|
|
| 96 |
+ "Content-Type": struct{}{},
|
|
| 97 |
+ "Expires": struct{}{},
|
|
| 98 |
+ "If-Match": struct{}{},
|
|
| 99 |
+ "If-Modified-Since": struct{}{},
|
|
| 100 |
+ "If-None-Match": struct{}{},
|
|
| 101 |
+ "If-Unmodified-Since": struct{}{},
|
|
| 102 |
+ "Range": struct{}{},
|
|
| 103 |
+ "X-Amz-Acl": struct{}{},
|
|
| 104 |
+ "X-Amz-Copy-Source": struct{}{},
|
|
| 105 |
+ "X-Amz-Copy-Source-If-Match": struct{}{},
|
|
| 106 |
+ "X-Amz-Copy-Source-If-Modified-Since": struct{}{},
|
|
| 107 |
+ "X-Amz-Copy-Source-If-None-Match": struct{}{},
|
|
| 108 |
+ "X-Amz-Copy-Source-If-Unmodified-Since": struct{}{},
|
|
| 109 |
+ "X-Amz-Copy-Source-Range": struct{}{},
|
|
| 110 |
+ "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
|
| 111 |
+ "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{},
|
|
| 112 |
+ "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
|
| 113 |
+ "X-Amz-Grant-Full-control": struct{}{},
|
|
| 114 |
+ "X-Amz-Grant-Read": struct{}{},
|
|
| 115 |
+ "X-Amz-Grant-Read-Acp": struct{}{},
|
|
| 116 |
+ "X-Amz-Grant-Write": struct{}{},
|
|
| 117 |
+ "X-Amz-Grant-Write-Acp": struct{}{},
|
|
| 118 |
+ "X-Amz-Metadata-Directive": struct{}{},
|
|
| 119 |
+ "X-Amz-Mfa": struct{}{},
|
|
| 120 |
+ "X-Amz-Request-Payer": struct{}{},
|
|
| 121 |
+ "X-Amz-Server-Side-Encryption": struct{}{},
|
|
| 122 |
+ "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{},
|
|
| 123 |
+ "X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
|
| 124 |
+ "X-Amz-Server-Side-Encryption-Customer-Key": struct{}{},
|
|
| 125 |
+ "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
|
| 126 |
+ "X-Amz-Storage-Class": struct{}{},
|
|
| 127 |
+ "X-Amz-Website-Redirect-Location": struct{}{},
|
|
| 128 |
+ }, |
|
| 129 |
+ }, |
|
| 130 |
+ patterns{"X-Amz-Meta-"},
|
|
| 131 |
+} |
|
| 132 |
+ |
|
| 133 |
+// allowedHoisting is a whitelist for build query headers. The boolean value |
|
| 134 |
+// represents whether or not it is a pattern. |
|
| 135 |
+var allowedQueryHoisting = inclusiveRules{
|
|
| 136 |
+ blacklist{requiredSignedHeaders},
|
|
| 137 |
+ patterns{"X-Amz-"},
|
|
| 138 |
+} |
|
| 139 |
+ |
|
| 140 |
+// Signer applies AWS v4 signing to given request. Use this to sign requests |
|
| 141 |
+// that need to be signed with AWS V4 Signatures. |
|
| 142 |
+type Signer struct {
|
|
| 143 |
+ // The authentication credentials the request will be signed against. |
|
| 144 |
+ // This value must be set to sign requests. |
|
| 145 |
+ Credentials *credentials.Credentials |
|
| 146 |
+ |
|
| 147 |
+ // Sets the log level the signer should use when reporting information to |
|
| 148 |
+ // the logger. If the logger is nil nothing will be logged. See |
|
| 149 |
+ // aws.LogLevelType for more information on available logging levels |
|
| 150 |
+ // |
|
| 151 |
+ // By default nothing will be logged. |
|
| 152 |
+ Debug aws.LogLevelType |
|
| 153 |
+ |
|
| 154 |
+ // The logger loging information will be written to. If there the logger |
|
| 155 |
+ // is nil, nothing will be logged. |
|
| 156 |
+ Logger aws.Logger |
|
| 157 |
+ |
|
| 158 |
+ // Disables the Signer's moving HTTP header key/value pairs from the HTTP |
|
| 159 |
+ // request header to the request's query string. This is most commonly used |
|
| 160 |
+ // with pre-signed requests preventing headers from being added to the |
|
| 161 |
+ // request's query string. |
|
| 162 |
+ DisableHeaderHoisting bool |
|
| 163 |
+ |
|
| 164 |
+ // Disables the automatic escaping of the URI path of the request for the |
|
| 165 |
+ // siganture's canonical string's path. For services that do not need additional |
|
| 166 |
+ // escaping then use this to disable the signer escaping the path. |
|
| 167 |
+ // |
|
| 168 |
+ // S3 is an example of a service that does not need additional escaping. |
|
| 169 |
+ // |
|
| 170 |
+ // http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html |
|
| 171 |
+ DisableURIPathEscaping bool |
|
| 172 |
+ |
|
| 173 |
+ // currentTimeFn returns the time value which represents the current time. |
|
| 174 |
+ // This value should only be used for testing. If it is nil the default |
|
| 175 |
+ // time.Now will be used. |
|
| 176 |
+ currentTimeFn func() time.Time |
|
| 177 |
+} |
|
| 178 |
+ |
|
| 179 |
+// NewSigner returns a Signer pointer configured with the credentials and optional |
|
| 180 |
+// option values provided. If not options are provided the Signer will use its |
|
| 181 |
+// default configuration. |
|
| 182 |
+func NewSigner(credentials *credentials.Credentials, options ...func(*Signer)) *Signer {
|
|
| 183 |
+ v4 := &Signer{
|
|
| 184 |
+ Credentials: credentials, |
|
| 185 |
+ } |
|
| 186 |
+ |
|
| 187 |
+ for _, option := range options {
|
|
| 188 |
+ option(v4) |
|
| 189 |
+ } |
|
| 190 |
+ |
|
| 191 |
+ return v4 |
|
| 192 |
+} |
|
| 193 |
+ |
|
| 194 |
+type signingCtx struct {
|
|
| 195 |
+ ServiceName string |
|
| 196 |
+ Region string |
|
| 197 |
+ Request *http.Request |
|
| 198 |
+ Body io.ReadSeeker |
|
| 199 |
+ Query url.Values |
|
| 200 |
+ Time time.Time |
|
| 201 |
+ ExpireTime time.Duration |
|
| 202 |
+ SignedHeaderVals http.Header |
|
| 203 |
+ |
|
| 204 |
+ DisableURIPathEscaping bool |
|
| 205 |
+ |
|
| 206 |
+ credValues credentials.Value |
|
| 207 |
+ isPresign bool |
|
| 208 |
+ formattedTime string |
|
| 209 |
+ formattedShortTime string |
|
| 210 |
+ |
|
| 211 |
+ bodyDigest string |
|
| 212 |
+ signedHeaders string |
|
| 213 |
+ canonicalHeaders string |
|
| 214 |
+ canonicalString string |
|
| 215 |
+ credentialString string |
|
| 216 |
+ stringToSign string |
|
| 217 |
+ signature string |
|
| 218 |
+ authorization string |
|
| 219 |
+} |
|
| 220 |
+ |
|
| 221 |
+// Sign signs AWS v4 requests with the provided body, service name, region the |
|
| 222 |
+// request is made to, and time the request is signed at. The signTime allows |
|
| 223 |
+// you to specify that a request is signed for the future, and cannot be |
|
| 224 |
+// used until then. |
|
| 225 |
+// |
|
| 226 |
+// Returns a list of HTTP headers that were included in the signature or an |
|
| 227 |
+// error if signing the request failed. Generally for signed requests this value |
|
| 228 |
+// is not needed as the full request context will be captured by the http.Request |
|
| 229 |
+// value. It is included for reference though. |
|
| 230 |
+// |
|
| 231 |
+// Sign will set the request's Body to be the `body` parameter passed in. If |
|
| 232 |
+// the body is not already an io.ReadCloser, it will be wrapped within one. If |
|
| 233 |
+// a `nil` body parameter passed to Sign, the request's Body field will be |
|
| 234 |
+// also set to nil. Its important to note that this functionality will not |
|
| 235 |
+// change the request's ContentLength of the request. |
|
| 236 |
+// |
|
| 237 |
+// Sign differs from Presign in that it will sign the request using HTTP |
|
| 238 |
+// header values. This type of signing is intended for http.Request values that |
|
| 239 |
+// will not be shared, or are shared in a way the header values on the request |
|
| 240 |
+// will not be lost. |
|
| 241 |
+// |
|
| 242 |
+// The requests body is an io.ReadSeeker so the SHA256 of the body can be |
|
| 243 |
+// generated. To bypass the signer computing the hash you can set the |
|
| 244 |
+// "X-Amz-Content-Sha256" header with a precomputed value. The signer will |
|
| 245 |
+// only compute the hash if the request header value is empty. |
|
| 246 |
+func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) {
|
|
| 247 |
+ return v4.signWithBody(r, body, service, region, 0, signTime) |
|
| 248 |
+} |
|
| 249 |
+ |
|
| 250 |
+// Presign signs AWS v4 requests with the provided body, service name, region |
|
| 251 |
+// the request is made to, and time the request is signed at. The signTime |
|
| 252 |
+// allows you to specify that a request is signed for the future, and cannot |
|
| 253 |
+// be used until then. |
|
| 254 |
+// |
|
| 255 |
+// Returns a list of HTTP headers that were included in the signature or an |
|
| 256 |
+// error if signing the request failed. For presigned requests these headers |
|
| 257 |
+// and their values must be included on the HTTP request when it is made. This |
|
| 258 |
+// is helpful to know what header values need to be shared with the party the |
|
| 259 |
+// presigned request will be distributed to. |
|
| 260 |
+// |
|
| 261 |
+// Presign differs from Sign in that it will sign the request using query string |
|
| 262 |
+// instead of header values. This allows you to share the Presigned Request's |
|
| 263 |
+// URL with third parties, or distribute it throughout your system with minimal |
|
| 264 |
+// dependencies. |
|
| 265 |
+// |
|
| 266 |
+// Presign also takes an exp value which is the duration the |
|
| 267 |
+// signed request will be valid after the signing time. This is allows you to |
|
| 268 |
+// set when the request will expire. |
|
| 269 |
+// |
|
| 270 |
+// The requests body is an io.ReadSeeker so the SHA256 of the body can be |
|
| 271 |
+// generated. To bypass the signer computing the hash you can set the |
|
| 272 |
+// "X-Amz-Content-Sha256" header with a precomputed value. The signer will |
|
| 273 |
+// only compute the hash if the request header value is empty. |
|
| 274 |
+// |
|
| 275 |
+// Presigning a S3 request will not compute the body's SHA256 hash by default. |
|
| 276 |
+// This is done due to the general use case for S3 presigned URLs is to share |
|
| 277 |
+// PUT/GET capabilities. If you would like to include the body's SHA256 in the |
|
| 278 |
+// presigned request's signature you can set the "X-Amz-Content-Sha256" |
|
| 279 |
+// HTTP header and that will be included in the request's signature. |
|
| 280 |
+func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
|
|
| 281 |
+ return v4.signWithBody(r, body, service, region, exp, signTime) |
|
| 282 |
+} |
|
| 283 |
+ |
|
| 284 |
+func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) {
|
|
| 285 |
+ currentTimeFn := v4.currentTimeFn |
|
| 286 |
+ if currentTimeFn == nil {
|
|
| 287 |
+ currentTimeFn = time.Now |
|
| 288 |
+ } |
|
| 289 |
+ |
|
| 290 |
+ ctx := &signingCtx{
|
|
| 291 |
+ Request: r, |
|
| 292 |
+ Body: body, |
|
| 293 |
+ Query: r.URL.Query(), |
|
| 294 |
+ Time: signTime, |
|
| 295 |
+ ExpireTime: exp, |
|
| 296 |
+ isPresign: exp != 0, |
|
| 297 |
+ ServiceName: service, |
|
| 298 |
+ Region: region, |
|
| 299 |
+ DisableURIPathEscaping: v4.DisableURIPathEscaping, |
|
| 300 |
+ } |
|
| 301 |
+ |
|
| 302 |
+ if ctx.isRequestSigned() {
|
|
| 303 |
+ ctx.Time = currentTimeFn() |
|
| 304 |
+ ctx.handlePresignRemoval() |
|
| 305 |
+ } |
|
| 306 |
+ |
|
| 307 |
+ var err error |
|
| 308 |
+ ctx.credValues, err = v4.Credentials.Get() |
|
| 309 |
+ if err != nil {
|
|
| 310 |
+ return http.Header{}, err
|
|
| 311 |
+ } |
|
| 312 |
+ |
|
| 313 |
+ ctx.assignAmzQueryValues() |
|
| 314 |
+ ctx.build(v4.DisableHeaderHoisting) |
|
| 315 |
+ |
|
| 316 |
+ // If the request is not presigned the body should be attached to it. This |
|
| 317 |
+ // prevents the confusion of wanting to send a signed request without |
|
| 318 |
+ // the body the request was signed for attached. |
|
| 319 |
+ if !ctx.isPresign {
|
|
| 320 |
+ var reader io.ReadCloser |
|
| 321 |
+ if body != nil {
|
|
| 322 |
+ var ok bool |
|
| 323 |
+ if reader, ok = body.(io.ReadCloser); !ok {
|
|
| 324 |
+ reader = ioutil.NopCloser(body) |
|
| 325 |
+ } |
|
| 326 |
+ } |
|
| 327 |
+ r.Body = reader |
|
| 328 |
+ } |
|
| 329 |
+ |
|
| 330 |
+ if v4.Debug.Matches(aws.LogDebugWithSigning) {
|
|
| 331 |
+ v4.logSigningInfo(ctx) |
|
| 332 |
+ } |
|
| 333 |
+ |
|
| 334 |
+ return ctx.SignedHeaderVals, nil |
|
| 335 |
+} |
|
| 336 |
+ |
|
| 337 |
+func (ctx *signingCtx) handlePresignRemoval() {
|
|
| 338 |
+ if !ctx.isPresign {
|
|
| 339 |
+ return |
|
| 340 |
+ } |
|
| 341 |
+ |
|
| 342 |
+ // The credentials have expired for this request. The current signing |
|
| 343 |
+ // is invalid, and needs to be request because the request will fail. |
|
| 344 |
+ ctx.removePresign() |
|
| 345 |
+ |
|
| 346 |
+ // Update the request's query string to ensure the values stays in |
|
| 347 |
+ // sync in the case retrieving the new credentials fails. |
|
| 348 |
+ ctx.Request.URL.RawQuery = ctx.Query.Encode() |
|
| 349 |
+} |
|
| 350 |
+ |
|
| 351 |
+func (ctx *signingCtx) assignAmzQueryValues() {
|
|
| 352 |
+ if ctx.isPresign {
|
|
| 353 |
+ ctx.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
|
|
| 354 |
+ if ctx.credValues.SessionToken != "" {
|
|
| 355 |
+ ctx.Query.Set("X-Amz-Security-Token", ctx.credValues.SessionToken)
|
|
| 356 |
+ } else {
|
|
| 357 |
+ ctx.Query.Del("X-Amz-Security-Token")
|
|
| 358 |
+ } |
|
| 359 |
+ |
|
| 360 |
+ return |
|
| 361 |
+ } |
|
| 362 |
+ |
|
| 363 |
+ if ctx.credValues.SessionToken != "" {
|
|
| 364 |
+ ctx.Request.Header.Set("X-Amz-Security-Token", ctx.credValues.SessionToken)
|
|
| 365 |
+ } |
|
| 366 |
+} |
|
| 367 |
+ |
|
| 368 |
+// SignRequestHandler is a named request handler the SDK will use to sign |
|
| 369 |
+// service client request with using the V4 signature. |
|
| 370 |
+var SignRequestHandler = request.NamedHandler{
|
|
| 371 |
+ Name: "v4.SignRequestHandler", Fn: SignSDKRequest, |
|
| 372 |
+} |
|
| 373 |
+ |
|
| 374 |
+// SignSDKRequest signs an AWS request with the V4 signature. This |
|
| 375 |
+// request handler is bested used only with the SDK's built in service client's |
|
| 376 |
+// API operation requests. |
|
| 377 |
+// |
|
| 378 |
+// This function should not be used on its on its own, but in conjunction with |
|
| 379 |
+// an AWS service client's API operation call. To sign a standalone request |
|
| 380 |
+// not created by a service client's API operation method use the "Sign" or |
|
| 381 |
+// "Presign" functions of the "Signer" type. |
|
| 382 |
+// |
|
| 383 |
+// If the credentials of the request's config are set to |
|
| 384 |
+// credentials.AnonymousCredentials the request will not be signed. |
|
| 385 |
+func SignSDKRequest(req *request.Request) {
|
|
| 386 |
+ signSDKRequestWithCurrTime(req, time.Now) |
|
| 387 |
+} |
|
| 388 |
+func signSDKRequestWithCurrTime(req *request.Request, curTimeFn func() time.Time) {
|
|
| 389 |
+ // If the request does not need to be signed ignore the signing of the |
|
| 390 |
+ // request if the AnonymousCredentials object is used. |
|
| 391 |
+ if req.Config.Credentials == credentials.AnonymousCredentials {
|
|
| 392 |
+ return |
|
| 393 |
+ } |
|
| 394 |
+ |
|
| 395 |
+ region := req.ClientInfo.SigningRegion |
|
| 396 |
+ if region == "" {
|
|
| 397 |
+ region = aws.StringValue(req.Config.Region) |
|
| 398 |
+ } |
|
| 399 |
+ |
|
| 400 |
+ name := req.ClientInfo.SigningName |
|
| 401 |
+ if name == "" {
|
|
| 402 |
+ name = req.ClientInfo.ServiceName |
|
| 403 |
+ } |
|
| 404 |
+ |
|
| 405 |
+ v4 := NewSigner(req.Config.Credentials, func(v4 *Signer) {
|
|
| 406 |
+ v4.Debug = req.Config.LogLevel.Value() |
|
| 407 |
+ v4.Logger = req.Config.Logger |
|
| 408 |
+ v4.DisableHeaderHoisting = req.NotHoist |
|
| 409 |
+ v4.currentTimeFn = curTimeFn |
|
| 410 |
+ if name == "s3" {
|
|
| 411 |
+ // S3 service should not have any escaping applied |
|
| 412 |
+ v4.DisableURIPathEscaping = true |
|
| 413 |
+ } |
|
| 414 |
+ }) |
|
| 415 |
+ |
|
| 416 |
+ signingTime := req.Time |
|
| 417 |
+ if !req.LastSignedAt.IsZero() {
|
|
| 418 |
+ signingTime = req.LastSignedAt |
|
| 419 |
+ } |
|
| 420 |
+ |
|
| 421 |
+ signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(), |
|
| 422 |
+ name, region, req.ExpireTime, signingTime, |
|
| 423 |
+ ) |
|
| 424 |
+ if err != nil {
|
|
| 425 |
+ req.Error = err |
|
| 426 |
+ req.SignedHeaderVals = nil |
|
| 427 |
+ return |
|
| 428 |
+ } |
|
| 429 |
+ |
|
| 430 |
+ req.SignedHeaderVals = signedHeaders |
|
| 431 |
+ req.LastSignedAt = curTimeFn() |
|
| 432 |
+} |
|
| 433 |
+ |
|
| 434 |
+const logSignInfoMsg = `DEBUG: Request Signature: |
|
| 435 |
+---[ CANONICAL STRING ]----------------------------- |
|
| 436 |
+%s |
|
| 437 |
+---[ STRING TO SIGN ]-------------------------------- |
|
| 438 |
+%s%s |
|
| 439 |
+-----------------------------------------------------` |
|
| 440 |
+const logSignedURLMsg = ` |
|
| 441 |
+---[ SIGNED URL ]------------------------------------ |
|
| 442 |
+%s` |
|
| 443 |
+ |
|
| 444 |
+func (v4 *Signer) logSigningInfo(ctx *signingCtx) {
|
|
| 445 |
+ signedURLMsg := "" |
|
| 446 |
+ if ctx.isPresign {
|
|
| 447 |
+ signedURLMsg = fmt.Sprintf(logSignedURLMsg, ctx.Request.URL.String()) |
|
| 448 |
+ } |
|
| 449 |
+ msg := fmt.Sprintf(logSignInfoMsg, ctx.canonicalString, ctx.stringToSign, signedURLMsg) |
|
| 450 |
+ v4.Logger.Log(msg) |
|
| 451 |
+} |
|
| 452 |
+ |
|
| 453 |
+func (ctx *signingCtx) build(disableHeaderHoisting bool) {
|
|
| 454 |
+ ctx.buildTime() // no depends |
|
| 455 |
+ ctx.buildCredentialString() // no depends |
|
| 456 |
+ |
|
| 457 |
+ unsignedHeaders := ctx.Request.Header |
|
| 458 |
+ if ctx.isPresign {
|
|
| 459 |
+ if !disableHeaderHoisting {
|
|
| 460 |
+ urlValues := url.Values{}
|
|
| 461 |
+ urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends |
|
| 462 |
+ for k := range urlValues {
|
|
| 463 |
+ ctx.Query[k] = urlValues[k] |
|
| 464 |
+ } |
|
| 465 |
+ } |
|
| 466 |
+ } |
|
| 467 |
+ |
|
| 468 |
+ ctx.buildBodyDigest() |
|
| 469 |
+ ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders) |
|
| 470 |
+ ctx.buildCanonicalString() // depends on canon headers / signed headers |
|
| 471 |
+ ctx.buildStringToSign() // depends on canon string |
|
| 472 |
+ ctx.buildSignature() // depends on string to sign |
|
| 473 |
+ |
|
| 474 |
+ if ctx.isPresign {
|
|
| 475 |
+ ctx.Request.URL.RawQuery += "&X-Amz-Signature=" + ctx.signature |
|
| 476 |
+ } else {
|
|
| 477 |
+ parts := []string{
|
|
| 478 |
+ authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString, |
|
| 479 |
+ "SignedHeaders=" + ctx.signedHeaders, |
|
| 480 |
+ "Signature=" + ctx.signature, |
|
| 481 |
+ } |
|
| 482 |
+ ctx.Request.Header.Set("Authorization", strings.Join(parts, ", "))
|
|
| 483 |
+ } |
|
| 484 |
+} |
|
| 485 |
+ |
|
| 486 |
+func (ctx *signingCtx) buildTime() {
|
|
| 487 |
+ ctx.formattedTime = ctx.Time.UTC().Format(timeFormat) |
|
| 488 |
+ ctx.formattedShortTime = ctx.Time.UTC().Format(shortTimeFormat) |
|
| 489 |
+ |
|
| 490 |
+ if ctx.isPresign {
|
|
| 491 |
+ duration := int64(ctx.ExpireTime / time.Second) |
|
| 492 |
+ ctx.Query.Set("X-Amz-Date", ctx.formattedTime)
|
|
| 493 |
+ ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
|
|
| 494 |
+ } else {
|
|
| 495 |
+ ctx.Request.Header.Set("X-Amz-Date", ctx.formattedTime)
|
|
| 496 |
+ } |
|
| 497 |
+} |
|
| 498 |
+ |
|
| 499 |
+func (ctx *signingCtx) buildCredentialString() {
|
|
| 500 |
+ ctx.credentialString = strings.Join([]string{
|
|
| 501 |
+ ctx.formattedShortTime, |
|
| 502 |
+ ctx.Region, |
|
| 503 |
+ ctx.ServiceName, |
|
| 504 |
+ "aws4_request", |
|
| 505 |
+ }, "/") |
|
| 506 |
+ |
|
| 507 |
+ if ctx.isPresign {
|
|
| 508 |
+ ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString)
|
|
| 509 |
+ } |
|
| 510 |
+} |
|
| 511 |
+ |
|
| 512 |
+func buildQuery(r rule, header http.Header) (url.Values, http.Header) {
|
|
| 513 |
+ query := url.Values{}
|
|
| 514 |
+ unsignedHeaders := http.Header{}
|
|
| 515 |
+ for k, h := range header {
|
|
| 516 |
+ if r.IsValid(k) {
|
|
| 517 |
+ query[k] = h |
|
| 518 |
+ } else {
|
|
| 519 |
+ unsignedHeaders[k] = h |
|
| 520 |
+ } |
|
| 521 |
+ } |
|
| 522 |
+ |
|
| 523 |
+ return query, unsignedHeaders |
|
| 524 |
+} |
|
| 525 |
+func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) {
|
|
| 526 |
+ var headers []string |
|
| 527 |
+ headers = append(headers, "host") |
|
| 528 |
+ for k, v := range header {
|
|
| 529 |
+ canonicalKey := http.CanonicalHeaderKey(k) |
|
| 530 |
+ if !r.IsValid(canonicalKey) {
|
|
| 531 |
+ continue // ignored header |
|
| 532 |
+ } |
|
| 533 |
+ if ctx.SignedHeaderVals == nil {
|
|
| 534 |
+ ctx.SignedHeaderVals = make(http.Header) |
|
| 535 |
+ } |
|
| 536 |
+ |
|
| 537 |
+ lowerCaseKey := strings.ToLower(k) |
|
| 538 |
+ if _, ok := ctx.SignedHeaderVals[lowerCaseKey]; ok {
|
|
| 539 |
+ // include additional values |
|
| 540 |
+ ctx.SignedHeaderVals[lowerCaseKey] = append(ctx.SignedHeaderVals[lowerCaseKey], v...) |
|
| 541 |
+ continue |
|
| 542 |
+ } |
|
| 543 |
+ |
|
| 544 |
+ headers = append(headers, lowerCaseKey) |
|
| 545 |
+ ctx.SignedHeaderVals[lowerCaseKey] = v |
|
| 546 |
+ } |
|
| 547 |
+ sort.Strings(headers) |
|
| 548 |
+ |
|
| 549 |
+ ctx.signedHeaders = strings.Join(headers, ";") |
|
| 550 |
+ |
|
| 551 |
+ if ctx.isPresign {
|
|
| 552 |
+ ctx.Query.Set("X-Amz-SignedHeaders", ctx.signedHeaders)
|
|
| 553 |
+ } |
|
| 554 |
+ |
|
| 555 |
+ headerValues := make([]string, len(headers)) |
|
| 556 |
+ for i, k := range headers {
|
|
| 557 |
+ if k == "host" {
|
|
| 558 |
+ headerValues[i] = "host:" + ctx.Request.URL.Host |
|
| 559 |
+ } else {
|
|
| 560 |
+ headerValues[i] = k + ":" + |
|
| 561 |
+ strings.Join(ctx.SignedHeaderVals[k], ",") |
|
| 562 |
+ } |
|
| 563 |
+ } |
|
| 564 |
+ |
|
| 565 |
+ ctx.canonicalHeaders = strings.Join(stripExcessSpaces(headerValues), "\n") |
|
| 566 |
+} |
|
| 567 |
+ |
|
| 568 |
+func (ctx *signingCtx) buildCanonicalString() {
|
|
| 569 |
+ ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1) |
|
| 570 |
+ |
|
| 571 |
+ uri := getURIPath(ctx.Request.URL) |
|
| 572 |
+ |
|
| 573 |
+ if !ctx.DisableURIPathEscaping {
|
|
| 574 |
+ uri = rest.EscapePath(uri, false) |
|
| 575 |
+ } |
|
| 576 |
+ |
|
| 577 |
+ ctx.canonicalString = strings.Join([]string{
|
|
| 578 |
+ ctx.Request.Method, |
|
| 579 |
+ uri, |
|
| 580 |
+ ctx.Request.URL.RawQuery, |
|
| 581 |
+ ctx.canonicalHeaders + "\n", |
|
| 582 |
+ ctx.signedHeaders, |
|
| 583 |
+ ctx.bodyDigest, |
|
| 584 |
+ }, "\n") |
|
| 585 |
+} |
|
| 586 |
+ |
|
| 587 |
+func (ctx *signingCtx) buildStringToSign() {
|
|
| 588 |
+ ctx.stringToSign = strings.Join([]string{
|
|
| 589 |
+ authHeaderPrefix, |
|
| 590 |
+ ctx.formattedTime, |
|
| 591 |
+ ctx.credentialString, |
|
| 592 |
+ hex.EncodeToString(makeSha256([]byte(ctx.canonicalString))), |
|
| 593 |
+ }, "\n") |
|
| 594 |
+} |
|
| 595 |
+ |
|
| 596 |
+func (ctx *signingCtx) buildSignature() {
|
|
| 597 |
+ secret := ctx.credValues.SecretAccessKey |
|
| 598 |
+ date := makeHmac([]byte("AWS4"+secret), []byte(ctx.formattedShortTime))
|
|
| 599 |
+ region := makeHmac(date, []byte(ctx.Region)) |
|
| 600 |
+ service := makeHmac(region, []byte(ctx.ServiceName)) |
|
| 601 |
+ credentials := makeHmac(service, []byte("aws4_request"))
|
|
| 602 |
+ signature := makeHmac(credentials, []byte(ctx.stringToSign)) |
|
| 603 |
+ ctx.signature = hex.EncodeToString(signature) |
|
| 604 |
+} |
|
| 605 |
+ |
|
| 606 |
+func (ctx *signingCtx) buildBodyDigest() {
|
|
| 607 |
+ hash := ctx.Request.Header.Get("X-Amz-Content-Sha256")
|
|
| 608 |
+ if hash == "" {
|
|
| 609 |
+ if ctx.isPresign && ctx.ServiceName == "s3" {
|
|
| 610 |
+ hash = "UNSIGNED-PAYLOAD" |
|
| 611 |
+ } else if ctx.Body == nil {
|
|
| 612 |
+ hash = emptyStringSHA256 |
|
| 613 |
+ } else {
|
|
| 614 |
+ hash = hex.EncodeToString(makeSha256Reader(ctx.Body)) |
|
| 615 |
+ } |
|
| 616 |
+ if ctx.ServiceName == "s3" || ctx.ServiceName == "glacier" {
|
|
| 617 |
+ ctx.Request.Header.Set("X-Amz-Content-Sha256", hash)
|
|
| 618 |
+ } |
|
| 619 |
+ } |
|
| 620 |
+ ctx.bodyDigest = hash |
|
| 621 |
+} |
|
| 622 |
+ |
|
| 623 |
+// isRequestSigned returns if the request is currently signed or presigned |
|
| 624 |
+func (ctx *signingCtx) isRequestSigned() bool {
|
|
| 625 |
+ if ctx.isPresign && ctx.Query.Get("X-Amz-Signature") != "" {
|
|
| 626 |
+ return true |
|
| 627 |
+ } |
|
| 628 |
+ if ctx.Request.Header.Get("Authorization") != "" {
|
|
| 629 |
+ return true |
|
| 630 |
+ } |
|
| 631 |
+ |
|
| 632 |
+ return false |
|
| 633 |
+} |
|
| 634 |
+ |
|
| 635 |
+// unsign removes signing flags for both signed and presigned requests. |
|
| 636 |
+func (ctx *signingCtx) removePresign() {
|
|
| 637 |
+ ctx.Query.Del("X-Amz-Algorithm")
|
|
| 638 |
+ ctx.Query.Del("X-Amz-Signature")
|
|
| 639 |
+ ctx.Query.Del("X-Amz-Security-Token")
|
|
| 640 |
+ ctx.Query.Del("X-Amz-Date")
|
|
| 641 |
+ ctx.Query.Del("X-Amz-Expires")
|
|
| 642 |
+ ctx.Query.Del("X-Amz-Credential")
|
|
| 643 |
+ ctx.Query.Del("X-Amz-SignedHeaders")
|
|
| 644 |
+} |
|
| 645 |
+ |
|
| 646 |
+func makeHmac(key []byte, data []byte) []byte {
|
|
| 647 |
+ hash := hmac.New(sha256.New, key) |
|
| 648 |
+ hash.Write(data) |
|
| 649 |
+ return hash.Sum(nil) |
|
| 650 |
+} |
|
| 651 |
+ |
|
| 652 |
+func makeSha256(data []byte) []byte {
|
|
| 653 |
+ hash := sha256.New() |
|
| 654 |
+ hash.Write(data) |
|
| 655 |
+ return hash.Sum(nil) |
|
| 656 |
+} |
|
| 657 |
+ |
|
| 658 |
+func makeSha256Reader(reader io.ReadSeeker) []byte {
|
|
| 659 |
+ hash := sha256.New() |
|
| 660 |
+ start, _ := reader.Seek(0, 1) |
|
| 661 |
+ defer reader.Seek(start, 0) |
|
| 662 |
+ |
|
| 663 |
+ io.Copy(hash, reader) |
|
| 664 |
+ return hash.Sum(nil) |
|
| 665 |
+} |
|
| 666 |
+ |
|
| 667 |
+const doubleSpaces = " " |
|
| 668 |
+ |
|
| 669 |
+var doubleSpaceBytes = []byte(doubleSpaces) |
|
| 670 |
+ |
|
| 671 |
+func stripExcessSpaces(headerVals []string) []string {
|
|
| 672 |
+ vals := make([]string, len(headerVals)) |
|
| 673 |
+ for i, str := range headerVals {
|
|
| 674 |
+ // Trim leading and trailing spaces |
|
| 675 |
+ trimmed := strings.TrimSpace(str) |
|
| 676 |
+ |
|
| 677 |
+ idx := strings.Index(trimmed, doubleSpaces) |
|
| 678 |
+ var buf []byte |
|
| 679 |
+ for idx > -1 {
|
|
| 680 |
+ // Multiple adjacent spaces found |
|
| 681 |
+ if buf == nil {
|
|
| 682 |
+ // first time create the buffer |
|
| 683 |
+ buf = []byte(trimmed) |
|
| 684 |
+ } |
|
| 685 |
+ |
|
| 686 |
+ stripToIdx := -1 |
|
| 687 |
+ for j := idx + 1; j < len(buf); j++ {
|
|
| 688 |
+ if buf[j] != ' ' {
|
|
| 689 |
+ buf = append(buf[:idx+1], buf[j:]...) |
|
| 690 |
+ stripToIdx = j |
|
| 691 |
+ break |
|
| 692 |
+ } |
|
| 693 |
+ } |
|
| 694 |
+ |
|
| 695 |
+ if stripToIdx >= 0 {
|
|
| 696 |
+ idx = bytes.Index(buf[stripToIdx:], doubleSpaceBytes) |
|
| 697 |
+ if idx >= 0 {
|
|
| 698 |
+ idx += stripToIdx |
|
| 699 |
+ } |
|
| 700 |
+ } else {
|
|
| 701 |
+ idx = -1 |
|
| 702 |
+ } |
|
| 703 |
+ } |
|
| 704 |
+ |
|
| 705 |
+ if buf != nil {
|
|
| 706 |
+ vals[i] = string(buf) |
|
| 707 |
+ } else {
|
|
| 708 |
+ vals[i] = trimmed |
|
| 709 |
+ } |
|
| 710 |
+ } |
|
| 711 |
+ return vals |
|
| 712 |
+} |
| ... | ... |
@@ -1,7 +1,7 @@ |
| 1 | 1 |
// Package endpoints validates regional endpoints for services. |
| 2 | 2 |
package endpoints |
| 3 | 3 |
|
| 4 |
-//go:generate go run ../model/cli/gen-endpoints/main.go endpoints.json endpoints_map.go |
|
| 4 |
+//go:generate go run -tags codegen ../model/cli/gen-endpoints/main.go endpoints.json endpoints_map.go |
|
| 5 | 5 |
//go:generate gofmt -s -w endpoints_map.go |
| 6 | 6 |
|
| 7 | 7 |
import ( |
| ... | ... |
@@ -14,9 +14,9 @@ import ( |
| 14 | 14 |
// normalized endpoint and signing region. If the endpoint is not an empty string |
| 15 | 15 |
// the service name and region will be used to look up the service's API endpoint. |
| 16 | 16 |
// If the endpoint is provided the scheme will be added if it is not present. |
| 17 |
-func NormalizeEndpoint(endpoint, serviceName, region string, disableSSL bool) (normEndpoint, signingRegion string) {
|
|
| 17 |
+func NormalizeEndpoint(endpoint, serviceName, region string, disableSSL, useDualStack bool) (normEndpoint, signingRegion string) {
|
|
| 18 | 18 |
if endpoint == "" {
|
| 19 |
- return EndpointForRegion(serviceName, region, disableSSL) |
|
| 19 |
+ return EndpointForRegion(serviceName, region, disableSSL, useDualStack) |
|
| 20 | 20 |
} |
| 21 | 21 |
|
| 22 | 22 |
return AddScheme(endpoint, disableSSL), "" |
| ... | ... |
@@ -24,12 +24,17 @@ func NormalizeEndpoint(endpoint, serviceName, region string, disableSSL bool) (n |
| 24 | 24 |
|
| 25 | 25 |
// EndpointForRegion returns an endpoint and its signing region for a service and region. |
| 26 | 26 |
// if the service and region pair are not found endpoint and signingRegion will be empty. |
| 27 |
-func EndpointForRegion(svcName, region string, disableSSL bool) (endpoint, signingRegion string) {
|
|
| 27 |
+func EndpointForRegion(svcName, region string, disableSSL, useDualStack bool) (endpoint, signingRegion string) {
|
|
| 28 |
+ dualStackField := "" |
|
| 29 |
+ if useDualStack {
|
|
| 30 |
+ dualStackField = "/dualstack" |
|
| 31 |
+ } |
|
| 32 |
+ |
|
| 28 | 33 |
derivedKeys := []string{
|
| 29 |
- region + "/" + svcName, |
|
| 30 |
- region + "/*", |
|
| 31 |
- "*/" + svcName, |
|
| 32 |
- "*/*", |
|
| 34 |
+ region + "/" + svcName + dualStackField, |
|
| 35 |
+ region + "/*" + dualStackField, |
|
| 36 |
+ "*/" + svcName + dualStackField, |
|
| 37 |
+ "*/*" + dualStackField, |
|
| 33 | 38 |
} |
| 34 | 39 |
|
| 35 | 40 |
for _, key := range derivedKeys {
|
| ... | ... |
@@ -23,6 +23,10 @@ |
| 23 | 23 |
"us-gov-west-1/ec2metadata": {
|
| 24 | 24 |
"endpoint": "http://169.254.169.254/latest" |
| 25 | 25 |
}, |
| 26 |
+ "*/budgets": {
|
|
| 27 |
+ "endpoint": "budgets.amazonaws.com", |
|
| 28 |
+ "signingRegion": "us-east-1" |
|
| 29 |
+ }, |
|
| 26 | 30 |
"*/cloudfront": {
|
| 27 | 31 |
"endpoint": "cloudfront.amazonaws.com", |
| 28 | 32 |
"signingRegion": "us-east-1" |
| ... | ... |
@@ -65,6 +69,9 @@ |
| 65 | 65 |
"*/s3": {
|
| 66 | 66 |
"endpoint": "s3-{region}.amazonaws.com"
|
| 67 | 67 |
}, |
| 68 |
+ "*/s3/dualstack": {
|
|
| 69 |
+ "endpoint": "s3.dualstack.{region}.amazonaws.com"
|
|
| 70 |
+ }, |
|
| 68 | 71 |
"us-east-1/s3": {
|
| 69 | 72 |
"endpoint": "s3.amazonaws.com" |
| 70 | 73 |
}, |
| ... | ... |
@@ -18,6 +18,10 @@ var endpointsMap = endpointStruct{
|
| 18 | 18 |
"*/*": {
|
| 19 | 19 |
Endpoint: "{service}.{region}.amazonaws.com",
|
| 20 | 20 |
}, |
| 21 |
+ "*/budgets": {
|
|
| 22 |
+ Endpoint: "budgets.amazonaws.com", |
|
| 23 |
+ SigningRegion: "us-east-1", |
|
| 24 |
+ }, |
|
| 21 | 25 |
"*/cloudfront": {
|
| 22 | 26 |
Endpoint: "cloudfront.amazonaws.com", |
| 23 | 27 |
SigningRegion: "us-east-1", |
| ... | ... |
@@ -48,6 +52,9 @@ var endpointsMap = endpointStruct{
|
| 48 | 48 |
"*/s3": {
|
| 49 | 49 |
Endpoint: "s3-{region}.amazonaws.com",
|
| 50 | 50 |
}, |
| 51 |
+ "*/s3/dualstack": {
|
|
| 52 |
+ Endpoint: "s3.dualstack.{region}.amazonaws.com",
|
|
| 53 |
+ }, |
|
| 51 | 54 |
"*/sts": {
|
| 52 | 55 |
Endpoint: "sts.amazonaws.com", |
| 53 | 56 |
SigningRegion: "us-east-1", |
| ... | ... |
@@ -1,4 +1,4 @@ |
| 1 |
-// Package jsonutil provides JSON serialisation of AWS requests and responses. |
|
| 1 |
+// Package jsonutil provides JSON serialization of AWS requests and responses. |
|
| 2 | 2 |
package jsonutil |
| 3 | 3 |
|
| 4 | 4 |
import ( |
| ... | ... |
@@ -160,7 +160,7 @@ func (sv sortedValues) Less(i, j int) bool { return sv[i].String() < sv[j].Strin
|
| 160 | 160 |
func buildMap(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error {
|
| 161 | 161 |
buf.WriteString("{")
|
| 162 | 162 |
|
| 163 |
- var sv sortedValues = value.MapKeys() |
|
| 163 |
+ sv := sortedValues(value.MapKeys()) |
|
| 164 | 164 |
sort.Sort(sv) |
| 165 | 165 |
|
| 166 | 166 |
for i, k := range sv {
|
| ... | ... |
@@ -1,9 +1,9 @@ |
| 1 |
-// Package jsonrpc provides JSON RPC utilities for serialisation of AWS |
|
| 1 |
+// Package jsonrpc provides JSON RPC utilities for serialization of AWS |
|
| 2 | 2 |
// requests and responses. |
| 3 | 3 |
package jsonrpc |
| 4 | 4 |
|
| 5 |
-//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/json.json build_test.go |
|
| 6 |
-//go:generate go run ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go |
|
| 5 |
+//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/json.json build_test.go |
|
| 6 |
+//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go |
|
| 7 | 7 |
|
| 8 | 8 |
import ( |
| 9 | 9 |
"encoding/json" |
| 10 | 10 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,36 @@ |
| 0 |
+// Package query provides serialization of AWS query requests, and responses. |
|
| 1 |
+package query |
|
| 2 |
+ |
|
| 3 |
+//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/query.json build_test.go |
|
| 4 |
+ |
|
| 5 |
+import ( |
|
| 6 |
+ "net/url" |
|
| 7 |
+ |
|
| 8 |
+ "github.com/aws/aws-sdk-go/aws/awserr" |
|
| 9 |
+ "github.com/aws/aws-sdk-go/aws/request" |
|
| 10 |
+ "github.com/aws/aws-sdk-go/private/protocol/query/queryutil" |
|
| 11 |
+) |
|
| 12 |
+ |
|
| 13 |
+// BuildHandler is a named request handler for building query protocol requests |
|
| 14 |
+var BuildHandler = request.NamedHandler{Name: "awssdk.query.Build", Fn: Build}
|
|
| 15 |
+ |
|
| 16 |
+// Build builds a request for an AWS Query service. |
|
| 17 |
+func Build(r *request.Request) {
|
|
| 18 |
+ body := url.Values{
|
|
| 19 |
+ "Action": {r.Operation.Name},
|
|
| 20 |
+ "Version": {r.ClientInfo.APIVersion},
|
|
| 21 |
+ } |
|
| 22 |
+ if err := queryutil.Parse(body, r.Params, false); err != nil {
|
|
| 23 |
+ r.Error = awserr.New("SerializationError", "failed encoding Query request", err)
|
|
| 24 |
+ return |
|
| 25 |
+ } |
|
| 26 |
+ |
|
| 27 |
+ if r.ExpireTime == 0 {
|
|
| 28 |
+ r.HTTPRequest.Method = "POST" |
|
| 29 |
+ r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8")
|
|
| 30 |
+ r.SetBufferBody([]byte(body.Encode())) |
|
| 31 |
+ } else { // This is a pre-signed request
|
|
| 32 |
+ r.HTTPRequest.Method = "GET" |
|
| 33 |
+ r.HTTPRequest.URL.RawQuery = body.Encode() |
|
| 34 |
+ } |
|
| 35 |
+} |
| 0 | 36 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,230 @@ |
| 0 |
+package queryutil |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/base64" |
|
| 4 |
+ "fmt" |
|
| 5 |
+ "net/url" |
|
| 6 |
+ "reflect" |
|
| 7 |
+ "sort" |
|
| 8 |
+ "strconv" |
|
| 9 |
+ "strings" |
|
| 10 |
+ "time" |
|
| 11 |
+ |
|
| 12 |
+ "github.com/aws/aws-sdk-go/private/protocol" |
|
| 13 |
+) |
|
| 14 |
+ |
|
| 15 |
+// Parse parses an object i and fills a url.Values object. The isEC2 flag |
|
| 16 |
+// indicates if this is the EC2 Query sub-protocol. |
|
| 17 |
+func Parse(body url.Values, i interface{}, isEC2 bool) error {
|
|
| 18 |
+ q := queryParser{isEC2: isEC2}
|
|
| 19 |
+ return q.parseValue(body, reflect.ValueOf(i), "", "") |
|
| 20 |
+} |
|
| 21 |
+ |
|
| 22 |
+func elemOf(value reflect.Value) reflect.Value {
|
|
| 23 |
+ for value.Kind() == reflect.Ptr {
|
|
| 24 |
+ value = value.Elem() |
|
| 25 |
+ } |
|
| 26 |
+ return value |
|
| 27 |
+} |
|
| 28 |
+ |
|
| 29 |
+type queryParser struct {
|
|
| 30 |
+ isEC2 bool |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
|
|
| 34 |
+ value = elemOf(value) |
|
| 35 |
+ |
|
| 36 |
+ // no need to handle zero values |
|
| 37 |
+ if !value.IsValid() {
|
|
| 38 |
+ return nil |
|
| 39 |
+ } |
|
| 40 |
+ |
|
| 41 |
+ t := tag.Get("type")
|
|
| 42 |
+ if t == "" {
|
|
| 43 |
+ switch value.Kind() {
|
|
| 44 |
+ case reflect.Struct: |
|
| 45 |
+ t = "structure" |
|
| 46 |
+ case reflect.Slice: |
|
| 47 |
+ t = "list" |
|
| 48 |
+ case reflect.Map: |
|
| 49 |
+ t = "map" |
|
| 50 |
+ } |
|
| 51 |
+ } |
|
| 52 |
+ |
|
| 53 |
+ switch t {
|
|
| 54 |
+ case "structure": |
|
| 55 |
+ return q.parseStruct(v, value, prefix) |
|
| 56 |
+ case "list": |
|
| 57 |
+ return q.parseList(v, value, prefix, tag) |
|
| 58 |
+ case "map": |
|
| 59 |
+ return q.parseMap(v, value, prefix, tag) |
|
| 60 |
+ default: |
|
| 61 |
+ return q.parseScalar(v, value, prefix, tag) |
|
| 62 |
+ } |
|
| 63 |
+} |
|
| 64 |
+ |
|
| 65 |
+func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix string) error {
|
|
| 66 |
+ if !value.IsValid() {
|
|
| 67 |
+ return nil |
|
| 68 |
+ } |
|
| 69 |
+ |
|
| 70 |
+ t := value.Type() |
|
| 71 |
+ for i := 0; i < value.NumField(); i++ {
|
|
| 72 |
+ elemValue := elemOf(value.Field(i)) |
|
| 73 |
+ field := t.Field(i) |
|
| 74 |
+ |
|
| 75 |
+ if field.PkgPath != "" {
|
|
| 76 |
+ continue // ignore unexported fields |
|
| 77 |
+ } |
|
| 78 |
+ |
|
| 79 |
+ if protocol.CanSetIdempotencyToken(value.Field(i), field) {
|
|
| 80 |
+ token := protocol.GetIdempotencyToken() |
|
| 81 |
+ elemValue = reflect.ValueOf(token) |
|
| 82 |
+ } |
|
| 83 |
+ |
|
| 84 |
+ var name string |
|
| 85 |
+ if q.isEC2 {
|
|
| 86 |
+ name = field.Tag.Get("queryName")
|
|
| 87 |
+ } |
|
| 88 |
+ if name == "" {
|
|
| 89 |
+ if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" {
|
|
| 90 |
+ name = field.Tag.Get("locationNameList")
|
|
| 91 |
+ } else if locName := field.Tag.Get("locationName"); locName != "" {
|
|
| 92 |
+ name = locName |
|
| 93 |
+ } |
|
| 94 |
+ if name != "" && q.isEC2 {
|
|
| 95 |
+ name = strings.ToUpper(name[0:1]) + name[1:] |
|
| 96 |
+ } |
|
| 97 |
+ } |
|
| 98 |
+ if name == "" {
|
|
| 99 |
+ name = field.Name |
|
| 100 |
+ } |
|
| 101 |
+ |
|
| 102 |
+ if prefix != "" {
|
|
| 103 |
+ name = prefix + "." + name |
|
| 104 |
+ } |
|
| 105 |
+ |
|
| 106 |
+ if err := q.parseValue(v, elemValue, name, field.Tag); err != nil {
|
|
| 107 |
+ return err |
|
| 108 |
+ } |
|
| 109 |
+ } |
|
| 110 |
+ return nil |
|
| 111 |
+} |
|
| 112 |
+ |
|
| 113 |
+func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
|
|
| 114 |
+ // If it's empty, generate an empty value |
|
| 115 |
+ if !value.IsNil() && value.Len() == 0 {
|
|
| 116 |
+ v.Set(prefix, "") |
|
| 117 |
+ return nil |
|
| 118 |
+ } |
|
| 119 |
+ |
|
| 120 |
+ // check for unflattened list member |
|
| 121 |
+ if !q.isEC2 && tag.Get("flattened") == "" {
|
|
| 122 |
+ prefix += ".member" |
|
| 123 |
+ } |
|
| 124 |
+ |
|
| 125 |
+ for i := 0; i < value.Len(); i++ {
|
|
| 126 |
+ slicePrefix := prefix |
|
| 127 |
+ if slicePrefix == "" {
|
|
| 128 |
+ slicePrefix = strconv.Itoa(i + 1) |
|
| 129 |
+ } else {
|
|
| 130 |
+ slicePrefix = slicePrefix + "." + strconv.Itoa(i+1) |
|
| 131 |
+ } |
|
| 132 |
+ if err := q.parseValue(v, value.Index(i), slicePrefix, ""); err != nil {
|
|
| 133 |
+ return err |
|
| 134 |
+ } |
|
| 135 |
+ } |
|
| 136 |
+ return nil |
|
| 137 |
+} |
|
| 138 |
+ |
|
| 139 |
+func (q *queryParser) parseMap(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error {
|
|
| 140 |
+ // If it's empty, generate an empty value |
|
| 141 |
+ if !value.IsNil() && value.Len() == 0 {
|
|
| 142 |
+ v.Set(prefix, "") |
|
| 143 |
+ return nil |
|
| 144 |
+ } |
|
| 145 |
+ |
|
| 146 |
+ // check for unflattened list member |
|
| 147 |
+ if !q.isEC2 && tag.Get("flattened") == "" {
|
|
| 148 |
+ prefix += ".entry" |
|
| 149 |
+ } |
|
| 150 |
+ |
|
| 151 |
+ // sort keys for improved serialization consistency. |
|
| 152 |
+ // this is not strictly necessary for protocol support. |
|
| 153 |
+ mapKeyValues := value.MapKeys() |
|
| 154 |
+ mapKeys := map[string]reflect.Value{}
|
|
| 155 |
+ mapKeyNames := make([]string, len(mapKeyValues)) |
|
| 156 |
+ for i, mapKey := range mapKeyValues {
|
|
| 157 |
+ name := mapKey.String() |
|
| 158 |
+ mapKeys[name] = mapKey |
|
| 159 |
+ mapKeyNames[i] = name |
|
| 160 |
+ } |
|
| 161 |
+ sort.Strings(mapKeyNames) |
|
| 162 |
+ |
|
| 163 |
+ for i, mapKeyName := range mapKeyNames {
|
|
| 164 |
+ mapKey := mapKeys[mapKeyName] |
|
| 165 |
+ mapValue := value.MapIndex(mapKey) |
|
| 166 |
+ |
|
| 167 |
+ kname := tag.Get("locationNameKey")
|
|
| 168 |
+ if kname == "" {
|
|
| 169 |
+ kname = "key" |
|
| 170 |
+ } |
|
| 171 |
+ vname := tag.Get("locationNameValue")
|
|
| 172 |
+ if vname == "" {
|
|
| 173 |
+ vname = "value" |
|
| 174 |
+ } |
|
| 175 |
+ |
|
| 176 |
+ // serialize key |
|
| 177 |
+ var keyName string |
|
| 178 |
+ if prefix == "" {
|
|
| 179 |
+ keyName = strconv.Itoa(i+1) + "." + kname |
|
| 180 |
+ } else {
|
|
| 181 |
+ keyName = prefix + "." + strconv.Itoa(i+1) + "." + kname |
|
| 182 |
+ } |
|
| 183 |
+ |
|
| 184 |
+ if err := q.parseValue(v, mapKey, keyName, ""); err != nil {
|
|
| 185 |
+ return err |
|
| 186 |
+ } |
|
| 187 |
+ |
|
| 188 |
+ // serialize value |
|
| 189 |
+ var valueName string |
|
| 190 |
+ if prefix == "" {
|
|
| 191 |
+ valueName = strconv.Itoa(i+1) + "." + vname |
|
| 192 |
+ } else {
|
|
| 193 |
+ valueName = prefix + "." + strconv.Itoa(i+1) + "." + vname |
|
| 194 |
+ } |
|
| 195 |
+ |
|
| 196 |
+ if err := q.parseValue(v, mapValue, valueName, ""); err != nil {
|
|
| 197 |
+ return err |
|
| 198 |
+ } |
|
| 199 |
+ } |
|
| 200 |
+ |
|
| 201 |
+ return nil |
|
| 202 |
+} |
|
| 203 |
+ |
|
| 204 |
+func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error {
|
|
| 205 |
+ switch value := r.Interface().(type) {
|
|
| 206 |
+ case string: |
|
| 207 |
+ v.Set(name, value) |
|
| 208 |
+ case []byte: |
|
| 209 |
+ if !r.IsNil() {
|
|
| 210 |
+ v.Set(name, base64.StdEncoding.EncodeToString(value)) |
|
| 211 |
+ } |
|
| 212 |
+ case bool: |
|
| 213 |
+ v.Set(name, strconv.FormatBool(value)) |
|
| 214 |
+ case int64: |
|
| 215 |
+ v.Set(name, strconv.FormatInt(value, 10)) |
|
| 216 |
+ case int: |
|
| 217 |
+ v.Set(name, strconv.Itoa(value)) |
|
| 218 |
+ case float64: |
|
| 219 |
+ v.Set(name, strconv.FormatFloat(value, 'f', -1, 64)) |
|
| 220 |
+ case float32: |
|
| 221 |
+ v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32)) |
|
| 222 |
+ case time.Time: |
|
| 223 |
+ const ISO8601UTC = "2006-01-02T15:04:05Z" |
|
| 224 |
+ v.Set(name, value.UTC().Format(ISO8601UTC)) |
|
| 225 |
+ default: |
|
| 226 |
+ return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name())
|
|
| 227 |
+ } |
|
| 228 |
+ return nil |
|
| 229 |
+} |
| 0 | 230 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,35 @@ |
| 0 |
+package query |
|
| 1 |
+ |
|
| 2 |
+//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/query.json unmarshal_test.go |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "encoding/xml" |
|
| 6 |
+ |
|
| 7 |
+ "github.com/aws/aws-sdk-go/aws/awserr" |
|
| 8 |
+ "github.com/aws/aws-sdk-go/aws/request" |
|
| 9 |
+ "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+// UnmarshalHandler is a named request handler for unmarshaling query protocol requests |
|
| 13 |
+var UnmarshalHandler = request.NamedHandler{Name: "awssdk.query.Unmarshal", Fn: Unmarshal}
|
|
| 14 |
+ |
|
| 15 |
+// UnmarshalMetaHandler is a named request handler for unmarshaling query protocol request metadata |
|
| 16 |
+var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalMeta", Fn: UnmarshalMeta}
|
|
| 17 |
+ |
|
| 18 |
+// Unmarshal unmarshals a response for an AWS Query service. |
|
| 19 |
+func Unmarshal(r *request.Request) {
|
|
| 20 |
+ defer r.HTTPResponse.Body.Close() |
|
| 21 |
+ if r.DataFilled() {
|
|
| 22 |
+ decoder := xml.NewDecoder(r.HTTPResponse.Body) |
|
| 23 |
+ err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result") |
|
| 24 |
+ if err != nil {
|
|
| 25 |
+ r.Error = awserr.New("SerializationError", "failed decoding Query response", err)
|
|
| 26 |
+ return |
|
| 27 |
+ } |
|
| 28 |
+ } |
|
| 29 |
+} |
|
| 30 |
+ |
|
| 31 |
+// UnmarshalMeta unmarshals header response values for an AWS Query service. |
|
| 32 |
+func UnmarshalMeta(r *request.Request) {
|
|
| 33 |
+ r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid")
|
|
| 34 |
+} |
| 0 | 35 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,66 @@ |
| 0 |
+package query |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/xml" |
|
| 4 |
+ "io/ioutil" |
|
| 5 |
+ |
|
| 6 |
+ "github.com/aws/aws-sdk-go/aws/awserr" |
|
| 7 |
+ "github.com/aws/aws-sdk-go/aws/request" |
|
| 8 |
+) |
|
| 9 |
+ |
|
| 10 |
+type xmlErrorResponse struct {
|
|
| 11 |
+ XMLName xml.Name `xml:"ErrorResponse"` |
|
| 12 |
+ Code string `xml:"Error>Code"` |
|
| 13 |
+ Message string `xml:"Error>Message"` |
|
| 14 |
+ RequestID string `xml:"RequestId"` |
|
| 15 |
+} |
|
| 16 |
+ |
|
| 17 |
+type xmlServiceUnavailableResponse struct {
|
|
| 18 |
+ XMLName xml.Name `xml:"ServiceUnavailableException"` |
|
| 19 |
+} |
|
| 20 |
+ |
|
| 21 |
+// UnmarshalErrorHandler is a name request handler to unmarshal request errors |
|
| 22 |
+var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError}
|
|
| 23 |
+ |
|
| 24 |
+// UnmarshalError unmarshals an error response for an AWS Query service. |
|
| 25 |
+func UnmarshalError(r *request.Request) {
|
|
| 26 |
+ defer r.HTTPResponse.Body.Close() |
|
| 27 |
+ |
|
| 28 |
+ bodyBytes, err := ioutil.ReadAll(r.HTTPResponse.Body) |
|
| 29 |
+ if err != nil {
|
|
| 30 |
+ r.Error = awserr.New("SerializationError", "failed to read from query HTTP response body", err)
|
|
| 31 |
+ return |
|
| 32 |
+ } |
|
| 33 |
+ |
|
| 34 |
+ // First check for specific error |
|
| 35 |
+ resp := xmlErrorResponse{}
|
|
| 36 |
+ decodeErr := xml.Unmarshal(bodyBytes, &resp) |
|
| 37 |
+ if decodeErr == nil {
|
|
| 38 |
+ reqID := resp.RequestID |
|
| 39 |
+ if reqID == "" {
|
|
| 40 |
+ reqID = r.RequestID |
|
| 41 |
+ } |
|
| 42 |
+ r.Error = awserr.NewRequestFailure( |
|
| 43 |
+ awserr.New(resp.Code, resp.Message, nil), |
|
| 44 |
+ r.HTTPResponse.StatusCode, |
|
| 45 |
+ reqID, |
|
| 46 |
+ ) |
|
| 47 |
+ return |
|
| 48 |
+ } |
|
| 49 |
+ |
|
| 50 |
+ // Check for unhandled error |
|
| 51 |
+ servUnavailResp := xmlServiceUnavailableResponse{}
|
|
| 52 |
+ unavailErr := xml.Unmarshal(bodyBytes, &servUnavailResp) |
|
| 53 |
+ if unavailErr == nil {
|
|
| 54 |
+ r.Error = awserr.NewRequestFailure( |
|
| 55 |
+ awserr.New("ServiceUnavailableException", "service is unavailable", nil),
|
|
| 56 |
+ r.HTTPResponse.StatusCode, |
|
| 57 |
+ r.RequestID, |
|
| 58 |
+ ) |
|
| 59 |
+ return |
|
| 60 |
+ } |
|
| 61 |
+ |
|
| 62 |
+ // Failed to retrieve any error message from the response body |
|
| 63 |
+ r.Error = awserr.New("SerializationError",
|
|
| 64 |
+ "failed to decode query XML error response", decodeErr) |
|
| 65 |
+} |
| 0 | 66 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,293 @@ |
| 0 |
+// Package xmlutil provides XML serialization of AWS requests and responses. |
|
| 1 |
+package xmlutil |
|
| 2 |
+ |
|
| 3 |
+import ( |
|
| 4 |
+ "encoding/base64" |
|
| 5 |
+ "encoding/xml" |
|
| 6 |
+ "fmt" |
|
| 7 |
+ "reflect" |
|
| 8 |
+ "sort" |
|
| 9 |
+ "strconv" |
|
| 10 |
+ "time" |
|
| 11 |
+ |
|
| 12 |
+ "github.com/aws/aws-sdk-go/private/protocol" |
|
| 13 |
+) |
|
| 14 |
+ |
|
| 15 |
+// BuildXML will serialize params into an xml.Encoder. |
|
| 16 |
+// Error will be returned if the serialization of any of the params or nested values fails. |
|
| 17 |
+func BuildXML(params interface{}, e *xml.Encoder) error {
|
|
| 18 |
+ b := xmlBuilder{encoder: e, namespaces: map[string]string{}}
|
|
| 19 |
+ root := NewXMLElement(xml.Name{})
|
|
| 20 |
+ if err := b.buildValue(reflect.ValueOf(params), root, ""); err != nil {
|
|
| 21 |
+ return err |
|
| 22 |
+ } |
|
| 23 |
+ for _, c := range root.Children {
|
|
| 24 |
+ for _, v := range c {
|
|
| 25 |
+ return StructToXML(e, v, false) |
|
| 26 |
+ } |
|
| 27 |
+ } |
|
| 28 |
+ return nil |
|
| 29 |
+} |
|
| 30 |
+ |
|
| 31 |
+// Returns the reflection element of a value, if it is a pointer. |
|
| 32 |
+func elemOf(value reflect.Value) reflect.Value {
|
|
| 33 |
+ for value.Kind() == reflect.Ptr {
|
|
| 34 |
+ value = value.Elem() |
|
| 35 |
+ } |
|
| 36 |
+ return value |
|
| 37 |
+} |
|
| 38 |
+ |
|
| 39 |
+// A xmlBuilder serializes values from Go code to XML |
|
| 40 |
+type xmlBuilder struct {
|
|
| 41 |
+ encoder *xml.Encoder |
|
| 42 |
+ namespaces map[string]string |
|
| 43 |
+} |
|
| 44 |
+ |
|
| 45 |
+// buildValue generic XMLNode builder for any type. Will build value for their specific type |
|
| 46 |
+// struct, list, map, scalar. |
|
| 47 |
+// |
|
| 48 |
+// Also takes a "type" tag value to set what type a value should be converted to XMLNode as. If |
|
| 49 |
+// type is not provided reflect will be used to determine the value's type. |
|
| 50 |
+func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
|
|
| 51 |
+ value = elemOf(value) |
|
| 52 |
+ if !value.IsValid() { // no need to handle zero values
|
|
| 53 |
+ return nil |
|
| 54 |
+ } else if tag.Get("location") != "" { // don't handle non-body location values
|
|
| 55 |
+ return nil |
|
| 56 |
+ } |
|
| 57 |
+ |
|
| 58 |
+ t := tag.Get("type")
|
|
| 59 |
+ if t == "" {
|
|
| 60 |
+ switch value.Kind() {
|
|
| 61 |
+ case reflect.Struct: |
|
| 62 |
+ t = "structure" |
|
| 63 |
+ case reflect.Slice: |
|
| 64 |
+ t = "list" |
|
| 65 |
+ case reflect.Map: |
|
| 66 |
+ t = "map" |
|
| 67 |
+ } |
|
| 68 |
+ } |
|
| 69 |
+ |
|
| 70 |
+ switch t {
|
|
| 71 |
+ case "structure": |
|
| 72 |
+ if field, ok := value.Type().FieldByName("_"); ok {
|
|
| 73 |
+ tag = tag + reflect.StructTag(" ") + field.Tag
|
|
| 74 |
+ } |
|
| 75 |
+ return b.buildStruct(value, current, tag) |
|
| 76 |
+ case "list": |
|
| 77 |
+ return b.buildList(value, current, tag) |
|
| 78 |
+ case "map": |
|
| 79 |
+ return b.buildMap(value, current, tag) |
|
| 80 |
+ default: |
|
| 81 |
+ return b.buildScalar(value, current, tag) |
|
| 82 |
+ } |
|
| 83 |
+} |
|
| 84 |
+ |
|
| 85 |
+// buildStruct adds a struct and its fields to the current XMLNode. All fields any any nested |
|
| 86 |
+// types are converted to XMLNodes also. |
|
| 87 |
+func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
|
|
| 88 |
+ if !value.IsValid() {
|
|
| 89 |
+ return nil |
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ fieldAdded := false |
|
| 93 |
+ |
|
| 94 |
+ // unwrap payloads |
|
| 95 |
+ if payload := tag.Get("payload"); payload != "" {
|
|
| 96 |
+ field, _ := value.Type().FieldByName(payload) |
|
| 97 |
+ tag = field.Tag |
|
| 98 |
+ value = elemOf(value.FieldByName(payload)) |
|
| 99 |
+ |
|
| 100 |
+ if !value.IsValid() {
|
|
| 101 |
+ return nil |
|
| 102 |
+ } |
|
| 103 |
+ } |
|
| 104 |
+ |
|
| 105 |
+ child := NewXMLElement(xml.Name{Local: tag.Get("locationName")})
|
|
| 106 |
+ |
|
| 107 |
+ // there is an xmlNamespace associated with this struct |
|
| 108 |
+ if prefix, uri := tag.Get("xmlPrefix"), tag.Get("xmlURI"); uri != "" {
|
|
| 109 |
+ ns := xml.Attr{
|
|
| 110 |
+ Name: xml.Name{Local: "xmlns"},
|
|
| 111 |
+ Value: uri, |
|
| 112 |
+ } |
|
| 113 |
+ if prefix != "" {
|
|
| 114 |
+ b.namespaces[prefix] = uri // register the namespace |
|
| 115 |
+ ns.Name.Local = "xmlns:" + prefix |
|
| 116 |
+ } |
|
| 117 |
+ |
|
| 118 |
+ child.Attr = append(child.Attr, ns) |
|
| 119 |
+ } |
|
| 120 |
+ |
|
| 121 |
+ t := value.Type() |
|
| 122 |
+ for i := 0; i < value.NumField(); i++ {
|
|
| 123 |
+ member := elemOf(value.Field(i)) |
|
| 124 |
+ field := t.Field(i) |
|
| 125 |
+ |
|
| 126 |
+ if field.PkgPath != "" {
|
|
| 127 |
+ continue // ignore unexported fields |
|
| 128 |
+ } |
|
| 129 |
+ |
|
| 130 |
+ mTag := field.Tag |
|
| 131 |
+ if mTag.Get("location") != "" { // skip non-body members
|
|
| 132 |
+ continue |
|
| 133 |
+ } |
|
| 134 |
+ |
|
| 135 |
+ if protocol.CanSetIdempotencyToken(value.Field(i), field) {
|
|
| 136 |
+ token := protocol.GetIdempotencyToken() |
|
| 137 |
+ member = reflect.ValueOf(token) |
|
| 138 |
+ } |
|
| 139 |
+ |
|
| 140 |
+ memberName := mTag.Get("locationName")
|
|
| 141 |
+ if memberName == "" {
|
|
| 142 |
+ memberName = field.Name |
|
| 143 |
+ mTag = reflect.StructTag(string(mTag) + ` locationName:"` + memberName + `"`) |
|
| 144 |
+ } |
|
| 145 |
+ if err := b.buildValue(member, child, mTag); err != nil {
|
|
| 146 |
+ return err |
|
| 147 |
+ } |
|
| 148 |
+ |
|
| 149 |
+ fieldAdded = true |
|
| 150 |
+ } |
|
| 151 |
+ |
|
| 152 |
+ if fieldAdded { // only append this child if we have one ore more valid members
|
|
| 153 |
+ current.AddChild(child) |
|
| 154 |
+ } |
|
| 155 |
+ |
|
| 156 |
+ return nil |
|
| 157 |
+} |
|
| 158 |
+ |
|
| 159 |
+// buildList adds the value's list items to the current XMLNode as children nodes. All |
|
| 160 |
+// nested values in the list are converted to XMLNodes also. |
|
| 161 |
+func (b *xmlBuilder) buildList(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
|
|
| 162 |
+ if value.IsNil() { // don't build omitted lists
|
|
| 163 |
+ return nil |
|
| 164 |
+ } |
|
| 165 |
+ |
|
| 166 |
+ // check for unflattened list member |
|
| 167 |
+ flattened := tag.Get("flattened") != ""
|
|
| 168 |
+ |
|
| 169 |
+ xname := xml.Name{Local: tag.Get("locationName")}
|
|
| 170 |
+ if flattened {
|
|
| 171 |
+ for i := 0; i < value.Len(); i++ {
|
|
| 172 |
+ child := NewXMLElement(xname) |
|
| 173 |
+ current.AddChild(child) |
|
| 174 |
+ if err := b.buildValue(value.Index(i), child, ""); err != nil {
|
|
| 175 |
+ return err |
|
| 176 |
+ } |
|
| 177 |
+ } |
|
| 178 |
+ } else {
|
|
| 179 |
+ list := NewXMLElement(xname) |
|
| 180 |
+ current.AddChild(list) |
|
| 181 |
+ |
|
| 182 |
+ for i := 0; i < value.Len(); i++ {
|
|
| 183 |
+ iname := tag.Get("locationNameList")
|
|
| 184 |
+ if iname == "" {
|
|
| 185 |
+ iname = "member" |
|
| 186 |
+ } |
|
| 187 |
+ |
|
| 188 |
+ child := NewXMLElement(xml.Name{Local: iname})
|
|
| 189 |
+ list.AddChild(child) |
|
| 190 |
+ if err := b.buildValue(value.Index(i), child, ""); err != nil {
|
|
| 191 |
+ return err |
|
| 192 |
+ } |
|
| 193 |
+ } |
|
| 194 |
+ } |
|
| 195 |
+ |
|
| 196 |
+ return nil |
|
| 197 |
+} |
|
| 198 |
+ |
|
| 199 |
+// buildMap adds the value's key/value pairs to the current XMLNode as children nodes. All |
|
| 200 |
+// nested values in the map are converted to XMLNodes also. |
|
| 201 |
+// |
|
| 202 |
+// Error will be returned if it is unable to build the map's values into XMLNodes |
|
| 203 |
+func (b *xmlBuilder) buildMap(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
|
|
| 204 |
+ if value.IsNil() { // don't build omitted maps
|
|
| 205 |
+ return nil |
|
| 206 |
+ } |
|
| 207 |
+ |
|
| 208 |
+ maproot := NewXMLElement(xml.Name{Local: tag.Get("locationName")})
|
|
| 209 |
+ current.AddChild(maproot) |
|
| 210 |
+ current = maproot |
|
| 211 |
+ |
|
| 212 |
+ kname, vname := "key", "value" |
|
| 213 |
+ if n := tag.Get("locationNameKey"); n != "" {
|
|
| 214 |
+ kname = n |
|
| 215 |
+ } |
|
| 216 |
+ if n := tag.Get("locationNameValue"); n != "" {
|
|
| 217 |
+ vname = n |
|
| 218 |
+ } |
|
| 219 |
+ |
|
| 220 |
+ // sorting is not required for compliance, but it makes testing easier |
|
| 221 |
+ keys := make([]string, value.Len()) |
|
| 222 |
+ for i, k := range value.MapKeys() {
|
|
| 223 |
+ keys[i] = k.String() |
|
| 224 |
+ } |
|
| 225 |
+ sort.Strings(keys) |
|
| 226 |
+ |
|
| 227 |
+ for _, k := range keys {
|
|
| 228 |
+ v := value.MapIndex(reflect.ValueOf(k)) |
|
| 229 |
+ |
|
| 230 |
+ mapcur := current |
|
| 231 |
+ if tag.Get("flattened") == "" { // add "entry" tag to non-flat maps
|
|
| 232 |
+ child := NewXMLElement(xml.Name{Local: "entry"})
|
|
| 233 |
+ mapcur.AddChild(child) |
|
| 234 |
+ mapcur = child |
|
| 235 |
+ } |
|
| 236 |
+ |
|
| 237 |
+ kchild := NewXMLElement(xml.Name{Local: kname})
|
|
| 238 |
+ kchild.Text = k |
|
| 239 |
+ vchild := NewXMLElement(xml.Name{Local: vname})
|
|
| 240 |
+ mapcur.AddChild(kchild) |
|
| 241 |
+ mapcur.AddChild(vchild) |
|
| 242 |
+ |
|
| 243 |
+ if err := b.buildValue(v, vchild, ""); err != nil {
|
|
| 244 |
+ return err |
|
| 245 |
+ } |
|
| 246 |
+ } |
|
| 247 |
+ |
|
| 248 |
+ return nil |
|
| 249 |
+} |
|
| 250 |
+ |
|
| 251 |
+// buildScalar will convert the value into a string and append it as a attribute or child |
|
| 252 |
+// of the current XMLNode. |
|
| 253 |
+// |
|
| 254 |
+// The value will be added as an attribute if tag contains a "xmlAttribute" attribute value. |
|
| 255 |
+// |
|
| 256 |
+// Error will be returned if the value type is unsupported. |
|
| 257 |
+func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
|
|
| 258 |
+ var str string |
|
| 259 |
+ switch converted := value.Interface().(type) {
|
|
| 260 |
+ case string: |
|
| 261 |
+ str = converted |
|
| 262 |
+ case []byte: |
|
| 263 |
+ if !value.IsNil() {
|
|
| 264 |
+ str = base64.StdEncoding.EncodeToString(converted) |
|
| 265 |
+ } |
|
| 266 |
+ case bool: |
|
| 267 |
+ str = strconv.FormatBool(converted) |
|
| 268 |
+ case int64: |
|
| 269 |
+ str = strconv.FormatInt(converted, 10) |
|
| 270 |
+ case int: |
|
| 271 |
+ str = strconv.Itoa(converted) |
|
| 272 |
+ case float64: |
|
| 273 |
+ str = strconv.FormatFloat(converted, 'f', -1, 64) |
|
| 274 |
+ case float32: |
|
| 275 |
+ str = strconv.FormatFloat(float64(converted), 'f', -1, 32) |
|
| 276 |
+ case time.Time: |
|
| 277 |
+ const ISO8601UTC = "2006-01-02T15:04:05Z" |
|
| 278 |
+ str = converted.UTC().Format(ISO8601UTC) |
|
| 279 |
+ default: |
|
| 280 |
+ return fmt.Errorf("unsupported value for param %s: %v (%s)",
|
|
| 281 |
+ tag.Get("locationName"), value.Interface(), value.Type().Name())
|
|
| 282 |
+ } |
|
| 283 |
+ |
|
| 284 |
+ xname := xml.Name{Local: tag.Get("locationName")}
|
|
| 285 |
+ if tag.Get("xmlAttribute") != "" { // put into current node's attribute list
|
|
| 286 |
+ attr := xml.Attr{Name: xname, Value: str}
|
|
| 287 |
+ current.Attr = append(current.Attr, attr) |
|
| 288 |
+ } else { // regular text node
|
|
| 289 |
+ current.AddChild(&XMLNode{Name: xname, Text: str})
|
|
| 290 |
+ } |
|
| 291 |
+ return nil |
|
| 292 |
+} |
| 0 | 293 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,260 @@ |
| 0 |
+package xmlutil |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/base64" |
|
| 4 |
+ "encoding/xml" |
|
| 5 |
+ "fmt" |
|
| 6 |
+ "io" |
|
| 7 |
+ "reflect" |
|
| 8 |
+ "strconv" |
|
| 9 |
+ "strings" |
|
| 10 |
+ "time" |
|
| 11 |
+) |
|
| 12 |
+ |
|
| 13 |
+// UnmarshalXML deserializes an xml.Decoder into the container v. V |
|
| 14 |
+// needs to match the shape of the XML expected to be decoded. |
|
| 15 |
+// If the shape doesn't match unmarshaling will fail. |
|
| 16 |
+func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error {
|
|
| 17 |
+ n, _ := XMLToStruct(d, nil) |
|
| 18 |
+ if n.Children != nil {
|
|
| 19 |
+ for _, root := range n.Children {
|
|
| 20 |
+ for _, c := range root {
|
|
| 21 |
+ if wrappedChild, ok := c.Children[wrapper]; ok {
|
|
| 22 |
+ c = wrappedChild[0] // pull out wrapped element |
|
| 23 |
+ } |
|
| 24 |
+ |
|
| 25 |
+ err := parse(reflect.ValueOf(v), c, "") |
|
| 26 |
+ if err != nil {
|
|
| 27 |
+ if err == io.EOF {
|
|
| 28 |
+ return nil |
|
| 29 |
+ } |
|
| 30 |
+ return err |
|
| 31 |
+ } |
|
| 32 |
+ } |
|
| 33 |
+ } |
|
| 34 |
+ return nil |
|
| 35 |
+ } |
|
| 36 |
+ return nil |
|
| 37 |
+} |
|
| 38 |
+ |
|
| 39 |
+// parse deserializes any value from the XMLNode. The type tag is used to infer the type, or reflect |
|
| 40 |
+// will be used to determine the type from r. |
|
| 41 |
+func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
|
| 42 |
+ rtype := r.Type() |
|
| 43 |
+ if rtype.Kind() == reflect.Ptr {
|
|
| 44 |
+ rtype = rtype.Elem() // check kind of actual element type |
|
| 45 |
+ } |
|
| 46 |
+ |
|
| 47 |
+ t := tag.Get("type")
|
|
| 48 |
+ if t == "" {
|
|
| 49 |
+ switch rtype.Kind() {
|
|
| 50 |
+ case reflect.Struct: |
|
| 51 |
+ t = "structure" |
|
| 52 |
+ case reflect.Slice: |
|
| 53 |
+ t = "list" |
|
| 54 |
+ case reflect.Map: |
|
| 55 |
+ t = "map" |
|
| 56 |
+ } |
|
| 57 |
+ } |
|
| 58 |
+ |
|
| 59 |
+ switch t {
|
|
| 60 |
+ case "structure": |
|
| 61 |
+ if field, ok := rtype.FieldByName("_"); ok {
|
|
| 62 |
+ tag = field.Tag |
|
| 63 |
+ } |
|
| 64 |
+ return parseStruct(r, node, tag) |
|
| 65 |
+ case "list": |
|
| 66 |
+ return parseList(r, node, tag) |
|
| 67 |
+ case "map": |
|
| 68 |
+ return parseMap(r, node, tag) |
|
| 69 |
+ default: |
|
| 70 |
+ return parseScalar(r, node, tag) |
|
| 71 |
+ } |
|
| 72 |
+} |
|
| 73 |
+ |
|
| 74 |
+// parseStruct deserializes a structure and its fields from an XMLNode. Any nested |
|
| 75 |
+// types in the structure will also be deserialized. |
|
| 76 |
+func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
|
| 77 |
+ t := r.Type() |
|
| 78 |
+ if r.Kind() == reflect.Ptr {
|
|
| 79 |
+ if r.IsNil() { // create the structure if it's nil
|
|
| 80 |
+ s := reflect.New(r.Type().Elem()) |
|
| 81 |
+ r.Set(s) |
|
| 82 |
+ r = s |
|
| 83 |
+ } |
|
| 84 |
+ |
|
| 85 |
+ r = r.Elem() |
|
| 86 |
+ t = t.Elem() |
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ // unwrap any payloads |
|
| 90 |
+ if payload := tag.Get("payload"); payload != "" {
|
|
| 91 |
+ field, _ := t.FieldByName(payload) |
|
| 92 |
+ return parseStruct(r.FieldByName(payload), node, field.Tag) |
|
| 93 |
+ } |
|
| 94 |
+ |
|
| 95 |
+ for i := 0; i < t.NumField(); i++ {
|
|
| 96 |
+ field := t.Field(i) |
|
| 97 |
+ if c := field.Name[0:1]; strings.ToLower(c) == c {
|
|
| 98 |
+ continue // ignore unexported fields |
|
| 99 |
+ } |
|
| 100 |
+ |
|
| 101 |
+ // figure out what this field is called |
|
| 102 |
+ name := field.Name |
|
| 103 |
+ if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" {
|
|
| 104 |
+ name = field.Tag.Get("locationNameList")
|
|
| 105 |
+ } else if locName := field.Tag.Get("locationName"); locName != "" {
|
|
| 106 |
+ name = locName |
|
| 107 |
+ } |
|
| 108 |
+ |
|
| 109 |
+ // try to find the field by name in elements |
|
| 110 |
+ elems := node.Children[name] |
|
| 111 |
+ |
|
| 112 |
+ if elems == nil { // try to find the field in attributes
|
|
| 113 |
+ for _, a := range node.Attr {
|
|
| 114 |
+ if name == a.Name.Local {
|
|
| 115 |
+ // turn this into a text node for de-serializing |
|
| 116 |
+ elems = []*XMLNode{{Text: a.Value}}
|
|
| 117 |
+ } |
|
| 118 |
+ } |
|
| 119 |
+ } |
|
| 120 |
+ |
|
| 121 |
+ member := r.FieldByName(field.Name) |
|
| 122 |
+ for _, elem := range elems {
|
|
| 123 |
+ err := parse(member, elem, field.Tag) |
|
| 124 |
+ if err != nil {
|
|
| 125 |
+ return err |
|
| 126 |
+ } |
|
| 127 |
+ } |
|
| 128 |
+ } |
|
| 129 |
+ return nil |
|
| 130 |
+} |
|
| 131 |
+ |
|
| 132 |
+// parseList deserializes a list of values from an XML node. Each list entry |
|
| 133 |
+// will also be deserialized. |
|
| 134 |
+func parseList(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
|
| 135 |
+ t := r.Type() |
|
| 136 |
+ |
|
| 137 |
+ if tag.Get("flattened") == "" { // look at all item entries
|
|
| 138 |
+ mname := "member" |
|
| 139 |
+ if name := tag.Get("locationNameList"); name != "" {
|
|
| 140 |
+ mname = name |
|
| 141 |
+ } |
|
| 142 |
+ |
|
| 143 |
+ if Children, ok := node.Children[mname]; ok {
|
|
| 144 |
+ if r.IsNil() {
|
|
| 145 |
+ r.Set(reflect.MakeSlice(t, len(Children), len(Children))) |
|
| 146 |
+ } |
|
| 147 |
+ |
|
| 148 |
+ for i, c := range Children {
|
|
| 149 |
+ err := parse(r.Index(i), c, "") |
|
| 150 |
+ if err != nil {
|
|
| 151 |
+ return err |
|
| 152 |
+ } |
|
| 153 |
+ } |
|
| 154 |
+ } |
|
| 155 |
+ } else { // flattened list means this is a single element
|
|
| 156 |
+ if r.IsNil() {
|
|
| 157 |
+ r.Set(reflect.MakeSlice(t, 0, 0)) |
|
| 158 |
+ } |
|
| 159 |
+ |
|
| 160 |
+ childR := reflect.Zero(t.Elem()) |
|
| 161 |
+ r.Set(reflect.Append(r, childR)) |
|
| 162 |
+ err := parse(r.Index(r.Len()-1), node, "") |
|
| 163 |
+ if err != nil {
|
|
| 164 |
+ return err |
|
| 165 |
+ } |
|
| 166 |
+ } |
|
| 167 |
+ |
|
| 168 |
+ return nil |
|
| 169 |
+} |
|
| 170 |
+ |
|
| 171 |
+// parseMap deserializes a map from an XMLNode. The direct children of the XMLNode |
|
| 172 |
+// will also be deserialized as map entries. |
|
| 173 |
+func parseMap(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
|
| 174 |
+ if r.IsNil() {
|
|
| 175 |
+ r.Set(reflect.MakeMap(r.Type())) |
|
| 176 |
+ } |
|
| 177 |
+ |
|
| 178 |
+ if tag.Get("flattened") == "" { // look at all child entries
|
|
| 179 |
+ for _, entry := range node.Children["entry"] {
|
|
| 180 |
+ parseMapEntry(r, entry, tag) |
|
| 181 |
+ } |
|
| 182 |
+ } else { // this element is itself an entry
|
|
| 183 |
+ parseMapEntry(r, node, tag) |
|
| 184 |
+ } |
|
| 185 |
+ |
|
| 186 |
+ return nil |
|
| 187 |
+} |
|
| 188 |
+ |
|
| 189 |
+// parseMapEntry deserializes a map entry from a XML node. |
|
| 190 |
+func parseMapEntry(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
|
| 191 |
+ kname, vname := "key", "value" |
|
| 192 |
+ if n := tag.Get("locationNameKey"); n != "" {
|
|
| 193 |
+ kname = n |
|
| 194 |
+ } |
|
| 195 |
+ if n := tag.Get("locationNameValue"); n != "" {
|
|
| 196 |
+ vname = n |
|
| 197 |
+ } |
|
| 198 |
+ |
|
| 199 |
+ keys, ok := node.Children[kname] |
|
| 200 |
+ values := node.Children[vname] |
|
| 201 |
+ if ok {
|
|
| 202 |
+ for i, key := range keys {
|
|
| 203 |
+ keyR := reflect.ValueOf(key.Text) |
|
| 204 |
+ value := values[i] |
|
| 205 |
+ valueR := reflect.New(r.Type().Elem()).Elem() |
|
| 206 |
+ |
|
| 207 |
+ parse(valueR, value, "") |
|
| 208 |
+ r.SetMapIndex(keyR, valueR) |
|
| 209 |
+ } |
|
| 210 |
+ } |
|
| 211 |
+ return nil |
|
| 212 |
+} |
|
| 213 |
+ |
|
| 214 |
+// parseScaller deserializes an XMLNode value into a concrete type based on the |
|
| 215 |
+// interface type of r. |
|
| 216 |
+// |
|
| 217 |
+// Error is returned if the deserialization fails due to invalid type conversion, |
|
| 218 |
+// or unsupported interface type. |
|
| 219 |
+func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error {
|
|
| 220 |
+ switch r.Interface().(type) {
|
|
| 221 |
+ case *string: |
|
| 222 |
+ r.Set(reflect.ValueOf(&node.Text)) |
|
| 223 |
+ return nil |
|
| 224 |
+ case []byte: |
|
| 225 |
+ b, err := base64.StdEncoding.DecodeString(node.Text) |
|
| 226 |
+ if err != nil {
|
|
| 227 |
+ return err |
|
| 228 |
+ } |
|
| 229 |
+ r.Set(reflect.ValueOf(b)) |
|
| 230 |
+ case *bool: |
|
| 231 |
+ v, err := strconv.ParseBool(node.Text) |
|
| 232 |
+ if err != nil {
|
|
| 233 |
+ return err |
|
| 234 |
+ } |
|
| 235 |
+ r.Set(reflect.ValueOf(&v)) |
|
| 236 |
+ case *int64: |
|
| 237 |
+ v, err := strconv.ParseInt(node.Text, 10, 64) |
|
| 238 |
+ if err != nil {
|
|
| 239 |
+ return err |
|
| 240 |
+ } |
|
| 241 |
+ r.Set(reflect.ValueOf(&v)) |
|
| 242 |
+ case *float64: |
|
| 243 |
+ v, err := strconv.ParseFloat(node.Text, 64) |
|
| 244 |
+ if err != nil {
|
|
| 245 |
+ return err |
|
| 246 |
+ } |
|
| 247 |
+ r.Set(reflect.ValueOf(&v)) |
|
| 248 |
+ case *time.Time: |
|
| 249 |
+ const ISO8601UTC = "2006-01-02T15:04:05Z" |
|
| 250 |
+ t, err := time.Parse(ISO8601UTC, node.Text) |
|
| 251 |
+ if err != nil {
|
|
| 252 |
+ return err |
|
| 253 |
+ } |
|
| 254 |
+ r.Set(reflect.ValueOf(&t)) |
|
| 255 |
+ default: |
|
| 256 |
+ return fmt.Errorf("unsupported value: %v (%s)", r.Interface(), r.Type())
|
|
| 257 |
+ } |
|
| 258 |
+ return nil |
|
| 259 |
+} |
| 0 | 260 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,105 @@ |
| 0 |
+package xmlutil |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "encoding/xml" |
|
| 4 |
+ "io" |
|
| 5 |
+ "sort" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+// A XMLNode contains the values to be encoded or decoded. |
|
| 9 |
+type XMLNode struct {
|
|
| 10 |
+ Name xml.Name `json:",omitempty"` |
|
| 11 |
+ Children map[string][]*XMLNode `json:",omitempty"` |
|
| 12 |
+ Text string `json:",omitempty"` |
|
| 13 |
+ Attr []xml.Attr `json:",omitempty"` |
|
| 14 |
+} |
|
| 15 |
+ |
|
| 16 |
+// NewXMLElement returns a pointer to a new XMLNode initialized to default values. |
|
| 17 |
+func NewXMLElement(name xml.Name) *XMLNode {
|
|
| 18 |
+ return &XMLNode{
|
|
| 19 |
+ Name: name, |
|
| 20 |
+ Children: map[string][]*XMLNode{},
|
|
| 21 |
+ Attr: []xml.Attr{},
|
|
| 22 |
+ } |
|
| 23 |
+} |
|
| 24 |
+ |
|
| 25 |
+// AddChild adds child to the XMLNode. |
|
| 26 |
+func (n *XMLNode) AddChild(child *XMLNode) {
|
|
| 27 |
+ if _, ok := n.Children[child.Name.Local]; !ok {
|
|
| 28 |
+ n.Children[child.Name.Local] = []*XMLNode{}
|
|
| 29 |
+ } |
|
| 30 |
+ n.Children[child.Name.Local] = append(n.Children[child.Name.Local], child) |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+// XMLToStruct converts a xml.Decoder stream to XMLNode with nested values. |
|
| 34 |
+func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) {
|
|
| 35 |
+ out := &XMLNode{}
|
|
| 36 |
+ for {
|
|
| 37 |
+ tok, err := d.Token() |
|
| 38 |
+ if tok == nil || err == io.EOF {
|
|
| 39 |
+ break |
|
| 40 |
+ } |
|
| 41 |
+ if err != nil {
|
|
| 42 |
+ return out, err |
|
| 43 |
+ } |
|
| 44 |
+ |
|
| 45 |
+ switch typed := tok.(type) {
|
|
| 46 |
+ case xml.CharData: |
|
| 47 |
+ out.Text = string(typed.Copy()) |
|
| 48 |
+ case xml.StartElement: |
|
| 49 |
+ el := typed.Copy() |
|
| 50 |
+ out.Attr = el.Attr |
|
| 51 |
+ if out.Children == nil {
|
|
| 52 |
+ out.Children = map[string][]*XMLNode{}
|
|
| 53 |
+ } |
|
| 54 |
+ |
|
| 55 |
+ name := typed.Name.Local |
|
| 56 |
+ slice := out.Children[name] |
|
| 57 |
+ if slice == nil {
|
|
| 58 |
+ slice = []*XMLNode{}
|
|
| 59 |
+ } |
|
| 60 |
+ node, e := XMLToStruct(d, &el) |
|
| 61 |
+ if e != nil {
|
|
| 62 |
+ return out, e |
|
| 63 |
+ } |
|
| 64 |
+ node.Name = typed.Name |
|
| 65 |
+ slice = append(slice, node) |
|
| 66 |
+ out.Children[name] = slice |
|
| 67 |
+ case xml.EndElement: |
|
| 68 |
+ if s != nil && s.Name.Local == typed.Name.Local { // matching end token
|
|
| 69 |
+ return out, nil |
|
| 70 |
+ } |
|
| 71 |
+ } |
|
| 72 |
+ } |
|
| 73 |
+ return out, nil |
|
| 74 |
+} |
|
| 75 |
+ |
|
| 76 |
+// StructToXML writes an XMLNode to a xml.Encoder as tokens. |
|
| 77 |
+func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error {
|
|
| 78 |
+ e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr})
|
|
| 79 |
+ |
|
| 80 |
+ if node.Text != "" {
|
|
| 81 |
+ e.EncodeToken(xml.CharData([]byte(node.Text))) |
|
| 82 |
+ } else if sorted {
|
|
| 83 |
+ sortedNames := []string{}
|
|
| 84 |
+ for k := range node.Children {
|
|
| 85 |
+ sortedNames = append(sortedNames, k) |
|
| 86 |
+ } |
|
| 87 |
+ sort.Strings(sortedNames) |
|
| 88 |
+ |
|
| 89 |
+ for _, k := range sortedNames {
|
|
| 90 |
+ for _, v := range node.Children[k] {
|
|
| 91 |
+ StructToXML(e, v, sorted) |
|
| 92 |
+ } |
|
| 93 |
+ } |
|
| 94 |
+ } else {
|
|
| 95 |
+ for _, c := range node.Children {
|
|
| 96 |
+ for _, v := range c {
|
|
| 97 |
+ StructToXML(e, v, sorted) |
|
| 98 |
+ } |
|
| 99 |
+ } |
|
| 100 |
+ } |
|
| 101 |
+ |
|
| 102 |
+ e.EncodeToken(xml.EndElement{Name: node.Name})
|
|
| 103 |
+ return e.Flush() |
|
| 104 |
+} |
| 0 | 105 |
deleted file mode 100644 |
| ... | ... |
@@ -1,82 +0,0 @@ |
| 1 |
-package v4 |
|
| 2 |
- |
|
| 3 |
-import ( |
|
| 4 |
- "net/http" |
|
| 5 |
- "strings" |
|
| 6 |
-) |
|
| 7 |
- |
|
| 8 |
-// validator houses a set of rule needed for validation of a |
|
| 9 |
-// string value |
|
| 10 |
-type rules []rule |
|
| 11 |
- |
|
| 12 |
-// rule interface allows for more flexible rules and just simply |
|
| 13 |
-// checks whether or not a value adheres to that rule |
|
| 14 |
-type rule interface {
|
|
| 15 |
- IsValid(value string) bool |
|
| 16 |
-} |
|
| 17 |
- |
|
| 18 |
-// IsValid will iterate through all rules and see if any rules |
|
| 19 |
-// apply to the value and supports nested rules |
|
| 20 |
-func (r rules) IsValid(value string) bool {
|
|
| 21 |
- for _, rule := range r {
|
|
| 22 |
- if rule.IsValid(value) {
|
|
| 23 |
- return true |
|
| 24 |
- } |
|
| 25 |
- } |
|
| 26 |
- return false |
|
| 27 |
-} |
|
| 28 |
- |
|
| 29 |
-// mapRule generic rule for maps |
|
| 30 |
-type mapRule map[string]struct{}
|
|
| 31 |
- |
|
| 32 |
-// IsValid for the map rule satisfies whether it exists in the map |
|
| 33 |
-func (m mapRule) IsValid(value string) bool {
|
|
| 34 |
- _, ok := m[value] |
|
| 35 |
- return ok |
|
| 36 |
-} |
|
| 37 |
- |
|
| 38 |
-// whitelist is a generic rule for whitelisting |
|
| 39 |
-type whitelist struct {
|
|
| 40 |
- rule |
|
| 41 |
-} |
|
| 42 |
- |
|
| 43 |
-// IsValid for whitelist checks if the value is within the whitelist |
|
| 44 |
-func (w whitelist) IsValid(value string) bool {
|
|
| 45 |
- return w.rule.IsValid(value) |
|
| 46 |
-} |
|
| 47 |
- |
|
| 48 |
-// blacklist is a generic rule for blacklisting |
|
| 49 |
-type blacklist struct {
|
|
| 50 |
- rule |
|
| 51 |
-} |
|
| 52 |
- |
|
| 53 |
-// IsValid for whitelist checks if the value is within the whitelist |
|
| 54 |
-func (b blacklist) IsValid(value string) bool {
|
|
| 55 |
- return !b.rule.IsValid(value) |
|
| 56 |
-} |
|
| 57 |
- |
|
| 58 |
-type patterns []string |
|
| 59 |
- |
|
| 60 |
-// IsValid for patterns checks each pattern and returns if a match has |
|
| 61 |
-// been found |
|
| 62 |
-func (p patterns) IsValid(value string) bool {
|
|
| 63 |
- for _, pattern := range p {
|
|
| 64 |
- if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) {
|
|
| 65 |
- return true |
|
| 66 |
- } |
|
| 67 |
- } |
|
| 68 |
- return false |
|
| 69 |
-} |
|
| 70 |
- |
|
| 71 |
-// inclusiveRules rules allow for rules to depend on one another |
|
| 72 |
-type inclusiveRules []rule |
|
| 73 |
- |
|
| 74 |
-// IsValid will return true if all rules are true |
|
| 75 |
-func (r inclusiveRules) IsValid(value string) bool {
|
|
| 76 |
- for _, rule := range r {
|
|
| 77 |
- if !rule.IsValid(value) {
|
|
| 78 |
- return false |
|
| 79 |
- } |
|
| 80 |
- } |
|
| 81 |
- return true |
|
| 82 |
-} |
| 83 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,465 +0,0 @@ |
| 1 |
-// Package v4 implements signing for AWS V4 signer |
|
| 2 |
-package v4 |
|
| 3 |
- |
|
| 4 |
-import ( |
|
| 5 |
- "crypto/hmac" |
|
| 6 |
- "crypto/sha256" |
|
| 7 |
- "encoding/hex" |
|
| 8 |
- "fmt" |
|
| 9 |
- "io" |
|
| 10 |
- "net/http" |
|
| 11 |
- "net/url" |
|
| 12 |
- "sort" |
|
| 13 |
- "strconv" |
|
| 14 |
- "strings" |
|
| 15 |
- "time" |
|
| 16 |
- |
|
| 17 |
- "github.com/aws/aws-sdk-go/aws" |
|
| 18 |
- "github.com/aws/aws-sdk-go/aws/credentials" |
|
| 19 |
- "github.com/aws/aws-sdk-go/aws/request" |
|
| 20 |
- "github.com/aws/aws-sdk-go/private/protocol/rest" |
|
| 21 |
-) |
|
| 22 |
- |
|
| 23 |
-const ( |
|
| 24 |
- authHeaderPrefix = "AWS4-HMAC-SHA256" |
|
| 25 |
- timeFormat = "20060102T150405Z" |
|
| 26 |
- shortTimeFormat = "20060102" |
|
| 27 |
-) |
|
| 28 |
- |
|
| 29 |
-var ignoredHeaders = rules{
|
|
| 30 |
- blacklist{
|
|
| 31 |
- mapRule{
|
|
| 32 |
- "Authorization": struct{}{},
|
|
| 33 |
- "User-Agent": struct{}{},
|
|
| 34 |
- }, |
|
| 35 |
- }, |
|
| 36 |
-} |
|
| 37 |
- |
|
| 38 |
-// requiredSignedHeaders is a whitelist for build canonical headers. |
|
| 39 |
-var requiredSignedHeaders = rules{
|
|
| 40 |
- whitelist{
|
|
| 41 |
- mapRule{
|
|
| 42 |
- "Cache-Control": struct{}{},
|
|
| 43 |
- "Content-Disposition": struct{}{},
|
|
| 44 |
- "Content-Encoding": struct{}{},
|
|
| 45 |
- "Content-Language": struct{}{},
|
|
| 46 |
- "Content-Md5": struct{}{},
|
|
| 47 |
- "Content-Type": struct{}{},
|
|
| 48 |
- "Expires": struct{}{},
|
|
| 49 |
- "If-Match": struct{}{},
|
|
| 50 |
- "If-Modified-Since": struct{}{},
|
|
| 51 |
- "If-None-Match": struct{}{},
|
|
| 52 |
- "If-Unmodified-Since": struct{}{},
|
|
| 53 |
- "Range": struct{}{},
|
|
| 54 |
- "X-Amz-Acl": struct{}{},
|
|
| 55 |
- "X-Amz-Copy-Source": struct{}{},
|
|
| 56 |
- "X-Amz-Copy-Source-If-Match": struct{}{},
|
|
| 57 |
- "X-Amz-Copy-Source-If-Modified-Since": struct{}{},
|
|
| 58 |
- "X-Amz-Copy-Source-If-None-Match": struct{}{},
|
|
| 59 |
- "X-Amz-Copy-Source-If-Unmodified-Since": struct{}{},
|
|
| 60 |
- "X-Amz-Copy-Source-Range": struct{}{},
|
|
| 61 |
- "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
|
| 62 |
- "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{},
|
|
| 63 |
- "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
|
| 64 |
- "X-Amz-Grant-Full-control": struct{}{},
|
|
| 65 |
- "X-Amz-Grant-Read": struct{}{},
|
|
| 66 |
- "X-Amz-Grant-Read-Acp": struct{}{},
|
|
| 67 |
- "X-Amz-Grant-Write": struct{}{},
|
|
| 68 |
- "X-Amz-Grant-Write-Acp": struct{}{},
|
|
| 69 |
- "X-Amz-Metadata-Directive": struct{}{},
|
|
| 70 |
- "X-Amz-Mfa": struct{}{},
|
|
| 71 |
- "X-Amz-Request-Payer": struct{}{},
|
|
| 72 |
- "X-Amz-Server-Side-Encryption": struct{}{},
|
|
| 73 |
- "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{},
|
|
| 74 |
- "X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{},
|
|
| 75 |
- "X-Amz-Server-Side-Encryption-Customer-Key": struct{}{},
|
|
| 76 |
- "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{},
|
|
| 77 |
- "X-Amz-Storage-Class": struct{}{},
|
|
| 78 |
- "X-Amz-Website-Redirect-Location": struct{}{},
|
|
| 79 |
- }, |
|
| 80 |
- }, |
|
| 81 |
- patterns{"X-Amz-Meta-"},
|
|
| 82 |
-} |
|
| 83 |
- |
|
| 84 |
-// allowedHoisting is a whitelist for build query headers. The boolean value |
|
| 85 |
-// represents whether or not it is a pattern. |
|
| 86 |
-var allowedQueryHoisting = inclusiveRules{
|
|
| 87 |
- blacklist{requiredSignedHeaders},
|
|
| 88 |
- patterns{"X-Amz-"},
|
|
| 89 |
-} |
|
| 90 |
- |
|
| 91 |
-type signer struct {
|
|
| 92 |
- Request *http.Request |
|
| 93 |
- Time time.Time |
|
| 94 |
- ExpireTime time.Duration |
|
| 95 |
- ServiceName string |
|
| 96 |
- Region string |
|
| 97 |
- CredValues credentials.Value |
|
| 98 |
- Credentials *credentials.Credentials |
|
| 99 |
- Query url.Values |
|
| 100 |
- Body io.ReadSeeker |
|
| 101 |
- Debug aws.LogLevelType |
|
| 102 |
- Logger aws.Logger |
|
| 103 |
- |
|
| 104 |
- isPresign bool |
|
| 105 |
- formattedTime string |
|
| 106 |
- formattedShortTime string |
|
| 107 |
- |
|
| 108 |
- signedHeaders string |
|
| 109 |
- canonicalHeaders string |
|
| 110 |
- canonicalString string |
|
| 111 |
- credentialString string |
|
| 112 |
- stringToSign string |
|
| 113 |
- signature string |
|
| 114 |
- authorization string |
|
| 115 |
- notHoist bool |
|
| 116 |
- signedHeaderVals http.Header |
|
| 117 |
-} |
|
| 118 |
- |
|
| 119 |
-// Sign requests with signature version 4. |
|
| 120 |
-// |
|
| 121 |
-// Will sign the requests with the service config's Credentials object |
|
| 122 |
-// Signing is skipped if the credentials is the credentials.AnonymousCredentials |
|
| 123 |
-// object. |
|
| 124 |
-func Sign(req *request.Request) {
|
|
| 125 |
- // If the request does not need to be signed ignore the signing of the |
|
| 126 |
- // request if the AnonymousCredentials object is used. |
|
| 127 |
- if req.Config.Credentials == credentials.AnonymousCredentials {
|
|
| 128 |
- return |
|
| 129 |
- } |
|
| 130 |
- |
|
| 131 |
- region := req.ClientInfo.SigningRegion |
|
| 132 |
- if region == "" {
|
|
| 133 |
- region = aws.StringValue(req.Config.Region) |
|
| 134 |
- } |
|
| 135 |
- |
|
| 136 |
- name := req.ClientInfo.SigningName |
|
| 137 |
- if name == "" {
|
|
| 138 |
- name = req.ClientInfo.ServiceName |
|
| 139 |
- } |
|
| 140 |
- |
|
| 141 |
- s := signer{
|
|
| 142 |
- Request: req.HTTPRequest, |
|
| 143 |
- Time: req.Time, |
|
| 144 |
- ExpireTime: req.ExpireTime, |
|
| 145 |
- Query: req.HTTPRequest.URL.Query(), |
|
| 146 |
- Body: req.Body, |
|
| 147 |
- ServiceName: name, |
|
| 148 |
- Region: region, |
|
| 149 |
- Credentials: req.Config.Credentials, |
|
| 150 |
- Debug: req.Config.LogLevel.Value(), |
|
| 151 |
- Logger: req.Config.Logger, |
|
| 152 |
- notHoist: req.NotHoist, |
|
| 153 |
- } |
|
| 154 |
- |
|
| 155 |
- req.Error = s.sign() |
|
| 156 |
- req.Time = s.Time |
|
| 157 |
- req.SignedHeaderVals = s.signedHeaderVals |
|
| 158 |
-} |
|
| 159 |
- |
|
| 160 |
-func (v4 *signer) sign() error {
|
|
| 161 |
- if v4.ExpireTime != 0 {
|
|
| 162 |
- v4.isPresign = true |
|
| 163 |
- } |
|
| 164 |
- |
|
| 165 |
- if v4.isRequestSigned() {
|
|
| 166 |
- if !v4.Credentials.IsExpired() && time.Now().Before(v4.Time.Add(10*time.Minute)) {
|
|
| 167 |
- // If the request is already signed, and the credentials have not |
|
| 168 |
- // expired, and the request is not too old ignore the signing request. |
|
| 169 |
- return nil |
|
| 170 |
- } |
|
| 171 |
- v4.Time = time.Now() |
|
| 172 |
- |
|
| 173 |
- // The credentials have expired for this request. The current signing |
|
| 174 |
- // is invalid, and needs to be request because the request will fail. |
|
| 175 |
- if v4.isPresign {
|
|
| 176 |
- v4.removePresign() |
|
| 177 |
- // Update the request's query string to ensure the values stays in |
|
| 178 |
- // sync in the case retrieving the new credentials fails. |
|
| 179 |
- v4.Request.URL.RawQuery = v4.Query.Encode() |
|
| 180 |
- } |
|
| 181 |
- } |
|
| 182 |
- |
|
| 183 |
- var err error |
|
| 184 |
- v4.CredValues, err = v4.Credentials.Get() |
|
| 185 |
- if err != nil {
|
|
| 186 |
- return err |
|
| 187 |
- } |
|
| 188 |
- |
|
| 189 |
- if v4.isPresign {
|
|
| 190 |
- v4.Query.Set("X-Amz-Algorithm", authHeaderPrefix)
|
|
| 191 |
- if v4.CredValues.SessionToken != "" {
|
|
| 192 |
- v4.Query.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
|
|
| 193 |
- } else {
|
|
| 194 |
- v4.Query.Del("X-Amz-Security-Token")
|
|
| 195 |
- } |
|
| 196 |
- } else if v4.CredValues.SessionToken != "" {
|
|
| 197 |
- v4.Request.Header.Set("X-Amz-Security-Token", v4.CredValues.SessionToken)
|
|
| 198 |
- } |
|
| 199 |
- |
|
| 200 |
- v4.build() |
|
| 201 |
- |
|
| 202 |
- if v4.Debug.Matches(aws.LogDebugWithSigning) {
|
|
| 203 |
- v4.logSigningInfo() |
|
| 204 |
- } |
|
| 205 |
- |
|
| 206 |
- return nil |
|
| 207 |
-} |
|
| 208 |
- |
|
| 209 |
-const logSignInfoMsg = `DEBUG: Request Signiture: |
|
| 210 |
-%s |
|
| 211 |
-%s%s |
|
| 212 |
-const logSignedURLMsg = ` |
|
| 213 |
-%s` |
|
| 214 |
- |
|
| 215 |
-func (v4 *signer) logSigningInfo() {
|
|
| 216 |
- signedURLMsg := "" |
|
| 217 |
- if v4.isPresign {
|
|
| 218 |
- signedURLMsg = fmt.Sprintf(logSignedURLMsg, v4.Request.URL.String()) |
|
| 219 |
- } |
|
| 220 |
- msg := fmt.Sprintf(logSignInfoMsg, v4.canonicalString, v4.stringToSign, signedURLMsg) |
|
| 221 |
- v4.Logger.Log(msg) |
|
| 222 |
-} |
|
| 223 |
- |
|
| 224 |
-func (v4 *signer) build() {
|
|
| 225 |
- |
|
| 226 |
- v4.buildTime() // no depends |
|
| 227 |
- v4.buildCredentialString() // no depends |
|
| 228 |
- |
|
| 229 |
- unsignedHeaders := v4.Request.Header |
|
| 230 |
- if v4.isPresign {
|
|
| 231 |
- if !v4.notHoist {
|
|
| 232 |
- urlValues := url.Values{}
|
|
| 233 |
- urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends |
|
| 234 |
- for k := range urlValues {
|
|
| 235 |
- v4.Query[k] = urlValues[k] |
|
| 236 |
- } |
|
| 237 |
- } |
|
| 238 |
- } |
|
| 239 |
- |
|
| 240 |
- v4.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders) |
|
| 241 |
- v4.buildCanonicalString() // depends on canon headers / signed headers |
|
| 242 |
- v4.buildStringToSign() // depends on canon string |
|
| 243 |
- v4.buildSignature() // depends on string to sign |
|
| 244 |
- |
|
| 245 |
- if v4.isPresign {
|
|
| 246 |
- v4.Request.URL.RawQuery += "&X-Amz-Signature=" + v4.signature |
|
| 247 |
- } else {
|
|
| 248 |
- parts := []string{
|
|
| 249 |
- authHeaderPrefix + " Credential=" + v4.CredValues.AccessKeyID + "/" + v4.credentialString, |
|
| 250 |
- "SignedHeaders=" + v4.signedHeaders, |
|
| 251 |
- "Signature=" + v4.signature, |
|
| 252 |
- } |
|
| 253 |
- v4.Request.Header.Set("Authorization", strings.Join(parts, ", "))
|
|
| 254 |
- } |
|
| 255 |
-} |
|
| 256 |
- |
|
| 257 |
-func (v4 *signer) buildTime() {
|
|
| 258 |
- v4.formattedTime = v4.Time.UTC().Format(timeFormat) |
|
| 259 |
- v4.formattedShortTime = v4.Time.UTC().Format(shortTimeFormat) |
|
| 260 |
- |
|
| 261 |
- if v4.isPresign {
|
|
| 262 |
- duration := int64(v4.ExpireTime / time.Second) |
|
| 263 |
- v4.Query.Set("X-Amz-Date", v4.formattedTime)
|
|
| 264 |
- v4.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10))
|
|
| 265 |
- } else {
|
|
| 266 |
- v4.Request.Header.Set("X-Amz-Date", v4.formattedTime)
|
|
| 267 |
- } |
|
| 268 |
-} |
|
| 269 |
- |
|
| 270 |
-func (v4 *signer) buildCredentialString() {
|
|
| 271 |
- v4.credentialString = strings.Join([]string{
|
|
| 272 |
- v4.formattedShortTime, |
|
| 273 |
- v4.Region, |
|
| 274 |
- v4.ServiceName, |
|
| 275 |
- "aws4_request", |
|
| 276 |
- }, "/") |
|
| 277 |
- |
|
| 278 |
- if v4.isPresign {
|
|
| 279 |
- v4.Query.Set("X-Amz-Credential", v4.CredValues.AccessKeyID+"/"+v4.credentialString)
|
|
| 280 |
- } |
|
| 281 |
-} |
|
| 282 |
- |
|
| 283 |
-func buildQuery(r rule, header http.Header) (url.Values, http.Header) {
|
|
| 284 |
- query := url.Values{}
|
|
| 285 |
- unsignedHeaders := http.Header{}
|
|
| 286 |
- for k, h := range header {
|
|
| 287 |
- if r.IsValid(k) {
|
|
| 288 |
- query[k] = h |
|
| 289 |
- } else {
|
|
| 290 |
- unsignedHeaders[k] = h |
|
| 291 |
- } |
|
| 292 |
- } |
|
| 293 |
- |
|
| 294 |
- return query, unsignedHeaders |
|
| 295 |
-} |
|
| 296 |
-func (v4 *signer) buildCanonicalHeaders(r rule, header http.Header) {
|
|
| 297 |
- var headers []string |
|
| 298 |
- headers = append(headers, "host") |
|
| 299 |
- for k, v := range header {
|
|
| 300 |
- canonicalKey := http.CanonicalHeaderKey(k) |
|
| 301 |
- if !r.IsValid(canonicalKey) {
|
|
| 302 |
- continue // ignored header |
|
| 303 |
- } |
|
| 304 |
- if v4.signedHeaderVals == nil {
|
|
| 305 |
- v4.signedHeaderVals = make(http.Header) |
|
| 306 |
- } |
|
| 307 |
- |
|
| 308 |
- lowerCaseKey := strings.ToLower(k) |
|
| 309 |
- if _, ok := v4.signedHeaderVals[lowerCaseKey]; ok {
|
|
| 310 |
- // include additional values |
|
| 311 |
- v4.signedHeaderVals[lowerCaseKey] = append(v4.signedHeaderVals[lowerCaseKey], v...) |
|
| 312 |
- continue |
|
| 313 |
- } |
|
| 314 |
- |
|
| 315 |
- headers = append(headers, lowerCaseKey) |
|
| 316 |
- v4.signedHeaderVals[lowerCaseKey] = v |
|
| 317 |
- } |
|
| 318 |
- sort.Strings(headers) |
|
| 319 |
- |
|
| 320 |
- v4.signedHeaders = strings.Join(headers, ";") |
|
| 321 |
- |
|
| 322 |
- if v4.isPresign {
|
|
| 323 |
- v4.Query.Set("X-Amz-SignedHeaders", v4.signedHeaders)
|
|
| 324 |
- } |
|
| 325 |
- |
|
| 326 |
- headerValues := make([]string, len(headers)) |
|
| 327 |
- for i, k := range headers {
|
|
| 328 |
- if k == "host" {
|
|
| 329 |
- headerValues[i] = "host:" + v4.Request.URL.Host |
|
| 330 |
- } else {
|
|
| 331 |
- headerValues[i] = k + ":" + |
|
| 332 |
- strings.Join(v4.signedHeaderVals[k], ",") |
|
| 333 |
- } |
|
| 334 |
- } |
|
| 335 |
- |
|
| 336 |
- v4.canonicalHeaders = strings.Join(stripExcessSpaces(headerValues), "\n") |
|
| 337 |
-} |
|
| 338 |
- |
|
| 339 |
-func (v4 *signer) buildCanonicalString() {
|
|
| 340 |
- v4.Request.URL.RawQuery = strings.Replace(v4.Query.Encode(), "+", "%20", -1) |
|
| 341 |
- uri := v4.Request.URL.Opaque |
|
| 342 |
- if uri != "" {
|
|
| 343 |
- uri = "/" + strings.Join(strings.Split(uri, "/")[3:], "/") |
|
| 344 |
- } else {
|
|
| 345 |
- uri = v4.Request.URL.Path |
|
| 346 |
- } |
|
| 347 |
- if uri == "" {
|
|
| 348 |
- uri = "/" |
|
| 349 |
- } |
|
| 350 |
- |
|
| 351 |
- if v4.ServiceName != "s3" {
|
|
| 352 |
- uri = rest.EscapePath(uri, false) |
|
| 353 |
- } |
|
| 354 |
- |
|
| 355 |
- v4.canonicalString = strings.Join([]string{
|
|
| 356 |
- v4.Request.Method, |
|
| 357 |
- uri, |
|
| 358 |
- v4.Request.URL.RawQuery, |
|
| 359 |
- v4.canonicalHeaders + "\n", |
|
| 360 |
- v4.signedHeaders, |
|
| 361 |
- v4.bodyDigest(), |
|
| 362 |
- }, "\n") |
|
| 363 |
-} |
|
| 364 |
- |
|
| 365 |
-func (v4 *signer) buildStringToSign() {
|
|
| 366 |
- v4.stringToSign = strings.Join([]string{
|
|
| 367 |
- authHeaderPrefix, |
|
| 368 |
- v4.formattedTime, |
|
| 369 |
- v4.credentialString, |
|
| 370 |
- hex.EncodeToString(makeSha256([]byte(v4.canonicalString))), |
|
| 371 |
- }, "\n") |
|
| 372 |
-} |
|
| 373 |
- |
|
| 374 |
-func (v4 *signer) buildSignature() {
|
|
| 375 |
- secret := v4.CredValues.SecretAccessKey |
|
| 376 |
- date := makeHmac([]byte("AWS4"+secret), []byte(v4.formattedShortTime))
|
|
| 377 |
- region := makeHmac(date, []byte(v4.Region)) |
|
| 378 |
- service := makeHmac(region, []byte(v4.ServiceName)) |
|
| 379 |
- credentials := makeHmac(service, []byte("aws4_request"))
|
|
| 380 |
- signature := makeHmac(credentials, []byte(v4.stringToSign)) |
|
| 381 |
- v4.signature = hex.EncodeToString(signature) |
|
| 382 |
-} |
|
| 383 |
- |
|
| 384 |
-func (v4 *signer) bodyDigest() string {
|
|
| 385 |
- hash := v4.Request.Header.Get("X-Amz-Content-Sha256")
|
|
| 386 |
- if hash == "" {
|
|
| 387 |
- if v4.isPresign && v4.ServiceName == "s3" {
|
|
| 388 |
- hash = "UNSIGNED-PAYLOAD" |
|
| 389 |
- } else if v4.Body == nil {
|
|
| 390 |
- hash = hex.EncodeToString(makeSha256([]byte{}))
|
|
| 391 |
- } else {
|
|
| 392 |
- hash = hex.EncodeToString(makeSha256Reader(v4.Body)) |
|
| 393 |
- } |
|
| 394 |
- v4.Request.Header.Add("X-Amz-Content-Sha256", hash)
|
|
| 395 |
- } |
|
| 396 |
- return hash |
|
| 397 |
-} |
|
| 398 |
- |
|
| 399 |
-// isRequestSigned returns if the request is currently signed or presigned |
|
| 400 |
-func (v4 *signer) isRequestSigned() bool {
|
|
| 401 |
- if v4.isPresign && v4.Query.Get("X-Amz-Signature") != "" {
|
|
| 402 |
- return true |
|
| 403 |
- } |
|
| 404 |
- if v4.Request.Header.Get("Authorization") != "" {
|
|
| 405 |
- return true |
|
| 406 |
- } |
|
| 407 |
- |
|
| 408 |
- return false |
|
| 409 |
-} |
|
| 410 |
- |
|
| 411 |
-// unsign removes signing flags for both signed and presigned requests. |
|
| 412 |
-func (v4 *signer) removePresign() {
|
|
| 413 |
- v4.Query.Del("X-Amz-Algorithm")
|
|
| 414 |
- v4.Query.Del("X-Amz-Signature")
|
|
| 415 |
- v4.Query.Del("X-Amz-Security-Token")
|
|
| 416 |
- v4.Query.Del("X-Amz-Date")
|
|
| 417 |
- v4.Query.Del("X-Amz-Expires")
|
|
| 418 |
- v4.Query.Del("X-Amz-Credential")
|
|
| 419 |
- v4.Query.Del("X-Amz-SignedHeaders")
|
|
| 420 |
-} |
|
| 421 |
- |
|
| 422 |
-func makeHmac(key []byte, data []byte) []byte {
|
|
| 423 |
- hash := hmac.New(sha256.New, key) |
|
| 424 |
- hash.Write(data) |
|
| 425 |
- return hash.Sum(nil) |
|
| 426 |
-} |
|
| 427 |
- |
|
| 428 |
-func makeSha256(data []byte) []byte {
|
|
| 429 |
- hash := sha256.New() |
|
| 430 |
- hash.Write(data) |
|
| 431 |
- return hash.Sum(nil) |
|
| 432 |
-} |
|
| 433 |
- |
|
| 434 |
-func makeSha256Reader(reader io.ReadSeeker) []byte {
|
|
| 435 |
- hash := sha256.New() |
|
| 436 |
- start, _ := reader.Seek(0, 1) |
|
| 437 |
- defer reader.Seek(start, 0) |
|
| 438 |
- |
|
| 439 |
- io.Copy(hash, reader) |
|
| 440 |
- return hash.Sum(nil) |
|
| 441 |
-} |
|
| 442 |
- |
|
| 443 |
-func stripExcessSpaces(headerVals []string) []string {
|
|
| 444 |
- vals := make([]string, len(headerVals)) |
|
| 445 |
- for i, str := range headerVals {
|
|
| 446 |
- stripped := "" |
|
| 447 |
- found := false |
|
| 448 |
- str = strings.TrimSpace(str) |
|
| 449 |
- for _, c := range str {
|
|
| 450 |
- if !found && c == ' ' {
|
|
| 451 |
- stripped += string(c) |
|
| 452 |
- found = true |
|
| 453 |
- } else if c != ' ' {
|
|
| 454 |
- stripped += string(c) |
|
| 455 |
- found = false |
|
| 456 |
- } |
|
| 457 |
- } |
|
| 458 |
- vals[i] = stripped |
|
| 459 |
- } |
|
| 460 |
- return vals |
|
| 461 |
-} |
| ... | ... |
@@ -14,7 +14,30 @@ import ( |
| 14 | 14 |
|
| 15 | 15 |
const opCancelExportTask = "CancelExportTask" |
| 16 | 16 |
|
| 17 |
-// CancelExportTaskRequest generates a request for the CancelExportTask operation. |
|
| 17 |
+// CancelExportTaskRequest generates a "aws/request.Request" representing the |
|
| 18 |
+// client's request for the CancelExportTask operation. The "output" return |
|
| 19 |
+// value can be used to capture response data after the request's "Send" method |
|
| 20 |
+// is called. |
|
| 21 |
+// |
|
| 22 |
+// See CancelExportTask for usage and error information. |
|
| 23 |
+// |
|
| 24 |
+// Creating a request object using this method should be used when you want to inject |
|
| 25 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 26 |
+// access properties on the request object before or after sending the request. If |
|
| 27 |
+// you just want the service response, call the CancelExportTask method directly |
|
| 28 |
+// instead. |
|
| 29 |
+// |
|
| 30 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 31 |
+// to execute the request. |
|
| 32 |
+// |
|
| 33 |
+// // Example sending a request using the CancelExportTaskRequest method. |
|
| 34 |
+// req, resp := client.CancelExportTaskRequest(params) |
|
| 35 |
+// |
|
| 36 |
+// err := req.Send() |
|
| 37 |
+// if err == nil { // resp is now filled
|
|
| 38 |
+// fmt.Println(resp) |
|
| 39 |
+// } |
|
| 40 |
+// |
|
| 18 | 41 |
func (c *CloudWatchLogs) CancelExportTaskRequest(input *CancelExportTaskInput) (req *request.Request, output *CancelExportTaskOutput) {
|
| 19 | 42 |
op := &request.Operation{
|
| 20 | 43 |
Name: opCancelExportTask, |
| ... | ... |
@@ -34,7 +57,30 @@ func (c *CloudWatchLogs) CancelExportTaskRequest(input *CancelExportTaskInput) ( |
| 34 | 34 |
return |
| 35 | 35 |
} |
| 36 | 36 |
|
| 37 |
+// CancelExportTask API operation for Amazon CloudWatch Logs. |
|
| 38 |
+// |
|
| 37 | 39 |
// Cancels an export task if it is in PENDING or RUNNING state. |
| 40 |
+// |
|
| 41 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 42 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 43 |
+// the error. |
|
| 44 |
+// |
|
| 45 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 46 |
+// API operation CancelExportTask for usage and error information. |
|
| 47 |
+// |
|
| 48 |
+// Returned Error Codes: |
|
| 49 |
+// * InvalidParameterException |
|
| 50 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 51 |
+// |
|
| 52 |
+// * ResourceNotFoundException |
|
| 53 |
+// Returned if the specified resource does not exist. |
|
| 54 |
+// |
|
| 55 |
+// * InvalidOperationException |
|
| 56 |
+// Returned if the operation is not valid on the specified resource |
|
| 57 |
+// |
|
| 58 |
+// * ServiceUnavailableException |
|
| 59 |
+// Returned if the service cannot complete the request. |
|
| 60 |
+// |
|
| 38 | 61 |
func (c *CloudWatchLogs) CancelExportTask(input *CancelExportTaskInput) (*CancelExportTaskOutput, error) {
|
| 39 | 62 |
req, out := c.CancelExportTaskRequest(input) |
| 40 | 63 |
err := req.Send() |
| ... | ... |
@@ -43,7 +89,30 @@ func (c *CloudWatchLogs) CancelExportTask(input *CancelExportTaskInput) (*Cancel |
| 43 | 43 |
|
| 44 | 44 |
const opCreateExportTask = "CreateExportTask" |
| 45 | 45 |
|
| 46 |
-// CreateExportTaskRequest generates a request for the CreateExportTask operation. |
|
| 46 |
+// CreateExportTaskRequest generates a "aws/request.Request" representing the |
|
| 47 |
+// client's request for the CreateExportTask operation. The "output" return |
|
| 48 |
+// value can be used to capture response data after the request's "Send" method |
|
| 49 |
+// is called. |
|
| 50 |
+// |
|
| 51 |
+// See CreateExportTask for usage and error information. |
|
| 52 |
+// |
|
| 53 |
+// Creating a request object using this method should be used when you want to inject |
|
| 54 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 55 |
+// access properties on the request object before or after sending the request. If |
|
| 56 |
+// you just want the service response, call the CreateExportTask method directly |
|
| 57 |
+// instead. |
|
| 58 |
+// |
|
| 59 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 60 |
+// to execute the request. |
|
| 61 |
+// |
|
| 62 |
+// // Example sending a request using the CreateExportTaskRequest method. |
|
| 63 |
+// req, resp := client.CreateExportTaskRequest(params) |
|
| 64 |
+// |
|
| 65 |
+// err := req.Send() |
|
| 66 |
+// if err == nil { // resp is now filled
|
|
| 67 |
+// fmt.Println(resp) |
|
| 68 |
+// } |
|
| 69 |
+// |
|
| 47 | 70 |
func (c *CloudWatchLogs) CreateExportTaskRequest(input *CreateExportTaskInput) (req *request.Request, output *CreateExportTaskOutput) {
|
| 48 | 71 |
op := &request.Operation{
|
| 49 | 72 |
Name: opCreateExportTask, |
| ... | ... |
@@ -61,19 +130,49 @@ func (c *CloudWatchLogs) CreateExportTaskRequest(input *CreateExportTaskInput) ( |
| 61 | 61 |
return |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 |
+// CreateExportTask API operation for Amazon CloudWatch Logs. |
|
| 65 |
+// |
|
| 64 | 66 |
// Creates an ExportTask which allows you to efficiently export data from a |
| 65 | 67 |
// Log Group to your Amazon S3 bucket. |
| 66 | 68 |
// |
| 67 |
-// This is an asynchronous call. If all the required information is provided, |
|
| 69 |
+// This is an asynchronous call. If all the required information is provided, |
|
| 68 | 70 |
// this API will initiate an export task and respond with the task Id. Once |
| 69 | 71 |
// started, DescribeExportTasks can be used to get the status of an export task. |
| 70 | 72 |
// You can only have one active (RUNNING or PENDING) export task at a time, |
| 71 | 73 |
// per account. |
| 72 | 74 |
// |
| 73 |
-// You can export logs from multiple log groups or multiple time ranges to |
|
| 74 |
-// the same Amazon S3 bucket. To separate out log data for each export task, |
|
| 75 |
-// you can specify a prefix that will be used as the Amazon S3 key prefix for |
|
| 76 |
-// all exported objects. |
|
| 75 |
+// You can export logs from multiple log groups or multiple time ranges to the |
|
| 76 |
+// same Amazon S3 bucket. To separate out log data for each export task, you |
|
| 77 |
+// can specify a prefix that will be used as the Amazon S3 key prefix for all |
|
| 78 |
+// exported objects. |
|
| 79 |
+// |
|
| 80 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 81 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 82 |
+// the error. |
|
| 83 |
+// |
|
| 84 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 85 |
+// API operation CreateExportTask for usage and error information. |
|
| 86 |
+// |
|
| 87 |
+// Returned Error Codes: |
|
| 88 |
+// * InvalidParameterException |
|
| 89 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 90 |
+// |
|
| 91 |
+// * LimitExceededException |
|
| 92 |
+// Returned if you have reached the maximum number of resources that can be |
|
| 93 |
+// created. |
|
| 94 |
+// |
|
| 95 |
+// * OperationAbortedException |
|
| 96 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 97 |
+// |
|
| 98 |
+// * ServiceUnavailableException |
|
| 99 |
+// Returned if the service cannot complete the request. |
|
| 100 |
+// |
|
| 101 |
+// * ResourceNotFoundException |
|
| 102 |
+// Returned if the specified resource does not exist. |
|
| 103 |
+// |
|
| 104 |
+// * ResourceAlreadyExistsException |
|
| 105 |
+// Returned if the specified resource already exists. |
|
| 106 |
+// |
|
| 77 | 107 |
func (c *CloudWatchLogs) CreateExportTask(input *CreateExportTaskInput) (*CreateExportTaskOutput, error) {
|
| 78 | 108 |
req, out := c.CreateExportTaskRequest(input) |
| 79 | 109 |
err := req.Send() |
| ... | ... |
@@ -82,7 +181,30 @@ func (c *CloudWatchLogs) CreateExportTask(input *CreateExportTaskInput) (*Create |
| 82 | 82 |
|
| 83 | 83 |
const opCreateLogGroup = "CreateLogGroup" |
| 84 | 84 |
|
| 85 |
-// CreateLogGroupRequest generates a request for the CreateLogGroup operation. |
|
| 85 |
+// CreateLogGroupRequest generates a "aws/request.Request" representing the |
|
| 86 |
+// client's request for the CreateLogGroup operation. The "output" return |
|
| 87 |
+// value can be used to capture response data after the request's "Send" method |
|
| 88 |
+// is called. |
|
| 89 |
+// |
|
| 90 |
+// See CreateLogGroup for usage and error information. |
|
| 91 |
+// |
|
| 92 |
+// Creating a request object using this method should be used when you want to inject |
|
| 93 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 94 |
+// access properties on the request object before or after sending the request. If |
|
| 95 |
+// you just want the service response, call the CreateLogGroup method directly |
|
| 96 |
+// instead. |
|
| 97 |
+// |
|
| 98 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 99 |
+// to execute the request. |
|
| 100 |
+// |
|
| 101 |
+// // Example sending a request using the CreateLogGroupRequest method. |
|
| 102 |
+// req, resp := client.CreateLogGroupRequest(params) |
|
| 103 |
+// |
|
| 104 |
+// err := req.Send() |
|
| 105 |
+// if err == nil { // resp is now filled
|
|
| 106 |
+// fmt.Println(resp) |
|
| 107 |
+// } |
|
| 108 |
+// |
|
| 86 | 109 |
func (c *CloudWatchLogs) CreateLogGroupRequest(input *CreateLogGroupInput) (req *request.Request, output *CreateLogGroupOutput) {
|
| 87 | 110 |
op := &request.Operation{
|
| 88 | 111 |
Name: opCreateLogGroup, |
| ... | ... |
@@ -102,13 +224,43 @@ func (c *CloudWatchLogs) CreateLogGroupRequest(input *CreateLogGroupInput) (req |
| 102 | 102 |
return |
| 103 | 103 |
} |
| 104 | 104 |
|
| 105 |
+// CreateLogGroup API operation for Amazon CloudWatch Logs. |
|
| 106 |
+// |
|
| 105 | 107 |
// Creates a new log group with the specified name. The name of the log group |
| 106 | 108 |
// must be unique within a region for an AWS account. You can create up to 500 |
| 107 | 109 |
// log groups per account. |
| 108 | 110 |
// |
| 109 |
-// You must use the following guidelines when naming a log group: Log group |
|
| 110 |
-// names can be between 1 and 512 characters long. Allowed characters are a-z, |
|
| 111 |
-// A-Z, 0-9, '_' (underscore), '-' (hyphen), '/' (forward slash), and '.' (period). |
|
| 111 |
+// You must use the following guidelines when naming a log group: |
|
| 112 |
+// |
|
| 113 |
+// * Log group names can be between 1 and 512 characters long. |
|
| 114 |
+// |
|
| 115 |
+// * Allowed characters are a-z, A-Z, 0-9, '_' (underscore), '-' (hyphen), |
|
| 116 |
+// '/' (forward slash), and '.' (period). |
|
| 117 |
+// |
|
| 118 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 119 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 120 |
+// the error. |
|
| 121 |
+// |
|
| 122 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 123 |
+// API operation CreateLogGroup for usage and error information. |
|
| 124 |
+// |
|
| 125 |
+// Returned Error Codes: |
|
| 126 |
+// * InvalidParameterException |
|
| 127 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 128 |
+// |
|
| 129 |
+// * ResourceAlreadyExistsException |
|
| 130 |
+// Returned if the specified resource already exists. |
|
| 131 |
+// |
|
| 132 |
+// * LimitExceededException |
|
| 133 |
+// Returned if you have reached the maximum number of resources that can be |
|
| 134 |
+// created. |
|
| 135 |
+// |
|
| 136 |
+// * OperationAbortedException |
|
| 137 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 138 |
+// |
|
| 139 |
+// * ServiceUnavailableException |
|
| 140 |
+// Returned if the service cannot complete the request. |
|
| 141 |
+// |
|
| 112 | 142 |
func (c *CloudWatchLogs) CreateLogGroup(input *CreateLogGroupInput) (*CreateLogGroupOutput, error) {
|
| 113 | 143 |
req, out := c.CreateLogGroupRequest(input) |
| 114 | 144 |
err := req.Send() |
| ... | ... |
@@ -117,7 +269,30 @@ func (c *CloudWatchLogs) CreateLogGroup(input *CreateLogGroupInput) (*CreateLogG |
| 117 | 117 |
|
| 118 | 118 |
const opCreateLogStream = "CreateLogStream" |
| 119 | 119 |
|
| 120 |
-// CreateLogStreamRequest generates a request for the CreateLogStream operation. |
|
| 120 |
+// CreateLogStreamRequest generates a "aws/request.Request" representing the |
|
| 121 |
+// client's request for the CreateLogStream operation. The "output" return |
|
| 122 |
+// value can be used to capture response data after the request's "Send" method |
|
| 123 |
+// is called. |
|
| 124 |
+// |
|
| 125 |
+// See CreateLogStream for usage and error information. |
|
| 126 |
+// |
|
| 127 |
+// Creating a request object using this method should be used when you want to inject |
|
| 128 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 129 |
+// access properties on the request object before or after sending the request. If |
|
| 130 |
+// you just want the service response, call the CreateLogStream method directly |
|
| 131 |
+// instead. |
|
| 132 |
+// |
|
| 133 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 134 |
+// to execute the request. |
|
| 135 |
+// |
|
| 136 |
+// // Example sending a request using the CreateLogStreamRequest method. |
|
| 137 |
+// req, resp := client.CreateLogStreamRequest(params) |
|
| 138 |
+// |
|
| 139 |
+// err := req.Send() |
|
| 140 |
+// if err == nil { // resp is now filled
|
|
| 141 |
+// fmt.Println(resp) |
|
| 142 |
+// } |
|
| 143 |
+// |
|
| 121 | 144 |
func (c *CloudWatchLogs) CreateLogStreamRequest(input *CreateLogStreamInput) (req *request.Request, output *CreateLogStreamOutput) {
|
| 122 | 145 |
op := &request.Operation{
|
| 123 | 146 |
Name: opCreateLogStream, |
| ... | ... |
@@ -137,13 +312,38 @@ func (c *CloudWatchLogs) CreateLogStreamRequest(input *CreateLogStreamInput) (re |
| 137 | 137 |
return |
| 138 | 138 |
} |
| 139 | 139 |
|
| 140 |
+// CreateLogStream API operation for Amazon CloudWatch Logs. |
|
| 141 |
+// |
|
| 140 | 142 |
// Creates a new log stream in the specified log group. The name of the log |
| 141 | 143 |
// stream must be unique within the log group. There is no limit on the number |
| 142 | 144 |
// of log streams that can exist in a log group. |
| 143 | 145 |
// |
| 144 |
-// You must use the following guidelines when naming a log stream: Log stream |
|
| 145 |
-// names can be between 1 and 512 characters long. The ':' colon character is |
|
| 146 |
-// not allowed. |
|
| 146 |
+// You must use the following guidelines when naming a log stream: |
|
| 147 |
+// |
|
| 148 |
+// * Log stream names can be between 1 and 512 characters long. |
|
| 149 |
+// |
|
| 150 |
+// * The ':' colon character is not allowed. |
|
| 151 |
+// |
|
| 152 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 153 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 154 |
+// the error. |
|
| 155 |
+// |
|
| 156 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 157 |
+// API operation CreateLogStream for usage and error information. |
|
| 158 |
+// |
|
| 159 |
+// Returned Error Codes: |
|
| 160 |
+// * InvalidParameterException |
|
| 161 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 162 |
+// |
|
| 163 |
+// * ResourceAlreadyExistsException |
|
| 164 |
+// Returned if the specified resource already exists. |
|
| 165 |
+// |
|
| 166 |
+// * ResourceNotFoundException |
|
| 167 |
+// Returned if the specified resource does not exist. |
|
| 168 |
+// |
|
| 169 |
+// * ServiceUnavailableException |
|
| 170 |
+// Returned if the service cannot complete the request. |
|
| 171 |
+// |
|
| 147 | 172 |
func (c *CloudWatchLogs) CreateLogStream(input *CreateLogStreamInput) (*CreateLogStreamOutput, error) {
|
| 148 | 173 |
req, out := c.CreateLogStreamRequest(input) |
| 149 | 174 |
err := req.Send() |
| ... | ... |
@@ -152,7 +352,30 @@ func (c *CloudWatchLogs) CreateLogStream(input *CreateLogStreamInput) (*CreateLo |
| 152 | 152 |
|
| 153 | 153 |
const opDeleteDestination = "DeleteDestination" |
| 154 | 154 |
|
| 155 |
-// DeleteDestinationRequest generates a request for the DeleteDestination operation. |
|
| 155 |
+// DeleteDestinationRequest generates a "aws/request.Request" representing the |
|
| 156 |
+// client's request for the DeleteDestination operation. The "output" return |
|
| 157 |
+// value can be used to capture response data after the request's "Send" method |
|
| 158 |
+// is called. |
|
| 159 |
+// |
|
| 160 |
+// See DeleteDestination for usage and error information. |
|
| 161 |
+// |
|
| 162 |
+// Creating a request object using this method should be used when you want to inject |
|
| 163 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 164 |
+// access properties on the request object before or after sending the request. If |
|
| 165 |
+// you just want the service response, call the DeleteDestination method directly |
|
| 166 |
+// instead. |
|
| 167 |
+// |
|
| 168 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 169 |
+// to execute the request. |
|
| 170 |
+// |
|
| 171 |
+// // Example sending a request using the DeleteDestinationRequest method. |
|
| 172 |
+// req, resp := client.DeleteDestinationRequest(params) |
|
| 173 |
+// |
|
| 174 |
+// err := req.Send() |
|
| 175 |
+// if err == nil { // resp is now filled
|
|
| 176 |
+// fmt.Println(resp) |
|
| 177 |
+// } |
|
| 178 |
+// |
|
| 156 | 179 |
func (c *CloudWatchLogs) DeleteDestinationRequest(input *DeleteDestinationInput) (req *request.Request, output *DeleteDestinationOutput) {
|
| 157 | 180 |
op := &request.Operation{
|
| 158 | 181 |
Name: opDeleteDestination, |
| ... | ... |
@@ -172,9 +395,32 @@ func (c *CloudWatchLogs) DeleteDestinationRequest(input *DeleteDestinationInput) |
| 172 | 172 |
return |
| 173 | 173 |
} |
| 174 | 174 |
|
| 175 |
+// DeleteDestination API operation for Amazon CloudWatch Logs. |
|
| 176 |
+// |
|
| 175 | 177 |
// Deletes the destination with the specified name and eventually disables all |
| 176 | 178 |
// the subscription filters that publish to it. This will not delete the physical |
| 177 | 179 |
// resource encapsulated by the destination. |
| 180 |
+// |
|
| 181 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 182 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 183 |
+// the error. |
|
| 184 |
+// |
|
| 185 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 186 |
+// API operation DeleteDestination for usage and error information. |
|
| 187 |
+// |
|
| 188 |
+// Returned Error Codes: |
|
| 189 |
+// * InvalidParameterException |
|
| 190 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 191 |
+// |
|
| 192 |
+// * ResourceNotFoundException |
|
| 193 |
+// Returned if the specified resource does not exist. |
|
| 194 |
+// |
|
| 195 |
+// * OperationAbortedException |
|
| 196 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 197 |
+// |
|
| 198 |
+// * ServiceUnavailableException |
|
| 199 |
+// Returned if the service cannot complete the request. |
|
| 200 |
+// |
|
| 178 | 201 |
func (c *CloudWatchLogs) DeleteDestination(input *DeleteDestinationInput) (*DeleteDestinationOutput, error) {
|
| 179 | 202 |
req, out := c.DeleteDestinationRequest(input) |
| 180 | 203 |
err := req.Send() |
| ... | ... |
@@ -183,7 +429,30 @@ func (c *CloudWatchLogs) DeleteDestination(input *DeleteDestinationInput) (*Dele |
| 183 | 183 |
|
| 184 | 184 |
const opDeleteLogGroup = "DeleteLogGroup" |
| 185 | 185 |
|
| 186 |
-// DeleteLogGroupRequest generates a request for the DeleteLogGroup operation. |
|
| 186 |
+// DeleteLogGroupRequest generates a "aws/request.Request" representing the |
|
| 187 |
+// client's request for the DeleteLogGroup operation. The "output" return |
|
| 188 |
+// value can be used to capture response data after the request's "Send" method |
|
| 189 |
+// is called. |
|
| 190 |
+// |
|
| 191 |
+// See DeleteLogGroup for usage and error information. |
|
| 192 |
+// |
|
| 193 |
+// Creating a request object using this method should be used when you want to inject |
|
| 194 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 195 |
+// access properties on the request object before or after sending the request. If |
|
| 196 |
+// you just want the service response, call the DeleteLogGroup method directly |
|
| 197 |
+// instead. |
|
| 198 |
+// |
|
| 199 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 200 |
+// to execute the request. |
|
| 201 |
+// |
|
| 202 |
+// // Example sending a request using the DeleteLogGroupRequest method. |
|
| 203 |
+// req, resp := client.DeleteLogGroupRequest(params) |
|
| 204 |
+// |
|
| 205 |
+// err := req.Send() |
|
| 206 |
+// if err == nil { // resp is now filled
|
|
| 207 |
+// fmt.Println(resp) |
|
| 208 |
+// } |
|
| 209 |
+// |
|
| 187 | 210 |
func (c *CloudWatchLogs) DeleteLogGroupRequest(input *DeleteLogGroupInput) (req *request.Request, output *DeleteLogGroupOutput) {
|
| 188 | 211 |
op := &request.Operation{
|
| 189 | 212 |
Name: opDeleteLogGroup, |
| ... | ... |
@@ -203,8 +472,31 @@ func (c *CloudWatchLogs) DeleteLogGroupRequest(input *DeleteLogGroupInput) (req |
| 203 | 203 |
return |
| 204 | 204 |
} |
| 205 | 205 |
|
| 206 |
+// DeleteLogGroup API operation for Amazon CloudWatch Logs. |
|
| 207 |
+// |
|
| 206 | 208 |
// Deletes the log group with the specified name and permanently deletes all |
| 207 | 209 |
// the archived log events associated with it. |
| 210 |
+// |
|
| 211 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 212 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 213 |
+// the error. |
|
| 214 |
+// |
|
| 215 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 216 |
+// API operation DeleteLogGroup for usage and error information. |
|
| 217 |
+// |
|
| 218 |
+// Returned Error Codes: |
|
| 219 |
+// * InvalidParameterException |
|
| 220 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 221 |
+// |
|
| 222 |
+// * ResourceNotFoundException |
|
| 223 |
+// Returned if the specified resource does not exist. |
|
| 224 |
+// |
|
| 225 |
+// * OperationAbortedException |
|
| 226 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 227 |
+// |
|
| 228 |
+// * ServiceUnavailableException |
|
| 229 |
+// Returned if the service cannot complete the request. |
|
| 230 |
+// |
|
| 208 | 231 |
func (c *CloudWatchLogs) DeleteLogGroup(input *DeleteLogGroupInput) (*DeleteLogGroupOutput, error) {
|
| 209 | 232 |
req, out := c.DeleteLogGroupRequest(input) |
| 210 | 233 |
err := req.Send() |
| ... | ... |
@@ -213,7 +505,30 @@ func (c *CloudWatchLogs) DeleteLogGroup(input *DeleteLogGroupInput) (*DeleteLogG |
| 213 | 213 |
|
| 214 | 214 |
const opDeleteLogStream = "DeleteLogStream" |
| 215 | 215 |
|
| 216 |
-// DeleteLogStreamRequest generates a request for the DeleteLogStream operation. |
|
| 216 |
+// DeleteLogStreamRequest generates a "aws/request.Request" representing the |
|
| 217 |
+// client's request for the DeleteLogStream operation. The "output" return |
|
| 218 |
+// value can be used to capture response data after the request's "Send" method |
|
| 219 |
+// is called. |
|
| 220 |
+// |
|
| 221 |
+// See DeleteLogStream for usage and error information. |
|
| 222 |
+// |
|
| 223 |
+// Creating a request object using this method should be used when you want to inject |
|
| 224 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 225 |
+// access properties on the request object before or after sending the request. If |
|
| 226 |
+// you just want the service response, call the DeleteLogStream method directly |
|
| 227 |
+// instead. |
|
| 228 |
+// |
|
| 229 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 230 |
+// to execute the request. |
|
| 231 |
+// |
|
| 232 |
+// // Example sending a request using the DeleteLogStreamRequest method. |
|
| 233 |
+// req, resp := client.DeleteLogStreamRequest(params) |
|
| 234 |
+// |
|
| 235 |
+// err := req.Send() |
|
| 236 |
+// if err == nil { // resp is now filled
|
|
| 237 |
+// fmt.Println(resp) |
|
| 238 |
+// } |
|
| 239 |
+// |
|
| 217 | 240 |
func (c *CloudWatchLogs) DeleteLogStreamRequest(input *DeleteLogStreamInput) (req *request.Request, output *DeleteLogStreamOutput) {
|
| 218 | 241 |
op := &request.Operation{
|
| 219 | 242 |
Name: opDeleteLogStream, |
| ... | ... |
@@ -233,8 +548,31 @@ func (c *CloudWatchLogs) DeleteLogStreamRequest(input *DeleteLogStreamInput) (re |
| 233 | 233 |
return |
| 234 | 234 |
} |
| 235 | 235 |
|
| 236 |
+// DeleteLogStream API operation for Amazon CloudWatch Logs. |
|
| 237 |
+// |
|
| 236 | 238 |
// Deletes a log stream and permanently deletes all the archived log events |
| 237 | 239 |
// associated with it. |
| 240 |
+// |
|
| 241 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 242 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 243 |
+// the error. |
|
| 244 |
+// |
|
| 245 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 246 |
+// API operation DeleteLogStream for usage and error information. |
|
| 247 |
+// |
|
| 248 |
+// Returned Error Codes: |
|
| 249 |
+// * InvalidParameterException |
|
| 250 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 251 |
+// |
|
| 252 |
+// * ResourceNotFoundException |
|
| 253 |
+// Returned if the specified resource does not exist. |
|
| 254 |
+// |
|
| 255 |
+// * OperationAbortedException |
|
| 256 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 257 |
+// |
|
| 258 |
+// * ServiceUnavailableException |
|
| 259 |
+// Returned if the service cannot complete the request. |
|
| 260 |
+// |
|
| 238 | 261 |
func (c *CloudWatchLogs) DeleteLogStream(input *DeleteLogStreamInput) (*DeleteLogStreamOutput, error) {
|
| 239 | 262 |
req, out := c.DeleteLogStreamRequest(input) |
| 240 | 263 |
err := req.Send() |
| ... | ... |
@@ -243,7 +581,30 @@ func (c *CloudWatchLogs) DeleteLogStream(input *DeleteLogStreamInput) (*DeleteLo |
| 243 | 243 |
|
| 244 | 244 |
const opDeleteMetricFilter = "DeleteMetricFilter" |
| 245 | 245 |
|
| 246 |
-// DeleteMetricFilterRequest generates a request for the DeleteMetricFilter operation. |
|
| 246 |
+// DeleteMetricFilterRequest generates a "aws/request.Request" representing the |
|
| 247 |
+// client's request for the DeleteMetricFilter operation. The "output" return |
|
| 248 |
+// value can be used to capture response data after the request's "Send" method |
|
| 249 |
+// is called. |
|
| 250 |
+// |
|
| 251 |
+// See DeleteMetricFilter for usage and error information. |
|
| 252 |
+// |
|
| 253 |
+// Creating a request object using this method should be used when you want to inject |
|
| 254 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 255 |
+// access properties on the request object before or after sending the request. If |
|
| 256 |
+// you just want the service response, call the DeleteMetricFilter method directly |
|
| 257 |
+// instead. |
|
| 258 |
+// |
|
| 259 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 260 |
+// to execute the request. |
|
| 261 |
+// |
|
| 262 |
+// // Example sending a request using the DeleteMetricFilterRequest method. |
|
| 263 |
+// req, resp := client.DeleteMetricFilterRequest(params) |
|
| 264 |
+// |
|
| 265 |
+// err := req.Send() |
|
| 266 |
+// if err == nil { // resp is now filled
|
|
| 267 |
+// fmt.Println(resp) |
|
| 268 |
+// } |
|
| 269 |
+// |
|
| 247 | 270 |
func (c *CloudWatchLogs) DeleteMetricFilterRequest(input *DeleteMetricFilterInput) (req *request.Request, output *DeleteMetricFilterOutput) {
|
| 248 | 271 |
op := &request.Operation{
|
| 249 | 272 |
Name: opDeleteMetricFilter, |
| ... | ... |
@@ -263,7 +624,30 @@ func (c *CloudWatchLogs) DeleteMetricFilterRequest(input *DeleteMetricFilterInpu |
| 263 | 263 |
return |
| 264 | 264 |
} |
| 265 | 265 |
|
| 266 |
+// DeleteMetricFilter API operation for Amazon CloudWatch Logs. |
|
| 267 |
+// |
|
| 266 | 268 |
// Deletes a metric filter associated with the specified log group. |
| 269 |
+// |
|
| 270 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 271 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 272 |
+// the error. |
|
| 273 |
+// |
|
| 274 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 275 |
+// API operation DeleteMetricFilter for usage and error information. |
|
| 276 |
+// |
|
| 277 |
+// Returned Error Codes: |
|
| 278 |
+// * InvalidParameterException |
|
| 279 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 280 |
+// |
|
| 281 |
+// * ResourceNotFoundException |
|
| 282 |
+// Returned if the specified resource does not exist. |
|
| 283 |
+// |
|
| 284 |
+// * OperationAbortedException |
|
| 285 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 286 |
+// |
|
| 287 |
+// * ServiceUnavailableException |
|
| 288 |
+// Returned if the service cannot complete the request. |
|
| 289 |
+// |
|
| 267 | 290 |
func (c *CloudWatchLogs) DeleteMetricFilter(input *DeleteMetricFilterInput) (*DeleteMetricFilterOutput, error) {
|
| 268 | 291 |
req, out := c.DeleteMetricFilterRequest(input) |
| 269 | 292 |
err := req.Send() |
| ... | ... |
@@ -272,7 +656,30 @@ func (c *CloudWatchLogs) DeleteMetricFilter(input *DeleteMetricFilterInput) (*De |
| 272 | 272 |
|
| 273 | 273 |
const opDeleteRetentionPolicy = "DeleteRetentionPolicy" |
| 274 | 274 |
|
| 275 |
-// DeleteRetentionPolicyRequest generates a request for the DeleteRetentionPolicy operation. |
|
| 275 |
+// DeleteRetentionPolicyRequest generates a "aws/request.Request" representing the |
|
| 276 |
+// client's request for the DeleteRetentionPolicy operation. The "output" return |
|
| 277 |
+// value can be used to capture response data after the request's "Send" method |
|
| 278 |
+// is called. |
|
| 279 |
+// |
|
| 280 |
+// See DeleteRetentionPolicy for usage and error information. |
|
| 281 |
+// |
|
| 282 |
+// Creating a request object using this method should be used when you want to inject |
|
| 283 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 284 |
+// access properties on the request object before or after sending the request. If |
|
| 285 |
+// you just want the service response, call the DeleteRetentionPolicy method directly |
|
| 286 |
+// instead. |
|
| 287 |
+// |
|
| 288 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 289 |
+// to execute the request. |
|
| 290 |
+// |
|
| 291 |
+// // Example sending a request using the DeleteRetentionPolicyRequest method. |
|
| 292 |
+// req, resp := client.DeleteRetentionPolicyRequest(params) |
|
| 293 |
+// |
|
| 294 |
+// err := req.Send() |
|
| 295 |
+// if err == nil { // resp is now filled
|
|
| 296 |
+// fmt.Println(resp) |
|
| 297 |
+// } |
|
| 298 |
+// |
|
| 276 | 299 |
func (c *CloudWatchLogs) DeleteRetentionPolicyRequest(input *DeleteRetentionPolicyInput) (req *request.Request, output *DeleteRetentionPolicyOutput) {
|
| 277 | 300 |
op := &request.Operation{
|
| 278 | 301 |
Name: opDeleteRetentionPolicy, |
| ... | ... |
@@ -292,8 +699,31 @@ func (c *CloudWatchLogs) DeleteRetentionPolicyRequest(input *DeleteRetentionPoli |
| 292 | 292 |
return |
| 293 | 293 |
} |
| 294 | 294 |
|
| 295 |
+// DeleteRetentionPolicy API operation for Amazon CloudWatch Logs. |
|
| 296 |
+// |
|
| 295 | 297 |
// Deletes the retention policy of the specified log group. Log events would |
| 296 | 298 |
// not expire if they belong to log groups without a retention policy. |
| 299 |
+// |
|
| 300 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 301 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 302 |
+// the error. |
|
| 303 |
+// |
|
| 304 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 305 |
+// API operation DeleteRetentionPolicy for usage and error information. |
|
| 306 |
+// |
|
| 307 |
+// Returned Error Codes: |
|
| 308 |
+// * InvalidParameterException |
|
| 309 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 310 |
+// |
|
| 311 |
+// * ResourceNotFoundException |
|
| 312 |
+// Returned if the specified resource does not exist. |
|
| 313 |
+// |
|
| 314 |
+// * OperationAbortedException |
|
| 315 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 316 |
+// |
|
| 317 |
+// * ServiceUnavailableException |
|
| 318 |
+// Returned if the service cannot complete the request. |
|
| 319 |
+// |
|
| 297 | 320 |
func (c *CloudWatchLogs) DeleteRetentionPolicy(input *DeleteRetentionPolicyInput) (*DeleteRetentionPolicyOutput, error) {
|
| 298 | 321 |
req, out := c.DeleteRetentionPolicyRequest(input) |
| 299 | 322 |
err := req.Send() |
| ... | ... |
@@ -302,7 +732,30 @@ func (c *CloudWatchLogs) DeleteRetentionPolicy(input *DeleteRetentionPolicyInput |
| 302 | 302 |
|
| 303 | 303 |
const opDeleteSubscriptionFilter = "DeleteSubscriptionFilter" |
| 304 | 304 |
|
| 305 |
-// DeleteSubscriptionFilterRequest generates a request for the DeleteSubscriptionFilter operation. |
|
| 305 |
+// DeleteSubscriptionFilterRequest generates a "aws/request.Request" representing the |
|
| 306 |
+// client's request for the DeleteSubscriptionFilter operation. The "output" return |
|
| 307 |
+// value can be used to capture response data after the request's "Send" method |
|
| 308 |
+// is called. |
|
| 309 |
+// |
|
| 310 |
+// See DeleteSubscriptionFilter for usage and error information. |
|
| 311 |
+// |
|
| 312 |
+// Creating a request object using this method should be used when you want to inject |
|
| 313 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 314 |
+// access properties on the request object before or after sending the request. If |
|
| 315 |
+// you just want the service response, call the DeleteSubscriptionFilter method directly |
|
| 316 |
+// instead. |
|
| 317 |
+// |
|
| 318 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 319 |
+// to execute the request. |
|
| 320 |
+// |
|
| 321 |
+// // Example sending a request using the DeleteSubscriptionFilterRequest method. |
|
| 322 |
+// req, resp := client.DeleteSubscriptionFilterRequest(params) |
|
| 323 |
+// |
|
| 324 |
+// err := req.Send() |
|
| 325 |
+// if err == nil { // resp is now filled
|
|
| 326 |
+// fmt.Println(resp) |
|
| 327 |
+// } |
|
| 328 |
+// |
|
| 306 | 329 |
func (c *CloudWatchLogs) DeleteSubscriptionFilterRequest(input *DeleteSubscriptionFilterInput) (req *request.Request, output *DeleteSubscriptionFilterOutput) {
|
| 307 | 330 |
op := &request.Operation{
|
| 308 | 331 |
Name: opDeleteSubscriptionFilter, |
| ... | ... |
@@ -322,7 +775,30 @@ func (c *CloudWatchLogs) DeleteSubscriptionFilterRequest(input *DeleteSubscripti |
| 322 | 322 |
return |
| 323 | 323 |
} |
| 324 | 324 |
|
| 325 |
+// DeleteSubscriptionFilter API operation for Amazon CloudWatch Logs. |
|
| 326 |
+// |
|
| 325 | 327 |
// Deletes a subscription filter associated with the specified log group. |
| 328 |
+// |
|
| 329 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 330 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 331 |
+// the error. |
|
| 332 |
+// |
|
| 333 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 334 |
+// API operation DeleteSubscriptionFilter for usage and error information. |
|
| 335 |
+// |
|
| 336 |
+// Returned Error Codes: |
|
| 337 |
+// * InvalidParameterException |
|
| 338 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 339 |
+// |
|
| 340 |
+// * ResourceNotFoundException |
|
| 341 |
+// Returned if the specified resource does not exist. |
|
| 342 |
+// |
|
| 343 |
+// * OperationAbortedException |
|
| 344 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 345 |
+// |
|
| 346 |
+// * ServiceUnavailableException |
|
| 347 |
+// Returned if the service cannot complete the request. |
|
| 348 |
+// |
|
| 326 | 349 |
func (c *CloudWatchLogs) DeleteSubscriptionFilter(input *DeleteSubscriptionFilterInput) (*DeleteSubscriptionFilterOutput, error) {
|
| 327 | 350 |
req, out := c.DeleteSubscriptionFilterRequest(input) |
| 328 | 351 |
err := req.Send() |
| ... | ... |
@@ -331,7 +807,30 @@ func (c *CloudWatchLogs) DeleteSubscriptionFilter(input *DeleteSubscriptionFilte |
| 331 | 331 |
|
| 332 | 332 |
const opDescribeDestinations = "DescribeDestinations" |
| 333 | 333 |
|
| 334 |
-// DescribeDestinationsRequest generates a request for the DescribeDestinations operation. |
|
| 334 |
+// DescribeDestinationsRequest generates a "aws/request.Request" representing the |
|
| 335 |
+// client's request for the DescribeDestinations operation. The "output" return |
|
| 336 |
+// value can be used to capture response data after the request's "Send" method |
|
| 337 |
+// is called. |
|
| 338 |
+// |
|
| 339 |
+// See DescribeDestinations for usage and error information. |
|
| 340 |
+// |
|
| 341 |
+// Creating a request object using this method should be used when you want to inject |
|
| 342 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 343 |
+// access properties on the request object before or after sending the request. If |
|
| 344 |
+// you just want the service response, call the DescribeDestinations method directly |
|
| 345 |
+// instead. |
|
| 346 |
+// |
|
| 347 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 348 |
+// to execute the request. |
|
| 349 |
+// |
|
| 350 |
+// // Example sending a request using the DescribeDestinationsRequest method. |
|
| 351 |
+// req, resp := client.DescribeDestinationsRequest(params) |
|
| 352 |
+// |
|
| 353 |
+// err := req.Send() |
|
| 354 |
+// if err == nil { // resp is now filled
|
|
| 355 |
+// fmt.Println(resp) |
|
| 356 |
+// } |
|
| 357 |
+// |
|
| 335 | 358 |
func (c *CloudWatchLogs) DescribeDestinationsRequest(input *DescribeDestinationsInput) (req *request.Request, output *DescribeDestinationsOutput) {
|
| 336 | 359 |
op := &request.Operation{
|
| 337 | 360 |
Name: opDescribeDestinations, |
| ... | ... |
@@ -355,20 +854,54 @@ func (c *CloudWatchLogs) DescribeDestinationsRequest(input *DescribeDestinations |
| 355 | 355 |
return |
| 356 | 356 |
} |
| 357 | 357 |
|
| 358 |
+// DescribeDestinations API operation for Amazon CloudWatch Logs. |
|
| 359 |
+// |
|
| 358 | 360 |
// Returns all the destinations that are associated with the AWS account making |
| 359 | 361 |
// the request. The list returned in the response is ASCII-sorted by destination |
| 360 | 362 |
// name. |
| 361 | 363 |
// |
| 362 |
-// By default, this operation returns up to 50 destinations. If there are |
|
| 363 |
-// more destinations to list, the response would contain a nextToken value in |
|
| 364 |
-// the response body. You can also limit the number of destinations returned |
|
| 365 |
-// in the response by specifying the limit parameter in the request. |
|
| 364 |
+// By default, this operation returns up to 50 destinations. If there are more |
|
| 365 |
+// destinations to list, the response would contain a nextToken value in the |
|
| 366 |
+// response body. You can also limit the number of destinations returned in |
|
| 367 |
+// the response by specifying the limit parameter in the request. |
|
| 368 |
+// |
|
| 369 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 370 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 371 |
+// the error. |
|
| 372 |
+// |
|
| 373 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 374 |
+// API operation DescribeDestinations for usage and error information. |
|
| 375 |
+// |
|
| 376 |
+// Returned Error Codes: |
|
| 377 |
+// * InvalidParameterException |
|
| 378 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 379 |
+// |
|
| 380 |
+// * ServiceUnavailableException |
|
| 381 |
+// Returned if the service cannot complete the request. |
|
| 382 |
+// |
|
| 366 | 383 |
func (c *CloudWatchLogs) DescribeDestinations(input *DescribeDestinationsInput) (*DescribeDestinationsOutput, error) {
|
| 367 | 384 |
req, out := c.DescribeDestinationsRequest(input) |
| 368 | 385 |
err := req.Send() |
| 369 | 386 |
return out, err |
| 370 | 387 |
} |
| 371 | 388 |
|
| 389 |
+// DescribeDestinationsPages iterates over the pages of a DescribeDestinations operation, |
|
| 390 |
+// calling the "fn" function with the response data for each page. To stop |
|
| 391 |
+// iterating, return false from the fn function. |
|
| 392 |
+// |
|
| 393 |
+// See DescribeDestinations method for more information on how to use this operation. |
|
| 394 |
+// |
|
| 395 |
+// Note: This operation can generate multiple requests to a service. |
|
| 396 |
+// |
|
| 397 |
+// // Example iterating over at most 3 pages of a DescribeDestinations operation. |
|
| 398 |
+// pageNum := 0 |
|
| 399 |
+// err := client.DescribeDestinationsPages(params, |
|
| 400 |
+// func(page *DescribeDestinationsOutput, lastPage bool) bool {
|
|
| 401 |
+// pageNum++ |
|
| 402 |
+// fmt.Println(page) |
|
| 403 |
+// return pageNum <= 3 |
|
| 404 |
+// }) |
|
| 405 |
+// |
|
| 372 | 406 |
func (c *CloudWatchLogs) DescribeDestinationsPages(input *DescribeDestinationsInput, fn func(p *DescribeDestinationsOutput, lastPage bool) (shouldContinue bool)) error {
|
| 373 | 407 |
page, _ := c.DescribeDestinationsRequest(input) |
| 374 | 408 |
page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
|
| ... | ... |
@@ -379,7 +912,30 @@ func (c *CloudWatchLogs) DescribeDestinationsPages(input *DescribeDestinationsIn |
| 379 | 379 |
|
| 380 | 380 |
const opDescribeExportTasks = "DescribeExportTasks" |
| 381 | 381 |
|
| 382 |
-// DescribeExportTasksRequest generates a request for the DescribeExportTasks operation. |
|
| 382 |
+// DescribeExportTasksRequest generates a "aws/request.Request" representing the |
|
| 383 |
+// client's request for the DescribeExportTasks operation. The "output" return |
|
| 384 |
+// value can be used to capture response data after the request's "Send" method |
|
| 385 |
+// is called. |
|
| 386 |
+// |
|
| 387 |
+// See DescribeExportTasks for usage and error information. |
|
| 388 |
+// |
|
| 389 |
+// Creating a request object using this method should be used when you want to inject |
|
| 390 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 391 |
+// access properties on the request object before or after sending the request. If |
|
| 392 |
+// you just want the service response, call the DescribeExportTasks method directly |
|
| 393 |
+// instead. |
|
| 394 |
+// |
|
| 395 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 396 |
+// to execute the request. |
|
| 397 |
+// |
|
| 398 |
+// // Example sending a request using the DescribeExportTasksRequest method. |
|
| 399 |
+// req, resp := client.DescribeExportTasksRequest(params) |
|
| 400 |
+// |
|
| 401 |
+// err := req.Send() |
|
| 402 |
+// if err == nil { // resp is now filled
|
|
| 403 |
+// fmt.Println(resp) |
|
| 404 |
+// } |
|
| 405 |
+// |
|
| 383 | 406 |
func (c *CloudWatchLogs) DescribeExportTasksRequest(input *DescribeExportTasksInput) (req *request.Request, output *DescribeExportTasksOutput) {
|
| 384 | 407 |
op := &request.Operation{
|
| 385 | 408 |
Name: opDescribeExportTasks, |
| ... | ... |
@@ -397,14 +953,31 @@ func (c *CloudWatchLogs) DescribeExportTasksRequest(input *DescribeExportTasksIn |
| 397 | 397 |
return |
| 398 | 398 |
} |
| 399 | 399 |
|
| 400 |
+// DescribeExportTasks API operation for Amazon CloudWatch Logs. |
|
| 401 |
+// |
|
| 400 | 402 |
// Returns all the export tasks that are associated with the AWS account making |
| 401 | 403 |
// the request. The export tasks can be filtered based on TaskId or TaskStatus. |
| 402 | 404 |
// |
| 403 |
-// By default, this operation returns up to 50 export tasks that satisfy the |
|
| 405 |
+// By default, this operation returns up to 50 export tasks that satisfy the |
|
| 404 | 406 |
// specified filters. If there are more export tasks to list, the response would |
| 405 | 407 |
// contain a nextToken value in the response body. You can also limit the number |
| 406 | 408 |
// of export tasks returned in the response by specifying the limit parameter |
| 407 | 409 |
// in the request. |
| 410 |
+// |
|
| 411 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 412 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 413 |
+// the error. |
|
| 414 |
+// |
|
| 415 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 416 |
+// API operation DescribeExportTasks for usage and error information. |
|
| 417 |
+// |
|
| 418 |
+// Returned Error Codes: |
|
| 419 |
+// * InvalidParameterException |
|
| 420 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 421 |
+// |
|
| 422 |
+// * ServiceUnavailableException |
|
| 423 |
+// Returned if the service cannot complete the request. |
|
| 424 |
+// |
|
| 408 | 425 |
func (c *CloudWatchLogs) DescribeExportTasks(input *DescribeExportTasksInput) (*DescribeExportTasksOutput, error) {
|
| 409 | 426 |
req, out := c.DescribeExportTasksRequest(input) |
| 410 | 427 |
err := req.Send() |
| ... | ... |
@@ -413,7 +986,30 @@ func (c *CloudWatchLogs) DescribeExportTasks(input *DescribeExportTasksInput) (* |
| 413 | 413 |
|
| 414 | 414 |
const opDescribeLogGroups = "DescribeLogGroups" |
| 415 | 415 |
|
| 416 |
-// DescribeLogGroupsRequest generates a request for the DescribeLogGroups operation. |
|
| 416 |
+// DescribeLogGroupsRequest generates a "aws/request.Request" representing the |
|
| 417 |
+// client's request for the DescribeLogGroups operation. The "output" return |
|
| 418 |
+// value can be used to capture response data after the request's "Send" method |
|
| 419 |
+// is called. |
|
| 420 |
+// |
|
| 421 |
+// See DescribeLogGroups for usage and error information. |
|
| 422 |
+// |
|
| 423 |
+// Creating a request object using this method should be used when you want to inject |
|
| 424 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 425 |
+// access properties on the request object before or after sending the request. If |
|
| 426 |
+// you just want the service response, call the DescribeLogGroups method directly |
|
| 427 |
+// instead. |
|
| 428 |
+// |
|
| 429 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 430 |
+// to execute the request. |
|
| 431 |
+// |
|
| 432 |
+// // Example sending a request using the DescribeLogGroupsRequest method. |
|
| 433 |
+// req, resp := client.DescribeLogGroupsRequest(params) |
|
| 434 |
+// |
|
| 435 |
+// err := req.Send() |
|
| 436 |
+// if err == nil { // resp is now filled
|
|
| 437 |
+// fmt.Println(resp) |
|
| 438 |
+// } |
|
| 439 |
+// |
|
| 417 | 440 |
func (c *CloudWatchLogs) DescribeLogGroupsRequest(input *DescribeLogGroupsInput) (req *request.Request, output *DescribeLogGroupsOutput) {
|
| 418 | 441 |
op := &request.Operation{
|
| 419 | 442 |
Name: opDescribeLogGroups, |
| ... | ... |
@@ -437,20 +1033,54 @@ func (c *CloudWatchLogs) DescribeLogGroupsRequest(input *DescribeLogGroupsInput) |
| 437 | 437 |
return |
| 438 | 438 |
} |
| 439 | 439 |
|
| 440 |
+// DescribeLogGroups API operation for Amazon CloudWatch Logs. |
|
| 441 |
+// |
|
| 440 | 442 |
// Returns all the log groups that are associated with the AWS account making |
| 441 | 443 |
// the request. The list returned in the response is ASCII-sorted by log group |
| 442 | 444 |
// name. |
| 443 | 445 |
// |
| 444 |
-// By default, this operation returns up to 50 log groups. If there are more |
|
| 446 |
+// By default, this operation returns up to 50 log groups. If there are more |
|
| 445 | 447 |
// log groups to list, the response would contain a nextToken value in the response |
| 446 | 448 |
// body. You can also limit the number of log groups returned in the response |
| 447 | 449 |
// by specifying the limit parameter in the request. |
| 450 |
+// |
|
| 451 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 452 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 453 |
+// the error. |
|
| 454 |
+// |
|
| 455 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 456 |
+// API operation DescribeLogGroups for usage and error information. |
|
| 457 |
+// |
|
| 458 |
+// Returned Error Codes: |
|
| 459 |
+// * InvalidParameterException |
|
| 460 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 461 |
+// |
|
| 462 |
+// * ServiceUnavailableException |
|
| 463 |
+// Returned if the service cannot complete the request. |
|
| 464 |
+// |
|
| 448 | 465 |
func (c *CloudWatchLogs) DescribeLogGroups(input *DescribeLogGroupsInput) (*DescribeLogGroupsOutput, error) {
|
| 449 | 466 |
req, out := c.DescribeLogGroupsRequest(input) |
| 450 | 467 |
err := req.Send() |
| 451 | 468 |
return out, err |
| 452 | 469 |
} |
| 453 | 470 |
|
| 471 |
+// DescribeLogGroupsPages iterates over the pages of a DescribeLogGroups operation, |
|
| 472 |
+// calling the "fn" function with the response data for each page. To stop |
|
| 473 |
+// iterating, return false from the fn function. |
|
| 474 |
+// |
|
| 475 |
+// See DescribeLogGroups method for more information on how to use this operation. |
|
| 476 |
+// |
|
| 477 |
+// Note: This operation can generate multiple requests to a service. |
|
| 478 |
+// |
|
| 479 |
+// // Example iterating over at most 3 pages of a DescribeLogGroups operation. |
|
| 480 |
+// pageNum := 0 |
|
| 481 |
+// err := client.DescribeLogGroupsPages(params, |
|
| 482 |
+// func(page *DescribeLogGroupsOutput, lastPage bool) bool {
|
|
| 483 |
+// pageNum++ |
|
| 484 |
+// fmt.Println(page) |
|
| 485 |
+// return pageNum <= 3 |
|
| 486 |
+// }) |
|
| 487 |
+// |
|
| 454 | 488 |
func (c *CloudWatchLogs) DescribeLogGroupsPages(input *DescribeLogGroupsInput, fn func(p *DescribeLogGroupsOutput, lastPage bool) (shouldContinue bool)) error {
|
| 455 | 489 |
page, _ := c.DescribeLogGroupsRequest(input) |
| 456 | 490 |
page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
|
| ... | ... |
@@ -461,7 +1091,30 @@ func (c *CloudWatchLogs) DescribeLogGroupsPages(input *DescribeLogGroupsInput, f |
| 461 | 461 |
|
| 462 | 462 |
const opDescribeLogStreams = "DescribeLogStreams" |
| 463 | 463 |
|
| 464 |
-// DescribeLogStreamsRequest generates a request for the DescribeLogStreams operation. |
|
| 464 |
+// DescribeLogStreamsRequest generates a "aws/request.Request" representing the |
|
| 465 |
+// client's request for the DescribeLogStreams operation. The "output" return |
|
| 466 |
+// value can be used to capture response data after the request's "Send" method |
|
| 467 |
+// is called. |
|
| 468 |
+// |
|
| 469 |
+// See DescribeLogStreams for usage and error information. |
|
| 470 |
+// |
|
| 471 |
+// Creating a request object using this method should be used when you want to inject |
|
| 472 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 473 |
+// access properties on the request object before or after sending the request. If |
|
| 474 |
+// you just want the service response, call the DescribeLogStreams method directly |
|
| 475 |
+// instead. |
|
| 476 |
+// |
|
| 477 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 478 |
+// to execute the request. |
|
| 479 |
+// |
|
| 480 |
+// // Example sending a request using the DescribeLogStreamsRequest method. |
|
| 481 |
+// req, resp := client.DescribeLogStreamsRequest(params) |
|
| 482 |
+// |
|
| 483 |
+// err := req.Send() |
|
| 484 |
+// if err == nil { // resp is now filled
|
|
| 485 |
+// fmt.Println(resp) |
|
| 486 |
+// } |
|
| 487 |
+// |
|
| 465 | 488 |
func (c *CloudWatchLogs) DescribeLogStreamsRequest(input *DescribeLogStreamsInput) (req *request.Request, output *DescribeLogStreamsOutput) {
|
| 466 | 489 |
op := &request.Operation{
|
| 467 | 490 |
Name: opDescribeLogStreams, |
| ... | ... |
@@ -485,21 +1138,58 @@ func (c *CloudWatchLogs) DescribeLogStreamsRequest(input *DescribeLogStreamsInpu |
| 485 | 485 |
return |
| 486 | 486 |
} |
| 487 | 487 |
|
| 488 |
+// DescribeLogStreams API operation for Amazon CloudWatch Logs. |
|
| 489 |
+// |
|
| 488 | 490 |
// Returns all the log streams that are associated with the specified log group. |
| 489 | 491 |
// The list returned in the response is ASCII-sorted by log stream name. |
| 490 | 492 |
// |
| 491 |
-// By default, this operation returns up to 50 log streams. If there are more |
|
| 493 |
+// By default, this operation returns up to 50 log streams. If there are more |
|
| 492 | 494 |
// log streams to list, the response would contain a nextToken value in the |
| 493 | 495 |
// response body. You can also limit the number of log streams returned in the |
| 494 | 496 |
// response by specifying the limit parameter in the request. This operation |
| 495 | 497 |
// has a limit of five transactions per second, after which transactions are |
| 496 | 498 |
// throttled. |
| 499 |
+// |
|
| 500 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 501 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 502 |
+// the error. |
|
| 503 |
+// |
|
| 504 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 505 |
+// API operation DescribeLogStreams for usage and error information. |
|
| 506 |
+// |
|
| 507 |
+// Returned Error Codes: |
|
| 508 |
+// * InvalidParameterException |
|
| 509 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 510 |
+// |
|
| 511 |
+// * ResourceNotFoundException |
|
| 512 |
+// Returned if the specified resource does not exist. |
|
| 513 |
+// |
|
| 514 |
+// * ServiceUnavailableException |
|
| 515 |
+// Returned if the service cannot complete the request. |
|
| 516 |
+// |
|
| 497 | 517 |
func (c *CloudWatchLogs) DescribeLogStreams(input *DescribeLogStreamsInput) (*DescribeLogStreamsOutput, error) {
|
| 498 | 518 |
req, out := c.DescribeLogStreamsRequest(input) |
| 499 | 519 |
err := req.Send() |
| 500 | 520 |
return out, err |
| 501 | 521 |
} |
| 502 | 522 |
|
| 523 |
+// DescribeLogStreamsPages iterates over the pages of a DescribeLogStreams operation, |
|
| 524 |
+// calling the "fn" function with the response data for each page. To stop |
|
| 525 |
+// iterating, return false from the fn function. |
|
| 526 |
+// |
|
| 527 |
+// See DescribeLogStreams method for more information on how to use this operation. |
|
| 528 |
+// |
|
| 529 |
+// Note: This operation can generate multiple requests to a service. |
|
| 530 |
+// |
|
| 531 |
+// // Example iterating over at most 3 pages of a DescribeLogStreams operation. |
|
| 532 |
+// pageNum := 0 |
|
| 533 |
+// err := client.DescribeLogStreamsPages(params, |
|
| 534 |
+// func(page *DescribeLogStreamsOutput, lastPage bool) bool {
|
|
| 535 |
+// pageNum++ |
|
| 536 |
+// fmt.Println(page) |
|
| 537 |
+// return pageNum <= 3 |
|
| 538 |
+// }) |
|
| 539 |
+// |
|
| 503 | 540 |
func (c *CloudWatchLogs) DescribeLogStreamsPages(input *DescribeLogStreamsInput, fn func(p *DescribeLogStreamsOutput, lastPage bool) (shouldContinue bool)) error {
|
| 504 | 541 |
page, _ := c.DescribeLogStreamsRequest(input) |
| 505 | 542 |
page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
|
| ... | ... |
@@ -510,7 +1200,30 @@ func (c *CloudWatchLogs) DescribeLogStreamsPages(input *DescribeLogStreamsInput, |
| 510 | 510 |
|
| 511 | 511 |
const opDescribeMetricFilters = "DescribeMetricFilters" |
| 512 | 512 |
|
| 513 |
-// DescribeMetricFiltersRequest generates a request for the DescribeMetricFilters operation. |
|
| 513 |
+// DescribeMetricFiltersRequest generates a "aws/request.Request" representing the |
|
| 514 |
+// client's request for the DescribeMetricFilters operation. The "output" return |
|
| 515 |
+// value can be used to capture response data after the request's "Send" method |
|
| 516 |
+// is called. |
|
| 517 |
+// |
|
| 518 |
+// See DescribeMetricFilters for usage and error information. |
|
| 519 |
+// |
|
| 520 |
+// Creating a request object using this method should be used when you want to inject |
|
| 521 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 522 |
+// access properties on the request object before or after sending the request. If |
|
| 523 |
+// you just want the service response, call the DescribeMetricFilters method directly |
|
| 524 |
+// instead. |
|
| 525 |
+// |
|
| 526 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 527 |
+// to execute the request. |
|
| 528 |
+// |
|
| 529 |
+// // Example sending a request using the DescribeMetricFiltersRequest method. |
|
| 530 |
+// req, resp := client.DescribeMetricFiltersRequest(params) |
|
| 531 |
+// |
|
| 532 |
+// err := req.Send() |
|
| 533 |
+// if err == nil { // resp is now filled
|
|
| 534 |
+// fmt.Println(resp) |
|
| 535 |
+// } |
|
| 536 |
+// |
|
| 514 | 537 |
func (c *CloudWatchLogs) DescribeMetricFiltersRequest(input *DescribeMetricFiltersInput) (req *request.Request, output *DescribeMetricFiltersOutput) {
|
| 515 | 538 |
op := &request.Operation{
|
| 516 | 539 |
Name: opDescribeMetricFilters, |
| ... | ... |
@@ -534,19 +1247,56 @@ func (c *CloudWatchLogs) DescribeMetricFiltersRequest(input *DescribeMetricFilte |
| 534 | 534 |
return |
| 535 | 535 |
} |
| 536 | 536 |
|
| 537 |
+// DescribeMetricFilters API operation for Amazon CloudWatch Logs. |
|
| 538 |
+// |
|
| 537 | 539 |
// Returns all the metrics filters associated with the specified log group. |
| 538 | 540 |
// The list returned in the response is ASCII-sorted by filter name. |
| 539 | 541 |
// |
| 540 |
-// By default, this operation returns up to 50 metric filters. If there are |
|
| 542 |
+// By default, this operation returns up to 50 metric filters. If there are |
|
| 541 | 543 |
// more metric filters to list, the response would contain a nextToken value |
| 542 | 544 |
// in the response body. You can also limit the number of metric filters returned |
| 543 | 545 |
// in the response by specifying the limit parameter in the request. |
| 546 |
+// |
|
| 547 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 548 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 549 |
+// the error. |
|
| 550 |
+// |
|
| 551 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 552 |
+// API operation DescribeMetricFilters for usage and error information. |
|
| 553 |
+// |
|
| 554 |
+// Returned Error Codes: |
|
| 555 |
+// * InvalidParameterException |
|
| 556 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 557 |
+// |
|
| 558 |
+// * ResourceNotFoundException |
|
| 559 |
+// Returned if the specified resource does not exist. |
|
| 560 |
+// |
|
| 561 |
+// * ServiceUnavailableException |
|
| 562 |
+// Returned if the service cannot complete the request. |
|
| 563 |
+// |
|
| 544 | 564 |
func (c *CloudWatchLogs) DescribeMetricFilters(input *DescribeMetricFiltersInput) (*DescribeMetricFiltersOutput, error) {
|
| 545 | 565 |
req, out := c.DescribeMetricFiltersRequest(input) |
| 546 | 566 |
err := req.Send() |
| 547 | 567 |
return out, err |
| 548 | 568 |
} |
| 549 | 569 |
|
| 570 |
+// DescribeMetricFiltersPages iterates over the pages of a DescribeMetricFilters operation, |
|
| 571 |
+// calling the "fn" function with the response data for each page. To stop |
|
| 572 |
+// iterating, return false from the fn function. |
|
| 573 |
+// |
|
| 574 |
+// See DescribeMetricFilters method for more information on how to use this operation. |
|
| 575 |
+// |
|
| 576 |
+// Note: This operation can generate multiple requests to a service. |
|
| 577 |
+// |
|
| 578 |
+// // Example iterating over at most 3 pages of a DescribeMetricFilters operation. |
|
| 579 |
+// pageNum := 0 |
|
| 580 |
+// err := client.DescribeMetricFiltersPages(params, |
|
| 581 |
+// func(page *DescribeMetricFiltersOutput, lastPage bool) bool {
|
|
| 582 |
+// pageNum++ |
|
| 583 |
+// fmt.Println(page) |
|
| 584 |
+// return pageNum <= 3 |
|
| 585 |
+// }) |
|
| 586 |
+// |
|
| 550 | 587 |
func (c *CloudWatchLogs) DescribeMetricFiltersPages(input *DescribeMetricFiltersInput, fn func(p *DescribeMetricFiltersOutput, lastPage bool) (shouldContinue bool)) error {
|
| 551 | 588 |
page, _ := c.DescribeMetricFiltersRequest(input) |
| 552 | 589 |
page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
|
| ... | ... |
@@ -557,7 +1307,30 @@ func (c *CloudWatchLogs) DescribeMetricFiltersPages(input *DescribeMetricFilters |
| 557 | 557 |
|
| 558 | 558 |
const opDescribeSubscriptionFilters = "DescribeSubscriptionFilters" |
| 559 | 559 |
|
| 560 |
-// DescribeSubscriptionFiltersRequest generates a request for the DescribeSubscriptionFilters operation. |
|
| 560 |
+// DescribeSubscriptionFiltersRequest generates a "aws/request.Request" representing the |
|
| 561 |
+// client's request for the DescribeSubscriptionFilters operation. The "output" return |
|
| 562 |
+// value can be used to capture response data after the request's "Send" method |
|
| 563 |
+// is called. |
|
| 564 |
+// |
|
| 565 |
+// See DescribeSubscriptionFilters for usage and error information. |
|
| 566 |
+// |
|
| 567 |
+// Creating a request object using this method should be used when you want to inject |
|
| 568 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 569 |
+// access properties on the request object before or after sending the request. If |
|
| 570 |
+// you just want the service response, call the DescribeSubscriptionFilters method directly |
|
| 571 |
+// instead. |
|
| 572 |
+// |
|
| 573 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 574 |
+// to execute the request. |
|
| 575 |
+// |
|
| 576 |
+// // Example sending a request using the DescribeSubscriptionFiltersRequest method. |
|
| 577 |
+// req, resp := client.DescribeSubscriptionFiltersRequest(params) |
|
| 578 |
+// |
|
| 579 |
+// err := req.Send() |
|
| 580 |
+// if err == nil { // resp is now filled
|
|
| 581 |
+// fmt.Println(resp) |
|
| 582 |
+// } |
|
| 583 |
+// |
|
| 561 | 584 |
func (c *CloudWatchLogs) DescribeSubscriptionFiltersRequest(input *DescribeSubscriptionFiltersInput) (req *request.Request, output *DescribeSubscriptionFiltersOutput) {
|
| 562 | 585 |
op := &request.Operation{
|
| 563 | 586 |
Name: opDescribeSubscriptionFilters, |
| ... | ... |
@@ -581,20 +1354,57 @@ func (c *CloudWatchLogs) DescribeSubscriptionFiltersRequest(input *DescribeSubsc |
| 581 | 581 |
return |
| 582 | 582 |
} |
| 583 | 583 |
|
| 584 |
+// DescribeSubscriptionFilters API operation for Amazon CloudWatch Logs. |
|
| 585 |
+// |
|
| 584 | 586 |
// Returns all the subscription filters associated with the specified log group. |
| 585 | 587 |
// The list returned in the response is ASCII-sorted by filter name. |
| 586 | 588 |
// |
| 587 |
-// By default, this operation returns up to 50 subscription filters. If there |
|
| 589 |
+// By default, this operation returns up to 50 subscription filters. If there |
|
| 588 | 590 |
// are more subscription filters to list, the response would contain a nextToken |
| 589 | 591 |
// value in the response body. You can also limit the number of subscription |
| 590 | 592 |
// filters returned in the response by specifying the limit parameter in the |
| 591 | 593 |
// request. |
| 594 |
+// |
|
| 595 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 596 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 597 |
+// the error. |
|
| 598 |
+// |
|
| 599 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 600 |
+// API operation DescribeSubscriptionFilters for usage and error information. |
|
| 601 |
+// |
|
| 602 |
+// Returned Error Codes: |
|
| 603 |
+// * InvalidParameterException |
|
| 604 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 605 |
+// |
|
| 606 |
+// * ResourceNotFoundException |
|
| 607 |
+// Returned if the specified resource does not exist. |
|
| 608 |
+// |
|
| 609 |
+// * ServiceUnavailableException |
|
| 610 |
+// Returned if the service cannot complete the request. |
|
| 611 |
+// |
|
| 592 | 612 |
func (c *CloudWatchLogs) DescribeSubscriptionFilters(input *DescribeSubscriptionFiltersInput) (*DescribeSubscriptionFiltersOutput, error) {
|
| 593 | 613 |
req, out := c.DescribeSubscriptionFiltersRequest(input) |
| 594 | 614 |
err := req.Send() |
| 595 | 615 |
return out, err |
| 596 | 616 |
} |
| 597 | 617 |
|
| 618 |
+// DescribeSubscriptionFiltersPages iterates over the pages of a DescribeSubscriptionFilters operation, |
|
| 619 |
+// calling the "fn" function with the response data for each page. To stop |
|
| 620 |
+// iterating, return false from the fn function. |
|
| 621 |
+// |
|
| 622 |
+// See DescribeSubscriptionFilters method for more information on how to use this operation. |
|
| 623 |
+// |
|
| 624 |
+// Note: This operation can generate multiple requests to a service. |
|
| 625 |
+// |
|
| 626 |
+// // Example iterating over at most 3 pages of a DescribeSubscriptionFilters operation. |
|
| 627 |
+// pageNum := 0 |
|
| 628 |
+// err := client.DescribeSubscriptionFiltersPages(params, |
|
| 629 |
+// func(page *DescribeSubscriptionFiltersOutput, lastPage bool) bool {
|
|
| 630 |
+// pageNum++ |
|
| 631 |
+// fmt.Println(page) |
|
| 632 |
+// return pageNum <= 3 |
|
| 633 |
+// }) |
|
| 634 |
+// |
|
| 598 | 635 |
func (c *CloudWatchLogs) DescribeSubscriptionFiltersPages(input *DescribeSubscriptionFiltersInput, fn func(p *DescribeSubscriptionFiltersOutput, lastPage bool) (shouldContinue bool)) error {
|
| 599 | 636 |
page, _ := c.DescribeSubscriptionFiltersRequest(input) |
| 600 | 637 |
page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
|
| ... | ... |
@@ -605,7 +1415,30 @@ func (c *CloudWatchLogs) DescribeSubscriptionFiltersPages(input *DescribeSubscri |
| 605 | 605 |
|
| 606 | 606 |
const opFilterLogEvents = "FilterLogEvents" |
| 607 | 607 |
|
| 608 |
-// FilterLogEventsRequest generates a request for the FilterLogEvents operation. |
|
| 608 |
+// FilterLogEventsRequest generates a "aws/request.Request" representing the |
|
| 609 |
+// client's request for the FilterLogEvents operation. The "output" return |
|
| 610 |
+// value can be used to capture response data after the request's "Send" method |
|
| 611 |
+// is called. |
|
| 612 |
+// |
|
| 613 |
+// See FilterLogEvents for usage and error information. |
|
| 614 |
+// |
|
| 615 |
+// Creating a request object using this method should be used when you want to inject |
|
| 616 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 617 |
+// access properties on the request object before or after sending the request. If |
|
| 618 |
+// you just want the service response, call the FilterLogEvents method directly |
|
| 619 |
+// instead. |
|
| 620 |
+// |
|
| 621 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 622 |
+// to execute the request. |
|
| 623 |
+// |
|
| 624 |
+// // Example sending a request using the FilterLogEventsRequest method. |
|
| 625 |
+// req, resp := client.FilterLogEventsRequest(params) |
|
| 626 |
+// |
|
| 627 |
+// err := req.Send() |
|
| 628 |
+// if err == nil { // resp is now filled
|
|
| 629 |
+// fmt.Println(resp) |
|
| 630 |
+// } |
|
| 631 |
+// |
|
| 609 | 632 |
func (c *CloudWatchLogs) FilterLogEventsRequest(input *FilterLogEventsInput) (req *request.Request, output *FilterLogEventsOutput) {
|
| 610 | 633 |
op := &request.Operation{
|
| 611 | 634 |
Name: opFilterLogEvents, |
| ... | ... |
@@ -629,26 +1462,63 @@ func (c *CloudWatchLogs) FilterLogEventsRequest(input *FilterLogEventsInput) (re |
| 629 | 629 |
return |
| 630 | 630 |
} |
| 631 | 631 |
|
| 632 |
+// FilterLogEvents API operation for Amazon CloudWatch Logs. |
|
| 633 |
+// |
|
| 632 | 634 |
// Retrieves log events, optionally filtered by a filter pattern from the specified |
| 633 | 635 |
// log group. You can provide an optional time range to filter the results on |
| 634 | 636 |
// the event timestamp. You can limit the streams searched to an explicit list |
| 635 | 637 |
// of logStreamNames. |
| 636 | 638 |
// |
| 637 |
-// By default, this operation returns as much matching log events as can fit |
|
| 639 |
+// By default, this operation returns as much matching log events as can fit |
|
| 638 | 640 |
// in a response size of 1MB, up to 10,000 log events, or all the events found |
| 639 | 641 |
// within a time-bounded scan window. If the response includes a nextToken, |
| 640 | 642 |
// then there is more data to search, and the search can be resumed with a new |
| 641 | 643 |
// request providing the nextToken. The response will contain a list of searchedLogStreams |
| 642 | 644 |
// that contains information about which streams were searched in the request |
| 643 | 645 |
// and whether they have been searched completely or require further pagination. |
| 644 |
-// The limit parameter in the request. can be used to specify the maximum number |
|
| 646 |
+// The limit parameter in the request can be used to specify the maximum number |
|
| 645 | 647 |
// of events to return in a page. |
| 648 |
+// |
|
| 649 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 650 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 651 |
+// the error. |
|
| 652 |
+// |
|
| 653 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 654 |
+// API operation FilterLogEvents for usage and error information. |
|
| 655 |
+// |
|
| 656 |
+// Returned Error Codes: |
|
| 657 |
+// * InvalidParameterException |
|
| 658 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 659 |
+// |
|
| 660 |
+// * ResourceNotFoundException |
|
| 661 |
+// Returned if the specified resource does not exist. |
|
| 662 |
+// |
|
| 663 |
+// * ServiceUnavailableException |
|
| 664 |
+// Returned if the service cannot complete the request. |
|
| 665 |
+// |
|
| 646 | 666 |
func (c *CloudWatchLogs) FilterLogEvents(input *FilterLogEventsInput) (*FilterLogEventsOutput, error) {
|
| 647 | 667 |
req, out := c.FilterLogEventsRequest(input) |
| 648 | 668 |
err := req.Send() |
| 649 | 669 |
return out, err |
| 650 | 670 |
} |
| 651 | 671 |
|
| 672 |
+// FilterLogEventsPages iterates over the pages of a FilterLogEvents operation, |
|
| 673 |
+// calling the "fn" function with the response data for each page. To stop |
|
| 674 |
+// iterating, return false from the fn function. |
|
| 675 |
+// |
|
| 676 |
+// See FilterLogEvents method for more information on how to use this operation. |
|
| 677 |
+// |
|
| 678 |
+// Note: This operation can generate multiple requests to a service. |
|
| 679 |
+// |
|
| 680 |
+// // Example iterating over at most 3 pages of a FilterLogEvents operation. |
|
| 681 |
+// pageNum := 0 |
|
| 682 |
+// err := client.FilterLogEventsPages(params, |
|
| 683 |
+// func(page *FilterLogEventsOutput, lastPage bool) bool {
|
|
| 684 |
+// pageNum++ |
|
| 685 |
+// fmt.Println(page) |
|
| 686 |
+// return pageNum <= 3 |
|
| 687 |
+// }) |
|
| 688 |
+// |
|
| 652 | 689 |
func (c *CloudWatchLogs) FilterLogEventsPages(input *FilterLogEventsInput, fn func(p *FilterLogEventsOutput, lastPage bool) (shouldContinue bool)) error {
|
| 653 | 690 |
page, _ := c.FilterLogEventsRequest(input) |
| 654 | 691 |
page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
|
| ... | ... |
@@ -659,7 +1529,30 @@ func (c *CloudWatchLogs) FilterLogEventsPages(input *FilterLogEventsInput, fn fu |
| 659 | 659 |
|
| 660 | 660 |
const opGetLogEvents = "GetLogEvents" |
| 661 | 661 |
|
| 662 |
-// GetLogEventsRequest generates a request for the GetLogEvents operation. |
|
| 662 |
+// GetLogEventsRequest generates a "aws/request.Request" representing the |
|
| 663 |
+// client's request for the GetLogEvents operation. The "output" return |
|
| 664 |
+// value can be used to capture response data after the request's "Send" method |
|
| 665 |
+// is called. |
|
| 666 |
+// |
|
| 667 |
+// See GetLogEvents for usage and error information. |
|
| 668 |
+// |
|
| 669 |
+// Creating a request object using this method should be used when you want to inject |
|
| 670 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 671 |
+// access properties on the request object before or after sending the request. If |
|
| 672 |
+// you just want the service response, call the GetLogEvents method directly |
|
| 673 |
+// instead. |
|
| 674 |
+// |
|
| 675 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 676 |
+// to execute the request. |
|
| 677 |
+// |
|
| 678 |
+// // Example sending a request using the GetLogEventsRequest method. |
|
| 679 |
+// req, resp := client.GetLogEventsRequest(params) |
|
| 680 |
+// |
|
| 681 |
+// err := req.Send() |
|
| 682 |
+// if err == nil { // resp is now filled
|
|
| 683 |
+// fmt.Println(resp) |
|
| 684 |
+// } |
|
| 685 |
+// |
|
| 663 | 686 |
func (c *CloudWatchLogs) GetLogEventsRequest(input *GetLogEventsInput) (req *request.Request, output *GetLogEventsOutput) {
|
| 664 | 687 |
op := &request.Operation{
|
| 665 | 688 |
Name: opGetLogEvents, |
| ... | ... |
@@ -683,22 +1576,59 @@ func (c *CloudWatchLogs) GetLogEventsRequest(input *GetLogEventsInput) (req *req |
| 683 | 683 |
return |
| 684 | 684 |
} |
| 685 | 685 |
|
| 686 |
+// GetLogEvents API operation for Amazon CloudWatch Logs. |
|
| 687 |
+// |
|
| 686 | 688 |
// Retrieves log events from the specified log stream. You can provide an optional |
| 687 | 689 |
// time range to filter the results on the event timestamp. |
| 688 | 690 |
// |
| 689 |
-// By default, this operation returns as much log events as can fit in a response |
|
| 691 |
+// By default, this operation returns as much log events as can fit in a response |
|
| 690 | 692 |
// size of 1MB, up to 10,000 log events. The response will always include a |
| 691 | 693 |
// nextForwardToken and a nextBackwardToken in the response body. You can use |
| 692 | 694 |
// any of these tokens in subsequent GetLogEvents requests to paginate through |
| 693 | 695 |
// events in either forward or backward direction. You can also limit the number |
| 694 | 696 |
// of log events returned in the response by specifying the limit parameter |
| 695 | 697 |
// in the request. |
| 698 |
+// |
|
| 699 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 700 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 701 |
+// the error. |
|
| 702 |
+// |
|
| 703 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 704 |
+// API operation GetLogEvents for usage and error information. |
|
| 705 |
+// |
|
| 706 |
+// Returned Error Codes: |
|
| 707 |
+// * InvalidParameterException |
|
| 708 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 709 |
+// |
|
| 710 |
+// * ResourceNotFoundException |
|
| 711 |
+// Returned if the specified resource does not exist. |
|
| 712 |
+// |
|
| 713 |
+// * ServiceUnavailableException |
|
| 714 |
+// Returned if the service cannot complete the request. |
|
| 715 |
+// |
|
| 696 | 716 |
func (c *CloudWatchLogs) GetLogEvents(input *GetLogEventsInput) (*GetLogEventsOutput, error) {
|
| 697 | 717 |
req, out := c.GetLogEventsRequest(input) |
| 698 | 718 |
err := req.Send() |
| 699 | 719 |
return out, err |
| 700 | 720 |
} |
| 701 | 721 |
|
| 722 |
+// GetLogEventsPages iterates over the pages of a GetLogEvents operation, |
|
| 723 |
+// calling the "fn" function with the response data for each page. To stop |
|
| 724 |
+// iterating, return false from the fn function. |
|
| 725 |
+// |
|
| 726 |
+// See GetLogEvents method for more information on how to use this operation. |
|
| 727 |
+// |
|
| 728 |
+// Note: This operation can generate multiple requests to a service. |
|
| 729 |
+// |
|
| 730 |
+// // Example iterating over at most 3 pages of a GetLogEvents operation. |
|
| 731 |
+// pageNum := 0 |
|
| 732 |
+// err := client.GetLogEventsPages(params, |
|
| 733 |
+// func(page *GetLogEventsOutput, lastPage bool) bool {
|
|
| 734 |
+// pageNum++ |
|
| 735 |
+// fmt.Println(page) |
|
| 736 |
+// return pageNum <= 3 |
|
| 737 |
+// }) |
|
| 738 |
+// |
|
| 702 | 739 |
func (c *CloudWatchLogs) GetLogEventsPages(input *GetLogEventsInput, fn func(p *GetLogEventsOutput, lastPage bool) (shouldContinue bool)) error {
|
| 703 | 740 |
page, _ := c.GetLogEventsRequest(input) |
| 704 | 741 |
page.Handlers.Build.PushBack(request.MakeAddToUserAgentFreeFormHandler("Paginator"))
|
| ... | ... |
@@ -709,7 +1639,30 @@ func (c *CloudWatchLogs) GetLogEventsPages(input *GetLogEventsInput, fn func(p * |
| 709 | 709 |
|
| 710 | 710 |
const opPutDestination = "PutDestination" |
| 711 | 711 |
|
| 712 |
-// PutDestinationRequest generates a request for the PutDestination operation. |
|
| 712 |
+// PutDestinationRequest generates a "aws/request.Request" representing the |
|
| 713 |
+// client's request for the PutDestination operation. The "output" return |
|
| 714 |
+// value can be used to capture response data after the request's "Send" method |
|
| 715 |
+// is called. |
|
| 716 |
+// |
|
| 717 |
+// See PutDestination for usage and error information. |
|
| 718 |
+// |
|
| 719 |
+// Creating a request object using this method should be used when you want to inject |
|
| 720 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 721 |
+// access properties on the request object before or after sending the request. If |
|
| 722 |
+// you just want the service response, call the PutDestination method directly |
|
| 723 |
+// instead. |
|
| 724 |
+// |
|
| 725 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 726 |
+// to execute the request. |
|
| 727 |
+// |
|
| 728 |
+// // Example sending a request using the PutDestinationRequest method. |
|
| 729 |
+// req, resp := client.PutDestinationRequest(params) |
|
| 730 |
+// |
|
| 731 |
+// err := req.Send() |
|
| 732 |
+// if err == nil { // resp is now filled
|
|
| 733 |
+// fmt.Println(resp) |
|
| 734 |
+// } |
|
| 735 |
+// |
|
| 713 | 736 |
func (c *CloudWatchLogs) PutDestinationRequest(input *PutDestinationInput) (req *request.Request, output *PutDestinationOutput) {
|
| 714 | 737 |
op := &request.Operation{
|
| 715 | 738 |
Name: opPutDestination, |
| ... | ... |
@@ -727,17 +1680,37 @@ func (c *CloudWatchLogs) PutDestinationRequest(input *PutDestinationInput) (req |
| 727 | 727 |
return |
| 728 | 728 |
} |
| 729 | 729 |
|
| 730 |
+// PutDestination API operation for Amazon CloudWatch Logs. |
|
| 731 |
+// |
|
| 730 | 732 |
// Creates or updates a Destination. A destination encapsulates a physical resource |
| 731 | 733 |
// (such as a Kinesis stream) and allows you to subscribe to a real-time stream |
| 732 | 734 |
// of log events of a different account, ingested through PutLogEvents requests. |
| 733 | 735 |
// Currently, the only supported physical resource is a Amazon Kinesis stream |
| 734 | 736 |
// belonging to the same account as the destination. |
| 735 | 737 |
// |
| 736 |
-// A destination controls what is written to its Amazon Kinesis stream through |
|
| 738 |
+// A destination controls what is written to its Amazon Kinesis stream through |
|
| 737 | 739 |
// an access policy. By default, PutDestination does not set any access policy |
| 738 | 740 |
// with the destination, which means a cross-account user will not be able to |
| 739 | 741 |
// call PutSubscriptionFilter against this destination. To enable that, the |
| 740 | 742 |
// destination owner must call PutDestinationPolicy after PutDestination. |
| 743 |
+// |
|
| 744 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 745 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 746 |
+// the error. |
|
| 747 |
+// |
|
| 748 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 749 |
+// API operation PutDestination for usage and error information. |
|
| 750 |
+// |
|
| 751 |
+// Returned Error Codes: |
|
| 752 |
+// * InvalidParameterException |
|
| 753 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 754 |
+// |
|
| 755 |
+// * OperationAbortedException |
|
| 756 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 757 |
+// |
|
| 758 |
+// * ServiceUnavailableException |
|
| 759 |
+// Returned if the service cannot complete the request. |
|
| 760 |
+// |
|
| 741 | 761 |
func (c *CloudWatchLogs) PutDestination(input *PutDestinationInput) (*PutDestinationOutput, error) {
|
| 742 | 762 |
req, out := c.PutDestinationRequest(input) |
| 743 | 763 |
err := req.Send() |
| ... | ... |
@@ -746,7 +1719,30 @@ func (c *CloudWatchLogs) PutDestination(input *PutDestinationInput) (*PutDestina |
| 746 | 746 |
|
| 747 | 747 |
const opPutDestinationPolicy = "PutDestinationPolicy" |
| 748 | 748 |
|
| 749 |
-// PutDestinationPolicyRequest generates a request for the PutDestinationPolicy operation. |
|
| 749 |
+// PutDestinationPolicyRequest generates a "aws/request.Request" representing the |
|
| 750 |
+// client's request for the PutDestinationPolicy operation. The "output" return |
|
| 751 |
+// value can be used to capture response data after the request's "Send" method |
|
| 752 |
+// is called. |
|
| 753 |
+// |
|
| 754 |
+// See PutDestinationPolicy for usage and error information. |
|
| 755 |
+// |
|
| 756 |
+// Creating a request object using this method should be used when you want to inject |
|
| 757 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 758 |
+// access properties on the request object before or after sending the request. If |
|
| 759 |
+// you just want the service response, call the PutDestinationPolicy method directly |
|
| 760 |
+// instead. |
|
| 761 |
+// |
|
| 762 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 763 |
+// to execute the request. |
|
| 764 |
+// |
|
| 765 |
+// // Example sending a request using the PutDestinationPolicyRequest method. |
|
| 766 |
+// req, resp := client.PutDestinationPolicyRequest(params) |
|
| 767 |
+// |
|
| 768 |
+// err := req.Send() |
|
| 769 |
+// if err == nil { // resp is now filled
|
|
| 770 |
+// fmt.Println(resp) |
|
| 771 |
+// } |
|
| 772 |
+// |
|
| 750 | 773 |
func (c *CloudWatchLogs) PutDestinationPolicyRequest(input *PutDestinationPolicyInput) (req *request.Request, output *PutDestinationPolicyOutput) {
|
| 751 | 774 |
op := &request.Operation{
|
| 752 | 775 |
Name: opPutDestinationPolicy, |
| ... | ... |
@@ -766,10 +1762,30 @@ func (c *CloudWatchLogs) PutDestinationPolicyRequest(input *PutDestinationPolicy |
| 766 | 766 |
return |
| 767 | 767 |
} |
| 768 | 768 |
|
| 769 |
+// PutDestinationPolicy API operation for Amazon CloudWatch Logs. |
|
| 770 |
+// |
|
| 769 | 771 |
// Creates or updates an access policy associated with an existing Destination. |
| 770 | 772 |
// An access policy is an IAM policy document (http://docs.aws.amazon.com/IAM/latest/UserGuide/policies_overview.html) |
| 771 | 773 |
// that is used to authorize claims to register a subscription filter against |
| 772 | 774 |
// a given destination. |
| 775 |
+// |
|
| 776 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 777 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 778 |
+// the error. |
|
| 779 |
+// |
|
| 780 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 781 |
+// API operation PutDestinationPolicy for usage and error information. |
|
| 782 |
+// |
|
| 783 |
+// Returned Error Codes: |
|
| 784 |
+// * InvalidParameterException |
|
| 785 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 786 |
+// |
|
| 787 |
+// * OperationAbortedException |
|
| 788 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 789 |
+// |
|
| 790 |
+// * ServiceUnavailableException |
|
| 791 |
+// Returned if the service cannot complete the request. |
|
| 792 |
+// |
|
| 773 | 793 |
func (c *CloudWatchLogs) PutDestinationPolicy(input *PutDestinationPolicyInput) (*PutDestinationPolicyOutput, error) {
|
| 774 | 794 |
req, out := c.PutDestinationPolicyRequest(input) |
| 775 | 795 |
err := req.Send() |
| ... | ... |
@@ -778,7 +1794,30 @@ func (c *CloudWatchLogs) PutDestinationPolicy(input *PutDestinationPolicyInput) |
| 778 | 778 |
|
| 779 | 779 |
const opPutLogEvents = "PutLogEvents" |
| 780 | 780 |
|
| 781 |
-// PutLogEventsRequest generates a request for the PutLogEvents operation. |
|
| 781 |
+// PutLogEventsRequest generates a "aws/request.Request" representing the |
|
| 782 |
+// client's request for the PutLogEvents operation. The "output" return |
|
| 783 |
+// value can be used to capture response data after the request's "Send" method |
|
| 784 |
+// is called. |
|
| 785 |
+// |
|
| 786 |
+// See PutLogEvents for usage and error information. |
|
| 787 |
+// |
|
| 788 |
+// Creating a request object using this method should be used when you want to inject |
|
| 789 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 790 |
+// access properties on the request object before or after sending the request. If |
|
| 791 |
+// you just want the service response, call the PutLogEvents method directly |
|
| 792 |
+// instead. |
|
| 793 |
+// |
|
| 794 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 795 |
+// to execute the request. |
|
| 796 |
+// |
|
| 797 |
+// // Example sending a request using the PutLogEventsRequest method. |
|
| 798 |
+// req, resp := client.PutLogEventsRequest(params) |
|
| 799 |
+// |
|
| 800 |
+// err := req.Send() |
|
| 801 |
+// if err == nil { // resp is now filled
|
|
| 802 |
+// fmt.Println(resp) |
|
| 803 |
+// } |
|
| 804 |
+// |
|
| 782 | 805 |
func (c *CloudWatchLogs) PutLogEventsRequest(input *PutLogEventsInput) (req *request.Request, output *PutLogEventsOutput) {
|
| 783 | 806 |
op := &request.Operation{
|
| 784 | 807 |
Name: opPutLogEvents, |
| ... | ... |
@@ -796,21 +1835,58 @@ func (c *CloudWatchLogs) PutLogEventsRequest(input *PutLogEventsInput) (req *req |
| 796 | 796 |
return |
| 797 | 797 |
} |
| 798 | 798 |
|
| 799 |
+// PutLogEvents API operation for Amazon CloudWatch Logs. |
|
| 800 |
+// |
|
| 799 | 801 |
// Uploads a batch of log events to the specified log stream. |
| 800 | 802 |
// |
| 801 |
-// Every PutLogEvents request must include the sequenceToken obtained from |
|
| 802 |
-// the response of the previous request. An upload in a newly created log stream |
|
| 803 |
-// does not require a sequenceToken. |
|
| 804 |
-// |
|
| 805 |
-// The batch of events must satisfy the following constraints: The maximum |
|
| 806 |
-// batch size is 1,048,576 bytes, and this size is calculated as the sum of |
|
| 807 |
-// all event messages in UTF-8, plus 26 bytes for each log event. None of the |
|
| 808 |
-// log events in the batch can be more than 2 hours in the future. None of the |
|
| 809 |
-// log events in the batch can be older than 14 days or the retention period |
|
| 810 |
-// of the log group. The log events in the batch must be in chronological ordered |
|
| 811 |
-// by their timestamp. The maximum number of log events in a batch is 10,000. |
|
| 812 |
-// A batch of log events in a single PutLogEvents request cannot span more than |
|
| 813 |
-// 24 hours. Otherwise, the PutLogEvents operation will fail. |
|
| 803 |
+// Every PutLogEvents request must include the sequenceToken obtained from the |
|
| 804 |
+// response of the previous request. An upload in a newly created log stream |
|
| 805 |
+// does not require a sequenceToken. You can also get the sequenceToken using |
|
| 806 |
+// DescribeLogStreams. |
|
| 807 |
+// |
|
| 808 |
+// The batch of events must satisfy the following constraints: |
|
| 809 |
+// |
|
| 810 |
+// * The maximum batch size is 1,048,576 bytes, and this size is calculated |
|
| 811 |
+// as the sum of all event messages in UTF-8, plus 26 bytes for each log |
|
| 812 |
+// event. |
|
| 813 |
+// |
|
| 814 |
+// * None of the log events in the batch can be more than 2 hours in the |
|
| 815 |
+// future. |
|
| 816 |
+// |
|
| 817 |
+// * None of the log events in the batch can be older than 14 days or the |
|
| 818 |
+// retention period of the log group. |
|
| 819 |
+// |
|
| 820 |
+// * The log events in the batch must be in chronological ordered by their |
|
| 821 |
+// timestamp. |
|
| 822 |
+// |
|
| 823 |
+// * The maximum number of log events in a batch is 10,000. |
|
| 824 |
+// |
|
| 825 |
+// * A batch of log events in a single PutLogEvents request cannot span more |
|
| 826 |
+// than 24 hours. Otherwise, the PutLogEvents operation will fail. |
|
| 827 |
+// |
|
| 828 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 829 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 830 |
+// the error. |
|
| 831 |
+// |
|
| 832 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 833 |
+// API operation PutLogEvents for usage and error information. |
|
| 834 |
+// |
|
| 835 |
+// Returned Error Codes: |
|
| 836 |
+// * InvalidParameterException |
|
| 837 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 838 |
+// |
|
| 839 |
+// * InvalidSequenceTokenException |
|
| 840 |
+ |
|
| 841 |
+// |
|
| 842 |
+// * DataAlreadyAcceptedException |
|
| 843 |
+ |
|
| 844 |
+// |
|
| 845 |
+// * ResourceNotFoundException |
|
| 846 |
+// Returned if the specified resource does not exist. |
|
| 847 |
+// |
|
| 848 |
+// * ServiceUnavailableException |
|
| 849 |
+// Returned if the service cannot complete the request. |
|
| 850 |
+// |
|
| 814 | 851 |
func (c *CloudWatchLogs) PutLogEvents(input *PutLogEventsInput) (*PutLogEventsOutput, error) {
|
| 815 | 852 |
req, out := c.PutLogEventsRequest(input) |
| 816 | 853 |
err := req.Send() |
| ... | ... |
@@ -819,7 +1895,30 @@ func (c *CloudWatchLogs) PutLogEvents(input *PutLogEventsInput) (*PutLogEventsOu |
| 819 | 819 |
|
| 820 | 820 |
const opPutMetricFilter = "PutMetricFilter" |
| 821 | 821 |
|
| 822 |
-// PutMetricFilterRequest generates a request for the PutMetricFilter operation. |
|
| 822 |
+// PutMetricFilterRequest generates a "aws/request.Request" representing the |
|
| 823 |
+// client's request for the PutMetricFilter operation. The "output" return |
|
| 824 |
+// value can be used to capture response data after the request's "Send" method |
|
| 825 |
+// is called. |
|
| 826 |
+// |
|
| 827 |
+// See PutMetricFilter for usage and error information. |
|
| 828 |
+// |
|
| 829 |
+// Creating a request object using this method should be used when you want to inject |
|
| 830 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 831 |
+// access properties on the request object before or after sending the request. If |
|
| 832 |
+// you just want the service response, call the PutMetricFilter method directly |
|
| 833 |
+// instead. |
|
| 834 |
+// |
|
| 835 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 836 |
+// to execute the request. |
|
| 837 |
+// |
|
| 838 |
+// // Example sending a request using the PutMetricFilterRequest method. |
|
| 839 |
+// req, resp := client.PutMetricFilterRequest(params) |
|
| 840 |
+// |
|
| 841 |
+// err := req.Send() |
|
| 842 |
+// if err == nil { // resp is now filled
|
|
| 843 |
+// fmt.Println(resp) |
|
| 844 |
+// } |
|
| 845 |
+// |
|
| 823 | 846 |
func (c *CloudWatchLogs) PutMetricFilterRequest(input *PutMetricFilterInput) (req *request.Request, output *PutMetricFilterOutput) {
|
| 824 | 847 |
op := &request.Operation{
|
| 825 | 848 |
Name: opPutMetricFilter, |
| ... | ... |
@@ -839,12 +1938,39 @@ func (c *CloudWatchLogs) PutMetricFilterRequest(input *PutMetricFilterInput) (re |
| 839 | 839 |
return |
| 840 | 840 |
} |
| 841 | 841 |
|
| 842 |
+// PutMetricFilter API operation for Amazon CloudWatch Logs. |
|
| 843 |
+// |
|
| 842 | 844 |
// Creates or updates a metric filter and associates it with the specified log |
| 843 | 845 |
// group. Metric filters allow you to configure rules to extract metric data |
| 844 | 846 |
// from log events ingested through PutLogEvents requests. |
| 845 | 847 |
// |
| 846 |
-// The maximum number of metric filters that can be associated with a log |
|
| 847 |
-// group is 100. |
|
| 848 |
+// The maximum number of metric filters that can be associated with a log group |
|
| 849 |
+// is 100. |
|
| 850 |
+// |
|
| 851 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 852 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 853 |
+// the error. |
|
| 854 |
+// |
|
| 855 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 856 |
+// API operation PutMetricFilter for usage and error information. |
|
| 857 |
+// |
|
| 858 |
+// Returned Error Codes: |
|
| 859 |
+// * InvalidParameterException |
|
| 860 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 861 |
+// |
|
| 862 |
+// * ResourceNotFoundException |
|
| 863 |
+// Returned if the specified resource does not exist. |
|
| 864 |
+// |
|
| 865 |
+// * OperationAbortedException |
|
| 866 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 867 |
+// |
|
| 868 |
+// * LimitExceededException |
|
| 869 |
+// Returned if you have reached the maximum number of resources that can be |
|
| 870 |
+// created. |
|
| 871 |
+// |
|
| 872 |
+// * ServiceUnavailableException |
|
| 873 |
+// Returned if the service cannot complete the request. |
|
| 874 |
+// |
|
| 848 | 875 |
func (c *CloudWatchLogs) PutMetricFilter(input *PutMetricFilterInput) (*PutMetricFilterOutput, error) {
|
| 849 | 876 |
req, out := c.PutMetricFilterRequest(input) |
| 850 | 877 |
err := req.Send() |
| ... | ... |
@@ -853,7 +1979,30 @@ func (c *CloudWatchLogs) PutMetricFilter(input *PutMetricFilterInput) (*PutMetri |
| 853 | 853 |
|
| 854 | 854 |
const opPutRetentionPolicy = "PutRetentionPolicy" |
| 855 | 855 |
|
| 856 |
-// PutRetentionPolicyRequest generates a request for the PutRetentionPolicy operation. |
|
| 856 |
+// PutRetentionPolicyRequest generates a "aws/request.Request" representing the |
|
| 857 |
+// client's request for the PutRetentionPolicy operation. The "output" return |
|
| 858 |
+// value can be used to capture response data after the request's "Send" method |
|
| 859 |
+// is called. |
|
| 860 |
+// |
|
| 861 |
+// See PutRetentionPolicy for usage and error information. |
|
| 862 |
+// |
|
| 863 |
+// Creating a request object using this method should be used when you want to inject |
|
| 864 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 865 |
+// access properties on the request object before or after sending the request. If |
|
| 866 |
+// you just want the service response, call the PutRetentionPolicy method directly |
|
| 867 |
+// instead. |
|
| 868 |
+// |
|
| 869 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 870 |
+// to execute the request. |
|
| 871 |
+// |
|
| 872 |
+// // Example sending a request using the PutRetentionPolicyRequest method. |
|
| 873 |
+// req, resp := client.PutRetentionPolicyRequest(params) |
|
| 874 |
+// |
|
| 875 |
+// err := req.Send() |
|
| 876 |
+// if err == nil { // resp is now filled
|
|
| 877 |
+// fmt.Println(resp) |
|
| 878 |
+// } |
|
| 879 |
+// |
|
| 857 | 880 |
func (c *CloudWatchLogs) PutRetentionPolicyRequest(input *PutRetentionPolicyInput) (req *request.Request, output *PutRetentionPolicyOutput) {
|
| 858 | 881 |
op := &request.Operation{
|
| 859 | 882 |
Name: opPutRetentionPolicy, |
| ... | ... |
@@ -873,9 +2022,32 @@ func (c *CloudWatchLogs) PutRetentionPolicyRequest(input *PutRetentionPolicyInpu |
| 873 | 873 |
return |
| 874 | 874 |
} |
| 875 | 875 |
|
| 876 |
+// PutRetentionPolicy API operation for Amazon CloudWatch Logs. |
|
| 877 |
+// |
|
| 876 | 878 |
// Sets the retention of the specified log group. A retention policy allows |
| 877 | 879 |
// you to configure the number of days you want to retain log events in the |
| 878 | 880 |
// specified log group. |
| 881 |
+// |
|
| 882 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 883 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 884 |
+// the error. |
|
| 885 |
+// |
|
| 886 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 887 |
+// API operation PutRetentionPolicy for usage and error information. |
|
| 888 |
+// |
|
| 889 |
+// Returned Error Codes: |
|
| 890 |
+// * InvalidParameterException |
|
| 891 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 892 |
+// |
|
| 893 |
+// * ResourceNotFoundException |
|
| 894 |
+// Returned if the specified resource does not exist. |
|
| 895 |
+// |
|
| 896 |
+// * OperationAbortedException |
|
| 897 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 898 |
+// |
|
| 899 |
+// * ServiceUnavailableException |
|
| 900 |
+// Returned if the service cannot complete the request. |
|
| 901 |
+// |
|
| 879 | 902 |
func (c *CloudWatchLogs) PutRetentionPolicy(input *PutRetentionPolicyInput) (*PutRetentionPolicyOutput, error) {
|
| 880 | 903 |
req, out := c.PutRetentionPolicyRequest(input) |
| 881 | 904 |
err := req.Send() |
| ... | ... |
@@ -884,7 +2056,30 @@ func (c *CloudWatchLogs) PutRetentionPolicy(input *PutRetentionPolicyInput) (*Pu |
| 884 | 884 |
|
| 885 | 885 |
const opPutSubscriptionFilter = "PutSubscriptionFilter" |
| 886 | 886 |
|
| 887 |
-// PutSubscriptionFilterRequest generates a request for the PutSubscriptionFilter operation. |
|
| 887 |
+// PutSubscriptionFilterRequest generates a "aws/request.Request" representing the |
|
| 888 |
+// client's request for the PutSubscriptionFilter operation. The "output" return |
|
| 889 |
+// value can be used to capture response data after the request's "Send" method |
|
| 890 |
+// is called. |
|
| 891 |
+// |
|
| 892 |
+// See PutSubscriptionFilter for usage and error information. |
|
| 893 |
+// |
|
| 894 |
+// Creating a request object using this method should be used when you want to inject |
|
| 895 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 896 |
+// access properties on the request object before or after sending the request. If |
|
| 897 |
+// you just want the service response, call the PutSubscriptionFilter method directly |
|
| 898 |
+// instead. |
|
| 899 |
+// |
|
| 900 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 901 |
+// to execute the request. |
|
| 902 |
+// |
|
| 903 |
+// // Example sending a request using the PutSubscriptionFilterRequest method. |
|
| 904 |
+// req, resp := client.PutSubscriptionFilterRequest(params) |
|
| 905 |
+// |
|
| 906 |
+// err := req.Send() |
|
| 907 |
+// if err == nil { // resp is now filled
|
|
| 908 |
+// fmt.Println(resp) |
|
| 909 |
+// } |
|
| 910 |
+// |
|
| 888 | 911 |
func (c *CloudWatchLogs) PutSubscriptionFilterRequest(input *PutSubscriptionFilterInput) (req *request.Request, output *PutSubscriptionFilterOutput) {
|
| 889 | 912 |
op := &request.Operation{
|
| 890 | 913 |
Name: opPutSubscriptionFilter, |
| ... | ... |
@@ -904,20 +2099,52 @@ func (c *CloudWatchLogs) PutSubscriptionFilterRequest(input *PutSubscriptionFilt |
| 904 | 904 |
return |
| 905 | 905 |
} |
| 906 | 906 |
|
| 907 |
+// PutSubscriptionFilter API operation for Amazon CloudWatch Logs. |
|
| 908 |
+// |
|
| 907 | 909 |
// Creates or updates a subscription filter and associates it with the specified |
| 908 | 910 |
// log group. Subscription filters allow you to subscribe to a real-time stream |
| 909 | 911 |
// of log events ingested through PutLogEvents requests and have them delivered |
| 910 |
-// to a specific destination. Currently, the supported destinations are: An |
|
| 911 |
-// Amazon Kinesis stream belonging to the same account as the subscription filter, |
|
| 912 |
-// for same-account delivery. A logical destination (used via an ARN of Destination) |
|
| 913 |
-// belonging to a different account, for cross-account delivery. An Amazon |
|
| 914 |
-// Kinesis Firehose stream belonging to the same account as the subscription |
|
| 915 |
-// filter, for same-account delivery. An AWS Lambda function belonging to |
|
| 916 |
-// the same account as the subscription filter, for same-account delivery. |
|
| 912 |
+// to a specific destination. Currently, the supported destinations are: |
|
| 913 |
+// |
|
| 914 |
+// * An Amazon Kinesis stream belonging to the same account as the subscription |
|
| 915 |
+// filter, for same-account delivery. |
|
| 916 |
+// |
|
| 917 |
+// * A logical destination (used via an ARN of Destination) belonging to |
|
| 918 |
+// a different account, for cross-account delivery. |
|
| 917 | 919 |
// |
| 920 |
+// * An Amazon Kinesis Firehose stream belonging to the same account as the |
|
| 921 |
+// subscription filter, for same-account delivery. |
|
| 918 | 922 |
// |
| 919 |
-// Currently there can only be one subscription filter associated with a log |
|
| 923 |
+// * An AWS Lambda function belonging to the same account as the subscription |
|
| 924 |
+// filter, for same-account delivery. |
|
| 925 |
+// |
|
| 926 |
+// Currently there can only be one subscription filter associated with a log |
|
| 920 | 927 |
// group. |
| 928 |
+// |
|
| 929 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 930 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 931 |
+// the error. |
|
| 932 |
+// |
|
| 933 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 934 |
+// API operation PutSubscriptionFilter for usage and error information. |
|
| 935 |
+// |
|
| 936 |
+// Returned Error Codes: |
|
| 937 |
+// * InvalidParameterException |
|
| 938 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 939 |
+// |
|
| 940 |
+// * ResourceNotFoundException |
|
| 941 |
+// Returned if the specified resource does not exist. |
|
| 942 |
+// |
|
| 943 |
+// * OperationAbortedException |
|
| 944 |
+// Returned if multiple requests to update the same resource were in conflict. |
|
| 945 |
+// |
|
| 946 |
+// * LimitExceededException |
|
| 947 |
+// Returned if you have reached the maximum number of resources that can be |
|
| 948 |
+// created. |
|
| 949 |
+// |
|
| 950 |
+// * ServiceUnavailableException |
|
| 951 |
+// Returned if the service cannot complete the request. |
|
| 952 |
+// |
|
| 921 | 953 |
func (c *CloudWatchLogs) PutSubscriptionFilter(input *PutSubscriptionFilterInput) (*PutSubscriptionFilterOutput, error) {
|
| 922 | 954 |
req, out := c.PutSubscriptionFilterRequest(input) |
| 923 | 955 |
err := req.Send() |
| ... | ... |
@@ -926,7 +2153,30 @@ func (c *CloudWatchLogs) PutSubscriptionFilter(input *PutSubscriptionFilterInput |
| 926 | 926 |
|
| 927 | 927 |
const opTestMetricFilter = "TestMetricFilter" |
| 928 | 928 |
|
| 929 |
-// TestMetricFilterRequest generates a request for the TestMetricFilter operation. |
|
| 929 |
+// TestMetricFilterRequest generates a "aws/request.Request" representing the |
|
| 930 |
+// client's request for the TestMetricFilter operation. The "output" return |
|
| 931 |
+// value can be used to capture response data after the request's "Send" method |
|
| 932 |
+// is called. |
|
| 933 |
+// |
|
| 934 |
+// See TestMetricFilter for usage and error information. |
|
| 935 |
+// |
|
| 936 |
+// Creating a request object using this method should be used when you want to inject |
|
| 937 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 938 |
+// access properties on the request object before or after sending the request. If |
|
| 939 |
+// you just want the service response, call the TestMetricFilter method directly |
|
| 940 |
+// instead. |
|
| 941 |
+// |
|
| 942 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 943 |
+// to execute the request. |
|
| 944 |
+// |
|
| 945 |
+// // Example sending a request using the TestMetricFilterRequest method. |
|
| 946 |
+// req, resp := client.TestMetricFilterRequest(params) |
|
| 947 |
+// |
|
| 948 |
+// err := req.Send() |
|
| 949 |
+// if err == nil { // resp is now filled
|
|
| 950 |
+// fmt.Println(resp) |
|
| 951 |
+// } |
|
| 952 |
+// |
|
| 930 | 953 |
func (c *CloudWatchLogs) TestMetricFilterRequest(input *TestMetricFilterInput) (req *request.Request, output *TestMetricFilterOutput) {
|
| 931 | 954 |
op := &request.Operation{
|
| 932 | 955 |
Name: opTestMetricFilter, |
| ... | ... |
@@ -944,9 +2194,26 @@ func (c *CloudWatchLogs) TestMetricFilterRequest(input *TestMetricFilterInput) ( |
| 944 | 944 |
return |
| 945 | 945 |
} |
| 946 | 946 |
|
| 947 |
+// TestMetricFilter API operation for Amazon CloudWatch Logs. |
|
| 948 |
+// |
|
| 947 | 949 |
// Tests the filter pattern of a metric filter against a sample of log event |
| 948 | 950 |
// messages. You can use this operation to validate the correctness of a metric |
| 949 | 951 |
// filter pattern. |
| 952 |
+// |
|
| 953 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 954 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 955 |
+// the error. |
|
| 956 |
+// |
|
| 957 |
+// See the AWS API reference guide for Amazon CloudWatch Logs's |
|
| 958 |
+// API operation TestMetricFilter for usage and error information. |
|
| 959 |
+// |
|
| 960 |
+// Returned Error Codes: |
|
| 961 |
+// * InvalidParameterException |
|
| 962 |
+// Returned if a parameter of the request is incorrectly specified. |
|
| 963 |
+// |
|
| 964 |
+// * ServiceUnavailableException |
|
| 965 |
+// Returned if the service cannot complete the request. |
|
| 966 |
+// |
|
| 950 | 967 |
func (c *CloudWatchLogs) TestMetricFilter(input *TestMetricFilterInput) (*TestMetricFilterOutput, error) {
|
| 951 | 968 |
req, out := c.TestMetricFilterRequest(input) |
| 952 | 969 |
err := req.Send() |
| ... | ... |
@@ -957,6 +2224,8 @@ type CancelExportTaskInput struct {
|
| 957 | 957 |
_ struct{} `type:"structure"`
|
| 958 | 958 |
|
| 959 | 959 |
// Id of the export task to cancel. |
| 960 |
+ // |
|
| 961 |
+ // TaskId is a required field |
|
| 960 | 962 |
TaskId *string `locationName:"taskId" min:"1" type:"string" required:"true"` |
| 961 | 963 |
} |
| 962 | 964 |
|
| ... | ... |
@@ -1006,6 +2275,8 @@ type CreateExportTaskInput struct {
|
| 1006 | 1006 |
// Name of Amazon S3 bucket to which the log data will be exported. |
| 1007 | 1007 |
// |
| 1008 | 1008 |
// Note: Only buckets in the same AWS region are supported. |
| 1009 |
+ // |
|
| 1010 |
+ // Destination is a required field |
|
| 1009 | 1011 |
Destination *string `locationName:"destination" min:"1" type:"string" required:"true"` |
| 1010 | 1012 |
|
| 1011 | 1013 |
// Prefix that will be used as the start of Amazon S3 key for every object exported. |
| ... | ... |
@@ -1015,9 +2286,13 @@ type CreateExportTaskInput struct {
|
| 1015 | 1015 |
// A point in time expressed as the number of milliseconds since Jan 1, 1970 |
| 1016 | 1016 |
// 00:00:00 UTC. It indicates the start time of the range for the request. Events |
| 1017 | 1017 |
// with a timestamp prior to this time will not be exported. |
| 1018 |
+ // |
|
| 1019 |
+ // From is a required field |
|
| 1018 | 1020 |
From *int64 `locationName:"from" type:"long" required:"true"` |
| 1019 | 1021 |
|
| 1020 | 1022 |
// The name of the log group to export. |
| 1023 |
+ // |
|
| 1024 |
+ // LogGroupName is a required field |
|
| 1021 | 1025 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1022 | 1026 |
|
| 1023 | 1027 |
// Will only export log streams that match the provided logStreamNamePrefix. |
| ... | ... |
@@ -1030,6 +2305,8 @@ type CreateExportTaskInput struct {
|
| 1030 | 1030 |
// A point in time expressed as the number of milliseconds since Jan 1, 1970 |
| 1031 | 1031 |
// 00:00:00 UTC. It indicates the end time of the range for the request. Events |
| 1032 | 1032 |
// with a timestamp later than this time will not be exported. |
| 1033 |
+ // |
|
| 1034 |
+ // To is a required field |
|
| 1033 | 1035 |
To *int64 `locationName:"to" type:"long" required:"true"` |
| 1034 | 1036 |
} |
| 1035 | 1037 |
|
| ... | ... |
@@ -1098,6 +2375,8 @@ type CreateLogGroupInput struct {
|
| 1098 | 1098 |
_ struct{} `type:"structure"`
|
| 1099 | 1099 |
|
| 1100 | 1100 |
// The name of the log group to create. |
| 1101 |
+ // |
|
| 1102 |
+ // LogGroupName is a required field |
|
| 1101 | 1103 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1102 | 1104 |
} |
| 1103 | 1105 |
|
| ... | ... |
@@ -1145,9 +2424,13 @@ type CreateLogStreamInput struct {
|
| 1145 | 1145 |
_ struct{} `type:"structure"`
|
| 1146 | 1146 |
|
| 1147 | 1147 |
// The name of the log group under which the log stream is to be created. |
| 1148 |
+ // |
|
| 1149 |
+ // LogGroupName is a required field |
|
| 1148 | 1150 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1149 | 1151 |
|
| 1150 | 1152 |
// The name of the log stream to create. |
| 1153 |
+ // |
|
| 1154 |
+ // LogStreamName is a required field |
|
| 1151 | 1155 |
LogStreamName *string `locationName:"logStreamName" min:"1" type:"string" required:"true"` |
| 1152 | 1156 |
} |
| 1153 | 1157 |
|
| ... | ... |
@@ -1201,6 +2484,8 @@ type DeleteDestinationInput struct {
|
| 1201 | 1201 |
_ struct{} `type:"structure"`
|
| 1202 | 1202 |
|
| 1203 | 1203 |
// The name of destination to delete. |
| 1204 |
+ // |
|
| 1205 |
+ // DestinationName is a required field |
|
| 1204 | 1206 |
DestinationName *string `locationName:"destinationName" min:"1" type:"string" required:"true"` |
| 1205 | 1207 |
} |
| 1206 | 1208 |
|
| ... | ... |
@@ -1248,6 +2533,8 @@ type DeleteLogGroupInput struct {
|
| 1248 | 1248 |
_ struct{} `type:"structure"`
|
| 1249 | 1249 |
|
| 1250 | 1250 |
// The name of the log group to delete. |
| 1251 |
+ // |
|
| 1252 |
+ // LogGroupName is a required field |
|
| 1251 | 1253 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1252 | 1254 |
} |
| 1253 | 1255 |
|
| ... | ... |
@@ -1295,9 +2582,13 @@ type DeleteLogStreamInput struct {
|
| 1295 | 1295 |
_ struct{} `type:"structure"`
|
| 1296 | 1296 |
|
| 1297 | 1297 |
// The name of the log group under which the log stream to delete belongs. |
| 1298 |
+ // |
|
| 1299 |
+ // LogGroupName is a required field |
|
| 1298 | 1300 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1299 | 1301 |
|
| 1300 | 1302 |
// The name of the log stream to delete. |
| 1303 |
+ // |
|
| 1304 |
+ // LogStreamName is a required field |
|
| 1301 | 1305 |
LogStreamName *string `locationName:"logStreamName" min:"1" type:"string" required:"true"` |
| 1302 | 1306 |
} |
| 1303 | 1307 |
|
| ... | ... |
@@ -1351,9 +2642,13 @@ type DeleteMetricFilterInput struct {
|
| 1351 | 1351 |
_ struct{} `type:"structure"`
|
| 1352 | 1352 |
|
| 1353 | 1353 |
// The name of the metric filter to delete. |
| 1354 |
+ // |
|
| 1355 |
+ // FilterName is a required field |
|
| 1354 | 1356 |
FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"` |
| 1355 | 1357 |
|
| 1356 | 1358 |
// The name of the log group that is associated with the metric filter to delete. |
| 1359 |
+ // |
|
| 1360 |
+ // LogGroupName is a required field |
|
| 1357 | 1361 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1358 | 1362 |
} |
| 1359 | 1363 |
|
| ... | ... |
@@ -1408,6 +2703,8 @@ type DeleteRetentionPolicyInput struct {
|
| 1408 | 1408 |
|
| 1409 | 1409 |
// The name of the log group that is associated with the retention policy to |
| 1410 | 1410 |
// delete. |
| 1411 |
+ // |
|
| 1412 |
+ // LogGroupName is a required field |
|
| 1411 | 1413 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1412 | 1414 |
} |
| 1413 | 1415 |
|
| ... | ... |
@@ -1455,10 +2752,14 @@ type DeleteSubscriptionFilterInput struct {
|
| 1455 | 1455 |
_ struct{} `type:"structure"`
|
| 1456 | 1456 |
|
| 1457 | 1457 |
// The name of the subscription filter to delete. |
| 1458 |
+ // |
|
| 1459 |
+ // FilterName is a required field |
|
| 1458 | 1460 |
FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"` |
| 1459 | 1461 |
|
| 1460 | 1462 |
// The name of the log group that is associated with the subscription filter |
| 1461 | 1463 |
// to delete. |
| 1464 |
+ // |
|
| 1465 |
+ // LogGroupName is a required field |
|
| 1462 | 1466 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1463 | 1467 |
} |
| 1464 | 1468 |
|
| ... | ... |
@@ -1726,6 +3027,8 @@ type DescribeLogStreamsInput struct {
|
| 1726 | 1726 |
Limit *int64 `locationName:"limit" min:"1" type:"integer"` |
| 1727 | 1727 |
|
| 1728 | 1728 |
// The log group name for which log streams are to be listed. |
| 1729 |
+ // |
|
| 1730 |
+ // LogGroupName is a required field |
|
| 1729 | 1731 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1730 | 1732 |
|
| 1731 | 1733 |
// Will only return log streams that match the provided logStreamNamePrefix. |
| ... | ... |
@@ -1813,6 +3116,8 @@ type DescribeMetricFiltersInput struct {
|
| 1813 | 1813 |
Limit *int64 `locationName:"limit" min:"1" type:"integer"` |
| 1814 | 1814 |
|
| 1815 | 1815 |
// The log group name for which metric filters are to be listed. |
| 1816 |
+ // |
|
| 1817 |
+ // LogGroupName is a required field |
|
| 1816 | 1818 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1817 | 1819 |
|
| 1818 | 1820 |
// A string token used for pagination that points to the next page of results. |
| ... | ... |
@@ -1888,6 +3193,8 @@ type DescribeSubscriptionFiltersInput struct {
|
| 1888 | 1888 |
Limit *int64 `locationName:"limit" min:"1" type:"integer"` |
| 1889 | 1889 |
|
| 1890 | 1890 |
// The log group name for which subscription filters are to be listed. |
| 1891 |
+ // |
|
| 1892 |
+ // LogGroupName is a required field |
|
| 1891 | 1893 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 1892 | 1894 |
|
| 1893 | 1895 |
// A string token used for pagination that points to the next page of results. |
| ... | ... |
@@ -2097,6 +3404,8 @@ type FilterLogEventsInput struct {
|
| 2097 | 2097 |
Limit *int64 `locationName:"limit" min:"1" type:"integer"` |
| 2098 | 2098 |
|
| 2099 | 2099 |
// The name of the log group to query. |
| 2100 |
+ // |
|
| 2101 |
+ // LogGroupName is a required field |
|
| 2100 | 2102 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 2101 | 2103 |
|
| 2102 | 2104 |
// Optional list of log stream names within the specified log group to search. |
| ... | ... |
@@ -2222,9 +3531,13 @@ type GetLogEventsInput struct {
|
| 2222 | 2222 |
Limit *int64 `locationName:"limit" min:"1" type:"integer"` |
| 2223 | 2223 |
|
| 2224 | 2224 |
// The name of the log group to query. |
| 2225 |
+ // |
|
| 2226 |
+ // LogGroupName is a required field |
|
| 2225 | 2227 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 2226 | 2228 |
|
| 2227 | 2229 |
// The name of the log stream to query. |
| 2230 |
+ // |
|
| 2231 |
+ // LogStreamName is a required field |
|
| 2228 | 2232 |
LogStreamName *string `locationName:"logStreamName" min:"1" type:"string" required:"true"` |
| 2229 | 2233 |
|
| 2230 | 2234 |
// A string token used for pagination that points to the next page of results. |
| ... | ... |
@@ -2312,10 +3625,13 @@ func (s GetLogEventsOutput) GoString() string {
|
| 2312 | 2312 |
type InputLogEvent struct {
|
| 2313 | 2313 |
_ struct{} `type:"structure"`
|
| 2314 | 2314 |
|
| 2315 |
+ // Message is a required field |
|
| 2315 | 2316 |
Message *string `locationName:"message" min:"1" type:"string" required:"true"` |
| 2316 | 2317 |
|
| 2317 | 2318 |
// A point in time expressed as the number of milliseconds since Jan 1, 1970 |
| 2318 | 2319 |
// 00:00:00 UTC. |
| 2320 |
+ // |
|
| 2321 |
+ // Timestamp is a required field |
|
| 2319 | 2322 |
Timestamp *int64 `locationName:"timestamp" type:"long" required:"true"` |
| 2320 | 2323 |
} |
| 2321 | 2324 |
|
| ... | ... |
@@ -2477,17 +3793,24 @@ func (s MetricFilterMatchRecord) GoString() string {
|
| 2477 | 2477 |
type MetricTransformation struct {
|
| 2478 | 2478 |
_ struct{} `type:"structure"`
|
| 2479 | 2479 |
|
| 2480 |
- // The name of the CloudWatch metric to which the monitored log information |
|
| 2481 |
- // should be published. For example, you may publish to a metric called ErrorCount. |
|
| 2480 |
+ // (Optional) A default value to emit when a filter pattern does not match a |
|
| 2481 |
+ // log event. Can be null. |
|
| 2482 |
+ DefaultValue *float64 `locationName:"defaultValue" type:"double"` |
|
| 2483 |
+ |
|
| 2484 |
+ // Name of the metric. |
|
| 2485 |
+ // |
|
| 2486 |
+ // MetricName is a required field |
|
| 2482 | 2487 |
MetricName *string `locationName:"metricName" type:"string" required:"true"` |
| 2483 | 2488 |
|
| 2484 |
- // The destination namespace of the new CloudWatch metric. |
|
| 2489 |
+ // Namespace to which the metric belongs. |
|
| 2490 |
+ // |
|
| 2491 |
+ // MetricNamespace is a required field |
|
| 2485 | 2492 |
MetricNamespace *string `locationName:"metricNamespace" type:"string" required:"true"` |
| 2486 | 2493 |
|
| 2487 |
- // What to publish to the metric. For example, if you're counting the occurrences |
|
| 2488 |
- // of a particular term like "Error", the value will be "1" for each occurrence. |
|
| 2489 |
- // If you're counting the bytes transferred the published value will be the |
|
| 2490 |
- // value in the log event. |
|
| 2494 |
+ // A string representing a value to publish to this metric when a filter pattern |
|
| 2495 |
+ // matches a log event. |
|
| 2496 |
+ // |
|
| 2497 |
+ // MetricValue is a required field |
|
| 2491 | 2498 |
MetricValue *string `locationName:"metricValue" type:"string" required:"true"` |
| 2492 | 2499 |
} |
| 2493 | 2500 |
|
| ... | ... |
@@ -2548,13 +3871,19 @@ type PutDestinationInput struct {
|
| 2548 | 2548 |
_ struct{} `type:"structure"`
|
| 2549 | 2549 |
|
| 2550 | 2550 |
// A name for the destination. |
| 2551 |
+ // |
|
| 2552 |
+ // DestinationName is a required field |
|
| 2551 | 2553 |
DestinationName *string `locationName:"destinationName" min:"1" type:"string" required:"true"` |
| 2552 | 2554 |
|
| 2553 | 2555 |
// The ARN of an IAM role that grants CloudWatch Logs permissions to do Amazon |
| 2554 |
- // Kinesis PutRecord requests on the desitnation stream. |
|
| 2556 |
+ // Kinesis PutRecord requests on the destination stream. |
|
| 2557 |
+ // |
|
| 2558 |
+ // RoleArn is a required field |
|
| 2555 | 2559 |
RoleArn *string `locationName:"roleArn" min:"1" type:"string" required:"true"` |
| 2556 | 2560 |
|
| 2557 | 2561 |
// The ARN of an Amazon Kinesis stream to deliver matching log events to. |
| 2562 |
+ // |
|
| 2563 |
+ // TargetArn is a required field |
|
| 2558 | 2564 |
TargetArn *string `locationName:"targetArn" min:"1" type:"string" required:"true"` |
| 2559 | 2565 |
} |
| 2560 | 2566 |
|
| ... | ... |
@@ -2618,9 +3947,13 @@ type PutDestinationPolicyInput struct {
|
| 2618 | 2618 |
|
| 2619 | 2619 |
// An IAM policy document that authorizes cross-account users to deliver their |
| 2620 | 2620 |
// log events to associated destination. |
| 2621 |
+ // |
|
| 2622 |
+ // AccessPolicy is a required field |
|
| 2621 | 2623 |
AccessPolicy *string `locationName:"accessPolicy" min:"1" type:"string" required:"true"` |
| 2622 | 2624 |
|
| 2623 | 2625 |
// A name for an existing destination. |
| 2626 |
+ // |
|
| 2627 |
+ // DestinationName is a required field |
|
| 2624 | 2628 |
DestinationName *string `locationName:"destinationName" min:"1" type:"string" required:"true"` |
| 2625 | 2629 |
} |
| 2626 | 2630 |
|
| ... | ... |
@@ -2674,12 +4007,18 @@ type PutLogEventsInput struct {
|
| 2674 | 2674 |
_ struct{} `type:"structure"`
|
| 2675 | 2675 |
|
| 2676 | 2676 |
// A list of log events belonging to a log stream. |
| 2677 |
+ // |
|
| 2678 |
+ // LogEvents is a required field |
|
| 2677 | 2679 |
LogEvents []*InputLogEvent `locationName:"logEvents" min:"1" type:"list" required:"true"` |
| 2678 | 2680 |
|
| 2679 | 2681 |
// The name of the log group to put log events to. |
| 2682 |
+ // |
|
| 2683 |
+ // LogGroupName is a required field |
|
| 2680 | 2684 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 2681 | 2685 |
|
| 2682 | 2686 |
// The name of the log stream to put log events to. |
| 2687 |
+ // |
|
| 2688 |
+ // LogStreamName is a required field |
|
| 2683 | 2689 |
LogStreamName *string `locationName:"logStreamName" min:"1" type:"string" required:"true"` |
| 2684 | 2690 |
|
| 2685 | 2691 |
// A string token that must be obtained from the response of the previous PutLogEvents |
| ... | ... |
@@ -2763,16 +4102,24 @@ type PutMetricFilterInput struct {
|
| 2763 | 2763 |
_ struct{} `type:"structure"`
|
| 2764 | 2764 |
|
| 2765 | 2765 |
// A name for the metric filter. |
| 2766 |
+ // |
|
| 2767 |
+ // FilterName is a required field |
|
| 2766 | 2768 |
FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"` |
| 2767 | 2769 |
|
| 2768 | 2770 |
// A valid CloudWatch Logs filter pattern for extracting metric data out of |
| 2769 | 2771 |
// ingested log events. |
| 2772 |
+ // |
|
| 2773 |
+ // FilterPattern is a required field |
|
| 2770 | 2774 |
FilterPattern *string `locationName:"filterPattern" type:"string" required:"true"` |
| 2771 | 2775 |
|
| 2772 | 2776 |
// The name of the log group to associate the metric filter with. |
| 2777 |
+ // |
|
| 2778 |
+ // LogGroupName is a required field |
|
| 2773 | 2779 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 2774 | 2780 |
|
| 2775 | 2781 |
// A collection of information needed to define how metric data gets emitted. |
| 2782 |
+ // |
|
| 2783 |
+ // MetricTransformations is a required field |
|
| 2776 | 2784 |
MetricTransformations []*MetricTransformation `locationName:"metricTransformations" min:"1" type:"list" required:"true"` |
| 2777 | 2785 |
} |
| 2778 | 2786 |
|
| ... | ... |
@@ -2845,11 +4192,15 @@ type PutRetentionPolicyInput struct {
|
| 2845 | 2845 |
_ struct{} `type:"structure"`
|
| 2846 | 2846 |
|
| 2847 | 2847 |
// The name of the log group to associate the retention policy with. |
| 2848 |
+ // |
|
| 2849 |
+ // LogGroupName is a required field |
|
| 2848 | 2850 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 2849 | 2851 |
|
| 2850 | 2852 |
// Specifies the number of days you want to retain log events in the specified |
| 2851 | 2853 |
// log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, |
| 2852 | 2854 |
// 365, 400, 545, 731, 1827, 3653. |
| 2855 |
+ // |
|
| 2856 |
+ // RetentionInDays is a required field |
|
| 2853 | 2857 |
RetentionInDays *int64 `locationName:"retentionInDays" type:"integer" required:"true"` |
| 2854 | 2858 |
} |
| 2855 | 2859 |
|
| ... | ... |
@@ -2900,23 +4251,37 @@ type PutSubscriptionFilterInput struct {
|
| 2900 | 2900 |
_ struct{} `type:"structure"`
|
| 2901 | 2901 |
|
| 2902 | 2902 |
// The ARN of the destination to deliver matching log events to. Currently, |
| 2903 |
- // the supported destinations are: An Amazon Kinesis stream belonging to the |
|
| 2904 |
- // same account as the subscription filter, for same-account delivery. A logical |
|
| 2905 |
- // destination (used via an ARN of Destination) belonging to a different account, |
|
| 2906 |
- // for cross-account delivery. An Amazon Kinesis Firehose stream belonging |
|
| 2907 |
- // to the same account as the subscription filter, for same-account delivery. |
|
| 2908 |
- // An AWS Lambda function belonging to the same account as the subscription |
|
| 2909 |
- // filter, for same-account delivery. |
|
| 2903 |
+ // the supported destinations are: |
|
| 2904 |
+ // |
|
| 2905 |
+ // * An Amazon Kinesis stream belonging to the same account as the subscription |
|
| 2906 |
+ // filter, for same-account delivery. |
|
| 2907 |
+ // |
|
| 2908 |
+ // * A logical destination (used via an ARN of Destination) belonging to |
|
| 2909 |
+ // a different account, for cross-account delivery. |
|
| 2910 |
+ // |
|
| 2911 |
+ // * An Amazon Kinesis Firehose stream belonging to the same account as the |
|
| 2912 |
+ // subscription filter, for same-account delivery. |
|
| 2913 |
+ // |
|
| 2914 |
+ // * An AWS Lambda function belonging to the same account as the subscription |
|
| 2915 |
+ // filter, for same-account delivery. |
|
| 2916 |
+ // |
|
| 2917 |
+ // DestinationArn is a required field |
|
| 2910 | 2918 |
DestinationArn *string `locationName:"destinationArn" min:"1" type:"string" required:"true"` |
| 2911 | 2919 |
|
| 2912 | 2920 |
// A name for the subscription filter. |
| 2921 |
+ // |
|
| 2922 |
+ // FilterName is a required field |
|
| 2913 | 2923 |
FilterName *string `locationName:"filterName" min:"1" type:"string" required:"true"` |
| 2914 | 2924 |
|
| 2915 | 2925 |
// A valid CloudWatch Logs filter pattern for subscribing to a filtered stream |
| 2916 | 2926 |
// of log events. |
| 2927 |
+ // |
|
| 2928 |
+ // FilterPattern is a required field |
|
| 2917 | 2929 |
FilterPattern *string `locationName:"filterPattern" type:"string" required:"true"` |
| 2918 | 2930 |
|
| 2919 | 2931 |
// The name of the log group to associate the subscription filter with. |
| 2932 |
+ // |
|
| 2933 |
+ // LogGroupName is a required field |
|
| 2920 | 2934 |
LogGroupName *string `locationName:"logGroupName" min:"1" type:"string" required:"true"` |
| 2921 | 2935 |
|
| 2922 | 2936 |
// The ARN of an IAM role that grants CloudWatch Logs permissions to deliver |
| ... | ... |
@@ -3067,9 +4432,13 @@ type TestMetricFilterInput struct {
|
| 3067 | 3067 |
// each log event. For example, a log event may contain timestamps, IP addresses, |
| 3068 | 3068 |
// strings, and so on. You use the filter pattern to specify what to look for |
| 3069 | 3069 |
// in the log event message. |
| 3070 |
+ // |
|
| 3071 |
+ // FilterPattern is a required field |
|
| 3070 | 3072 |
FilterPattern *string `locationName:"filterPattern" type:"string" required:"true"` |
| 3071 | 3073 |
|
| 3072 | 3074 |
// A list of log event messages to test. |
| 3075 |
+ // |
|
| 3076 |
+ // LogEventMessages is a required field |
|
| 3073 | 3077 |
LogEventMessages []*string `locationName:"logEventMessages" min:"1" type:"list" required:"true"` |
| 3074 | 3078 |
} |
| 3075 | 3079 |
|
| ... | ... |
@@ -3119,23 +4488,29 @@ func (s TestMetricFilterOutput) GoString() string {
|
| 3119 | 3119 |
} |
| 3120 | 3120 |
|
| 3121 | 3121 |
const ( |
| 3122 |
- // @enum ExportTaskStatusCode |
|
| 3122 |
+ // ExportTaskStatusCodeCancelled is a ExportTaskStatusCode enum value |
|
| 3123 | 3123 |
ExportTaskStatusCodeCancelled = "CANCELLED" |
| 3124 |
- // @enum ExportTaskStatusCode |
|
| 3124 |
+ |
|
| 3125 |
+ // ExportTaskStatusCodeCompleted is a ExportTaskStatusCode enum value |
|
| 3125 | 3126 |
ExportTaskStatusCodeCompleted = "COMPLETED" |
| 3126 |
- // @enum ExportTaskStatusCode |
|
| 3127 |
+ |
|
| 3128 |
+ // ExportTaskStatusCodeFailed is a ExportTaskStatusCode enum value |
|
| 3127 | 3129 |
ExportTaskStatusCodeFailed = "FAILED" |
| 3128 |
- // @enum ExportTaskStatusCode |
|
| 3130 |
+ |
|
| 3131 |
+ // ExportTaskStatusCodePending is a ExportTaskStatusCode enum value |
|
| 3129 | 3132 |
ExportTaskStatusCodePending = "PENDING" |
| 3130 |
- // @enum ExportTaskStatusCode |
|
| 3133 |
+ |
|
| 3134 |
+ // ExportTaskStatusCodePendingCancel is a ExportTaskStatusCode enum value |
|
| 3131 | 3135 |
ExportTaskStatusCodePendingCancel = "PENDING_CANCEL" |
| 3132 |
- // @enum ExportTaskStatusCode |
|
| 3136 |
+ |
|
| 3137 |
+ // ExportTaskStatusCodeRunning is a ExportTaskStatusCode enum value |
|
| 3133 | 3138 |
ExportTaskStatusCodeRunning = "RUNNING" |
| 3134 | 3139 |
) |
| 3135 | 3140 |
|
| 3136 | 3141 |
const ( |
| 3137 |
- // @enum OrderBy |
|
| 3142 |
+ // OrderByLogStreamName is a OrderBy enum value |
|
| 3138 | 3143 |
OrderByLogStreamName = "LogStreamName" |
| 3139 |
- // @enum OrderBy |
|
| 3144 |
+ |
|
| 3145 |
+ // OrderByLastEventTime is a OrderBy enum value |
|
| 3140 | 3146 |
OrderByLastEventTime = "LastEventTime" |
| 3141 | 3147 |
) |
| ... | ... |
@@ -7,8 +7,8 @@ import ( |
| 7 | 7 |
"github.com/aws/aws-sdk-go/aws/client" |
| 8 | 8 |
"github.com/aws/aws-sdk-go/aws/client/metadata" |
| 9 | 9 |
"github.com/aws/aws-sdk-go/aws/request" |
| 10 |
+ "github.com/aws/aws-sdk-go/aws/signer/v4" |
|
| 10 | 11 |
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc" |
| 11 |
- "github.com/aws/aws-sdk-go/private/signer/v4" |
|
| 12 | 12 |
) |
| 13 | 13 |
|
| 14 | 14 |
// You can use Amazon CloudWatch Logs to monitor, store, and access your log |
| ... | ... |
@@ -19,27 +19,28 @@ import ( |
| 19 | 19 |
// |
| 20 | 20 |
// You can use CloudWatch Logs to: |
| 21 | 21 |
// |
| 22 |
-// Monitor Logs from Amazon EC2 Instances in Real-time: You can use CloudWatch |
|
| 23 |
-// Logs to monitor applications and systems using log data. For example, CloudWatch |
|
| 24 |
-// Logs can track the number of errors that occur in your application logs and |
|
| 25 |
-// send you a notification whenever the rate of errors exceeds a threshold you |
|
| 26 |
-// specify. CloudWatch Logs uses your log data for monitoring; so, no code changes |
|
| 27 |
-// are required. For example, you can monitor application logs for specific |
|
| 28 |
-// literal terms (such as "NullReferenceException") or count the number of occurrences |
|
| 29 |
-// of a literal term at a particular position in log data (such as "404" status |
|
| 30 |
-// codes in an Apache access log). When the term you are searching for is found, |
|
| 31 |
-// CloudWatch Logs reports the data to a Amazon CloudWatch metric that you specify. |
|
| 22 |
+// * Monitor Logs from Amazon EC2 Instances in Real-time: You can use CloudWatch |
|
| 23 |
+// Logs to monitor applications and systems using log data. For example, |
|
| 24 |
+// CloudWatch Logs can track the number of errors that occur in your application |
|
| 25 |
+// logs and send you a notification whenever the rate of errors exceeds a |
|
| 26 |
+// threshold you specify. CloudWatch Logs uses your log data for monitoring; |
|
| 27 |
+// so, no code changes are required. For example, you can monitor application |
|
| 28 |
+// logs for specific literal terms (such as "NullReferenceException") or |
|
| 29 |
+// count the number of occurrences of a literal term at a particular position |
|
| 30 |
+// in log data (such as "404" status codes in an Apache access log). When |
|
| 31 |
+// the term you are searching for is found, CloudWatch Logs reports the data |
|
| 32 |
+// to a Amazon CloudWatch metric that you specify. |
|
| 32 | 33 |
// |
| 33 |
-// Monitor Amazon CloudTrail Logged Events: You can create alarms in Amazon |
|
| 34 |
-// CloudWatch and receive notifications of particular API activity as captured |
|
| 35 |
-// by CloudTrail and use the notification to perform troubleshooting. |
|
| 34 |
+// * Monitor Amazon CloudTrail Logged Events: You can create alarms in Amazon |
|
| 35 |
+// CloudWatch and receive notifications of particular API activity as captured |
|
| 36 |
+// by CloudTrail and use the notification to perform troubleshooting. |
|
| 36 | 37 |
// |
| 37 |
-// Archive Log Data: You can use CloudWatch Logs to store your log data in |
|
| 38 |
-// highly durable storage. You can change the log retention setting so that |
|
| 39 |
-// any log events older than this setting are automatically deleted. The CloudWatch |
|
| 40 |
-// Logs agent makes it easy to quickly send both rotated and non-rotated log |
|
| 41 |
-// data off of a host and into the log service. You can then access the raw |
|
| 42 |
-// log data when you need it. |
|
| 38 |
+// * Archive Log Data: You can use CloudWatch Logs to store your log data |
|
| 39 |
+// in highly durable storage. You can change the log retention setting so |
|
| 40 |
+// that any log events older than this setting are automatically deleted. |
|
| 41 |
+// The CloudWatch Logs agent makes it easy to quickly send both rotated and |
|
| 42 |
+// non-rotated log data off of a host and into the log service. You can then |
|
| 43 |
+// access the raw log data when you need it. |
|
| 43 | 44 |
//The service client's operations are safe to be used concurrently. |
| 44 | 45 |
// It is not safe to mutate any of the client's properties though. |
| 45 | 46 |
type CloudWatchLogs struct {
|
| ... | ... |
@@ -88,7 +89,7 @@ func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegio |
| 88 | 88 |
} |
| 89 | 89 |
|
| 90 | 90 |
// Handlers |
| 91 |
- svc.Handlers.Sign.PushBack(v4.Sign) |
|
| 91 |
+ svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) |
|
| 92 | 92 |
svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler) |
| 93 | 93 |
svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler) |
| 94 | 94 |
svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler) |
| 95 | 95 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,1894 @@ |
| 0 |
+// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. |
|
| 1 |
+ |
|
| 2 |
+// Package sts provides a client for AWS Security Token Service. |
|
| 3 |
+package sts |
|
| 4 |
+ |
|
| 5 |
+import ( |
|
| 6 |
+ "time" |
|
| 7 |
+ |
|
| 8 |
+ "github.com/aws/aws-sdk-go/aws/awsutil" |
|
| 9 |
+ "github.com/aws/aws-sdk-go/aws/request" |
|
| 10 |
+) |
|
| 11 |
+ |
|
| 12 |
+const opAssumeRole = "AssumeRole" |
|
| 13 |
+ |
|
| 14 |
+// AssumeRoleRequest generates a "aws/request.Request" representing the |
|
| 15 |
+// client's request for the AssumeRole operation. The "output" return |
|
| 16 |
+// value can be used to capture response data after the request's "Send" method |
|
| 17 |
+// is called. |
|
| 18 |
+// |
|
| 19 |
+// See AssumeRole for usage and error information. |
|
| 20 |
+// |
|
| 21 |
+// Creating a request object using this method should be used when you want to inject |
|
| 22 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 23 |
+// access properties on the request object before or after sending the request. If |
|
| 24 |
+// you just want the service response, call the AssumeRole method directly |
|
| 25 |
+// instead. |
|
| 26 |
+// |
|
| 27 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 28 |
+// to execute the request. |
|
| 29 |
+// |
|
| 30 |
+// // Example sending a request using the AssumeRoleRequest method. |
|
| 31 |
+// req, resp := client.AssumeRoleRequest(params) |
|
| 32 |
+// |
|
| 33 |
+// err := req.Send() |
|
| 34 |
+// if err == nil { // resp is now filled
|
|
| 35 |
+// fmt.Println(resp) |
|
| 36 |
+// } |
|
| 37 |
+// |
|
| 38 |
+func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, output *AssumeRoleOutput) {
|
|
| 39 |
+ op := &request.Operation{
|
|
| 40 |
+ Name: opAssumeRole, |
|
| 41 |
+ HTTPMethod: "POST", |
|
| 42 |
+ HTTPPath: "/", |
|
| 43 |
+ } |
|
| 44 |
+ |
|
| 45 |
+ if input == nil {
|
|
| 46 |
+ input = &AssumeRoleInput{}
|
|
| 47 |
+ } |
|
| 48 |
+ |
|
| 49 |
+ req = c.newRequest(op, input, output) |
|
| 50 |
+ output = &AssumeRoleOutput{}
|
|
| 51 |
+ req.Data = output |
|
| 52 |
+ return |
|
| 53 |
+} |
|
| 54 |
+ |
|
| 55 |
+// AssumeRole API operation for AWS Security Token Service. |
|
| 56 |
+// |
|
| 57 |
+// Returns a set of temporary security credentials (consisting of an access |
|
| 58 |
+// key ID, a secret access key, and a security token) that you can use to access |
|
| 59 |
+// AWS resources that you might not normally have access to. Typically, you |
|
| 60 |
+// use AssumeRole for cross-account access or federation. For a comparison of |
|
| 61 |
+// AssumeRole with the other APIs that produce temporary credentials, see Requesting |
|
| 62 |
+// Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) |
|
| 63 |
+// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) |
|
| 64 |
+// in the IAM User Guide. |
|
| 65 |
+// |
|
| 66 |
+// Important: You cannot call AssumeRole by using AWS root account credentials; |
|
| 67 |
+// access is denied. You must use credentials for an IAM user or an IAM role |
|
| 68 |
+// to call AssumeRole. |
|
| 69 |
+// |
|
| 70 |
+// For cross-account access, imagine that you own multiple accounts and need |
|
| 71 |
+// to access resources in each account. You could create long-term credentials |
|
| 72 |
+// in each account to access those resources. However, managing all those credentials |
|
| 73 |
+// and remembering which one can access which account can be time consuming. |
|
| 74 |
+// Instead, you can create one set of long-term credentials in one account and |
|
| 75 |
+// then use temporary security credentials to access all the other accounts |
|
| 76 |
+// by assuming roles in those accounts. For more information about roles, see |
|
| 77 |
+// IAM Roles (Delegation and Federation) (http://docs.aws.amazon.com/IAM/latest/UserGuide/roles-toplevel.html) |
|
| 78 |
+// in the IAM User Guide. |
|
| 79 |
+// |
|
| 80 |
+// For federation, you can, for example, grant single sign-on access to the |
|
| 81 |
+// AWS Management Console. If you already have an identity and authentication |
|
| 82 |
+// system in your corporate network, you don't have to recreate user identities |
|
| 83 |
+// in AWS in order to grant those user identities access to AWS. Instead, after |
|
| 84 |
+// a user has been authenticated, you call AssumeRole (and specify the role |
|
| 85 |
+// with the appropriate permissions) to get temporary security credentials for |
|
| 86 |
+// that user. With those temporary security credentials, you construct a sign-in |
|
| 87 |
+// URL that users can use to access the console. For more information, see Common |
|
| 88 |
+// Scenarios for Temporary Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html#sts-introduction) |
|
| 89 |
+// in the IAM User Guide. |
|
| 90 |
+// |
|
| 91 |
+// The temporary security credentials are valid for the duration that you specified |
|
| 92 |
+// when calling AssumeRole, which can be from 900 seconds (15 minutes) to a |
|
| 93 |
+// maximum of 3600 seconds (1 hour). The default is 1 hour. |
|
| 94 |
+// |
|
| 95 |
+// The temporary security credentials created by AssumeRole can be used to make |
|
| 96 |
+// API calls to any AWS service with the following exception: you cannot call |
|
| 97 |
+// the STS service's GetFederationToken or GetSessionToken APIs. |
|
| 98 |
+// |
|
| 99 |
+// Optionally, you can pass an IAM access policy to this operation. If you choose |
|
| 100 |
+// not to pass a policy, the temporary security credentials that are returned |
|
| 101 |
+// by the operation have the permissions that are defined in the access policy |
|
| 102 |
+// of the role that is being assumed. If you pass a policy to this operation, |
|
| 103 |
+// the temporary security credentials that are returned by the operation have |
|
| 104 |
+// the permissions that are allowed by both the access policy of the role that |
|
| 105 |
+// is being assumed, and the policy that you pass. This gives you a way to further |
|
| 106 |
+// restrict the permissions for the resulting temporary security credentials. |
|
| 107 |
+// You cannot use the passed policy to grant permissions that are in excess |
|
| 108 |
+// of those allowed by the access policy of the role that is being assumed. |
|
| 109 |
+// For more information, see Permissions for AssumeRole, AssumeRoleWithSAML, |
|
| 110 |
+// and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) |
|
| 111 |
+// in the IAM User Guide. |
|
| 112 |
+// |
|
| 113 |
+// To assume a role, your AWS account must be trusted by the role. The trust |
|
| 114 |
+// relationship is defined in the role's trust policy when the role is created. |
|
| 115 |
+// That trust policy states which accounts are allowed to delegate access to |
|
| 116 |
+// this account's role. |
|
| 117 |
+// |
|
| 118 |
+// The user who wants to access the role must also have permissions delegated |
|
| 119 |
+// from the role's administrator. If the user is in a different account than |
|
| 120 |
+// the role, then the user's administrator must attach a policy that allows |
|
| 121 |
+// the user to call AssumeRole on the ARN of the role in the other account. |
|
| 122 |
+// If the user is in the same account as the role, then you can either attach |
|
| 123 |
+// a policy to the user (identical to the previous different account user), |
|
| 124 |
+// or you can add the user as a principal directly in the role's trust policy |
|
| 125 |
+// |
|
| 126 |
+// Using MFA with AssumeRole |
|
| 127 |
+// |
|
| 128 |
+// You can optionally include multi-factor authentication (MFA) information |
|
| 129 |
+// when you call AssumeRole. This is useful for cross-account scenarios in which |
|
| 130 |
+// you want to make sure that the user who is assuming the role has been authenticated |
|
| 131 |
+// using an AWS MFA device. In that scenario, the trust policy of the role being |
|
| 132 |
+// assumed includes a condition that tests for MFA authentication; if the caller |
|
| 133 |
+// does not include valid MFA information, the request to assume the role is |
|
| 134 |
+// denied. The condition in a trust policy that tests for MFA authentication |
|
| 135 |
+// might look like the following example. |
|
| 136 |
+// |
|
| 137 |
+// "Condition": {"Bool": {"aws:MultiFactorAuthPresent": true}}
|
|
| 138 |
+// |
|
| 139 |
+// For more information, see Configuring MFA-Protected API Access (http://docs.aws.amazon.com/IAM/latest/UserGuide/MFAProtectedAPI.html) |
|
| 140 |
+// in the IAM User Guide guide. |
|
| 141 |
+// |
|
| 142 |
+// To use MFA with AssumeRole, you pass values for the SerialNumber and TokenCode |
|
| 143 |
+// parameters. The SerialNumber value identifies the user's hardware or virtual |
|
| 144 |
+// MFA device. The TokenCode is the time-based one-time password (TOTP) that |
|
| 145 |
+// the MFA devices produces. |
|
| 146 |
+// |
|
| 147 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 148 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 149 |
+// the error. |
|
| 150 |
+// |
|
| 151 |
+// See the AWS API reference guide for AWS Security Token Service's |
|
| 152 |
+// API operation AssumeRole for usage and error information. |
|
| 153 |
+// |
|
| 154 |
+// Returned Error Codes: |
|
| 155 |
+// * MalformedPolicyDocument |
|
| 156 |
+// The request was rejected because the policy document was malformed. The error |
|
| 157 |
+// message describes the specific error. |
|
| 158 |
+// |
|
| 159 |
+// * PackedPolicyTooLarge |
|
| 160 |
+// The request was rejected because the policy document was too large. The error |
|
| 161 |
+// message describes how big the policy document is, in packed form, as a percentage |
|
| 162 |
+// of what the API allows. |
|
| 163 |
+// |
|
| 164 |
+// * RegionDisabledException |
|
| 165 |
+// STS is not activated in the requested region for the account that is being |
|
| 166 |
+// asked to generate credentials. The account administrator must use the IAM |
|
| 167 |
+// console to activate STS in that region. For more information, see Activating |
|
| 168 |
+// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) |
|
| 169 |
+// in the IAM User Guide. |
|
| 170 |
+// |
|
| 171 |
+func (c *STS) AssumeRole(input *AssumeRoleInput) (*AssumeRoleOutput, error) {
|
|
| 172 |
+ req, out := c.AssumeRoleRequest(input) |
|
| 173 |
+ err := req.Send() |
|
| 174 |
+ return out, err |
|
| 175 |
+} |
|
| 176 |
+ |
|
| 177 |
+const opAssumeRoleWithSAML = "AssumeRoleWithSAML" |
|
| 178 |
+ |
|
| 179 |
+// AssumeRoleWithSAMLRequest generates a "aws/request.Request" representing the |
|
| 180 |
+// client's request for the AssumeRoleWithSAML operation. The "output" return |
|
| 181 |
+// value can be used to capture response data after the request's "Send" method |
|
| 182 |
+// is called. |
|
| 183 |
+// |
|
| 184 |
+// See AssumeRoleWithSAML for usage and error information. |
|
| 185 |
+// |
|
| 186 |
+// Creating a request object using this method should be used when you want to inject |
|
| 187 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 188 |
+// access properties on the request object before or after sending the request. If |
|
| 189 |
+// you just want the service response, call the AssumeRoleWithSAML method directly |
|
| 190 |
+// instead. |
|
| 191 |
+// |
|
| 192 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 193 |
+// to execute the request. |
|
| 194 |
+// |
|
| 195 |
+// // Example sending a request using the AssumeRoleWithSAMLRequest method. |
|
| 196 |
+// req, resp := client.AssumeRoleWithSAMLRequest(params) |
|
| 197 |
+// |
|
| 198 |
+// err := req.Send() |
|
| 199 |
+// if err == nil { // resp is now filled
|
|
| 200 |
+// fmt.Println(resp) |
|
| 201 |
+// } |
|
| 202 |
+// |
|
| 203 |
+func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *request.Request, output *AssumeRoleWithSAMLOutput) {
|
|
| 204 |
+ op := &request.Operation{
|
|
| 205 |
+ Name: opAssumeRoleWithSAML, |
|
| 206 |
+ HTTPMethod: "POST", |
|
| 207 |
+ HTTPPath: "/", |
|
| 208 |
+ } |
|
| 209 |
+ |
|
| 210 |
+ if input == nil {
|
|
| 211 |
+ input = &AssumeRoleWithSAMLInput{}
|
|
| 212 |
+ } |
|
| 213 |
+ |
|
| 214 |
+ req = c.newRequest(op, input, output) |
|
| 215 |
+ output = &AssumeRoleWithSAMLOutput{}
|
|
| 216 |
+ req.Data = output |
|
| 217 |
+ return |
|
| 218 |
+} |
|
| 219 |
+ |
|
| 220 |
+// AssumeRoleWithSAML API operation for AWS Security Token Service. |
|
| 221 |
+// |
|
| 222 |
+// Returns a set of temporary security credentials for users who have been authenticated |
|
| 223 |
+// via a SAML authentication response. This operation provides a mechanism for |
|
| 224 |
+// tying an enterprise identity store or directory to role-based AWS access |
|
| 225 |
+// without user-specific credentials or configuration. For a comparison of AssumeRoleWithSAML |
|
| 226 |
+// with the other APIs that produce temporary credentials, see Requesting Temporary |
|
| 227 |
+// Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) |
|
| 228 |
+// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) |
|
| 229 |
+// in the IAM User Guide. |
|
| 230 |
+// |
|
| 231 |
+// The temporary security credentials returned by this operation consist of |
|
| 232 |
+// an access key ID, a secret access key, and a security token. Applications |
|
| 233 |
+// can use these temporary security credentials to sign calls to AWS services. |
|
| 234 |
+// |
|
| 235 |
+// The temporary security credentials are valid for the duration that you specified |
|
| 236 |
+// when calling AssumeRole, or until the time specified in the SAML authentication |
|
| 237 |
+// response's SessionNotOnOrAfter value, whichever is shorter. The duration |
|
| 238 |
+// can be from 900 seconds (15 minutes) to a maximum of 3600 seconds (1 hour). |
|
| 239 |
+// The default is 1 hour. |
|
| 240 |
+// |
|
| 241 |
+// The temporary security credentials created by AssumeRoleWithSAML can be used |
|
| 242 |
+// to make API calls to any AWS service with the following exception: you cannot |
|
| 243 |
+// call the STS service's GetFederationToken or GetSessionToken APIs. |
|
| 244 |
+// |
|
| 245 |
+// Optionally, you can pass an IAM access policy to this operation. If you choose |
|
| 246 |
+// not to pass a policy, the temporary security credentials that are returned |
|
| 247 |
+// by the operation have the permissions that are defined in the access policy |
|
| 248 |
+// of the role that is being assumed. If you pass a policy to this operation, |
|
| 249 |
+// the temporary security credentials that are returned by the operation have |
|
| 250 |
+// the permissions that are allowed by the intersection of both the access policy |
|
| 251 |
+// of the role that is being assumed, and the policy that you pass. This means |
|
| 252 |
+// that both policies must grant the permission for the action to be allowed. |
|
| 253 |
+// This gives you a way to further restrict the permissions for the resulting |
|
| 254 |
+// temporary security credentials. You cannot use the passed policy to grant |
|
| 255 |
+// permissions that are in excess of those allowed by the access policy of the |
|
| 256 |
+// role that is being assumed. For more information, see Permissions for AssumeRole, |
|
| 257 |
+// AssumeRoleWithSAML, and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) |
|
| 258 |
+// in the IAM User Guide. |
|
| 259 |
+// |
|
| 260 |
+// Before your application can call AssumeRoleWithSAML, you must configure your |
|
| 261 |
+// SAML identity provider (IdP) to issue the claims required by AWS. Additionally, |
|
| 262 |
+// you must use AWS Identity and Access Management (IAM) to create a SAML provider |
|
| 263 |
+// entity in your AWS account that represents your identity provider, and create |
|
| 264 |
+// an IAM role that specifies this SAML provider in its trust policy. |
|
| 265 |
+// |
|
| 266 |
+// Calling AssumeRoleWithSAML does not require the use of AWS security credentials. |
|
| 267 |
+// The identity of the caller is validated by using keys in the metadata document |
|
| 268 |
+// that is uploaded for the SAML provider entity for your identity provider. |
|
| 269 |
+// |
|
| 270 |
+// Calling AssumeRoleWithSAML can result in an entry in your AWS CloudTrail |
|
| 271 |
+// logs. The entry includes the value in the NameID element of the SAML assertion. |
|
| 272 |
+// We recommend that you use a NameIDType that is not associated with any personally |
|
| 273 |
+// identifiable information (PII). For example, you could instead use the Persistent |
|
| 274 |
+// Identifier (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent). |
|
| 275 |
+// |
|
| 276 |
+// For more information, see the following resources: |
|
| 277 |
+// |
|
| 278 |
+// * About SAML 2.0-based Federation (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html) |
|
| 279 |
+// in the IAM User Guide. |
|
| 280 |
+// |
|
| 281 |
+// * Creating SAML Identity Providers (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html) |
|
| 282 |
+// in the IAM User Guide. |
|
| 283 |
+// |
|
| 284 |
+// * Configuring a Relying Party and Claims (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_relying-party.html) |
|
| 285 |
+// in the IAM User Guide. |
|
| 286 |
+// |
|
| 287 |
+// * Creating a Role for SAML 2.0 Federation (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html) |
|
| 288 |
+// in the IAM User Guide. |
|
| 289 |
+// |
|
| 290 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 291 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 292 |
+// the error. |
|
| 293 |
+// |
|
| 294 |
+// See the AWS API reference guide for AWS Security Token Service's |
|
| 295 |
+// API operation AssumeRoleWithSAML for usage and error information. |
|
| 296 |
+// |
|
| 297 |
+// Returned Error Codes: |
|
| 298 |
+// * MalformedPolicyDocument |
|
| 299 |
+// The request was rejected because the policy document was malformed. The error |
|
| 300 |
+// message describes the specific error. |
|
| 301 |
+// |
|
| 302 |
+// * PackedPolicyTooLarge |
|
| 303 |
+// The request was rejected because the policy document was too large. The error |
|
| 304 |
+// message describes how big the policy document is, in packed form, as a percentage |
|
| 305 |
+// of what the API allows. |
|
| 306 |
+// |
|
| 307 |
+// * IDPRejectedClaim |
|
| 308 |
+// The identity provider (IdP) reported that authentication failed. This might |
|
| 309 |
+// be because the claim is invalid. |
|
| 310 |
+// |
|
| 311 |
+// If this error is returned for the AssumeRoleWithWebIdentity operation, it |
|
| 312 |
+// can also mean that the claim has expired or has been explicitly revoked. |
|
| 313 |
+// |
|
| 314 |
+// * InvalidIdentityToken |
|
| 315 |
+// The web identity token that was passed could not be validated by AWS. Get |
|
| 316 |
+// a new identity token from the identity provider and then retry the request. |
|
| 317 |
+// |
|
| 318 |
+// * ExpiredTokenException |
|
| 319 |
+// The web identity token that was passed is expired or is not valid. Get a |
|
| 320 |
+// new identity token from the identity provider and then retry the request. |
|
| 321 |
+// |
|
| 322 |
+// * RegionDisabledException |
|
| 323 |
+// STS is not activated in the requested region for the account that is being |
|
| 324 |
+// asked to generate credentials. The account administrator must use the IAM |
|
| 325 |
+// console to activate STS in that region. For more information, see Activating |
|
| 326 |
+// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) |
|
| 327 |
+// in the IAM User Guide. |
|
| 328 |
+// |
|
| 329 |
+func (c *STS) AssumeRoleWithSAML(input *AssumeRoleWithSAMLInput) (*AssumeRoleWithSAMLOutput, error) {
|
|
| 330 |
+ req, out := c.AssumeRoleWithSAMLRequest(input) |
|
| 331 |
+ err := req.Send() |
|
| 332 |
+ return out, err |
|
| 333 |
+} |
|
| 334 |
+ |
|
| 335 |
+const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity" |
|
| 336 |
+ |
|
| 337 |
+// AssumeRoleWithWebIdentityRequest generates a "aws/request.Request" representing the |
|
| 338 |
+// client's request for the AssumeRoleWithWebIdentity operation. The "output" return |
|
| 339 |
+// value can be used to capture response data after the request's "Send" method |
|
| 340 |
+// is called. |
|
| 341 |
+// |
|
| 342 |
+// See AssumeRoleWithWebIdentity for usage and error information. |
|
| 343 |
+// |
|
| 344 |
+// Creating a request object using this method should be used when you want to inject |
|
| 345 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 346 |
+// access properties on the request object before or after sending the request. If |
|
| 347 |
+// you just want the service response, call the AssumeRoleWithWebIdentity method directly |
|
| 348 |
+// instead. |
|
| 349 |
+// |
|
| 350 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 351 |
+// to execute the request. |
|
| 352 |
+// |
|
| 353 |
+// // Example sending a request using the AssumeRoleWithWebIdentityRequest method. |
|
| 354 |
+// req, resp := client.AssumeRoleWithWebIdentityRequest(params) |
|
| 355 |
+// |
|
| 356 |
+// err := req.Send() |
|
| 357 |
+// if err == nil { // resp is now filled
|
|
| 358 |
+// fmt.Println(resp) |
|
| 359 |
+// } |
|
| 360 |
+// |
|
| 361 |
+func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityInput) (req *request.Request, output *AssumeRoleWithWebIdentityOutput) {
|
|
| 362 |
+ op := &request.Operation{
|
|
| 363 |
+ Name: opAssumeRoleWithWebIdentity, |
|
| 364 |
+ HTTPMethod: "POST", |
|
| 365 |
+ HTTPPath: "/", |
|
| 366 |
+ } |
|
| 367 |
+ |
|
| 368 |
+ if input == nil {
|
|
| 369 |
+ input = &AssumeRoleWithWebIdentityInput{}
|
|
| 370 |
+ } |
|
| 371 |
+ |
|
| 372 |
+ req = c.newRequest(op, input, output) |
|
| 373 |
+ output = &AssumeRoleWithWebIdentityOutput{}
|
|
| 374 |
+ req.Data = output |
|
| 375 |
+ return |
|
| 376 |
+} |
|
| 377 |
+ |
|
| 378 |
+// AssumeRoleWithWebIdentity API operation for AWS Security Token Service. |
|
| 379 |
+// |
|
| 380 |
+// Returns a set of temporary security credentials for users who have been authenticated |
|
| 381 |
+// in a mobile or web application with a web identity provider, such as Amazon |
|
| 382 |
+// Cognito, Login with Amazon, Facebook, Google, or any OpenID Connect-compatible |
|
| 383 |
+// identity provider. |
|
| 384 |
+// |
|
| 385 |
+// For mobile applications, we recommend that you use Amazon Cognito. You can |
|
| 386 |
+// use Amazon Cognito with the AWS SDK for iOS (http://aws.amazon.com/sdkforios/) |
|
| 387 |
+// and the AWS SDK for Android (http://aws.amazon.com/sdkforandroid/) to uniquely |
|
| 388 |
+// identify a user and supply the user with a consistent identity throughout |
|
| 389 |
+// the lifetime of an application. |
|
| 390 |
+// |
|
| 391 |
+// To learn more about Amazon Cognito, see Amazon Cognito Overview (http://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html#d0e840) |
|
| 392 |
+// in the AWS SDK for Android Developer Guide guide and Amazon Cognito Overview |
|
| 393 |
+// (http://docs.aws.amazon.com/mobile/sdkforios/developerguide/cognito-auth.html#d0e664) |
|
| 394 |
+// in the AWS SDK for iOS Developer Guide. |
|
| 395 |
+// |
|
| 396 |
+// Calling AssumeRoleWithWebIdentity does not require the use of AWS security |
|
| 397 |
+// credentials. Therefore, you can distribute an application (for example, on |
|
| 398 |
+// mobile devices) that requests temporary security credentials without including |
|
| 399 |
+// long-term AWS credentials in the application, and without deploying server-based |
|
| 400 |
+// proxy services that use long-term AWS credentials. Instead, the identity |
|
| 401 |
+// of the caller is validated by using a token from the web identity provider. |
|
| 402 |
+// For a comparison of AssumeRoleWithWebIdentity with the other APIs that produce |
|
| 403 |
+// temporary credentials, see Requesting Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) |
|
| 404 |
+// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) |
|
| 405 |
+// in the IAM User Guide. |
|
| 406 |
+// |
|
| 407 |
+// The temporary security credentials returned by this API consist of an access |
|
| 408 |
+// key ID, a secret access key, and a security token. Applications can use these |
|
| 409 |
+// temporary security credentials to sign calls to AWS service APIs. |
|
| 410 |
+// |
|
| 411 |
+// The credentials are valid for the duration that you specified when calling |
|
| 412 |
+// AssumeRoleWithWebIdentity, which can be from 900 seconds (15 minutes) to |
|
| 413 |
+// a maximum of 3600 seconds (1 hour). The default is 1 hour. |
|
| 414 |
+// |
|
| 415 |
+// The temporary security credentials created by AssumeRoleWithWebIdentity can |
|
| 416 |
+// be used to make API calls to any AWS service with the following exception: |
|
| 417 |
+// you cannot call the STS service's GetFederationToken or GetSessionToken APIs. |
|
| 418 |
+// |
|
| 419 |
+// Optionally, you can pass an IAM access policy to this operation. If you choose |
|
| 420 |
+// not to pass a policy, the temporary security credentials that are returned |
|
| 421 |
+// by the operation have the permissions that are defined in the access policy |
|
| 422 |
+// of the role that is being assumed. If you pass a policy to this operation, |
|
| 423 |
+// the temporary security credentials that are returned by the operation have |
|
| 424 |
+// the permissions that are allowed by both the access policy of the role that |
|
| 425 |
+// is being assumed, and the policy that you pass. This gives you a way to further |
|
| 426 |
+// restrict the permissions for the resulting temporary security credentials. |
|
| 427 |
+// You cannot use the passed policy to grant permissions that are in excess |
|
| 428 |
+// of those allowed by the access policy of the role that is being assumed. |
|
| 429 |
+// For more information, see Permissions for AssumeRole, AssumeRoleWithSAML, |
|
| 430 |
+// and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) |
|
| 431 |
+// in the IAM User Guide. |
|
| 432 |
+// |
|
| 433 |
+// Before your application can call AssumeRoleWithWebIdentity, you must have |
|
| 434 |
+// an identity token from a supported identity provider and create a role that |
|
| 435 |
+// the application can assume. The role that your application assumes must trust |
|
| 436 |
+// the identity provider that is associated with the identity token. In other |
|
| 437 |
+// words, the identity provider must be specified in the role's trust policy. |
|
| 438 |
+// |
|
| 439 |
+// Calling AssumeRoleWithWebIdentity can result in an entry in your AWS CloudTrail |
|
| 440 |
+// logs. The entry includes the Subject (http://openid.net/specs/openid-connect-core-1_0.html#Claims) |
|
| 441 |
+// of the provided Web Identity Token. We recommend that you avoid using any |
|
| 442 |
+// personally identifiable information (PII) in this field. For example, you |
|
| 443 |
+// could instead use a GUID or a pairwise identifier, as suggested in the OIDC |
|
| 444 |
+// specification (http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes). |
|
| 445 |
+// |
|
| 446 |
+// For more information about how to use web identity federation and the AssumeRoleWithWebIdentity |
|
| 447 |
+// API, see the following resources: |
|
| 448 |
+// |
|
| 449 |
+// * Using Web Identity Federation APIs for Mobile Apps (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual) |
|
| 450 |
+// and Federation Through a Web-based Identity Provider (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). |
|
| 451 |
+// |
|
| 452 |
+// |
|
| 453 |
+// * Web Identity Federation Playground (https://web-identity-federation-playground.s3.amazonaws.com/index.html). |
|
| 454 |
+// This interactive website lets you walk through the process of authenticating |
|
| 455 |
+// via Login with Amazon, Facebook, or Google, getting temporary security |
|
| 456 |
+// credentials, and then using those credentials to make a request to AWS. |
|
| 457 |
+// |
|
| 458 |
+// |
|
| 459 |
+// * AWS SDK for iOS (http://aws.amazon.com/sdkforios/) and AWS SDK for Android |
|
| 460 |
+// (http://aws.amazon.com/sdkforandroid/). These toolkits contain sample |
|
| 461 |
+// apps that show how to invoke the identity providers, and then how to use |
|
| 462 |
+// the information from these providers to get and use temporary security |
|
| 463 |
+// credentials. |
|
| 464 |
+// |
|
| 465 |
+// * Web Identity Federation with Mobile Applications (http://aws.amazon.com/articles/4617974389850313). |
|
| 466 |
+// This article discusses web identity federation and shows an example of |
|
| 467 |
+// how to use web identity federation to get access to content in Amazon |
|
| 468 |
+// S3. |
|
| 469 |
+// |
|
| 470 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 471 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 472 |
+// the error. |
|
| 473 |
+// |
|
| 474 |
+// See the AWS API reference guide for AWS Security Token Service's |
|
| 475 |
+// API operation AssumeRoleWithWebIdentity for usage and error information. |
|
| 476 |
+// |
|
| 477 |
+// Returned Error Codes: |
|
| 478 |
+// * MalformedPolicyDocument |
|
| 479 |
+// The request was rejected because the policy document was malformed. The error |
|
| 480 |
+// message describes the specific error. |
|
| 481 |
+// |
|
| 482 |
+// * PackedPolicyTooLarge |
|
| 483 |
+// The request was rejected because the policy document was too large. The error |
|
| 484 |
+// message describes how big the policy document is, in packed form, as a percentage |
|
| 485 |
+// of what the API allows. |
|
| 486 |
+// |
|
| 487 |
+// * IDPRejectedClaim |
|
| 488 |
+// The identity provider (IdP) reported that authentication failed. This might |
|
| 489 |
+// be because the claim is invalid. |
|
| 490 |
+// |
|
| 491 |
+// If this error is returned for the AssumeRoleWithWebIdentity operation, it |
|
| 492 |
+// can also mean that the claim has expired or has been explicitly revoked. |
|
| 493 |
+// |
|
| 494 |
+// * IDPCommunicationError |
|
| 495 |
+// The request could not be fulfilled because the non-AWS identity provider |
|
| 496 |
+// (IDP) that was asked to verify the incoming identity token could not be reached. |
|
| 497 |
+// This is often a transient error caused by network conditions. Retry the request |
|
| 498 |
+// a limited number of times so that you don't exceed the request rate. If the |
|
| 499 |
+// error persists, the non-AWS identity provider might be down or not responding. |
|
| 500 |
+// |
|
| 501 |
+// * InvalidIdentityToken |
|
| 502 |
+// The web identity token that was passed could not be validated by AWS. Get |
|
| 503 |
+// a new identity token from the identity provider and then retry the request. |
|
| 504 |
+// |
|
| 505 |
+// * ExpiredTokenException |
|
| 506 |
+// The web identity token that was passed is expired or is not valid. Get a |
|
| 507 |
+// new identity token from the identity provider and then retry the request. |
|
| 508 |
+// |
|
| 509 |
+// * RegionDisabledException |
|
| 510 |
+// STS is not activated in the requested region for the account that is being |
|
| 511 |
+// asked to generate credentials. The account administrator must use the IAM |
|
| 512 |
+// console to activate STS in that region. For more information, see Activating |
|
| 513 |
+// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) |
|
| 514 |
+// in the IAM User Guide. |
|
| 515 |
+// |
|
| 516 |
+func (c *STS) AssumeRoleWithWebIdentity(input *AssumeRoleWithWebIdentityInput) (*AssumeRoleWithWebIdentityOutput, error) {
|
|
| 517 |
+ req, out := c.AssumeRoleWithWebIdentityRequest(input) |
|
| 518 |
+ err := req.Send() |
|
| 519 |
+ return out, err |
|
| 520 |
+} |
|
| 521 |
+ |
|
| 522 |
+const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage" |
|
| 523 |
+ |
|
| 524 |
+// DecodeAuthorizationMessageRequest generates a "aws/request.Request" representing the |
|
| 525 |
+// client's request for the DecodeAuthorizationMessage operation. The "output" return |
|
| 526 |
+// value can be used to capture response data after the request's "Send" method |
|
| 527 |
+// is called. |
|
| 528 |
+// |
|
| 529 |
+// See DecodeAuthorizationMessage for usage and error information. |
|
| 530 |
+// |
|
| 531 |
+// Creating a request object using this method should be used when you want to inject |
|
| 532 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 533 |
+// access properties on the request object before or after sending the request. If |
|
| 534 |
+// you just want the service response, call the DecodeAuthorizationMessage method directly |
|
| 535 |
+// instead. |
|
| 536 |
+// |
|
| 537 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 538 |
+// to execute the request. |
|
| 539 |
+// |
|
| 540 |
+// // Example sending a request using the DecodeAuthorizationMessageRequest method. |
|
| 541 |
+// req, resp := client.DecodeAuthorizationMessageRequest(params) |
|
| 542 |
+// |
|
| 543 |
+// err := req.Send() |
|
| 544 |
+// if err == nil { // resp is now filled
|
|
| 545 |
+// fmt.Println(resp) |
|
| 546 |
+// } |
|
| 547 |
+// |
|
| 548 |
+func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessageInput) (req *request.Request, output *DecodeAuthorizationMessageOutput) {
|
|
| 549 |
+ op := &request.Operation{
|
|
| 550 |
+ Name: opDecodeAuthorizationMessage, |
|
| 551 |
+ HTTPMethod: "POST", |
|
| 552 |
+ HTTPPath: "/", |
|
| 553 |
+ } |
|
| 554 |
+ |
|
| 555 |
+ if input == nil {
|
|
| 556 |
+ input = &DecodeAuthorizationMessageInput{}
|
|
| 557 |
+ } |
|
| 558 |
+ |
|
| 559 |
+ req = c.newRequest(op, input, output) |
|
| 560 |
+ output = &DecodeAuthorizationMessageOutput{}
|
|
| 561 |
+ req.Data = output |
|
| 562 |
+ return |
|
| 563 |
+} |
|
| 564 |
+ |
|
| 565 |
+// DecodeAuthorizationMessage API operation for AWS Security Token Service. |
|
| 566 |
+// |
|
| 567 |
+// Decodes additional information about the authorization status of a request |
|
| 568 |
+// from an encoded message returned in response to an AWS request. |
|
| 569 |
+// |
|
| 570 |
+// For example, if a user is not authorized to perform an action that he or |
|
| 571 |
+// she has requested, the request returns a Client.UnauthorizedOperation response |
|
| 572 |
+// (an HTTP 403 response). Some AWS actions additionally return an encoded message |
|
| 573 |
+// that can provide details about this authorization failure. |
|
| 574 |
+// |
|
| 575 |
+// Only certain AWS actions return an encoded authorization message. The documentation |
|
| 576 |
+// for an individual action indicates whether that action returns an encoded |
|
| 577 |
+// message in addition to returning an HTTP code. |
|
| 578 |
+// |
|
| 579 |
+// The message is encoded because the details of the authorization status can |
|
| 580 |
+// constitute privileged information that the user who requested the action |
|
| 581 |
+// should not see. To decode an authorization status message, a user must be |
|
| 582 |
+// granted permissions via an IAM policy to request the DecodeAuthorizationMessage |
|
| 583 |
+// (sts:DecodeAuthorizationMessage) action. |
|
| 584 |
+// |
|
| 585 |
+// The decoded message includes the following type of information: |
|
| 586 |
+// |
|
| 587 |
+// * Whether the request was denied due to an explicit deny or due to the |
|
| 588 |
+// absence of an explicit allow. For more information, see Determining Whether |
|
| 589 |
+// a Request is Allowed or Denied (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow) |
|
| 590 |
+// in the IAM User Guide. |
|
| 591 |
+// |
|
| 592 |
+// * The principal who made the request. |
|
| 593 |
+// |
|
| 594 |
+// * The requested action. |
|
| 595 |
+// |
|
| 596 |
+// * The requested resource. |
|
| 597 |
+// |
|
| 598 |
+// * The values of condition keys in the context of the user's request. |
|
| 599 |
+// |
|
| 600 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 601 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 602 |
+// the error. |
|
| 603 |
+// |
|
| 604 |
+// See the AWS API reference guide for AWS Security Token Service's |
|
| 605 |
+// API operation DecodeAuthorizationMessage for usage and error information. |
|
| 606 |
+// |
|
| 607 |
+// Returned Error Codes: |
|
| 608 |
+// * InvalidAuthorizationMessageException |
|
| 609 |
+// The error returned if the message passed to DecodeAuthorizationMessage was |
|
| 610 |
+// invalid. This can happen if the token contains invalid characters, such as |
|
| 611 |
+// linebreaks. |
|
| 612 |
+// |
|
| 613 |
+func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) {
|
|
| 614 |
+ req, out := c.DecodeAuthorizationMessageRequest(input) |
|
| 615 |
+ err := req.Send() |
|
| 616 |
+ return out, err |
|
| 617 |
+} |
|
| 618 |
+ |
|
| 619 |
+const opGetCallerIdentity = "GetCallerIdentity" |
|
| 620 |
+ |
|
| 621 |
+// GetCallerIdentityRequest generates a "aws/request.Request" representing the |
|
| 622 |
+// client's request for the GetCallerIdentity operation. The "output" return |
|
| 623 |
+// value can be used to capture response data after the request's "Send" method |
|
| 624 |
+// is called. |
|
| 625 |
+// |
|
| 626 |
+// See GetCallerIdentity for usage and error information. |
|
| 627 |
+// |
|
| 628 |
+// Creating a request object using this method should be used when you want to inject |
|
| 629 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 630 |
+// access properties on the request object before or after sending the request. If |
|
| 631 |
+// you just want the service response, call the GetCallerIdentity method directly |
|
| 632 |
+// instead. |
|
| 633 |
+// |
|
| 634 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 635 |
+// to execute the request. |
|
| 636 |
+// |
|
| 637 |
+// // Example sending a request using the GetCallerIdentityRequest method. |
|
| 638 |
+// req, resp := client.GetCallerIdentityRequest(params) |
|
| 639 |
+// |
|
| 640 |
+// err := req.Send() |
|
| 641 |
+// if err == nil { // resp is now filled
|
|
| 642 |
+// fmt.Println(resp) |
|
| 643 |
+// } |
|
| 644 |
+// |
|
| 645 |
+func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *request.Request, output *GetCallerIdentityOutput) {
|
|
| 646 |
+ op := &request.Operation{
|
|
| 647 |
+ Name: opGetCallerIdentity, |
|
| 648 |
+ HTTPMethod: "POST", |
|
| 649 |
+ HTTPPath: "/", |
|
| 650 |
+ } |
|
| 651 |
+ |
|
| 652 |
+ if input == nil {
|
|
| 653 |
+ input = &GetCallerIdentityInput{}
|
|
| 654 |
+ } |
|
| 655 |
+ |
|
| 656 |
+ req = c.newRequest(op, input, output) |
|
| 657 |
+ output = &GetCallerIdentityOutput{}
|
|
| 658 |
+ req.Data = output |
|
| 659 |
+ return |
|
| 660 |
+} |
|
| 661 |
+ |
|
| 662 |
+// GetCallerIdentity API operation for AWS Security Token Service. |
|
| 663 |
+// |
|
| 664 |
+// Returns details about the IAM identity whose credentials are used to call |
|
| 665 |
+// the API. |
|
| 666 |
+// |
|
| 667 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 668 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 669 |
+// the error. |
|
| 670 |
+// |
|
| 671 |
+// See the AWS API reference guide for AWS Security Token Service's |
|
| 672 |
+// API operation GetCallerIdentity for usage and error information. |
|
| 673 |
+func (c *STS) GetCallerIdentity(input *GetCallerIdentityInput) (*GetCallerIdentityOutput, error) {
|
|
| 674 |
+ req, out := c.GetCallerIdentityRequest(input) |
|
| 675 |
+ err := req.Send() |
|
| 676 |
+ return out, err |
|
| 677 |
+} |
|
| 678 |
+ |
|
| 679 |
+const opGetFederationToken = "GetFederationToken" |
|
| 680 |
+ |
|
| 681 |
+// GetFederationTokenRequest generates a "aws/request.Request" representing the |
|
| 682 |
+// client's request for the GetFederationToken operation. The "output" return |
|
| 683 |
+// value can be used to capture response data after the request's "Send" method |
|
| 684 |
+// is called. |
|
| 685 |
+// |
|
| 686 |
+// See GetFederationToken for usage and error information. |
|
| 687 |
+// |
|
| 688 |
+// Creating a request object using this method should be used when you want to inject |
|
| 689 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 690 |
+// access properties on the request object before or after sending the request. If |
|
| 691 |
+// you just want the service response, call the GetFederationToken method directly |
|
| 692 |
+// instead. |
|
| 693 |
+// |
|
| 694 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 695 |
+// to execute the request. |
|
| 696 |
+// |
|
| 697 |
+// // Example sending a request using the GetFederationTokenRequest method. |
|
| 698 |
+// req, resp := client.GetFederationTokenRequest(params) |
|
| 699 |
+// |
|
| 700 |
+// err := req.Send() |
|
| 701 |
+// if err == nil { // resp is now filled
|
|
| 702 |
+// fmt.Println(resp) |
|
| 703 |
+// } |
|
| 704 |
+// |
|
| 705 |
+func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *request.Request, output *GetFederationTokenOutput) {
|
|
| 706 |
+ op := &request.Operation{
|
|
| 707 |
+ Name: opGetFederationToken, |
|
| 708 |
+ HTTPMethod: "POST", |
|
| 709 |
+ HTTPPath: "/", |
|
| 710 |
+ } |
|
| 711 |
+ |
|
| 712 |
+ if input == nil {
|
|
| 713 |
+ input = &GetFederationTokenInput{}
|
|
| 714 |
+ } |
|
| 715 |
+ |
|
| 716 |
+ req = c.newRequest(op, input, output) |
|
| 717 |
+ output = &GetFederationTokenOutput{}
|
|
| 718 |
+ req.Data = output |
|
| 719 |
+ return |
|
| 720 |
+} |
|
| 721 |
+ |
|
| 722 |
+// GetFederationToken API operation for AWS Security Token Service. |
|
| 723 |
+// |
|
| 724 |
+// Returns a set of temporary security credentials (consisting of an access |
|
| 725 |
+// key ID, a secret access key, and a security token) for a federated user. |
|
| 726 |
+// A typical use is in a proxy application that gets temporary security credentials |
|
| 727 |
+// on behalf of distributed applications inside a corporate network. Because |
|
| 728 |
+// you must call the GetFederationToken action using the long-term security |
|
| 729 |
+// credentials of an IAM user, this call is appropriate in contexts where those |
|
| 730 |
+// credentials can be safely stored, usually in a server-based application. |
|
| 731 |
+// For a comparison of GetFederationToken with the other APIs that produce temporary |
|
| 732 |
+// credentials, see Requesting Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) |
|
| 733 |
+// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) |
|
| 734 |
+// in the IAM User Guide. |
|
| 735 |
+// |
|
| 736 |
+// If you are creating a mobile-based or browser-based app that can authenticate |
|
| 737 |
+// users using a web identity provider like Login with Amazon, Facebook, Google, |
|
| 738 |
+// or an OpenID Connect-compatible identity provider, we recommend that you |
|
| 739 |
+// use Amazon Cognito (http://aws.amazon.com/cognito/) or AssumeRoleWithWebIdentity. |
|
| 740 |
+// For more information, see Federation Through a Web-based Identity Provider |
|
| 741 |
+// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). |
|
| 742 |
+// |
|
| 743 |
+// The GetFederationToken action must be called by using the long-term AWS security |
|
| 744 |
+// credentials of an IAM user. You can also call GetFederationToken using the |
|
| 745 |
+// security credentials of an AWS root account, but we do not recommended it. |
|
| 746 |
+// Instead, we recommend that you create an IAM user for the purpose of the |
|
| 747 |
+// proxy application and then attach a policy to the IAM user that limits federated |
|
| 748 |
+// users to only the actions and resources that they need access to. For more |
|
| 749 |
+// information, see IAM Best Practices (http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) |
|
| 750 |
+// in the IAM User Guide. |
|
| 751 |
+// |
|
| 752 |
+// The temporary security credentials that are obtained by using the long-term |
|
| 753 |
+// credentials of an IAM user are valid for the specified duration, from 900 |
|
| 754 |
+// seconds (15 minutes) up to a maximium of 129600 seconds (36 hours). The default |
|
| 755 |
+// is 43200 seconds (12 hours). Temporary credentials that are obtained by using |
|
| 756 |
+// AWS root account credentials have a maximum duration of 3600 seconds (1 hour). |
|
| 757 |
+// |
|
| 758 |
+// The temporary security credentials created by GetFederationToken can be used |
|
| 759 |
+// to make API calls to any AWS service with the following exceptions: |
|
| 760 |
+// |
|
| 761 |
+// * You cannot use these credentials to call any IAM APIs. |
|
| 762 |
+// |
|
| 763 |
+// * You cannot call any STS APIs. |
|
| 764 |
+// |
|
| 765 |
+// Permissions |
|
| 766 |
+// |
|
| 767 |
+// The permissions for the temporary security credentials returned by GetFederationToken |
|
| 768 |
+// are determined by a combination of the following: |
|
| 769 |
+// |
|
| 770 |
+// * The policy or policies that are attached to the IAM user whose credentials |
|
| 771 |
+// are used to call GetFederationToken. |
|
| 772 |
+// |
|
| 773 |
+// * The policy that is passed as a parameter in the call. |
|
| 774 |
+// |
|
| 775 |
+// The passed policy is attached to the temporary security credentials that |
|
| 776 |
+// result from the GetFederationToken API call--that is, to the federated user. |
|
| 777 |
+// When the federated user makes an AWS request, AWS evaluates the policy attached |
|
| 778 |
+// to the federated user in combination with the policy or policies attached |
|
| 779 |
+// to the IAM user whose credentials were used to call GetFederationToken. AWS |
|
| 780 |
+// allows the federated user's request only when both the federated user and |
|
| 781 |
+// the IAM user are explicitly allowed to perform the requested action. The |
|
| 782 |
+// passed policy cannot grant more permissions than those that are defined in |
|
| 783 |
+// the IAM user policy. |
|
| 784 |
+// |
|
| 785 |
+// A typical use case is that the permissions of the IAM user whose credentials |
|
| 786 |
+// are used to call GetFederationToken are designed to allow access to all the |
|
| 787 |
+// actions and resources that any federated user will need. Then, for individual |
|
| 788 |
+// users, you pass a policy to the operation that scopes down the permissions |
|
| 789 |
+// to a level that's appropriate to that individual user, using a policy that |
|
| 790 |
+// allows only a subset of permissions that are granted to the IAM user. |
|
| 791 |
+// |
|
| 792 |
+// If you do not pass a policy, the resulting temporary security credentials |
|
| 793 |
+// have no effective permissions. The only exception is when the temporary security |
|
| 794 |
+// credentials are used to access a resource that has a resource-based policy |
|
| 795 |
+// that specifically allows the federated user to access the resource. |
|
| 796 |
+// |
|
| 797 |
+// For more information about how permissions work, see Permissions for GetFederationToken |
|
| 798 |
+// (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getfederationtoken.html). |
|
| 799 |
+// For information about using GetFederationToken to create temporary security |
|
| 800 |
+// credentials, see GetFederationToken—Federation Through a Custom Identity |
|
| 801 |
+// Broker (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken). |
|
| 802 |
+// |
|
| 803 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 804 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 805 |
+// the error. |
|
| 806 |
+// |
|
| 807 |
+// See the AWS API reference guide for AWS Security Token Service's |
|
| 808 |
+// API operation GetFederationToken for usage and error information. |
|
| 809 |
+// |
|
| 810 |
+// Returned Error Codes: |
|
| 811 |
+// * MalformedPolicyDocument |
|
| 812 |
+// The request was rejected because the policy document was malformed. The error |
|
| 813 |
+// message describes the specific error. |
|
| 814 |
+// |
|
| 815 |
+// * PackedPolicyTooLarge |
|
| 816 |
+// The request was rejected because the policy document was too large. The error |
|
| 817 |
+// message describes how big the policy document is, in packed form, as a percentage |
|
| 818 |
+// of what the API allows. |
|
| 819 |
+// |
|
| 820 |
+// * RegionDisabledException |
|
| 821 |
+// STS is not activated in the requested region for the account that is being |
|
| 822 |
+// asked to generate credentials. The account administrator must use the IAM |
|
| 823 |
+// console to activate STS in that region. For more information, see Activating |
|
| 824 |
+// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) |
|
| 825 |
+// in the IAM User Guide. |
|
| 826 |
+// |
|
| 827 |
+func (c *STS) GetFederationToken(input *GetFederationTokenInput) (*GetFederationTokenOutput, error) {
|
|
| 828 |
+ req, out := c.GetFederationTokenRequest(input) |
|
| 829 |
+ err := req.Send() |
|
| 830 |
+ return out, err |
|
| 831 |
+} |
|
| 832 |
+ |
|
| 833 |
+const opGetSessionToken = "GetSessionToken" |
|
| 834 |
+ |
|
| 835 |
+// GetSessionTokenRequest generates a "aws/request.Request" representing the |
|
| 836 |
+// client's request for the GetSessionToken operation. The "output" return |
|
| 837 |
+// value can be used to capture response data after the request's "Send" method |
|
| 838 |
+// is called. |
|
| 839 |
+// |
|
| 840 |
+// See GetSessionToken for usage and error information. |
|
| 841 |
+// |
|
| 842 |
+// Creating a request object using this method should be used when you want to inject |
|
| 843 |
+// custom logic into the request's lifecycle using a custom handler, or if you want to |
|
| 844 |
+// access properties on the request object before or after sending the request. If |
|
| 845 |
+// you just want the service response, call the GetSessionToken method directly |
|
| 846 |
+// instead. |
|
| 847 |
+// |
|
| 848 |
+// Note: You must call the "Send" method on the returned request object in order |
|
| 849 |
+// to execute the request. |
|
| 850 |
+// |
|
| 851 |
+// // Example sending a request using the GetSessionTokenRequest method. |
|
| 852 |
+// req, resp := client.GetSessionTokenRequest(params) |
|
| 853 |
+// |
|
| 854 |
+// err := req.Send() |
|
| 855 |
+// if err == nil { // resp is now filled
|
|
| 856 |
+// fmt.Println(resp) |
|
| 857 |
+// } |
|
| 858 |
+// |
|
| 859 |
+func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.Request, output *GetSessionTokenOutput) {
|
|
| 860 |
+ op := &request.Operation{
|
|
| 861 |
+ Name: opGetSessionToken, |
|
| 862 |
+ HTTPMethod: "POST", |
|
| 863 |
+ HTTPPath: "/", |
|
| 864 |
+ } |
|
| 865 |
+ |
|
| 866 |
+ if input == nil {
|
|
| 867 |
+ input = &GetSessionTokenInput{}
|
|
| 868 |
+ } |
|
| 869 |
+ |
|
| 870 |
+ req = c.newRequest(op, input, output) |
|
| 871 |
+ output = &GetSessionTokenOutput{}
|
|
| 872 |
+ req.Data = output |
|
| 873 |
+ return |
|
| 874 |
+} |
|
| 875 |
+ |
|
| 876 |
+// GetSessionToken API operation for AWS Security Token Service. |
|
| 877 |
+// |
|
| 878 |
+// Returns a set of temporary credentials for an AWS account or IAM user. The |
|
| 879 |
+// credentials consist of an access key ID, a secret access key, and a security |
|
| 880 |
+// token. Typically, you use GetSessionToken if you want to use MFA to protect |
|
| 881 |
+// programmatic calls to specific AWS APIs like Amazon EC2 StopInstances. MFA-enabled |
|
| 882 |
+// IAM users would need to call GetSessionToken and submit an MFA code that |
|
| 883 |
+// is associated with their MFA device. Using the temporary security credentials |
|
| 884 |
+// that are returned from the call, IAM users can then make programmatic calls |
|
| 885 |
+// to APIs that require MFA authentication. If you do not supply a correct MFA |
|
| 886 |
+// code, then the API returns an access denied error. For a comparison of GetSessionToken |
|
| 887 |
+// with the other APIs that produce temporary credentials, see Requesting Temporary |
|
| 888 |
+// Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) |
|
| 889 |
+// and Comparing the AWS STS APIs (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) |
|
| 890 |
+// in the IAM User Guide. |
|
| 891 |
+// |
|
| 892 |
+// The GetSessionToken action must be called by using the long-term AWS security |
|
| 893 |
+// credentials of the AWS account or an IAM user. Credentials that are created |
|
| 894 |
+// by IAM users are valid for the duration that you specify, from 900 seconds |
|
| 895 |
+// (15 minutes) up to a maximum of 129600 seconds (36 hours), with a default |
|
| 896 |
+// of 43200 seconds (12 hours); credentials that are created by using account |
|
| 897 |
+// credentials can range from 900 seconds (15 minutes) up to a maximum of 3600 |
|
| 898 |
+// seconds (1 hour), with a default of 1 hour. |
|
| 899 |
+// |
|
| 900 |
+// The temporary security credentials created by GetSessionToken can be used |
|
| 901 |
+// to make API calls to any AWS service with the following exceptions: |
|
| 902 |
+// |
|
| 903 |
+// * You cannot call any IAM APIs unless MFA authentication information is |
|
| 904 |
+// included in the request. |
|
| 905 |
+// |
|
| 906 |
+// * You cannot call any STS API exceptAssumeRole. |
|
| 907 |
+// |
|
| 908 |
+// We recommend that you do not call GetSessionToken with root account credentials. |
|
| 909 |
+// Instead, follow our best practices (http://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users) |
|
| 910 |
+// by creating one or more IAM users, giving them the necessary permissions, |
|
| 911 |
+// and using IAM users for everyday interaction with AWS. |
|
| 912 |
+// |
|
| 913 |
+// The permissions associated with the temporary security credentials returned |
|
| 914 |
+// by GetSessionToken are based on the permissions associated with account or |
|
| 915 |
+// IAM user whose credentials are used to call the action. If GetSessionToken |
|
| 916 |
+// is called using root account credentials, the temporary credentials have |
|
| 917 |
+// root account permissions. Similarly, if GetSessionToken is called using the |
|
| 918 |
+// credentials of an IAM user, the temporary credentials have the same permissions |
|
| 919 |
+// as the IAM user. |
|
| 920 |
+// |
|
| 921 |
+// For more information about using GetSessionToken to create temporary credentials, |
|
| 922 |
+// go to Temporary Credentials for Users in Untrusted Environments (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getsessiontoken) |
|
| 923 |
+// in the IAM User Guide. |
|
| 924 |
+// |
|
| 925 |
+// Returns awserr.Error for service API and SDK errors. Use runtime type assertions |
|
| 926 |
+// with awserr.Error's Code and Message methods to get detailed information about |
|
| 927 |
+// the error. |
|
| 928 |
+// |
|
| 929 |
+// See the AWS API reference guide for AWS Security Token Service's |
|
| 930 |
+// API operation GetSessionToken for usage and error information. |
|
| 931 |
+// |
|
| 932 |
+// Returned Error Codes: |
|
| 933 |
+// * RegionDisabledException |
|
| 934 |
+// STS is not activated in the requested region for the account that is being |
|
| 935 |
+// asked to generate credentials. The account administrator must use the IAM |
|
| 936 |
+// console to activate STS in that region. For more information, see Activating |
|
| 937 |
+// and Deactivating AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) |
|
| 938 |
+// in the IAM User Guide. |
|
| 939 |
+// |
|
| 940 |
+func (c *STS) GetSessionToken(input *GetSessionTokenInput) (*GetSessionTokenOutput, error) {
|
|
| 941 |
+ req, out := c.GetSessionTokenRequest(input) |
|
| 942 |
+ err := req.Send() |
|
| 943 |
+ return out, err |
|
| 944 |
+} |
|
| 945 |
+ |
|
| 946 |
+type AssumeRoleInput struct {
|
|
| 947 |
+ _ struct{} `type:"structure"`
|
|
| 948 |
+ |
|
| 949 |
+ // The duration, in seconds, of the role session. The value can range from 900 |
|
| 950 |
+ // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set |
|
| 951 |
+ // to 3600 seconds. |
|
| 952 |
+ // |
|
| 953 |
+ // This is separate from the duration of a console session that you might request |
|
| 954 |
+ // using the returned credentials. The request to the federation endpoint for |
|
| 955 |
+ // a console sign-in token takes a SessionDuration parameter that specifies |
|
| 956 |
+ // the maximum length of the console session, separately from the DurationSeconds |
|
| 957 |
+ // parameter on this API. For more information, see Creating a URL that Enables |
|
| 958 |
+ // Federated Users to Access the AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) |
|
| 959 |
+ // in the IAM User Guide. |
|
| 960 |
+ DurationSeconds *int64 `min:"900" type:"integer"` |
|
| 961 |
+ |
|
| 962 |
+ // A unique identifier that is used by third parties when assuming roles in |
|
| 963 |
+ // their customers' accounts. For each role that the third party can assume, |
|
| 964 |
+ // they should instruct their customers to ensure the role's trust policy checks |
|
| 965 |
+ // for the external ID that the third party generated. Each time the third party |
|
| 966 |
+ // assumes the role, they should pass the customer's external ID. The external |
|
| 967 |
+ // ID is useful in order to help third parties bind a role to the customer who |
|
| 968 |
+ // created it. For more information about the external ID, see How to Use an |
|
| 969 |
+ // External ID When Granting Access to Your AWS Resources to a Third Party (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) |
|
| 970 |
+ // in the IAM User Guide. |
|
| 971 |
+ // |
|
| 972 |
+ // The format for this parameter, as described by its regex pattern, is a string |
|
| 973 |
+ // of characters consisting of upper- and lower-case alphanumeric characters |
|
| 974 |
+ // with no spaces. You can also include underscores or any of the following |
|
| 975 |
+ // characters: =,.@:\/- |
|
| 976 |
+ ExternalId *string `min:"2" type:"string"` |
|
| 977 |
+ |
|
| 978 |
+ // An IAM policy in JSON format. |
|
| 979 |
+ // |
|
| 980 |
+ // This parameter is optional. If you pass a policy, the temporary security |
|
| 981 |
+ // credentials that are returned by the operation have the permissions that |
|
| 982 |
+ // are allowed by both (the intersection of) the access policy of the role that |
|
| 983 |
+ // is being assumed, and the policy that you pass. This gives you a way to further |
|
| 984 |
+ // restrict the permissions for the resulting temporary security credentials. |
|
| 985 |
+ // You cannot use the passed policy to grant permissions that are in excess |
|
| 986 |
+ // of those allowed by the access policy of the role that is being assumed. |
|
| 987 |
+ // For more information, see Permissions for AssumeRole, AssumeRoleWithSAML, |
|
| 988 |
+ // and AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) |
|
| 989 |
+ // in the IAM User Guide. |
|
| 990 |
+ // |
|
| 991 |
+ // The format for this parameter, as described by its regex pattern, is a string |
|
| 992 |
+ // of characters up to 2048 characters in length. The characters can be any |
|
| 993 |
+ // ASCII character from the space character to the end of the valid character |
|
| 994 |
+ // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), |
|
| 995 |
+ // and carriage return (\u000D) characters. |
|
| 996 |
+ // |
|
| 997 |
+ // The policy plain text must be 2048 bytes or shorter. However, an internal |
|
| 998 |
+ // conversion compresses it into a packed binary format with a separate limit. |
|
| 999 |
+ // The PackedPolicySize response element indicates by percentage how close to |
|
| 1000 |
+ // the upper size limit the policy is, with 100% equaling the maximum allowed |
|
| 1001 |
+ // size. |
|
| 1002 |
+ Policy *string `min:"1" type:"string"` |
|
| 1003 |
+ |
|
| 1004 |
+ // The Amazon Resource Name (ARN) of the role to assume. |
|
| 1005 |
+ // |
|
| 1006 |
+ // RoleArn is a required field |
|
| 1007 |
+ RoleArn *string `min:"20" type:"string" required:"true"` |
|
| 1008 |
+ |
|
| 1009 |
+ // An identifier for the assumed role session. |
|
| 1010 |
+ // |
|
| 1011 |
+ // Use the role session name to uniquely identify a session when the same role |
|
| 1012 |
+ // is assumed by different principals or for different reasons. In cross-account |
|
| 1013 |
+ // scenarios, the role session name is visible to, and can be logged by the |
|
| 1014 |
+ // account that owns the role. The role session name is also used in the ARN |
|
| 1015 |
+ // of the assumed role principal. This means that subsequent cross-account API |
|
| 1016 |
+ // requests using the temporary security credentials will expose the role session |
|
| 1017 |
+ // name to the external account in their CloudTrail logs. |
|
| 1018 |
+ // |
|
| 1019 |
+ // The format for this parameter, as described by its regex pattern, is a string |
|
| 1020 |
+ // of characters consisting of upper- and lower-case alphanumeric characters |
|
| 1021 |
+ // with no spaces. You can also include underscores or any of the following |
|
| 1022 |
+ // characters: =,.@- |
|
| 1023 |
+ // |
|
| 1024 |
+ // RoleSessionName is a required field |
|
| 1025 |
+ RoleSessionName *string `min:"2" type:"string" required:"true"` |
|
| 1026 |
+ |
|
| 1027 |
+ // The identification number of the MFA device that is associated with the user |
|
| 1028 |
+ // who is making the AssumeRole call. Specify this value if the trust policy |
|
| 1029 |
+ // of the role being assumed includes a condition that requires MFA authentication. |
|
| 1030 |
+ // The value is either the serial number for a hardware device (such as GAHT12345678) |
|
| 1031 |
+ // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). |
|
| 1032 |
+ // |
|
| 1033 |
+ // The format for this parameter, as described by its regex pattern, is a string |
|
| 1034 |
+ // of characters consisting of upper- and lower-case alphanumeric characters |
|
| 1035 |
+ // with no spaces. You can also include underscores or any of the following |
|
| 1036 |
+ // characters: =,.@- |
|
| 1037 |
+ SerialNumber *string `min:"9" type:"string"` |
|
| 1038 |
+ |
|
| 1039 |
+ // The value provided by the MFA device, if the trust policy of the role being |
|
| 1040 |
+ // assumed requires MFA (that is, if the policy includes a condition that tests |
|
| 1041 |
+ // for MFA). If the role being assumed requires MFA and if the TokenCode value |
|
| 1042 |
+ // is missing or expired, the AssumeRole call returns an "access denied" error. |
|
| 1043 |
+ // |
|
| 1044 |
+ // The format for this parameter, as described by its regex pattern, is a sequence |
|
| 1045 |
+ // of six numeric digits. |
|
| 1046 |
+ TokenCode *string `min:"6" type:"string"` |
|
| 1047 |
+} |
|
| 1048 |
+ |
|
| 1049 |
+// String returns the string representation |
|
| 1050 |
+func (s AssumeRoleInput) String() string {
|
|
| 1051 |
+ return awsutil.Prettify(s) |
|
| 1052 |
+} |
|
| 1053 |
+ |
|
| 1054 |
+// GoString returns the string representation |
|
| 1055 |
+func (s AssumeRoleInput) GoString() string {
|
|
| 1056 |
+ return s.String() |
|
| 1057 |
+} |
|
| 1058 |
+ |
|
| 1059 |
+// Validate inspects the fields of the type to determine if they are valid. |
|
| 1060 |
+func (s *AssumeRoleInput) Validate() error {
|
|
| 1061 |
+ invalidParams := request.ErrInvalidParams{Context: "AssumeRoleInput"}
|
|
| 1062 |
+ if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
|
|
| 1063 |
+ invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
|
|
| 1064 |
+ } |
|
| 1065 |
+ if s.ExternalId != nil && len(*s.ExternalId) < 2 {
|
|
| 1066 |
+ invalidParams.Add(request.NewErrParamMinLen("ExternalId", 2))
|
|
| 1067 |
+ } |
|
| 1068 |
+ if s.Policy != nil && len(*s.Policy) < 1 {
|
|
| 1069 |
+ invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
|
|
| 1070 |
+ } |
|
| 1071 |
+ if s.RoleArn == nil {
|
|
| 1072 |
+ invalidParams.Add(request.NewErrParamRequired("RoleArn"))
|
|
| 1073 |
+ } |
|
| 1074 |
+ if s.RoleArn != nil && len(*s.RoleArn) < 20 {
|
|
| 1075 |
+ invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20))
|
|
| 1076 |
+ } |
|
| 1077 |
+ if s.RoleSessionName == nil {
|
|
| 1078 |
+ invalidParams.Add(request.NewErrParamRequired("RoleSessionName"))
|
|
| 1079 |
+ } |
|
| 1080 |
+ if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 {
|
|
| 1081 |
+ invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2))
|
|
| 1082 |
+ } |
|
| 1083 |
+ if s.SerialNumber != nil && len(*s.SerialNumber) < 9 {
|
|
| 1084 |
+ invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9))
|
|
| 1085 |
+ } |
|
| 1086 |
+ if s.TokenCode != nil && len(*s.TokenCode) < 6 {
|
|
| 1087 |
+ invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6))
|
|
| 1088 |
+ } |
|
| 1089 |
+ |
|
| 1090 |
+ if invalidParams.Len() > 0 {
|
|
| 1091 |
+ return invalidParams |
|
| 1092 |
+ } |
|
| 1093 |
+ return nil |
|
| 1094 |
+} |
|
| 1095 |
+ |
|
| 1096 |
+// Contains the response to a successful AssumeRole request, including temporary |
|
| 1097 |
+// AWS credentials that can be used to make AWS requests. |
|
| 1098 |
+type AssumeRoleOutput struct {
|
|
| 1099 |
+ _ struct{} `type:"structure"`
|
|
| 1100 |
+ |
|
| 1101 |
+ // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers |
|
| 1102 |
+ // that you can use to refer to the resulting temporary security credentials. |
|
| 1103 |
+ // For example, you can reference these credentials as a principal in a resource-based |
|
| 1104 |
+ // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName |
|
| 1105 |
+ // that you specified when you called AssumeRole. |
|
| 1106 |
+ AssumedRoleUser *AssumedRoleUser `type:"structure"` |
|
| 1107 |
+ |
|
| 1108 |
+ // The temporary security credentials, which include an access key ID, a secret |
|
| 1109 |
+ // access key, and a security (or session) token. |
|
| 1110 |
+ // |
|
| 1111 |
+ // Note: The size of the security token that STS APIs return is not fixed. We |
|
| 1112 |
+ // strongly recommend that you make no assumptions about the maximum size. As |
|
| 1113 |
+ // of this writing, the typical size is less than 4096 bytes, but that can vary. |
|
| 1114 |
+ // Also, future updates to AWS might require larger sizes. |
|
| 1115 |
+ Credentials *Credentials `type:"structure"` |
|
| 1116 |
+ |
|
| 1117 |
+ // A percentage value that indicates the size of the policy in packed form. |
|
| 1118 |
+ // The service rejects any policy with a packed size greater than 100 percent, |
|
| 1119 |
+ // which means the policy exceeded the allowed space. |
|
| 1120 |
+ PackedPolicySize *int64 `type:"integer"` |
|
| 1121 |
+} |
|
| 1122 |
+ |
|
| 1123 |
+// String returns the string representation |
|
| 1124 |
+func (s AssumeRoleOutput) String() string {
|
|
| 1125 |
+ return awsutil.Prettify(s) |
|
| 1126 |
+} |
|
| 1127 |
+ |
|
| 1128 |
+// GoString returns the string representation |
|
| 1129 |
+func (s AssumeRoleOutput) GoString() string {
|
|
| 1130 |
+ return s.String() |
|
| 1131 |
+} |
|
| 1132 |
+ |
|
| 1133 |
+type AssumeRoleWithSAMLInput struct {
|
|
| 1134 |
+ _ struct{} `type:"structure"`
|
|
| 1135 |
+ |
|
| 1136 |
+ // The duration, in seconds, of the role session. The value can range from 900 |
|
| 1137 |
+ // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set |
|
| 1138 |
+ // to 3600 seconds. An expiration can also be specified in the SAML authentication |
|
| 1139 |
+ // response's SessionNotOnOrAfter value. The actual expiration time is whichever |
|
| 1140 |
+ // value is shorter. |
|
| 1141 |
+ // |
|
| 1142 |
+ // This is separate from the duration of a console session that you might request |
|
| 1143 |
+ // using the returned credentials. The request to the federation endpoint for |
|
| 1144 |
+ // a console sign-in token takes a SessionDuration parameter that specifies |
|
| 1145 |
+ // the maximum length of the console session, separately from the DurationSeconds |
|
| 1146 |
+ // parameter on this API. For more information, see Enabling SAML 2.0 Federated |
|
| 1147 |
+ // Users to Access the AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-saml.html) |
|
| 1148 |
+ // in the IAM User Guide. |
|
| 1149 |
+ DurationSeconds *int64 `min:"900" type:"integer"` |
|
| 1150 |
+ |
|
| 1151 |
+ // An IAM policy in JSON format. |
|
| 1152 |
+ // |
|
| 1153 |
+ // The policy parameter is optional. If you pass a policy, the temporary security |
|
| 1154 |
+ // credentials that are returned by the operation have the permissions that |
|
| 1155 |
+ // are allowed by both the access policy of the role that is being assumed, |
|
| 1156 |
+ // and the policy that you pass. This gives you a way to further restrict the |
|
| 1157 |
+ // permissions for the resulting temporary security credentials. You cannot |
|
| 1158 |
+ // use the passed policy to grant permissions that are in excess of those allowed |
|
| 1159 |
+ // by the access policy of the role that is being assumed. For more information, |
|
| 1160 |
+ // Permissions for AssumeRole, AssumeRoleWithSAML, and AssumeRoleWithWebIdentity |
|
| 1161 |
+ // (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) |
|
| 1162 |
+ // in the IAM User Guide. |
|
| 1163 |
+ // |
|
| 1164 |
+ // The format for this parameter, as described by its regex pattern, is a string |
|
| 1165 |
+ // of characters up to 2048 characters in length. The characters can be any |
|
| 1166 |
+ // ASCII character from the space character to the end of the valid character |
|
| 1167 |
+ // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), |
|
| 1168 |
+ // and carriage return (\u000D) characters. |
|
| 1169 |
+ // |
|
| 1170 |
+ // The policy plain text must be 2048 bytes or shorter. However, an internal |
|
| 1171 |
+ // conversion compresses it into a packed binary format with a separate limit. |
|
| 1172 |
+ // The PackedPolicySize response element indicates by percentage how close to |
|
| 1173 |
+ // the upper size limit the policy is, with 100% equaling the maximum allowed |
|
| 1174 |
+ // size. |
|
| 1175 |
+ Policy *string `min:"1" type:"string"` |
|
| 1176 |
+ |
|
| 1177 |
+ // The Amazon Resource Name (ARN) of the SAML provider in IAM that describes |
|
| 1178 |
+ // the IdP. |
|
| 1179 |
+ // |
|
| 1180 |
+ // PrincipalArn is a required field |
|
| 1181 |
+ PrincipalArn *string `min:"20" type:"string" required:"true"` |
|
| 1182 |
+ |
|
| 1183 |
+ // The Amazon Resource Name (ARN) of the role that the caller is assuming. |
|
| 1184 |
+ // |
|
| 1185 |
+ // RoleArn is a required field |
|
| 1186 |
+ RoleArn *string `min:"20" type:"string" required:"true"` |
|
| 1187 |
+ |
|
| 1188 |
+ // The base-64 encoded SAML authentication response provided by the IdP. |
|
| 1189 |
+ // |
|
| 1190 |
+ // For more information, see Configuring a Relying Party and Adding Claims (http://docs.aws.amazon.com/IAM/latest/UserGuide/create-role-saml-IdP-tasks.html) |
|
| 1191 |
+ // in the Using IAM guide. |
|
| 1192 |
+ // |
|
| 1193 |
+ // SAMLAssertion is a required field |
|
| 1194 |
+ SAMLAssertion *string `min:"4" type:"string" required:"true"` |
|
| 1195 |
+} |
|
| 1196 |
+ |
|
| 1197 |
+// String returns the string representation |
|
| 1198 |
+func (s AssumeRoleWithSAMLInput) String() string {
|
|
| 1199 |
+ return awsutil.Prettify(s) |
|
| 1200 |
+} |
|
| 1201 |
+ |
|
| 1202 |
+// GoString returns the string representation |
|
| 1203 |
+func (s AssumeRoleWithSAMLInput) GoString() string {
|
|
| 1204 |
+ return s.String() |
|
| 1205 |
+} |
|
| 1206 |
+ |
|
| 1207 |
+// Validate inspects the fields of the type to determine if they are valid. |
|
| 1208 |
+func (s *AssumeRoleWithSAMLInput) Validate() error {
|
|
| 1209 |
+ invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithSAMLInput"}
|
|
| 1210 |
+ if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
|
|
| 1211 |
+ invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
|
|
| 1212 |
+ } |
|
| 1213 |
+ if s.Policy != nil && len(*s.Policy) < 1 {
|
|
| 1214 |
+ invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
|
|
| 1215 |
+ } |
|
| 1216 |
+ if s.PrincipalArn == nil {
|
|
| 1217 |
+ invalidParams.Add(request.NewErrParamRequired("PrincipalArn"))
|
|
| 1218 |
+ } |
|
| 1219 |
+ if s.PrincipalArn != nil && len(*s.PrincipalArn) < 20 {
|
|
| 1220 |
+ invalidParams.Add(request.NewErrParamMinLen("PrincipalArn", 20))
|
|
| 1221 |
+ } |
|
| 1222 |
+ if s.RoleArn == nil {
|
|
| 1223 |
+ invalidParams.Add(request.NewErrParamRequired("RoleArn"))
|
|
| 1224 |
+ } |
|
| 1225 |
+ if s.RoleArn != nil && len(*s.RoleArn) < 20 {
|
|
| 1226 |
+ invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20))
|
|
| 1227 |
+ } |
|
| 1228 |
+ if s.SAMLAssertion == nil {
|
|
| 1229 |
+ invalidParams.Add(request.NewErrParamRequired("SAMLAssertion"))
|
|
| 1230 |
+ } |
|
| 1231 |
+ if s.SAMLAssertion != nil && len(*s.SAMLAssertion) < 4 {
|
|
| 1232 |
+ invalidParams.Add(request.NewErrParamMinLen("SAMLAssertion", 4))
|
|
| 1233 |
+ } |
|
| 1234 |
+ |
|
| 1235 |
+ if invalidParams.Len() > 0 {
|
|
| 1236 |
+ return invalidParams |
|
| 1237 |
+ } |
|
| 1238 |
+ return nil |
|
| 1239 |
+} |
|
| 1240 |
+ |
|
| 1241 |
+// Contains the response to a successful AssumeRoleWithSAML request, including |
|
| 1242 |
+// temporary AWS credentials that can be used to make AWS requests. |
|
| 1243 |
+type AssumeRoleWithSAMLOutput struct {
|
|
| 1244 |
+ _ struct{} `type:"structure"`
|
|
| 1245 |
+ |
|
| 1246 |
+ // The identifiers for the temporary security credentials that the operation |
|
| 1247 |
+ // returns. |
|
| 1248 |
+ AssumedRoleUser *AssumedRoleUser `type:"structure"` |
|
| 1249 |
+ |
|
| 1250 |
+ // The value of the Recipient attribute of the SubjectConfirmationData element |
|
| 1251 |
+ // of the SAML assertion. |
|
| 1252 |
+ Audience *string `type:"string"` |
|
| 1253 |
+ |
|
| 1254 |
+ // The temporary security credentials, which include an access key ID, a secret |
|
| 1255 |
+ // access key, and a security (or session) token. |
|
| 1256 |
+ // |
|
| 1257 |
+ // Note: The size of the security token that STS APIs return is not fixed. We |
|
| 1258 |
+ // strongly recommend that you make no assumptions about the maximum size. As |
|
| 1259 |
+ // of this writing, the typical size is less than 4096 bytes, but that can vary. |
|
| 1260 |
+ // Also, future updates to AWS might require larger sizes. |
|
| 1261 |
+ Credentials *Credentials `type:"structure"` |
|
| 1262 |
+ |
|
| 1263 |
+ // The value of the Issuer element of the SAML assertion. |
|
| 1264 |
+ Issuer *string `type:"string"` |
|
| 1265 |
+ |
|
| 1266 |
+ // A hash value based on the concatenation of the Issuer response value, the |
|
| 1267 |
+ // AWS account ID, and the friendly name (the last part of the ARN) of the SAML |
|
| 1268 |
+ // provider in IAM. The combination of NameQualifier and Subject can be used |
|
| 1269 |
+ // to uniquely identify a federated user. |
|
| 1270 |
+ // |
|
| 1271 |
+ // The following pseudocode shows how the hash value is calculated: |
|
| 1272 |
+ // |
|
| 1273 |
+ // BASE64 ( SHA1 ( "https://example.com/saml" + "123456789012" + "/MySAMLIdP" |
|
| 1274 |
+ // ) ) |
|
| 1275 |
+ NameQualifier *string `type:"string"` |
|
| 1276 |
+ |
|
| 1277 |
+ // A percentage value that indicates the size of the policy in packed form. |
|
| 1278 |
+ // The service rejects any policy with a packed size greater than 100 percent, |
|
| 1279 |
+ // which means the policy exceeded the allowed space. |
|
| 1280 |
+ PackedPolicySize *int64 `type:"integer"` |
|
| 1281 |
+ |
|
| 1282 |
+ // The value of the NameID element in the Subject element of the SAML assertion. |
|
| 1283 |
+ Subject *string `type:"string"` |
|
| 1284 |
+ |
|
| 1285 |
+ // The format of the name ID, as defined by the Format attribute in the NameID |
|
| 1286 |
+ // element of the SAML assertion. Typical examples of the format are transient |
|
| 1287 |
+ // or persistent. |
|
| 1288 |
+ // |
|
| 1289 |
+ // If the format includes the prefix urn:oasis:names:tc:SAML:2.0:nameid-format, |
|
| 1290 |
+ // that prefix is removed. For example, urn:oasis:names:tc:SAML:2.0:nameid-format:transient |
|
| 1291 |
+ // is returned as transient. If the format includes any other prefix, the format |
|
| 1292 |
+ // is returned with no modifications. |
|
| 1293 |
+ SubjectType *string `type:"string"` |
|
| 1294 |
+} |
|
| 1295 |
+ |
|
| 1296 |
+// String returns the string representation |
|
| 1297 |
+func (s AssumeRoleWithSAMLOutput) String() string {
|
|
| 1298 |
+ return awsutil.Prettify(s) |
|
| 1299 |
+} |
|
| 1300 |
+ |
|
| 1301 |
+// GoString returns the string representation |
|
| 1302 |
+func (s AssumeRoleWithSAMLOutput) GoString() string {
|
|
| 1303 |
+ return s.String() |
|
| 1304 |
+} |
|
| 1305 |
+ |
|
| 1306 |
+type AssumeRoleWithWebIdentityInput struct {
|
|
| 1307 |
+ _ struct{} `type:"structure"`
|
|
| 1308 |
+ |
|
| 1309 |
+ // The duration, in seconds, of the role session. The value can range from 900 |
|
| 1310 |
+ // seconds (15 minutes) to 3600 seconds (1 hour). By default, the value is set |
|
| 1311 |
+ // to 3600 seconds. |
|
| 1312 |
+ // |
|
| 1313 |
+ // This is separate from the duration of a console session that you might request |
|
| 1314 |
+ // using the returned credentials. The request to the federation endpoint for |
|
| 1315 |
+ // a console sign-in token takes a SessionDuration parameter that specifies |
|
| 1316 |
+ // the maximum length of the console session, separately from the DurationSeconds |
|
| 1317 |
+ // parameter on this API. For more information, see Creating a URL that Enables |
|
| 1318 |
+ // Federated Users to Access the AWS Management Console (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) |
|
| 1319 |
+ // in the IAM User Guide. |
|
| 1320 |
+ DurationSeconds *int64 `min:"900" type:"integer"` |
|
| 1321 |
+ |
|
| 1322 |
+ // An IAM policy in JSON format. |
|
| 1323 |
+ // |
|
| 1324 |
+ // The policy parameter is optional. If you pass a policy, the temporary security |
|
| 1325 |
+ // credentials that are returned by the operation have the permissions that |
|
| 1326 |
+ // are allowed by both the access policy of the role that is being assumed, |
|
| 1327 |
+ // and the policy that you pass. This gives you a way to further restrict the |
|
| 1328 |
+ // permissions for the resulting temporary security credentials. You cannot |
|
| 1329 |
+ // use the passed policy to grant permissions that are in excess of those allowed |
|
| 1330 |
+ // by the access policy of the role that is being assumed. For more information, |
|
| 1331 |
+ // see Permissions for AssumeRoleWithWebIdentity (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_assumerole.html) |
|
| 1332 |
+ // in the IAM User Guide. |
|
| 1333 |
+ // |
|
| 1334 |
+ // The format for this parameter, as described by its regex pattern, is a string |
|
| 1335 |
+ // of characters up to 2048 characters in length. The characters can be any |
|
| 1336 |
+ // ASCII character from the space character to the end of the valid character |
|
| 1337 |
+ // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), |
|
| 1338 |
+ // and carriage return (\u000D) characters. |
|
| 1339 |
+ // |
|
| 1340 |
+ // The policy plain text must be 2048 bytes or shorter. However, an internal |
|
| 1341 |
+ // conversion compresses it into a packed binary format with a separate limit. |
|
| 1342 |
+ // The PackedPolicySize response element indicates by percentage how close to |
|
| 1343 |
+ // the upper size limit the policy is, with 100% equaling the maximum allowed |
|
| 1344 |
+ // size. |
|
| 1345 |
+ Policy *string `min:"1" type:"string"` |
|
| 1346 |
+ |
|
| 1347 |
+ // The fully qualified host component of the domain name of the identity provider. |
|
| 1348 |
+ // |
|
| 1349 |
+ // Specify this value only for OAuth 2.0 access tokens. Currently www.amazon.com |
|
| 1350 |
+ // and graph.facebook.com are the only supported identity providers for OAuth |
|
| 1351 |
+ // 2.0 access tokens. Do not include URL schemes and port numbers. |
|
| 1352 |
+ // |
|
| 1353 |
+ // Do not specify this value for OpenID Connect ID tokens. |
|
| 1354 |
+ ProviderId *string `min:"4" type:"string"` |
|
| 1355 |
+ |
|
| 1356 |
+ // The Amazon Resource Name (ARN) of the role that the caller is assuming. |
|
| 1357 |
+ // |
|
| 1358 |
+ // RoleArn is a required field |
|
| 1359 |
+ RoleArn *string `min:"20" type:"string" required:"true"` |
|
| 1360 |
+ |
|
| 1361 |
+ // An identifier for the assumed role session. Typically, you pass the name |
|
| 1362 |
+ // or identifier that is associated with the user who is using your application. |
|
| 1363 |
+ // That way, the temporary security credentials that your application will use |
|
| 1364 |
+ // are associated with that user. This session name is included as part of the |
|
| 1365 |
+ // ARN and assumed role ID in the AssumedRoleUser response element. |
|
| 1366 |
+ // |
|
| 1367 |
+ // The format for this parameter, as described by its regex pattern, is a string |
|
| 1368 |
+ // of characters consisting of upper- and lower-case alphanumeric characters |
|
| 1369 |
+ // with no spaces. You can also include underscores or any of the following |
|
| 1370 |
+ // characters: =,.@- |
|
| 1371 |
+ // |
|
| 1372 |
+ // RoleSessionName is a required field |
|
| 1373 |
+ RoleSessionName *string `min:"2" type:"string" required:"true"` |
|
| 1374 |
+ |
|
| 1375 |
+ // The OAuth 2.0 access token or OpenID Connect ID token that is provided by |
|
| 1376 |
+ // the identity provider. Your application must get this token by authenticating |
|
| 1377 |
+ // the user who is using your application with a web identity provider before |
|
| 1378 |
+ // the application makes an AssumeRoleWithWebIdentity call. |
|
| 1379 |
+ // |
|
| 1380 |
+ // WebIdentityToken is a required field |
|
| 1381 |
+ WebIdentityToken *string `min:"4" type:"string" required:"true"` |
|
| 1382 |
+} |
|
| 1383 |
+ |
|
| 1384 |
+// String returns the string representation |
|
| 1385 |
+func (s AssumeRoleWithWebIdentityInput) String() string {
|
|
| 1386 |
+ return awsutil.Prettify(s) |
|
| 1387 |
+} |
|
| 1388 |
+ |
|
| 1389 |
+// GoString returns the string representation |
|
| 1390 |
+func (s AssumeRoleWithWebIdentityInput) GoString() string {
|
|
| 1391 |
+ return s.String() |
|
| 1392 |
+} |
|
| 1393 |
+ |
|
| 1394 |
+// Validate inspects the fields of the type to determine if they are valid. |
|
| 1395 |
+func (s *AssumeRoleWithWebIdentityInput) Validate() error {
|
|
| 1396 |
+ invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithWebIdentityInput"}
|
|
| 1397 |
+ if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
|
|
| 1398 |
+ invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
|
|
| 1399 |
+ } |
|
| 1400 |
+ if s.Policy != nil && len(*s.Policy) < 1 {
|
|
| 1401 |
+ invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
|
|
| 1402 |
+ } |
|
| 1403 |
+ if s.ProviderId != nil && len(*s.ProviderId) < 4 {
|
|
| 1404 |
+ invalidParams.Add(request.NewErrParamMinLen("ProviderId", 4))
|
|
| 1405 |
+ } |
|
| 1406 |
+ if s.RoleArn == nil {
|
|
| 1407 |
+ invalidParams.Add(request.NewErrParamRequired("RoleArn"))
|
|
| 1408 |
+ } |
|
| 1409 |
+ if s.RoleArn != nil && len(*s.RoleArn) < 20 {
|
|
| 1410 |
+ invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20))
|
|
| 1411 |
+ } |
|
| 1412 |
+ if s.RoleSessionName == nil {
|
|
| 1413 |
+ invalidParams.Add(request.NewErrParamRequired("RoleSessionName"))
|
|
| 1414 |
+ } |
|
| 1415 |
+ if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 {
|
|
| 1416 |
+ invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2))
|
|
| 1417 |
+ } |
|
| 1418 |
+ if s.WebIdentityToken == nil {
|
|
| 1419 |
+ invalidParams.Add(request.NewErrParamRequired("WebIdentityToken"))
|
|
| 1420 |
+ } |
|
| 1421 |
+ if s.WebIdentityToken != nil && len(*s.WebIdentityToken) < 4 {
|
|
| 1422 |
+ invalidParams.Add(request.NewErrParamMinLen("WebIdentityToken", 4))
|
|
| 1423 |
+ } |
|
| 1424 |
+ |
|
| 1425 |
+ if invalidParams.Len() > 0 {
|
|
| 1426 |
+ return invalidParams |
|
| 1427 |
+ } |
|
| 1428 |
+ return nil |
|
| 1429 |
+} |
|
| 1430 |
+ |
|
| 1431 |
+// Contains the response to a successful AssumeRoleWithWebIdentity request, |
|
| 1432 |
+// including temporary AWS credentials that can be used to make AWS requests. |
|
| 1433 |
+type AssumeRoleWithWebIdentityOutput struct {
|
|
| 1434 |
+ _ struct{} `type:"structure"`
|
|
| 1435 |
+ |
|
| 1436 |
+ // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers |
|
| 1437 |
+ // that you can use to refer to the resulting temporary security credentials. |
|
| 1438 |
+ // For example, you can reference these credentials as a principal in a resource-based |
|
| 1439 |
+ // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName |
|
| 1440 |
+ // that you specified when you called AssumeRole. |
|
| 1441 |
+ AssumedRoleUser *AssumedRoleUser `type:"structure"` |
|
| 1442 |
+ |
|
| 1443 |
+ // The intended audience (also known as client ID) of the web identity token. |
|
| 1444 |
+ // This is traditionally the client identifier issued to the application that |
|
| 1445 |
+ // requested the web identity token. |
|
| 1446 |
+ Audience *string `type:"string"` |
|
| 1447 |
+ |
|
| 1448 |
+ // The temporary security credentials, which include an access key ID, a secret |
|
| 1449 |
+ // access key, and a security token. |
|
| 1450 |
+ // |
|
| 1451 |
+ // Note: The size of the security token that STS APIs return is not fixed. We |
|
| 1452 |
+ // strongly recommend that you make no assumptions about the maximum size. As |
|
| 1453 |
+ // of this writing, the typical size is less than 4096 bytes, but that can vary. |
|
| 1454 |
+ // Also, future updates to AWS might require larger sizes. |
|
| 1455 |
+ Credentials *Credentials `type:"structure"` |
|
| 1456 |
+ |
|
| 1457 |
+ // A percentage value that indicates the size of the policy in packed form. |
|
| 1458 |
+ // The service rejects any policy with a packed size greater than 100 percent, |
|
| 1459 |
+ // which means the policy exceeded the allowed space. |
|
| 1460 |
+ PackedPolicySize *int64 `type:"integer"` |
|
| 1461 |
+ |
|
| 1462 |
+ // The issuing authority of the web identity token presented. For OpenID Connect |
|
| 1463 |
+ // ID Tokens this contains the value of the iss field. For OAuth 2.0 access |
|
| 1464 |
+ // tokens, this contains the value of the ProviderId parameter that was passed |
|
| 1465 |
+ // in the AssumeRoleWithWebIdentity request. |
|
| 1466 |
+ Provider *string `type:"string"` |
|
| 1467 |
+ |
|
| 1468 |
+ // The unique user identifier that is returned by the identity provider. This |
|
| 1469 |
+ // identifier is associated with the WebIdentityToken that was submitted with |
|
| 1470 |
+ // the AssumeRoleWithWebIdentity call. The identifier is typically unique to |
|
| 1471 |
+ // the user and the application that acquired the WebIdentityToken (pairwise |
|
| 1472 |
+ // identifier). For OpenID Connect ID tokens, this field contains the value |
|
| 1473 |
+ // returned by the identity provider as the token's sub (Subject) claim. |
|
| 1474 |
+ SubjectFromWebIdentityToken *string `min:"6" type:"string"` |
|
| 1475 |
+} |
|
| 1476 |
+ |
|
| 1477 |
+// String returns the string representation |
|
| 1478 |
+func (s AssumeRoleWithWebIdentityOutput) String() string {
|
|
| 1479 |
+ return awsutil.Prettify(s) |
|
| 1480 |
+} |
|
| 1481 |
+ |
|
| 1482 |
+// GoString returns the string representation |
|
| 1483 |
+func (s AssumeRoleWithWebIdentityOutput) GoString() string {
|
|
| 1484 |
+ return s.String() |
|
| 1485 |
+} |
|
| 1486 |
+ |
|
| 1487 |
+// The identifiers for the temporary security credentials that the operation |
|
| 1488 |
+// returns. |
|
| 1489 |
+type AssumedRoleUser struct {
|
|
| 1490 |
+ _ struct{} `type:"structure"`
|
|
| 1491 |
+ |
|
| 1492 |
+ // The ARN of the temporary security credentials that are returned from the |
|
| 1493 |
+ // AssumeRole action. For more information about ARNs and how to use them in |
|
| 1494 |
+ // policies, see IAM Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) |
|
| 1495 |
+ // in Using IAM. |
|
| 1496 |
+ // |
|
| 1497 |
+ // Arn is a required field |
|
| 1498 |
+ Arn *string `min:"20" type:"string" required:"true"` |
|
| 1499 |
+ |
|
| 1500 |
+ // A unique identifier that contains the role ID and the role session name of |
|
| 1501 |
+ // the role that is being assumed. The role ID is generated by AWS when the |
|
| 1502 |
+ // role is created. |
|
| 1503 |
+ // |
|
| 1504 |
+ // AssumedRoleId is a required field |
|
| 1505 |
+ AssumedRoleId *string `min:"2" type:"string" required:"true"` |
|
| 1506 |
+} |
|
| 1507 |
+ |
|
| 1508 |
+// String returns the string representation |
|
| 1509 |
+func (s AssumedRoleUser) String() string {
|
|
| 1510 |
+ return awsutil.Prettify(s) |
|
| 1511 |
+} |
|
| 1512 |
+ |
|
| 1513 |
+// GoString returns the string representation |
|
| 1514 |
+func (s AssumedRoleUser) GoString() string {
|
|
| 1515 |
+ return s.String() |
|
| 1516 |
+} |
|
| 1517 |
+ |
|
| 1518 |
+// AWS credentials for API authentication. |
|
| 1519 |
+type Credentials struct {
|
|
| 1520 |
+ _ struct{} `type:"structure"`
|
|
| 1521 |
+ |
|
| 1522 |
+ // The access key ID that identifies the temporary security credentials. |
|
| 1523 |
+ // |
|
| 1524 |
+ // AccessKeyId is a required field |
|
| 1525 |
+ AccessKeyId *string `min:"16" type:"string" required:"true"` |
|
| 1526 |
+ |
|
| 1527 |
+ // The date on which the current credentials expire. |
|
| 1528 |
+ // |
|
| 1529 |
+ // Expiration is a required field |
|
| 1530 |
+ Expiration *time.Time `type:"timestamp" timestampFormat:"iso8601" required:"true"` |
|
| 1531 |
+ |
|
| 1532 |
+ // The secret access key that can be used to sign requests. |
|
| 1533 |
+ // |
|
| 1534 |
+ // SecretAccessKey is a required field |
|
| 1535 |
+ SecretAccessKey *string `type:"string" required:"true"` |
|
| 1536 |
+ |
|
| 1537 |
+ // The token that users must pass to the service API to use the temporary credentials. |
|
| 1538 |
+ // |
|
| 1539 |
+ // SessionToken is a required field |
|
| 1540 |
+ SessionToken *string `type:"string" required:"true"` |
|
| 1541 |
+} |
|
| 1542 |
+ |
|
| 1543 |
+// String returns the string representation |
|
| 1544 |
+func (s Credentials) String() string {
|
|
| 1545 |
+ return awsutil.Prettify(s) |
|
| 1546 |
+} |
|
| 1547 |
+ |
|
| 1548 |
+// GoString returns the string representation |
|
| 1549 |
+func (s Credentials) GoString() string {
|
|
| 1550 |
+ return s.String() |
|
| 1551 |
+} |
|
| 1552 |
+ |
|
| 1553 |
+type DecodeAuthorizationMessageInput struct {
|
|
| 1554 |
+ _ struct{} `type:"structure"`
|
|
| 1555 |
+ |
|
| 1556 |
+ // The encoded message that was returned with the response. |
|
| 1557 |
+ // |
|
| 1558 |
+ // EncodedMessage is a required field |
|
| 1559 |
+ EncodedMessage *string `min:"1" type:"string" required:"true"` |
|
| 1560 |
+} |
|
| 1561 |
+ |
|
| 1562 |
+// String returns the string representation |
|
| 1563 |
+func (s DecodeAuthorizationMessageInput) String() string {
|
|
| 1564 |
+ return awsutil.Prettify(s) |
|
| 1565 |
+} |
|
| 1566 |
+ |
|
| 1567 |
+// GoString returns the string representation |
|
| 1568 |
+func (s DecodeAuthorizationMessageInput) GoString() string {
|
|
| 1569 |
+ return s.String() |
|
| 1570 |
+} |
|
| 1571 |
+ |
|
| 1572 |
+// Validate inspects the fields of the type to determine if they are valid. |
|
| 1573 |
+func (s *DecodeAuthorizationMessageInput) Validate() error {
|
|
| 1574 |
+ invalidParams := request.ErrInvalidParams{Context: "DecodeAuthorizationMessageInput"}
|
|
| 1575 |
+ if s.EncodedMessage == nil {
|
|
| 1576 |
+ invalidParams.Add(request.NewErrParamRequired("EncodedMessage"))
|
|
| 1577 |
+ } |
|
| 1578 |
+ if s.EncodedMessage != nil && len(*s.EncodedMessage) < 1 {
|
|
| 1579 |
+ invalidParams.Add(request.NewErrParamMinLen("EncodedMessage", 1))
|
|
| 1580 |
+ } |
|
| 1581 |
+ |
|
| 1582 |
+ if invalidParams.Len() > 0 {
|
|
| 1583 |
+ return invalidParams |
|
| 1584 |
+ } |
|
| 1585 |
+ return nil |
|
| 1586 |
+} |
|
| 1587 |
+ |
|
| 1588 |
+// A document that contains additional information about the authorization status |
|
| 1589 |
+// of a request from an encoded message that is returned in response to an AWS |
|
| 1590 |
+// request. |
|
| 1591 |
+type DecodeAuthorizationMessageOutput struct {
|
|
| 1592 |
+ _ struct{} `type:"structure"`
|
|
| 1593 |
+ |
|
| 1594 |
+ // An XML document that contains the decoded message. |
|
| 1595 |
+ DecodedMessage *string `type:"string"` |
|
| 1596 |
+} |
|
| 1597 |
+ |
|
| 1598 |
+// String returns the string representation |
|
| 1599 |
+func (s DecodeAuthorizationMessageOutput) String() string {
|
|
| 1600 |
+ return awsutil.Prettify(s) |
|
| 1601 |
+} |
|
| 1602 |
+ |
|
| 1603 |
+// GoString returns the string representation |
|
| 1604 |
+func (s DecodeAuthorizationMessageOutput) GoString() string {
|
|
| 1605 |
+ return s.String() |
|
| 1606 |
+} |
|
| 1607 |
+ |
|
| 1608 |
+// Identifiers for the federated user that is associated with the credentials. |
|
| 1609 |
+type FederatedUser struct {
|
|
| 1610 |
+ _ struct{} `type:"structure"`
|
|
| 1611 |
+ |
|
| 1612 |
+ // The ARN that specifies the federated user that is associated with the credentials. |
|
| 1613 |
+ // For more information about ARNs and how to use them in policies, see IAM |
|
| 1614 |
+ // Identifiers (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) |
|
| 1615 |
+ // in Using IAM. |
|
| 1616 |
+ // |
|
| 1617 |
+ // Arn is a required field |
|
| 1618 |
+ Arn *string `min:"20" type:"string" required:"true"` |
|
| 1619 |
+ |
|
| 1620 |
+ // The string that identifies the federated user associated with the credentials, |
|
| 1621 |
+ // similar to the unique ID of an IAM user. |
|
| 1622 |
+ // |
|
| 1623 |
+ // FederatedUserId is a required field |
|
| 1624 |
+ FederatedUserId *string `min:"2" type:"string" required:"true"` |
|
| 1625 |
+} |
|
| 1626 |
+ |
|
| 1627 |
+// String returns the string representation |
|
| 1628 |
+func (s FederatedUser) String() string {
|
|
| 1629 |
+ return awsutil.Prettify(s) |
|
| 1630 |
+} |
|
| 1631 |
+ |
|
| 1632 |
+// GoString returns the string representation |
|
| 1633 |
+func (s FederatedUser) GoString() string {
|
|
| 1634 |
+ return s.String() |
|
| 1635 |
+} |
|
| 1636 |
+ |
|
| 1637 |
+type GetCallerIdentityInput struct {
|
|
| 1638 |
+ _ struct{} `type:"structure"`
|
|
| 1639 |
+} |
|
| 1640 |
+ |
|
| 1641 |
+// String returns the string representation |
|
| 1642 |
+func (s GetCallerIdentityInput) String() string {
|
|
| 1643 |
+ return awsutil.Prettify(s) |
|
| 1644 |
+} |
|
| 1645 |
+ |
|
| 1646 |
+// GoString returns the string representation |
|
| 1647 |
+func (s GetCallerIdentityInput) GoString() string {
|
|
| 1648 |
+ return s.String() |
|
| 1649 |
+} |
|
| 1650 |
+ |
|
| 1651 |
+// Contains the response to a successful GetCallerIdentity request, including |
|
| 1652 |
+// information about the entity making the request. |
|
| 1653 |
+type GetCallerIdentityOutput struct {
|
|
| 1654 |
+ _ struct{} `type:"structure"`
|
|
| 1655 |
+ |
|
| 1656 |
+ // The AWS account ID number of the account that owns or contains the calling |
|
| 1657 |
+ // entity. |
|
| 1658 |
+ Account *string `type:"string"` |
|
| 1659 |
+ |
|
| 1660 |
+ // The AWS ARN associated with the calling entity. |
|
| 1661 |
+ Arn *string `min:"20" type:"string"` |
|
| 1662 |
+ |
|
| 1663 |
+ // The unique identifier of the calling entity. The exact value depends on the |
|
| 1664 |
+ // type of entity making the call. The values returned are those listed in the |
|
| 1665 |
+ // aws:userid column in the Principal table (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#principaltable) |
|
| 1666 |
+ // found on the Policy Variables reference page in the IAM User Guide. |
|
| 1667 |
+ UserId *string `type:"string"` |
|
| 1668 |
+} |
|
| 1669 |
+ |
|
| 1670 |
+// String returns the string representation |
|
| 1671 |
+func (s GetCallerIdentityOutput) String() string {
|
|
| 1672 |
+ return awsutil.Prettify(s) |
|
| 1673 |
+} |
|
| 1674 |
+ |
|
| 1675 |
+// GoString returns the string representation |
|
| 1676 |
+func (s GetCallerIdentityOutput) GoString() string {
|
|
| 1677 |
+ return s.String() |
|
| 1678 |
+} |
|
| 1679 |
+ |
|
| 1680 |
+type GetFederationTokenInput struct {
|
|
| 1681 |
+ _ struct{} `type:"structure"`
|
|
| 1682 |
+ |
|
| 1683 |
+ // The duration, in seconds, that the session should last. Acceptable durations |
|
| 1684 |
+ // for federation sessions range from 900 seconds (15 minutes) to 129600 seconds |
|
| 1685 |
+ // (36 hours), with 43200 seconds (12 hours) as the default. Sessions obtained |
|
| 1686 |
+ // using AWS account (root) credentials are restricted to a maximum of 3600 |
|
| 1687 |
+ // seconds (one hour). If the specified duration is longer than one hour, the |
|
| 1688 |
+ // session obtained by using AWS account (root) credentials defaults to one |
|
| 1689 |
+ // hour. |
|
| 1690 |
+ DurationSeconds *int64 `min:"900" type:"integer"` |
|
| 1691 |
+ |
|
| 1692 |
+ // The name of the federated user. The name is used as an identifier for the |
|
| 1693 |
+ // temporary security credentials (such as Bob). For example, you can reference |
|
| 1694 |
+ // the federated user name in a resource-based policy, such as in an Amazon |
|
| 1695 |
+ // S3 bucket policy. |
|
| 1696 |
+ // |
|
| 1697 |
+ // The format for this parameter, as described by its regex pattern, is a string |
|
| 1698 |
+ // of characters consisting of upper- and lower-case alphanumeric characters |
|
| 1699 |
+ // with no spaces. You can also include underscores or any of the following |
|
| 1700 |
+ // characters: =,.@- |
|
| 1701 |
+ // |
|
| 1702 |
+ // Name is a required field |
|
| 1703 |
+ Name *string `min:"2" type:"string" required:"true"` |
|
| 1704 |
+ |
|
| 1705 |
+ // An IAM policy in JSON format that is passed with the GetFederationToken call |
|
| 1706 |
+ // and evaluated along with the policy or policies that are attached to the |
|
| 1707 |
+ // IAM user whose credentials are used to call GetFederationToken. The passed |
|
| 1708 |
+ // policy is used to scope down the permissions that are available to the IAM |
|
| 1709 |
+ // user, by allowing only a subset of the permissions that are granted to the |
|
| 1710 |
+ // IAM user. The passed policy cannot grant more permissions than those granted |
|
| 1711 |
+ // to the IAM user. The final permissions for the federated user are the most |
|
| 1712 |
+ // restrictive set based on the intersection of the passed policy and the IAM |
|
| 1713 |
+ // user policy. |
|
| 1714 |
+ // |
|
| 1715 |
+ // If you do not pass a policy, the resulting temporary security credentials |
|
| 1716 |
+ // have no effective permissions. The only exception is when the temporary security |
|
| 1717 |
+ // credentials are used to access a resource that has a resource-based policy |
|
| 1718 |
+ // that specifically allows the federated user to access the resource. |
|
| 1719 |
+ // |
|
| 1720 |
+ // The format for this parameter, as described by its regex pattern, is a string |
|
| 1721 |
+ // of characters up to 2048 characters in length. The characters can be any |
|
| 1722 |
+ // ASCII character from the space character to the end of the valid character |
|
| 1723 |
+ // list (\u0020-\u00FF). It can also include the tab (\u0009), linefeed (\u000A), |
|
| 1724 |
+ // and carriage return (\u000D) characters. |
|
| 1725 |
+ // |
|
| 1726 |
+ // The policy plain text must be 2048 bytes or shorter. However, an internal |
|
| 1727 |
+ // conversion compresses it into a packed binary format with a separate limit. |
|
| 1728 |
+ // The PackedPolicySize response element indicates by percentage how close to |
|
| 1729 |
+ // the upper size limit the policy is, with 100% equaling the maximum allowed |
|
| 1730 |
+ // size. |
|
| 1731 |
+ // |
|
| 1732 |
+ // For more information about how permissions work, see Permissions for GetFederationToken |
|
| 1733 |
+ // (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_getfederationtoken.html). |
|
| 1734 |
+ Policy *string `min:"1" type:"string"` |
|
| 1735 |
+} |
|
| 1736 |
+ |
|
| 1737 |
+// String returns the string representation |
|
| 1738 |
+func (s GetFederationTokenInput) String() string {
|
|
| 1739 |
+ return awsutil.Prettify(s) |
|
| 1740 |
+} |
|
| 1741 |
+ |
|
| 1742 |
+// GoString returns the string representation |
|
| 1743 |
+func (s GetFederationTokenInput) GoString() string {
|
|
| 1744 |
+ return s.String() |
|
| 1745 |
+} |
|
| 1746 |
+ |
|
| 1747 |
+// Validate inspects the fields of the type to determine if they are valid. |
|
| 1748 |
+func (s *GetFederationTokenInput) Validate() error {
|
|
| 1749 |
+ invalidParams := request.ErrInvalidParams{Context: "GetFederationTokenInput"}
|
|
| 1750 |
+ if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
|
|
| 1751 |
+ invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
|
|
| 1752 |
+ } |
|
| 1753 |
+ if s.Name == nil {
|
|
| 1754 |
+ invalidParams.Add(request.NewErrParamRequired("Name"))
|
|
| 1755 |
+ } |
|
| 1756 |
+ if s.Name != nil && len(*s.Name) < 2 {
|
|
| 1757 |
+ invalidParams.Add(request.NewErrParamMinLen("Name", 2))
|
|
| 1758 |
+ } |
|
| 1759 |
+ if s.Policy != nil && len(*s.Policy) < 1 {
|
|
| 1760 |
+ invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
|
|
| 1761 |
+ } |
|
| 1762 |
+ |
|
| 1763 |
+ if invalidParams.Len() > 0 {
|
|
| 1764 |
+ return invalidParams |
|
| 1765 |
+ } |
|
| 1766 |
+ return nil |
|
| 1767 |
+} |
|
| 1768 |
+ |
|
| 1769 |
+// Contains the response to a successful GetFederationToken request, including |
|
| 1770 |
+// temporary AWS credentials that can be used to make AWS requests. |
|
| 1771 |
+type GetFederationTokenOutput struct {
|
|
| 1772 |
+ _ struct{} `type:"structure"`
|
|
| 1773 |
+ |
|
| 1774 |
+ // The temporary security credentials, which include an access key ID, a secret |
|
| 1775 |
+ // access key, and a security (or session) token. |
|
| 1776 |
+ // |
|
| 1777 |
+ // Note: The size of the security token that STS APIs return is not fixed. We |
|
| 1778 |
+ // strongly recommend that you make no assumptions about the maximum size. As |
|
| 1779 |
+ // of this writing, the typical size is less than 4096 bytes, but that can vary. |
|
| 1780 |
+ // Also, future updates to AWS might require larger sizes. |
|
| 1781 |
+ Credentials *Credentials `type:"structure"` |
|
| 1782 |
+ |
|
| 1783 |
+ // Identifiers for the federated user associated with the credentials (such |
|
| 1784 |
+ // as arn:aws:sts::123456789012:federated-user/Bob or 123456789012:Bob). You |
|
| 1785 |
+ // can use the federated user's ARN in your resource-based policies, such as |
|
| 1786 |
+ // an Amazon S3 bucket policy. |
|
| 1787 |
+ FederatedUser *FederatedUser `type:"structure"` |
|
| 1788 |
+ |
|
| 1789 |
+ // A percentage value indicating the size of the policy in packed form. The |
|
| 1790 |
+ // service rejects policies for which the packed size is greater than 100 percent |
|
| 1791 |
+ // of the allowed value. |
|
| 1792 |
+ PackedPolicySize *int64 `type:"integer"` |
|
| 1793 |
+} |
|
| 1794 |
+ |
|
| 1795 |
+// String returns the string representation |
|
| 1796 |
+func (s GetFederationTokenOutput) String() string {
|
|
| 1797 |
+ return awsutil.Prettify(s) |
|
| 1798 |
+} |
|
| 1799 |
+ |
|
| 1800 |
+// GoString returns the string representation |
|
| 1801 |
+func (s GetFederationTokenOutput) GoString() string {
|
|
| 1802 |
+ return s.String() |
|
| 1803 |
+} |
|
| 1804 |
+ |
|
| 1805 |
+type GetSessionTokenInput struct {
|
|
| 1806 |
+ _ struct{} `type:"structure"`
|
|
| 1807 |
+ |
|
| 1808 |
+ // The duration, in seconds, that the credentials should remain valid. Acceptable |
|
| 1809 |
+ // durations for IAM user sessions range from 900 seconds (15 minutes) to 129600 |
|
| 1810 |
+ // seconds (36 hours), with 43200 seconds (12 hours) as the default. Sessions |
|
| 1811 |
+ // for AWS account owners are restricted to a maximum of 3600 seconds (one hour). |
|
| 1812 |
+ // If the duration is longer than one hour, the session for AWS account owners |
|
| 1813 |
+ // defaults to one hour. |
|
| 1814 |
+ DurationSeconds *int64 `min:"900" type:"integer"` |
|
| 1815 |
+ |
|
| 1816 |
+ // The identification number of the MFA device that is associated with the IAM |
|
| 1817 |
+ // user who is making the GetSessionToken call. Specify this value if the IAM |
|
| 1818 |
+ // user has a policy that requires MFA authentication. The value is either the |
|
| 1819 |
+ // serial number for a hardware device (such as GAHT12345678) or an Amazon Resource |
|
| 1820 |
+ // Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). |
|
| 1821 |
+ // You can find the device for an IAM user by going to the AWS Management Console |
|
| 1822 |
+ // and viewing the user's security credentials. |
|
| 1823 |
+ // |
|
| 1824 |
+ // The format for this parameter, as described by its regex pattern, is a string |
|
| 1825 |
+ // of characters consisting of upper- and lower-case alphanumeric characters |
|
| 1826 |
+ // with no spaces. You can also include underscores or any of the following |
|
| 1827 |
+ // characters: =,.@- |
|
| 1828 |
+ SerialNumber *string `min:"9" type:"string"` |
|
| 1829 |
+ |
|
| 1830 |
+ // The value provided by the MFA device, if MFA is required. If any policy requires |
|
| 1831 |
+ // the IAM user to submit an MFA code, specify this value. If MFA authentication |
|
| 1832 |
+ // is required, and the user does not provide a code when requesting a set of |
|
| 1833 |
+ // temporary security credentials, the user will receive an "access denied" |
|
| 1834 |
+ // response when requesting resources that require MFA authentication. |
|
| 1835 |
+ // |
|
| 1836 |
+ // The format for this parameter, as described by its regex pattern, is a sequence |
|
| 1837 |
+ // of six numeric digits. |
|
| 1838 |
+ TokenCode *string `min:"6" type:"string"` |
|
| 1839 |
+} |
|
| 1840 |
+ |
|
| 1841 |
+// String returns the string representation |
|
| 1842 |
+func (s GetSessionTokenInput) String() string {
|
|
| 1843 |
+ return awsutil.Prettify(s) |
|
| 1844 |
+} |
|
| 1845 |
+ |
|
| 1846 |
+// GoString returns the string representation |
|
| 1847 |
+func (s GetSessionTokenInput) GoString() string {
|
|
| 1848 |
+ return s.String() |
|
| 1849 |
+} |
|
| 1850 |
+ |
|
| 1851 |
+// Validate inspects the fields of the type to determine if they are valid. |
|
| 1852 |
+func (s *GetSessionTokenInput) Validate() error {
|
|
| 1853 |
+ invalidParams := request.ErrInvalidParams{Context: "GetSessionTokenInput"}
|
|
| 1854 |
+ if s.DurationSeconds != nil && *s.DurationSeconds < 900 {
|
|
| 1855 |
+ invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900))
|
|
| 1856 |
+ } |
|
| 1857 |
+ if s.SerialNumber != nil && len(*s.SerialNumber) < 9 {
|
|
| 1858 |
+ invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9))
|
|
| 1859 |
+ } |
|
| 1860 |
+ if s.TokenCode != nil && len(*s.TokenCode) < 6 {
|
|
| 1861 |
+ invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6))
|
|
| 1862 |
+ } |
|
| 1863 |
+ |
|
| 1864 |
+ if invalidParams.Len() > 0 {
|
|
| 1865 |
+ return invalidParams |
|
| 1866 |
+ } |
|
| 1867 |
+ return nil |
|
| 1868 |
+} |
|
| 1869 |
+ |
|
| 1870 |
+// Contains the response to a successful GetSessionToken request, including |
|
| 1871 |
+// temporary AWS credentials that can be used to make AWS requests. |
|
| 1872 |
+type GetSessionTokenOutput struct {
|
|
| 1873 |
+ _ struct{} `type:"structure"`
|
|
| 1874 |
+ |
|
| 1875 |
+ // The temporary security credentials, which include an access key ID, a secret |
|
| 1876 |
+ // access key, and a security (or session) token. |
|
| 1877 |
+ // |
|
| 1878 |
+ // Note: The size of the security token that STS APIs return is not fixed. We |
|
| 1879 |
+ // strongly recommend that you make no assumptions about the maximum size. As |
|
| 1880 |
+ // of this writing, the typical size is less than 4096 bytes, but that can vary. |
|
| 1881 |
+ // Also, future updates to AWS might require larger sizes. |
|
| 1882 |
+ Credentials *Credentials `type:"structure"` |
|
| 1883 |
+} |
|
| 1884 |
+ |
|
| 1885 |
+// String returns the string representation |
|
| 1886 |
+func (s GetSessionTokenOutput) String() string {
|
|
| 1887 |
+ return awsutil.Prettify(s) |
|
| 1888 |
+} |
|
| 1889 |
+ |
|
| 1890 |
+// GoString returns the string representation |
|
| 1891 |
+func (s GetSessionTokenOutput) GoString() string {
|
|
| 1892 |
+ return s.String() |
|
| 1893 |
+} |
| 0 | 1894 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,12 @@ |
| 0 |
+package sts |
|
| 1 |
+ |
|
| 2 |
+import "github.com/aws/aws-sdk-go/aws/request" |
|
| 3 |
+ |
|
| 4 |
+func init() {
|
|
| 5 |
+ initRequest = func(r *request.Request) {
|
|
| 6 |
+ switch r.Operation.Name {
|
|
| 7 |
+ case opAssumeRoleWithSAML, opAssumeRoleWithWebIdentity: |
|
| 8 |
+ r.Handlers.Sign.Clear() // these operations are unsigned |
|
| 9 |
+ } |
|
| 10 |
+ } |
|
| 11 |
+} |
| 0 | 12 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,130 @@ |
| 0 |
+// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. |
|
| 1 |
+ |
|
| 2 |
+package sts |
|
| 3 |
+ |
|
| 4 |
+import ( |
|
| 5 |
+ "github.com/aws/aws-sdk-go/aws" |
|
| 6 |
+ "github.com/aws/aws-sdk-go/aws/client" |
|
| 7 |
+ "github.com/aws/aws-sdk-go/aws/client/metadata" |
|
| 8 |
+ "github.com/aws/aws-sdk-go/aws/request" |
|
| 9 |
+ "github.com/aws/aws-sdk-go/aws/signer/v4" |
|
| 10 |
+ "github.com/aws/aws-sdk-go/private/protocol/query" |
|
| 11 |
+) |
|
| 12 |
+ |
|
| 13 |
+// The AWS Security Token Service (STS) is a web service that enables you to |
|
| 14 |
+// request temporary, limited-privilege credentials for AWS Identity and Access |
|
| 15 |
+// Management (IAM) users or for users that you authenticate (federated users). |
|
| 16 |
+// This guide provides descriptions of the STS API. For more detailed information |
|
| 17 |
+// about using this service, go to Temporary Security Credentials (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html). |
|
| 18 |
+// |
|
| 19 |
+// As an alternative to using the API, you can use one of the AWS SDKs, which |
|
| 20 |
+// consist of libraries and sample code for various programming languages and |
|
| 21 |
+// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient |
|
| 22 |
+// way to create programmatic access to STS. For example, the SDKs take care |
|
| 23 |
+// of cryptographically signing requests, managing errors, and retrying requests |
|
| 24 |
+// automatically. For information about the AWS SDKs, including how to download |
|
| 25 |
+// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/). |
|
| 26 |
+// |
|
| 27 |
+// For information about setting up signatures and authorization through the |
|
| 28 |
+// API, go to Signing AWS API Requests (http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) |
|
| 29 |
+// in the AWS General Reference. For general information about the Query API, |
|
| 30 |
+// go to Making Query Requests (http://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html) |
|
| 31 |
+// in Using IAM. For information about using security tokens with other AWS |
|
| 32 |
+// products, go to AWS Services That Work with IAM (http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) |
|
| 33 |
+// in the IAM User Guide. |
|
| 34 |
+// |
|
| 35 |
+// If you're new to AWS and need additional technical information about a specific |
|
| 36 |
+// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/ |
|
| 37 |
+// (http://aws.amazon.com/documentation/). |
|
| 38 |
+// |
|
| 39 |
+// Endpoints |
|
| 40 |
+// |
|
| 41 |
+// The AWS Security Token Service (STS) has a default endpoint of https://sts.amazonaws.com |
|
| 42 |
+// that maps to the US East (N. Virginia) region. Additional regions are available |
|
| 43 |
+// and are activated by default. For more information, see Activating and Deactivating |
|
| 44 |
+// AWS STS in an AWS Region (http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) |
|
| 45 |
+// in the IAM User Guide. |
|
| 46 |
+// |
|
| 47 |
+// For information about STS endpoints, see Regions and Endpoints (http://docs.aws.amazon.com/general/latest/gr/rande.html#sts_region) |
|
| 48 |
+// in the AWS General Reference. |
|
| 49 |
+// |
|
| 50 |
+// Recording API requests |
|
| 51 |
+// |
|
| 52 |
+// STS supports AWS CloudTrail, which is a service that records AWS calls for |
|
| 53 |
+// your AWS account and delivers log files to an Amazon S3 bucket. By using |
|
| 54 |
+// information collected by CloudTrail, you can determine what requests were |
|
| 55 |
+// successfully made to STS, who made the request, when it was made, and so |
|
| 56 |
+// on. To learn more about CloudTrail, including how to turn it on and find |
|
| 57 |
+// your log files, see the AWS CloudTrail User Guide (http://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html). |
|
| 58 |
+//The service client's operations are safe to be used concurrently. |
|
| 59 |
+// It is not safe to mutate any of the client's properties though. |
|
| 60 |
+type STS struct {
|
|
| 61 |
+ *client.Client |
|
| 62 |
+} |
|
| 63 |
+ |
|
| 64 |
+// Used for custom client initialization logic |
|
| 65 |
+var initClient func(*client.Client) |
|
| 66 |
+ |
|
| 67 |
+// Used for custom request initialization logic |
|
| 68 |
+var initRequest func(*request.Request) |
|
| 69 |
+ |
|
| 70 |
+// A ServiceName is the name of the service the client will make API calls to. |
|
| 71 |
+const ServiceName = "sts" |
|
| 72 |
+ |
|
| 73 |
+// New creates a new instance of the STS client with a session. |
|
| 74 |
+// If additional configuration is needed for the client instance use the optional |
|
| 75 |
+// aws.Config parameter to add your extra config. |
|
| 76 |
+// |
|
| 77 |
+// Example: |
|
| 78 |
+// // Create a STS client from just a session. |
|
| 79 |
+// svc := sts.New(mySession) |
|
| 80 |
+// |
|
| 81 |
+// // Create a STS client with additional configuration |
|
| 82 |
+// svc := sts.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
|
| 83 |
+func New(p client.ConfigProvider, cfgs ...*aws.Config) *STS {
|
|
| 84 |
+ c := p.ClientConfig(ServiceName, cfgs...) |
|
| 85 |
+ return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion) |
|
| 86 |
+} |
|
| 87 |
+ |
|
| 88 |
+// newClient creates, initializes and returns a new service client instance. |
|
| 89 |
+func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion string) *STS {
|
|
| 90 |
+ svc := &STS{
|
|
| 91 |
+ Client: client.New( |
|
| 92 |
+ cfg, |
|
| 93 |
+ metadata.ClientInfo{
|
|
| 94 |
+ ServiceName: ServiceName, |
|
| 95 |
+ SigningRegion: signingRegion, |
|
| 96 |
+ Endpoint: endpoint, |
|
| 97 |
+ APIVersion: "2011-06-15", |
|
| 98 |
+ }, |
|
| 99 |
+ handlers, |
|
| 100 |
+ ), |
|
| 101 |
+ } |
|
| 102 |
+ |
|
| 103 |
+ // Handlers |
|
| 104 |
+ svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) |
|
| 105 |
+ svc.Handlers.Build.PushBackNamed(query.BuildHandler) |
|
| 106 |
+ svc.Handlers.Unmarshal.PushBackNamed(query.UnmarshalHandler) |
|
| 107 |
+ svc.Handlers.UnmarshalMeta.PushBackNamed(query.UnmarshalMetaHandler) |
|
| 108 |
+ svc.Handlers.UnmarshalError.PushBackNamed(query.UnmarshalErrorHandler) |
|
| 109 |
+ |
|
| 110 |
+ // Run custom client initialization if present |
|
| 111 |
+ if initClient != nil {
|
|
| 112 |
+ initClient(svc.Client) |
|
| 113 |
+ } |
|
| 114 |
+ |
|
| 115 |
+ return svc |
|
| 116 |
+} |
|
| 117 |
+ |
|
| 118 |
+// newRequest creates a new request for a STS operation and runs any |
|
| 119 |
+// custom request initialization. |
|
| 120 |
+func (c *STS) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
|
| 121 |
+ req := c.NewRequest(op, params, data) |
|
| 122 |
+ |
|
| 123 |
+ // Run custom request initialization if present |
|
| 124 |
+ if initRequest != nil {
|
|
| 125 |
+ initRequest(req) |
|
| 126 |
+ } |
|
| 127 |
+ |
|
| 128 |
+ return req |
|
| 129 |
+} |