From 55a983d26a51a35a32d74ee909b191347627e952 Mon Sep 17 00:00:00 2001 From: "darcy.rayner" Date: Wed, 22 May 2019 11:24:39 -0400 Subject: [PATCH] Update xray go SDK to be at least earliest version with lambda support --- Gopkg.toml | 2 +- .../ec2rolecreds/ec2_role_provider.go | 180 + .../aws/credentials/endpointcreds/provider.go | 203 + .../aws/credentials/processcreds/provider.go | 425 ++ .../stscreds/assume_role_provider.go | 313 + .../github.com/aws/aws-sdk-go/aws/csm/doc.go | 46 + .../aws/aws-sdk-go/aws/csm/enable.go | 67 + .../aws/aws-sdk-go/aws/csm/metric.go | 109 + .../aws/aws-sdk-go/aws/csm/metric_chan.go | 54 + .../aws-sdk-go/aws/csm/metric_exception.go | 26 + .../aws/aws-sdk-go/aws/csm/reporter.go | 260 + .../aws/aws-sdk-go/aws/defaults/defaults.go | 207 + .../aws-sdk-go/aws/defaults/shared_config.go | 27 + .../aws/session/cabundle_transport.go | 26 + .../aws/session/cabundle_transport_1_5.go | 22 + .../aws/session/cabundle_transport_1_6.go | 23 + .../aws/aws-sdk-go/aws/session/doc.go | 273 + .../aws/aws-sdk-go/aws/session/env_config.go | 236 + .../aws/aws-sdk-go/aws/session/session.go | 719 ++ .../aws-sdk-go/aws/session/shared_config.go | 329 + .../aws-sdk-go/aws/signer/v4/header_rules.go | 82 + .../aws/aws-sdk-go/aws/signer/v4/options.go | 7 + .../aws/aws-sdk-go/aws/signer/v4/uri_path.go | 24 + .../aws/aws-sdk-go/aws/signer/v4/v4.go | 796 ++ .../aws/aws-sdk-go/private/protocol/host.go | 68 + .../private/protocol/host_prefix.go | 54 + .../private/protocol/idempotency.go | 75 + .../private/protocol/json/jsonutil/build.go | 296 + .../protocol/json/jsonutil/unmarshal.go | 250 + .../private/protocol/jsonrpc/jsonrpc.go | 110 + .../aws-sdk-go/private/protocol/jsonvalue.go | 76 + .../aws-sdk-go/private/protocol/payload.go | 81 + .../private/protocol/query/build.go | 36 + .../protocol/query/queryutil/queryutil.go | 246 + .../private/protocol/query/unmarshal.go | 39 + .../private/protocol/query/unmarshal_error.go | 69 + .../aws-sdk-go/private/protocol/rest/build.go | 310 + .../private/protocol/rest/payload.go | 45 + .../private/protocol/rest/unmarshal.go | 225 + .../private/protocol/restjson/restjson.go | 88 + .../aws-sdk-go/private/protocol/timestamp.go | 72 + .../aws-sdk-go/private/protocol/unmarshal.go | 21 + .../private/protocol/xml/xmlutil/build.go | 306 + .../private/protocol/xml/xmlutil/unmarshal.go | 291 + .../protocol/xml/xmlutil/xml_to_struct.go | 148 + .../aws/aws-sdk-go/service/sts/api.go | 2581 +++++++ .../aws/aws-sdk-go/service/sts/doc.go | 116 + .../aws/aws-sdk-go/service/sts/errors.go | 73 + .../aws/aws-sdk-go/service/sts/service.go | 95 + .../aws/aws-sdk-go/service/xray/api.go | 6414 +++++++++++++++++ .../aws/aws-sdk-go/service/xray/doc.go | 29 + .../aws/aws-sdk-go/service/xray/errors.go | 24 + .../aws/aws-sdk-go/service/xray/service.go | 95 + .../daemoncfg/daemon_config.go | 172 + .../internal/plugins/plugin.go | 32 +- .../resources/DefaultSamplingRules.json | 2 +- .../resources/ExampleSamplingRules.json | 4 +- .../default_exception_formatting_strategy.go | 14 +- .../strategy/sampling/centralized.go | 522 ++ .../centralized_sampling_rule_manifest.go | 294 + .../strategy/sampling/localized.go | 8 +- .../strategy/sampling/proxy.go | 94 + .../strategy/sampling/reservoir.go | 138 +- .../strategy/sampling/sampling_attributes.go | 23 + .../strategy/sampling/sampling_rule.go | 201 +- .../sampling/sampling_rule_manifest.go | 118 +- .../strategy/sampling/sampling_strategy.go | 2 +- .../aws/aws-xray-sdk-go/utils/clock.go | 26 + .../aws/aws-xray-sdk-go/utils/mock_clock.go | 31 + .../aws/aws-xray-sdk-go/utils/mock_rand.go | 31 + .../aws/aws-xray-sdk-go/utils/rand.go | 46 + .../aws/aws-xray-sdk-go/utils/timer.go | 44 + .../aws/aws-xray-sdk-go/xray/aws.go | 27 +- .../aws/aws-xray-sdk-go/xray/capture.go | 11 +- .../aws/aws-xray-sdk-go/xray/client.go | 27 +- .../aws/aws-xray-sdk-go/xray/config.go | 159 +- .../aws/aws-xray-sdk-go/xray/context.go | 12 + .../aws-xray-sdk-go/xray/default_emitter.go | 103 + .../xray/default_streaming_strategy.go | 6 +- .../aws/aws-xray-sdk-go/xray/emitter.go | 82 +- .../aws/aws-xray-sdk-go/xray/handler.go | 154 +- .../aws/aws-xray-sdk-go/xray/httptrace.go | 41 +- .../aws-xray-sdk-go/xray/httptrace_go17.go | 184 + .../aws/aws-xray-sdk-go/xray/lambda.go | 91 + .../aws/aws-xray-sdk-go/xray/segment.go | 275 +- .../aws/aws-xray-sdk-go/xray/segment_model.go | 40 +- .../aws/aws-xray-sdk-go/xray/sql.go | 21 + 87 files changed, 19433 insertions(+), 391 deletions(-) create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_5.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_6.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/session.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go create mode 100644 vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/host.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/restjson/restjson.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go create mode 100644 vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/sts/service.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/xray/api.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/xray/doc.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/xray/errors.go create mode 100644 vendor/github.com/aws/aws-sdk-go/service/xray/service.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/daemoncfg/daemon_config.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/centralized.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/centralized_sampling_rule_manifest.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/proxy.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_attributes.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/utils/clock.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/utils/mock_clock.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/utils/mock_rand.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/utils/rand.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/utils/timer.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/xray/default_emitter.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/xray/httptrace_go17.go create mode 100644 vendor/github.com/aws/aws-xray-sdk-go/xray/lambda.go diff --git a/Gopkg.toml b/Gopkg.toml index 02a815e5..7f7a1ba8 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -35,4 +35,4 @@ [[constraint]] name = "github.com/aws/aws-xray-sdk-go" - version = "0.9.4" + version = "^v1.0.0-rc.1" diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go new file mode 100644 index 00000000..43d4ed38 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds/ec2_role_provider.go @@ -0,0 +1,180 @@ +package ec2rolecreds + +import ( + "bufio" + "encoding/json" + "fmt" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/ec2metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/sdkuri" +) + +// ProviderName provides a name of EC2Role provider +const ProviderName = "EC2RoleProvider" + +// A EC2RoleProvider retrieves credentials from the EC2 service, and keeps track if +// those credentials are expired. +// +// Example how to configure the EC2RoleProvider with custom http Client, Endpoint +// or ExpiryWindow +// +// p := &ec2rolecreds.EC2RoleProvider{ +// // Pass in a custom timeout to be used when requesting +// // IAM EC2 Role credentials. +// Client: ec2metadata.New(sess, aws.Config{ +// HTTPClient: &http.Client{Timeout: 10 * time.Second}, +// }), +// +// // Do not use early expiry of credentials. If a non zero value is +// // specified the credentials will be expired early +// ExpiryWindow: 0, +// } +type EC2RoleProvider struct { + credentials.Expiry + + // Required EC2Metadata client to use when connecting to EC2 metadata service. + Client *ec2metadata.EC2Metadata + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration +} + +// NewCredentials returns a pointer to a new Credentials object wrapping +// the EC2RoleProvider. Takes a ConfigProvider to create a EC2Metadata client. +// The ConfigProvider is satisfied by the session.Session type. +func NewCredentials(c client.ConfigProvider, options ...func(*EC2RoleProvider)) *credentials.Credentials { + p := &EC2RoleProvider{ + Client: ec2metadata.New(c), + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping +// the EC2RoleProvider. Takes a EC2Metadata client to use when connecting to EC2 +// metadata service. +func NewCredentialsWithClient(client *ec2metadata.EC2Metadata, options ...func(*EC2RoleProvider)) *credentials.Credentials { + p := &EC2RoleProvider{ + Client: client, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// Retrieve retrieves credentials from the EC2 service. +// Error will be returned if the request fails, or unable to extract +// the desired credentials. +func (m *EC2RoleProvider) Retrieve() (credentials.Value, error) { + credsList, err := requestCredList(m.Client) + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + if len(credsList) == 0 { + return credentials.Value{ProviderName: ProviderName}, awserr.New("EmptyEC2RoleList", "empty EC2 Role list", nil) + } + credsName := credsList[0] + + roleCreds, err := requestCred(m.Client, credsName) + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + m.SetExpiration(roleCreds.Expiration, m.ExpiryWindow) + + return credentials.Value{ + AccessKeyID: roleCreds.AccessKeyID, + SecretAccessKey: roleCreds.SecretAccessKey, + SessionToken: roleCreds.Token, + ProviderName: ProviderName, + }, nil +} + +// A ec2RoleCredRespBody provides the shape for unmarshaling credential +// request responses. +type ec2RoleCredRespBody struct { + // Success State + Expiration time.Time + AccessKeyID string + SecretAccessKey string + Token string + + // Error state + Code string + Message string +} + +const iamSecurityCredsPath = "iam/security-credentials/" + +// requestCredList requests a list of credentials from the EC2 service. +// If there are no credentials, or there is an error making or receiving the request +func requestCredList(client *ec2metadata.EC2Metadata) ([]string, error) { + resp, err := client.GetMetadata(iamSecurityCredsPath) + if err != nil { + return nil, awserr.New("EC2RoleRequestError", "no EC2 instance role found", err) + } + + credsList := []string{} + s := bufio.NewScanner(strings.NewReader(resp)) + for s.Scan() { + credsList = append(credsList, s.Text()) + } + + if err := s.Err(); err != nil { + return nil, awserr.New(request.ErrCodeSerialization, + "failed to read EC2 instance role from metadata service", err) + } + + return credsList, nil +} + +// requestCred requests the credentials for a specific credentials from the EC2 service. +// +// If the credentials cannot be found, or there is an error reading the response +// and error will be returned. +func requestCred(client *ec2metadata.EC2Metadata, credsName string) (ec2RoleCredRespBody, error) { + resp, err := client.GetMetadata(sdkuri.PathJoin(iamSecurityCredsPath, credsName)) + if err != nil { + return ec2RoleCredRespBody{}, + awserr.New("EC2RoleRequestError", + fmt.Sprintf("failed to get %s EC2 instance role credentials", credsName), + err) + } + + respCreds := ec2RoleCredRespBody{} + if err := json.NewDecoder(strings.NewReader(resp)).Decode(&respCreds); err != nil { + return ec2RoleCredRespBody{}, + awserr.New(request.ErrCodeSerialization, + fmt.Sprintf("failed to decode %s EC2 instance role credentials", credsName), + err) + } + + if respCreds.Code != "Success" { + // If an error code was returned something failed requesting the role. + return ec2RoleCredRespBody{}, awserr.New(respCreds.Code, respCreds.Message, nil) + } + + return respCreds, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go new file mode 100644 index 00000000..c2b2c5d6 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/endpointcreds/provider.go @@ -0,0 +1,203 @@ +// Package endpointcreds provides support for retrieving credentials from an +// arbitrary HTTP endpoint. +// +// The credentials endpoint Provider can receive both static and refreshable +// credentials that will expire. Credentials are static when an "Expiration" +// value is not provided in the endpoint's response. +// +// Static credentials will never expire once they have been retrieved. The format +// of the static credentials response: +// { +// "AccessKeyId" : "MUA...", +// "SecretAccessKey" : "/7PC5om....", +// } +// +// Refreshable credentials will expire within the "ExpiryWindow" of the Expiration +// value in the response. The format of the refreshable credentials response: +// { +// "AccessKeyId" : "MUA...", +// "SecretAccessKey" : "/7PC5om....", +// "Token" : "AQoDY....=", +// "Expiration" : "2016-02-25T06:03:31Z" +// } +// +// Errors should be returned in the following format and only returned with 400 +// or 500 HTTP status codes. +// { +// "code": "ErrorCode", +// "message": "Helpful error message." +// } +package endpointcreds + +import ( + "encoding/json" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" +) + +// ProviderName is the name of the credentials provider. +const ProviderName = `CredentialsEndpointProvider` + +// Provider satisfies the credentials.Provider interface, and is a client to +// retrieve credentials from an arbitrary endpoint. +type Provider struct { + staticCreds bool + credentials.Expiry + + // Requires a AWS Client to make HTTP requests to the endpoint with. + // the Endpoint the request will be made to is provided by the aws.Config's + // Endpoint value. + Client *client.Client + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration + + // Optional authorization token value if set will be used as the value of + // the Authorization header of the endpoint credential request. + AuthorizationToken string +} + +// NewProviderClient returns a credentials Provider for retrieving AWS credentials +// from arbitrary endpoint. +func NewProviderClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) credentials.Provider { + p := &Provider{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: "CredentialsEndpoint", + Endpoint: endpoint, + }, + handlers, + ), + } + + p.Client.Handlers.Unmarshal.PushBack(unmarshalHandler) + p.Client.Handlers.UnmarshalError.PushBack(unmarshalError) + p.Client.Handlers.Validate.Clear() + p.Client.Handlers.Validate.PushBack(validateEndpointHandler) + + for _, option := range options { + option(p) + } + + return p +} + +// NewCredentialsClient returns a Credentials wrapper for retrieving credentials +// from an arbitrary endpoint concurrently. The client will request the +func NewCredentialsClient(cfg aws.Config, handlers request.Handlers, endpoint string, options ...func(*Provider)) *credentials.Credentials { + return credentials.NewCredentials(NewProviderClient(cfg, handlers, endpoint, options...)) +} + +// IsExpired returns true if the credentials retrieved are expired, or not yet +// retrieved. +func (p *Provider) IsExpired() bool { + if p.staticCreds { + return false + } + return p.Expiry.IsExpired() +} + +// Retrieve will attempt to request the credentials from the endpoint the Provider +// was configured for. And error will be returned if the retrieval fails. +func (p *Provider) Retrieve() (credentials.Value, error) { + resp, err := p.getCredentials() + if err != nil { + return credentials.Value{ProviderName: ProviderName}, + awserr.New("CredentialsEndpointError", "failed to load credentials", err) + } + + if resp.Expiration != nil { + p.SetExpiration(*resp.Expiration, p.ExpiryWindow) + } else { + p.staticCreds = true + } + + return credentials.Value{ + AccessKeyID: resp.AccessKeyID, + SecretAccessKey: resp.SecretAccessKey, + SessionToken: resp.Token, + ProviderName: ProviderName, + }, nil +} + +type getCredentialsOutput struct { + Expiration *time.Time + AccessKeyID string + SecretAccessKey string + Token string +} + +type errorOutput struct { + Code string `json:"code"` + Message string `json:"message"` +} + +func (p *Provider) getCredentials() (*getCredentialsOutput, error) { + op := &request.Operation{ + Name: "GetCredentials", + HTTPMethod: "GET", + } + + out := &getCredentialsOutput{} + req := p.Client.NewRequest(op, nil, out) + req.HTTPRequest.Header.Set("Accept", "application/json") + if authToken := p.AuthorizationToken; len(authToken) != 0 { + req.HTTPRequest.Header.Set("Authorization", authToken) + } + + return out, req.Send() +} + +func validateEndpointHandler(r *request.Request) { + if len(r.ClientInfo.Endpoint) == 0 { + r.Error = aws.ErrMissingEndpoint + } +} + +func unmarshalHandler(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + out := r.Data.(*getCredentialsOutput) + if err := json.NewDecoder(r.HTTPResponse.Body).Decode(&out); err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, + "failed to decode endpoint credentials", + err, + ) + } +} + +func unmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + var errOut errorOutput + err := jsonutil.UnmarshalJSONError(&errOut, r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to decode error message", err), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + + // Response body format is not consistent between metadata endpoints. + // Grab the error message as a string and include that as the source error + r.Error = awserr.New(errOut.Code, errOut.Message, nil) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go new file mode 100644 index 00000000..1980c8c1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/processcreds/provider.go @@ -0,0 +1,425 @@ +/* +Package processcreds is a credential Provider to retrieve `credential_process` +credentials. + +WARNING: The following describes a method of sourcing credentials from an external +process. This can potentially be dangerous, so proceed with caution. Other +credential providers should be preferred if at all possible. If using this +option, you should make sure that the config file is as locked down as possible +using security best practices for your operating system. + +You can use credentials from a `credential_process` in a variety of ways. + +One way is to setup your shared config file, located in the default +location, with the `credential_process` key and the command you want to be +called. You also need to set the AWS_SDK_LOAD_CONFIG environment variable +(e.g., `export AWS_SDK_LOAD_CONFIG=1`) to use the shared config file. + + [default] + credential_process = /command/to/call + +Creating a new session will use the credential process to retrieve credentials. +NOTE: If there are credentials in the profile you are using, the credential +process will not be used. + + // Initialize a session to load credentials. + sess, _ := session.NewSession(&aws.Config{ + Region: aws.String("us-east-1")}, + ) + + // Create S3 service client to use the credentials. + svc := s3.New(sess) + +Another way to use the `credential_process` method is by using +`credentials.NewCredentials()` and providing a command to be executed to +retrieve credentials: + + // Create credentials using the ProcessProvider. + creds := processcreds.NewCredentials("/path/to/command") + + // Create service client value configured for credentials. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +You can set a non-default timeout for the `credential_process` with another +constructor, `credentials.NewCredentialsTimeout()`, providing the timeout. To +set a one minute timeout: + + // Create credentials using the ProcessProvider. + creds := processcreds.NewCredentialsTimeout( + "/path/to/command", + time.Duration(500) * time.Millisecond) + +If you need more control, you can set any configurable options in the +credentials using one or more option functions. For example, you can set a two +minute timeout, a credential duration of 60 minutes, and a maximum stdout +buffer size of 2k. + + creds := processcreds.NewCredentials( + "/path/to/command", + func(opt *ProcessProvider) { + opt.Timeout = time.Duration(2) * time.Minute + opt.Duration = time.Duration(60) * time.Minute + opt.MaxBufSize = 2048 + }) + +You can also use your own `exec.Cmd`: + + // Create an exec.Cmd + myCommand := exec.Command("/path/to/command") + + // Create credentials using your exec.Cmd and custom timeout + creds := processcreds.NewCredentialsCommand( + myCommand, + func(opt *processcreds.ProcessProvider) { + opt.Timeout = time.Duration(1) * time.Second + }) +*/ +package processcreds + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "runtime" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" +) + +const ( + // ProviderName is the name this credentials provider will label any + // returned credentials Value with. + ProviderName = `ProcessProvider` + + // ErrCodeProcessProviderParse error parsing process output + ErrCodeProcessProviderParse = "ProcessProviderParseError" + + // ErrCodeProcessProviderVersion version error in output + ErrCodeProcessProviderVersion = "ProcessProviderVersionError" + + // ErrCodeProcessProviderRequired required attribute missing in output + ErrCodeProcessProviderRequired = "ProcessProviderRequiredError" + + // ErrCodeProcessProviderExecution execution of command failed + ErrCodeProcessProviderExecution = "ProcessProviderExecutionError" + + // errMsgProcessProviderTimeout process took longer than allowed + errMsgProcessProviderTimeout = "credential process timed out" + + // errMsgProcessProviderProcess process error + errMsgProcessProviderProcess = "error in credential_process" + + // errMsgProcessProviderParse problem parsing output + errMsgProcessProviderParse = "parse failed of credential_process output" + + // errMsgProcessProviderVersion version error in output + errMsgProcessProviderVersion = "wrong version in process output (not 1)" + + // errMsgProcessProviderMissKey missing access key id in output + errMsgProcessProviderMissKey = "missing AccessKeyId in process output" + + // errMsgProcessProviderMissSecret missing secret acess key in output + errMsgProcessProviderMissSecret = "missing SecretAccessKey in process output" + + // errMsgProcessProviderPrepareCmd prepare of command failed + errMsgProcessProviderPrepareCmd = "failed to prepare command" + + // errMsgProcessProviderEmptyCmd command must not be empty + errMsgProcessProviderEmptyCmd = "command must not be empty" + + // errMsgProcessProviderPipe failed to initialize pipe + errMsgProcessProviderPipe = "failed to initialize pipe" + + // DefaultDuration is the default amount of time in minutes that the + // credentials will be valid for. + DefaultDuration = time.Duration(15) * time.Minute + + // DefaultBufSize limits buffer size from growing to an enormous + // amount due to a faulty process. + DefaultBufSize = 1024 + + // DefaultTimeout default limit on time a process can run. + DefaultTimeout = time.Duration(1) * time.Minute +) + +// ProcessProvider satisfies the credentials.Provider interface, and is a +// client to retrieve credentials from a process. +type ProcessProvider struct { + staticCreds bool + credentials.Expiry + originalCommand []string + + // Expiry duration of the credentials. Defaults to 15 minutes if not set. + Duration time.Duration + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration + + // A string representing an os command that should return a JSON with + // credential information. + command *exec.Cmd + + // MaxBufSize limits memory usage from growing to an enormous + // amount due to a faulty process. + MaxBufSize int + + // Timeout limits the time a process can run. + Timeout time.Duration +} + +// NewCredentials returns a pointer to a new Credentials object wrapping the +// ProcessProvider. The credentials will expire every 15 minutes by default. +func NewCredentials(command string, options ...func(*ProcessProvider)) *credentials.Credentials { + p := &ProcessProvider{ + command: exec.Command(command), + Duration: DefaultDuration, + Timeout: DefaultTimeout, + MaxBufSize: DefaultBufSize, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// NewCredentialsTimeout returns a pointer to a new Credentials object with +// the specified command and timeout, and default duration and max buffer size. +func NewCredentialsTimeout(command string, timeout time.Duration) *credentials.Credentials { + p := NewCredentials(command, func(opt *ProcessProvider) { + opt.Timeout = timeout + }) + + return p +} + +// NewCredentialsCommand returns a pointer to a new Credentials object with +// the specified command, and default timeout, duration and max buffer size. +func NewCredentialsCommand(command *exec.Cmd, options ...func(*ProcessProvider)) *credentials.Credentials { + p := &ProcessProvider{ + command: command, + Duration: DefaultDuration, + Timeout: DefaultTimeout, + MaxBufSize: DefaultBufSize, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +type credentialProcessResponse struct { + Version int + AccessKeyID string `json:"AccessKeyId"` + SecretAccessKey string + SessionToken string + Expiration *time.Time +} + +// Retrieve executes the 'credential_process' and returns the credentials. +func (p *ProcessProvider) Retrieve() (credentials.Value, error) { + out, err := p.executeCredentialProcess() + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + // Serialize and validate response + resp := &credentialProcessResponse{} + if err = json.Unmarshal(out, resp); err != nil { + return credentials.Value{ProviderName: ProviderName}, awserr.New( + ErrCodeProcessProviderParse, + fmt.Sprintf("%s: %s", errMsgProcessProviderParse, string(out)), + err) + } + + if resp.Version != 1 { + return credentials.Value{ProviderName: ProviderName}, awserr.New( + ErrCodeProcessProviderVersion, + errMsgProcessProviderVersion, + nil) + } + + if len(resp.AccessKeyID) == 0 { + return credentials.Value{ProviderName: ProviderName}, awserr.New( + ErrCodeProcessProviderRequired, + errMsgProcessProviderMissKey, + nil) + } + + if len(resp.SecretAccessKey) == 0 { + return credentials.Value{ProviderName: ProviderName}, awserr.New( + ErrCodeProcessProviderRequired, + errMsgProcessProviderMissSecret, + nil) + } + + // Handle expiration + p.staticCreds = resp.Expiration == nil + if resp.Expiration != nil { + p.SetExpiration(*resp.Expiration, p.ExpiryWindow) + } + + return credentials.Value{ + ProviderName: ProviderName, + AccessKeyID: resp.AccessKeyID, + SecretAccessKey: resp.SecretAccessKey, + SessionToken: resp.SessionToken, + }, nil +} + +// IsExpired returns true if the credentials retrieved are expired, or not yet +// retrieved. +func (p *ProcessProvider) IsExpired() bool { + if p.staticCreds { + return false + } + return p.Expiry.IsExpired() +} + +// prepareCommand prepares the command to be executed. +func (p *ProcessProvider) prepareCommand() error { + + var cmdArgs []string + if runtime.GOOS == "windows" { + cmdArgs = []string{"cmd.exe", "/C"} + } else { + cmdArgs = []string{"sh", "-c"} + } + + if len(p.originalCommand) == 0 { + p.originalCommand = make([]string, len(p.command.Args)) + copy(p.originalCommand, p.command.Args) + + // check for empty command because it succeeds + if len(strings.TrimSpace(p.originalCommand[0])) < 1 { + return awserr.New( + ErrCodeProcessProviderExecution, + fmt.Sprintf( + "%s: %s", + errMsgProcessProviderPrepareCmd, + errMsgProcessProviderEmptyCmd), + nil) + } + } + + cmdArgs = append(cmdArgs, p.originalCommand...) + p.command = exec.Command(cmdArgs[0], cmdArgs[1:]...) + p.command.Env = os.Environ() + + return nil +} + +// executeCredentialProcess starts the credential process on the OS and +// returns the results or an error. +func (p *ProcessProvider) executeCredentialProcess() ([]byte, error) { + + if err := p.prepareCommand(); err != nil { + return nil, err + } + + // Setup the pipes + outReadPipe, outWritePipe, err := os.Pipe() + if err != nil { + return nil, awserr.New( + ErrCodeProcessProviderExecution, + errMsgProcessProviderPipe, + err) + } + + p.command.Stderr = os.Stderr // display stderr on console for MFA + p.command.Stdout = outWritePipe // get creds json on process's stdout + p.command.Stdin = os.Stdin // enable stdin for MFA + + output := bytes.NewBuffer(make([]byte, 0, p.MaxBufSize)) + + stdoutCh := make(chan error, 1) + go readInput( + io.LimitReader(outReadPipe, int64(p.MaxBufSize)), + output, + stdoutCh) + + execCh := make(chan error, 1) + go executeCommand(*p.command, execCh) + + finished := false + var errors []error + for !finished { + select { + case readError := <-stdoutCh: + errors = appendError(errors, readError) + finished = true + case execError := <-execCh: + err := outWritePipe.Close() + errors = appendError(errors, err) + errors = appendError(errors, execError) + if errors != nil { + return output.Bytes(), awserr.NewBatchError( + ErrCodeProcessProviderExecution, + errMsgProcessProviderProcess, + errors) + } + case <-time.After(p.Timeout): + finished = true + return output.Bytes(), awserr.NewBatchError( + ErrCodeProcessProviderExecution, + errMsgProcessProviderTimeout, + errors) // errors can be nil + } + } + + out := output.Bytes() + + if runtime.GOOS == "windows" { + // windows adds slashes to quotes + out = []byte(strings.Replace(string(out), `\"`, `"`, -1)) + } + + return out, nil +} + +// appendError conveniently checks for nil before appending slice +func appendError(errors []error, err error) []error { + if err != nil { + return append(errors, err) + } + return errors +} + +func executeCommand(cmd exec.Cmd, exec chan error) { + // Start the command + err := cmd.Start() + if err == nil { + err = cmd.Wait() + } + + exec <- err +} + +func readInput(r io.Reader, w io.Writer, read chan error) { + tee := io.TeeReader(r, w) + + _, err := ioutil.ReadAll(tee) + + if err == io.EOF { + err = nil + } + + read <- err // will only arrive here when write end of pipe is closed +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go new file mode 100644 index 00000000..b6dbfd24 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/credentials/stscreds/assume_role_provider.go @@ -0,0 +1,313 @@ +/* +Package stscreds are credential Providers to retrieve STS AWS credentials. + +STS provides multiple ways to retrieve credentials which can be used when making +future AWS service API operation calls. + +The SDK will ensure that per instance of credentials.Credentials all requests +to refresh the credentials will be synchronized. But, the SDK is unable to +ensure synchronous usage of the AssumeRoleProvider if the value is shared +between multiple Credentials, Sessions or service clients. + +Assume Role + +To assume an IAM role using STS with the SDK you can create a new Credentials +with the SDKs's stscreds package. + + // Initial credentials loaded from SDK's default credential chain. Such as + // the environment, shared credentials (~/.aws/credentials), or EC2 Instance + // Role. These credentials will be used to to make the STS Assume Role API. + sess := session.Must(session.NewSession()) + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN. + creds := stscreds.NewCredentials(sess, "myRoleArn") + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +Assume Role with static MFA Token + +To assume an IAM role with a MFA token you can either specify a MFA token code +directly or provide a function to prompt the user each time the credentials +need to refresh the role's credentials. Specifying the TokenCode should be used +for short lived operations that will not need to be refreshed, and when you do +not want to have direct control over the user provides their MFA token. + +With TokenCode the AssumeRoleProvider will be not be able to refresh the role's +credentials. + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN using the MFA token code provided. + creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) { + p.SerialNumber = aws.String("myTokenSerialNumber") + p.TokenCode = aws.String("00000000") + }) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +Assume Role with MFA Token Provider + +To assume an IAM role with MFA for longer running tasks where the credentials +may need to be refreshed setting the TokenProvider field of AssumeRoleProvider +will allow the credential provider to prompt for new MFA token code when the +role's credentials need to be refreshed. + +The StdinTokenProvider function is available to prompt on stdin to retrieve +the MFA token code from the user. You can also implement custom prompts by +satisfing the TokenProvider function signature. + +Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will +have undesirable results as the StdinTokenProvider will not be synchronized. A +single Credentials with an AssumeRoleProvider can be shared safely. + + // Create the credentials from AssumeRoleProvider to assume the role + // referenced by the "myRoleARN" ARN. Prompting for MFA token from stdin. + creds := stscreds.NewCredentials(sess, "myRoleArn", func(p *stscreds.AssumeRoleProvider) { + p.SerialNumber = aws.String("myTokenSerialNumber") + p.TokenProvider = stscreds.StdinTokenProvider + }) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess, &aws.Config{Credentials: creds}) + +*/ +package stscreds + +import ( + "fmt" + "os" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/internal/sdkrand" + "github.com/aws/aws-sdk-go/service/sts" +) + +// StdinTokenProvider will prompt on stderr and read from stdin for a string value. +// An error is returned if reading from stdin fails. +// +// Use this function go read MFA tokens from stdin. The function makes no attempt +// to make atomic prompts from stdin across multiple gorouties. +// +// Using StdinTokenProvider with multiple AssumeRoleProviders, or Credentials will +// have undesirable results as the StdinTokenProvider will not be synchronized. A +// single Credentials with an AssumeRoleProvider can be shared safely +// +// Will wait forever until something is provided on the stdin. +func StdinTokenProvider() (string, error) { + var v string + fmt.Fprintf(os.Stderr, "Assume Role MFA token code: ") + _, err := fmt.Scanln(&v) + + return v, err +} + +// ProviderName provides a name of AssumeRole provider +const ProviderName = "AssumeRoleProvider" + +// AssumeRoler represents the minimal subset of the STS client API used by this provider. +type AssumeRoler interface { + AssumeRole(input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) +} + +// DefaultDuration is the default amount of time in minutes that the credentials +// will be valid for. +var DefaultDuration = time.Duration(15) * time.Minute + +// AssumeRoleProvider retrieves temporary credentials from the STS service, and +// keeps track of their expiration time. +// +// This credential provider will be used by the SDKs default credential change +// when shared configuration is enabled, and the shared config or shared credentials +// file configure assume role. See Session docs for how to do this. +// +// AssumeRoleProvider does not provide any synchronization and it is not safe +// to share this value across multiple Credentials, Sessions, or service clients +// without also sharing the same Credentials instance. +type AssumeRoleProvider struct { + credentials.Expiry + + // STS client to make assume role request with. + Client AssumeRoler + + // Role to be assumed. + RoleARN string + + // Session name, if you wish to reuse the credentials elsewhere. + RoleSessionName string + + // Expiry duration of the STS credentials. Defaults to 15 minutes if not set. + Duration time.Duration + + // Optional ExternalID to pass along, defaults to nil if not set. + ExternalID *string + + // The policy plain text must be 2048 bytes or shorter. However, an internal + // conversion compresses it into a packed binary format with a separate limit. + // The PackedPolicySize response element indicates by percentage how close to + // the upper size limit the policy is, with 100% equaling the maximum allowed + // size. + Policy *string + + // The identification number of the MFA device that is associated with the user + // who is making the AssumeRole call. Specify this value if the trust policy + // of the role being assumed includes a condition that requires MFA authentication. + // The value is either the serial number for a hardware device (such as GAHT12345678) + // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). + SerialNumber *string + + // The value provided by the MFA device, if the trust policy of the role being + // assumed requires MFA (that is, if the policy includes a condition that tests + // for MFA). If the role being assumed requires MFA and if the TokenCode value + // is missing or expired, the AssumeRole call returns an "access denied" error. + // + // If SerialNumber is set and neither TokenCode nor TokenProvider are also + // set an error will be returned. + TokenCode *string + + // Async method of providing MFA token code for assuming an IAM role with MFA. + // The value returned by the function will be used as the TokenCode in the Retrieve + // call. See StdinTokenProvider for a provider that prompts and reads from stdin. + // + // This token provider will be called when ever the assumed role's + // credentials need to be refreshed when SerialNumber is also set and + // TokenCode is not set. + // + // If both TokenCode and TokenProvider is set, TokenProvider will be used and + // TokenCode is ignored. + TokenProvider func() (string, error) + + // ExpiryWindow will allow the credentials to trigger refreshing prior to + // the credentials actually expiring. This is beneficial so race conditions + // with expiring credentials do not cause request to fail unexpectedly + // due to ExpiredTokenException exceptions. + // + // So a ExpiryWindow of 10s would cause calls to IsExpired() to return true + // 10 seconds before the credentials are actually expired. + // + // If ExpiryWindow is 0 or less it will be ignored. + ExpiryWindow time.Duration + + // MaxJitterFrac reduces the effective Duration of each credential requested + // by a random percentage between 0 and MaxJitterFraction. MaxJitterFrac must + // have a value between 0 and 1. Any other value may lead to expected behavior. + // With a MaxJitterFrac value of 0, default) will no jitter will be used. + // + // For example, with a Duration of 30m and a MaxJitterFrac of 0.1, the + // AssumeRole call will be made with an arbitrary Duration between 27m and + // 30m. + // + // MaxJitterFrac should not be negative. + MaxJitterFrac float64 +} + +// NewCredentials returns a pointer to a new Credentials object wrapping the +// AssumeRoleProvider. The credentials will expire every 15 minutes and the +// role will be named after a nanosecond timestamp of this operation. +// +// Takes a Config provider to create the STS client. The ConfigProvider is +// satisfied by the session.Session type. +// +// It is safe to share the returned Credentials with multiple Sessions and +// service clients. All access to the credentials and refreshing them +// will be synchronized. +func NewCredentials(c client.ConfigProvider, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { + p := &AssumeRoleProvider{ + Client: sts.New(c), + RoleARN: roleARN, + Duration: DefaultDuration, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// NewCredentialsWithClient returns a pointer to a new Credentials object wrapping the +// AssumeRoleProvider. The credentials will expire every 15 minutes and the +// role will be named after a nanosecond timestamp of this operation. +// +// Takes an AssumeRoler which can be satisfied by the STS client. +// +// It is safe to share the returned Credentials with multiple Sessions and +// service clients. All access to the credentials and refreshing them +// will be synchronized. +func NewCredentialsWithClient(svc AssumeRoler, roleARN string, options ...func(*AssumeRoleProvider)) *credentials.Credentials { + p := &AssumeRoleProvider{ + Client: svc, + RoleARN: roleARN, + Duration: DefaultDuration, + } + + for _, option := range options { + option(p) + } + + return credentials.NewCredentials(p) +} + +// Retrieve generates a new set of temporary credentials using STS. +func (p *AssumeRoleProvider) Retrieve() (credentials.Value, error) { + + // Apply defaults where parameters are not set. + if p.RoleSessionName == "" { + // Try to work out a role name that will hopefully end up unique. + p.RoleSessionName = fmt.Sprintf("%d", time.Now().UTC().UnixNano()) + } + if p.Duration == 0 { + // Expire as often as AWS permits. + p.Duration = DefaultDuration + } + jitter := time.Duration(sdkrand.SeededRand.Float64() * p.MaxJitterFrac * float64(p.Duration)) + input := &sts.AssumeRoleInput{ + DurationSeconds: aws.Int64(int64((p.Duration - jitter) / time.Second)), + RoleArn: aws.String(p.RoleARN), + RoleSessionName: aws.String(p.RoleSessionName), + ExternalId: p.ExternalID, + } + if p.Policy != nil { + input.Policy = p.Policy + } + if p.SerialNumber != nil { + if p.TokenCode != nil { + input.SerialNumber = p.SerialNumber + input.TokenCode = p.TokenCode + } else if p.TokenProvider != nil { + input.SerialNumber = p.SerialNumber + code, err := p.TokenProvider() + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + input.TokenCode = aws.String(code) + } else { + return credentials.Value{ProviderName: ProviderName}, + awserr.New("AssumeRoleTokenNotAvailable", + "assume role with MFA enabled, but neither TokenCode nor TokenProvider are set", nil) + } + } + + roleOutput, err := p.Client.AssumeRole(input) + if err != nil { + return credentials.Value{ProviderName: ProviderName}, err + } + + // We will proactively generate new credentials before they expire. + p.SetExpiration(*roleOutput.Credentials.Expiration, p.ExpiryWindow) + + return credentials.Value{ + AccessKeyID: *roleOutput.Credentials.AccessKeyId, + SecretAccessKey: *roleOutput.Credentials.SecretAccessKey, + SessionToken: *roleOutput.Credentials.SessionToken, + ProviderName: ProviderName, + }, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go new file mode 100644 index 00000000..152d785b --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/doc.go @@ -0,0 +1,46 @@ +// Package csm provides Client Side Monitoring (CSM) which enables sending metrics +// via UDP connection. Using the Start function will enable the reporting of +// metrics on a given port. If Start is called, with different parameters, again, +// a panic will occur. +// +// Pause can be called to pause any metrics publishing on a given port. Sessions +// that have had their handlers modified via InjectHandlers may still be used. +// However, the handlers will act as a no-op meaning no metrics will be published. +// +// Example: +// r, err := csm.Start("clientID", ":31000") +// if err != nil { +// panic(fmt.Errorf("failed starting CSM: %v", err)) +// } +// +// sess, err := session.NewSession(&aws.Config{}) +// if err != nil { +// panic(fmt.Errorf("failed loading session: %v", err)) +// } +// +// r.InjectHandlers(&sess.Handlers) +// +// client := s3.New(sess) +// resp, err := client.GetObject(&s3.GetObjectInput{ +// Bucket: aws.String("bucket"), +// Key: aws.String("key"), +// }) +// +// // Will pause monitoring +// r.Pause() +// resp, err = client.GetObject(&s3.GetObjectInput{ +// Bucket: aws.String("bucket"), +// Key: aws.String("key"), +// }) +// +// // Resume monitoring +// r.Continue() +// +// Start returns a Reporter that is used to enable or disable monitoring. If +// access to the Reporter is required later, calling Get will return the Reporter +// singleton. +// +// Example: +// r := csm.Get() +// r.Continue() +package csm diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go new file mode 100644 index 00000000..2f0c6eac --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/enable.go @@ -0,0 +1,67 @@ +package csm + +import ( + "fmt" + "sync" +) + +var ( + lock sync.Mutex +) + +// Client side metric handler names +const ( + APICallMetricHandlerName = "awscsm.SendAPICallMetric" + APICallAttemptMetricHandlerName = "awscsm.SendAPICallAttemptMetric" +) + +// Start will start the a long running go routine to capture +// client side metrics. Calling start multiple time will only +// start the metric listener once and will panic if a different +// client ID or port is passed in. +// +// Example: +// r, err := csm.Start("clientID", "127.0.0.1:8094") +// if err != nil { +// panic(fmt.Errorf("expected no error, but received %v", err)) +// } +// sess := session.NewSession() +// r.InjectHandlers(sess.Handlers) +// +// svc := s3.New(sess) +// out, err := svc.GetObject(&s3.GetObjectInput{ +// Bucket: aws.String("bucket"), +// Key: aws.String("key"), +// }) +func Start(clientID string, url string) (*Reporter, error) { + lock.Lock() + defer lock.Unlock() + + if sender == nil { + sender = newReporter(clientID, url) + } else { + if sender.clientID != clientID { + panic(fmt.Errorf("inconsistent client IDs. %q was expected, but received %q", sender.clientID, clientID)) + } + + if sender.url != url { + panic(fmt.Errorf("inconsistent URLs. %q was expected, but received %q", sender.url, url)) + } + } + + if err := connect(url); err != nil { + sender = nil + return nil, err + } + + return sender, nil +} + +// Get will return a reporter if one exists, if one does not exist, nil will +// be returned. +func Get() *Reporter { + lock.Lock() + defer lock.Unlock() + + return sender +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go new file mode 100644 index 00000000..5bacc791 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric.go @@ -0,0 +1,109 @@ +package csm + +import ( + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws" +) + +type metricTime time.Time + +func (t metricTime) MarshalJSON() ([]byte, error) { + ns := time.Duration(time.Time(t).UnixNano()) + return []byte(strconv.FormatInt(int64(ns/time.Millisecond), 10)), nil +} + +type metric struct { + ClientID *string `json:"ClientId,omitempty"` + API *string `json:"Api,omitempty"` + Service *string `json:"Service,omitempty"` + Timestamp *metricTime `json:"Timestamp,omitempty"` + Type *string `json:"Type,omitempty"` + Version *int `json:"Version,omitempty"` + + AttemptCount *int `json:"AttemptCount,omitempty"` + Latency *int `json:"Latency,omitempty"` + + Fqdn *string `json:"Fqdn,omitempty"` + UserAgent *string `json:"UserAgent,omitempty"` + AttemptLatency *int `json:"AttemptLatency,omitempty"` + + SessionToken *string `json:"SessionToken,omitempty"` + Region *string `json:"Region,omitempty"` + AccessKey *string `json:"AccessKey,omitempty"` + HTTPStatusCode *int `json:"HttpStatusCode,omitempty"` + XAmzID2 *string `json:"XAmzId2,omitempty"` + XAmzRequestID *string `json:"XAmznRequestId,omitempty"` + + AWSException *string `json:"AwsException,omitempty"` + AWSExceptionMessage *string `json:"AwsExceptionMessage,omitempty"` + SDKException *string `json:"SdkException,omitempty"` + SDKExceptionMessage *string `json:"SdkExceptionMessage,omitempty"` + + FinalHTTPStatusCode *int `json:"FinalHttpStatusCode,omitempty"` + FinalAWSException *string `json:"FinalAwsException,omitempty"` + FinalAWSExceptionMessage *string `json:"FinalAwsExceptionMessage,omitempty"` + FinalSDKException *string `json:"FinalSdkException,omitempty"` + FinalSDKExceptionMessage *string `json:"FinalSdkExceptionMessage,omitempty"` + + DestinationIP *string `json:"DestinationIp,omitempty"` + ConnectionReused *int `json:"ConnectionReused,omitempty"` + + AcquireConnectionLatency *int `json:"AcquireConnectionLatency,omitempty"` + ConnectLatency *int `json:"ConnectLatency,omitempty"` + RequestLatency *int `json:"RequestLatency,omitempty"` + DNSLatency *int `json:"DnsLatency,omitempty"` + TCPLatency *int `json:"TcpLatency,omitempty"` + SSLLatency *int `json:"SslLatency,omitempty"` + + MaxRetriesExceeded *int `json:"MaxRetriesExceeded,omitempty"` +} + +func (m *metric) TruncateFields() { + m.ClientID = truncateString(m.ClientID, 255) + m.UserAgent = truncateString(m.UserAgent, 256) + + m.AWSException = truncateString(m.AWSException, 128) + m.AWSExceptionMessage = truncateString(m.AWSExceptionMessage, 512) + + m.SDKException = truncateString(m.SDKException, 128) + m.SDKExceptionMessage = truncateString(m.SDKExceptionMessage, 512) + + m.FinalAWSException = truncateString(m.FinalAWSException, 128) + m.FinalAWSExceptionMessage = truncateString(m.FinalAWSExceptionMessage, 512) + + m.FinalSDKException = truncateString(m.FinalSDKException, 128) + m.FinalSDKExceptionMessage = truncateString(m.FinalSDKExceptionMessage, 512) +} + +func truncateString(v *string, l int) *string { + if v != nil && len(*v) > l { + nv := (*v)[:l] + return &nv + } + + return v +} + +func (m *metric) SetException(e metricException) { + switch te := e.(type) { + case awsException: + m.AWSException = aws.String(te.exception) + m.AWSExceptionMessage = aws.String(te.message) + case sdkException: + m.SDKException = aws.String(te.exception) + m.SDKExceptionMessage = aws.String(te.message) + } +} + +func (m *metric) SetFinalException(e metricException) { + switch te := e.(type) { + case awsException: + m.FinalAWSException = aws.String(te.exception) + m.FinalAWSExceptionMessage = aws.String(te.message) + case sdkException: + m.FinalSDKException = aws.String(te.exception) + m.FinalSDKExceptionMessage = aws.String(te.message) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go new file mode 100644 index 00000000..514fc373 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_chan.go @@ -0,0 +1,54 @@ +package csm + +import ( + "sync/atomic" +) + +const ( + runningEnum = iota + pausedEnum +) + +var ( + // MetricsChannelSize of metrics to hold in the channel + MetricsChannelSize = 100 +) + +type metricChan struct { + ch chan metric + paused int64 +} + +func newMetricChan(size int) metricChan { + return metricChan{ + ch: make(chan metric, size), + } +} + +func (ch *metricChan) Pause() { + atomic.StoreInt64(&ch.paused, pausedEnum) +} + +func (ch *metricChan) Continue() { + atomic.StoreInt64(&ch.paused, runningEnum) +} + +func (ch *metricChan) IsPaused() bool { + v := atomic.LoadInt64(&ch.paused) + return v == pausedEnum +} + +// Push will push metrics to the metric channel if the channel +// is not paused +func (ch *metricChan) Push(m metric) bool { + if ch.IsPaused() { + return false + } + + select { + case ch.ch <- m: + return true + default: + return false + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go new file mode 100644 index 00000000..54a99280 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/metric_exception.go @@ -0,0 +1,26 @@ +package csm + +type metricException interface { + Exception() string + Message() string +} + +type requestException struct { + exception string + message string +} + +func (e requestException) Exception() string { + return e.exception +} +func (e requestException) Message() string { + return e.message +} + +type awsException struct { + requestException +} + +type sdkException struct { + requestException +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go b/vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go new file mode 100644 index 00000000..d9aa5b06 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/csm/reporter.go @@ -0,0 +1,260 @@ +package csm + +import ( + "encoding/json" + "net" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" +) + +const ( + // DefaultPort is used when no port is specified + DefaultPort = "31000" +) + +// Reporter will gather metrics of API requests made and +// send those metrics to the CSM endpoint. +type Reporter struct { + clientID string + url string + conn net.Conn + metricsCh metricChan + done chan struct{} +} + +var ( + sender *Reporter +) + +func connect(url string) error { + const network = "udp" + if err := sender.connect(network, url); err != nil { + return err + } + + if sender.done == nil { + sender.done = make(chan struct{}) + go sender.start() + } + + return nil +} + +func newReporter(clientID, url string) *Reporter { + return &Reporter{ + clientID: clientID, + url: url, + metricsCh: newMetricChan(MetricsChannelSize), + } +} + +func (rep *Reporter) sendAPICallAttemptMetric(r *request.Request) { + if rep == nil { + return + } + + now := time.Now() + creds, _ := r.Config.Credentials.Get() + + m := metric{ + ClientID: aws.String(rep.clientID), + API: aws.String(r.Operation.Name), + Service: aws.String(r.ClientInfo.ServiceID), + Timestamp: (*metricTime)(&now), + UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")), + Region: r.Config.Region, + Type: aws.String("ApiCallAttempt"), + Version: aws.Int(1), + + XAmzRequestID: aws.String(r.RequestID), + + AttemptCount: aws.Int(r.RetryCount + 1), + AttemptLatency: aws.Int(int(now.Sub(r.AttemptTime).Nanoseconds() / int64(time.Millisecond))), + AccessKey: aws.String(creds.AccessKeyID), + } + + if r.HTTPResponse != nil { + m.HTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode) + } + + if r.Error != nil { + if awserr, ok := r.Error.(awserr.Error); ok { + m.SetException(getMetricException(awserr)) + } + } + + m.TruncateFields() + rep.metricsCh.Push(m) +} + +func getMetricException(err awserr.Error) metricException { + msg := err.Error() + code := err.Code() + + switch code { + case "RequestError", + request.ErrCodeSerialization, + request.CanceledErrorCode: + return sdkException{ + requestException{exception: code, message: msg}, + } + default: + return awsException{ + requestException{exception: code, message: msg}, + } + } +} + +func (rep *Reporter) sendAPICallMetric(r *request.Request) { + if rep == nil { + return + } + + now := time.Now() + m := metric{ + ClientID: aws.String(rep.clientID), + API: aws.String(r.Operation.Name), + Service: aws.String(r.ClientInfo.ServiceID), + Timestamp: (*metricTime)(&now), + UserAgent: aws.String(r.HTTPRequest.Header.Get("User-Agent")), + Type: aws.String("ApiCall"), + AttemptCount: aws.Int(r.RetryCount + 1), + Region: r.Config.Region, + Latency: aws.Int(int(time.Now().Sub(r.Time) / time.Millisecond)), + XAmzRequestID: aws.String(r.RequestID), + MaxRetriesExceeded: aws.Int(boolIntValue(r.RetryCount >= r.MaxRetries())), + } + + if r.HTTPResponse != nil { + m.FinalHTTPStatusCode = aws.Int(r.HTTPResponse.StatusCode) + } + + if r.Error != nil { + if awserr, ok := r.Error.(awserr.Error); ok { + m.SetFinalException(getMetricException(awserr)) + } + } + + m.TruncateFields() + + // TODO: Probably want to figure something out for logging dropped + // metrics + rep.metricsCh.Push(m) +} + +func (rep *Reporter) connect(network, url string) error { + if rep.conn != nil { + rep.conn.Close() + } + + conn, err := net.Dial(network, url) + if err != nil { + return awserr.New("UDPError", "Could not connect", err) + } + + rep.conn = conn + + return nil +} + +func (rep *Reporter) close() { + if rep.done != nil { + close(rep.done) + } + + rep.metricsCh.Pause() +} + +func (rep *Reporter) start() { + defer func() { + rep.metricsCh.Pause() + }() + + for { + select { + case <-rep.done: + rep.done = nil + return + case m := <-rep.metricsCh.ch: + // TODO: What to do with this error? Probably should just log + b, err := json.Marshal(m) + if err != nil { + continue + } + + rep.conn.Write(b) + } + } +} + +// Pause will pause the metric channel preventing any new metrics from +// being added. +func (rep *Reporter) Pause() { + lock.Lock() + defer lock.Unlock() + + if rep == nil { + return + } + + rep.close() +} + +// Continue will reopen the metric channel and allow for monitoring +// to be resumed. +func (rep *Reporter) Continue() { + lock.Lock() + defer lock.Unlock() + if rep == nil { + return + } + + if !rep.metricsCh.IsPaused() { + return + } + + rep.metricsCh.Continue() +} + +// InjectHandlers will will enable client side metrics and inject the proper +// handlers to handle how metrics are sent. +// +// Example: +// // Start must be called in order to inject the correct handlers +// r, err := csm.Start("clientID", "127.0.0.1:8094") +// if err != nil { +// panic(fmt.Errorf("expected no error, but received %v", err)) +// } +// +// sess := session.NewSession() +// r.InjectHandlers(&sess.Handlers) +// +// // create a new service client with our client side metric session +// svc := s3.New(sess) +func (rep *Reporter) InjectHandlers(handlers *request.Handlers) { + if rep == nil { + return + } + + handlers.Complete.PushFrontNamed(request.NamedHandler{ + Name: APICallMetricHandlerName, + Fn: rep.sendAPICallMetric, + }) + + handlers.CompleteAttempt.PushFrontNamed(request.NamedHandler{ + Name: APICallAttemptMetricHandlerName, + Fn: rep.sendAPICallAttemptMetric, + }) +} + +// boolIntValue return 1 for true and 0 for false. +func boolIntValue(b bool) int { + if b { + return 1 + } + + return 0 +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go new file mode 100644 index 00000000..23bb639e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/defaults.go @@ -0,0 +1,207 @@ +// Package defaults is a collection of helpers to retrieve the SDK's default +// configuration and handlers. +// +// Generally this package shouldn't be used directly, but session.Session +// instead. This package is useful when you need to reset the defaults +// of a session or service client to the SDK defaults before setting +// additional parameters. +package defaults + +import ( + "fmt" + "net" + "net/http" + "net/url" + "os" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds" + "github.com/aws/aws-sdk-go/aws/credentials/endpointcreds" + "github.com/aws/aws-sdk-go/aws/ec2metadata" + "github.com/aws/aws-sdk-go/aws/endpoints" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/shareddefaults" +) + +// A Defaults provides a collection of default values for SDK clients. +type Defaults struct { + Config *aws.Config + Handlers request.Handlers +} + +// Get returns the SDK's default values with Config and handlers pre-configured. +func Get() Defaults { + cfg := Config() + handlers := Handlers() + cfg.Credentials = CredChain(cfg, handlers) + + return Defaults{ + Config: cfg, + Handlers: handlers, + } +} + +// Config returns the default configuration without credentials. +// To retrieve a config with credentials also included use +// `defaults.Get().Config` instead. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the configuration of an +// existing service client or session. +func Config() *aws.Config { + return aws.NewConfig(). + WithCredentials(credentials.AnonymousCredentials). + WithRegion(os.Getenv("AWS_REGION")). + WithHTTPClient(http.DefaultClient). + WithMaxRetries(aws.UseServiceDefaultRetries). + WithLogger(aws.NewDefaultLogger()). + WithLogLevel(aws.LogOff). + WithEndpointResolver(endpoints.DefaultResolver()) +} + +// Handlers returns the default request handlers. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the request handlers of an +// existing service client or session. +func Handlers() request.Handlers { + var handlers request.Handlers + + handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler) + handlers.Validate.AfterEachFn = request.HandlerListStopOnError + handlers.Build.PushBackNamed(corehandlers.SDKVersionUserAgentHandler) + handlers.Build.PushBackNamed(corehandlers.AddHostExecEnvUserAgentHander) + handlers.Build.AfterEachFn = request.HandlerListStopOnError + handlers.Sign.PushBackNamed(corehandlers.BuildContentLengthHandler) + handlers.Send.PushBackNamed(corehandlers.ValidateReqSigHandler) + handlers.Send.PushBackNamed(corehandlers.SendHandler) + handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler) + handlers.ValidateResponse.PushBackNamed(corehandlers.ValidateResponseHandler) + + return handlers +} + +// CredChain returns the default credential chain. +// +// Generally you shouldn't need to use this method directly, but +// is available if you need to reset the credentials of an +// existing service client or session's Config. +func CredChain(cfg *aws.Config, handlers request.Handlers) *credentials.Credentials { + return credentials.NewCredentials(&credentials.ChainProvider{ + VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), + Providers: CredProviders(cfg, handlers), + }) +} + +// CredProviders returns the slice of providers used in +// the default credential chain. +// +// For applications that need to use some other provider (for example use +// different environment variables for legacy reasons) but still fall back +// on the default chain of providers. This allows that default chaint to be +// automatically updated +func CredProviders(cfg *aws.Config, handlers request.Handlers) []credentials.Provider { + return []credentials.Provider{ + &credentials.EnvProvider{}, + &credentials.SharedCredentialsProvider{Filename: "", Profile: ""}, + RemoteCredProvider(*cfg, handlers), + } +} + +const ( + httpProviderAuthorizationEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN" + httpProviderEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI" +) + +// RemoteCredProvider returns a credentials provider for the default remote +// endpoints such as EC2 or ECS Roles. +func RemoteCredProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { + if u := os.Getenv(httpProviderEnvVar); len(u) > 0 { + return localHTTPCredProvider(cfg, handlers, u) + } + + if uri := os.Getenv(shareddefaults.ECSCredsProviderEnvVar); len(uri) > 0 { + u := fmt.Sprintf("%s%s", shareddefaults.ECSContainerCredentialsURI, uri) + return httpCredProvider(cfg, handlers, u) + } + + return ec2RoleProvider(cfg, handlers) +} + +var lookupHostFn = net.LookupHost + +func isLoopbackHost(host string) (bool, error) { + ip := net.ParseIP(host) + if ip != nil { + return ip.IsLoopback(), nil + } + + // Host is not an ip, perform lookup + addrs, err := lookupHostFn(host) + if err != nil { + return false, err + } + for _, addr := range addrs { + if !net.ParseIP(addr).IsLoopback() { + return false, nil + } + } + + return true, nil +} + +func localHTTPCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { + var errMsg string + + parsed, err := url.Parse(u) + if err != nil { + errMsg = fmt.Sprintf("invalid URL, %v", err) + } else { + host := aws.URLHostname(parsed) + if len(host) == 0 { + errMsg = "unable to parse host from local HTTP cred provider URL" + } else if isLoopback, loopbackErr := isLoopbackHost(host); loopbackErr != nil { + errMsg = fmt.Sprintf("failed to resolve host %q, %v", host, loopbackErr) + } else if !isLoopback { + errMsg = fmt.Sprintf("invalid endpoint host, %q, only loopback hosts are allowed.", host) + } + } + + if len(errMsg) > 0 { + if cfg.Logger != nil { + cfg.Logger.Log("Ignoring, HTTP credential provider", errMsg, err) + } + return credentials.ErrorProvider{ + Err: awserr.New("CredentialsEndpointError", errMsg, err), + ProviderName: endpointcreds.ProviderName, + } + } + + return httpCredProvider(cfg, handlers, u) +} + +func httpCredProvider(cfg aws.Config, handlers request.Handlers, u string) credentials.Provider { + return endpointcreds.NewProviderClient(cfg, handlers, u, + func(p *endpointcreds.Provider) { + p.ExpiryWindow = 5 * time.Minute + p.AuthorizationToken = os.Getenv(httpProviderAuthorizationEnvVar) + }, + ) +} + +func ec2RoleProvider(cfg aws.Config, handlers request.Handlers) credentials.Provider { + resolver := cfg.EndpointResolver + if resolver == nil { + resolver = endpoints.DefaultResolver() + } + + e, _ := resolver.EndpointFor(endpoints.Ec2metadataServiceID, "") + return &ec2rolecreds.EC2RoleProvider{ + Client: ec2metadata.NewClient(cfg, handlers, e.URL, e.SigningRegion), + ExpiryWindow: 5 * time.Minute, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go b/vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go new file mode 100644 index 00000000..ca0ee1dc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/defaults/shared_config.go @@ -0,0 +1,27 @@ +package defaults + +import ( + "github.com/aws/aws-sdk-go/internal/shareddefaults" +) + +// SharedCredentialsFilename returns the SDK's default file path +// for the shared credentials file. +// +// Builds the shared config file path based on the OS's platform. +// +// - Linux/Unix: $HOME/.aws/credentials +// - Windows: %USERPROFILE%\.aws\credentials +func SharedCredentialsFilename() string { + return shareddefaults.SharedCredentialsFilename() +} + +// SharedConfigFilename returns the SDK's default file path for +// the shared config file. +// +// Builds the shared config file path based on the OS's platform. +// +// - Linux/Unix: $HOME/.aws/config +// - Windows: %USERPROFILE%\.aws\config +func SharedConfigFilename() string { + return shareddefaults.SharedConfigFilename() +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport.go b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport.go new file mode 100644 index 00000000..ea9ebb6f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport.go @@ -0,0 +1,26 @@ +// +build go1.7 + +package session + +import ( + "net" + "net/http" + "time" +) + +// Transport that should be used when a custom CA bundle is specified with the +// SDK. +func getCABundleTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_5.go b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_5.go new file mode 100644 index 00000000..fec39dfc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_5.go @@ -0,0 +1,22 @@ +// +build !go1.6,go1.5 + +package session + +import ( + "net" + "net/http" + "time" +) + +// Transport that should be used when a custom CA bundle is specified with the +// SDK. +func getCABundleTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_6.go b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_6.go new file mode 100644 index 00000000..1c5a5391 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/cabundle_transport_1_6.go @@ -0,0 +1,23 @@ +// +build !go1.7,go1.6 + +package session + +import ( + "net" + "net/http" + "time" +) + +// Transport that should be used when a custom CA bundle is specified with the +// SDK. +func getCABundleTransport() *http.Transport { + return &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go new file mode 100644 index 00000000..38a7b05a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/doc.go @@ -0,0 +1,273 @@ +/* +Package session provides configuration for the SDK's service clients. + +Sessions can be shared across all service clients that share the same base +configuration. The Session is built from the SDK's default configuration and +request handlers. + +Sessions should be cached when possible, because creating a new Session will +load all configuration values from the environment, and config files each time +the Session is created. Sharing the Session value across all of your service +clients will ensure the configuration is loaded the fewest number of times possible. + +Concurrency + +Sessions are safe to use concurrently as long as the Session is not being +modified. The SDK will not modify the Session once the Session has been created. +Creating service clients concurrently from a shared Session is safe. + +Sessions from Shared Config + +Sessions can be created using the method above that will only load the +additional config if the AWS_SDK_LOAD_CONFIG environment variable is set. +Alternatively you can explicitly create a Session with shared config enabled. +To do this you can use NewSessionWithOptions to configure how the Session will +be created. Using the NewSessionWithOptions with SharedConfigState set to +SharedConfigEnable will create the session as if the AWS_SDK_LOAD_CONFIG +environment variable was set. + +Creating Sessions + +When creating Sessions optional aws.Config values can be passed in that will +override the default, or loaded config values the Session is being created +with. This allows you to provide additional, or case based, configuration +as needed. + +By default NewSession will only load credentials from the shared credentials +file (~/.aws/credentials). If the AWS_SDK_LOAD_CONFIG environment variable is +set to a truthy value the Session will be created from the configuration +values from the shared config (~/.aws/config) and shared credentials +(~/.aws/credentials) files. See the section Sessions from Shared Config for +more information. + +Create a Session with the default config and request handlers. With credentials +region, and profile loaded from the environment and shared config automatically. +Requires the AWS_PROFILE to be set, or "default" is used. + + // Create Session + sess := session.Must(session.NewSession()) + + // Create a Session with a custom region + sess := session.Must(session.NewSession(&aws.Config{ + Region: aws.String("us-east-1"), + })) + + // Create a S3 client instance from a session + sess := session.Must(session.NewSession()) + + svc := s3.New(sess) + +Create Session With Option Overrides + +In addition to NewSession, Sessions can be created using NewSessionWithOptions. +This func allows you to control and override how the Session will be created +through code instead of being driven by environment variables only. + +Use NewSessionWithOptions when you want to provide the config profile, or +override the shared config state (AWS_SDK_LOAD_CONFIG). + + // Equivalent to session.NewSession() + sess := session.Must(session.NewSessionWithOptions(session.Options{ + // Options + })) + + // Specify profile to load for the session's config + sess := session.Must(session.NewSessionWithOptions(session.Options{ + Profile: "profile_name", + })) + + // Specify profile for config and region for requests + sess := session.Must(session.NewSessionWithOptions(session.Options{ + Config: aws.Config{Region: aws.String("us-east-1")}, + Profile: "profile_name", + })) + + // Force enable Shared Config support + sess := session.Must(session.NewSessionWithOptions(session.Options{ + SharedConfigState: session.SharedConfigEnable, + })) + +Adding Handlers + +You can add handlers to a session for processing HTTP requests. All service +clients that use the session inherit the handlers. For example, the following +handler logs every request and its payload made by a service client: + + // Create a session, and add additional handlers for all service + // clients created with the Session to inherit. Adds logging handler. + sess := session.Must(session.NewSession()) + + sess.Handlers.Send.PushFront(func(r *request.Request) { + // Log every request made and its payload + logger.Printf("Request: %s/%s, Payload: %s", + r.ClientInfo.ServiceName, r.Operation, r.Params) + }) + +Deprecated "New" function + +The New session function has been deprecated because it does not provide good +way to return errors that occur when loading the configuration files and values. +Because of this, NewSession was created so errors can be retrieved when +creating a session fails. + +Shared Config Fields + +By default the SDK will only load the shared credentials file's (~/.aws/credentials) +credentials values, and all other config is provided by the environment variables, +SDK defaults, and user provided aws.Config values. + +If the AWS_SDK_LOAD_CONFIG environment variable is set, or SharedConfigEnable +option is used to create the Session the full shared config values will be +loaded. This includes credentials, region, and support for assume role. In +addition the Session will load its configuration from both the shared config +file (~/.aws/config) and shared credentials file (~/.aws/credentials). Both +files have the same format. + +If both config files are present the configuration from both files will be +read. The Session will be created from configuration values from the shared +credentials file (~/.aws/credentials) over those in the shared config file (~/.aws/config). + +Credentials are the values the SDK should use for authenticating requests with +AWS Services. They are from a configuration file will need to include both +aws_access_key_id and aws_secret_access_key must be provided together in the +same file to be considered valid. The values will be ignored if not a complete +group. aws_session_token is an optional field that can be provided if both of +the other two fields are also provided. + + aws_access_key_id = AKID + aws_secret_access_key = SECRET + aws_session_token = TOKEN + +Assume Role values allow you to configure the SDK to assume an IAM role using +a set of credentials provided in a config file via the source_profile field. +Both "role_arn" and "source_profile" are required. The SDK supports assuming +a role with MFA token if the session option AssumeRoleTokenProvider +is set. + + role_arn = arn:aws:iam:::role/ + source_profile = profile_with_creds + external_id = 1234 + mfa_serial = + role_session_name = session_name + +Region is the region the SDK should use for looking up AWS service endpoints +and signing requests. + + region = us-east-1 + +Assume Role with MFA token + +To create a session with support for assuming an IAM role with MFA set the +session option AssumeRoleTokenProvider to a function that will prompt for the +MFA token code when the SDK assumes the role and refreshes the role's credentials. +This allows you to configure the SDK via the shared config to assumea role +with MFA tokens. + +In order for the SDK to assume a role with MFA the SharedConfigState +session option must be set to SharedConfigEnable, or AWS_SDK_LOAD_CONFIG +environment variable set. + +The shared configuration instructs the SDK to assume an IAM role with MFA +when the mfa_serial configuration field is set in the shared config +(~/.aws/config) or shared credentials (~/.aws/credentials) file. + +If mfa_serial is set in the configuration, the SDK will assume the role, and +the AssumeRoleTokenProvider session option is not set an an error will +be returned when creating the session. + + sess := session.Must(session.NewSessionWithOptions(session.Options{ + AssumeRoleTokenProvider: stscreds.StdinTokenProvider, + })) + + // Create service client value configured for credentials + // from assumed role. + svc := s3.New(sess) + +To setup assume role outside of a session see the stscreds.AssumeRoleProvider +documentation. + +Environment Variables + +When a Session is created several environment variables can be set to adjust +how the SDK functions, and what configuration data it loads when creating +Sessions. All environment values are optional, but some values like credentials +require multiple of the values to set or the partial values will be ignored. +All environment variable values are strings unless otherwise noted. + +Environment configuration values. If set both Access Key ID and Secret Access +Key must be provided. Session Token and optionally also be provided, but is +not required. + + # Access Key ID + AWS_ACCESS_KEY_ID=AKID + AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. + + # Secret Access Key + AWS_SECRET_ACCESS_KEY=SECRET + AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. + + # Session Token + AWS_SESSION_TOKEN=TOKEN + +Region value will instruct the SDK where to make service API requests to. If is +not provided in the environment the region must be provided before a service +client request is made. + + AWS_REGION=us-east-1 + + # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set, + # and AWS_REGION is not also set. + AWS_DEFAULT_REGION=us-east-1 + +Profile name the SDK should load use when loading shared config from the +configuration files. If not provided "default" will be used as the profile name. + + AWS_PROFILE=my_profile + + # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set, + # and AWS_PROFILE is not also set. + AWS_DEFAULT_PROFILE=my_profile + +SDK load config instructs the SDK to load the shared config in addition to +shared credentials. This also expands the configuration loaded so the shared +credentials will have parity with the shared config file. This also enables +Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE +env values as well. + + AWS_SDK_LOAD_CONFIG=1 + +Shared credentials file path can be set to instruct the SDK to use an alternative +file for the shared credentials. If not set the file will be loaded from +$HOME/.aws/credentials on Linux/Unix based systems, and +%USERPROFILE%\.aws\credentials on Windows. + + AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials + +Shared config file path can be set to instruct the SDK to use an alternative +file for the shared config. If not set the file will be loaded from +$HOME/.aws/config on Linux/Unix based systems, and +%USERPROFILE%\.aws\config on Windows. + + AWS_CONFIG_FILE=$HOME/my_shared_config + +Path to a custom Credentials Authority (CA) bundle PEM file that the SDK +will use instead of the default system's root CA bundle. Use this only +if you want to replace the CA bundle the SDK uses for TLS requests. + + AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle + +Enabling this option will attempt to merge the Transport into the SDK's HTTP +client. If the client's Transport is not a http.Transport an error will be +returned. If the Transport's TLS config is set this option will cause the SDK +to overwrite the Transport's TLS config's RootCAs value. If the CA bundle file +contains multiple certificates all of them will be loaded. + +The Session option CustomCABundle is also available when creating sessions +to also enable this feature. CustomCABundle session option field has priority +over the AWS_CA_BUNDLE environment variable, and will be used if both are set. + +Setting a custom HTTPClient in the aws.Config options will override this setting. +To use this option and custom HTTP client, the HTTP client needs to be provided +when creating the session. Not the service client. +*/ +package session diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go new file mode 100644 index 00000000..e3959b95 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/env_config.go @@ -0,0 +1,236 @@ +package session + +import ( + "os" + "strconv" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/defaults" +) + +// EnvProviderName provides a name of the provider when config is loaded from environment. +const EnvProviderName = "EnvConfigCredentials" + +// envConfig is a collection of environment values the SDK will read +// setup config from. All environment values are optional. But some values +// such as credentials require multiple values to be complete or the values +// will be ignored. +type envConfig struct { + // Environment configuration values. If set both Access Key ID and Secret Access + // Key must be provided. Session Token and optionally also be provided, but is + // not required. + // + // # Access Key ID + // AWS_ACCESS_KEY_ID=AKID + // AWS_ACCESS_KEY=AKID # only read if AWS_ACCESS_KEY_ID is not set. + // + // # Secret Access Key + // AWS_SECRET_ACCESS_KEY=SECRET + // AWS_SECRET_KEY=SECRET=SECRET # only read if AWS_SECRET_ACCESS_KEY is not set. + // + // # Session Token + // AWS_SESSION_TOKEN=TOKEN + Creds credentials.Value + + // Region value will instruct the SDK where to make service API requests to. If is + // not provided in the environment the region must be provided before a service + // client request is made. + // + // AWS_REGION=us-east-1 + // + // # AWS_DEFAULT_REGION is only read if AWS_SDK_LOAD_CONFIG is also set, + // # and AWS_REGION is not also set. + // AWS_DEFAULT_REGION=us-east-1 + Region string + + // Profile name the SDK should load use when loading shared configuration from the + // shared configuration files. If not provided "default" will be used as the + // profile name. + // + // AWS_PROFILE=my_profile + // + // # AWS_DEFAULT_PROFILE is only read if AWS_SDK_LOAD_CONFIG is also set, + // # and AWS_PROFILE is not also set. + // AWS_DEFAULT_PROFILE=my_profile + Profile string + + // SDK load config instructs the SDK to load the shared config in addition to + // shared credentials. This also expands the configuration loaded from the shared + // credentials to have parity with the shared config file. This also enables + // Region and Profile support for the AWS_DEFAULT_REGION and AWS_DEFAULT_PROFILE + // env values as well. + // + // AWS_SDK_LOAD_CONFIG=1 + EnableSharedConfig bool + + // Shared credentials file path can be set to instruct the SDK to use an alternate + // file for the shared credentials. If not set the file will be loaded from + // $HOME/.aws/credentials on Linux/Unix based systems, and + // %USERPROFILE%\.aws\credentials on Windows. + // + // AWS_SHARED_CREDENTIALS_FILE=$HOME/my_shared_credentials + SharedCredentialsFile string + + // Shared config file path can be set to instruct the SDK to use an alternate + // file for the shared config. If not set the file will be loaded from + // $HOME/.aws/config on Linux/Unix based systems, and + // %USERPROFILE%\.aws\config on Windows. + // + // AWS_CONFIG_FILE=$HOME/my_shared_config + SharedConfigFile string + + // Sets the path to a custom Credentials Authority (CA) Bundle PEM file + // that the SDK will use instead of the system's root CA bundle. + // Only use this if you want to configure the SDK to use a custom set + // of CAs. + // + // Enabling this option will attempt to merge the Transport + // into the SDK's HTTP client. If the client's Transport is + // not a http.Transport an error will be returned. If the + // Transport's TLS config is set this option will cause the + // SDK to overwrite the Transport's TLS config's RootCAs value. + // + // Setting a custom HTTPClient in the aws.Config options will override this setting. + // To use this option and custom HTTP client, the HTTP client needs to be provided + // when creating the session. Not the service client. + // + // AWS_CA_BUNDLE=$HOME/my_custom_ca_bundle + CustomCABundle string + + csmEnabled string + CSMEnabled bool + CSMPort string + CSMClientID string + + enableEndpointDiscovery string + // Enables endpoint discovery via environment variables. + // + // AWS_ENABLE_ENDPOINT_DISCOVERY=true + EnableEndpointDiscovery *bool +} + +var ( + csmEnabledEnvKey = []string{ + "AWS_CSM_ENABLED", + } + csmPortEnvKey = []string{ + "AWS_CSM_PORT", + } + csmClientIDEnvKey = []string{ + "AWS_CSM_CLIENT_ID", + } + credAccessEnvKey = []string{ + "AWS_ACCESS_KEY_ID", + "AWS_ACCESS_KEY", + } + credSecretEnvKey = []string{ + "AWS_SECRET_ACCESS_KEY", + "AWS_SECRET_KEY", + } + credSessionEnvKey = []string{ + "AWS_SESSION_TOKEN", + } + + enableEndpointDiscoveryEnvKey = []string{ + "AWS_ENABLE_ENDPOINT_DISCOVERY", + } + + regionEnvKeys = []string{ + "AWS_REGION", + "AWS_DEFAULT_REGION", // Only read if AWS_SDK_LOAD_CONFIG is also set + } + profileEnvKeys = []string{ + "AWS_PROFILE", + "AWS_DEFAULT_PROFILE", // Only read if AWS_SDK_LOAD_CONFIG is also set + } + sharedCredsFileEnvKey = []string{ + "AWS_SHARED_CREDENTIALS_FILE", + } + sharedConfigFileEnvKey = []string{ + "AWS_CONFIG_FILE", + } +) + +// loadEnvConfig retrieves the SDK's environment configuration. +// See `envConfig` for the values that will be retrieved. +// +// If the environment variable `AWS_SDK_LOAD_CONFIG` is set to a truthy value +// the shared SDK config will be loaded in addition to the SDK's specific +// configuration values. +func loadEnvConfig() envConfig { + enableSharedConfig, _ := strconv.ParseBool(os.Getenv("AWS_SDK_LOAD_CONFIG")) + return envConfigLoad(enableSharedConfig) +} + +// loadEnvSharedConfig retrieves the SDK's environment configuration, and the +// SDK shared config. See `envConfig` for the values that will be retrieved. +// +// Loads the shared configuration in addition to the SDK's specific configuration. +// This will load the same values as `loadEnvConfig` if the `AWS_SDK_LOAD_CONFIG` +// environment variable is set. +func loadSharedEnvConfig() envConfig { + return envConfigLoad(true) +} + +func envConfigLoad(enableSharedConfig bool) envConfig { + cfg := envConfig{} + + cfg.EnableSharedConfig = enableSharedConfig + + setFromEnvVal(&cfg.Creds.AccessKeyID, credAccessEnvKey) + setFromEnvVal(&cfg.Creds.SecretAccessKey, credSecretEnvKey) + setFromEnvVal(&cfg.Creds.SessionToken, credSessionEnvKey) + + // CSM environment variables + setFromEnvVal(&cfg.csmEnabled, csmEnabledEnvKey) + setFromEnvVal(&cfg.CSMPort, csmPortEnvKey) + setFromEnvVal(&cfg.CSMClientID, csmClientIDEnvKey) + cfg.CSMEnabled = len(cfg.csmEnabled) > 0 + + // Require logical grouping of credentials + if len(cfg.Creds.AccessKeyID) == 0 || len(cfg.Creds.SecretAccessKey) == 0 { + cfg.Creds = credentials.Value{} + } else { + cfg.Creds.ProviderName = EnvProviderName + } + + regionKeys := regionEnvKeys + profileKeys := profileEnvKeys + if !cfg.EnableSharedConfig { + regionKeys = regionKeys[:1] + profileKeys = profileKeys[:1] + } + + setFromEnvVal(&cfg.Region, regionKeys) + setFromEnvVal(&cfg.Profile, profileKeys) + + // endpoint discovery is in reference to it being enabled. + setFromEnvVal(&cfg.enableEndpointDiscovery, enableEndpointDiscoveryEnvKey) + if len(cfg.enableEndpointDiscovery) > 0 { + cfg.EnableEndpointDiscovery = aws.Bool(cfg.enableEndpointDiscovery != "false") + } + + setFromEnvVal(&cfg.SharedCredentialsFile, sharedCredsFileEnvKey) + setFromEnvVal(&cfg.SharedConfigFile, sharedConfigFileEnvKey) + + if len(cfg.SharedCredentialsFile) == 0 { + cfg.SharedCredentialsFile = defaults.SharedCredentialsFilename() + } + if len(cfg.SharedConfigFile) == 0 { + cfg.SharedConfigFile = defaults.SharedConfigFilename() + } + + cfg.CustomCABundle = os.Getenv("AWS_CA_BUNDLE") + + return cfg +} + +func setFromEnvVal(dst *string, keys []string) { + for _, k := range keys { + if v := os.Getenv(k); len(v) > 0 { + *dst = v + break + } + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/session.go b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go new file mode 100644 index 00000000..be4b5f07 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/session.go @@ -0,0 +1,719 @@ +package session + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/corehandlers" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/credentials/processcreds" + "github.com/aws/aws-sdk-go/aws/credentials/stscreds" + "github.com/aws/aws-sdk-go/aws/csm" + "github.com/aws/aws-sdk-go/aws/defaults" + "github.com/aws/aws-sdk-go/aws/endpoints" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/shareddefaults" +) + +const ( + // ErrCodeSharedConfig represents an error that occurs in the shared + // configuration logic + ErrCodeSharedConfig = "SharedConfigErr" +) + +// ErrSharedConfigSourceCollision will be returned if a section contains both +// source_profile and credential_source +var ErrSharedConfigSourceCollision = awserr.New(ErrCodeSharedConfig, "only source profile or credential source can be specified, not both", nil) + +// ErrSharedConfigECSContainerEnvVarEmpty will be returned if the environment +// variables are empty and Environment was set as the credential source +var ErrSharedConfigECSContainerEnvVarEmpty = awserr.New(ErrCodeSharedConfig, "EcsContainer was specified as the credential_source, but 'AWS_CONTAINER_CREDENTIALS_RELATIVE_URI' was not set", nil) + +// ErrSharedConfigInvalidCredSource will be returned if an invalid credential source was provided +var ErrSharedConfigInvalidCredSource = awserr.New(ErrCodeSharedConfig, "credential source values must be EcsContainer, Ec2InstanceMetadata, or Environment", nil) + +// A Session provides a central location to create service clients from and +// store configurations and request handlers for those services. +// +// Sessions are safe to create service clients concurrently, but it is not safe +// to mutate the Session concurrently. +// +// The Session satisfies the service client's client.ConfigProvider. +type Session struct { + Config *aws.Config + Handlers request.Handlers +} + +// New creates a new instance of the handlers merging in the provided configs +// on top of the SDK's default configurations. Once the Session is created it +// can be mutated to modify the Config or Handlers. The Session is safe to be +// read concurrently, but it should not be written to concurrently. +// +// If the AWS_SDK_LOAD_CONFIG environment is set to a truthy value, the New +// method could now encounter an error when loading the configuration. When +// The environment variable is set, and an error occurs, New will return a +// session that will fail all requests reporting the error that occurred while +// loading the session. Use NewSession to get the error when creating the +// session. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded, in addition to +// the shared credentials file (~/.aws/credentials). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. +// +// Deprecated: Use NewSession functions to create sessions instead. NewSession +// has the same functionality as New except an error can be returned when the +// func is called instead of waiting to receive an error until a request is made. +func New(cfgs ...*aws.Config) *Session { + // load initial config from environment + envCfg := loadEnvConfig() + + if envCfg.EnableSharedConfig { + var cfg aws.Config + cfg.MergeIn(cfgs...) + s, err := NewSessionWithOptions(Options{ + Config: cfg, + SharedConfigState: SharedConfigEnable, + }) + if err != nil { + // Old session.New expected all errors to be discovered when + // a request is made, and would report the errors then. This + // needs to be replicated if an error occurs while creating + // the session. + msg := "failed to create session with AWS_SDK_LOAD_CONFIG enabled. " + + "Use session.NewSession to handle errors occurring during session creation." + + // Session creation failed, need to report the error and prevent + // any requests from succeeding. + s = &Session{Config: defaults.Config()} + s.Config.MergeIn(cfgs...) + s.Config.Logger.Log("ERROR:", msg, "Error:", err) + s.Handlers.Validate.PushBack(func(r *request.Request) { + r.Error = err + }) + } + + return s + } + + s := deprecatedNewSession(cfgs...) + if envCfg.CSMEnabled { + enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger) + } + + return s +} + +// NewSession returns a new Session created from SDK defaults, config files, +// environment, and user provided config files. Once the Session is created +// it can be mutated to modify the Config or Handlers. The Session is safe to +// be read concurrently, but it should not be written to concurrently. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded in addition to +// the shared credentials file (~/.aws/credentials). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. Enabling the Shared Config will also allow the Session +// to be built with retrieving credentials with AssumeRole set in the config. +// +// See the NewSessionWithOptions func for information on how to override or +// control through code how the Session will be created. Such as specifying the +// config profile, and controlling if shared config is enabled or not. +func NewSession(cfgs ...*aws.Config) (*Session, error) { + opts := Options{} + opts.Config.MergeIn(cfgs...) + + return NewSessionWithOptions(opts) +} + +// SharedConfigState provides the ability to optionally override the state +// of the session's creation based on the shared config being enabled or +// disabled. +type SharedConfigState int + +const ( + // SharedConfigStateFromEnv does not override any state of the + // AWS_SDK_LOAD_CONFIG env var. It is the default value of the + // SharedConfigState type. + SharedConfigStateFromEnv SharedConfigState = iota + + // SharedConfigDisable overrides the AWS_SDK_LOAD_CONFIG env var value + // and disables the shared config functionality. + SharedConfigDisable + + // SharedConfigEnable overrides the AWS_SDK_LOAD_CONFIG env var value + // and enables the shared config functionality. + SharedConfigEnable +) + +// Options provides the means to control how a Session is created and what +// configuration values will be loaded. +// +type Options struct { + // Provides config values for the SDK to use when creating service clients + // and making API requests to services. Any value set in with this field + // will override the associated value provided by the SDK defaults, + // environment or config files where relevant. + // + // If not set, configuration values from from SDK defaults, environment, + // config will be used. + Config aws.Config + + // Overrides the config profile the Session should be created from. If not + // set the value of the environment variable will be loaded (AWS_PROFILE, + // or AWS_DEFAULT_PROFILE if the Shared Config is enabled). + // + // If not set and environment variables are not set the "default" + // (DefaultSharedConfigProfile) will be used as the profile to load the + // session config from. + Profile string + + // Instructs how the Session will be created based on the AWS_SDK_LOAD_CONFIG + // environment variable. By default a Session will be created using the + // value provided by the AWS_SDK_LOAD_CONFIG environment variable. + // + // Setting this value to SharedConfigEnable or SharedConfigDisable + // will allow you to override the AWS_SDK_LOAD_CONFIG environment variable + // and enable or disable the shared config functionality. + SharedConfigState SharedConfigState + + // Ordered list of files the session will load configuration from. + // It will override environment variable AWS_SHARED_CREDENTIALS_FILE, AWS_CONFIG_FILE. + SharedConfigFiles []string + + // When the SDK's shared config is configured to assume a role with MFA + // this option is required in order to provide the mechanism that will + // retrieve the MFA token. There is no default value for this field. If + // it is not set an error will be returned when creating the session. + // + // This token provider will be called when ever the assumed role's + // credentials need to be refreshed. Within the context of service clients + // all sharing the same session the SDK will ensure calls to the token + // provider are atomic. When sharing a token provider across multiple + // sessions additional synchronization logic is needed to ensure the + // token providers do not introduce race conditions. It is recommend to + // share the session where possible. + // + // stscreds.StdinTokenProvider is a basic implementation that will prompt + // from stdin for the MFA token code. + // + // This field is only used if the shared configuration is enabled, and + // the config enables assume role wit MFA via the mfa_serial field. + AssumeRoleTokenProvider func() (string, error) + + // Reader for a custom Credentials Authority (CA) bundle in PEM format that + // the SDK will use instead of the default system's root CA bundle. Use this + // only if you want to replace the CA bundle the SDK uses for TLS requests. + // + // Enabling this option will attempt to merge the Transport into the SDK's HTTP + // client. If the client's Transport is not a http.Transport an error will be + // returned. If the Transport's TLS config is set this option will cause the SDK + // to overwrite the Transport's TLS config's RootCAs value. If the CA + // bundle reader contains multiple certificates all of them will be loaded. + // + // The Session option CustomCABundle is also available when creating sessions + // to also enable this feature. CustomCABundle session option field has priority + // over the AWS_CA_BUNDLE environment variable, and will be used if both are set. + CustomCABundle io.Reader +} + +// NewSessionWithOptions returns a new Session created from SDK defaults, config files, +// environment, and user provided config files. This func uses the Options +// values to configure how the Session is created. +// +// If the AWS_SDK_LOAD_CONFIG environment variable is set to a truthy value +// the shared config file (~/.aws/config) will also be loaded in addition to +// the shared credentials file (~/.aws/credentials). Values set in both the +// shared config, and shared credentials will be taken from the shared +// credentials file. Enabling the Shared Config will also allow the Session +// to be built with retrieving credentials with AssumeRole set in the config. +// +// // Equivalent to session.New +// sess := session.Must(session.NewSessionWithOptions(session.Options{})) +// +// // Specify profile to load for the session's config +// sess := session.Must(session.NewSessionWithOptions(session.Options{ +// Profile: "profile_name", +// })) +// +// // Specify profile for config and region for requests +// sess := session.Must(session.NewSessionWithOptions(session.Options{ +// Config: aws.Config{Region: aws.String("us-east-1")}, +// Profile: "profile_name", +// })) +// +// // Force enable Shared Config support +// sess := session.Must(session.NewSessionWithOptions(session.Options{ +// SharedConfigState: session.SharedConfigEnable, +// })) +func NewSessionWithOptions(opts Options) (*Session, error) { + var envCfg envConfig + if opts.SharedConfigState == SharedConfigEnable { + envCfg = loadSharedEnvConfig() + } else { + envCfg = loadEnvConfig() + } + + if len(opts.Profile) > 0 { + envCfg.Profile = opts.Profile + } + + switch opts.SharedConfigState { + case SharedConfigDisable: + envCfg.EnableSharedConfig = false + case SharedConfigEnable: + envCfg.EnableSharedConfig = true + } + + // Only use AWS_CA_BUNDLE if session option is not provided. + if len(envCfg.CustomCABundle) != 0 && opts.CustomCABundle == nil { + f, err := os.Open(envCfg.CustomCABundle) + if err != nil { + return nil, awserr.New("LoadCustomCABundleError", + "failed to open custom CA bundle PEM file", err) + } + defer f.Close() + opts.CustomCABundle = f + } + + return newSession(opts, envCfg, &opts.Config) +} + +// Must is a helper function to ensure the Session is valid and there was no +// error when calling a NewSession function. +// +// This helper is intended to be used in variable initialization to load the +// Session and configuration at startup. Such as: +// +// var sess = session.Must(session.NewSession()) +func Must(sess *Session, err error) *Session { + if err != nil { + panic(err) + } + + return sess +} + +func deprecatedNewSession(cfgs ...*aws.Config) *Session { + cfg := defaults.Config() + handlers := defaults.Handlers() + + // Apply the passed in configs so the configuration can be applied to the + // default credential chain + cfg.MergeIn(cfgs...) + if cfg.EndpointResolver == nil { + // An endpoint resolver is required for a session to be able to provide + // endpoints for service client configurations. + cfg.EndpointResolver = endpoints.DefaultResolver() + } + cfg.Credentials = defaults.CredChain(cfg, handlers) + + // Reapply any passed in configs to override credentials if set + cfg.MergeIn(cfgs...) + + s := &Session{ + Config: cfg, + Handlers: handlers, + } + + initHandlers(s) + return s +} + +func enableCSM(handlers *request.Handlers, clientID string, port string, logger aws.Logger) { + logger.Log("Enabling CSM") + if len(port) == 0 { + port = csm.DefaultPort + } + + r, err := csm.Start(clientID, "127.0.0.1:"+port) + if err != nil { + return + } + r.InjectHandlers(handlers) +} + +func newSession(opts Options, envCfg envConfig, cfgs ...*aws.Config) (*Session, error) { + cfg := defaults.Config() + handlers := defaults.Handlers() + + // Get a merged version of the user provided config to determine if + // credentials were. + userCfg := &aws.Config{} + userCfg.MergeIn(cfgs...) + + // Ordered config files will be loaded in with later files overwriting + // previous config file values. + var cfgFiles []string + if opts.SharedConfigFiles != nil { + cfgFiles = opts.SharedConfigFiles + } else { + cfgFiles = []string{envCfg.SharedConfigFile, envCfg.SharedCredentialsFile} + if !envCfg.EnableSharedConfig { + // The shared config file (~/.aws/config) is only loaded if instructed + // to load via the envConfig.EnableSharedConfig (AWS_SDK_LOAD_CONFIG). + cfgFiles = cfgFiles[1:] + } + } + + // Load additional config from file(s) + sharedCfg, err := loadSharedConfig(envCfg.Profile, cfgFiles) + if err != nil { + return nil, err + } + + if err := mergeConfigSrcs(cfg, userCfg, envCfg, sharedCfg, handlers, opts); err != nil { + return nil, err + } + + s := &Session{ + Config: cfg, + Handlers: handlers, + } + + initHandlers(s) + if envCfg.CSMEnabled { + enableCSM(&s.Handlers, envCfg.CSMClientID, envCfg.CSMPort, s.Config.Logger) + } + + // Setup HTTP client with custom cert bundle if enabled + if opts.CustomCABundle != nil { + if err := loadCustomCABundle(s, opts.CustomCABundle); err != nil { + return nil, err + } + } + + return s, nil +} + +func loadCustomCABundle(s *Session, bundle io.Reader) error { + var t *http.Transport + switch v := s.Config.HTTPClient.Transport.(type) { + case *http.Transport: + t = v + default: + if s.Config.HTTPClient.Transport != nil { + return awserr.New("LoadCustomCABundleError", + "unable to load custom CA bundle, HTTPClient's transport unsupported type", nil) + } + } + if t == nil { + // Nil transport implies `http.DefaultTransport` should be used. Since + // the SDK cannot modify, nor copy the `DefaultTransport` specifying + // the values the next closest behavior. + t = getCABundleTransport() + } + + p, err := loadCertPool(bundle) + if err != nil { + return err + } + if t.TLSClientConfig == nil { + t.TLSClientConfig = &tls.Config{} + } + t.TLSClientConfig.RootCAs = p + + s.Config.HTTPClient.Transport = t + + return nil +} + +func loadCertPool(r io.Reader) (*x509.CertPool, error) { + b, err := ioutil.ReadAll(r) + if err != nil { + return nil, awserr.New("LoadCustomCABundleError", + "failed to read custom CA bundle PEM file", err) + } + + p := x509.NewCertPool() + if !p.AppendCertsFromPEM(b) { + return nil, awserr.New("LoadCustomCABundleError", + "failed to load custom CA bundle PEM file", err) + } + + return p, nil +} + +func mergeConfigSrcs(cfg, userCfg *aws.Config, envCfg envConfig, sharedCfg sharedConfig, handlers request.Handlers, sessOpts Options) error { + // Merge in user provided configuration + cfg.MergeIn(userCfg) + + // Region if not already set by user + if len(aws.StringValue(cfg.Region)) == 0 { + if len(envCfg.Region) > 0 { + cfg.WithRegion(envCfg.Region) + } else if envCfg.EnableSharedConfig && len(sharedCfg.Region) > 0 { + cfg.WithRegion(sharedCfg.Region) + } + } + + if cfg.EnableEndpointDiscovery == nil { + if envCfg.EnableEndpointDiscovery != nil { + cfg.WithEndpointDiscovery(*envCfg.EnableEndpointDiscovery) + } else if envCfg.EnableSharedConfig && sharedCfg.EnableEndpointDiscovery != nil { + cfg.WithEndpointDiscovery(*sharedCfg.EnableEndpointDiscovery) + } + } + + // Configure credentials if not already set + if cfg.Credentials == credentials.AnonymousCredentials && userCfg.Credentials == nil { + + // inspect the profile to see if a credential source has been specified. + if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.CredentialSource) > 0 { + + // if both credential_source and source_profile have been set, return an error + // as this is undefined behavior. + if len(sharedCfg.AssumeRole.SourceProfile) > 0 { + return ErrSharedConfigSourceCollision + } + + // valid credential source values + const ( + credSourceEc2Metadata = "Ec2InstanceMetadata" + credSourceEnvironment = "Environment" + credSourceECSContainer = "EcsContainer" + ) + + switch sharedCfg.AssumeRole.CredentialSource { + case credSourceEc2Metadata: + cfgCp := *cfg + p := defaults.RemoteCredProvider(cfgCp, handlers) + cfgCp.Credentials = credentials.NewCredentials(p) + + if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil { + // AssumeRole Token provider is required if doing Assume Role + // with MFA. + return AssumeRoleTokenProviderNotSetError{} + } + + cfg.Credentials = assumeRoleCredentials(cfgCp, handlers, sharedCfg, sessOpts) + case credSourceEnvironment: + cfg.Credentials = credentials.NewStaticCredentialsFromCreds( + envCfg.Creds, + ) + case credSourceECSContainer: + if len(os.Getenv(shareddefaults.ECSCredsProviderEnvVar)) == 0 { + return ErrSharedConfigECSContainerEnvVarEmpty + } + + cfgCp := *cfg + p := defaults.RemoteCredProvider(cfgCp, handlers) + creds := credentials.NewCredentials(p) + + cfg.Credentials = creds + default: + return ErrSharedConfigInvalidCredSource + } + + return nil + } + + if len(envCfg.Creds.AccessKeyID) > 0 { + cfg.Credentials = credentials.NewStaticCredentialsFromCreds( + envCfg.Creds, + ) + } else if envCfg.EnableSharedConfig && len(sharedCfg.AssumeRole.RoleARN) > 0 && sharedCfg.AssumeRoleSource != nil { + cfgCp := *cfg + cfgCp.Credentials = credentials.NewStaticCredentialsFromCreds( + sharedCfg.AssumeRoleSource.Creds, + ) + + if len(sharedCfg.AssumeRole.MFASerial) > 0 && sessOpts.AssumeRoleTokenProvider == nil { + // AssumeRole Token provider is required if doing Assume Role + // with MFA. + return AssumeRoleTokenProviderNotSetError{} + } + + cfg.Credentials = assumeRoleCredentials(cfgCp, handlers, sharedCfg, sessOpts) + } else if len(sharedCfg.Creds.AccessKeyID) > 0 { + cfg.Credentials = credentials.NewStaticCredentialsFromCreds( + sharedCfg.Creds, + ) + } else if len(sharedCfg.CredentialProcess) > 0 { + cfg.Credentials = processcreds.NewCredentials( + sharedCfg.CredentialProcess, + ) + } else { + // Fallback to default credentials provider, include mock errors + // for the credential chain so user can identify why credentials + // failed to be retrieved. + cfg.Credentials = credentials.NewCredentials(&credentials.ChainProvider{ + VerboseErrors: aws.BoolValue(cfg.CredentialsChainVerboseErrors), + Providers: []credentials.Provider{ + &credProviderError{Err: awserr.New("EnvAccessKeyNotFound", "failed to find credentials in the environment.", nil)}, + &credProviderError{Err: awserr.New("SharedCredsLoad", fmt.Sprintf("failed to load profile, %s.", envCfg.Profile), nil)}, + defaults.RemoteCredProvider(*cfg, handlers), + }, + }) + } + } + + return nil +} + +func assumeRoleCredentials(cfg aws.Config, handlers request.Handlers, sharedCfg sharedConfig, sessOpts Options) *credentials.Credentials { + return stscreds.NewCredentials( + &Session{ + Config: &cfg, + Handlers: handlers.Copy(), + }, + sharedCfg.AssumeRole.RoleARN, + func(opt *stscreds.AssumeRoleProvider) { + opt.RoleSessionName = sharedCfg.AssumeRole.RoleSessionName + + // Assume role with external ID + if len(sharedCfg.AssumeRole.ExternalID) > 0 { + opt.ExternalID = aws.String(sharedCfg.AssumeRole.ExternalID) + } + + // Assume role with MFA + if len(sharedCfg.AssumeRole.MFASerial) > 0 { + opt.SerialNumber = aws.String(sharedCfg.AssumeRole.MFASerial) + opt.TokenProvider = sessOpts.AssumeRoleTokenProvider + } + }, + ) +} + +// AssumeRoleTokenProviderNotSetError is an error returned when creating a session when the +// MFAToken option is not set when shared config is configured load assume a +// role with an MFA token. +type AssumeRoleTokenProviderNotSetError struct{} + +// Code is the short id of the error. +func (e AssumeRoleTokenProviderNotSetError) Code() string { + return "AssumeRoleTokenProviderNotSetError" +} + +// Message is the description of the error +func (e AssumeRoleTokenProviderNotSetError) Message() string { + return fmt.Sprintf("assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.") +} + +// OrigErr is the underlying error that caused the failure. +func (e AssumeRoleTokenProviderNotSetError) OrigErr() error { + return nil +} + +// Error satisfies the error interface. +func (e AssumeRoleTokenProviderNotSetError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", nil) +} + +type credProviderError struct { + Err error +} + +var emptyCreds = credentials.Value{} + +func (c credProviderError) Retrieve() (credentials.Value, error) { + return credentials.Value{}, c.Err +} +func (c credProviderError) IsExpired() bool { + return true +} + +func initHandlers(s *Session) { + // Add the Validate parameter handler if it is not disabled. + s.Handlers.Validate.Remove(corehandlers.ValidateParametersHandler) + if !aws.BoolValue(s.Config.DisableParamValidation) { + s.Handlers.Validate.PushBackNamed(corehandlers.ValidateParametersHandler) + } +} + +// Copy creates and returns a copy of the current Session, coping the config +// and handlers. If any additional configs are provided they will be merged +// on top of the Session's copied config. +// +// // Create a copy of the current Session, configured for the us-west-2 region. +// sess.Copy(&aws.Config{Region: aws.String("us-west-2")}) +func (s *Session) Copy(cfgs ...*aws.Config) *Session { + newSession := &Session{ + Config: s.Config.Copy(cfgs...), + Handlers: s.Handlers.Copy(), + } + + initHandlers(newSession) + + return newSession +} + +// ClientConfig satisfies the client.ConfigProvider interface and is used to +// configure the service client instances. Passing the Session to the service +// client's constructor (New) will use this method to configure the client. +func (s *Session) ClientConfig(serviceName string, cfgs ...*aws.Config) client.Config { + // Backwards compatibility, the error will be eaten if user calls ClientConfig + // directly. All SDK services will use ClientconfigWithError. + cfg, _ := s.clientConfigWithErr(serviceName, cfgs...) + + return cfg +} + +func (s *Session) clientConfigWithErr(serviceName string, cfgs ...*aws.Config) (client.Config, error) { + s = s.Copy(cfgs...) + + var resolved endpoints.ResolvedEndpoint + var err error + + region := aws.StringValue(s.Config.Region) + + if endpoint := aws.StringValue(s.Config.Endpoint); len(endpoint) != 0 { + resolved.URL = endpoints.AddScheme(endpoint, aws.BoolValue(s.Config.DisableSSL)) + resolved.SigningRegion = region + } else { + resolved, err = s.Config.EndpointResolver.EndpointFor( + serviceName, region, + func(opt *endpoints.Options) { + opt.DisableSSL = aws.BoolValue(s.Config.DisableSSL) + opt.UseDualStack = aws.BoolValue(s.Config.UseDualStack) + + // Support the condition where the service is modeled but its + // endpoint metadata is not available. + opt.ResolveUnknownService = true + }, + ) + } + + return client.Config{ + Config: s.Config, + Handlers: s.Handlers, + Endpoint: resolved.URL, + SigningRegion: resolved.SigningRegion, + SigningNameDerived: resolved.SigningNameDerived, + SigningName: resolved.SigningName, + }, err +} + +// ClientConfigNoResolveEndpoint is the same as ClientConfig with the exception +// that the EndpointResolver will not be used to resolve the endpoint. The only +// endpoint set must come from the aws.Config.Endpoint field. +func (s *Session) ClientConfigNoResolveEndpoint(cfgs ...*aws.Config) client.Config { + s = s.Copy(cfgs...) + + var resolved endpoints.ResolvedEndpoint + + region := aws.StringValue(s.Config.Region) + + if ep := aws.StringValue(s.Config.Endpoint); len(ep) > 0 { + resolved.URL = endpoints.AddScheme(ep, aws.BoolValue(s.Config.DisableSSL)) + resolved.SigningRegion = region + } + + return client.Config{ + Config: s.Config, + Handlers: s.Handlers, + Endpoint: resolved.URL, + SigningRegion: resolved.SigningRegion, + SigningNameDerived: resolved.SigningNameDerived, + SigningName: resolved.SigningName, + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go new file mode 100644 index 00000000..7cb44021 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/session/shared_config.go @@ -0,0 +1,329 @@ +package session + +import ( + "fmt" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/credentials" + + "github.com/aws/aws-sdk-go/internal/ini" +) + +const ( + // Static Credentials group + accessKeyIDKey = `aws_access_key_id` // group required + secretAccessKey = `aws_secret_access_key` // group required + sessionTokenKey = `aws_session_token` // optional + + // Assume Role Credentials group + roleArnKey = `role_arn` // group required + sourceProfileKey = `source_profile` // group required (or credential_source) + credentialSourceKey = `credential_source` // group required (or source_profile) + externalIDKey = `external_id` // optional + mfaSerialKey = `mfa_serial` // optional + roleSessionNameKey = `role_session_name` // optional + + // Additional Config fields + regionKey = `region` + + // endpoint discovery group + enableEndpointDiscoveryKey = `endpoint_discovery_enabled` // optional + // External Credential Process + credentialProcessKey = `credential_process` + + // DefaultSharedConfigProfile is the default profile to be used when + // loading configuration from the config files if another profile name + // is not provided. + DefaultSharedConfigProfile = `default` +) + +type assumeRoleConfig struct { + RoleARN string + SourceProfile string + CredentialSource string + ExternalID string + MFASerial string + RoleSessionName string +} + +// sharedConfig represents the configuration fields of the SDK config files. +type sharedConfig struct { + // Credentials values from the config file. Both aws_access_key_id + // and aws_secret_access_key must be provided together in the same file + // to be considered valid. The values will be ignored if not a complete group. + // aws_session_token is an optional field that can be provided if both of the + // other two fields are also provided. + // + // aws_access_key_id + // aws_secret_access_key + // aws_session_token + Creds credentials.Value + + AssumeRole assumeRoleConfig + AssumeRoleSource *sharedConfig + + // An external process to request credentials + CredentialProcess string + + // Region is the region the SDK should use for looking up AWS service endpoints + // and signing requests. + // + // region + Region string + + // EnableEndpointDiscovery can be enabled in the shared config by setting + // endpoint_discovery_enabled to true + // + // endpoint_discovery_enabled = true + EnableEndpointDiscovery *bool +} + +type sharedConfigFile struct { + Filename string + IniData ini.Sections +} + +// loadSharedConfig retrieves the configuration from the list of files +// using the profile provided. The order the files are listed will determine +// precedence. Values in subsequent files will overwrite values defined in +// earlier files. +// +// For example, given two files A and B. Both define credentials. If the order +// of the files are A then B, B's credential values will be used instead of A's. +// +// See sharedConfig.setFromFile for information how the config files +// will be loaded. +func loadSharedConfig(profile string, filenames []string) (sharedConfig, error) { + if len(profile) == 0 { + profile = DefaultSharedConfigProfile + } + + files, err := loadSharedConfigIniFiles(filenames) + if err != nil { + return sharedConfig{}, err + } + + cfg := sharedConfig{} + if err = cfg.setFromIniFiles(profile, files); err != nil { + return sharedConfig{}, err + } + + if len(cfg.AssumeRole.SourceProfile) > 0 { + if err := cfg.setAssumeRoleSource(profile, files); err != nil { + return sharedConfig{}, err + } + } + + return cfg, nil +} + +func loadSharedConfigIniFiles(filenames []string) ([]sharedConfigFile, error) { + files := make([]sharedConfigFile, 0, len(filenames)) + + for _, filename := range filenames { + sections, err := ini.OpenFile(filename) + if aerr, ok := err.(awserr.Error); ok && aerr.Code() == ini.ErrCodeUnableToReadFile { + // Skip files which can't be opened and read for whatever reason + continue + } else if err != nil { + return nil, SharedConfigLoadError{Filename: filename, Err: err} + } + + files = append(files, sharedConfigFile{ + Filename: filename, IniData: sections, + }) + } + + return files, nil +} + +func (cfg *sharedConfig) setAssumeRoleSource(origProfile string, files []sharedConfigFile) error { + var assumeRoleSrc sharedConfig + + if len(cfg.AssumeRole.CredentialSource) > 0 { + // setAssumeRoleSource is only called when source_profile is found. + // If both source_profile and credential_source are set, then + // ErrSharedConfigSourceCollision will be returned + return ErrSharedConfigSourceCollision + } + + // Multiple level assume role chains are not support + if cfg.AssumeRole.SourceProfile == origProfile { + assumeRoleSrc = *cfg + assumeRoleSrc.AssumeRole = assumeRoleConfig{} + } else { + err := assumeRoleSrc.setFromIniFiles(cfg.AssumeRole.SourceProfile, files) + if err != nil { + return err + } + } + + if len(assumeRoleSrc.Creds.AccessKeyID) == 0 { + return SharedConfigAssumeRoleError{RoleARN: cfg.AssumeRole.RoleARN} + } + + cfg.AssumeRoleSource = &assumeRoleSrc + + return nil +} + +func (cfg *sharedConfig) setFromIniFiles(profile string, files []sharedConfigFile) error { + // Trim files from the list that don't exist. + for _, f := range files { + if err := cfg.setFromIniFile(profile, f); err != nil { + if _, ok := err.(SharedConfigProfileNotExistsError); ok { + // Ignore proviles missings + continue + } + return err + } + } + + return nil +} + +// setFromFile loads the configuration from the file using +// the profile provided. A sharedConfig pointer type value is used so that +// multiple config file loadings can be chained. +// +// Only loads complete logically grouped values, and will not set fields in cfg +// for incomplete grouped values in the config. Such as credentials. For example +// if a config file only includes aws_access_key_id but no aws_secret_access_key +// the aws_access_key_id will be ignored. +func (cfg *sharedConfig) setFromIniFile(profile string, file sharedConfigFile) error { + section, ok := file.IniData.GetSection(profile) + if !ok { + // Fallback to to alternate profile name: profile + section, ok = file.IniData.GetSection(fmt.Sprintf("profile %s", profile)) + if !ok { + return SharedConfigProfileNotExistsError{Profile: profile, Err: nil} + } + } + + // Shared Credentials + akid := section.String(accessKeyIDKey) + secret := section.String(secretAccessKey) + if len(akid) > 0 && len(secret) > 0 { + cfg.Creds = credentials.Value{ + AccessKeyID: akid, + SecretAccessKey: secret, + SessionToken: section.String(sessionTokenKey), + ProviderName: fmt.Sprintf("SharedConfigCredentials: %s", file.Filename), + } + } + + // Assume Role + roleArn := section.String(roleArnKey) + srcProfile := section.String(sourceProfileKey) + credentialSource := section.String(credentialSourceKey) + hasSource := len(srcProfile) > 0 || len(credentialSource) > 0 + if len(roleArn) > 0 && hasSource { + cfg.AssumeRole = assumeRoleConfig{ + RoleARN: roleArn, + SourceProfile: srcProfile, + CredentialSource: credentialSource, + ExternalID: section.String(externalIDKey), + MFASerial: section.String(mfaSerialKey), + RoleSessionName: section.String(roleSessionNameKey), + } + } + + // `credential_process` + if credProc := section.String(credentialProcessKey); len(credProc) > 0 { + cfg.CredentialProcess = credProc + } + + // Region + if v := section.String(regionKey); len(v) > 0 { + cfg.Region = v + } + + // Endpoint discovery + if section.Has(enableEndpointDiscoveryKey) { + v := section.Bool(enableEndpointDiscoveryKey) + cfg.EnableEndpointDiscovery = &v + } + + return nil +} + +// SharedConfigLoadError is an error for the shared config file failed to load. +type SharedConfigLoadError struct { + Filename string + Err error +} + +// Code is the short id of the error. +func (e SharedConfigLoadError) Code() string { + return "SharedConfigLoadError" +} + +// Message is the description of the error +func (e SharedConfigLoadError) Message() string { + return fmt.Sprintf("failed to load config file, %s", e.Filename) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigLoadError) OrigErr() error { + return e.Err +} + +// Error satisfies the error interface. +func (e SharedConfigLoadError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", e.Err) +} + +// SharedConfigProfileNotExistsError is an error for the shared config when +// the profile was not find in the config file. +type SharedConfigProfileNotExistsError struct { + Profile string + Err error +} + +// Code is the short id of the error. +func (e SharedConfigProfileNotExistsError) Code() string { + return "SharedConfigProfileNotExistsError" +} + +// Message is the description of the error +func (e SharedConfigProfileNotExistsError) Message() string { + return fmt.Sprintf("failed to get profile, %s", e.Profile) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigProfileNotExistsError) OrigErr() error { + return e.Err +} + +// Error satisfies the error interface. +func (e SharedConfigProfileNotExistsError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", e.Err) +} + +// SharedConfigAssumeRoleError is an error for the shared config when the +// profile contains assume role information, but that information is invalid +// or not complete. +type SharedConfigAssumeRoleError struct { + RoleARN string +} + +// Code is the short id of the error. +func (e SharedConfigAssumeRoleError) Code() string { + return "SharedConfigAssumeRoleError" +} + +// Message is the description of the error +func (e SharedConfigAssumeRoleError) Message() string { + return fmt.Sprintf("failed to load assume role for %s, source profile has no shared credentials", + e.RoleARN) +} + +// OrigErr is the underlying error that caused the failure. +func (e SharedConfigAssumeRoleError) OrigErr() error { + return nil +} + +// Error satisfies the error interface. +func (e SharedConfigAssumeRoleError) Error() string { + return awserr.SprintError(e.Code(), e.Message(), "", nil) +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go new file mode 100644 index 00000000..244c86da --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/header_rules.go @@ -0,0 +1,82 @@ +package v4 + +import ( + "net/http" + "strings" +) + +// validator houses a set of rule needed for validation of a +// string value +type rules []rule + +// rule interface allows for more flexible rules and just simply +// checks whether or not a value adheres to that rule +type rule interface { + IsValid(value string) bool +} + +// IsValid will iterate through all rules and see if any rules +// apply to the value and supports nested rules +func (r rules) IsValid(value string) bool { + for _, rule := range r { + if rule.IsValid(value) { + return true + } + } + return false +} + +// mapRule generic rule for maps +type mapRule map[string]struct{} + +// IsValid for the map rule satisfies whether it exists in the map +func (m mapRule) IsValid(value string) bool { + _, ok := m[value] + return ok +} + +// whitelist is a generic rule for whitelisting +type whitelist struct { + rule +} + +// IsValid for whitelist checks if the value is within the whitelist +func (w whitelist) IsValid(value string) bool { + return w.rule.IsValid(value) +} + +// blacklist is a generic rule for blacklisting +type blacklist struct { + rule +} + +// IsValid for whitelist checks if the value is within the whitelist +func (b blacklist) IsValid(value string) bool { + return !b.rule.IsValid(value) +} + +type patterns []string + +// IsValid for patterns checks each pattern and returns if a match has +// been found +func (p patterns) IsValid(value string) bool { + for _, pattern := range p { + if strings.HasPrefix(http.CanonicalHeaderKey(value), pattern) { + return true + } + } + return false +} + +// inclusiveRules rules allow for rules to depend on one another +type inclusiveRules []rule + +// IsValid will return true if all rules are true +func (r inclusiveRules) IsValid(value string) bool { + for _, rule := range r { + if !rule.IsValid(value) { + return false + } + } + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go new file mode 100644 index 00000000..6aa2ed24 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/options.go @@ -0,0 +1,7 @@ +package v4 + +// WithUnsignedPayload will enable and set the UnsignedPayload field to +// true of the signer. +func WithUnsignedPayload(v4 *Signer) { + v4.UnsignedPayload = true +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go new file mode 100644 index 00000000..bd082e9d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/uri_path.go @@ -0,0 +1,24 @@ +// +build go1.5 + +package v4 + +import ( + "net/url" + "strings" +) + +func getURIPath(u *url.URL) string { + var uri string + + if len(u.Opaque) > 0 { + uri = "/" + strings.Join(strings.Split(u.Opaque, "/")[3:], "/") + } else { + uri = u.EscapedPath() + } + + if len(uri) == 0 { + uri = "/" + } + + return uri +} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go new file mode 100644 index 00000000..523db79f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/aws/signer/v4/v4.go @@ -0,0 +1,796 @@ +// Package v4 implements signing for AWS V4 signer +// +// Provides request signing for request that need to be signed with +// AWS V4 Signatures. +// +// Standalone Signer +// +// Generally using the signer outside of the SDK should not require any additional +// logic when using Go v1.5 or higher. The signer does this by taking advantage +// of the URL.EscapedPath method. If your request URI requires additional escaping +// you many need to use the URL.Opaque to define what the raw URI should be sent +// to the service as. +// +// The signer will first check the URL.Opaque field, and use its value if set. +// The signer does require the URL.Opaque field to be set in the form of: +// +// "///" +// +// // e.g. +// "//example.com/some/path" +// +// The leading "//" and hostname are required or the URL.Opaque escaping will +// not work correctly. +// +// If URL.Opaque is not set the signer will fallback to the URL.EscapedPath() +// method and using the returned value. If you're using Go v1.4 you must set +// URL.Opaque if the URI path needs escaping. If URL.Opaque is not set with +// Go v1.5 the signer will fallback to URL.Path. +// +// AWS v4 signature validation requires that the canonical string's URI path +// element must be the URI escaped form of the HTTP request's path. +// http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html +// +// The Go HTTP client will perform escaping automatically on the request. Some +// of these escaping may cause signature validation errors because the HTTP +// request differs from the URI path or query that the signature was generated. +// https://golang.org/pkg/net/url/#URL.EscapedPath +// +// Because of this, it is recommended that when using the signer outside of the +// SDK that explicitly escaping the request prior to being signed is preferable, +// and will help prevent signature validation errors. This can be done by setting +// the URL.Opaque or URL.RawPath. The SDK will use URL.Opaque first and then +// call URL.EscapedPath() if Opaque is not set. +// +// If signing a request intended for HTTP2 server, and you're using Go 1.6.2 +// through 1.7.4 you should use the URL.RawPath as the pre-escaped form of the +// request URL. https://github.com/golang/go/issues/16847 points to a bug in +// Go pre 1.8 that fails to make HTTP2 requests using absolute URL in the HTTP +// message. URL.Opaque generally will force Go to make requests with absolute URL. +// URL.RawPath does not do this, but RawPath must be a valid escaping of Path +// or url.EscapedPath will ignore the RawPath escaping. +// +// Test `TestStandaloneSign` provides a complete example of using the signer +// outside of the SDK and pre-escaping the URI path. +package v4 + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "sort" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/internal/sdkio" + "github.com/aws/aws-sdk-go/private/protocol/rest" +) + +const ( + authHeaderPrefix = "AWS4-HMAC-SHA256" + timeFormat = "20060102T150405Z" + shortTimeFormat = "20060102" + + // emptyStringSHA256 is a SHA256 of an empty string + emptyStringSHA256 = `e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855` +) + +var ignoredHeaders = rules{ + blacklist{ + mapRule{ + "Authorization": struct{}{}, + "User-Agent": struct{}{}, + "X-Amzn-Trace-Id": struct{}{}, + }, + }, +} + +// requiredSignedHeaders is a whitelist for build canonical headers. +var requiredSignedHeaders = rules{ + whitelist{ + mapRule{ + "Cache-Control": struct{}{}, + "Content-Disposition": struct{}{}, + "Content-Encoding": struct{}{}, + "Content-Language": struct{}{}, + "Content-Md5": struct{}{}, + "Content-Type": struct{}{}, + "Expires": struct{}{}, + "If-Match": struct{}{}, + "If-Modified-Since": struct{}{}, + "If-None-Match": struct{}{}, + "If-Unmodified-Since": struct{}{}, + "Range": struct{}{}, + "X-Amz-Acl": struct{}{}, + "X-Amz-Copy-Source": struct{}{}, + "X-Amz-Copy-Source-If-Match": struct{}{}, + "X-Amz-Copy-Source-If-Modified-Since": struct{}{}, + "X-Amz-Copy-Source-If-None-Match": struct{}{}, + "X-Amz-Copy-Source-If-Unmodified-Since": struct{}{}, + "X-Amz-Copy-Source-Range": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Copy-Source-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Grant-Full-control": struct{}{}, + "X-Amz-Grant-Read": struct{}{}, + "X-Amz-Grant-Read-Acp": struct{}{}, + "X-Amz-Grant-Write": struct{}{}, + "X-Amz-Grant-Write-Acp": struct{}{}, + "X-Amz-Metadata-Directive": struct{}{}, + "X-Amz-Mfa": struct{}{}, + "X-Amz-Request-Payer": struct{}{}, + "X-Amz-Server-Side-Encryption": struct{}{}, + "X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Algorithm": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key": struct{}{}, + "X-Amz-Server-Side-Encryption-Customer-Key-Md5": struct{}{}, + "X-Amz-Storage-Class": struct{}{}, + "X-Amz-Tagging": struct{}{}, + "X-Amz-Website-Redirect-Location": struct{}{}, + "X-Amz-Content-Sha256": struct{}{}, + }, + }, + patterns{"X-Amz-Meta-"}, +} + +// allowedHoisting is a whitelist for build query headers. The boolean value +// represents whether or not it is a pattern. +var allowedQueryHoisting = inclusiveRules{ + blacklist{requiredSignedHeaders}, + patterns{"X-Amz-"}, +} + +// Signer applies AWS v4 signing to given request. Use this to sign requests +// that need to be signed with AWS V4 Signatures. +type Signer struct { + // The authentication credentials the request will be signed against. + // This value must be set to sign requests. + Credentials *credentials.Credentials + + // Sets the log level the signer should use when reporting information to + // the logger. If the logger is nil nothing will be logged. See + // aws.LogLevelType for more information on available logging levels + // + // By default nothing will be logged. + Debug aws.LogLevelType + + // The logger loging information will be written to. If there the logger + // is nil, nothing will be logged. + Logger aws.Logger + + // Disables the Signer's moving HTTP header key/value pairs from the HTTP + // request header to the request's query string. This is most commonly used + // with pre-signed requests preventing headers from being added to the + // request's query string. + DisableHeaderHoisting bool + + // Disables the automatic escaping of the URI path of the request for the + // siganture's canonical string's path. For services that do not need additional + // escaping then use this to disable the signer escaping the path. + // + // S3 is an example of a service that does not need additional escaping. + // + // http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html + DisableURIPathEscaping bool + + // Disables the automatical setting of the HTTP request's Body field with the + // io.ReadSeeker passed in to the signer. This is useful if you're using a + // custom wrapper around the body for the io.ReadSeeker and want to preserve + // the Body value on the Request.Body. + // + // This does run the risk of signing a request with a body that will not be + // sent in the request. Need to ensure that the underlying data of the Body + // values are the same. + DisableRequestBodyOverwrite bool + + // currentTimeFn returns the time value which represents the current time. + // This value should only be used for testing. If it is nil the default + // time.Now will be used. + currentTimeFn func() time.Time + + // UnsignedPayload will prevent signing of the payload. This will only + // work for services that have support for this. + UnsignedPayload bool +} + +// NewSigner returns a Signer pointer configured with the credentials and optional +// option values provided. If not options are provided the Signer will use its +// default configuration. +func NewSigner(credentials *credentials.Credentials, options ...func(*Signer)) *Signer { + v4 := &Signer{ + Credentials: credentials, + } + + for _, option := range options { + option(v4) + } + + return v4 +} + +type signingCtx struct { + ServiceName string + Region string + Request *http.Request + Body io.ReadSeeker + Query url.Values + Time time.Time + ExpireTime time.Duration + SignedHeaderVals http.Header + + DisableURIPathEscaping bool + + credValues credentials.Value + isPresign bool + formattedTime string + formattedShortTime string + unsignedPayload bool + + bodyDigest string + signedHeaders string + canonicalHeaders string + canonicalString string + credentialString string + stringToSign string + signature string + authorization string +} + +// Sign signs AWS v4 requests with the provided body, service name, region the +// request is made to, and time the request is signed at. The signTime allows +// you to specify that a request is signed for the future, and cannot be +// used until then. +// +// Returns a list of HTTP headers that were included in the signature or an +// error if signing the request failed. Generally for signed requests this value +// is not needed as the full request context will be captured by the http.Request +// value. It is included for reference though. +// +// Sign will set the request's Body to be the `body` parameter passed in. If +// the body is not already an io.ReadCloser, it will be wrapped within one. If +// a `nil` body parameter passed to Sign, the request's Body field will be +// also set to nil. Its important to note that this functionality will not +// change the request's ContentLength of the request. +// +// Sign differs from Presign in that it will sign the request using HTTP +// header values. This type of signing is intended for http.Request values that +// will not be shared, or are shared in a way the header values on the request +// will not be lost. +// +// The requests body is an io.ReadSeeker so the SHA256 of the body can be +// generated. To bypass the signer computing the hash you can set the +// "X-Amz-Content-Sha256" header with a precomputed value. The signer will +// only compute the hash if the request header value is empty. +func (v4 Signer) Sign(r *http.Request, body io.ReadSeeker, service, region string, signTime time.Time) (http.Header, error) { + return v4.signWithBody(r, body, service, region, 0, false, signTime) +} + +// Presign signs AWS v4 requests with the provided body, service name, region +// the request is made to, and time the request is signed at. The signTime +// allows you to specify that a request is signed for the future, and cannot +// be used until then. +// +// Returns a list of HTTP headers that were included in the signature or an +// error if signing the request failed. For presigned requests these headers +// and their values must be included on the HTTP request when it is made. This +// is helpful to know what header values need to be shared with the party the +// presigned request will be distributed to. +// +// Presign differs from Sign in that it will sign the request using query string +// instead of header values. This allows you to share the Presigned Request's +// URL with third parties, or distribute it throughout your system with minimal +// dependencies. +// +// Presign also takes an exp value which is the duration the +// signed request will be valid after the signing time. This is allows you to +// set when the request will expire. +// +// The requests body is an io.ReadSeeker so the SHA256 of the body can be +// generated. To bypass the signer computing the hash you can set the +// "X-Amz-Content-Sha256" header with a precomputed value. The signer will +// only compute the hash if the request header value is empty. +// +// Presigning a S3 request will not compute the body's SHA256 hash by default. +// This is done due to the general use case for S3 presigned URLs is to share +// PUT/GET capabilities. If you would like to include the body's SHA256 in the +// presigned request's signature you can set the "X-Amz-Content-Sha256" +// HTTP header and that will be included in the request's signature. +func (v4 Signer) Presign(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, signTime time.Time) (http.Header, error) { + return v4.signWithBody(r, body, service, region, exp, true, signTime) +} + +func (v4 Signer) signWithBody(r *http.Request, body io.ReadSeeker, service, region string, exp time.Duration, isPresign bool, signTime time.Time) (http.Header, error) { + currentTimeFn := v4.currentTimeFn + if currentTimeFn == nil { + currentTimeFn = time.Now + } + + ctx := &signingCtx{ + Request: r, + Body: body, + Query: r.URL.Query(), + Time: signTime, + ExpireTime: exp, + isPresign: isPresign, + ServiceName: service, + Region: region, + DisableURIPathEscaping: v4.DisableURIPathEscaping, + unsignedPayload: v4.UnsignedPayload, + } + + for key := range ctx.Query { + sort.Strings(ctx.Query[key]) + } + + if ctx.isRequestSigned() { + ctx.Time = currentTimeFn() + ctx.handlePresignRemoval() + } + + var err error + ctx.credValues, err = v4.Credentials.Get() + if err != nil { + return http.Header{}, err + } + + ctx.sanitizeHostForHeader() + ctx.assignAmzQueryValues() + if err := ctx.build(v4.DisableHeaderHoisting); err != nil { + return nil, err + } + + // If the request is not presigned the body should be attached to it. This + // prevents the confusion of wanting to send a signed request without + // the body the request was signed for attached. + if !(v4.DisableRequestBodyOverwrite || ctx.isPresign) { + var reader io.ReadCloser + if body != nil { + var ok bool + if reader, ok = body.(io.ReadCloser); !ok { + reader = ioutil.NopCloser(body) + } + } + r.Body = reader + } + + if v4.Debug.Matches(aws.LogDebugWithSigning) { + v4.logSigningInfo(ctx) + } + + return ctx.SignedHeaderVals, nil +} + +func (ctx *signingCtx) sanitizeHostForHeader() { + request.SanitizeHostForHeader(ctx.Request) +} + +func (ctx *signingCtx) handlePresignRemoval() { + if !ctx.isPresign { + return + } + + // The credentials have expired for this request. The current signing + // is invalid, and needs to be request because the request will fail. + ctx.removePresign() + + // Update the request's query string to ensure the values stays in + // sync in the case retrieving the new credentials fails. + ctx.Request.URL.RawQuery = ctx.Query.Encode() +} + +func (ctx *signingCtx) assignAmzQueryValues() { + if ctx.isPresign { + ctx.Query.Set("X-Amz-Algorithm", authHeaderPrefix) + if ctx.credValues.SessionToken != "" { + ctx.Query.Set("X-Amz-Security-Token", ctx.credValues.SessionToken) + } else { + ctx.Query.Del("X-Amz-Security-Token") + } + + return + } + + if ctx.credValues.SessionToken != "" { + ctx.Request.Header.Set("X-Amz-Security-Token", ctx.credValues.SessionToken) + } +} + +// SignRequestHandler is a named request handler the SDK will use to sign +// service client request with using the V4 signature. +var SignRequestHandler = request.NamedHandler{ + Name: "v4.SignRequestHandler", Fn: SignSDKRequest, +} + +// SignSDKRequest signs an AWS request with the V4 signature. This +// request handler should only be used with the SDK's built in service client's +// API operation requests. +// +// This function should not be used on its on its own, but in conjunction with +// an AWS service client's API operation call. To sign a standalone request +// not created by a service client's API operation method use the "Sign" or +// "Presign" functions of the "Signer" type. +// +// If the credentials of the request's config are set to +// credentials.AnonymousCredentials the request will not be signed. +func SignSDKRequest(req *request.Request) { + SignSDKRequestWithCurrentTime(req, time.Now) +} + +// BuildNamedHandler will build a generic handler for signing. +func BuildNamedHandler(name string, opts ...func(*Signer)) request.NamedHandler { + return request.NamedHandler{ + Name: name, + Fn: func(req *request.Request) { + SignSDKRequestWithCurrentTime(req, time.Now, opts...) + }, + } +} + +// SignSDKRequestWithCurrentTime will sign the SDK's request using the time +// function passed in. Behaves the same as SignSDKRequest with the exception +// the request is signed with the value returned by the current time function. +func SignSDKRequestWithCurrentTime(req *request.Request, curTimeFn func() time.Time, opts ...func(*Signer)) { + // If the request does not need to be signed ignore the signing of the + // request if the AnonymousCredentials object is used. + if req.Config.Credentials == credentials.AnonymousCredentials { + return + } + + region := req.ClientInfo.SigningRegion + if region == "" { + region = aws.StringValue(req.Config.Region) + } + + name := req.ClientInfo.SigningName + if name == "" { + name = req.ClientInfo.ServiceName + } + + v4 := NewSigner(req.Config.Credentials, func(v4 *Signer) { + v4.Debug = req.Config.LogLevel.Value() + v4.Logger = req.Config.Logger + v4.DisableHeaderHoisting = req.NotHoist + v4.currentTimeFn = curTimeFn + if name == "s3" { + // S3 service should not have any escaping applied + v4.DisableURIPathEscaping = true + } + // Prevents setting the HTTPRequest's Body. Since the Body could be + // wrapped in a custom io.Closer that we do not want to be stompped + // on top of by the signer. + v4.DisableRequestBodyOverwrite = true + }) + + for _, opt := range opts { + opt(v4) + } + + curTime := curTimeFn() + signedHeaders, err := v4.signWithBody(req.HTTPRequest, req.GetBody(), + name, region, req.ExpireTime, req.ExpireTime > 0, curTime, + ) + if err != nil { + req.Error = err + req.SignedHeaderVals = nil + return + } + + req.SignedHeaderVals = signedHeaders + req.LastSignedAt = curTime +} + +const logSignInfoMsg = `DEBUG: Request Signature: +---[ CANONICAL STRING ]----------------------------- +%s +---[ STRING TO SIGN ]-------------------------------- +%s%s +-----------------------------------------------------` +const logSignedURLMsg = ` +---[ SIGNED URL ]------------------------------------ +%s` + +func (v4 *Signer) logSigningInfo(ctx *signingCtx) { + signedURLMsg := "" + if ctx.isPresign { + signedURLMsg = fmt.Sprintf(logSignedURLMsg, ctx.Request.URL.String()) + } + msg := fmt.Sprintf(logSignInfoMsg, ctx.canonicalString, ctx.stringToSign, signedURLMsg) + v4.Logger.Log(msg) +} + +func (ctx *signingCtx) build(disableHeaderHoisting bool) error { + ctx.buildTime() // no depends + ctx.buildCredentialString() // no depends + + if err := ctx.buildBodyDigest(); err != nil { + return err + } + + unsignedHeaders := ctx.Request.Header + if ctx.isPresign { + if !disableHeaderHoisting { + urlValues := url.Values{} + urlValues, unsignedHeaders = buildQuery(allowedQueryHoisting, unsignedHeaders) // no depends + for k := range urlValues { + ctx.Query[k] = urlValues[k] + } + } + } + + ctx.buildCanonicalHeaders(ignoredHeaders, unsignedHeaders) + ctx.buildCanonicalString() // depends on canon headers / signed headers + ctx.buildStringToSign() // depends on canon string + ctx.buildSignature() // depends on string to sign + + if ctx.isPresign { + ctx.Request.URL.RawQuery += "&X-Amz-Signature=" + ctx.signature + } else { + parts := []string{ + authHeaderPrefix + " Credential=" + ctx.credValues.AccessKeyID + "/" + ctx.credentialString, + "SignedHeaders=" + ctx.signedHeaders, + "Signature=" + ctx.signature, + } + ctx.Request.Header.Set("Authorization", strings.Join(parts, ", ")) + } + + return nil +} + +func (ctx *signingCtx) buildTime() { + ctx.formattedTime = ctx.Time.UTC().Format(timeFormat) + ctx.formattedShortTime = ctx.Time.UTC().Format(shortTimeFormat) + + if ctx.isPresign { + duration := int64(ctx.ExpireTime / time.Second) + ctx.Query.Set("X-Amz-Date", ctx.formattedTime) + ctx.Query.Set("X-Amz-Expires", strconv.FormatInt(duration, 10)) + } else { + ctx.Request.Header.Set("X-Amz-Date", ctx.formattedTime) + } +} + +func (ctx *signingCtx) buildCredentialString() { + ctx.credentialString = strings.Join([]string{ + ctx.formattedShortTime, + ctx.Region, + ctx.ServiceName, + "aws4_request", + }, "/") + + if ctx.isPresign { + ctx.Query.Set("X-Amz-Credential", ctx.credValues.AccessKeyID+"/"+ctx.credentialString) + } +} + +func buildQuery(r rule, header http.Header) (url.Values, http.Header) { + query := url.Values{} + unsignedHeaders := http.Header{} + for k, h := range header { + if r.IsValid(k) { + query[k] = h + } else { + unsignedHeaders[k] = h + } + } + + return query, unsignedHeaders +} +func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) { + var headers []string + headers = append(headers, "host") + for k, v := range header { + canonicalKey := http.CanonicalHeaderKey(k) + if !r.IsValid(canonicalKey) { + continue // ignored header + } + if ctx.SignedHeaderVals == nil { + ctx.SignedHeaderVals = make(http.Header) + } + + lowerCaseKey := strings.ToLower(k) + if _, ok := ctx.SignedHeaderVals[lowerCaseKey]; ok { + // include additional values + ctx.SignedHeaderVals[lowerCaseKey] = append(ctx.SignedHeaderVals[lowerCaseKey], v...) + continue + } + + headers = append(headers, lowerCaseKey) + ctx.SignedHeaderVals[lowerCaseKey] = v + } + sort.Strings(headers) + + ctx.signedHeaders = strings.Join(headers, ";") + + if ctx.isPresign { + ctx.Query.Set("X-Amz-SignedHeaders", ctx.signedHeaders) + } + + headerValues := make([]string, len(headers)) + for i, k := range headers { + if k == "host" { + if ctx.Request.Host != "" { + headerValues[i] = "host:" + ctx.Request.Host + } else { + headerValues[i] = "host:" + ctx.Request.URL.Host + } + } else { + headerValues[i] = k + ":" + + strings.Join(ctx.SignedHeaderVals[k], ",") + } + } + stripExcessSpaces(headerValues) + ctx.canonicalHeaders = strings.Join(headerValues, "\n") +} + +func (ctx *signingCtx) buildCanonicalString() { + ctx.Request.URL.RawQuery = strings.Replace(ctx.Query.Encode(), "+", "%20", -1) + + uri := getURIPath(ctx.Request.URL) + + if !ctx.DisableURIPathEscaping { + uri = rest.EscapePath(uri, false) + } + + ctx.canonicalString = strings.Join([]string{ + ctx.Request.Method, + uri, + ctx.Request.URL.RawQuery, + ctx.canonicalHeaders + "\n", + ctx.signedHeaders, + ctx.bodyDigest, + }, "\n") +} + +func (ctx *signingCtx) buildStringToSign() { + ctx.stringToSign = strings.Join([]string{ + authHeaderPrefix, + ctx.formattedTime, + ctx.credentialString, + hex.EncodeToString(makeSha256([]byte(ctx.canonicalString))), + }, "\n") +} + +func (ctx *signingCtx) buildSignature() { + secret := ctx.credValues.SecretAccessKey + date := makeHmac([]byte("AWS4"+secret), []byte(ctx.formattedShortTime)) + region := makeHmac(date, []byte(ctx.Region)) + service := makeHmac(region, []byte(ctx.ServiceName)) + credentials := makeHmac(service, []byte("aws4_request")) + signature := makeHmac(credentials, []byte(ctx.stringToSign)) + ctx.signature = hex.EncodeToString(signature) +} + +func (ctx *signingCtx) buildBodyDigest() error { + hash := ctx.Request.Header.Get("X-Amz-Content-Sha256") + if hash == "" { + includeSHA256Header := ctx.unsignedPayload || + ctx.ServiceName == "s3" || + ctx.ServiceName == "glacier" + + s3Presign := ctx.isPresign && ctx.ServiceName == "s3" + + if ctx.unsignedPayload || s3Presign { + hash = "UNSIGNED-PAYLOAD" + includeSHA256Header = !s3Presign + } else if ctx.Body == nil { + hash = emptyStringSHA256 + } else { + if !aws.IsReaderSeekable(ctx.Body) { + return fmt.Errorf("cannot use unseekable request body %T, for signed request with body", ctx.Body) + } + hash = hex.EncodeToString(makeSha256Reader(ctx.Body)) + } + + if includeSHA256Header { + ctx.Request.Header.Set("X-Amz-Content-Sha256", hash) + } + } + ctx.bodyDigest = hash + + return nil +} + +// isRequestSigned returns if the request is currently signed or presigned +func (ctx *signingCtx) isRequestSigned() bool { + if ctx.isPresign && ctx.Query.Get("X-Amz-Signature") != "" { + return true + } + if ctx.Request.Header.Get("Authorization") != "" { + return true + } + + return false +} + +// unsign removes signing flags for both signed and presigned requests. +func (ctx *signingCtx) removePresign() { + ctx.Query.Del("X-Amz-Algorithm") + ctx.Query.Del("X-Amz-Signature") + ctx.Query.Del("X-Amz-Security-Token") + ctx.Query.Del("X-Amz-Date") + ctx.Query.Del("X-Amz-Expires") + ctx.Query.Del("X-Amz-Credential") + ctx.Query.Del("X-Amz-SignedHeaders") +} + +func makeHmac(key []byte, data []byte) []byte { + hash := hmac.New(sha256.New, key) + hash.Write(data) + return hash.Sum(nil) +} + +func makeSha256(data []byte) []byte { + hash := sha256.New() + hash.Write(data) + return hash.Sum(nil) +} + +func makeSha256Reader(reader io.ReadSeeker) []byte { + hash := sha256.New() + start, _ := reader.Seek(0, sdkio.SeekCurrent) + defer reader.Seek(start, sdkio.SeekStart) + + // Use CopyN to avoid allocating the 32KB buffer in io.Copy for bodies + // smaller than 32KB. Fall back to io.Copy if we fail to determine the size. + size, err := aws.SeekerLen(reader) + if err != nil { + io.Copy(hash, reader) + } else { + io.CopyN(hash, reader, size) + } + + return hash.Sum(nil) +} + +const doubleSpace = " " + +// stripExcessSpaces will rewrite the passed in slice's string values to not +// contain multiple side-by-side spaces. +func stripExcessSpaces(vals []string) { + var j, k, l, m, spaces int + for i, str := range vals { + // Trim trailing spaces + for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- { + } + + // Trim leading spaces + for k = 0; k < j && str[k] == ' '; k++ { + } + str = str[k : j+1] + + // Strip multiple spaces. + j = strings.Index(str, doubleSpace) + if j < 0 { + vals[i] = str + continue + } + + buf := []byte(str) + for k, m, l = j, j, len(buf); k < l; k++ { + if buf[k] == ' ' { + if spaces == 0 { + // First space. + buf[m] = buf[k] + m++ + } + spaces++ + } else { + // End of multiple spaces. + spaces = 0 + buf[m] = buf[k] + m++ + } + } + + vals[i] = string(buf[:m]) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/host.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/host.go new file mode 100644 index 00000000..d7d42db0 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/host.go @@ -0,0 +1,68 @@ +package protocol + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws/request" +) + +// ValidateEndpointHostHandler is a request handler that will validate the +// request endpoint's hosts is a valid RFC 3986 host. +var ValidateEndpointHostHandler = request.NamedHandler{ + Name: "awssdk.protocol.ValidateEndpointHostHandler", + Fn: func(r *request.Request) { + err := ValidateEndpointHost(r.Operation.Name, r.HTTPRequest.URL.Host) + if err != nil { + r.Error = err + } + }, +} + +// ValidateEndpointHost validates that the host string passed in is a valid RFC +// 3986 host. Returns error if the host is not valid. +func ValidateEndpointHost(opName, host string) error { + paramErrs := request.ErrInvalidParams{Context: opName} + labels := strings.Split(host, ".") + + for i, label := range labels { + if i == len(labels)-1 && len(label) == 0 { + // Allow trailing dot for FQDN hosts. + continue + } + + if !ValidHostLabel(label) { + paramErrs.Add(request.NewErrParamFormat( + "endpoint host label", "[a-zA-Z0-9-]{1,63}", label)) + } + } + + if len(host) > 255 { + paramErrs.Add(request.NewErrParamMaxLen( + "endpoint host", 255, host, + )) + } + + if paramErrs.Len() > 0 { + return paramErrs + } + return nil +} + +// ValidHostLabel returns if the label is a valid RFC 3986 host label. +func ValidHostLabel(label string) bool { + if l := len(label); l == 0 || l > 63 { + return false + } + for _, r := range label { + switch { + case r >= '0' && r <= '9': + case r >= 'A' && r <= 'Z': + case r >= 'a' && r <= 'z': + case r == '-': + default: + return false + } + } + + return true +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go new file mode 100644 index 00000000..915b0fca --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/host_prefix.go @@ -0,0 +1,54 @@ +package protocol + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/request" +) + +// HostPrefixHandlerName is the handler name for the host prefix request +// handler. +const HostPrefixHandlerName = "awssdk.endpoint.HostPrefixHandler" + +// NewHostPrefixHandler constructs a build handler +func NewHostPrefixHandler(prefix string, labelsFn func() map[string]string) request.NamedHandler { + builder := HostPrefixBuilder{ + Prefix: prefix, + LabelsFn: labelsFn, + } + + return request.NamedHandler{ + Name: HostPrefixHandlerName, + Fn: builder.Build, + } +} + +// HostPrefixBuilder provides the request handler to expand and prepend +// the host prefix into the operation's request endpoint host. +type HostPrefixBuilder struct { + Prefix string + LabelsFn func() map[string]string +} + +// Build updates the passed in Request with the HostPrefix template expanded. +func (h HostPrefixBuilder) Build(r *request.Request) { + if aws.BoolValue(r.Config.DisableEndpointHostPrefix) { + return + } + + var labels map[string]string + if h.LabelsFn != nil { + labels = h.LabelsFn() + } + + prefix := h.Prefix + for name, value := range labels { + prefix = strings.Replace(prefix, "{"+name+"}", value, -1) + } + + r.HTTPRequest.URL.Host = prefix + r.HTTPRequest.URL.Host + if len(r.HTTPRequest.Host) > 0 { + r.HTTPRequest.Host = prefix + r.HTTPRequest.Host + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go new file mode 100644 index 00000000..53831dff --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/idempotency.go @@ -0,0 +1,75 @@ +package protocol + +import ( + "crypto/rand" + "fmt" + "reflect" +) + +// RandReader is the random reader the protocol package will use to read +// random bytes from. This is exported for testing, and should not be used. +var RandReader = rand.Reader + +const idempotencyTokenFillTag = `idempotencyToken` + +// CanSetIdempotencyToken returns true if the struct field should be +// automatically populated with a Idempotency token. +// +// Only *string and string type fields that are tagged with idempotencyToken +// which are not already set can be auto filled. +func CanSetIdempotencyToken(v reflect.Value, f reflect.StructField) bool { + switch u := v.Interface().(type) { + // To auto fill an Idempotency token the field must be a string, + // tagged for auto fill, and have a zero value. + case *string: + return u == nil && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 + case string: + return len(u) == 0 && len(f.Tag.Get(idempotencyTokenFillTag)) != 0 + } + + return false +} + +// GetIdempotencyToken returns a randomly generated idempotency token. +func GetIdempotencyToken() string { + b := make([]byte, 16) + RandReader.Read(b) + + return UUIDVersion4(b) +} + +// SetIdempotencyToken will set the value provided with a Idempotency Token. +// Given that the value can be set. Will panic if value is not setable. +func SetIdempotencyToken(v reflect.Value) { + if v.Kind() == reflect.Ptr { + if v.IsNil() && v.CanSet() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + v = reflect.Indirect(v) + + if !v.CanSet() { + panic(fmt.Sprintf("unable to set idempotnecy token %v", v)) + } + + b := make([]byte, 16) + _, err := rand.Read(b) + if err != nil { + // TODO handle error + return + } + + v.Set(reflect.ValueOf(UUIDVersion4(b))) +} + +// UUIDVersion4 returns a Version 4 random UUID from the byte slice provided +func UUIDVersion4(u []byte) string { + // https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29 + // 13th character is "4" + u[6] = (u[6] | 0x40) & 0x4F + // 17th character is "8", "9", "a", or "b" + u[8] = (u[8] | 0x80) & 0xBF + + return fmt.Sprintf(`%X-%X-%X-%X-%X`, u[0:4], u[4:6], u[6:8], u[8:10], u[10:]) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go new file mode 100644 index 00000000..864fb670 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/build.go @@ -0,0 +1,296 @@ +// Package jsonutil provides JSON serialization of AWS requests and responses. +package jsonutil + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "math" + "reflect" + "sort" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/private/protocol" +) + +var timeType = reflect.ValueOf(time.Time{}).Type() +var byteSliceType = reflect.ValueOf([]byte{}).Type() + +// BuildJSON builds a JSON string for a given object v. +func BuildJSON(v interface{}) ([]byte, error) { + var buf bytes.Buffer + + err := buildAny(reflect.ValueOf(v), &buf, "") + return buf.Bytes(), err +} + +func buildAny(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + origVal := value + value = reflect.Indirect(value) + if !value.IsValid() { + return nil + } + + vtype := value.Type() + + t := tag.Get("type") + if t == "" { + switch vtype.Kind() { + case reflect.Struct: + // also it can't be a time object + if value.Type() != timeType { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := value.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } + } + } + + switch t { + case "structure": + if field, ok := vtype.FieldByName("_"); ok { + tag = field.Tag + } + return buildStruct(value, buf, tag) + case "list": + return buildList(value, buf, tag) + case "map": + return buildMap(value, buf, tag) + default: + return buildScalar(origVal, buf, tag) + } +} + +func buildStruct(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + if !value.IsValid() { + return nil + } + + // unwrap payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := value.Type().FieldByName(payload) + tag = field.Tag + value = elemOf(value.FieldByName(payload)) + + if !value.IsValid() { + return nil + } + } + + buf.WriteByte('{') + + t := value.Type() + first := true + for i := 0; i < t.NumField(); i++ { + member := value.Field(i) + + // This allocates the most memory. + // Additionally, we cannot skip nil fields due to + // idempotency auto filling. + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + if field.Tag.Get("json") == "-" { + continue + } + if field.Tag.Get("location") != "" { + continue // ignore non-body elements + } + if field.Tag.Get("ignore") != "" { + continue + } + + if protocol.CanSetIdempotencyToken(member, field) { + token := protocol.GetIdempotencyToken() + member = reflect.ValueOf(&token) + } + + if (member.Kind() == reflect.Ptr || member.Kind() == reflect.Slice || member.Kind() == reflect.Map) && member.IsNil() { + continue // ignore unset fields + } + + if first { + first = false + } else { + buf.WriteByte(',') + } + + // figure out what this field is called + name := field.Name + if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + writeString(name, buf) + buf.WriteString(`:`) + + err := buildAny(member, buf, field.Tag) + if err != nil { + return err + } + + } + + buf.WriteString("}") + + return nil +} + +func buildList(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + buf.WriteString("[") + + for i := 0; i < value.Len(); i++ { + buildAny(value.Index(i), buf, "") + + if i < value.Len()-1 { + buf.WriteString(",") + } + } + + buf.WriteString("]") + + return nil +} + +type sortedValues []reflect.Value + +func (sv sortedValues) Len() int { return len(sv) } +func (sv sortedValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] } +func (sv sortedValues) Less(i, j int) bool { return sv[i].String() < sv[j].String() } + +func buildMap(value reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + buf.WriteString("{") + + sv := sortedValues(value.MapKeys()) + sort.Sort(sv) + + for i, k := range sv { + if i > 0 { + buf.WriteByte(',') + } + + writeString(k.String(), buf) + buf.WriteString(`:`) + + buildAny(value.MapIndex(k), buf, "") + } + + buf.WriteString("}") + + return nil +} + +func buildScalar(v reflect.Value, buf *bytes.Buffer, tag reflect.StructTag) error { + // prevents allocation on the heap. + scratch := [64]byte{} + switch value := reflect.Indirect(v); value.Kind() { + case reflect.String: + writeString(value.String(), buf) + case reflect.Bool: + if value.Bool() { + buf.WriteString("true") + } else { + buf.WriteString("false") + } + case reflect.Int64: + buf.Write(strconv.AppendInt(scratch[:0], value.Int(), 10)) + case reflect.Float64: + f := value.Float() + if math.IsInf(f, 0) || math.IsNaN(f) { + return &json.UnsupportedValueError{Value: v, Str: strconv.FormatFloat(f, 'f', -1, 64)} + } + buf.Write(strconv.AppendFloat(scratch[:0], f, 'f', -1, 64)) + default: + switch converted := value.Interface().(type) { + case time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.UnixTimeFormatName + } + + ts := protocol.FormatTime(format, converted) + if format != protocol.UnixTimeFormatName { + ts = `"` + ts + `"` + } + + buf.WriteString(ts) + case []byte: + if !value.IsNil() { + buf.WriteByte('"') + if len(converted) < 1024 { + // for small buffers, using Encode directly is much faster. + dst := make([]byte, base64.StdEncoding.EncodedLen(len(converted))) + base64.StdEncoding.Encode(dst, converted) + buf.Write(dst) + } else { + // for large buffers, avoid unnecessary extra temporary + // buffer space. + enc := base64.NewEncoder(base64.StdEncoding, buf) + enc.Write(converted) + enc.Close() + } + buf.WriteByte('"') + } + case aws.JSONValue: + str, err := protocol.EncodeJSONValue(converted, protocol.QuotedEscape) + if err != nil { + return fmt.Errorf("unable to encode JSONValue, %v", err) + } + buf.WriteString(str) + default: + return fmt.Errorf("unsupported JSON value %v (%s)", value.Interface(), value.Type()) + } + } + return nil +} + +var hex = "0123456789abcdef" + +func writeString(s string, buf *bytes.Buffer) { + buf.WriteByte('"') + for i := 0; i < len(s); i++ { + if s[i] == '"' { + buf.WriteString(`\"`) + } else if s[i] == '\\' { + buf.WriteString(`\\`) + } else if s[i] == '\b' { + buf.WriteString(`\b`) + } else if s[i] == '\f' { + buf.WriteString(`\f`) + } else if s[i] == '\r' { + buf.WriteString(`\r`) + } else if s[i] == '\t' { + buf.WriteString(`\t`) + } else if s[i] == '\n' { + buf.WriteString(`\n`) + } else if s[i] < 32 { + buf.WriteString("\\u00") + buf.WriteByte(hex[s[i]>>4]) + buf.WriteByte(hex[s[i]&0xF]) + } else { + buf.WriteByte(s[i]) + } + } + buf.WriteByte('"') +} + +// Returns the reflection element of a value, if it is a pointer. +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go new file mode 100644 index 00000000..ea0da79a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/json/jsonutil/unmarshal.go @@ -0,0 +1,250 @@ +package jsonutil + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "reflect" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/private/protocol" +) + +// UnmarshalJSONError unmarshal's the reader's JSON document into the passed in +// type. The value to unmarshal the json document into must be a pointer to the +// type. +func UnmarshalJSONError(v interface{}, stream io.Reader) error { + var errBuf bytes.Buffer + body := io.TeeReader(stream, &errBuf) + + err := json.NewDecoder(body).Decode(v) + if err != nil { + msg := "failed decoding error message" + if err == io.EOF { + msg = "error message missing" + err = nil + } + return awserr.NewUnmarshalError(err, msg, errBuf.Bytes()) + } + + return nil +} + +// UnmarshalJSON reads a stream and unmarshals the results in object v. +func UnmarshalJSON(v interface{}, stream io.Reader) error { + var out interface{} + + err := json.NewDecoder(stream).Decode(&out) + if err == io.EOF { + return nil + } else if err != nil { + return err + } + + return unmarshalAny(reflect.ValueOf(v), out, "") +} + +func unmarshalAny(value reflect.Value, data interface{}, tag reflect.StructTag) error { + vtype := value.Type() + if vtype.Kind() == reflect.Ptr { + vtype = vtype.Elem() // check kind of actual element type + } + + t := tag.Get("type") + if t == "" { + switch vtype.Kind() { + case reflect.Struct: + // also it can't be a time object + if _, ok := value.Interface().(*time.Time); !ok { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := value.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + // cannot be a JSONValue map + if _, ok := value.Interface().(aws.JSONValue); !ok { + t = "map" + } + } + } + + switch t { + case "structure": + if field, ok := vtype.FieldByName("_"); ok { + tag = field.Tag + } + return unmarshalStruct(value, data, tag) + case "list": + return unmarshalList(value, data, tag) + case "map": + return unmarshalMap(value, data, tag) + default: + return unmarshalScalar(value, data, tag) + } +} + +func unmarshalStruct(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + mapData, ok := data.(map[string]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a structure (%#v)", data) + } + + t := value.Type() + if value.Kind() == reflect.Ptr { + if value.IsNil() { // create the structure if it's nil + s := reflect.New(value.Type().Elem()) + value.Set(s) + value = s + } + + value = value.Elem() + t = t.Elem() + } + + // unwrap any payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := t.FieldByName(payload) + return unmarshalAny(value.FieldByName(payload), data, field.Tag) + } + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if field.PkgPath != "" { + continue // ignore unexported fields + } + + // figure out what this field is called + name := field.Name + if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + member := value.FieldByIndex(field.Index) + err := unmarshalAny(member, mapData[name], field.Tag) + if err != nil { + return err + } + } + return nil +} + +func unmarshalList(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + listData, ok := data.([]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a list (%#v)", data) + } + + if value.IsNil() { + l := len(listData) + value.Set(reflect.MakeSlice(value.Type(), l, l)) + } + + for i, c := range listData { + err := unmarshalAny(value.Index(i), c, "") + if err != nil { + return err + } + } + + return nil +} + +func unmarshalMap(value reflect.Value, data interface{}, tag reflect.StructTag) error { + if data == nil { + return nil + } + mapData, ok := data.(map[string]interface{}) + if !ok { + return fmt.Errorf("JSON value is not a map (%#v)", data) + } + + if value.IsNil() { + value.Set(reflect.MakeMap(value.Type())) + } + + for k, v := range mapData { + kvalue := reflect.ValueOf(k) + vvalue := reflect.New(value.Type().Elem()).Elem() + + unmarshalAny(vvalue, v, "") + value.SetMapIndex(kvalue, vvalue) + } + + return nil +} + +func unmarshalScalar(value reflect.Value, data interface{}, tag reflect.StructTag) error { + + switch d := data.(type) { + case nil: + return nil // nothing to do here + case string: + switch value.Interface().(type) { + case *string: + value.Set(reflect.ValueOf(&d)) + case []byte: + b, err := base64.StdEncoding.DecodeString(d) + if err != nil { + return err + } + value.Set(reflect.ValueOf(b)) + case *time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.ISO8601TimeFormatName + } + + t, err := protocol.ParseTime(format, d) + if err != nil { + return err + } + value.Set(reflect.ValueOf(&t)) + case aws.JSONValue: + // No need to use escaping as the value is a non-quoted string. + v, err := protocol.DecodeJSONValue(d, protocol.NoEscape) + if err != nil { + return err + } + value.Set(reflect.ValueOf(v)) + default: + return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) + } + case float64: + switch value.Interface().(type) { + case *int64: + di := int64(d) + value.Set(reflect.ValueOf(&di)) + case *float64: + value.Set(reflect.ValueOf(&d)) + case *time.Time: + // Time unmarshaled from a float64 can only be epoch seconds + t := time.Unix(int64(d), 0).UTC() + value.Set(reflect.ValueOf(&t)) + default: + return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) + } + case bool: + switch value.Interface().(type) { + case *bool: + value.Set(reflect.ValueOf(&d)) + default: + return fmt.Errorf("unsupported value: %v (%s)", value.Interface(), value.Type()) + } + default: + return fmt.Errorf("unsupported JSON value (%v)", data) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go new file mode 100644 index 00000000..bfedc9fd --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonrpc/jsonrpc.go @@ -0,0 +1,110 @@ +// Package jsonrpc provides JSON RPC utilities for serialization of AWS +// requests and responses. +package jsonrpc + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/json.json build_test.go +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/json.json unmarshal_test.go + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" + "github.com/aws/aws-sdk-go/private/protocol/rest" +) + +var emptyJSON = []byte("{}") + +// BuildHandler is a named request handler for building jsonrpc protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Build", Fn: Build} + +// UnmarshalHandler is a named request handler for unmarshaling jsonrpc protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.jsonrpc.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling jsonrpc protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalMeta", Fn: UnmarshalMeta} + +// UnmarshalErrorHandler is a named request handler for unmarshaling jsonrpc protocol request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.jsonrpc.UnmarshalError", Fn: UnmarshalError} + +// Build builds a JSON payload for a JSON RPC request. +func Build(req *request.Request) { + var buf []byte + var err error + if req.ParamsFilled() { + buf, err = jsonutil.BuildJSON(req.Params) + if err != nil { + req.Error = awserr.New(request.ErrCodeSerialization, "failed encoding JSON RPC request", err) + return + } + } else { + buf = emptyJSON + } + + if req.ClientInfo.TargetPrefix != "" || string(buf) != "{}" { + req.SetBufferBody(buf) + } + + if req.ClientInfo.TargetPrefix != "" { + target := req.ClientInfo.TargetPrefix + "." + req.Operation.Name + req.HTTPRequest.Header.Add("X-Amz-Target", target) + } + + // Only set the content type if one is not already specified and an + // JSONVersion is specified. + if ct, v := req.HTTPRequest.Header.Get("Content-Type"), req.ClientInfo.JSONVersion; len(ct) == 0 && len(v) != 0 { + jsonVersion := req.ClientInfo.JSONVersion + req.HTTPRequest.Header.Set("Content-Type", "application/x-amz-json-"+jsonVersion) + } +} + +// Unmarshal unmarshals a response for a JSON RPC service. +func Unmarshal(req *request.Request) { + defer req.HTTPResponse.Body.Close() + if req.DataFilled() { + err := jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body) + if err != nil { + req.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, "failed decoding JSON RPC response", err), + req.HTTPResponse.StatusCode, + req.RequestID, + ) + } + } + return +} + +// UnmarshalMeta unmarshals headers from a response for a JSON RPC service. +func UnmarshalMeta(req *request.Request) { + rest.UnmarshalMeta(req) +} + +// UnmarshalError unmarshals an error response for a JSON RPC service. +func UnmarshalError(req *request.Request) { + defer req.HTTPResponse.Body.Close() + + var jsonErr jsonErrorResponse + err := jsonutil.UnmarshalJSONError(&jsonErr, req.HTTPResponse.Body) + if err != nil { + req.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to unmarshal error message", err), + req.HTTPResponse.StatusCode, + req.RequestID, + ) + return + } + + codes := strings.SplitN(jsonErr.Code, "#", 2) + req.Error = awserr.NewRequestFailure( + awserr.New(codes[len(codes)-1], jsonErr.Message, nil), + req.HTTPResponse.StatusCode, + req.RequestID, + ) +} + +type jsonErrorResponse struct { + Code string `json:"__type"` + Message string `json:"message"` +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go new file mode 100644 index 00000000..776d1101 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/jsonvalue.go @@ -0,0 +1,76 @@ +package protocol + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + + "github.com/aws/aws-sdk-go/aws" +) + +// EscapeMode is the mode that should be use for escaping a value +type EscapeMode uint + +// The modes for escaping a value before it is marshaled, and unmarshaled. +const ( + NoEscape EscapeMode = iota + Base64Escape + QuotedEscape +) + +// EncodeJSONValue marshals the value into a JSON string, and optionally base64 +// encodes the string before returning it. +// +// Will panic if the escape mode is unknown. +func EncodeJSONValue(v aws.JSONValue, escape EscapeMode) (string, error) { + b, err := json.Marshal(v) + if err != nil { + return "", err + } + + switch escape { + case NoEscape: + return string(b), nil + case Base64Escape: + return base64.StdEncoding.EncodeToString(b), nil + case QuotedEscape: + return strconv.Quote(string(b)), nil + } + + panic(fmt.Sprintf("EncodeJSONValue called with unknown EscapeMode, %v", escape)) +} + +// DecodeJSONValue will attempt to decode the string input as a JSONValue. +// Optionally decoding base64 the value first before JSON unmarshaling. +// +// Will panic if the escape mode is unknown. +func DecodeJSONValue(v string, escape EscapeMode) (aws.JSONValue, error) { + var b []byte + var err error + + switch escape { + case NoEscape: + b = []byte(v) + case Base64Escape: + b, err = base64.StdEncoding.DecodeString(v) + case QuotedEscape: + var u string + u, err = strconv.Unquote(v) + b = []byte(u) + default: + panic(fmt.Sprintf("DecodeJSONValue called with unknown EscapeMode, %v", escape)) + } + + if err != nil { + return nil, err + } + + m := aws.JSONValue{} + err = json.Unmarshal(b, &m) + if err != nil { + return nil, err + } + + return m, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go new file mode 100644 index 00000000..e21614a1 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/payload.go @@ -0,0 +1,81 @@ +package protocol + +import ( + "io" + "io/ioutil" + "net/http" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" +) + +// PayloadUnmarshaler provides the interface for unmarshaling a payload's +// reader into a SDK shape. +type PayloadUnmarshaler interface { + UnmarshalPayload(io.Reader, interface{}) error +} + +// HandlerPayloadUnmarshal implements the PayloadUnmarshaler from a +// HandlerList. This provides the support for unmarshaling a payload reader to +// a shape without needing a SDK request first. +type HandlerPayloadUnmarshal struct { + Unmarshalers request.HandlerList +} + +// UnmarshalPayload unmarshals the io.Reader payload into the SDK shape using +// the Unmarshalers HandlerList provided. Returns an error if unable +// unmarshaling fails. +func (h HandlerPayloadUnmarshal) UnmarshalPayload(r io.Reader, v interface{}) error { + req := &request.Request{ + HTTPRequest: &http.Request{}, + HTTPResponse: &http.Response{ + StatusCode: 200, + Header: http.Header{}, + Body: ioutil.NopCloser(r), + }, + Data: v, + } + + h.Unmarshalers.Run(req) + + return req.Error +} + +// PayloadMarshaler provides the interface for marshaling a SDK shape into and +// io.Writer. +type PayloadMarshaler interface { + MarshalPayload(io.Writer, interface{}) error +} + +// HandlerPayloadMarshal implements the PayloadMarshaler from a HandlerList. +// This provides support for marshaling a SDK shape into an io.Writer without +// needing a SDK request first. +type HandlerPayloadMarshal struct { + Marshalers request.HandlerList +} + +// MarshalPayload marshals the SDK shape into the io.Writer using the +// Marshalers HandlerList provided. Returns an error if unable if marshal +// fails. +func (h HandlerPayloadMarshal) MarshalPayload(w io.Writer, v interface{}) error { + req := request.New( + aws.Config{}, + metadata.ClientInfo{}, + request.Handlers{}, + nil, + &request.Operation{HTTPMethod: "GET"}, + v, + nil, + ) + + h.Marshalers.Run(req) + + if req.Error != nil { + return req.Error + } + + io.Copy(w, req.GetBody()) + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go new file mode 100644 index 00000000..0cb99eb5 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/build.go @@ -0,0 +1,36 @@ +// Package query provides serialization of AWS query requests, and responses. +package query + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/query.json build_test.go + +import ( + "net/url" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/query/queryutil" +) + +// BuildHandler is a named request handler for building query protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.query.Build", Fn: Build} + +// Build builds a request for an AWS Query service. +func Build(r *request.Request) { + body := url.Values{ + "Action": {r.Operation.Name}, + "Version": {r.ClientInfo.APIVersion}, + } + if err := queryutil.Parse(body, r.Params, false); err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed encoding Query request", err) + return + } + + if !r.IsPresigned() { + r.HTTPRequest.Method = "POST" + r.HTTPRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=utf-8") + r.SetBufferBody([]byte(body.Encode())) + } else { // This is a pre-signed request + r.HTTPRequest.Method = "GET" + r.HTTPRequest.URL.RawQuery = body.Encode() + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go new file mode 100644 index 00000000..75866d01 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/queryutil/queryutil.go @@ -0,0 +1,246 @@ +package queryutil + +import ( + "encoding/base64" + "fmt" + "net/url" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/private/protocol" +) + +// Parse parses an object i and fills a url.Values object. The isEC2 flag +// indicates if this is the EC2 Query sub-protocol. +func Parse(body url.Values, i interface{}, isEC2 bool) error { + q := queryParser{isEC2: isEC2} + return q.parseValue(body, reflect.ValueOf(i), "", "") +} + +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} + +type queryParser struct { + isEC2 bool +} + +func (q *queryParser) parseValue(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + value = elemOf(value) + + // no need to handle zero values + if !value.IsValid() { + return nil + } + + t := tag.Get("type") + if t == "" { + switch value.Kind() { + case reflect.Struct: + t = "structure" + case reflect.Slice: + t = "list" + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + return q.parseStruct(v, value, prefix) + case "list": + return q.parseList(v, value, prefix, tag) + case "map": + return q.parseMap(v, value, prefix, tag) + default: + return q.parseScalar(v, value, prefix, tag) + } +} + +func (q *queryParser) parseStruct(v url.Values, value reflect.Value, prefix string) error { + if !value.IsValid() { + return nil + } + + t := value.Type() + for i := 0; i < value.NumField(); i++ { + elemValue := elemOf(value.Field(i)) + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + if field.Tag.Get("ignore") != "" { + continue + } + + if protocol.CanSetIdempotencyToken(value.Field(i), field) { + token := protocol.GetIdempotencyToken() + elemValue = reflect.ValueOf(token) + } + + var name string + if q.isEC2 { + name = field.Tag.Get("queryName") + } + if name == "" { + if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" { + name = field.Tag.Get("locationNameList") + } else if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + if name != "" && q.isEC2 { + name = strings.ToUpper(name[0:1]) + name[1:] + } + } + if name == "" { + name = field.Name + } + + if prefix != "" { + name = prefix + "." + name + } + + if err := q.parseValue(v, elemValue, name, field.Tag); err != nil { + return err + } + } + return nil +} + +func (q *queryParser) parseList(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + // If it's empty, generate an empty value + if !value.IsNil() && value.Len() == 0 { + v.Set(prefix, "") + return nil + } + + if _, ok := value.Interface().([]byte); ok { + return q.parseScalar(v, value, prefix, tag) + } + + // check for unflattened list member + if !q.isEC2 && tag.Get("flattened") == "" { + if listName := tag.Get("locationNameList"); listName == "" { + prefix += ".member" + } else { + prefix += "." + listName + } + } + + for i := 0; i < value.Len(); i++ { + slicePrefix := prefix + if slicePrefix == "" { + slicePrefix = strconv.Itoa(i + 1) + } else { + slicePrefix = slicePrefix + "." + strconv.Itoa(i+1) + } + if err := q.parseValue(v, value.Index(i), slicePrefix, ""); err != nil { + return err + } + } + return nil +} + +func (q *queryParser) parseMap(v url.Values, value reflect.Value, prefix string, tag reflect.StructTag) error { + // If it's empty, generate an empty value + if !value.IsNil() && value.Len() == 0 { + v.Set(prefix, "") + return nil + } + + // check for unflattened list member + if !q.isEC2 && tag.Get("flattened") == "" { + prefix += ".entry" + } + + // sort keys for improved serialization consistency. + // this is not strictly necessary for protocol support. + mapKeyValues := value.MapKeys() + mapKeys := map[string]reflect.Value{} + mapKeyNames := make([]string, len(mapKeyValues)) + for i, mapKey := range mapKeyValues { + name := mapKey.String() + mapKeys[name] = mapKey + mapKeyNames[i] = name + } + sort.Strings(mapKeyNames) + + for i, mapKeyName := range mapKeyNames { + mapKey := mapKeys[mapKeyName] + mapValue := value.MapIndex(mapKey) + + kname := tag.Get("locationNameKey") + if kname == "" { + kname = "key" + } + vname := tag.Get("locationNameValue") + if vname == "" { + vname = "value" + } + + // serialize key + var keyName string + if prefix == "" { + keyName = strconv.Itoa(i+1) + "." + kname + } else { + keyName = prefix + "." + strconv.Itoa(i+1) + "." + kname + } + + if err := q.parseValue(v, mapKey, keyName, ""); err != nil { + return err + } + + // serialize value + var valueName string + if prefix == "" { + valueName = strconv.Itoa(i+1) + "." + vname + } else { + valueName = prefix + "." + strconv.Itoa(i+1) + "." + vname + } + + if err := q.parseValue(v, mapValue, valueName, ""); err != nil { + return err + } + } + + return nil +} + +func (q *queryParser) parseScalar(v url.Values, r reflect.Value, name string, tag reflect.StructTag) error { + switch value := r.Interface().(type) { + case string: + v.Set(name, value) + case []byte: + if !r.IsNil() { + v.Set(name, base64.StdEncoding.EncodeToString(value)) + } + case bool: + v.Set(name, strconv.FormatBool(value)) + case int64: + v.Set(name, strconv.FormatInt(value, 10)) + case int: + v.Set(name, strconv.Itoa(value)) + case float64: + v.Set(name, strconv.FormatFloat(value, 'f', -1, 64)) + case float32: + v.Set(name, strconv.FormatFloat(float64(value), 'f', -1, 32)) + case time.Time: + const ISO8601UTC = "2006-01-02T15:04:05Z" + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.ISO8601TimeFormatName + } + + v.Set(name, protocol.FormatTime(format, value)) + default: + return fmt.Errorf("unsupported value for param %s: %v (%s)", name, r.Interface(), r.Type().Name()) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go new file mode 100644 index 00000000..f69c1efc --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal.go @@ -0,0 +1,39 @@ +package query + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/query.json unmarshal_test.go + +import ( + "encoding/xml" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" +) + +// UnmarshalHandler is a named request handler for unmarshaling query protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.query.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling query protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalMeta", Fn: UnmarshalMeta} + +// Unmarshal unmarshals a response for an AWS Query service. +func Unmarshal(r *request.Request) { + defer r.HTTPResponse.Body.Close() + if r.DataFilled() { + decoder := xml.NewDecoder(r.HTTPResponse.Body) + err := xmlutil.UnmarshalXML(r.Data, decoder, r.Operation.Name+"Result") + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, "failed decoding Query response", err), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + } +} + +// UnmarshalMeta unmarshals header response values for an AWS Query service. +func UnmarshalMeta(r *request.Request) { + r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go new file mode 100644 index 00000000..831b0110 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/query/unmarshal_error.go @@ -0,0 +1,69 @@ +package query + +import ( + "encoding/xml" + "fmt" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" +) + +// UnmarshalErrorHandler is a name request handler to unmarshal request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.query.UnmarshalError", Fn: UnmarshalError} + +type xmlErrorResponse struct { + Code string `xml:"Error>Code"` + Message string `xml:"Error>Message"` + RequestID string `xml:"RequestId"` +} + +type xmlResponseError struct { + xmlErrorResponse +} + +func (e *xmlResponseError) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + const svcUnavailableTagName = "ServiceUnavailableException" + const errorResponseTagName = "ErrorResponse" + + switch start.Name.Local { + case svcUnavailableTagName: + e.Code = svcUnavailableTagName + e.Message = "service is unavailable" + return d.Skip() + + case errorResponseTagName: + return d.DecodeElement(&e.xmlErrorResponse, &start) + + default: + return fmt.Errorf("unknown error response tag, %v", start) + } +} + +// UnmarshalError unmarshals an error response for an AWS Query service. +func UnmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + var respErr xmlResponseError + err := xmlutil.UnmarshalXMLError(&respErr, r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to unmarshal error message", err), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + + reqID := respErr.RequestID + if len(reqID) == 0 { + reqID = r.RequestID + } + + r.Error = awserr.NewRequestFailure( + awserr.New(respErr.Code, respErr.Message, nil), + r.HTTPResponse.StatusCode, + reqID, + ) +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go new file mode 100644 index 00000000..1301b149 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/build.go @@ -0,0 +1,310 @@ +// Package rest provides RESTful serialization of AWS requests and responses. +package rest + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "net/http" + "net/url" + "path" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" +) + +// Whether the byte value can be sent without escaping in AWS URLs +var noEscape [256]bool + +var errValueNotSet = fmt.Errorf("value not set") + +var byteSliceType = reflect.TypeOf([]byte{}) + +func init() { + for i := 0; i < len(noEscape); i++ { + // AWS expects every character except these to be escaped + noEscape[i] = (i >= 'A' && i <= 'Z') || + (i >= 'a' && i <= 'z') || + (i >= '0' && i <= '9') || + i == '-' || + i == '.' || + i == '_' || + i == '~' + } +} + +// BuildHandler is a named request handler for building rest protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.rest.Build", Fn: Build} + +// Build builds the REST component of a service request. +func Build(r *request.Request) { + if r.ParamsFilled() { + v := reflect.ValueOf(r.Params).Elem() + buildLocationElements(r, v, false) + buildBody(r, v) + } +} + +// BuildAsGET builds the REST component of a service request with the ability to hoist +// data from the body. +func BuildAsGET(r *request.Request) { + if r.ParamsFilled() { + v := reflect.ValueOf(r.Params).Elem() + buildLocationElements(r, v, true) + buildBody(r, v) + } +} + +func buildLocationElements(r *request.Request, v reflect.Value, buildGETQuery bool) { + query := r.HTTPRequest.URL.Query() + + // Setup the raw path to match the base path pattern. This is needed + // so that when the path is mutated a custom escaped version can be + // stored in RawPath that will be used by the Go client. + r.HTTPRequest.URL.RawPath = r.HTTPRequest.URL.Path + + for i := 0; i < v.NumField(); i++ { + m := v.Field(i) + if n := v.Type().Field(i).Name; n[0:1] == strings.ToLower(n[0:1]) { + continue + } + + if m.IsValid() { + field := v.Type().Field(i) + name := field.Tag.Get("locationName") + if name == "" { + name = field.Name + } + if kind := m.Kind(); kind == reflect.Ptr { + m = m.Elem() + } else if kind == reflect.Interface { + if !m.Elem().IsValid() { + continue + } + } + if !m.IsValid() { + continue + } + if field.Tag.Get("ignore") != "" { + continue + } + + // Support the ability to customize values to be marshaled as a + // blob even though they were modeled as a string. Required for S3 + // API operations like SSECustomerKey is modeled as stirng but + // required to be base64 encoded in request. + if field.Tag.Get("marshal-as") == "blob" { + m = m.Convert(byteSliceType) + } + + var err error + switch field.Tag.Get("location") { + case "headers": // header maps + err = buildHeaderMap(&r.HTTPRequest.Header, m, field.Tag) + case "header": + err = buildHeader(&r.HTTPRequest.Header, m, name, field.Tag) + case "uri": + err = buildURI(r.HTTPRequest.URL, m, name, field.Tag) + case "querystring": + err = buildQueryString(query, m, name, field.Tag) + default: + if buildGETQuery { + err = buildQueryString(query, m, name, field.Tag) + } + } + r.Error = err + } + if r.Error != nil { + return + } + } + + r.HTTPRequest.URL.RawQuery = query.Encode() + if !aws.BoolValue(r.Config.DisableRestProtocolURICleaning) { + cleanPath(r.HTTPRequest.URL) + } +} + +func buildBody(r *request.Request, v reflect.Value) { + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + pfield, _ := v.Type().FieldByName(payloadName) + if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { + payload := reflect.Indirect(v.FieldByName(payloadName)) + if payload.IsValid() && payload.Interface() != nil { + switch reader := payload.Interface().(type) { + case io.ReadSeeker: + r.SetReaderBody(reader) + case []byte: + r.SetBufferBody(reader) + case string: + r.SetStringBody(reader) + default: + r.Error = awserr.New(request.ErrCodeSerialization, + "failed to encode REST request", + fmt.Errorf("unknown payload type %s", payload.Type())) + } + } + } + } + } +} + +func buildHeader(header *http.Header, v reflect.Value, name string, tag reflect.StructTag) error { + str, err := convertType(v, tag) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + } + + name = strings.TrimSpace(name) + str = strings.TrimSpace(str) + + header.Add(name, str) + + return nil +} + +func buildHeaderMap(header *http.Header, v reflect.Value, tag reflect.StructTag) error { + prefix := tag.Get("locationName") + for _, key := range v.MapKeys() { + str, err := convertType(v.MapIndex(key), tag) + if err == errValueNotSet { + continue + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + + } + keyStr := strings.TrimSpace(key.String()) + str = strings.TrimSpace(str) + + header.Add(prefix+keyStr, str) + } + return nil +} + +func buildURI(u *url.URL, v reflect.Value, name string, tag reflect.StructTag) error { + value, err := convertType(v, tag) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + } + + u.Path = strings.Replace(u.Path, "{"+name+"}", value, -1) + u.Path = strings.Replace(u.Path, "{"+name+"+}", value, -1) + + u.RawPath = strings.Replace(u.RawPath, "{"+name+"}", EscapePath(value, true), -1) + u.RawPath = strings.Replace(u.RawPath, "{"+name+"+}", EscapePath(value, false), -1) + + return nil +} + +func buildQueryString(query url.Values, v reflect.Value, name string, tag reflect.StructTag) error { + switch value := v.Interface().(type) { + case []*string: + for _, item := range value { + query.Add(name, *item) + } + case map[string]*string: + for key, item := range value { + query.Add(key, *item) + } + case map[string][]*string: + for key, items := range value { + for _, item := range items { + query.Add(key, *item) + } + } + default: + str, err := convertType(v, tag) + if err == errValueNotSet { + return nil + } else if err != nil { + return awserr.New(request.ErrCodeSerialization, "failed to encode REST request", err) + } + query.Set(name, str) + } + + return nil +} + +func cleanPath(u *url.URL) { + hasSlash := strings.HasSuffix(u.Path, "/") + + // clean up path, removing duplicate `/` + u.Path = path.Clean(u.Path) + u.RawPath = path.Clean(u.RawPath) + + if hasSlash && !strings.HasSuffix(u.Path, "/") { + u.Path += "/" + u.RawPath += "/" + } +} + +// EscapePath escapes part of a URL path in Amazon style +func EscapePath(path string, encodeSep bool) string { + var buf bytes.Buffer + for i := 0; i < len(path); i++ { + c := path[i] + if noEscape[c] || (c == '/' && !encodeSep) { + buf.WriteByte(c) + } else { + fmt.Fprintf(&buf, "%%%02X", c) + } + } + return buf.String() +} + +func convertType(v reflect.Value, tag reflect.StructTag) (str string, err error) { + v = reflect.Indirect(v) + if !v.IsValid() { + return "", errValueNotSet + } + + switch value := v.Interface().(type) { + case string: + str = value + case []byte: + str = base64.StdEncoding.EncodeToString(value) + case bool: + str = strconv.FormatBool(value) + case int64: + str = strconv.FormatInt(value, 10) + case float64: + str = strconv.FormatFloat(value, 'f', -1, 64) + case time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.RFC822TimeFormatName + if tag.Get("location") == "querystring" { + format = protocol.ISO8601TimeFormatName + } + } + str = protocol.FormatTime(format, value) + case aws.JSONValue: + if len(value) == 0 { + return "", errValueNotSet + } + escaping := protocol.NoEscape + if tag.Get("location") == "header" { + escaping = protocol.Base64Escape + } + str, err = protocol.EncodeJSONValue(value, escaping) + if err != nil { + return "", fmt.Errorf("unable to encode JSONValue, %v", err) + } + default: + err := fmt.Errorf("unsupported value for param %v (%s)", v.Interface(), v.Type()) + return "", err + } + return str, nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go new file mode 100644 index 00000000..4366de2e --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/payload.go @@ -0,0 +1,45 @@ +package rest + +import "reflect" + +// PayloadMember returns the payload field member of i if there is one, or nil. +func PayloadMember(i interface{}) interface{} { + if i == nil { + return nil + } + + v := reflect.ValueOf(i).Elem() + if !v.IsValid() { + return nil + } + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + field, _ := v.Type().FieldByName(payloadName) + if field.Tag.Get("type") != "structure" { + return nil + } + + payload := v.FieldByName(payloadName) + if payload.IsValid() || (payload.Kind() == reflect.Ptr && !payload.IsNil()) { + return payload.Interface() + } + } + } + return nil +} + +// PayloadType returns the type of a payload field member of i if there is one, or "". +func PayloadType(i interface{}) string { + v := reflect.Indirect(reflect.ValueOf(i)) + if !v.IsValid() { + return "" + } + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + if member, ok := v.Type().FieldByName(payloadName); ok { + return member.Tag.Get("type") + } + } + } + return "" +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go new file mode 100644 index 00000000..de021367 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/rest/unmarshal.go @@ -0,0 +1,225 @@ +package rest + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "io/ioutil" + "net/http" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" +) + +// UnmarshalHandler is a named request handler for unmarshaling rest protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.rest.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling rest protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.rest.UnmarshalMeta", Fn: UnmarshalMeta} + +// Unmarshal unmarshals the REST component of a response in a REST service. +func Unmarshal(r *request.Request) { + if r.DataFilled() { + v := reflect.Indirect(reflect.ValueOf(r.Data)) + unmarshalBody(r, v) + } +} + +// UnmarshalMeta unmarshals the REST metadata of a response in a REST service +func UnmarshalMeta(r *request.Request) { + r.RequestID = r.HTTPResponse.Header.Get("X-Amzn-Requestid") + if r.RequestID == "" { + // Alternative version of request id in the header + r.RequestID = r.HTTPResponse.Header.Get("X-Amz-Request-Id") + } + if r.DataFilled() { + v := reflect.Indirect(reflect.ValueOf(r.Data)) + unmarshalLocationElements(r, v) + } +} + +func unmarshalBody(r *request.Request, v reflect.Value) { + if field, ok := v.Type().FieldByName("_"); ok { + if payloadName := field.Tag.Get("payload"); payloadName != "" { + pfield, _ := v.Type().FieldByName(payloadName) + if ptag := pfield.Tag.Get("type"); ptag != "" && ptag != "structure" { + payload := v.FieldByName(payloadName) + if payload.IsValid() { + switch payload.Interface().(type) { + case []byte: + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + } else { + payload.Set(reflect.ValueOf(b)) + } + case *string: + defer r.HTTPResponse.Body.Close() + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + } else { + str := string(b) + payload.Set(reflect.ValueOf(&str)) + } + default: + switch payload.Type().String() { + case "io.ReadCloser": + payload.Set(reflect.ValueOf(r.HTTPResponse.Body)) + case "io.ReadSeeker": + b, err := ioutil.ReadAll(r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, + "failed to read response body", err) + return + } + payload.Set(reflect.ValueOf(ioutil.NopCloser(bytes.NewReader(b)))) + default: + io.Copy(ioutil.Discard, r.HTTPResponse.Body) + defer r.HTTPResponse.Body.Close() + r.Error = awserr.New(request.ErrCodeSerialization, + "failed to decode REST response", + fmt.Errorf("unknown payload type %s", payload.Type())) + } + } + } + } + } + } +} + +func unmarshalLocationElements(r *request.Request, v reflect.Value) { + for i := 0; i < v.NumField(); i++ { + m, field := v.Field(i), v.Type().Field(i) + if n := field.Name; n[0:1] == strings.ToLower(n[0:1]) { + continue + } + + if m.IsValid() { + name := field.Tag.Get("locationName") + if name == "" { + name = field.Name + } + + switch field.Tag.Get("location") { + case "statusCode": + unmarshalStatusCode(m, r.HTTPResponse.StatusCode) + case "header": + err := unmarshalHeader(m, r.HTTPResponse.Header.Get(name), field.Tag) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + break + } + case "headers": + prefix := field.Tag.Get("locationName") + err := unmarshalHeaderMap(m, r.HTTPResponse.Header, prefix) + if err != nil { + r.Error = awserr.New(request.ErrCodeSerialization, "failed to decode REST response", err) + break + } + } + } + if r.Error != nil { + return + } + } +} + +func unmarshalStatusCode(v reflect.Value, statusCode int) { + if !v.IsValid() { + return + } + + switch v.Interface().(type) { + case *int64: + s := int64(statusCode) + v.Set(reflect.ValueOf(&s)) + } +} + +func unmarshalHeaderMap(r reflect.Value, headers http.Header, prefix string) error { + switch r.Interface().(type) { + case map[string]*string: // we only support string map value types + out := map[string]*string{} + for k, v := range headers { + k = http.CanonicalHeaderKey(k) + if strings.HasPrefix(strings.ToLower(k), strings.ToLower(prefix)) { + out[k[len(prefix):]] = &v[0] + } + } + r.Set(reflect.ValueOf(out)) + } + return nil +} + +func unmarshalHeader(v reflect.Value, header string, tag reflect.StructTag) error { + isJSONValue := tag.Get("type") == "jsonvalue" + if isJSONValue { + if len(header) == 0 { + return nil + } + } else if !v.IsValid() || (header == "" && v.Elem().Kind() != reflect.String) { + return nil + } + + switch v.Interface().(type) { + case *string: + v.Set(reflect.ValueOf(&header)) + case []byte: + b, err := base64.StdEncoding.DecodeString(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&b)) + case *bool: + b, err := strconv.ParseBool(header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&b)) + case *int64: + i, err := strconv.ParseInt(header, 10, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&i)) + case *float64: + f, err := strconv.ParseFloat(header, 64) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&f)) + case *time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.RFC822TimeFormatName + } + t, err := protocol.ParseTime(format, header) + if err != nil { + return err + } + v.Set(reflect.ValueOf(&t)) + case aws.JSONValue: + escaping := protocol.NoEscape + if tag.Get("location") == "header" { + escaping = protocol.Base64Escape + } + m, err := protocol.DecodeJSONValue(header, escaping) + if err != nil { + return err + } + v.Set(reflect.ValueOf(m)) + default: + err := fmt.Errorf("Unsupported value for param %v (%s)", v.Interface(), v.Type()) + return err + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/restjson/restjson.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/restjson/restjson.go new file mode 100644 index 00000000..af4f6154 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/restjson/restjson.go @@ -0,0 +1,88 @@ +// Package restjson provides RESTful JSON serialization of AWS +// requests and responses. +package restjson + +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/input/rest-json.json build_test.go +//go:generate go run -tags codegen ../../../models/protocol_tests/generate.go ../../../models/protocol_tests/output/rest-json.json unmarshal_test.go + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" + "github.com/aws/aws-sdk-go/private/protocol/jsonrpc" + "github.com/aws/aws-sdk-go/private/protocol/rest" +) + +// BuildHandler is a named request handler for building restjson protocol requests +var BuildHandler = request.NamedHandler{Name: "awssdk.restjson.Build", Fn: Build} + +// UnmarshalHandler is a named request handler for unmarshaling restjson protocol requests +var UnmarshalHandler = request.NamedHandler{Name: "awssdk.restjson.Unmarshal", Fn: Unmarshal} + +// UnmarshalMetaHandler is a named request handler for unmarshaling restjson protocol request metadata +var UnmarshalMetaHandler = request.NamedHandler{Name: "awssdk.restjson.UnmarshalMeta", Fn: UnmarshalMeta} + +// UnmarshalErrorHandler is a named request handler for unmarshaling restjson protocol request errors +var UnmarshalErrorHandler = request.NamedHandler{Name: "awssdk.restjson.UnmarshalError", Fn: UnmarshalError} + +// Build builds a request for the REST JSON protocol. +func Build(r *request.Request) { + rest.Build(r) + + if t := rest.PayloadType(r.Params); t == "structure" || t == "" { + if v := r.HTTPRequest.Header.Get("Content-Type"); len(v) == 0 { + r.HTTPRequest.Header.Set("Content-Type", "application/json") + } + jsonrpc.Build(r) + } +} + +// Unmarshal unmarshals a response body for the REST JSON protocol. +func Unmarshal(r *request.Request) { + if t := rest.PayloadType(r.Data); t == "structure" || t == "" { + jsonrpc.Unmarshal(r) + } else { + rest.Unmarshal(r) + } +} + +// UnmarshalMeta unmarshals response headers for the REST JSON protocol. +func UnmarshalMeta(r *request.Request) { + rest.UnmarshalMeta(r) +} + +// UnmarshalError unmarshals a response error for the REST JSON protocol. +func UnmarshalError(r *request.Request) { + defer r.HTTPResponse.Body.Close() + + var jsonErr jsonErrorResponse + err := jsonutil.UnmarshalJSONError(&jsonErr, r.HTTPResponse.Body) + if err != nil { + r.Error = awserr.NewRequestFailure( + awserr.New(request.ErrCodeSerialization, + "failed to unmarshal response error", err), + r.HTTPResponse.StatusCode, + r.RequestID, + ) + return + } + + code := r.HTTPResponse.Header.Get("X-Amzn-Errortype") + if code == "" { + code = jsonErr.Code + } + + code = strings.SplitN(code, ":", 2)[0] + r.Error = awserr.NewRequestFailure( + awserr.New(code, jsonErr.Message, nil), + r.HTTPResponse.StatusCode, + r.RequestID, + ) +} + +type jsonErrorResponse struct { + Code string `json:"code"` + Message string `json:"message"` +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go new file mode 100644 index 00000000..b7ed6c6f --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/timestamp.go @@ -0,0 +1,72 @@ +package protocol + +import ( + "strconv" + "time" +) + +// Names of time formats supported by the SDK +const ( + RFC822TimeFormatName = "rfc822" + ISO8601TimeFormatName = "iso8601" + UnixTimeFormatName = "unixTimestamp" +) + +// Time formats supported by the SDK +const ( + // RFC 7231#section-7.1.1.1 timetamp format. e.g Tue, 29 Apr 2014 18:30:38 GMT + RFC822TimeFormat = "Mon, 2 Jan 2006 15:04:05 GMT" + + // RFC3339 a subset of the ISO8601 timestamp format. e.g 2014-04-29T18:30:38Z + ISO8601TimeFormat = "2006-01-02T15:04:05Z" +) + +// IsKnownTimestampFormat returns if the timestamp format name +// is know to the SDK's protocols. +func IsKnownTimestampFormat(name string) bool { + switch name { + case RFC822TimeFormatName: + fallthrough + case ISO8601TimeFormatName: + fallthrough + case UnixTimeFormatName: + return true + default: + return false + } +} + +// FormatTime returns a string value of the time. +func FormatTime(name string, t time.Time) string { + t = t.UTC() + + switch name { + case RFC822TimeFormatName: + return t.Format(RFC822TimeFormat) + case ISO8601TimeFormatName: + return t.Format(ISO8601TimeFormat) + case UnixTimeFormatName: + return strconv.FormatInt(t.Unix(), 10) + default: + panic("unknown timestamp format name, " + name) + } +} + +// ParseTime attempts to parse the time given the format. Returns +// the time if it was able to be parsed, and fails otherwise. +func ParseTime(formatName, value string) (time.Time, error) { + switch formatName { + case RFC822TimeFormatName: + return time.Parse(RFC822TimeFormat, value) + case ISO8601TimeFormatName: + return time.Parse(ISO8601TimeFormat, value) + case UnixTimeFormatName: + v, err := strconv.ParseFloat(value, 64) + if err != nil { + return time.Time{}, err + } + return time.Unix(int64(v), 0), nil + default: + panic("unknown timestamp format name, " + formatName) + } +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go new file mode 100644 index 00000000..da1a6811 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/unmarshal.go @@ -0,0 +1,21 @@ +package protocol + +import ( + "io" + "io/ioutil" + + "github.com/aws/aws-sdk-go/aws/request" +) + +// UnmarshalDiscardBodyHandler is a named request handler to empty and close a response's body +var UnmarshalDiscardBodyHandler = request.NamedHandler{Name: "awssdk.shared.UnmarshalDiscardBody", Fn: UnmarshalDiscardBody} + +// UnmarshalDiscardBody is a request handler to empty a response's body and closing it. +func UnmarshalDiscardBody(r *request.Request) { + if r.HTTPResponse == nil || r.HTTPResponse.Body == nil { + return + } + + io.Copy(ioutil.Discard, r.HTTPResponse.Body) + r.HTTPResponse.Body.Close() +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go new file mode 100644 index 00000000..cf981fe9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/build.go @@ -0,0 +1,306 @@ +// Package xmlutil provides XML serialization of AWS requests and responses. +package xmlutil + +import ( + "encoding/base64" + "encoding/xml" + "fmt" + "reflect" + "sort" + "strconv" + "time" + + "github.com/aws/aws-sdk-go/private/protocol" +) + +// BuildXML will serialize params into an xml.Encoder. Error will be returned +// if the serialization of any of the params or nested values fails. +func BuildXML(params interface{}, e *xml.Encoder) error { + return buildXML(params, e, false) +} + +func buildXML(params interface{}, e *xml.Encoder, sorted bool) error { + b := xmlBuilder{encoder: e, namespaces: map[string]string{}} + root := NewXMLElement(xml.Name{}) + if err := b.buildValue(reflect.ValueOf(params), root, ""); err != nil { + return err + } + for _, c := range root.Children { + for _, v := range c { + return StructToXML(e, v, sorted) + } + } + return nil +} + +// Returns the reflection element of a value, if it is a pointer. +func elemOf(value reflect.Value) reflect.Value { + for value.Kind() == reflect.Ptr { + value = value.Elem() + } + return value +} + +// A xmlBuilder serializes values from Go code to XML +type xmlBuilder struct { + encoder *xml.Encoder + namespaces map[string]string +} + +// buildValue generic XMLNode builder for any type. Will build value for their specific type +// struct, list, map, scalar. +// +// Also takes a "type" tag value to set what type a value should be converted to XMLNode as. If +// type is not provided reflect will be used to determine the value's type. +func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + value = elemOf(value) + if !value.IsValid() { // no need to handle zero values + return nil + } else if tag.Get("location") != "" { // don't handle non-body location values + return nil + } + + t := tag.Get("type") + if t == "" { + switch value.Kind() { + case reflect.Struct: + t = "structure" + case reflect.Slice: + t = "list" + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + if field, ok := value.Type().FieldByName("_"); ok { + tag = tag + reflect.StructTag(" ") + field.Tag + } + return b.buildStruct(value, current, tag) + case "list": + return b.buildList(value, current, tag) + case "map": + return b.buildMap(value, current, tag) + default: + return b.buildScalar(value, current, tag) + } +} + +// buildStruct adds a struct and its fields to the current XMLNode. All fields and any nested +// types are converted to XMLNodes also. +func (b *xmlBuilder) buildStruct(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if !value.IsValid() { + return nil + } + + // unwrap payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := value.Type().FieldByName(payload) + tag = field.Tag + value = elemOf(value.FieldByName(payload)) + + if !value.IsValid() { + return nil + } + } + + child := NewXMLElement(xml.Name{Local: tag.Get("locationName")}) + + // there is an xmlNamespace associated with this struct + if prefix, uri := tag.Get("xmlPrefix"), tag.Get("xmlURI"); uri != "" { + ns := xml.Attr{ + Name: xml.Name{Local: "xmlns"}, + Value: uri, + } + if prefix != "" { + b.namespaces[prefix] = uri // register the namespace + ns.Name.Local = "xmlns:" + prefix + } + + child.Attr = append(child.Attr, ns) + } + + var payloadFields, nonPayloadFields int + + t := value.Type() + for i := 0; i < value.NumField(); i++ { + member := elemOf(value.Field(i)) + field := t.Field(i) + + if field.PkgPath != "" { + continue // ignore unexported fields + } + if field.Tag.Get("ignore") != "" { + continue + } + + mTag := field.Tag + if mTag.Get("location") != "" { // skip non-body members + nonPayloadFields++ + continue + } + payloadFields++ + + if protocol.CanSetIdempotencyToken(value.Field(i), field) { + token := protocol.GetIdempotencyToken() + member = reflect.ValueOf(token) + } + + memberName := mTag.Get("locationName") + if memberName == "" { + memberName = field.Name + mTag = reflect.StructTag(string(mTag) + ` locationName:"` + memberName + `"`) + } + if err := b.buildValue(member, child, mTag); err != nil { + return err + } + } + + // Only case where the child shape is not added is if the shape only contains + // non-payload fields, e.g headers/query. + if !(payloadFields == 0 && nonPayloadFields > 0) { + current.AddChild(child) + } + + return nil +} + +// buildList adds the value's list items to the current XMLNode as children nodes. All +// nested values in the list are converted to XMLNodes also. +func (b *xmlBuilder) buildList(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if value.IsNil() { // don't build omitted lists + return nil + } + + // check for unflattened list member + flattened := tag.Get("flattened") != "" + + xname := xml.Name{Local: tag.Get("locationName")} + if flattened { + for i := 0; i < value.Len(); i++ { + child := NewXMLElement(xname) + current.AddChild(child) + if err := b.buildValue(value.Index(i), child, ""); err != nil { + return err + } + } + } else { + list := NewXMLElement(xname) + current.AddChild(list) + + for i := 0; i < value.Len(); i++ { + iname := tag.Get("locationNameList") + if iname == "" { + iname = "member" + } + + child := NewXMLElement(xml.Name{Local: iname}) + list.AddChild(child) + if err := b.buildValue(value.Index(i), child, ""); err != nil { + return err + } + } + } + + return nil +} + +// buildMap adds the value's key/value pairs to the current XMLNode as children nodes. All +// nested values in the map are converted to XMLNodes also. +// +// Error will be returned if it is unable to build the map's values into XMLNodes +func (b *xmlBuilder) buildMap(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + if value.IsNil() { // don't build omitted maps + return nil + } + + maproot := NewXMLElement(xml.Name{Local: tag.Get("locationName")}) + current.AddChild(maproot) + current = maproot + + kname, vname := "key", "value" + if n := tag.Get("locationNameKey"); n != "" { + kname = n + } + if n := tag.Get("locationNameValue"); n != "" { + vname = n + } + + // sorting is not required for compliance, but it makes testing easier + keys := make([]string, value.Len()) + for i, k := range value.MapKeys() { + keys[i] = k.String() + } + sort.Strings(keys) + + for _, k := range keys { + v := value.MapIndex(reflect.ValueOf(k)) + + mapcur := current + if tag.Get("flattened") == "" { // add "entry" tag to non-flat maps + child := NewXMLElement(xml.Name{Local: "entry"}) + mapcur.AddChild(child) + mapcur = child + } + + kchild := NewXMLElement(xml.Name{Local: kname}) + kchild.Text = k + vchild := NewXMLElement(xml.Name{Local: vname}) + mapcur.AddChild(kchild) + mapcur.AddChild(vchild) + + if err := b.buildValue(v, vchild, ""); err != nil { + return err + } + } + + return nil +} + +// buildScalar will convert the value into a string and append it as a attribute or child +// of the current XMLNode. +// +// The value will be added as an attribute if tag contains a "xmlAttribute" attribute value. +// +// Error will be returned if the value type is unsupported. +func (b *xmlBuilder) buildScalar(value reflect.Value, current *XMLNode, tag reflect.StructTag) error { + var str string + switch converted := value.Interface().(type) { + case string: + str = converted + case []byte: + if !value.IsNil() { + str = base64.StdEncoding.EncodeToString(converted) + } + case bool: + str = strconv.FormatBool(converted) + case int64: + str = strconv.FormatInt(converted, 10) + case int: + str = strconv.Itoa(converted) + case float64: + str = strconv.FormatFloat(converted, 'f', -1, 64) + case float32: + str = strconv.FormatFloat(float64(converted), 'f', -1, 32) + case time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.ISO8601TimeFormatName + } + + str = protocol.FormatTime(format, converted) + default: + return fmt.Errorf("unsupported value for param %s: %v (%s)", + tag.Get("locationName"), value.Interface(), value.Type().Name()) + } + + xname := xml.Name{Local: tag.Get("locationName")} + if tag.Get("xmlAttribute") != "" { // put into current node's attribute list + attr := xml.Attr{Name: xname, Value: str} + current.Attr = append(current.Attr, attr) + } else { // regular text node + current.AddChild(&XMLNode{Name: xname, Text: str}) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go new file mode 100644 index 00000000..7108d380 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/unmarshal.go @@ -0,0 +1,291 @@ +package xmlutil + +import ( + "bytes" + "encoding/base64" + "encoding/xml" + "fmt" + "io" + "reflect" + "strconv" + "strings" + "time" + + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/private/protocol" +) + +// UnmarshalXMLError unmarshals the XML error from the stream into the value +// type specified. The value must be a pointer. If the message fails to +// unmarshal, the message content will be included in the returned error as a +// awserr.UnmarshalError. +func UnmarshalXMLError(v interface{}, stream io.Reader) error { + var errBuf bytes.Buffer + body := io.TeeReader(stream, &errBuf) + + err := xml.NewDecoder(body).Decode(v) + if err != nil && err != io.EOF { + return awserr.NewUnmarshalError(err, + "failed to unmarshal error message", errBuf.Bytes()) + } + + return nil +} + +// UnmarshalXML deserializes an xml.Decoder into the container v. V +// needs to match the shape of the XML expected to be decoded. +// If the shape doesn't match unmarshaling will fail. +func UnmarshalXML(v interface{}, d *xml.Decoder, wrapper string) error { + n, err := XMLToStruct(d, nil) + if err != nil { + return err + } + if n.Children != nil { + for _, root := range n.Children { + for _, c := range root { + if wrappedChild, ok := c.Children[wrapper]; ok { + c = wrappedChild[0] // pull out wrapped element + } + + err = parse(reflect.ValueOf(v), c, "") + if err != nil { + if err == io.EOF { + return nil + } + return err + } + } + } + return nil + } + return nil +} + +// parse deserializes any value from the XMLNode. The type tag is used to infer the type, or reflect +// will be used to determine the type from r. +func parse(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + rtype := r.Type() + if rtype.Kind() == reflect.Ptr { + rtype = rtype.Elem() // check kind of actual element type + } + + t := tag.Get("type") + if t == "" { + switch rtype.Kind() { + case reflect.Struct: + // also it can't be a time object + if _, ok := r.Interface().(*time.Time); !ok { + t = "structure" + } + case reflect.Slice: + // also it can't be a byte slice + if _, ok := r.Interface().([]byte); !ok { + t = "list" + } + case reflect.Map: + t = "map" + } + } + + switch t { + case "structure": + if field, ok := rtype.FieldByName("_"); ok { + tag = field.Tag + } + return parseStruct(r, node, tag) + case "list": + return parseList(r, node, tag) + case "map": + return parseMap(r, node, tag) + default: + return parseScalar(r, node, tag) + } +} + +// parseStruct deserializes a structure and its fields from an XMLNode. Any nested +// types in the structure will also be deserialized. +func parseStruct(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + t := r.Type() + if r.Kind() == reflect.Ptr { + if r.IsNil() { // create the structure if it's nil + s := reflect.New(r.Type().Elem()) + r.Set(s) + r = s + } + + r = r.Elem() + t = t.Elem() + } + + // unwrap any payloads + if payload := tag.Get("payload"); payload != "" { + field, _ := t.FieldByName(payload) + return parseStruct(r.FieldByName(payload), node, field.Tag) + } + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + if c := field.Name[0:1]; strings.ToLower(c) == c { + continue // ignore unexported fields + } + + // figure out what this field is called + name := field.Name + if field.Tag.Get("flattened") != "" && field.Tag.Get("locationNameList") != "" { + name = field.Tag.Get("locationNameList") + } else if locName := field.Tag.Get("locationName"); locName != "" { + name = locName + } + + // try to find the field by name in elements + elems := node.Children[name] + + if elems == nil { // try to find the field in attributes + if val, ok := node.findElem(name); ok { + elems = []*XMLNode{{Text: val}} + } + } + + member := r.FieldByName(field.Name) + for _, elem := range elems { + err := parse(member, elem, field.Tag) + if err != nil { + return err + } + } + } + return nil +} + +// parseList deserializes a list of values from an XML node. Each list entry +// will also be deserialized. +func parseList(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + t := r.Type() + + if tag.Get("flattened") == "" { // look at all item entries + mname := "member" + if name := tag.Get("locationNameList"); name != "" { + mname = name + } + + if Children, ok := node.Children[mname]; ok { + if r.IsNil() { + r.Set(reflect.MakeSlice(t, len(Children), len(Children))) + } + + for i, c := range Children { + err := parse(r.Index(i), c, "") + if err != nil { + return err + } + } + } + } else { // flattened list means this is a single element + if r.IsNil() { + r.Set(reflect.MakeSlice(t, 0, 0)) + } + + childR := reflect.Zero(t.Elem()) + r.Set(reflect.Append(r, childR)) + err := parse(r.Index(r.Len()-1), node, "") + if err != nil { + return err + } + } + + return nil +} + +// parseMap deserializes a map from an XMLNode. The direct children of the XMLNode +// will also be deserialized as map entries. +func parseMap(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + if r.IsNil() { + r.Set(reflect.MakeMap(r.Type())) + } + + if tag.Get("flattened") == "" { // look at all child entries + for _, entry := range node.Children["entry"] { + parseMapEntry(r, entry, tag) + } + } else { // this element is itself an entry + parseMapEntry(r, node, tag) + } + + return nil +} + +// parseMapEntry deserializes a map entry from a XML node. +func parseMapEntry(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + kname, vname := "key", "value" + if n := tag.Get("locationNameKey"); n != "" { + kname = n + } + if n := tag.Get("locationNameValue"); n != "" { + vname = n + } + + keys, ok := node.Children[kname] + values := node.Children[vname] + if ok { + for i, key := range keys { + keyR := reflect.ValueOf(key.Text) + value := values[i] + valueR := reflect.New(r.Type().Elem()).Elem() + + parse(valueR, value, "") + r.SetMapIndex(keyR, valueR) + } + } + return nil +} + +// parseScaller deserializes an XMLNode value into a concrete type based on the +// interface type of r. +// +// Error is returned if the deserialization fails due to invalid type conversion, +// or unsupported interface type. +func parseScalar(r reflect.Value, node *XMLNode, tag reflect.StructTag) error { + switch r.Interface().(type) { + case *string: + r.Set(reflect.ValueOf(&node.Text)) + return nil + case []byte: + b, err := base64.StdEncoding.DecodeString(node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(b)) + case *bool: + v, err := strconv.ParseBool(node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&v)) + case *int64: + v, err := strconv.ParseInt(node.Text, 10, 64) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&v)) + case *float64: + v, err := strconv.ParseFloat(node.Text, 64) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&v)) + case *time.Time: + format := tag.Get("timestampFormat") + if len(format) == 0 { + format = protocol.ISO8601TimeFormatName + } + + t, err := protocol.ParseTime(format, node.Text) + if err != nil { + return err + } + r.Set(reflect.ValueOf(&t)) + default: + return fmt.Errorf("unsupported value: %v (%s)", r.Interface(), r.Type()) + } + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go new file mode 100644 index 00000000..515ce152 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil/xml_to_struct.go @@ -0,0 +1,148 @@ +package xmlutil + +import ( + "encoding/xml" + "fmt" + "io" + "sort" +) + +// A XMLNode contains the values to be encoded or decoded. +type XMLNode struct { + Name xml.Name `json:",omitempty"` + Children map[string][]*XMLNode `json:",omitempty"` + Text string `json:",omitempty"` + Attr []xml.Attr `json:",omitempty"` + + namespaces map[string]string + parent *XMLNode +} + +// NewXMLElement returns a pointer to a new XMLNode initialized to default values. +func NewXMLElement(name xml.Name) *XMLNode { + return &XMLNode{ + Name: name, + Children: map[string][]*XMLNode{}, + Attr: []xml.Attr{}, + } +} + +// AddChild adds child to the XMLNode. +func (n *XMLNode) AddChild(child *XMLNode) { + child.parent = n + if _, ok := n.Children[child.Name.Local]; !ok { + n.Children[child.Name.Local] = []*XMLNode{} + } + n.Children[child.Name.Local] = append(n.Children[child.Name.Local], child) +} + +// XMLToStruct converts a xml.Decoder stream to XMLNode with nested values. +func XMLToStruct(d *xml.Decoder, s *xml.StartElement) (*XMLNode, error) { + out := &XMLNode{} + for { + tok, err := d.Token() + if err != nil { + if err == io.EOF { + break + } else { + return out, err + } + } + + if tok == nil { + break + } + + switch typed := tok.(type) { + case xml.CharData: + out.Text = string(typed.Copy()) + case xml.StartElement: + el := typed.Copy() + out.Attr = el.Attr + if out.Children == nil { + out.Children = map[string][]*XMLNode{} + } + + name := typed.Name.Local + slice := out.Children[name] + if slice == nil { + slice = []*XMLNode{} + } + node, e := XMLToStruct(d, &el) + out.findNamespaces() + if e != nil { + return out, e + } + node.Name = typed.Name + node.findNamespaces() + tempOut := *out + // Save into a temp variable, simply because out gets squashed during + // loop iterations + node.parent = &tempOut + slice = append(slice, node) + out.Children[name] = slice + case xml.EndElement: + if s != nil && s.Name.Local == typed.Name.Local { // matching end token + return out, nil + } + out = &XMLNode{} + } + } + return out, nil +} + +func (n *XMLNode) findNamespaces() { + ns := map[string]string{} + for _, a := range n.Attr { + if a.Name.Space == "xmlns" { + ns[a.Value] = a.Name.Local + } + } + + n.namespaces = ns +} + +func (n *XMLNode) findElem(name string) (string, bool) { + for node := n; node != nil; node = node.parent { + for _, a := range node.Attr { + namespace := a.Name.Space + if v, ok := node.namespaces[namespace]; ok { + namespace = v + } + if name == fmt.Sprintf("%s:%s", namespace, a.Name.Local) { + return a.Value, true + } + } + } + return "", false +} + +// StructToXML writes an XMLNode to a xml.Encoder as tokens. +func StructToXML(e *xml.Encoder, node *XMLNode, sorted bool) error { + e.EncodeToken(xml.StartElement{Name: node.Name, Attr: node.Attr}) + + if node.Text != "" { + e.EncodeToken(xml.CharData([]byte(node.Text))) + } else if sorted { + sortedNames := []string{} + for k := range node.Children { + sortedNames = append(sortedNames, k) + } + sort.Strings(sortedNames) + + for _, k := range sortedNames { + for _, v := range node.Children[k] { + StructToXML(e, v, sorted) + } + } + } else { + for _, c := range node.Children { + for _, v := range c { + StructToXML(e, v, sorted) + } + } + } + + e.EncodeToken(xml.EndElement{Name: node.Name}) + return e.Flush() +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/api.go b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go new file mode 100644 index 00000000..1853d0ec --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/api.go @@ -0,0 +1,2581 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package sts + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/request" +) + +const opAssumeRole = "AssumeRole" + +// AssumeRoleRequest generates a "aws/request.Request" representing the +// client's request for the AssumeRole operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AssumeRole for more information on using the AssumeRole +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AssumeRoleRequest method. +// req, resp := client.AssumeRoleRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole +func (c *STS) AssumeRoleRequest(input *AssumeRoleInput) (req *request.Request, output *AssumeRoleOutput) { + op := &request.Operation{ + Name: opAssumeRole, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleInput{} + } + + output = &AssumeRoleOutput{} + req = c.newRequest(op, input, output) + return +} + +// AssumeRole API operation for AWS Security Token Service. +// +// Returns a set of temporary security credentials that you can use to access +// AWS resources that you might not normally have access to. These temporary +// credentials consist of an access key ID, a secret access key, and a security +// token. Typically, you use AssumeRole within your account or for cross-account +// access. For a comparison of AssumeRole with other API operations that produce +// temporary credentials, see Requesting Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// You cannot use AWS account root user credentials to call AssumeRole. You +// must use credentials for an IAM user or an IAM role to call AssumeRole. +// +// For cross-account access, imagine that you own multiple accounts and need +// to access resources in each account. You could create long-term credentials +// in each account to access those resources. However, managing all those credentials +// and remembering which one can access which account can be time consuming. +// Instead, you can create one set of long-term credentials in one account. +// Then use temporary security credentials to access all the other accounts +// by assuming roles in those accounts. For more information about roles, see +// IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) +// in the IAM User Guide. +// +// By default, the temporary security credentials created by AssumeRole last +// for one hour. However, you can use the optional DurationSeconds parameter +// to specify the duration of your session. You can provide a value from 900 +// seconds (15 minutes) up to the maximum session duration setting for the role. +// This setting can have a value from 1 hour to 12 hours. To learn how to view +// the maximum value for your role, see View the Maximum Session Duration Setting +// for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) +// in the IAM User Guide. The maximum session duration limit applies when you +// use the AssumeRole* API operations or the assume-role* CLI commands. However +// the limit does not apply when you use those operations to create a console +// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) +// in the IAM User Guide. +// +// The temporary security credentials created by AssumeRole can be used to make +// API calls to any AWS service with the following exception: You cannot call +// the AWS STS GetFederationToken or GetSessionToken API operations. +// +// (Optional) You can pass inline or managed session policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// to this operation. You can pass a single JSON policy document to use as an +// inline session policy. You can also specify up to 10 managed policies to +// use as managed session policies. The plain text that you use for both inline +// and managed session policies shouldn't exceed 2048 characters. Passing policies +// to this operation returns new temporary credentials. The resulting session's +// permissions are the intersection of the role's identity-based policy and +// the session policies. You can use the role's temporary credentials in subsequent +// AWS API calls to access resources in the account that owns the role. You +// cannot use session policies to grant more permissions than those allowed +// by the identity-based policy of the role that is being assumed. For more +// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) +// in the IAM User Guide. +// +// To assume a role from a different account, your AWS account must be trusted +// by the role. The trust relationship is defined in the role's trust policy +// when the role is created. That trust policy states which accounts are allowed +// to delegate that access to users in the account. +// +// A user who wants to access a role in a different account must also have permissions +// that are delegated from the user account administrator. The administrator +// must attach a policy that allows the user to call AssumeRole for the ARN +// of the role in the other account. If the user is in the same account as the +// role, then you can do either of the following: +// +// * Attach a policy to the user (identical to the previous user in a different +// account). +// +// * Add the user as a principal directly in the role's trust policy. +// +// In this case, the trust policy acts as an IAM resource-based policy. Users +// in the same account as the role do not need explicit permission to assume +// the role. For more information about trust policies and resource-based policies, +// see IAM Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html) +// in the IAM User Guide. +// +// Using MFA with AssumeRole +// +// (Optional) You can include multi-factor authentication (MFA) information +// when you call AssumeRole. This is useful for cross-account scenarios to ensure +// that the user that assumes the role has been authenticated with an AWS MFA +// device. In that scenario, the trust policy of the role being assumed includes +// a condition that tests for MFA authentication. If the caller does not include +// valid MFA information, the request to assume the role is denied. The condition +// in a trust policy that tests for MFA authentication might look like the following +// example. +// +// "Condition": {"Bool": {"aws:MultiFactorAuthPresent": true}} +// +// For more information, see Configuring MFA-Protected API Access (https://docs.aws.amazon.com/IAM/latest/UserGuide/MFAProtectedAPI.html) +// in the IAM User Guide guide. +// +// To use MFA with AssumeRole, you pass values for the SerialNumber and TokenCode +// parameters. The SerialNumber value identifies the user's hardware or virtual +// MFA device. The TokenCode is the time-based one-time password (TOTP) that +// the MFA device produces. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation AssumeRole for usage and error information. +// +// Returned Error Codes: +// * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument" +// The request was rejected because the policy document was malformed. The error +// message describes the specific error. +// +// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" +// The request was rejected because the policy document was too large. The error +// message describes how big the policy document is, in packed form, as a percentage +// of what the API allows. +// +// * ErrCodeRegionDisabledException "RegionDisabledException" +// STS is not activated in the requested region for the account that is being +// asked to generate credentials. The account administrator must use the IAM +// console to activate STS in that region. For more information, see Activating +// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRole +func (c *STS) AssumeRole(input *AssumeRoleInput) (*AssumeRoleOutput, error) { + req, out := c.AssumeRoleRequest(input) + return out, req.Send() +} + +// AssumeRoleWithContext is the same as AssumeRole with the addition of +// the ability to pass a context and additional request options. +// +// See AssumeRole for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) AssumeRoleWithContext(ctx aws.Context, input *AssumeRoleInput, opts ...request.Option) (*AssumeRoleOutput, error) { + req, out := c.AssumeRoleRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opAssumeRoleWithSAML = "AssumeRoleWithSAML" + +// AssumeRoleWithSAMLRequest generates a "aws/request.Request" representing the +// client's request for the AssumeRoleWithSAML operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AssumeRoleWithSAML for more information on using the AssumeRoleWithSAML +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AssumeRoleWithSAMLRequest method. +// req, resp := client.AssumeRoleWithSAMLRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML +func (c *STS) AssumeRoleWithSAMLRequest(input *AssumeRoleWithSAMLInput) (req *request.Request, output *AssumeRoleWithSAMLOutput) { + op := &request.Operation{ + Name: opAssumeRoleWithSAML, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleWithSAMLInput{} + } + + output = &AssumeRoleWithSAMLOutput{} + req = c.newRequest(op, input, output) + req.Config.Credentials = credentials.AnonymousCredentials + return +} + +// AssumeRoleWithSAML API operation for AWS Security Token Service. +// +// Returns a set of temporary security credentials for users who have been authenticated +// via a SAML authentication response. This operation provides a mechanism for +// tying an enterprise identity store or directory to role-based AWS access +// without user-specific credentials or configuration. For a comparison of AssumeRoleWithSAML +// with the other API operations that produce temporary credentials, see Requesting +// Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The temporary security credentials returned by this operation consist of +// an access key ID, a secret access key, and a security token. Applications +// can use these temporary security credentials to sign calls to AWS services. +// +// By default, the temporary security credentials created by AssumeRoleWithSAML +// last for one hour. However, you can use the optional DurationSeconds parameter +// to specify the duration of your session. Your role session lasts for the +// duration that you specify, or until the time specified in the SAML authentication +// response's SessionNotOnOrAfter value, whichever is shorter. You can provide +// a DurationSeconds value from 900 seconds (15 minutes) up to the maximum session +// duration setting for the role. This setting can have a value from 1 hour +// to 12 hours. To learn how to view the maximum value for your role, see View +// the Maximum Session Duration Setting for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) +// in the IAM User Guide. The maximum session duration limit applies when you +// use the AssumeRole* API operations or the assume-role* CLI commands. However +// the limit does not apply when you use those operations to create a console +// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) +// in the IAM User Guide. +// +// The temporary security credentials created by AssumeRoleWithSAML can be used +// to make API calls to any AWS service with the following exception: you cannot +// call the STS GetFederationToken or GetSessionToken API operations. +// +// (Optional) You can pass inline or managed session policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// to this operation. You can pass a single JSON policy document to use as an +// inline session policy. You can also specify up to 10 managed policies to +// use as managed session policies. The plain text that you use for both inline +// and managed session policies shouldn't exceed 2048 characters. Passing policies +// to this operation returns new temporary credentials. The resulting session's +// permissions are the intersection of the role's identity-based policy and +// the session policies. You can use the role's temporary credentials in subsequent +// AWS API calls to access resources in the account that owns the role. You +// cannot use session policies to grant more permissions than those allowed +// by the identity-based policy of the role that is being assumed. For more +// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) +// in the IAM User Guide. +// +// Before your application can call AssumeRoleWithSAML, you must configure your +// SAML identity provider (IdP) to issue the claims required by AWS. Additionally, +// you must use AWS Identity and Access Management (IAM) to create a SAML provider +// entity in your AWS account that represents your identity provider. You must +// also create an IAM role that specifies this SAML provider in its trust policy. +// +// Calling AssumeRoleWithSAML does not require the use of AWS security credentials. +// The identity of the caller is validated by using keys in the metadata document +// that is uploaded for the SAML provider entity for your identity provider. +// +// Calling AssumeRoleWithSAML can result in an entry in your AWS CloudTrail +// logs. The entry includes the value in the NameID element of the SAML assertion. +// We recommend that you use a NameIDType that is not associated with any personally +// identifiable information (PII). For example, you could instead use the Persistent +// Identifier (urn:oasis:names:tc:SAML:2.0:nameid-format:persistent). +// +// For more information, see the following resources: +// +// * About SAML 2.0-based Federation (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_saml.html) +// in the IAM User Guide. +// +// * Creating SAML Identity Providers (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml.html) +// in the IAM User Guide. +// +// * Configuring a Relying Party and Claims (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_saml_relying-party.html) +// in the IAM User Guide. +// +// * Creating a Role for SAML 2.0 Federation (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_saml.html) +// in the IAM User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation AssumeRoleWithSAML for usage and error information. +// +// Returned Error Codes: +// * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument" +// The request was rejected because the policy document was malformed. The error +// message describes the specific error. +// +// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" +// The request was rejected because the policy document was too large. The error +// message describes how big the policy document is, in packed form, as a percentage +// of what the API allows. +// +// * ErrCodeIDPRejectedClaimException "IDPRejectedClaim" +// The identity provider (IdP) reported that authentication failed. This might +// be because the claim is invalid. +// +// If this error is returned for the AssumeRoleWithWebIdentity operation, it +// can also mean that the claim has expired or has been explicitly revoked. +// +// * ErrCodeInvalidIdentityTokenException "InvalidIdentityToken" +// The web identity token that was passed could not be validated by AWS. Get +// a new identity token from the identity provider and then retry the request. +// +// * ErrCodeExpiredTokenException "ExpiredTokenException" +// The web identity token that was passed is expired or is not valid. Get a +// new identity token from the identity provider and then retry the request. +// +// * ErrCodeRegionDisabledException "RegionDisabledException" +// STS is not activated in the requested region for the account that is being +// asked to generate credentials. The account administrator must use the IAM +// console to activate STS in that region. For more information, see Activating +// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithSAML +func (c *STS) AssumeRoleWithSAML(input *AssumeRoleWithSAMLInput) (*AssumeRoleWithSAMLOutput, error) { + req, out := c.AssumeRoleWithSAMLRequest(input) + return out, req.Send() +} + +// AssumeRoleWithSAMLWithContext is the same as AssumeRoleWithSAML with the addition of +// the ability to pass a context and additional request options. +// +// See AssumeRoleWithSAML for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) AssumeRoleWithSAMLWithContext(ctx aws.Context, input *AssumeRoleWithSAMLInput, opts ...request.Option) (*AssumeRoleWithSAMLOutput, error) { + req, out := c.AssumeRoleWithSAMLRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opAssumeRoleWithWebIdentity = "AssumeRoleWithWebIdentity" + +// AssumeRoleWithWebIdentityRequest generates a "aws/request.Request" representing the +// client's request for the AssumeRoleWithWebIdentity operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See AssumeRoleWithWebIdentity for more information on using the AssumeRoleWithWebIdentity +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the AssumeRoleWithWebIdentityRequest method. +// req, resp := client.AssumeRoleWithWebIdentityRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity +func (c *STS) AssumeRoleWithWebIdentityRequest(input *AssumeRoleWithWebIdentityInput) (req *request.Request, output *AssumeRoleWithWebIdentityOutput) { + op := &request.Operation{ + Name: opAssumeRoleWithWebIdentity, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &AssumeRoleWithWebIdentityInput{} + } + + output = &AssumeRoleWithWebIdentityOutput{} + req = c.newRequest(op, input, output) + req.Config.Credentials = credentials.AnonymousCredentials + return +} + +// AssumeRoleWithWebIdentity API operation for AWS Security Token Service. +// +// Returns a set of temporary security credentials for users who have been authenticated +// in a mobile or web application with a web identity provider. Example providers +// include Amazon Cognito, Login with Amazon, Facebook, Google, or any OpenID +// Connect-compatible identity provider. +// +// For mobile applications, we recommend that you use Amazon Cognito. You can +// use Amazon Cognito with the AWS SDK for iOS Developer Guide (http://aws.amazon.com/sdkforios/) +// and the AWS SDK for Android Developer Guide (http://aws.amazon.com/sdkforandroid/) +// to uniquely identify a user. You can also supply the user with a consistent +// identity throughout the lifetime of an application. +// +// To learn more about Amazon Cognito, see Amazon Cognito Overview (https://docs.aws.amazon.com/mobile/sdkforandroid/developerguide/cognito-auth.html#d0e840) +// in AWS SDK for Android Developer Guide and Amazon Cognito Overview (https://docs.aws.amazon.com/mobile/sdkforios/developerguide/cognito-auth.html#d0e664) +// in the AWS SDK for iOS Developer Guide. +// +// Calling AssumeRoleWithWebIdentity does not require the use of AWS security +// credentials. Therefore, you can distribute an application (for example, on +// mobile devices) that requests temporary security credentials without including +// long-term AWS credentials in the application. You also don't need to deploy +// server-based proxy services that use long-term AWS credentials. Instead, +// the identity of the caller is validated by using a token from the web identity +// provider. For a comparison of AssumeRoleWithWebIdentity with the other API +// operations that produce temporary credentials, see Requesting Temporary Security +// Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The temporary security credentials returned by this API consist of an access +// key ID, a secret access key, and a security token. Applications can use these +// temporary security credentials to sign calls to AWS service API operations. +// +// By default, the temporary security credentials created by AssumeRoleWithWebIdentity +// last for one hour. However, you can use the optional DurationSeconds parameter +// to specify the duration of your session. You can provide a value from 900 +// seconds (15 minutes) up to the maximum session duration setting for the role. +// This setting can have a value from 1 hour to 12 hours. To learn how to view +// the maximum value for your role, see View the Maximum Session Duration Setting +// for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) +// in the IAM User Guide. The maximum session duration limit applies when you +// use the AssumeRole* API operations or the assume-role* CLI commands. However +// the limit does not apply when you use those operations to create a console +// URL. For more information, see Using IAM Roles (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html) +// in the IAM User Guide. +// +// The temporary security credentials created by AssumeRoleWithWebIdentity can +// be used to make API calls to any AWS service with the following exception: +// you cannot call the STS GetFederationToken or GetSessionToken API operations. +// +// (Optional) You can pass inline or managed session policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// to this operation. You can pass a single JSON policy document to use as an +// inline session policy. You can also specify up to 10 managed policies to +// use as managed session policies. The plain text that you use for both inline +// and managed session policies shouldn't exceed 2048 characters. Passing policies +// to this operation returns new temporary credentials. The resulting session's +// permissions are the intersection of the role's identity-based policy and +// the session policies. You can use the role's temporary credentials in subsequent +// AWS API calls to access resources in the account that owns the role. You +// cannot use session policies to grant more permissions than those allowed +// by the identity-based policy of the role that is being assumed. For more +// information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) +// in the IAM User Guide. +// +// Before your application can call AssumeRoleWithWebIdentity, you must have +// an identity token from a supported identity provider and create a role that +// the application can assume. The role that your application assumes must trust +// the identity provider that is associated with the identity token. In other +// words, the identity provider must be specified in the role's trust policy. +// +// Calling AssumeRoleWithWebIdentity can result in an entry in your AWS CloudTrail +// logs. The entry includes the Subject (http://openid.net/specs/openid-connect-core-1_0.html#Claims) +// of the provided Web Identity Token. We recommend that you avoid using any +// personally identifiable information (PII) in this field. For example, you +// could instead use a GUID or a pairwise identifier, as suggested in the OIDC +// specification (http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes). +// +// For more information about how to use web identity federation and the AssumeRoleWithWebIdentity +// API, see the following resources: +// +// * Using Web Identity Federation API Operations for Mobile Apps (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html) +// and Federation Through a Web-based Identity Provider (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). +// +// +// * Web Identity Federation Playground (https://web-identity-federation-playground.s3.amazonaws.com/index.html). +// Walk through the process of authenticating through Login with Amazon, +// Facebook, or Google, getting temporary security credentials, and then +// using those credentials to make a request to AWS. +// +// * AWS SDK for iOS Developer Guide (http://aws.amazon.com/sdkforios/) and +// AWS SDK for Android Developer Guide (http://aws.amazon.com/sdkforandroid/). +// These toolkits contain sample apps that show how to invoke the identity +// providers, and then how to use the information from these providers to +// get and use temporary security credentials. +// +// * Web Identity Federation with Mobile Applications (http://aws.amazon.com/articles/web-identity-federation-with-mobile-applications). +// This article discusses web identity federation and shows an example of +// how to use web identity federation to get access to content in Amazon +// S3. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation AssumeRoleWithWebIdentity for usage and error information. +// +// Returned Error Codes: +// * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument" +// The request was rejected because the policy document was malformed. The error +// message describes the specific error. +// +// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" +// The request was rejected because the policy document was too large. The error +// message describes how big the policy document is, in packed form, as a percentage +// of what the API allows. +// +// * ErrCodeIDPRejectedClaimException "IDPRejectedClaim" +// The identity provider (IdP) reported that authentication failed. This might +// be because the claim is invalid. +// +// If this error is returned for the AssumeRoleWithWebIdentity operation, it +// can also mean that the claim has expired or has been explicitly revoked. +// +// * ErrCodeIDPCommunicationErrorException "IDPCommunicationError" +// The request could not be fulfilled because the non-AWS identity provider +// (IDP) that was asked to verify the incoming identity token could not be reached. +// This is often a transient error caused by network conditions. Retry the request +// a limited number of times so that you don't exceed the request rate. If the +// error persists, the non-AWS identity provider might be down or not responding. +// +// * ErrCodeInvalidIdentityTokenException "InvalidIdentityToken" +// The web identity token that was passed could not be validated by AWS. Get +// a new identity token from the identity provider and then retry the request. +// +// * ErrCodeExpiredTokenException "ExpiredTokenException" +// The web identity token that was passed is expired or is not valid. Get a +// new identity token from the identity provider and then retry the request. +// +// * ErrCodeRegionDisabledException "RegionDisabledException" +// STS is not activated in the requested region for the account that is being +// asked to generate credentials. The account administrator must use the IAM +// console to activate STS in that region. For more information, see Activating +// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumeRoleWithWebIdentity +func (c *STS) AssumeRoleWithWebIdentity(input *AssumeRoleWithWebIdentityInput) (*AssumeRoleWithWebIdentityOutput, error) { + req, out := c.AssumeRoleWithWebIdentityRequest(input) + return out, req.Send() +} + +// AssumeRoleWithWebIdentityWithContext is the same as AssumeRoleWithWebIdentity with the addition of +// the ability to pass a context and additional request options. +// +// See AssumeRoleWithWebIdentity for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) AssumeRoleWithWebIdentityWithContext(ctx aws.Context, input *AssumeRoleWithWebIdentityInput, opts ...request.Option) (*AssumeRoleWithWebIdentityOutput, error) { + req, out := c.AssumeRoleWithWebIdentityRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDecodeAuthorizationMessage = "DecodeAuthorizationMessage" + +// DecodeAuthorizationMessageRequest generates a "aws/request.Request" representing the +// client's request for the DecodeAuthorizationMessage operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DecodeAuthorizationMessage for more information on using the DecodeAuthorizationMessage +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DecodeAuthorizationMessageRequest method. +// req, resp := client.DecodeAuthorizationMessageRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage +func (c *STS) DecodeAuthorizationMessageRequest(input *DecodeAuthorizationMessageInput) (req *request.Request, output *DecodeAuthorizationMessageOutput) { + op := &request.Operation{ + Name: opDecodeAuthorizationMessage, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &DecodeAuthorizationMessageInput{} + } + + output = &DecodeAuthorizationMessageOutput{} + req = c.newRequest(op, input, output) + return +} + +// DecodeAuthorizationMessage API operation for AWS Security Token Service. +// +// Decodes additional information about the authorization status of a request +// from an encoded message returned in response to an AWS request. +// +// For example, if a user is not authorized to perform an operation that he +// or she has requested, the request returns a Client.UnauthorizedOperation +// response (an HTTP 403 response). Some AWS operations additionally return +// an encoded message that can provide details about this authorization failure. +// +// Only certain AWS operations return an encoded authorization message. The +// documentation for an individual operation indicates whether that operation +// returns an encoded message in addition to returning an HTTP code. +// +// The message is encoded because the details of the authorization status can +// constitute privileged information that the user who requested the operation +// should not see. To decode an authorization status message, a user must be +// granted permissions via an IAM policy to request the DecodeAuthorizationMessage +// (sts:DecodeAuthorizationMessage) action. +// +// The decoded message includes the following type of information: +// +// * Whether the request was denied due to an explicit deny or due to the +// absence of an explicit allow. For more information, see Determining Whether +// a Request is Allowed or Denied (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow) +// in the IAM User Guide. +// +// * The principal who made the request. +// +// * The requested action. +// +// * The requested resource. +// +// * The values of condition keys in the context of the user's request. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation DecodeAuthorizationMessage for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidAuthorizationMessageException "InvalidAuthorizationMessageException" +// The error returned if the message passed to DecodeAuthorizationMessage was +// invalid. This can happen if the token contains invalid characters, such as +// linebreaks. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/DecodeAuthorizationMessage +func (c *STS) DecodeAuthorizationMessage(input *DecodeAuthorizationMessageInput) (*DecodeAuthorizationMessageOutput, error) { + req, out := c.DecodeAuthorizationMessageRequest(input) + return out, req.Send() +} + +// DecodeAuthorizationMessageWithContext is the same as DecodeAuthorizationMessage with the addition of +// the ability to pass a context and additional request options. +// +// See DecodeAuthorizationMessage for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) DecodeAuthorizationMessageWithContext(ctx aws.Context, input *DecodeAuthorizationMessageInput, opts ...request.Option) (*DecodeAuthorizationMessageOutput, error) { + req, out := c.DecodeAuthorizationMessageRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetCallerIdentity = "GetCallerIdentity" + +// GetCallerIdentityRequest generates a "aws/request.Request" representing the +// client's request for the GetCallerIdentity operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetCallerIdentity for more information on using the GetCallerIdentity +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetCallerIdentityRequest method. +// req, resp := client.GetCallerIdentityRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity +func (c *STS) GetCallerIdentityRequest(input *GetCallerIdentityInput) (req *request.Request, output *GetCallerIdentityOutput) { + op := &request.Operation{ + Name: opGetCallerIdentity, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetCallerIdentityInput{} + } + + output = &GetCallerIdentityOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetCallerIdentity API operation for AWS Security Token Service. +// +// Returns details about the IAM identity whose credentials are used to call +// the API. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation GetCallerIdentity for usage and error information. +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetCallerIdentity +func (c *STS) GetCallerIdentity(input *GetCallerIdentityInput) (*GetCallerIdentityOutput, error) { + req, out := c.GetCallerIdentityRequest(input) + return out, req.Send() +} + +// GetCallerIdentityWithContext is the same as GetCallerIdentity with the addition of +// the ability to pass a context and additional request options. +// +// See GetCallerIdentity for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) GetCallerIdentityWithContext(ctx aws.Context, input *GetCallerIdentityInput, opts ...request.Option) (*GetCallerIdentityOutput, error) { + req, out := c.GetCallerIdentityRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetFederationToken = "GetFederationToken" + +// GetFederationTokenRequest generates a "aws/request.Request" representing the +// client's request for the GetFederationToken operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetFederationToken for more information on using the GetFederationToken +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetFederationTokenRequest method. +// req, resp := client.GetFederationTokenRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken +func (c *STS) GetFederationTokenRequest(input *GetFederationTokenInput) (req *request.Request, output *GetFederationTokenOutput) { + op := &request.Operation{ + Name: opGetFederationToken, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetFederationTokenInput{} + } + + output = &GetFederationTokenOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetFederationToken API operation for AWS Security Token Service. +// +// Returns a set of temporary security credentials (consisting of an access +// key ID, a secret access key, and a security token) for a federated user. +// A typical use is in a proxy application that gets temporary security credentials +// on behalf of distributed applications inside a corporate network. You must +// call the GetFederationToken operation using the long-term security credentials +// of an IAM user. As a result, this call is appropriate in contexts where those +// credentials can be safely stored, usually in a server-based application. +// For a comparison of GetFederationToken with the other API operations that +// produce temporary credentials, see Requesting Temporary Security Credentials +// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// You can create a mobile-based or browser-based app that can authenticate +// users using a web identity provider like Login with Amazon, Facebook, Google, +// or an OpenID Connect-compatible identity provider. In this case, we recommend +// that you use Amazon Cognito (http://aws.amazon.com/cognito/) or AssumeRoleWithWebIdentity. +// For more information, see Federation Through a Web-based Identity Provider +// (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity). +// +// You can also call GetFederationToken using the security credentials of an +// AWS account root user, but we do not recommend it. Instead, we recommend +// that you create an IAM user for the purpose of the proxy application. Then +// attach a policy to the IAM user that limits federated users to only the actions +// and resources that they need to access. For more information, see IAM Best +// Practices (https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) +// in the IAM User Guide. +// +// The temporary credentials are valid for the specified duration, from 900 +// seconds (15 minutes) up to a maximum of 129,600 seconds (36 hours). The default +// is 43,200 seconds (12 hours). Temporary credentials that are obtained by +// using AWS account root user credentials have a maximum duration of 3,600 +// seconds (1 hour). +// +// The temporary security credentials created by GetFederationToken can be used +// to make API calls to any AWS service with the following exceptions: +// +// * You cannot use these credentials to call any IAM API operations. +// +// * You cannot call any STS API operations except GetCallerIdentity. +// +// Permissions +// +// You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) +// to this operation. You can pass a single JSON policy document to use as an +// inline session policy. You can also specify up to 10 managed policies to +// use as managed session policies. The plain text that you use for both inline +// and managed session policies shouldn't exceed 2048 characters. +// +// Though the session policy parameters are optional, if you do not pass a policy, +// then the resulting federated user session has no permissions. The only exception +// is when the credentials are used to access a resource that has a resource-based +// policy that specifically references the federated user session in the Principal +// element of the policy. When you pass session policies, the session permissions +// are the intersection of the IAM user policies and the session policies that +// you pass. This gives you a way to further restrict the permissions for a +// federated user. You cannot use session policies to grant more permissions +// than those that are defined in the permissions policy of the IAM user. For +// more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) +// in the IAM User Guide. For information about using GetFederationToken to +// create temporary security credentials, see GetFederationToken—Federation +// Through a Custom Identity Broker (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getfederationtoken). +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation GetFederationToken for usage and error information. +// +// Returned Error Codes: +// * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocument" +// The request was rejected because the policy document was malformed. The error +// message describes the specific error. +// +// * ErrCodePackedPolicyTooLargeException "PackedPolicyTooLarge" +// The request was rejected because the policy document was too large. The error +// message describes how big the policy document is, in packed form, as a percentage +// of what the API allows. +// +// * ErrCodeRegionDisabledException "RegionDisabledException" +// STS is not activated in the requested region for the account that is being +// asked to generate credentials. The account administrator must use the IAM +// console to activate STS in that region. For more information, see Activating +// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetFederationToken +func (c *STS) GetFederationToken(input *GetFederationTokenInput) (*GetFederationTokenOutput, error) { + req, out := c.GetFederationTokenRequest(input) + return out, req.Send() +} + +// GetFederationTokenWithContext is the same as GetFederationToken with the addition of +// the ability to pass a context and additional request options. +// +// See GetFederationToken for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) GetFederationTokenWithContext(ctx aws.Context, input *GetFederationTokenInput, opts ...request.Option) (*GetFederationTokenOutput, error) { + req, out := c.GetFederationTokenRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetSessionToken = "GetSessionToken" + +// GetSessionTokenRequest generates a "aws/request.Request" representing the +// client's request for the GetSessionToken operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetSessionToken for more information on using the GetSessionToken +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetSessionTokenRequest method. +// req, resp := client.GetSessionTokenRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken +func (c *STS) GetSessionTokenRequest(input *GetSessionTokenInput) (req *request.Request, output *GetSessionTokenOutput) { + op := &request.Operation{ + Name: opGetSessionToken, + HTTPMethod: "POST", + HTTPPath: "/", + } + + if input == nil { + input = &GetSessionTokenInput{} + } + + output = &GetSessionTokenOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetSessionToken API operation for AWS Security Token Service. +// +// Returns a set of temporary credentials for an AWS account or IAM user. The +// credentials consist of an access key ID, a secret access key, and a security +// token. Typically, you use GetSessionToken if you want to use MFA to protect +// programmatic calls to specific AWS API operations like Amazon EC2 StopInstances. +// MFA-enabled IAM users would need to call GetSessionToken and submit an MFA +// code that is associated with their MFA device. Using the temporary security +// credentials that are returned from the call, IAM users can then make programmatic +// calls to API operations that require MFA authentication. If you do not supply +// a correct MFA code, then the API returns an access denied error. For a comparison +// of GetSessionToken with the other API operations that produce temporary credentials, +// see Requesting Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html) +// and Comparing the AWS STS API operations (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) +// in the IAM User Guide. +// +// The GetSessionToken operation must be called by using the long-term AWS security +// credentials of the AWS account root user or an IAM user. Credentials that +// are created by IAM users are valid for the duration that you specify. This +// duration can range from 900 seconds (15 minutes) up to a maximum of 129,600 +// seconds (36 hours), with a default of 43,200 seconds (12 hours). Credentials +// based on account credentials can range from 900 seconds (15 minutes) up to +// 3,600 seconds (1 hour), with a default of 1 hour. +// +// The temporary security credentials created by GetSessionToken can be used +// to make API calls to any AWS service with the following exceptions: +// +// * You cannot call any IAM API operations unless MFA authentication information +// is included in the request. +// +// * You cannot call any STS API exceptAssumeRole or GetCallerIdentity. +// +// We recommend that you do not call GetSessionToken with AWS account root user +// credentials. Instead, follow our best practices (https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#create-iam-users) +// by creating one or more IAM users, giving them the necessary permissions, +// and using IAM users for everyday interaction with AWS. +// +// The credentials that are returned by GetSessionToken are based on permissions +// associated with the user whose credentials were used to call the operation. +// If GetSessionToken is called using AWS account root user credentials, the +// temporary credentials have root user permissions. Similarly, if GetSessionToken +// is called using the credentials of an IAM user, the temporary credentials +// have the same permissions as the IAM user. +// +// For more information about using GetSessionToken to create temporary credentials, +// go to Temporary Credentials for Users in Untrusted Environments (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_getsessiontoken) +// in the IAM User Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS Security Token Service's +// API operation GetSessionToken for usage and error information. +// +// Returned Error Codes: +// * ErrCodeRegionDisabledException "RegionDisabledException" +// STS is not activated in the requested region for the account that is being +// asked to generate credentials. The account administrator must use the IAM +// console to activate STS in that region. For more information, see Activating +// and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/GetSessionToken +func (c *STS) GetSessionToken(input *GetSessionTokenInput) (*GetSessionTokenOutput, error) { + req, out := c.GetSessionTokenRequest(input) + return out, req.Send() +} + +// GetSessionTokenWithContext is the same as GetSessionToken with the addition of +// the ability to pass a context and additional request options. +// +// See GetSessionToken for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *STS) GetSessionTokenWithContext(ctx aws.Context, input *GetSessionTokenInput, opts ...request.Option) (*GetSessionTokenOutput, error) { + req, out := c.GetSessionTokenRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +type AssumeRoleInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. The value can range from 900 + // seconds (15 minutes) up to the maximum session duration setting for the role. + // This setting can have a value from 1 hour to 12 hours. If you specify a value + // higher than this setting, the operation fails. For example, if you specify + // a session duration of 12 hours, but your administrator set the maximum session + // duration to 6 hours, your operation fails. To learn how to view the maximum + // value for your role, see View the Maximum Session Duration Setting for a + // Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) + // in the IAM User Guide. + // + // By default, the value is set to 3600 seconds. + // + // The DurationSeconds parameter is separate from the duration of a console + // session that you might request using the returned credentials. The request + // to the federation endpoint for a console sign-in token takes a SessionDuration + // parameter that specifies the maximum length of the console session. For more + // information, see Creating a URL that Enables Federated Users to Access the + // AWS Management Console (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) + // in the IAM User Guide. + DurationSeconds *int64 `min:"900" type:"integer"` + + // A unique identifier that might be required when you assume a role in another + // account. If the administrator of the account to which the role belongs provided + // you with an external ID, then provide that value in the ExternalId parameter. + // This value can be any string, such as a passphrase or account number. A cross-account + // role is usually set up to trust everyone in an account. Therefore, the administrator + // of the trusting account might send an external ID to the administrator of + // the trusted account. That way, only someone with the ID can assume the role, + // rather than everyone in the account. For more information about the external + // ID, see How to Use an External ID When Granting Access to Your AWS Resources + // to a Third Party (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) + // in the IAM User Guide. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@:/- + ExternalId *string `min:"2" type:"string"` + + // An IAM policy in JSON format that you want to use as an inline session policy. + // + // This parameter is optional. Passing policies to this operation returns new + // temporary credentials. The resulting session's permissions are the intersection + // of the role's identity-based policy and the session policies. You can use + // the role's temporary credentials in subsequent AWS API calls to access resources + // in the account that owns the role. You cannot use session policies to grant + // more permissions than those allowed by the identity-based policy of the role + // that is being assumed. For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + // + // The plain text that you use for both inline and managed session policies + // shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII + // character from the space character to the end of the valid character list + // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + Policy *string `min:"1" type:"string"` + + // The Amazon Resource Names (ARNs) of the IAM managed policies that you want + // to use as managed session policies. The policies must exist in the same account + // as the role. + // + // This parameter is optional. You can provide up to 10 managed policy ARNs. + // However, the plain text that you use for both inline and managed session + // policies shouldn't exceed 2048 characters. For more information about ARNs, + // see Amazon Resource Names (ARNs) and AWS Service Namespaces (general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + // + // Passing policies to this operation returns new temporary credentials. The + // resulting session's permissions are the intersection of the role's identity-based + // policy and the session policies. You can use the role's temporary credentials + // in subsequent AWS API calls to access resources in the account that owns + // the role. You cannot use session policies to grant more permissions than + // those allowed by the identity-based policy of the role that is being assumed. + // For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + PolicyArns []*PolicyDescriptorType `type:"list"` + + // The Amazon Resource Name (ARN) of the role to assume. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // An identifier for the assumed role session. + // + // Use the role session name to uniquely identify a session when the same role + // is assumed by different principals or for different reasons. In cross-account + // scenarios, the role session name is visible to, and can be logged by the + // account that owns the role. The role session name is also used in the ARN + // of the assumed role principal. This means that subsequent cross-account API + // requests that use the temporary security credentials will expose the role + // session name to the external account in their AWS CloudTrail logs. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + // + // RoleSessionName is a required field + RoleSessionName *string `min:"2" type:"string" required:"true"` + + // The identification number of the MFA device that is associated with the user + // who is making the AssumeRole call. Specify this value if the trust policy + // of the role being assumed includes a condition that requires MFA authentication. + // The value is either the serial number for a hardware device (such as GAHT12345678) + // or an Amazon Resource Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + SerialNumber *string `min:"9" type:"string"` + + // The value provided by the MFA device, if the trust policy of the role being + // assumed requires MFA (that is, if the policy includes a condition that tests + // for MFA). If the role being assumed requires MFA and if the TokenCode value + // is missing or expired, the AssumeRole call returns an "access denied" error. + // + // The format for this parameter, as described by its regex pattern, is a sequence + // of six numeric digits. + TokenCode *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s AssumeRoleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssumeRoleInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.ExternalId != nil && len(*s.ExternalId) < 2 { + invalidParams.Add(request.NewErrParamMinLen("ExternalId", 2)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.RoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20)) + } + if s.RoleSessionName == nil { + invalidParams.Add(request.NewErrParamRequired("RoleSessionName")) + } + if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2)) + } + if s.SerialNumber != nil && len(*s.SerialNumber) < 9 { + invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9)) + } + if s.TokenCode != nil && len(*s.TokenCode) < 6 { + invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6)) + } + if s.PolicyArns != nil { + for i, v := range s.PolicyArns { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationSeconds sets the DurationSeconds field's value. +func (s *AssumeRoleInput) SetDurationSeconds(v int64) *AssumeRoleInput { + s.DurationSeconds = &v + return s +} + +// SetExternalId sets the ExternalId field's value. +func (s *AssumeRoleInput) SetExternalId(v string) *AssumeRoleInput { + s.ExternalId = &v + return s +} + +// SetPolicy sets the Policy field's value. +func (s *AssumeRoleInput) SetPolicy(v string) *AssumeRoleInput { + s.Policy = &v + return s +} + +// SetPolicyArns sets the PolicyArns field's value. +func (s *AssumeRoleInput) SetPolicyArns(v []*PolicyDescriptorType) *AssumeRoleInput { + s.PolicyArns = v + return s +} + +// SetRoleArn sets the RoleArn field's value. +func (s *AssumeRoleInput) SetRoleArn(v string) *AssumeRoleInput { + s.RoleArn = &v + return s +} + +// SetRoleSessionName sets the RoleSessionName field's value. +func (s *AssumeRoleInput) SetRoleSessionName(v string) *AssumeRoleInput { + s.RoleSessionName = &v + return s +} + +// SetSerialNumber sets the SerialNumber field's value. +func (s *AssumeRoleInput) SetSerialNumber(v string) *AssumeRoleInput { + s.SerialNumber = &v + return s +} + +// SetTokenCode sets the TokenCode field's value. +func (s *AssumeRoleInput) SetTokenCode(v string) *AssumeRoleInput { + s.TokenCode = &v + return s +} + +// Contains the response to a successful AssumeRole request, including temporary +// AWS credentials that can be used to make AWS requests. +type AssumeRoleOutput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers + // that you can use to refer to the resulting temporary security credentials. + // For example, you can reference these credentials as a principal in a resource-based + // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName + // that you specified when you called AssumeRole. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // The size of the security token that STS API operations return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + Credentials *Credentials `type:"structure"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` +} + +// String returns the string representation +func (s AssumeRoleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleOutput) GoString() string { + return s.String() +} + +// SetAssumedRoleUser sets the AssumedRoleUser field's value. +func (s *AssumeRoleOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleOutput { + s.AssumedRoleUser = v + return s +} + +// SetCredentials sets the Credentials field's value. +func (s *AssumeRoleOutput) SetCredentials(v *Credentials) *AssumeRoleOutput { + s.Credentials = v + return s +} + +// SetPackedPolicySize sets the PackedPolicySize field's value. +func (s *AssumeRoleOutput) SetPackedPolicySize(v int64) *AssumeRoleOutput { + s.PackedPolicySize = &v + return s +} + +type AssumeRoleWithSAMLInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. Your role session lasts for + // the duration that you specify for the DurationSeconds parameter, or until + // the time specified in the SAML authentication response's SessionNotOnOrAfter + // value, whichever is shorter. You can provide a DurationSeconds value from + // 900 seconds (15 minutes) up to the maximum session duration setting for the + // role. This setting can have a value from 1 hour to 12 hours. If you specify + // a value higher than this setting, the operation fails. For example, if you + // specify a session duration of 12 hours, but your administrator set the maximum + // session duration to 6 hours, your operation fails. To learn how to view the + // maximum value for your role, see View the Maximum Session Duration Setting + // for a Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) + // in the IAM User Guide. + // + // By default, the value is set to 3600 seconds. + // + // The DurationSeconds parameter is separate from the duration of a console + // session that you might request using the returned credentials. The request + // to the federation endpoint for a console sign-in token takes a SessionDuration + // parameter that specifies the maximum length of the console session. For more + // information, see Creating a URL that Enables Federated Users to Access the + // AWS Management Console (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) + // in the IAM User Guide. + DurationSeconds *int64 `min:"900" type:"integer"` + + // An IAM policy in JSON format that you want to use as an inline session policy. + // + // This parameter is optional. Passing policies to this operation returns new + // temporary credentials. The resulting session's permissions are the intersection + // of the role's identity-based policy and the session policies. You can use + // the role's temporary credentials in subsequent AWS API calls to access resources + // in the account that owns the role. You cannot use session policies to grant + // more permissions than those allowed by the identity-based policy of the role + // that is being assumed. For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + // + // The plain text that you use for both inline and managed session policies + // shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII + // character from the space character to the end of the valid character list + // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + Policy *string `min:"1" type:"string"` + + // The Amazon Resource Names (ARNs) of the IAM managed policies that you want + // to use as managed session policies. The policies must exist in the same account + // as the role. + // + // This parameter is optional. You can provide up to 10 managed policy ARNs. + // However, the plain text that you use for both inline and managed session + // policies shouldn't exceed 2048 characters. For more information about ARNs, + // see Amazon Resource Names (ARNs) and AWS Service Namespaces (general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + // + // Passing policies to this operation returns new temporary credentials. The + // resulting session's permissions are the intersection of the role's identity-based + // policy and the session policies. You can use the role's temporary credentials + // in subsequent AWS API calls to access resources in the account that owns + // the role. You cannot use session policies to grant more permissions than + // those allowed by the identity-based policy of the role that is being assumed. + // For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + PolicyArns []*PolicyDescriptorType `type:"list"` + + // The Amazon Resource Name (ARN) of the SAML provider in IAM that describes + // the IdP. + // + // PrincipalArn is a required field + PrincipalArn *string `min:"20" type:"string" required:"true"` + + // The Amazon Resource Name (ARN) of the role that the caller is assuming. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // The base-64 encoded SAML authentication response provided by the IdP. + // + // For more information, see Configuring a Relying Party and Adding Claims (https://docs.aws.amazon.com/IAM/latest/UserGuide/create-role-saml-IdP-tasks.html) + // in the IAM User Guide. + // + // SAMLAssertion is a required field + SAMLAssertion *string `min:"4" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumeRoleWithSAMLInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithSAMLInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleWithSAMLInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithSAMLInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.PrincipalArn == nil { + invalidParams.Add(request.NewErrParamRequired("PrincipalArn")) + } + if s.PrincipalArn != nil && len(*s.PrincipalArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("PrincipalArn", 20)) + } + if s.RoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20)) + } + if s.SAMLAssertion == nil { + invalidParams.Add(request.NewErrParamRequired("SAMLAssertion")) + } + if s.SAMLAssertion != nil && len(*s.SAMLAssertion) < 4 { + invalidParams.Add(request.NewErrParamMinLen("SAMLAssertion", 4)) + } + if s.PolicyArns != nil { + for i, v := range s.PolicyArns { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationSeconds sets the DurationSeconds field's value. +func (s *AssumeRoleWithSAMLInput) SetDurationSeconds(v int64) *AssumeRoleWithSAMLInput { + s.DurationSeconds = &v + return s +} + +// SetPolicy sets the Policy field's value. +func (s *AssumeRoleWithSAMLInput) SetPolicy(v string) *AssumeRoleWithSAMLInput { + s.Policy = &v + return s +} + +// SetPolicyArns sets the PolicyArns field's value. +func (s *AssumeRoleWithSAMLInput) SetPolicyArns(v []*PolicyDescriptorType) *AssumeRoleWithSAMLInput { + s.PolicyArns = v + return s +} + +// SetPrincipalArn sets the PrincipalArn field's value. +func (s *AssumeRoleWithSAMLInput) SetPrincipalArn(v string) *AssumeRoleWithSAMLInput { + s.PrincipalArn = &v + return s +} + +// SetRoleArn sets the RoleArn field's value. +func (s *AssumeRoleWithSAMLInput) SetRoleArn(v string) *AssumeRoleWithSAMLInput { + s.RoleArn = &v + return s +} + +// SetSAMLAssertion sets the SAMLAssertion field's value. +func (s *AssumeRoleWithSAMLInput) SetSAMLAssertion(v string) *AssumeRoleWithSAMLInput { + s.SAMLAssertion = &v + return s +} + +// Contains the response to a successful AssumeRoleWithSAML request, including +// temporary AWS credentials that can be used to make AWS requests. +type AssumeRoleWithSAMLOutput struct { + _ struct{} `type:"structure"` + + // The identifiers for the temporary security credentials that the operation + // returns. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The value of the Recipient attribute of the SubjectConfirmationData element + // of the SAML assertion. + Audience *string `type:"string"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // The size of the security token that STS API operations return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + Credentials *Credentials `type:"structure"` + + // The value of the Issuer element of the SAML assertion. + Issuer *string `type:"string"` + + // A hash value based on the concatenation of the Issuer response value, the + // AWS account ID, and the friendly name (the last part of the ARN) of the SAML + // provider in IAM. The combination of NameQualifier and Subject can be used + // to uniquely identify a federated user. + // + // The following pseudocode shows how the hash value is calculated: + // + // BASE64 ( SHA1 ( "https://example.com/saml" + "123456789012" + "/MySAMLIdP" + // ) ) + NameQualifier *string `type:"string"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` + + // The value of the NameID element in the Subject element of the SAML assertion. + Subject *string `type:"string"` + + // The format of the name ID, as defined by the Format attribute in the NameID + // element of the SAML assertion. Typical examples of the format are transient + // or persistent. + // + // If the format includes the prefix urn:oasis:names:tc:SAML:2.0:nameid-format, + // that prefix is removed. For example, urn:oasis:names:tc:SAML:2.0:nameid-format:transient + // is returned as transient. If the format includes any other prefix, the format + // is returned with no modifications. + SubjectType *string `type:"string"` +} + +// String returns the string representation +func (s AssumeRoleWithSAMLOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithSAMLOutput) GoString() string { + return s.String() +} + +// SetAssumedRoleUser sets the AssumedRoleUser field's value. +func (s *AssumeRoleWithSAMLOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleWithSAMLOutput { + s.AssumedRoleUser = v + return s +} + +// SetAudience sets the Audience field's value. +func (s *AssumeRoleWithSAMLOutput) SetAudience(v string) *AssumeRoleWithSAMLOutput { + s.Audience = &v + return s +} + +// SetCredentials sets the Credentials field's value. +func (s *AssumeRoleWithSAMLOutput) SetCredentials(v *Credentials) *AssumeRoleWithSAMLOutput { + s.Credentials = v + return s +} + +// SetIssuer sets the Issuer field's value. +func (s *AssumeRoleWithSAMLOutput) SetIssuer(v string) *AssumeRoleWithSAMLOutput { + s.Issuer = &v + return s +} + +// SetNameQualifier sets the NameQualifier field's value. +func (s *AssumeRoleWithSAMLOutput) SetNameQualifier(v string) *AssumeRoleWithSAMLOutput { + s.NameQualifier = &v + return s +} + +// SetPackedPolicySize sets the PackedPolicySize field's value. +func (s *AssumeRoleWithSAMLOutput) SetPackedPolicySize(v int64) *AssumeRoleWithSAMLOutput { + s.PackedPolicySize = &v + return s +} + +// SetSubject sets the Subject field's value. +func (s *AssumeRoleWithSAMLOutput) SetSubject(v string) *AssumeRoleWithSAMLOutput { + s.Subject = &v + return s +} + +// SetSubjectType sets the SubjectType field's value. +func (s *AssumeRoleWithSAMLOutput) SetSubjectType(v string) *AssumeRoleWithSAMLOutput { + s.SubjectType = &v + return s +} + +type AssumeRoleWithWebIdentityInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, of the role session. The value can range from 900 + // seconds (15 minutes) up to the maximum session duration setting for the role. + // This setting can have a value from 1 hour to 12 hours. If you specify a value + // higher than this setting, the operation fails. For example, if you specify + // a session duration of 12 hours, but your administrator set the maximum session + // duration to 6 hours, your operation fails. To learn how to view the maximum + // value for your role, see View the Maximum Session Duration Setting for a + // Role (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session) + // in the IAM User Guide. + // + // By default, the value is set to 3600 seconds. + // + // The DurationSeconds parameter is separate from the duration of a console + // session that you might request using the returned credentials. The request + // to the federation endpoint for a console sign-in token takes a SessionDuration + // parameter that specifies the maximum length of the console session. For more + // information, see Creating a URL that Enables Federated Users to Access the + // AWS Management Console (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html) + // in the IAM User Guide. + DurationSeconds *int64 `min:"900" type:"integer"` + + // An IAM policy in JSON format that you want to use as an inline session policy. + // + // This parameter is optional. Passing policies to this operation returns new + // temporary credentials. The resulting session's permissions are the intersection + // of the role's identity-based policy and the session policies. You can use + // the role's temporary credentials in subsequent AWS API calls to access resources + // in the account that owns the role. You cannot use session policies to grant + // more permissions than those allowed by the identity-based policy of the role + // that is being assumed. For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + // + // The plain text that you use for both inline and managed session policies + // shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII + // character from the space character to the end of the valid character list + // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + Policy *string `min:"1" type:"string"` + + // The Amazon Resource Names (ARNs) of the IAM managed policies that you want + // to use as managed session policies. The policies must exist in the same account + // as the role. + // + // This parameter is optional. You can provide up to 10 managed policy ARNs. + // However, the plain text that you use for both inline and managed session + // policies shouldn't exceed 2048 characters. For more information about ARNs, + // see Amazon Resource Names (ARNs) and AWS Service Namespaces (general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + // + // Passing policies to this operation returns new temporary credentials. The + // resulting session's permissions are the intersection of the role's identity-based + // policy and the session policies. You can use the role's temporary credentials + // in subsequent AWS API calls to access resources in the account that owns + // the role. You cannot use session policies to grant more permissions than + // those allowed by the identity-based policy of the role that is being assumed. + // For more information, see Session Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + PolicyArns []*PolicyDescriptorType `type:"list"` + + // The fully qualified host component of the domain name of the identity provider. + // + // Specify this value only for OAuth 2.0 access tokens. Currently www.amazon.com + // and graph.facebook.com are the only supported identity providers for OAuth + // 2.0 access tokens. Do not include URL schemes and port numbers. + // + // Do not specify this value for OpenID Connect ID tokens. + ProviderId *string `min:"4" type:"string"` + + // The Amazon Resource Name (ARN) of the role that the caller is assuming. + // + // RoleArn is a required field + RoleArn *string `min:"20" type:"string" required:"true"` + + // An identifier for the assumed role session. Typically, you pass the name + // or identifier that is associated with the user who is using your application. + // That way, the temporary security credentials that your application will use + // are associated with that user. This session name is included as part of the + // ARN and assumed role ID in the AssumedRoleUser response element. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + // + // RoleSessionName is a required field + RoleSessionName *string `min:"2" type:"string" required:"true"` + + // The OAuth 2.0 access token or OpenID Connect ID token that is provided by + // the identity provider. Your application must get this token by authenticating + // the user who is using your application with a web identity provider before + // the application makes an AssumeRoleWithWebIdentity call. + // + // WebIdentityToken is a required field + WebIdentityToken *string `min:"4" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumeRoleWithWebIdentityInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithWebIdentityInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *AssumeRoleWithWebIdentityInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "AssumeRoleWithWebIdentityInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.ProviderId != nil && len(*s.ProviderId) < 4 { + invalidParams.Add(request.NewErrParamMinLen("ProviderId", 4)) + } + if s.RoleArn == nil { + invalidParams.Add(request.NewErrParamRequired("RoleArn")) + } + if s.RoleArn != nil && len(*s.RoleArn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("RoleArn", 20)) + } + if s.RoleSessionName == nil { + invalidParams.Add(request.NewErrParamRequired("RoleSessionName")) + } + if s.RoleSessionName != nil && len(*s.RoleSessionName) < 2 { + invalidParams.Add(request.NewErrParamMinLen("RoleSessionName", 2)) + } + if s.WebIdentityToken == nil { + invalidParams.Add(request.NewErrParamRequired("WebIdentityToken")) + } + if s.WebIdentityToken != nil && len(*s.WebIdentityToken) < 4 { + invalidParams.Add(request.NewErrParamMinLen("WebIdentityToken", 4)) + } + if s.PolicyArns != nil { + for i, v := range s.PolicyArns { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationSeconds sets the DurationSeconds field's value. +func (s *AssumeRoleWithWebIdentityInput) SetDurationSeconds(v int64) *AssumeRoleWithWebIdentityInput { + s.DurationSeconds = &v + return s +} + +// SetPolicy sets the Policy field's value. +func (s *AssumeRoleWithWebIdentityInput) SetPolicy(v string) *AssumeRoleWithWebIdentityInput { + s.Policy = &v + return s +} + +// SetPolicyArns sets the PolicyArns field's value. +func (s *AssumeRoleWithWebIdentityInput) SetPolicyArns(v []*PolicyDescriptorType) *AssumeRoleWithWebIdentityInput { + s.PolicyArns = v + return s +} + +// SetProviderId sets the ProviderId field's value. +func (s *AssumeRoleWithWebIdentityInput) SetProviderId(v string) *AssumeRoleWithWebIdentityInput { + s.ProviderId = &v + return s +} + +// SetRoleArn sets the RoleArn field's value. +func (s *AssumeRoleWithWebIdentityInput) SetRoleArn(v string) *AssumeRoleWithWebIdentityInput { + s.RoleArn = &v + return s +} + +// SetRoleSessionName sets the RoleSessionName field's value. +func (s *AssumeRoleWithWebIdentityInput) SetRoleSessionName(v string) *AssumeRoleWithWebIdentityInput { + s.RoleSessionName = &v + return s +} + +// SetWebIdentityToken sets the WebIdentityToken field's value. +func (s *AssumeRoleWithWebIdentityInput) SetWebIdentityToken(v string) *AssumeRoleWithWebIdentityInput { + s.WebIdentityToken = &v + return s +} + +// Contains the response to a successful AssumeRoleWithWebIdentity request, +// including temporary AWS credentials that can be used to make AWS requests. +type AssumeRoleWithWebIdentityOutput struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers + // that you can use to refer to the resulting temporary security credentials. + // For example, you can reference these credentials as a principal in a resource-based + // policy by using the ARN or assumed role ID. The ARN and ID include the RoleSessionName + // that you specified when you called AssumeRole. + AssumedRoleUser *AssumedRoleUser `type:"structure"` + + // The intended audience (also known as client ID) of the web identity token. + // This is traditionally the client identifier issued to the application that + // requested the web identity token. + Audience *string `type:"string"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security token. + // + // The size of the security token that STS API operations return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + Credentials *Credentials `type:"structure"` + + // A percentage value that indicates the size of the policy in packed form. + // The service rejects any policy with a packed size greater than 100 percent, + // which means the policy exceeded the allowed space. + PackedPolicySize *int64 `type:"integer"` + + // The issuing authority of the web identity token presented. For OpenID Connect + // ID tokens, this contains the value of the iss field. For OAuth 2.0 access + // tokens, this contains the value of the ProviderId parameter that was passed + // in the AssumeRoleWithWebIdentity request. + Provider *string `type:"string"` + + // The unique user identifier that is returned by the identity provider. This + // identifier is associated with the WebIdentityToken that was submitted with + // the AssumeRoleWithWebIdentity call. The identifier is typically unique to + // the user and the application that acquired the WebIdentityToken (pairwise + // identifier). For OpenID Connect ID tokens, this field contains the value + // returned by the identity provider as the token's sub (Subject) claim. + SubjectFromWebIdentityToken *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s AssumeRoleWithWebIdentityOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumeRoleWithWebIdentityOutput) GoString() string { + return s.String() +} + +// SetAssumedRoleUser sets the AssumedRoleUser field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetAssumedRoleUser(v *AssumedRoleUser) *AssumeRoleWithWebIdentityOutput { + s.AssumedRoleUser = v + return s +} + +// SetAudience sets the Audience field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetAudience(v string) *AssumeRoleWithWebIdentityOutput { + s.Audience = &v + return s +} + +// SetCredentials sets the Credentials field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetCredentials(v *Credentials) *AssumeRoleWithWebIdentityOutput { + s.Credentials = v + return s +} + +// SetPackedPolicySize sets the PackedPolicySize field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetPackedPolicySize(v int64) *AssumeRoleWithWebIdentityOutput { + s.PackedPolicySize = &v + return s +} + +// SetProvider sets the Provider field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetProvider(v string) *AssumeRoleWithWebIdentityOutput { + s.Provider = &v + return s +} + +// SetSubjectFromWebIdentityToken sets the SubjectFromWebIdentityToken field's value. +func (s *AssumeRoleWithWebIdentityOutput) SetSubjectFromWebIdentityToken(v string) *AssumeRoleWithWebIdentityOutput { + s.SubjectFromWebIdentityToken = &v + return s +} + +// The identifiers for the temporary security credentials that the operation +// returns. +type AssumedRoleUser struct { + _ struct{} `type:"structure"` + + // The ARN of the temporary security credentials that are returned from the + // AssumeRole action. For more information about ARNs and how to use them in + // policies, see IAM Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) + // in Using IAM. + // + // Arn is a required field + Arn *string `min:"20" type:"string" required:"true"` + + // A unique identifier that contains the role ID and the role session name of + // the role that is being assumed. The role ID is generated by AWS when the + // role is created. + // + // AssumedRoleId is a required field + AssumedRoleId *string `min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s AssumedRoleUser) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AssumedRoleUser) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *AssumedRoleUser) SetArn(v string) *AssumedRoleUser { + s.Arn = &v + return s +} + +// SetAssumedRoleId sets the AssumedRoleId field's value. +func (s *AssumedRoleUser) SetAssumedRoleId(v string) *AssumedRoleUser { + s.AssumedRoleId = &v + return s +} + +// AWS credentials for API authentication. +type Credentials struct { + _ struct{} `type:"structure"` + + // The access key ID that identifies the temporary security credentials. + // + // AccessKeyId is a required field + AccessKeyId *string `min:"16" type:"string" required:"true"` + + // The date on which the current credentials expire. + // + // Expiration is a required field + Expiration *time.Time `type:"timestamp" required:"true"` + + // The secret access key that can be used to sign requests. + // + // SecretAccessKey is a required field + SecretAccessKey *string `type:"string" required:"true"` + + // The token that users must pass to the service API to use the temporary credentials. + // + // SessionToken is a required field + SessionToken *string `type:"string" required:"true"` +} + +// String returns the string representation +func (s Credentials) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Credentials) GoString() string { + return s.String() +} + +// SetAccessKeyId sets the AccessKeyId field's value. +func (s *Credentials) SetAccessKeyId(v string) *Credentials { + s.AccessKeyId = &v + return s +} + +// SetExpiration sets the Expiration field's value. +func (s *Credentials) SetExpiration(v time.Time) *Credentials { + s.Expiration = &v + return s +} + +// SetSecretAccessKey sets the SecretAccessKey field's value. +func (s *Credentials) SetSecretAccessKey(v string) *Credentials { + s.SecretAccessKey = &v + return s +} + +// SetSessionToken sets the SessionToken field's value. +func (s *Credentials) SetSessionToken(v string) *Credentials { + s.SessionToken = &v + return s +} + +type DecodeAuthorizationMessageInput struct { + _ struct{} `type:"structure"` + + // The encoded message that was returned with the response. + // + // EncodedMessage is a required field + EncodedMessage *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s DecodeAuthorizationMessageInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DecodeAuthorizationMessageInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DecodeAuthorizationMessageInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DecodeAuthorizationMessageInput"} + if s.EncodedMessage == nil { + invalidParams.Add(request.NewErrParamRequired("EncodedMessage")) + } + if s.EncodedMessage != nil && len(*s.EncodedMessage) < 1 { + invalidParams.Add(request.NewErrParamMinLen("EncodedMessage", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEncodedMessage sets the EncodedMessage field's value. +func (s *DecodeAuthorizationMessageInput) SetEncodedMessage(v string) *DecodeAuthorizationMessageInput { + s.EncodedMessage = &v + return s +} + +// A document that contains additional information about the authorization status +// of a request from an encoded message that is returned in response to an AWS +// request. +type DecodeAuthorizationMessageOutput struct { + _ struct{} `type:"structure"` + + // An XML document that contains the decoded message. + DecodedMessage *string `type:"string"` +} + +// String returns the string representation +func (s DecodeAuthorizationMessageOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DecodeAuthorizationMessageOutput) GoString() string { + return s.String() +} + +// SetDecodedMessage sets the DecodedMessage field's value. +func (s *DecodeAuthorizationMessageOutput) SetDecodedMessage(v string) *DecodeAuthorizationMessageOutput { + s.DecodedMessage = &v + return s +} + +// Identifiers for the federated user that is associated with the credentials. +type FederatedUser struct { + _ struct{} `type:"structure"` + + // The ARN that specifies the federated user that is associated with the credentials. + // For more information about ARNs and how to use them in policies, see IAM + // Identifiers (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html) + // in Using IAM. + // + // Arn is a required field + Arn *string `min:"20" type:"string" required:"true"` + + // The string that identifies the federated user associated with the credentials, + // similar to the unique ID of an IAM user. + // + // FederatedUserId is a required field + FederatedUserId *string `min:"2" type:"string" required:"true"` +} + +// String returns the string representation +func (s FederatedUser) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FederatedUser) GoString() string { + return s.String() +} + +// SetArn sets the Arn field's value. +func (s *FederatedUser) SetArn(v string) *FederatedUser { + s.Arn = &v + return s +} + +// SetFederatedUserId sets the FederatedUserId field's value. +func (s *FederatedUser) SetFederatedUserId(v string) *FederatedUser { + s.FederatedUserId = &v + return s +} + +type GetCallerIdentityInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s GetCallerIdentityInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCallerIdentityInput) GoString() string { + return s.String() +} + +// Contains the response to a successful GetCallerIdentity request, including +// information about the entity making the request. +type GetCallerIdentityOutput struct { + _ struct{} `type:"structure"` + + // The AWS account ID number of the account that owns or contains the calling + // entity. + Account *string `type:"string"` + + // The AWS ARN associated with the calling entity. + Arn *string `min:"20" type:"string"` + + // The unique identifier of the calling entity. The exact value depends on the + // type of entity that is making the call. The values returned are those listed + // in the aws:userid column in the Principal table (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#principaltable) + // found on the Policy Variables reference page in the IAM User Guide. + UserId *string `type:"string"` +} + +// String returns the string representation +func (s GetCallerIdentityOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetCallerIdentityOutput) GoString() string { + return s.String() +} + +// SetAccount sets the Account field's value. +func (s *GetCallerIdentityOutput) SetAccount(v string) *GetCallerIdentityOutput { + s.Account = &v + return s +} + +// SetArn sets the Arn field's value. +func (s *GetCallerIdentityOutput) SetArn(v string) *GetCallerIdentityOutput { + s.Arn = &v + return s +} + +// SetUserId sets the UserId field's value. +func (s *GetCallerIdentityOutput) SetUserId(v string) *GetCallerIdentityOutput { + s.UserId = &v + return s +} + +type GetFederationTokenInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, that the session should last. Acceptable durations + // for federation sessions range from 900 seconds (15 minutes) to 129,600 seconds + // (36 hours), with 43,200 seconds (12 hours) as the default. Sessions obtained + // using AWS account root user credentials are restricted to a maximum of 3,600 + // seconds (one hour). If the specified duration is longer than one hour, the + // session obtained by using root user credentials defaults to one hour. + DurationSeconds *int64 `min:"900" type:"integer"` + + // The name of the federated user. The name is used as an identifier for the + // temporary security credentials (such as Bob). For example, you can reference + // the federated user name in a resource-based policy, such as in an Amazon + // S3 bucket policy. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@- + // + // Name is a required field + Name *string `min:"2" type:"string" required:"true"` + + // An IAM policy in JSON format that you want to use as an inline session policy. + // + // You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // to this operation. You can pass a single JSON policy document to use as an + // inline session policy. You can also specify up to 10 managed policies to + // use as managed session policies. + // + // This parameter is optional. However, if you do not pass any session policies, + // then the resulting federated user session has no permissions. The only exception + // is when the credentials are used to access a resource that has a resource-based + // policy that specifically references the federated user session in the Principal + // element of the policy. + // + // When you pass session policies, the session permissions are the intersection + // of the IAM user policies and the session policies that you pass. This gives + // you a way to further restrict the permissions for a federated user. You cannot + // use session policies to grant more permissions than those that are defined + // in the permissions policy of the IAM user. For more information, see Session + // Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + // + // The plain text that you use for both inline and managed session policies + // shouldn't exceed 2048 characters. The JSON policy characters can be any ASCII + // character from the space character to the end of the valid character list + // (\u0020 through \u00FF). It can also include the tab (\u0009), linefeed (\u000A), + // and carriage return (\u000D) characters. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + Policy *string `min:"1" type:"string"` + + // The Amazon Resource Names (ARNs) of the IAM managed policies that you want + // to use as a managed session policy. The policies must exist in the same account + // as the IAM user that is requesting federated access. + // + // You must pass an inline or managed session policy (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session) + // to this operation. You can pass a single JSON policy document to use as an + // inline session policy. You can also specify up to 10 managed policies to + // use as managed session policies. The plain text that you use for both inline + // and managed session policies shouldn't exceed 2048 characters. You can provide + // up to 10 managed policy ARNs. For more information about ARNs, see Amazon + // Resource Names (ARNs) and AWS Service Namespaces (general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + // + // This parameter is optional. However, if you do not pass any session policies, + // then the resulting federated user session has no permissions. The only exception + // is when the credentials are used to access a resource that has a resource-based + // policy that specifically references the federated user session in the Principal + // element of the policy. + // + // When you pass session policies, the session permissions are the intersection + // of the IAM user policies and the session policies that you pass. This gives + // you a way to further restrict the permissions for a federated user. You cannot + // use session policies to grant more permissions than those that are defined + // in the permissions policy of the IAM user. For more information, see Session + // Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM/latest/UserGuide/access_policies.html#policies_session) + // in the IAM User Guide. + // + // The characters in this parameter count towards the 2048 character session + // policy guideline. However, an AWS conversion compresses the session policies + // into a packed binary format that has a separate limit. This is the enforced + // limit. The PackedPolicySize response element indicates by percentage how + // close the policy is to the upper size limit. + PolicyArns []*PolicyDescriptorType `type:"list"` +} + +// String returns the string representation +func (s GetFederationTokenInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetFederationTokenInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetFederationTokenInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetFederationTokenInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.Name == nil { + invalidParams.Add(request.NewErrParamRequired("Name")) + } + if s.Name != nil && len(*s.Name) < 2 { + invalidParams.Add(request.NewErrParamMinLen("Name", 2)) + } + if s.Policy != nil && len(*s.Policy) < 1 { + invalidParams.Add(request.NewErrParamMinLen("Policy", 1)) + } + if s.PolicyArns != nil { + for i, v := range s.PolicyArns { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "PolicyArns", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationSeconds sets the DurationSeconds field's value. +func (s *GetFederationTokenInput) SetDurationSeconds(v int64) *GetFederationTokenInput { + s.DurationSeconds = &v + return s +} + +// SetName sets the Name field's value. +func (s *GetFederationTokenInput) SetName(v string) *GetFederationTokenInput { + s.Name = &v + return s +} + +// SetPolicy sets the Policy field's value. +func (s *GetFederationTokenInput) SetPolicy(v string) *GetFederationTokenInput { + s.Policy = &v + return s +} + +// SetPolicyArns sets the PolicyArns field's value. +func (s *GetFederationTokenInput) SetPolicyArns(v []*PolicyDescriptorType) *GetFederationTokenInput { + s.PolicyArns = v + return s +} + +// Contains the response to a successful GetFederationToken request, including +// temporary AWS credentials that can be used to make AWS requests. +type GetFederationTokenOutput struct { + _ struct{} `type:"structure"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // The size of the security token that STS API operations return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + Credentials *Credentials `type:"structure"` + + // Identifiers for the federated user associated with the credentials (such + // as arn:aws:sts::123456789012:federated-user/Bob or 123456789012:Bob). You + // can use the federated user's ARN in your resource-based policies, such as + // an Amazon S3 bucket policy. + FederatedUser *FederatedUser `type:"structure"` + + // A percentage value indicating the size of the policy in packed form. The + // service rejects policies for which the packed size is greater than 100 percent + // of the allowed value. + PackedPolicySize *int64 `type:"integer"` +} + +// String returns the string representation +func (s GetFederationTokenOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetFederationTokenOutput) GoString() string { + return s.String() +} + +// SetCredentials sets the Credentials field's value. +func (s *GetFederationTokenOutput) SetCredentials(v *Credentials) *GetFederationTokenOutput { + s.Credentials = v + return s +} + +// SetFederatedUser sets the FederatedUser field's value. +func (s *GetFederationTokenOutput) SetFederatedUser(v *FederatedUser) *GetFederationTokenOutput { + s.FederatedUser = v + return s +} + +// SetPackedPolicySize sets the PackedPolicySize field's value. +func (s *GetFederationTokenOutput) SetPackedPolicySize(v int64) *GetFederationTokenOutput { + s.PackedPolicySize = &v + return s +} + +type GetSessionTokenInput struct { + _ struct{} `type:"structure"` + + // The duration, in seconds, that the credentials should remain valid. Acceptable + // durations for IAM user sessions range from 900 seconds (15 minutes) to 129,600 + // seconds (36 hours), with 43,200 seconds (12 hours) as the default. Sessions + // for AWS account owners are restricted to a maximum of 3,600 seconds (one + // hour). If the duration is longer than one hour, the session for AWS account + // owners defaults to one hour. + DurationSeconds *int64 `min:"900" type:"integer"` + + // The identification number of the MFA device that is associated with the IAM + // user who is making the GetSessionToken call. Specify this value if the IAM + // user has a policy that requires MFA authentication. The value is either the + // serial number for a hardware device (such as GAHT12345678) or an Amazon Resource + // Name (ARN) for a virtual device (such as arn:aws:iam::123456789012:mfa/user). + // You can find the device for an IAM user by going to the AWS Management Console + // and viewing the user's security credentials. + // + // The regex used to validate this parameter is a string of characters consisting + // of upper- and lower-case alphanumeric characters with no spaces. You can + // also include underscores or any of the following characters: =,.@:/- + SerialNumber *string `min:"9" type:"string"` + + // The value provided by the MFA device, if MFA is required. If any policy requires + // the IAM user to submit an MFA code, specify this value. If MFA authentication + // is required, the user must provide a code when requesting a set of temporary + // security credentials. A user who fails to provide the code receives an "access + // denied" response when requesting resources that require MFA authentication. + // + // The format for this parameter, as described by its regex pattern, is a sequence + // of six numeric digits. + TokenCode *string `min:"6" type:"string"` +} + +// String returns the string representation +func (s GetSessionTokenInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSessionTokenInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetSessionTokenInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetSessionTokenInput"} + if s.DurationSeconds != nil && *s.DurationSeconds < 900 { + invalidParams.Add(request.NewErrParamMinValue("DurationSeconds", 900)) + } + if s.SerialNumber != nil && len(*s.SerialNumber) < 9 { + invalidParams.Add(request.NewErrParamMinLen("SerialNumber", 9)) + } + if s.TokenCode != nil && len(*s.TokenCode) < 6 { + invalidParams.Add(request.NewErrParamMinLen("TokenCode", 6)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetDurationSeconds sets the DurationSeconds field's value. +func (s *GetSessionTokenInput) SetDurationSeconds(v int64) *GetSessionTokenInput { + s.DurationSeconds = &v + return s +} + +// SetSerialNumber sets the SerialNumber field's value. +func (s *GetSessionTokenInput) SetSerialNumber(v string) *GetSessionTokenInput { + s.SerialNumber = &v + return s +} + +// SetTokenCode sets the TokenCode field's value. +func (s *GetSessionTokenInput) SetTokenCode(v string) *GetSessionTokenInput { + s.TokenCode = &v + return s +} + +// Contains the response to a successful GetSessionToken request, including +// temporary AWS credentials that can be used to make AWS requests. +type GetSessionTokenOutput struct { + _ struct{} `type:"structure"` + + // The temporary security credentials, which include an access key ID, a secret + // access key, and a security (or session) token. + // + // The size of the security token that STS API operations return is not fixed. + // We strongly recommend that you make no assumptions about the maximum size. + Credentials *Credentials `type:"structure"` +} + +// String returns the string representation +func (s GetSessionTokenOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSessionTokenOutput) GoString() string { + return s.String() +} + +// SetCredentials sets the Credentials field's value. +func (s *GetSessionTokenOutput) SetCredentials(v *Credentials) *GetSessionTokenOutput { + s.Credentials = v + return s +} + +// A reference to the IAM managed policy that is passed as a session policy +// for a role session or a federated user session. +type PolicyDescriptorType struct { + _ struct{} `type:"structure"` + + // The Amazon Resource Name (ARN) of the IAM managed policy to use as a session + // policy for the role. For more information about ARNs, see Amazon Resource + // Names (ARNs) and AWS Service Namespaces (general/latest/gr/aws-arns-and-namespaces.html) + // in the AWS General Reference. + Arn *string `locationName:"arn" min:"20" type:"string"` +} + +// String returns the string representation +func (s PolicyDescriptorType) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PolicyDescriptorType) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PolicyDescriptorType) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PolicyDescriptorType"} + if s.Arn != nil && len(*s.Arn) < 20 { + invalidParams.Add(request.NewErrParamMinLen("Arn", 20)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetArn sets the Arn field's value. +func (s *PolicyDescriptorType) SetArn(v string) *PolicyDescriptorType { + s.Arn = &v + return s +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go b/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go new file mode 100644 index 00000000..fa7a4c66 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/doc.go @@ -0,0 +1,116 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package sts provides the client and types for making API +// requests to AWS Security Token Service. +// +// The AWS Security Token Service (STS) is a web service that enables you to +// request temporary, limited-privilege credentials for AWS Identity and Access +// Management (IAM) users or for users that you authenticate (federated users). +// This guide provides descriptions of the STS API. For more detailed information +// about using this service, go to Temporary Security Credentials (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html). +// +// As an alternative to using the API, you can use one of the AWS SDKs, which +// consist of libraries and sample code for various programming languages and +// platforms (Java, Ruby, .NET, iOS, Android, etc.). The SDKs provide a convenient +// way to create programmatic access to STS. For example, the SDKs take care +// of cryptographically signing requests, managing errors, and retrying requests +// automatically. For information about the AWS SDKs, including how to download +// and install them, see the Tools for Amazon Web Services page (http://aws.amazon.com/tools/). +// +// For information about setting up signatures and authorization through the +// API, go to Signing AWS API Requests (https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html) +// in the AWS General Reference. For general information about the Query API, +// go to Making Query Requests (https://docs.aws.amazon.com/IAM/latest/UserGuide/IAM_UsingQueryAPI.html) +// in Using IAM. For information about using security tokens with other AWS +// products, go to AWS Services That Work with IAM (https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) +// in the IAM User Guide. +// +// If you're new to AWS and need additional technical information about a specific +// AWS product, you can find the product's technical documentation at http://aws.amazon.com/documentation/ +// (http://aws.amazon.com/documentation/). +// +// Endpoints +// +// By default, AWS Security Token Service (STS) is available as a global service, +// and all AWS STS requests go to a single endpoint at https://sts.amazonaws.com. +// Global requests map to the US East (N. Virginia) region. AWS recommends using +// Regional AWS STS endpoints instead of the global endpoint to reduce latency, +// build in redundancy, and increase session token validity. For more information, +// see Managing AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) +// in the IAM User Guide. +// +// Most AWS Regions are enabled for operations in all AWS services by default. +// Those Regions are automatically activated for use with AWS STS. Some Regions, +// such as Asia Pacific (Hong Kong), must be manually enabled. To learn more +// about enabling and disabling AWS Regions, see Managing AWS Regions (https://docs.aws.amazon.com/general/latest/gr/rande-manage.html) +// in the AWS General Reference. When you enable these AWS Regions, they are +// automatically activated for use with AWS STS. You cannot activate the STS +// endpoint for a Region that is disabled. Tokens that are valid in all AWS +// Regions are longer than tokens that are valid in Regions that are enabled +// by default. Changing this setting might affect existing systems where you +// temporarily store tokens. For more information, see Managing Global Endpoint +// Session Tokens (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#sts-regions-manage-tokens) +// in the IAM User Guide. +// +// After you activate a Region for use with AWS STS, you can direct AWS STS +// API calls to that Region. AWS STS recommends that you use both the setRegion +// and setEndpoint methods to make calls to a Regional endpoint. You can use +// the setRegion method alone for manually enabled Regions, such as Asia Pacific +// (Hong Kong). In this case, the calls are directed to the STS Regional endpoint. +// However, if you use the setRegion method alone for Regions enabled by default, +// the calls are directed to the global endpoint of https://sts.amazonaws.com. +// +// To view the list of AWS STS endpoints and whether they are active by default, +// see Writing Code to Use AWS STS Regions (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#id_credentials_temp_enable-regions_writing_code) +// in the IAM User Guide. +// +// Recording API requests +// +// STS supports AWS CloudTrail, which is a service that records AWS calls for +// your AWS account and delivers log files to an Amazon S3 bucket. By using +// information collected by CloudTrail, you can determine what requests were +// successfully made to STS, who made the request, when it was made, and so +// on. +// +// If you activate AWS STS endpoints in Regions other than the default global +// endpoint, then you must also turn on CloudTrail logging in those Regions. +// This is necessary to record any AWS STS API calls that are made in those +// Regions. For more information, see Turning On CloudTrail in Additional Regions +// (https://docs.aws.amazon.com/awscloudtrail/latest/userguide/aggregating_logs_regions_turn_on_ct.html) +// in the AWS CloudTrail User Guide. +// +// AWS Security Token Service (STS) is a global service with a single endpoint +// at https://sts.amazonaws.com. Calls to this endpoint are logged as calls +// to a global service. However, because this endpoint is physically located +// in the US East (N. Virginia) Region, your logs list us-east-1 as the event +// Region. CloudTrail does not write these logs to the US East (Ohio) Region +// unless you choose to include global service logs in that Region. CloudTrail +// writes calls to all Regional endpoints to their respective Regions. For example, +// calls to sts.us-east-2.amazonaws.com are published to the US East (Ohio) +// Region and calls to sts.eu-central-1.amazonaws.com are published to the EU +// (Frankfurt) Region. +// +// To learn more about CloudTrail, including how to turn it on and find your +// log files, see the AWS CloudTrail User Guide (https://docs.aws.amazon.com/awscloudtrail/latest/userguide/what_is_cloud_trail_top_level.html). +// +// See https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15 for more information on this service. +// +// See sts package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/ +// +// Using the Client +// +// To contact AWS Security Token Service with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the AWS Security Token Service client STS for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/sts/#New +package sts diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/errors.go b/vendor/github.com/aws/aws-sdk-go/service/sts/errors.go new file mode 100644 index 00000000..41ea09c3 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/errors.go @@ -0,0 +1,73 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package sts + +const ( + + // ErrCodeExpiredTokenException for service response error code + // "ExpiredTokenException". + // + // The web identity token that was passed is expired or is not valid. Get a + // new identity token from the identity provider and then retry the request. + ErrCodeExpiredTokenException = "ExpiredTokenException" + + // ErrCodeIDPCommunicationErrorException for service response error code + // "IDPCommunicationError". + // + // The request could not be fulfilled because the non-AWS identity provider + // (IDP) that was asked to verify the incoming identity token could not be reached. + // This is often a transient error caused by network conditions. Retry the request + // a limited number of times so that you don't exceed the request rate. If the + // error persists, the non-AWS identity provider might be down or not responding. + ErrCodeIDPCommunicationErrorException = "IDPCommunicationError" + + // ErrCodeIDPRejectedClaimException for service response error code + // "IDPRejectedClaim". + // + // The identity provider (IdP) reported that authentication failed. This might + // be because the claim is invalid. + // + // If this error is returned for the AssumeRoleWithWebIdentity operation, it + // can also mean that the claim has expired or has been explicitly revoked. + ErrCodeIDPRejectedClaimException = "IDPRejectedClaim" + + // ErrCodeInvalidAuthorizationMessageException for service response error code + // "InvalidAuthorizationMessageException". + // + // The error returned if the message passed to DecodeAuthorizationMessage was + // invalid. This can happen if the token contains invalid characters, such as + // linebreaks. + ErrCodeInvalidAuthorizationMessageException = "InvalidAuthorizationMessageException" + + // ErrCodeInvalidIdentityTokenException for service response error code + // "InvalidIdentityToken". + // + // The web identity token that was passed could not be validated by AWS. Get + // a new identity token from the identity provider and then retry the request. + ErrCodeInvalidIdentityTokenException = "InvalidIdentityToken" + + // ErrCodeMalformedPolicyDocumentException for service response error code + // "MalformedPolicyDocument". + // + // The request was rejected because the policy document was malformed. The error + // message describes the specific error. + ErrCodeMalformedPolicyDocumentException = "MalformedPolicyDocument" + + // ErrCodePackedPolicyTooLargeException for service response error code + // "PackedPolicyTooLarge". + // + // The request was rejected because the policy document was too large. The error + // message describes how big the policy document is, in packed form, as a percentage + // of what the API allows. + ErrCodePackedPolicyTooLargeException = "PackedPolicyTooLarge" + + // ErrCodeRegionDisabledException for service response error code + // "RegionDisabledException". + // + // STS is not activated in the requested region for the account that is being + // asked to generate credentials. The account administrator must use the IAM + // console to activate STS in that region. For more information, see Activating + // and Deactivating AWS STS in an AWS Region (https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html) + // in the IAM User Guide. + ErrCodeRegionDisabledException = "RegionDisabledException" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/sts/service.go b/vendor/github.com/aws/aws-sdk-go/service/sts/service.go new file mode 100644 index 00000000..185c914d --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/sts/service.go @@ -0,0 +1,95 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package sts + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol/query" +) + +// STS provides the API operation methods for making requests to +// AWS Security Token Service. See this package's package overview docs +// for details on the service. +// +// STS methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type STS struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// Service information constants +const ( + ServiceName = "sts" // Name of service. + EndpointsID = ServiceName // ID to lookup a service endpoint with. + ServiceID = "STS" // ServiceID is a unique identifer of a specific service. +) + +// New creates a new instance of the STS client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// // Create a STS client from just a session. +// svc := sts.New(mySession) +// +// // Create a STS client with additional configuration +// svc := sts.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *STS { + c := p.ClientConfig(EndpointsID, cfgs...) + return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *STS { + svc := &STS{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + ServiceID: ServiceID, + SigningName: signingName, + SigningRegion: signingRegion, + Endpoint: endpoint, + APIVersion: "2011-06-15", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(query.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(query.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(query.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed(query.UnmarshalErrorHandler) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a STS operation and runs any +// custom request initialization. +func (c *STS) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} diff --git a/vendor/github.com/aws/aws-sdk-go/service/xray/api.go b/vendor/github.com/aws/aws-sdk-go/service/xray/api.go new file mode 100644 index 00000000..8ea57822 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/xray/api.go @@ -0,0 +1,6414 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package xray + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awsutil" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/private/protocol" + "github.com/aws/aws-sdk-go/private/protocol/restjson" +) + +const opBatchGetTraces = "BatchGetTraces" + +// BatchGetTracesRequest generates a "aws/request.Request" representing the +// client's request for the BatchGetTraces operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See BatchGetTraces for more information on using the BatchGetTraces +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the BatchGetTracesRequest method. +// req, resp := client.BatchGetTracesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/BatchGetTraces +func (c *XRay) BatchGetTracesRequest(input *BatchGetTracesInput) (req *request.Request, output *BatchGetTracesOutput) { + op := &request.Operation{ + Name: opBatchGetTraces, + HTTPMethod: "POST", + HTTPPath: "/Traces", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &BatchGetTracesInput{} + } + + output = &BatchGetTracesOutput{} + req = c.newRequest(op, input, output) + return +} + +// BatchGetTraces API operation for AWS X-Ray. +// +// Retrieves a list of traces specified by ID. Each trace is a collection of +// segment documents that originates from a single request. Use GetTraceSummaries +// to get a list of trace IDs. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation BatchGetTraces for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/BatchGetTraces +func (c *XRay) BatchGetTraces(input *BatchGetTracesInput) (*BatchGetTracesOutput, error) { + req, out := c.BatchGetTracesRequest(input) + return out, req.Send() +} + +// BatchGetTracesWithContext is the same as BatchGetTraces with the addition of +// the ability to pass a context and additional request options. +// +// See BatchGetTraces for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) BatchGetTracesWithContext(ctx aws.Context, input *BatchGetTracesInput, opts ...request.Option) (*BatchGetTracesOutput, error) { + req, out := c.BatchGetTracesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// BatchGetTracesPages iterates over the pages of a BatchGetTraces operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See BatchGetTraces method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a BatchGetTraces operation. +// pageNum := 0 +// err := client.BatchGetTracesPages(params, +// func(page *BatchGetTracesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *XRay) BatchGetTracesPages(input *BatchGetTracesInput, fn func(*BatchGetTracesOutput, bool) bool) error { + return c.BatchGetTracesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// BatchGetTracesPagesWithContext same as BatchGetTracesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) BatchGetTracesPagesWithContext(ctx aws.Context, input *BatchGetTracesInput, fn func(*BatchGetTracesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *BatchGetTracesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.BatchGetTracesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*BatchGetTracesOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opCreateGroup = "CreateGroup" + +// CreateGroupRequest generates a "aws/request.Request" representing the +// client's request for the CreateGroup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateGroup for more information on using the CreateGroup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateGroupRequest method. +// req, resp := client.CreateGroupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/CreateGroup +func (c *XRay) CreateGroupRequest(input *CreateGroupInput) (req *request.Request, output *CreateGroupOutput) { + op := &request.Operation{ + Name: opCreateGroup, + HTTPMethod: "POST", + HTTPPath: "/CreateGroup", + } + + if input == nil { + input = &CreateGroupInput{} + } + + output = &CreateGroupOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateGroup API operation for AWS X-Ray. +// +// Creates a group resource with a name and a filter expression. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation CreateGroup for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/CreateGroup +func (c *XRay) CreateGroup(input *CreateGroupInput) (*CreateGroupOutput, error) { + req, out := c.CreateGroupRequest(input) + return out, req.Send() +} + +// CreateGroupWithContext is the same as CreateGroup with the addition of +// the ability to pass a context and additional request options. +// +// See CreateGroup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) CreateGroupWithContext(ctx aws.Context, input *CreateGroupInput, opts ...request.Option) (*CreateGroupOutput, error) { + req, out := c.CreateGroupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opCreateSamplingRule = "CreateSamplingRule" + +// CreateSamplingRuleRequest generates a "aws/request.Request" representing the +// client's request for the CreateSamplingRule operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See CreateSamplingRule for more information on using the CreateSamplingRule +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the CreateSamplingRuleRequest method. +// req, resp := client.CreateSamplingRuleRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/CreateSamplingRule +func (c *XRay) CreateSamplingRuleRequest(input *CreateSamplingRuleInput) (req *request.Request, output *CreateSamplingRuleOutput) { + op := &request.Operation{ + Name: opCreateSamplingRule, + HTTPMethod: "POST", + HTTPPath: "/CreateSamplingRule", + } + + if input == nil { + input = &CreateSamplingRuleInput{} + } + + output = &CreateSamplingRuleOutput{} + req = c.newRequest(op, input, output) + return +} + +// CreateSamplingRule API operation for AWS X-Ray. +// +// Creates a rule to control sampling behavior for instrumented applications. +// Services retrieve rules with GetSamplingRules, and evaluate each rule in +// ascending order of priority for each request. If a rule matches, the service +// records a trace, borrowing it from the reservoir size. After 10 seconds, +// the service reports back to X-Ray with GetSamplingTargets to get updated +// versions of each in-use rule. The updated rule contains a trace quota that +// the service can use instead of borrowing from the reservoir. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation CreateSamplingRule for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// * ErrCodeRuleLimitExceededException "RuleLimitExceededException" +// You have reached the maximum number of sampling rules. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/CreateSamplingRule +func (c *XRay) CreateSamplingRule(input *CreateSamplingRuleInput) (*CreateSamplingRuleOutput, error) { + req, out := c.CreateSamplingRuleRequest(input) + return out, req.Send() +} + +// CreateSamplingRuleWithContext is the same as CreateSamplingRule with the addition of +// the ability to pass a context and additional request options. +// +// See CreateSamplingRule for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) CreateSamplingRuleWithContext(ctx aws.Context, input *CreateSamplingRuleInput, opts ...request.Option) (*CreateSamplingRuleOutput, error) { + req, out := c.CreateSamplingRuleRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteGroup = "DeleteGroup" + +// DeleteGroupRequest generates a "aws/request.Request" representing the +// client's request for the DeleteGroup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteGroup for more information on using the DeleteGroup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteGroupRequest method. +// req, resp := client.DeleteGroupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/DeleteGroup +func (c *XRay) DeleteGroupRequest(input *DeleteGroupInput) (req *request.Request, output *DeleteGroupOutput) { + op := &request.Operation{ + Name: opDeleteGroup, + HTTPMethod: "POST", + HTTPPath: "/DeleteGroup", + } + + if input == nil { + input = &DeleteGroupInput{} + } + + output = &DeleteGroupOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restjson.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// DeleteGroup API operation for AWS X-Ray. +// +// Deletes a group resource. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation DeleteGroup for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/DeleteGroup +func (c *XRay) DeleteGroup(input *DeleteGroupInput) (*DeleteGroupOutput, error) { + req, out := c.DeleteGroupRequest(input) + return out, req.Send() +} + +// DeleteGroupWithContext is the same as DeleteGroup with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteGroup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) DeleteGroupWithContext(ctx aws.Context, input *DeleteGroupInput, opts ...request.Option) (*DeleteGroupOutput, error) { + req, out := c.DeleteGroupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opDeleteSamplingRule = "DeleteSamplingRule" + +// DeleteSamplingRuleRequest generates a "aws/request.Request" representing the +// client's request for the DeleteSamplingRule operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See DeleteSamplingRule for more information on using the DeleteSamplingRule +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the DeleteSamplingRuleRequest method. +// req, resp := client.DeleteSamplingRuleRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/DeleteSamplingRule +func (c *XRay) DeleteSamplingRuleRequest(input *DeleteSamplingRuleInput) (req *request.Request, output *DeleteSamplingRuleOutput) { + op := &request.Operation{ + Name: opDeleteSamplingRule, + HTTPMethod: "POST", + HTTPPath: "/DeleteSamplingRule", + } + + if input == nil { + input = &DeleteSamplingRuleInput{} + } + + output = &DeleteSamplingRuleOutput{} + req = c.newRequest(op, input, output) + return +} + +// DeleteSamplingRule API operation for AWS X-Ray. +// +// Deletes a sampling rule. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation DeleteSamplingRule for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/DeleteSamplingRule +func (c *XRay) DeleteSamplingRule(input *DeleteSamplingRuleInput) (*DeleteSamplingRuleOutput, error) { + req, out := c.DeleteSamplingRuleRequest(input) + return out, req.Send() +} + +// DeleteSamplingRuleWithContext is the same as DeleteSamplingRule with the addition of +// the ability to pass a context and additional request options. +// +// See DeleteSamplingRule for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) DeleteSamplingRuleWithContext(ctx aws.Context, input *DeleteSamplingRuleInput, opts ...request.Option) (*DeleteSamplingRuleOutput, error) { + req, out := c.DeleteSamplingRuleRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetEncryptionConfig = "GetEncryptionConfig" + +// GetEncryptionConfigRequest generates a "aws/request.Request" representing the +// client's request for the GetEncryptionConfig operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetEncryptionConfig for more information on using the GetEncryptionConfig +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetEncryptionConfigRequest method. +// req, resp := client.GetEncryptionConfigRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetEncryptionConfig +func (c *XRay) GetEncryptionConfigRequest(input *GetEncryptionConfigInput) (req *request.Request, output *GetEncryptionConfigOutput) { + op := &request.Operation{ + Name: opGetEncryptionConfig, + HTTPMethod: "POST", + HTTPPath: "/EncryptionConfig", + } + + if input == nil { + input = &GetEncryptionConfigInput{} + } + + output = &GetEncryptionConfigOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetEncryptionConfig API operation for AWS X-Ray. +// +// Retrieves the current encryption configuration for X-Ray data. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation GetEncryptionConfig for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetEncryptionConfig +func (c *XRay) GetEncryptionConfig(input *GetEncryptionConfigInput) (*GetEncryptionConfigOutput, error) { + req, out := c.GetEncryptionConfigRequest(input) + return out, req.Send() +} + +// GetEncryptionConfigWithContext is the same as GetEncryptionConfig with the addition of +// the ability to pass a context and additional request options. +// +// See GetEncryptionConfig for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetEncryptionConfigWithContext(ctx aws.Context, input *GetEncryptionConfigInput, opts ...request.Option) (*GetEncryptionConfigOutput, error) { + req, out := c.GetEncryptionConfigRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetGroup = "GetGroup" + +// GetGroupRequest generates a "aws/request.Request" representing the +// client's request for the GetGroup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetGroup for more information on using the GetGroup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetGroupRequest method. +// req, resp := client.GetGroupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetGroup +func (c *XRay) GetGroupRequest(input *GetGroupInput) (req *request.Request, output *GetGroupOutput) { + op := &request.Operation{ + Name: opGetGroup, + HTTPMethod: "POST", + HTTPPath: "/GetGroup", + } + + if input == nil { + input = &GetGroupInput{} + } + + output = &GetGroupOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetGroup API operation for AWS X-Ray. +// +// Retrieves group resource details. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation GetGroup for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetGroup +func (c *XRay) GetGroup(input *GetGroupInput) (*GetGroupOutput, error) { + req, out := c.GetGroupRequest(input) + return out, req.Send() +} + +// GetGroupWithContext is the same as GetGroup with the addition of +// the ability to pass a context and additional request options. +// +// See GetGroup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetGroupWithContext(ctx aws.Context, input *GetGroupInput, opts ...request.Option) (*GetGroupOutput, error) { + req, out := c.GetGroupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetGroups = "GetGroups" + +// GetGroupsRequest generates a "aws/request.Request" representing the +// client's request for the GetGroups operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetGroups for more information on using the GetGroups +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetGroupsRequest method. +// req, resp := client.GetGroupsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetGroups +func (c *XRay) GetGroupsRequest(input *GetGroupsInput) (req *request.Request, output *GetGroupsOutput) { + op := &request.Operation{ + Name: opGetGroups, + HTTPMethod: "POST", + HTTPPath: "/Groups", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetGroupsInput{} + } + + output = &GetGroupsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetGroups API operation for AWS X-Ray. +// +// Retrieves all active group details. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation GetGroups for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetGroups +func (c *XRay) GetGroups(input *GetGroupsInput) (*GetGroupsOutput, error) { + req, out := c.GetGroupsRequest(input) + return out, req.Send() +} + +// GetGroupsWithContext is the same as GetGroups with the addition of +// the ability to pass a context and additional request options. +// +// See GetGroups for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetGroupsWithContext(ctx aws.Context, input *GetGroupsInput, opts ...request.Option) (*GetGroupsOutput, error) { + req, out := c.GetGroupsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetGroupsPages iterates over the pages of a GetGroups operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetGroups method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetGroups operation. +// pageNum := 0 +// err := client.GetGroupsPages(params, +// func(page *GetGroupsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *XRay) GetGroupsPages(input *GetGroupsInput, fn func(*GetGroupsOutput, bool) bool) error { + return c.GetGroupsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetGroupsPagesWithContext same as GetGroupsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetGroupsPagesWithContext(ctx aws.Context, input *GetGroupsInput, fn func(*GetGroupsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetGroupsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetGroupsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*GetGroupsOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opGetSamplingRules = "GetSamplingRules" + +// GetSamplingRulesRequest generates a "aws/request.Request" representing the +// client's request for the GetSamplingRules operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetSamplingRules for more information on using the GetSamplingRules +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetSamplingRulesRequest method. +// req, resp := client.GetSamplingRulesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetSamplingRules +func (c *XRay) GetSamplingRulesRequest(input *GetSamplingRulesInput) (req *request.Request, output *GetSamplingRulesOutput) { + op := &request.Operation{ + Name: opGetSamplingRules, + HTTPMethod: "POST", + HTTPPath: "/GetSamplingRules", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetSamplingRulesInput{} + } + + output = &GetSamplingRulesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetSamplingRules API operation for AWS X-Ray. +// +// Retrieves all sampling rules. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation GetSamplingRules for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetSamplingRules +func (c *XRay) GetSamplingRules(input *GetSamplingRulesInput) (*GetSamplingRulesOutput, error) { + req, out := c.GetSamplingRulesRequest(input) + return out, req.Send() +} + +// GetSamplingRulesWithContext is the same as GetSamplingRules with the addition of +// the ability to pass a context and additional request options. +// +// See GetSamplingRules for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetSamplingRulesWithContext(ctx aws.Context, input *GetSamplingRulesInput, opts ...request.Option) (*GetSamplingRulesOutput, error) { + req, out := c.GetSamplingRulesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetSamplingRulesPages iterates over the pages of a GetSamplingRules operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetSamplingRules method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetSamplingRules operation. +// pageNum := 0 +// err := client.GetSamplingRulesPages(params, +// func(page *GetSamplingRulesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *XRay) GetSamplingRulesPages(input *GetSamplingRulesInput, fn func(*GetSamplingRulesOutput, bool) bool) error { + return c.GetSamplingRulesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetSamplingRulesPagesWithContext same as GetSamplingRulesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetSamplingRulesPagesWithContext(ctx aws.Context, input *GetSamplingRulesInput, fn func(*GetSamplingRulesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetSamplingRulesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetSamplingRulesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*GetSamplingRulesOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opGetSamplingStatisticSummaries = "GetSamplingStatisticSummaries" + +// GetSamplingStatisticSummariesRequest generates a "aws/request.Request" representing the +// client's request for the GetSamplingStatisticSummaries operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetSamplingStatisticSummaries for more information on using the GetSamplingStatisticSummaries +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetSamplingStatisticSummariesRequest method. +// req, resp := client.GetSamplingStatisticSummariesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetSamplingStatisticSummaries +func (c *XRay) GetSamplingStatisticSummariesRequest(input *GetSamplingStatisticSummariesInput) (req *request.Request, output *GetSamplingStatisticSummariesOutput) { + op := &request.Operation{ + Name: opGetSamplingStatisticSummaries, + HTTPMethod: "POST", + HTTPPath: "/SamplingStatisticSummaries", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetSamplingStatisticSummariesInput{} + } + + output = &GetSamplingStatisticSummariesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetSamplingStatisticSummaries API operation for AWS X-Ray. +// +// Retrieves information about recent sampling results for all sampling rules. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation GetSamplingStatisticSummaries for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetSamplingStatisticSummaries +func (c *XRay) GetSamplingStatisticSummaries(input *GetSamplingStatisticSummariesInput) (*GetSamplingStatisticSummariesOutput, error) { + req, out := c.GetSamplingStatisticSummariesRequest(input) + return out, req.Send() +} + +// GetSamplingStatisticSummariesWithContext is the same as GetSamplingStatisticSummaries with the addition of +// the ability to pass a context and additional request options. +// +// See GetSamplingStatisticSummaries for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetSamplingStatisticSummariesWithContext(ctx aws.Context, input *GetSamplingStatisticSummariesInput, opts ...request.Option) (*GetSamplingStatisticSummariesOutput, error) { + req, out := c.GetSamplingStatisticSummariesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetSamplingStatisticSummariesPages iterates over the pages of a GetSamplingStatisticSummaries operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetSamplingStatisticSummaries method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetSamplingStatisticSummaries operation. +// pageNum := 0 +// err := client.GetSamplingStatisticSummariesPages(params, +// func(page *GetSamplingStatisticSummariesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *XRay) GetSamplingStatisticSummariesPages(input *GetSamplingStatisticSummariesInput, fn func(*GetSamplingStatisticSummariesOutput, bool) bool) error { + return c.GetSamplingStatisticSummariesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetSamplingStatisticSummariesPagesWithContext same as GetSamplingStatisticSummariesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetSamplingStatisticSummariesPagesWithContext(ctx aws.Context, input *GetSamplingStatisticSummariesInput, fn func(*GetSamplingStatisticSummariesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetSamplingStatisticSummariesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetSamplingStatisticSummariesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*GetSamplingStatisticSummariesOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opGetSamplingTargets = "GetSamplingTargets" + +// GetSamplingTargetsRequest generates a "aws/request.Request" representing the +// client's request for the GetSamplingTargets operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetSamplingTargets for more information on using the GetSamplingTargets +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetSamplingTargetsRequest method. +// req, resp := client.GetSamplingTargetsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetSamplingTargets +func (c *XRay) GetSamplingTargetsRequest(input *GetSamplingTargetsInput) (req *request.Request, output *GetSamplingTargetsOutput) { + op := &request.Operation{ + Name: opGetSamplingTargets, + HTTPMethod: "POST", + HTTPPath: "/SamplingTargets", + } + + if input == nil { + input = &GetSamplingTargetsInput{} + } + + output = &GetSamplingTargetsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetSamplingTargets API operation for AWS X-Ray. +// +// Requests a sampling quota for rules that the service is using to sample requests. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation GetSamplingTargets for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetSamplingTargets +func (c *XRay) GetSamplingTargets(input *GetSamplingTargetsInput) (*GetSamplingTargetsOutput, error) { + req, out := c.GetSamplingTargetsRequest(input) + return out, req.Send() +} + +// GetSamplingTargetsWithContext is the same as GetSamplingTargets with the addition of +// the ability to pass a context and additional request options. +// +// See GetSamplingTargets for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetSamplingTargetsWithContext(ctx aws.Context, input *GetSamplingTargetsInput, opts ...request.Option) (*GetSamplingTargetsOutput, error) { + req, out := c.GetSamplingTargetsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opGetServiceGraph = "GetServiceGraph" + +// GetServiceGraphRequest generates a "aws/request.Request" representing the +// client's request for the GetServiceGraph operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetServiceGraph for more information on using the GetServiceGraph +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetServiceGraphRequest method. +// req, resp := client.GetServiceGraphRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetServiceGraph +func (c *XRay) GetServiceGraphRequest(input *GetServiceGraphInput) (req *request.Request, output *GetServiceGraphOutput) { + op := &request.Operation{ + Name: opGetServiceGraph, + HTTPMethod: "POST", + HTTPPath: "/ServiceGraph", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetServiceGraphInput{} + } + + output = &GetServiceGraphOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetServiceGraph API operation for AWS X-Ray. +// +// Retrieves a document that describes services that process incoming requests, +// and downstream services that they call as a result. Root services process +// incoming requests and make calls to downstream services. Root services are +// applications that use the AWS X-Ray SDK. Downstream services can be other +// applications, AWS resources, HTTP web APIs, or SQL databases. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation GetServiceGraph for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetServiceGraph +func (c *XRay) GetServiceGraph(input *GetServiceGraphInput) (*GetServiceGraphOutput, error) { + req, out := c.GetServiceGraphRequest(input) + return out, req.Send() +} + +// GetServiceGraphWithContext is the same as GetServiceGraph with the addition of +// the ability to pass a context and additional request options. +// +// See GetServiceGraph for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetServiceGraphWithContext(ctx aws.Context, input *GetServiceGraphInput, opts ...request.Option) (*GetServiceGraphOutput, error) { + req, out := c.GetServiceGraphRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetServiceGraphPages iterates over the pages of a GetServiceGraph operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetServiceGraph method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetServiceGraph operation. +// pageNum := 0 +// err := client.GetServiceGraphPages(params, +// func(page *GetServiceGraphOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *XRay) GetServiceGraphPages(input *GetServiceGraphInput, fn func(*GetServiceGraphOutput, bool) bool) error { + return c.GetServiceGraphPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetServiceGraphPagesWithContext same as GetServiceGraphPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetServiceGraphPagesWithContext(ctx aws.Context, input *GetServiceGraphInput, fn func(*GetServiceGraphOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetServiceGraphInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetServiceGraphRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*GetServiceGraphOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opGetTimeSeriesServiceStatistics = "GetTimeSeriesServiceStatistics" + +// GetTimeSeriesServiceStatisticsRequest generates a "aws/request.Request" representing the +// client's request for the GetTimeSeriesServiceStatistics operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetTimeSeriesServiceStatistics for more information on using the GetTimeSeriesServiceStatistics +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetTimeSeriesServiceStatisticsRequest method. +// req, resp := client.GetTimeSeriesServiceStatisticsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetTimeSeriesServiceStatistics +func (c *XRay) GetTimeSeriesServiceStatisticsRequest(input *GetTimeSeriesServiceStatisticsInput) (req *request.Request, output *GetTimeSeriesServiceStatisticsOutput) { + op := &request.Operation{ + Name: opGetTimeSeriesServiceStatistics, + HTTPMethod: "POST", + HTTPPath: "/TimeSeriesServiceStatistics", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetTimeSeriesServiceStatisticsInput{} + } + + output = &GetTimeSeriesServiceStatisticsOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetTimeSeriesServiceStatistics API operation for AWS X-Ray. +// +// Get an aggregation of service statistics defined by a specific time range. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation GetTimeSeriesServiceStatistics for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetTimeSeriesServiceStatistics +func (c *XRay) GetTimeSeriesServiceStatistics(input *GetTimeSeriesServiceStatisticsInput) (*GetTimeSeriesServiceStatisticsOutput, error) { + req, out := c.GetTimeSeriesServiceStatisticsRequest(input) + return out, req.Send() +} + +// GetTimeSeriesServiceStatisticsWithContext is the same as GetTimeSeriesServiceStatistics with the addition of +// the ability to pass a context and additional request options. +// +// See GetTimeSeriesServiceStatistics for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetTimeSeriesServiceStatisticsWithContext(ctx aws.Context, input *GetTimeSeriesServiceStatisticsInput, opts ...request.Option) (*GetTimeSeriesServiceStatisticsOutput, error) { + req, out := c.GetTimeSeriesServiceStatisticsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetTimeSeriesServiceStatisticsPages iterates over the pages of a GetTimeSeriesServiceStatistics operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetTimeSeriesServiceStatistics method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetTimeSeriesServiceStatistics operation. +// pageNum := 0 +// err := client.GetTimeSeriesServiceStatisticsPages(params, +// func(page *GetTimeSeriesServiceStatisticsOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *XRay) GetTimeSeriesServiceStatisticsPages(input *GetTimeSeriesServiceStatisticsInput, fn func(*GetTimeSeriesServiceStatisticsOutput, bool) bool) error { + return c.GetTimeSeriesServiceStatisticsPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetTimeSeriesServiceStatisticsPagesWithContext same as GetTimeSeriesServiceStatisticsPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetTimeSeriesServiceStatisticsPagesWithContext(ctx aws.Context, input *GetTimeSeriesServiceStatisticsInput, fn func(*GetTimeSeriesServiceStatisticsOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetTimeSeriesServiceStatisticsInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetTimeSeriesServiceStatisticsRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*GetTimeSeriesServiceStatisticsOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opGetTraceGraph = "GetTraceGraph" + +// GetTraceGraphRequest generates a "aws/request.Request" representing the +// client's request for the GetTraceGraph operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetTraceGraph for more information on using the GetTraceGraph +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetTraceGraphRequest method. +// req, resp := client.GetTraceGraphRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetTraceGraph +func (c *XRay) GetTraceGraphRequest(input *GetTraceGraphInput) (req *request.Request, output *GetTraceGraphOutput) { + op := &request.Operation{ + Name: opGetTraceGraph, + HTTPMethod: "POST", + HTTPPath: "/TraceGraph", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetTraceGraphInput{} + } + + output = &GetTraceGraphOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetTraceGraph API operation for AWS X-Ray. +// +// Retrieves a service graph for one or more specific trace IDs. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation GetTraceGraph for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetTraceGraph +func (c *XRay) GetTraceGraph(input *GetTraceGraphInput) (*GetTraceGraphOutput, error) { + req, out := c.GetTraceGraphRequest(input) + return out, req.Send() +} + +// GetTraceGraphWithContext is the same as GetTraceGraph with the addition of +// the ability to pass a context and additional request options. +// +// See GetTraceGraph for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetTraceGraphWithContext(ctx aws.Context, input *GetTraceGraphInput, opts ...request.Option) (*GetTraceGraphOutput, error) { + req, out := c.GetTraceGraphRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetTraceGraphPages iterates over the pages of a GetTraceGraph operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetTraceGraph method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetTraceGraph operation. +// pageNum := 0 +// err := client.GetTraceGraphPages(params, +// func(page *GetTraceGraphOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *XRay) GetTraceGraphPages(input *GetTraceGraphInput, fn func(*GetTraceGraphOutput, bool) bool) error { + return c.GetTraceGraphPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetTraceGraphPagesWithContext same as GetTraceGraphPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetTraceGraphPagesWithContext(ctx aws.Context, input *GetTraceGraphInput, fn func(*GetTraceGraphOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetTraceGraphInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetTraceGraphRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*GetTraceGraphOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opGetTraceSummaries = "GetTraceSummaries" + +// GetTraceSummariesRequest generates a "aws/request.Request" representing the +// client's request for the GetTraceSummaries operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See GetTraceSummaries for more information on using the GetTraceSummaries +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the GetTraceSummariesRequest method. +// req, resp := client.GetTraceSummariesRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetTraceSummaries +func (c *XRay) GetTraceSummariesRequest(input *GetTraceSummariesInput) (req *request.Request, output *GetTraceSummariesOutput) { + op := &request.Operation{ + Name: opGetTraceSummaries, + HTTPMethod: "POST", + HTTPPath: "/TraceSummaries", + Paginator: &request.Paginator{ + InputTokens: []string{"NextToken"}, + OutputTokens: []string{"NextToken"}, + LimitToken: "", + TruncationToken: "", + }, + } + + if input == nil { + input = &GetTraceSummariesInput{} + } + + output = &GetTraceSummariesOutput{} + req = c.newRequest(op, input, output) + return +} + +// GetTraceSummaries API operation for AWS X-Ray. +// +// Retrieves IDs and metadata for traces available for a specified time frame +// using an optional filter. To get the full traces, pass the trace IDs to BatchGetTraces. +// +// A filter expression can target traced requests that hit specific service +// nodes or edges, have errors, or come from a known user. For example, the +// following filter expression targets traces that pass through api.example.com: +// +// service("api.example.com") +// +// This filter expression finds traces that have an annotation named account +// with the value 12345: +// +// annotation.account = "12345" +// +// For a full list of indexed fields and keywords that you can use in filter +// expressions, see Using Filter Expressions (https://docs.aws.amazon.com/xray/latest/devguide/xray-console-filters.html) +// in the AWS X-Ray Developer Guide. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation GetTraceSummaries for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/GetTraceSummaries +func (c *XRay) GetTraceSummaries(input *GetTraceSummariesInput) (*GetTraceSummariesOutput, error) { + req, out := c.GetTraceSummariesRequest(input) + return out, req.Send() +} + +// GetTraceSummariesWithContext is the same as GetTraceSummaries with the addition of +// the ability to pass a context and additional request options. +// +// See GetTraceSummaries for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetTraceSummariesWithContext(ctx aws.Context, input *GetTraceSummariesInput, opts ...request.Option) (*GetTraceSummariesOutput, error) { + req, out := c.GetTraceSummariesRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// GetTraceSummariesPages iterates over the pages of a GetTraceSummaries operation, +// calling the "fn" function with the response data for each page. To stop +// iterating, return false from the fn function. +// +// See GetTraceSummaries method for more information on how to use this operation. +// +// Note: This operation can generate multiple requests to a service. +// +// // Example iterating over at most 3 pages of a GetTraceSummaries operation. +// pageNum := 0 +// err := client.GetTraceSummariesPages(params, +// func(page *GetTraceSummariesOutput, lastPage bool) bool { +// pageNum++ +// fmt.Println(page) +// return pageNum <= 3 +// }) +// +func (c *XRay) GetTraceSummariesPages(input *GetTraceSummariesInput, fn func(*GetTraceSummariesOutput, bool) bool) error { + return c.GetTraceSummariesPagesWithContext(aws.BackgroundContext(), input, fn) +} + +// GetTraceSummariesPagesWithContext same as GetTraceSummariesPages except +// it takes a Context and allows setting request options on the pages. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) GetTraceSummariesPagesWithContext(ctx aws.Context, input *GetTraceSummariesInput, fn func(*GetTraceSummariesOutput, bool) bool, opts ...request.Option) error { + p := request.Pagination{ + NewRequest: func() (*request.Request, error) { + var inCpy *GetTraceSummariesInput + if input != nil { + tmp := *input + inCpy = &tmp + } + req, _ := c.GetTraceSummariesRequest(inCpy) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return req, nil + }, + } + + cont := true + for p.Next() && cont { + cont = fn(p.Page().(*GetTraceSummariesOutput), !p.HasNextPage()) + } + return p.Err() +} + +const opPutEncryptionConfig = "PutEncryptionConfig" + +// PutEncryptionConfigRequest generates a "aws/request.Request" representing the +// client's request for the PutEncryptionConfig operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See PutEncryptionConfig for more information on using the PutEncryptionConfig +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the PutEncryptionConfigRequest method. +// req, resp := client.PutEncryptionConfigRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/PutEncryptionConfig +func (c *XRay) PutEncryptionConfigRequest(input *PutEncryptionConfigInput) (req *request.Request, output *PutEncryptionConfigOutput) { + op := &request.Operation{ + Name: opPutEncryptionConfig, + HTTPMethod: "POST", + HTTPPath: "/PutEncryptionConfig", + } + + if input == nil { + input = &PutEncryptionConfigInput{} + } + + output = &PutEncryptionConfigOutput{} + req = c.newRequest(op, input, output) + return +} + +// PutEncryptionConfig API operation for AWS X-Ray. +// +// Updates the encryption configuration for X-Ray data. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation PutEncryptionConfig for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/PutEncryptionConfig +func (c *XRay) PutEncryptionConfig(input *PutEncryptionConfigInput) (*PutEncryptionConfigOutput, error) { + req, out := c.PutEncryptionConfigRequest(input) + return out, req.Send() +} + +// PutEncryptionConfigWithContext is the same as PutEncryptionConfig with the addition of +// the ability to pass a context and additional request options. +// +// See PutEncryptionConfig for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) PutEncryptionConfigWithContext(ctx aws.Context, input *PutEncryptionConfigInput, opts ...request.Option) (*PutEncryptionConfigOutput, error) { + req, out := c.PutEncryptionConfigRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opPutTelemetryRecords = "PutTelemetryRecords" + +// PutTelemetryRecordsRequest generates a "aws/request.Request" representing the +// client's request for the PutTelemetryRecords operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See PutTelemetryRecords for more information on using the PutTelemetryRecords +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the PutTelemetryRecordsRequest method. +// req, resp := client.PutTelemetryRecordsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/PutTelemetryRecords +func (c *XRay) PutTelemetryRecordsRequest(input *PutTelemetryRecordsInput) (req *request.Request, output *PutTelemetryRecordsOutput) { + op := &request.Operation{ + Name: opPutTelemetryRecords, + HTTPMethod: "POST", + HTTPPath: "/TelemetryRecords", + } + + if input == nil { + input = &PutTelemetryRecordsInput{} + } + + output = &PutTelemetryRecordsOutput{} + req = c.newRequest(op, input, output) + req.Handlers.Unmarshal.Swap(restjson.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler) + return +} + +// PutTelemetryRecords API operation for AWS X-Ray. +// +// Used by the AWS X-Ray daemon to upload telemetry. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation PutTelemetryRecords for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/PutTelemetryRecords +func (c *XRay) PutTelemetryRecords(input *PutTelemetryRecordsInput) (*PutTelemetryRecordsOutput, error) { + req, out := c.PutTelemetryRecordsRequest(input) + return out, req.Send() +} + +// PutTelemetryRecordsWithContext is the same as PutTelemetryRecords with the addition of +// the ability to pass a context and additional request options. +// +// See PutTelemetryRecords for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) PutTelemetryRecordsWithContext(ctx aws.Context, input *PutTelemetryRecordsInput, opts ...request.Option) (*PutTelemetryRecordsOutput, error) { + req, out := c.PutTelemetryRecordsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opPutTraceSegments = "PutTraceSegments" + +// PutTraceSegmentsRequest generates a "aws/request.Request" representing the +// client's request for the PutTraceSegments operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See PutTraceSegments for more information on using the PutTraceSegments +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the PutTraceSegmentsRequest method. +// req, resp := client.PutTraceSegmentsRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/PutTraceSegments +func (c *XRay) PutTraceSegmentsRequest(input *PutTraceSegmentsInput) (req *request.Request, output *PutTraceSegmentsOutput) { + op := &request.Operation{ + Name: opPutTraceSegments, + HTTPMethod: "POST", + HTTPPath: "/TraceSegments", + } + + if input == nil { + input = &PutTraceSegmentsInput{} + } + + output = &PutTraceSegmentsOutput{} + req = c.newRequest(op, input, output) + return +} + +// PutTraceSegments API operation for AWS X-Ray. +// +// Uploads segment documents to AWS X-Ray. The X-Ray SDK generates segment documents +// and sends them to the X-Ray daemon, which uploads them in batches. A segment +// document can be a completed segment, an in-progress segment, or an array +// of subsegments. +// +// Segments must include the following fields. For the full segment document +// schema, see AWS X-Ray Segment Documents (https://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html) +// in the AWS X-Ray Developer Guide. +// +// Required Segment Document Fields +// +// * name - The name of the service that handled the request. +// +// * id - A 64-bit identifier for the segment, unique among segments in the +// same trace, in 16 hexadecimal digits. +// +// * trace_id - A unique identifier that connects all segments and subsegments +// originating from a single client request. +// +// * start_time - Time the segment or subsegment was created, in floating +// point seconds in epoch time, accurate to milliseconds. For example, 1480615200.010 +// or 1.480615200010E9. +// +// * end_time - Time the segment or subsegment was closed. For example, 1480615200.090 +// or 1.480615200090E9. Specify either an end_time or in_progress. +// +// * in_progress - Set to true instead of specifying an end_time to record +// that a segment has been started, but is not complete. Send an in progress +// segment when your application receives a request that will take a long +// time to serve, to trace the fact that the request was received. When the +// response is sent, send the complete segment to overwrite the in-progress +// segment. +// +// A trace_id consists of three numbers separated by hyphens. For example, 1-58406520-a006649127e371903a2de979. +// This includes: +// +// Trace ID Format +// +// * The version number, i.e. 1. +// +// * The time of the original request, in Unix epoch time, in 8 hexadecimal +// digits. For example, 10:00AM December 2nd, 2016 PST in epoch time is 1480615200 +// seconds, or 58406520 in hexadecimal. +// +// * A 96-bit identifier for the trace, globally unique, in 24 hexadecimal +// digits. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation PutTraceSegments for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/PutTraceSegments +func (c *XRay) PutTraceSegments(input *PutTraceSegmentsInput) (*PutTraceSegmentsOutput, error) { + req, out := c.PutTraceSegmentsRequest(input) + return out, req.Send() +} + +// PutTraceSegmentsWithContext is the same as PutTraceSegments with the addition of +// the ability to pass a context and additional request options. +// +// See PutTraceSegments for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) PutTraceSegmentsWithContext(ctx aws.Context, input *PutTraceSegmentsInput, opts ...request.Option) (*PutTraceSegmentsOutput, error) { + req, out := c.PutTraceSegmentsRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateGroup = "UpdateGroup" + +// UpdateGroupRequest generates a "aws/request.Request" representing the +// client's request for the UpdateGroup operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateGroup for more information on using the UpdateGroup +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateGroupRequest method. +// req, resp := client.UpdateGroupRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/UpdateGroup +func (c *XRay) UpdateGroupRequest(input *UpdateGroupInput) (req *request.Request, output *UpdateGroupOutput) { + op := &request.Operation{ + Name: opUpdateGroup, + HTTPMethod: "POST", + HTTPPath: "/UpdateGroup", + } + + if input == nil { + input = &UpdateGroupInput{} + } + + output = &UpdateGroupOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateGroup API operation for AWS X-Ray. +// +// Updates a group resource. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation UpdateGroup for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/UpdateGroup +func (c *XRay) UpdateGroup(input *UpdateGroupInput) (*UpdateGroupOutput, error) { + req, out := c.UpdateGroupRequest(input) + return out, req.Send() +} + +// UpdateGroupWithContext is the same as UpdateGroup with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateGroup for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) UpdateGroupWithContext(ctx aws.Context, input *UpdateGroupInput, opts ...request.Option) (*UpdateGroupOutput, error) { + req, out := c.UpdateGroupRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +const opUpdateSamplingRule = "UpdateSamplingRule" + +// UpdateSamplingRuleRequest generates a "aws/request.Request" representing the +// client's request for the UpdateSamplingRule operation. The "output" return +// value will be populated with the request's response once the request completes +// successfully. +// +// Use "Send" method on the returned Request to send the API call to the service. +// the "output" return value is not valid until after Send returns without error. +// +// See UpdateSamplingRule for more information on using the UpdateSamplingRule +// API call, and error handling. +// +// This method is useful when you want to inject custom logic or configuration +// into the SDK's request lifecycle. Such as custom headers, or retry logic. +// +// +// // Example sending a request using the UpdateSamplingRuleRequest method. +// req, resp := client.UpdateSamplingRuleRequest(params) +// +// err := req.Send() +// if err == nil { // resp is now filled +// fmt.Println(resp) +// } +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/UpdateSamplingRule +func (c *XRay) UpdateSamplingRuleRequest(input *UpdateSamplingRuleInput) (req *request.Request, output *UpdateSamplingRuleOutput) { + op := &request.Operation{ + Name: opUpdateSamplingRule, + HTTPMethod: "POST", + HTTPPath: "/UpdateSamplingRule", + } + + if input == nil { + input = &UpdateSamplingRuleInput{} + } + + output = &UpdateSamplingRuleOutput{} + req = c.newRequest(op, input, output) + return +} + +// UpdateSamplingRule API operation for AWS X-Ray. +// +// Modifies a sampling rule's configuration. +// +// Returns awserr.Error for service API and SDK errors. Use runtime type assertions +// with awserr.Error's Code and Message methods to get detailed information about +// the error. +// +// See the AWS API reference guide for AWS X-Ray's +// API operation UpdateSamplingRule for usage and error information. +// +// Returned Error Codes: +// * ErrCodeInvalidRequestException "InvalidRequestException" +// The request is missing required parameters or has invalid parameters. +// +// * ErrCodeThrottledException "ThrottledException" +// The request exceeds the maximum number of requests per second. +// +// See also, https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12/UpdateSamplingRule +func (c *XRay) UpdateSamplingRule(input *UpdateSamplingRuleInput) (*UpdateSamplingRuleOutput, error) { + req, out := c.UpdateSamplingRuleRequest(input) + return out, req.Send() +} + +// UpdateSamplingRuleWithContext is the same as UpdateSamplingRule with the addition of +// the ability to pass a context and additional request options. +// +// See UpdateSamplingRule for details on how to use this API operation. +// +// The context must be non-nil and will be used for request cancellation. If +// the context is nil a panic will occur. In the future the SDK may create +// sub-contexts for http.Requests. See https://golang.org/pkg/context/ +// for more information on using Contexts. +func (c *XRay) UpdateSamplingRuleWithContext(ctx aws.Context, input *UpdateSamplingRuleInput, opts ...request.Option) (*UpdateSamplingRuleOutput, error) { + req, out := c.UpdateSamplingRuleRequest(input) + req.SetContext(ctx) + req.ApplyOptions(opts...) + return out, req.Send() +} + +// An alias for an edge. +type Alias struct { + _ struct{} `type:"structure"` + + // The canonical name of the alias. + Name *string `type:"string"` + + // A list of names for the alias, including the canonical name. + Names []*string `type:"list"` + + // The type of the alias. + Type *string `type:"string"` +} + +// String returns the string representation +func (s Alias) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Alias) GoString() string { + return s.String() +} + +// SetName sets the Name field's value. +func (s *Alias) SetName(v string) *Alias { + s.Name = &v + return s +} + +// SetNames sets the Names field's value. +func (s *Alias) SetNames(v []*string) *Alias { + s.Names = v + return s +} + +// SetType sets the Type field's value. +func (s *Alias) SetType(v string) *Alias { + s.Type = &v + return s +} + +// Value of a segment annotation. Has one of three value types: Number, Boolean +// or String. +type AnnotationValue struct { + _ struct{} `type:"structure"` + + // Value for a Boolean annotation. + BooleanValue *bool `type:"boolean"` + + // Value for a Number annotation. + NumberValue *float64 `type:"double"` + + // Value for a String annotation. + StringValue *string `type:"string"` +} + +// String returns the string representation +func (s AnnotationValue) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AnnotationValue) GoString() string { + return s.String() +} + +// SetBooleanValue sets the BooleanValue field's value. +func (s *AnnotationValue) SetBooleanValue(v bool) *AnnotationValue { + s.BooleanValue = &v + return s +} + +// SetNumberValue sets the NumberValue field's value. +func (s *AnnotationValue) SetNumberValue(v float64) *AnnotationValue { + s.NumberValue = &v + return s +} + +// SetStringValue sets the StringValue field's value. +func (s *AnnotationValue) SetStringValue(v string) *AnnotationValue { + s.StringValue = &v + return s +} + +// A list of availability zones corresponding to the segments in a trace. +type AvailabilityZoneDetail struct { + _ struct{} `type:"structure"` + + // The name of a corresponding availability zone. + Name *string `type:"string"` +} + +// String returns the string representation +func (s AvailabilityZoneDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s AvailabilityZoneDetail) GoString() string { + return s.String() +} + +// SetName sets the Name field's value. +func (s *AvailabilityZoneDetail) SetName(v string) *AvailabilityZoneDetail { + s.Name = &v + return s +} + +type BackendConnectionErrors struct { + _ struct{} `type:"structure"` + + ConnectionRefusedCount *int64 `type:"integer"` + + HTTPCode4XXCount *int64 `type:"integer"` + + HTTPCode5XXCount *int64 `type:"integer"` + + OtherCount *int64 `type:"integer"` + + TimeoutCount *int64 `type:"integer"` + + UnknownHostCount *int64 `type:"integer"` +} + +// String returns the string representation +func (s BackendConnectionErrors) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BackendConnectionErrors) GoString() string { + return s.String() +} + +// SetConnectionRefusedCount sets the ConnectionRefusedCount field's value. +func (s *BackendConnectionErrors) SetConnectionRefusedCount(v int64) *BackendConnectionErrors { + s.ConnectionRefusedCount = &v + return s +} + +// SetHTTPCode4XXCount sets the HTTPCode4XXCount field's value. +func (s *BackendConnectionErrors) SetHTTPCode4XXCount(v int64) *BackendConnectionErrors { + s.HTTPCode4XXCount = &v + return s +} + +// SetHTTPCode5XXCount sets the HTTPCode5XXCount field's value. +func (s *BackendConnectionErrors) SetHTTPCode5XXCount(v int64) *BackendConnectionErrors { + s.HTTPCode5XXCount = &v + return s +} + +// SetOtherCount sets the OtherCount field's value. +func (s *BackendConnectionErrors) SetOtherCount(v int64) *BackendConnectionErrors { + s.OtherCount = &v + return s +} + +// SetTimeoutCount sets the TimeoutCount field's value. +func (s *BackendConnectionErrors) SetTimeoutCount(v int64) *BackendConnectionErrors { + s.TimeoutCount = &v + return s +} + +// SetUnknownHostCount sets the UnknownHostCount field's value. +func (s *BackendConnectionErrors) SetUnknownHostCount(v int64) *BackendConnectionErrors { + s.UnknownHostCount = &v + return s +} + +type BatchGetTracesInput struct { + _ struct{} `type:"structure"` + + // Pagination token. Not used. + NextToken *string `type:"string"` + + // Specify the trace IDs of requests for which to retrieve segments. + // + // TraceIds is a required field + TraceIds []*string `type:"list" required:"true"` +} + +// String returns the string representation +func (s BatchGetTracesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BatchGetTracesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *BatchGetTracesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "BatchGetTracesInput"} + if s.TraceIds == nil { + invalidParams.Add(request.NewErrParamRequired("TraceIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetNextToken sets the NextToken field's value. +func (s *BatchGetTracesInput) SetNextToken(v string) *BatchGetTracesInput { + s.NextToken = &v + return s +} + +// SetTraceIds sets the TraceIds field's value. +func (s *BatchGetTracesInput) SetTraceIds(v []*string) *BatchGetTracesInput { + s.TraceIds = v + return s +} + +type BatchGetTracesOutput struct { + _ struct{} `type:"structure"` + + // Pagination token. Not used. + NextToken *string `type:"string"` + + // Full traces for the specified requests. + Traces []*Trace `type:"list"` + + // Trace IDs of requests that haven't been processed. + UnprocessedTraceIds []*string `type:"list"` +} + +// String returns the string representation +func (s BatchGetTracesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s BatchGetTracesOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *BatchGetTracesOutput) SetNextToken(v string) *BatchGetTracesOutput { + s.NextToken = &v + return s +} + +// SetTraces sets the Traces field's value. +func (s *BatchGetTracesOutput) SetTraces(v []*Trace) *BatchGetTracesOutput { + s.Traces = v + return s +} + +// SetUnprocessedTraceIds sets the UnprocessedTraceIds field's value. +func (s *BatchGetTracesOutput) SetUnprocessedTraceIds(v []*string) *BatchGetTracesOutput { + s.UnprocessedTraceIds = v + return s +} + +type CreateGroupInput struct { + _ struct{} `type:"structure"` + + // The filter expression defining criteria by which to group traces. + FilterExpression *string `type:"string"` + + // The case-sensitive name of the new group. Default is a reserved name and + // names must be unique. + // + // GroupName is a required field + GroupName *string `min:"1" type:"string" required:"true"` +} + +// String returns the string representation +func (s CreateGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateGroupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateGroupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateGroupInput"} + if s.GroupName == nil { + invalidParams.Add(request.NewErrParamRequired("GroupName")) + } + if s.GroupName != nil && len(*s.GroupName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupName", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetFilterExpression sets the FilterExpression field's value. +func (s *CreateGroupInput) SetFilterExpression(v string) *CreateGroupInput { + s.FilterExpression = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *CreateGroupInput) SetGroupName(v string) *CreateGroupInput { + s.GroupName = &v + return s +} + +type CreateGroupOutput struct { + _ struct{} `type:"structure"` + + // The group that was created. Contains the name of the group that was created, + // the ARN of the group that was generated based on the group name, and the + // filter expression that was assigned to the group. + Group *Group `type:"structure"` +} + +// String returns the string representation +func (s CreateGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateGroupOutput) GoString() string { + return s.String() +} + +// SetGroup sets the Group field's value. +func (s *CreateGroupOutput) SetGroup(v *Group) *CreateGroupOutput { + s.Group = v + return s +} + +type CreateSamplingRuleInput struct { + _ struct{} `type:"structure"` + + // The rule definition. + // + // SamplingRule is a required field + SamplingRule *SamplingRule `type:"structure" required:"true"` +} + +// String returns the string representation +func (s CreateSamplingRuleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSamplingRuleInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *CreateSamplingRuleInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "CreateSamplingRuleInput"} + if s.SamplingRule == nil { + invalidParams.Add(request.NewErrParamRequired("SamplingRule")) + } + if s.SamplingRule != nil { + if err := s.SamplingRule.Validate(); err != nil { + invalidParams.AddNested("SamplingRule", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetSamplingRule sets the SamplingRule field's value. +func (s *CreateSamplingRuleInput) SetSamplingRule(v *SamplingRule) *CreateSamplingRuleInput { + s.SamplingRule = v + return s +} + +type CreateSamplingRuleOutput struct { + _ struct{} `type:"structure"` + + // The saved rule definition and metadata. + SamplingRuleRecord *SamplingRuleRecord `type:"structure"` +} + +// String returns the string representation +func (s CreateSamplingRuleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s CreateSamplingRuleOutput) GoString() string { + return s.String() +} + +// SetSamplingRuleRecord sets the SamplingRuleRecord field's value. +func (s *CreateSamplingRuleOutput) SetSamplingRuleRecord(v *SamplingRuleRecord) *CreateSamplingRuleOutput { + s.SamplingRuleRecord = v + return s +} + +type DeleteGroupInput struct { + _ struct{} `type:"structure"` + + // The ARN of the group that was generated on creation. + GroupARN *string `min:"1" type:"string"` + + // The case-sensitive name of the group. + GroupName *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s DeleteGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteGroupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *DeleteGroupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "DeleteGroupInput"} + if s.GroupARN != nil && len(*s.GroupARN) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupARN", 1)) + } + if s.GroupName != nil && len(*s.GroupName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupName", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGroupARN sets the GroupARN field's value. +func (s *DeleteGroupInput) SetGroupARN(v string) *DeleteGroupInput { + s.GroupARN = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *DeleteGroupInput) SetGroupName(v string) *DeleteGroupInput { + s.GroupName = &v + return s +} + +type DeleteGroupOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s DeleteGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteGroupOutput) GoString() string { + return s.String() +} + +type DeleteSamplingRuleInput struct { + _ struct{} `type:"structure"` + + // The ARN of the sampling rule. Specify a rule by either name or ARN, but not + // both. + RuleARN *string `type:"string"` + + // The name of the sampling rule. Specify a rule by either name or ARN, but + // not both. + RuleName *string `type:"string"` +} + +// String returns the string representation +func (s DeleteSamplingRuleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSamplingRuleInput) GoString() string { + return s.String() +} + +// SetRuleARN sets the RuleARN field's value. +func (s *DeleteSamplingRuleInput) SetRuleARN(v string) *DeleteSamplingRuleInput { + s.RuleARN = &v + return s +} + +// SetRuleName sets the RuleName field's value. +func (s *DeleteSamplingRuleInput) SetRuleName(v string) *DeleteSamplingRuleInput { + s.RuleName = &v + return s +} + +type DeleteSamplingRuleOutput struct { + _ struct{} `type:"structure"` + + // The deleted rule definition and metadata. + SamplingRuleRecord *SamplingRuleRecord `type:"structure"` +} + +// String returns the string representation +func (s DeleteSamplingRuleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s DeleteSamplingRuleOutput) GoString() string { + return s.String() +} + +// SetSamplingRuleRecord sets the SamplingRuleRecord field's value. +func (s *DeleteSamplingRuleOutput) SetSamplingRuleRecord(v *SamplingRuleRecord) *DeleteSamplingRuleOutput { + s.SamplingRuleRecord = v + return s +} + +// Information about a connection between two services. +type Edge struct { + _ struct{} `type:"structure"` + + // Aliases for the edge. + Aliases []*Alias `type:"list"` + + // The end time of the last segment on the edge. + EndTime *time.Time `type:"timestamp"` + + // Identifier of the edge. Unique within a service map. + ReferenceId *int64 `type:"integer"` + + // A histogram that maps the spread of client response times on an edge. + ResponseTimeHistogram []*HistogramEntry `type:"list"` + + // The start time of the first segment on the edge. + StartTime *time.Time `type:"timestamp"` + + // Response statistics for segments on the edge. + SummaryStatistics *EdgeStatistics `type:"structure"` +} + +// String returns the string representation +func (s Edge) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Edge) GoString() string { + return s.String() +} + +// SetAliases sets the Aliases field's value. +func (s *Edge) SetAliases(v []*Alias) *Edge { + s.Aliases = v + return s +} + +// SetEndTime sets the EndTime field's value. +func (s *Edge) SetEndTime(v time.Time) *Edge { + s.EndTime = &v + return s +} + +// SetReferenceId sets the ReferenceId field's value. +func (s *Edge) SetReferenceId(v int64) *Edge { + s.ReferenceId = &v + return s +} + +// SetResponseTimeHistogram sets the ResponseTimeHistogram field's value. +func (s *Edge) SetResponseTimeHistogram(v []*HistogramEntry) *Edge { + s.ResponseTimeHistogram = v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *Edge) SetStartTime(v time.Time) *Edge { + s.StartTime = &v + return s +} + +// SetSummaryStatistics sets the SummaryStatistics field's value. +func (s *Edge) SetSummaryStatistics(v *EdgeStatistics) *Edge { + s.SummaryStatistics = v + return s +} + +// Response statistics for an edge. +type EdgeStatistics struct { + _ struct{} `type:"structure"` + + // Information about requests that failed with a 4xx Client Error status code. + ErrorStatistics *ErrorStatistics `type:"structure"` + + // Information about requests that failed with a 5xx Server Error status code. + FaultStatistics *FaultStatistics `type:"structure"` + + // The number of requests that completed with a 2xx Success status code. + OkCount *int64 `type:"long"` + + // The total number of completed requests. + TotalCount *int64 `type:"long"` + + // The aggregate response time of completed requests. + TotalResponseTime *float64 `type:"double"` +} + +// String returns the string representation +func (s EdgeStatistics) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EdgeStatistics) GoString() string { + return s.String() +} + +// SetErrorStatistics sets the ErrorStatistics field's value. +func (s *EdgeStatistics) SetErrorStatistics(v *ErrorStatistics) *EdgeStatistics { + s.ErrorStatistics = v + return s +} + +// SetFaultStatistics sets the FaultStatistics field's value. +func (s *EdgeStatistics) SetFaultStatistics(v *FaultStatistics) *EdgeStatistics { + s.FaultStatistics = v + return s +} + +// SetOkCount sets the OkCount field's value. +func (s *EdgeStatistics) SetOkCount(v int64) *EdgeStatistics { + s.OkCount = &v + return s +} + +// SetTotalCount sets the TotalCount field's value. +func (s *EdgeStatistics) SetTotalCount(v int64) *EdgeStatistics { + s.TotalCount = &v + return s +} + +// SetTotalResponseTime sets the TotalResponseTime field's value. +func (s *EdgeStatistics) SetTotalResponseTime(v float64) *EdgeStatistics { + s.TotalResponseTime = &v + return s +} + +// A configuration document that specifies encryption configuration settings. +type EncryptionConfig struct { + _ struct{} `type:"structure"` + + // The ID of the customer master key (CMK) used for encryption, if applicable. + KeyId *string `type:"string"` + + // The encryption status. While the status is UPDATING, X-Ray may encrypt data + // with a combination of the new and old settings. + Status *string `type:"string" enum:"EncryptionStatus"` + + // The type of encryption. Set to KMS for encryption with CMKs. Set to NONE + // for default encryption. + Type *string `type:"string" enum:"EncryptionType"` +} + +// String returns the string representation +func (s EncryptionConfig) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s EncryptionConfig) GoString() string { + return s.String() +} + +// SetKeyId sets the KeyId field's value. +func (s *EncryptionConfig) SetKeyId(v string) *EncryptionConfig { + s.KeyId = &v + return s +} + +// SetStatus sets the Status field's value. +func (s *EncryptionConfig) SetStatus(v string) *EncryptionConfig { + s.Status = &v + return s +} + +// SetType sets the Type field's value. +func (s *EncryptionConfig) SetType(v string) *EncryptionConfig { + s.Type = &v + return s +} + +// The root cause of a trace summary error. +type ErrorRootCause struct { + _ struct{} `type:"structure"` + + // A list of services corresponding to an error. A service identifies a segment + // and it contains a name, account ID, type, and inferred flag. + Services []*ErrorRootCauseService `type:"list"` +} + +// String returns the string representation +func (s ErrorRootCause) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ErrorRootCause) GoString() string { + return s.String() +} + +// SetServices sets the Services field's value. +func (s *ErrorRootCause) SetServices(v []*ErrorRootCauseService) *ErrorRootCause { + s.Services = v + return s +} + +// A collection of segments and corresponding subsegments associated to a trace +// summary error. +type ErrorRootCauseEntity struct { + _ struct{} `type:"structure"` + + // The types and messages of the exceptions. + Exceptions []*RootCauseException `type:"list"` + + // The name of the entity. + Name *string `type:"string"` + + // A flag that denotes a remote subsegment. + Remote *bool `type:"boolean"` +} + +// String returns the string representation +func (s ErrorRootCauseEntity) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ErrorRootCauseEntity) GoString() string { + return s.String() +} + +// SetExceptions sets the Exceptions field's value. +func (s *ErrorRootCauseEntity) SetExceptions(v []*RootCauseException) *ErrorRootCauseEntity { + s.Exceptions = v + return s +} + +// SetName sets the Name field's value. +func (s *ErrorRootCauseEntity) SetName(v string) *ErrorRootCauseEntity { + s.Name = &v + return s +} + +// SetRemote sets the Remote field's value. +func (s *ErrorRootCauseEntity) SetRemote(v bool) *ErrorRootCauseEntity { + s.Remote = &v + return s +} + +// A collection of fields identifying the services in a trace summary error. +type ErrorRootCauseService struct { + _ struct{} `type:"structure"` + + // The account ID associated to the service. + AccountId *string `type:"string"` + + // The path of root cause entities found on the service. + EntityPath []*ErrorRootCauseEntity `type:"list"` + + // A Boolean value indicating if the service is inferred from the trace. + Inferred *bool `type:"boolean"` + + // The service name. + Name *string `type:"string"` + + // A collection of associated service names. + Names []*string `type:"list"` + + // The type associated to the service. + Type *string `type:"string"` +} + +// String returns the string representation +func (s ErrorRootCauseService) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ErrorRootCauseService) GoString() string { + return s.String() +} + +// SetAccountId sets the AccountId field's value. +func (s *ErrorRootCauseService) SetAccountId(v string) *ErrorRootCauseService { + s.AccountId = &v + return s +} + +// SetEntityPath sets the EntityPath field's value. +func (s *ErrorRootCauseService) SetEntityPath(v []*ErrorRootCauseEntity) *ErrorRootCauseService { + s.EntityPath = v + return s +} + +// SetInferred sets the Inferred field's value. +func (s *ErrorRootCauseService) SetInferred(v bool) *ErrorRootCauseService { + s.Inferred = &v + return s +} + +// SetName sets the Name field's value. +func (s *ErrorRootCauseService) SetName(v string) *ErrorRootCauseService { + s.Name = &v + return s +} + +// SetNames sets the Names field's value. +func (s *ErrorRootCauseService) SetNames(v []*string) *ErrorRootCauseService { + s.Names = v + return s +} + +// SetType sets the Type field's value. +func (s *ErrorRootCauseService) SetType(v string) *ErrorRootCauseService { + s.Type = &v + return s +} + +// Information about requests that failed with a 4xx Client Error status code. +type ErrorStatistics struct { + _ struct{} `type:"structure"` + + // The number of requests that failed with untracked 4xx Client Error status + // codes. + OtherCount *int64 `type:"long"` + + // The number of requests that failed with a 419 throttling status code. + ThrottleCount *int64 `type:"long"` + + // The total number of requests that failed with a 4xx Client Error status code. + TotalCount *int64 `type:"long"` +} + +// String returns the string representation +func (s ErrorStatistics) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ErrorStatistics) GoString() string { + return s.String() +} + +// SetOtherCount sets the OtherCount field's value. +func (s *ErrorStatistics) SetOtherCount(v int64) *ErrorStatistics { + s.OtherCount = &v + return s +} + +// SetThrottleCount sets the ThrottleCount field's value. +func (s *ErrorStatistics) SetThrottleCount(v int64) *ErrorStatistics { + s.ThrottleCount = &v + return s +} + +// SetTotalCount sets the TotalCount field's value. +func (s *ErrorStatistics) SetTotalCount(v int64) *ErrorStatistics { + s.TotalCount = &v + return s +} + +// The root cause information for a trace summary fault. +type FaultRootCause struct { + _ struct{} `type:"structure"` + + // A list of corresponding services. A service identifies a segment and it contains + // a name, account ID, type, and inferred flag. + Services []*FaultRootCauseService `type:"list"` +} + +// String returns the string representation +func (s FaultRootCause) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FaultRootCause) GoString() string { + return s.String() +} + +// SetServices sets the Services field's value. +func (s *FaultRootCause) SetServices(v []*FaultRootCauseService) *FaultRootCause { + s.Services = v + return s +} + +// A collection of segments and corresponding subsegments associated to a trace +// summary fault error. +type FaultRootCauseEntity struct { + _ struct{} `type:"structure"` + + // The types and messages of the exceptions. + Exceptions []*RootCauseException `type:"list"` + + // The name of the entity. + Name *string `type:"string"` + + // A flag that denotes a remote subsegment. + Remote *bool `type:"boolean"` +} + +// String returns the string representation +func (s FaultRootCauseEntity) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FaultRootCauseEntity) GoString() string { + return s.String() +} + +// SetExceptions sets the Exceptions field's value. +func (s *FaultRootCauseEntity) SetExceptions(v []*RootCauseException) *FaultRootCauseEntity { + s.Exceptions = v + return s +} + +// SetName sets the Name field's value. +func (s *FaultRootCauseEntity) SetName(v string) *FaultRootCauseEntity { + s.Name = &v + return s +} + +// SetRemote sets the Remote field's value. +func (s *FaultRootCauseEntity) SetRemote(v bool) *FaultRootCauseEntity { + s.Remote = &v + return s +} + +// A collection of fields identifying the services in a trace summary fault. +type FaultRootCauseService struct { + _ struct{} `type:"structure"` + + // The account ID associated to the service. + AccountId *string `type:"string"` + + // The path of root cause entities found on the service. + EntityPath []*FaultRootCauseEntity `type:"list"` + + // A Boolean value indicating if the service is inferred from the trace. + Inferred *bool `type:"boolean"` + + // The service name. + Name *string `type:"string"` + + // A collection of associated service names. + Names []*string `type:"list"` + + // The type associated to the service. + Type *string `type:"string"` +} + +// String returns the string representation +func (s FaultRootCauseService) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FaultRootCauseService) GoString() string { + return s.String() +} + +// SetAccountId sets the AccountId field's value. +func (s *FaultRootCauseService) SetAccountId(v string) *FaultRootCauseService { + s.AccountId = &v + return s +} + +// SetEntityPath sets the EntityPath field's value. +func (s *FaultRootCauseService) SetEntityPath(v []*FaultRootCauseEntity) *FaultRootCauseService { + s.EntityPath = v + return s +} + +// SetInferred sets the Inferred field's value. +func (s *FaultRootCauseService) SetInferred(v bool) *FaultRootCauseService { + s.Inferred = &v + return s +} + +// SetName sets the Name field's value. +func (s *FaultRootCauseService) SetName(v string) *FaultRootCauseService { + s.Name = &v + return s +} + +// SetNames sets the Names field's value. +func (s *FaultRootCauseService) SetNames(v []*string) *FaultRootCauseService { + s.Names = v + return s +} + +// SetType sets the Type field's value. +func (s *FaultRootCauseService) SetType(v string) *FaultRootCauseService { + s.Type = &v + return s +} + +// Information about requests that failed with a 5xx Server Error status code. +type FaultStatistics struct { + _ struct{} `type:"structure"` + + // The number of requests that failed with untracked 5xx Server Error status + // codes. + OtherCount *int64 `type:"long"` + + // The total number of requests that failed with a 5xx Server Error status code. + TotalCount *int64 `type:"long"` +} + +// String returns the string representation +func (s FaultStatistics) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s FaultStatistics) GoString() string { + return s.String() +} + +// SetOtherCount sets the OtherCount field's value. +func (s *FaultStatistics) SetOtherCount(v int64) *FaultStatistics { + s.OtherCount = &v + return s +} + +// SetTotalCount sets the TotalCount field's value. +func (s *FaultStatistics) SetTotalCount(v int64) *FaultStatistics { + s.TotalCount = &v + return s +} + +type GetEncryptionConfigInput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s GetEncryptionConfigInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetEncryptionConfigInput) GoString() string { + return s.String() +} + +type GetEncryptionConfigOutput struct { + _ struct{} `type:"structure"` + + // The encryption configuration document. + EncryptionConfig *EncryptionConfig `type:"structure"` +} + +// String returns the string representation +func (s GetEncryptionConfigOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetEncryptionConfigOutput) GoString() string { + return s.String() +} + +// SetEncryptionConfig sets the EncryptionConfig field's value. +func (s *GetEncryptionConfigOutput) SetEncryptionConfig(v *EncryptionConfig) *GetEncryptionConfigOutput { + s.EncryptionConfig = v + return s +} + +type GetGroupInput struct { + _ struct{} `type:"structure"` + + // The ARN of the group that was generated on creation. + GroupARN *string `min:"1" type:"string"` + + // The case-sensitive name of the group. + GroupName *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s GetGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetGroupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetGroupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetGroupInput"} + if s.GroupARN != nil && len(*s.GroupARN) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupARN", 1)) + } + if s.GroupName != nil && len(*s.GroupName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupName", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetGroupARN sets the GroupARN field's value. +func (s *GetGroupInput) SetGroupARN(v string) *GetGroupInput { + s.GroupARN = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *GetGroupInput) SetGroupName(v string) *GetGroupInput { + s.GroupName = &v + return s +} + +type GetGroupOutput struct { + _ struct{} `type:"structure"` + + // The group that was requested. Contains the name of the group, the ARN of + // the group, and the filter expression that assigned to the group. + Group *Group `type:"structure"` +} + +// String returns the string representation +func (s GetGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetGroupOutput) GoString() string { + return s.String() +} + +// SetGroup sets the Group field's value. +func (s *GetGroupOutput) SetGroup(v *Group) *GetGroupOutput { + s.Group = v + return s +} + +type GetGroupsInput struct { + _ struct{} `type:"structure"` + + // Pagination token. Not used. + NextToken *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s GetGroupsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetGroupsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetGroupsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetGroupsInput"} + if s.NextToken != nil && len(*s.NextToken) < 1 { + invalidParams.Add(request.NewErrParamMinLen("NextToken", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetNextToken sets the NextToken field's value. +func (s *GetGroupsInput) SetNextToken(v string) *GetGroupsInput { + s.NextToken = &v + return s +} + +type GetGroupsOutput struct { + _ struct{} `type:"structure"` + + // The collection of all active groups. + Groups []*GroupSummary `type:"list"` + + // Pagination token. Not used. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s GetGroupsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetGroupsOutput) GoString() string { + return s.String() +} + +// SetGroups sets the Groups field's value. +func (s *GetGroupsOutput) SetGroups(v []*GroupSummary) *GetGroupsOutput { + s.Groups = v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetGroupsOutput) SetNextToken(v string) *GetGroupsOutput { + s.NextToken = &v + return s +} + +type GetSamplingRulesInput struct { + _ struct{} `type:"structure"` + + // Pagination token. Not used. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s GetSamplingRulesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSamplingRulesInput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *GetSamplingRulesInput) SetNextToken(v string) *GetSamplingRulesInput { + s.NextToken = &v + return s +} + +type GetSamplingRulesOutput struct { + _ struct{} `type:"structure"` + + // Pagination token. Not used. + NextToken *string `type:"string"` + + // Rule definitions and metadata. + SamplingRuleRecords []*SamplingRuleRecord `type:"list"` +} + +// String returns the string representation +func (s GetSamplingRulesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSamplingRulesOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *GetSamplingRulesOutput) SetNextToken(v string) *GetSamplingRulesOutput { + s.NextToken = &v + return s +} + +// SetSamplingRuleRecords sets the SamplingRuleRecords field's value. +func (s *GetSamplingRulesOutput) SetSamplingRuleRecords(v []*SamplingRuleRecord) *GetSamplingRulesOutput { + s.SamplingRuleRecords = v + return s +} + +type GetSamplingStatisticSummariesInput struct { + _ struct{} `type:"structure"` + + // Pagination token. Not used. + NextToken *string `type:"string"` +} + +// String returns the string representation +func (s GetSamplingStatisticSummariesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSamplingStatisticSummariesInput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *GetSamplingStatisticSummariesInput) SetNextToken(v string) *GetSamplingStatisticSummariesInput { + s.NextToken = &v + return s +} + +type GetSamplingStatisticSummariesOutput struct { + _ struct{} `type:"structure"` + + // Pagination token. Not used. + NextToken *string `type:"string"` + + // Information about the number of requests instrumented for each sampling rule. + SamplingStatisticSummaries []*SamplingStatisticSummary `type:"list"` +} + +// String returns the string representation +func (s GetSamplingStatisticSummariesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSamplingStatisticSummariesOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *GetSamplingStatisticSummariesOutput) SetNextToken(v string) *GetSamplingStatisticSummariesOutput { + s.NextToken = &v + return s +} + +// SetSamplingStatisticSummaries sets the SamplingStatisticSummaries field's value. +func (s *GetSamplingStatisticSummariesOutput) SetSamplingStatisticSummaries(v []*SamplingStatisticSummary) *GetSamplingStatisticSummariesOutput { + s.SamplingStatisticSummaries = v + return s +} + +type GetSamplingTargetsInput struct { + _ struct{} `type:"structure"` + + // Information about rules that the service is using to sample requests. + // + // SamplingStatisticsDocuments is a required field + SamplingStatisticsDocuments []*SamplingStatisticsDocument `type:"list" required:"true"` +} + +// String returns the string representation +func (s GetSamplingTargetsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSamplingTargetsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetSamplingTargetsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetSamplingTargetsInput"} + if s.SamplingStatisticsDocuments == nil { + invalidParams.Add(request.NewErrParamRequired("SamplingStatisticsDocuments")) + } + if s.SamplingStatisticsDocuments != nil { + for i, v := range s.SamplingStatisticsDocuments { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "SamplingStatisticsDocuments", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetSamplingStatisticsDocuments sets the SamplingStatisticsDocuments field's value. +func (s *GetSamplingTargetsInput) SetSamplingStatisticsDocuments(v []*SamplingStatisticsDocument) *GetSamplingTargetsInput { + s.SamplingStatisticsDocuments = v + return s +} + +type GetSamplingTargetsOutput struct { + _ struct{} `type:"structure"` + + // The last time a user changed the sampling rule configuration. If the sampling + // rule configuration changed since the service last retrieved it, the service + // should call GetSamplingRules to get the latest version. + LastRuleModification *time.Time `type:"timestamp"` + + // Updated rules that the service should use to sample requests. + SamplingTargetDocuments []*SamplingTargetDocument `type:"list"` + + // Information about SamplingStatisticsDocument that X-Ray could not process. + UnprocessedStatistics []*UnprocessedStatistics `type:"list"` +} + +// String returns the string representation +func (s GetSamplingTargetsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetSamplingTargetsOutput) GoString() string { + return s.String() +} + +// SetLastRuleModification sets the LastRuleModification field's value. +func (s *GetSamplingTargetsOutput) SetLastRuleModification(v time.Time) *GetSamplingTargetsOutput { + s.LastRuleModification = &v + return s +} + +// SetSamplingTargetDocuments sets the SamplingTargetDocuments field's value. +func (s *GetSamplingTargetsOutput) SetSamplingTargetDocuments(v []*SamplingTargetDocument) *GetSamplingTargetsOutput { + s.SamplingTargetDocuments = v + return s +} + +// SetUnprocessedStatistics sets the UnprocessedStatistics field's value. +func (s *GetSamplingTargetsOutput) SetUnprocessedStatistics(v []*UnprocessedStatistics) *GetSamplingTargetsOutput { + s.UnprocessedStatistics = v + return s +} + +type GetServiceGraphInput struct { + _ struct{} `type:"structure"` + + // The end of the timeframe for which to generate a graph. + // + // EndTime is a required field + EndTime *time.Time `type:"timestamp" required:"true"` + + // The ARN of a group to generate a graph based on. + GroupARN *string `min:"1" type:"string"` + + // The name of a group to generate a graph based on. + GroupName *string `min:"1" type:"string"` + + // Pagination token. Not used. + NextToken *string `type:"string"` + + // The start of the time frame for which to generate a graph. + // + // StartTime is a required field + StartTime *time.Time `type:"timestamp" required:"true"` +} + +// String returns the string representation +func (s GetServiceGraphInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetServiceGraphInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetServiceGraphInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetServiceGraphInput"} + if s.EndTime == nil { + invalidParams.Add(request.NewErrParamRequired("EndTime")) + } + if s.GroupARN != nil && len(*s.GroupARN) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupARN", 1)) + } + if s.GroupName != nil && len(*s.GroupName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupName", 1)) + } + if s.StartTime == nil { + invalidParams.Add(request.NewErrParamRequired("StartTime")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEndTime sets the EndTime field's value. +func (s *GetServiceGraphInput) SetEndTime(v time.Time) *GetServiceGraphInput { + s.EndTime = &v + return s +} + +// SetGroupARN sets the GroupARN field's value. +func (s *GetServiceGraphInput) SetGroupARN(v string) *GetServiceGraphInput { + s.GroupARN = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *GetServiceGraphInput) SetGroupName(v string) *GetServiceGraphInput { + s.GroupName = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetServiceGraphInput) SetNextToken(v string) *GetServiceGraphInput { + s.NextToken = &v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *GetServiceGraphInput) SetStartTime(v time.Time) *GetServiceGraphInput { + s.StartTime = &v + return s +} + +type GetServiceGraphOutput struct { + _ struct{} `type:"structure"` + + // A flag indicating whether the group's filter expression has been consistent, + // or if the returned service graph may show traces from an older version of + // the group's filter expression. + ContainsOldGroupVersions *bool `type:"boolean"` + + // The end of the time frame for which the graph was generated. + EndTime *time.Time `type:"timestamp"` + + // Pagination token. Not used. + NextToken *string `type:"string"` + + // The services that have processed a traced request during the specified time + // frame. + Services []*Service `type:"list"` + + // The start of the time frame for which the graph was generated. + StartTime *time.Time `type:"timestamp"` +} + +// String returns the string representation +func (s GetServiceGraphOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetServiceGraphOutput) GoString() string { + return s.String() +} + +// SetContainsOldGroupVersions sets the ContainsOldGroupVersions field's value. +func (s *GetServiceGraphOutput) SetContainsOldGroupVersions(v bool) *GetServiceGraphOutput { + s.ContainsOldGroupVersions = &v + return s +} + +// SetEndTime sets the EndTime field's value. +func (s *GetServiceGraphOutput) SetEndTime(v time.Time) *GetServiceGraphOutput { + s.EndTime = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetServiceGraphOutput) SetNextToken(v string) *GetServiceGraphOutput { + s.NextToken = &v + return s +} + +// SetServices sets the Services field's value. +func (s *GetServiceGraphOutput) SetServices(v []*Service) *GetServiceGraphOutput { + s.Services = v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *GetServiceGraphOutput) SetStartTime(v time.Time) *GetServiceGraphOutput { + s.StartTime = &v + return s +} + +type GetTimeSeriesServiceStatisticsInput struct { + _ struct{} `type:"structure"` + + // The end of the time frame for which to aggregate statistics. + // + // EndTime is a required field + EndTime *time.Time `type:"timestamp" required:"true"` + + // A filter expression defining entities that will be aggregated for statistics. + // Supports ID, service, and edge functions. If no selector expression is specified, + // edge statistics are returned. + EntitySelectorExpression *string `min:"1" type:"string"` + + // The ARN of the group for which to pull statistics from. + GroupARN *string `min:"1" type:"string"` + + // The case-sensitive name of the group for which to pull statistics from. + GroupName *string `min:"1" type:"string"` + + // Pagination token. Not used. + NextToken *string `type:"string"` + + // Aggregation period in seconds. + Period *int64 `type:"integer"` + + // The start of the time frame for which to aggregate statistics. + // + // StartTime is a required field + StartTime *time.Time `type:"timestamp" required:"true"` +} + +// String returns the string representation +func (s GetTimeSeriesServiceStatisticsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTimeSeriesServiceStatisticsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetTimeSeriesServiceStatisticsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetTimeSeriesServiceStatisticsInput"} + if s.EndTime == nil { + invalidParams.Add(request.NewErrParamRequired("EndTime")) + } + if s.EntitySelectorExpression != nil && len(*s.EntitySelectorExpression) < 1 { + invalidParams.Add(request.NewErrParamMinLen("EntitySelectorExpression", 1)) + } + if s.GroupARN != nil && len(*s.GroupARN) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupARN", 1)) + } + if s.GroupName != nil && len(*s.GroupName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupName", 1)) + } + if s.StartTime == nil { + invalidParams.Add(request.NewErrParamRequired("StartTime")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEndTime sets the EndTime field's value. +func (s *GetTimeSeriesServiceStatisticsInput) SetEndTime(v time.Time) *GetTimeSeriesServiceStatisticsInput { + s.EndTime = &v + return s +} + +// SetEntitySelectorExpression sets the EntitySelectorExpression field's value. +func (s *GetTimeSeriesServiceStatisticsInput) SetEntitySelectorExpression(v string) *GetTimeSeriesServiceStatisticsInput { + s.EntitySelectorExpression = &v + return s +} + +// SetGroupARN sets the GroupARN field's value. +func (s *GetTimeSeriesServiceStatisticsInput) SetGroupARN(v string) *GetTimeSeriesServiceStatisticsInput { + s.GroupARN = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *GetTimeSeriesServiceStatisticsInput) SetGroupName(v string) *GetTimeSeriesServiceStatisticsInput { + s.GroupName = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetTimeSeriesServiceStatisticsInput) SetNextToken(v string) *GetTimeSeriesServiceStatisticsInput { + s.NextToken = &v + return s +} + +// SetPeriod sets the Period field's value. +func (s *GetTimeSeriesServiceStatisticsInput) SetPeriod(v int64) *GetTimeSeriesServiceStatisticsInput { + s.Period = &v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *GetTimeSeriesServiceStatisticsInput) SetStartTime(v time.Time) *GetTimeSeriesServiceStatisticsInput { + s.StartTime = &v + return s +} + +type GetTimeSeriesServiceStatisticsOutput struct { + _ struct{} `type:"structure"` + + // A flag indicating whether or not a group's filter expression has been consistent, + // or if a returned aggregation may show statistics from an older version of + // the group's filter expression. + ContainsOldGroupVersions *bool `type:"boolean"` + + // Pagination token. Not used. + NextToken *string `type:"string"` + + // The collection of statistics. + TimeSeriesServiceStatistics []*TimeSeriesServiceStatistics `type:"list"` +} + +// String returns the string representation +func (s GetTimeSeriesServiceStatisticsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTimeSeriesServiceStatisticsOutput) GoString() string { + return s.String() +} + +// SetContainsOldGroupVersions sets the ContainsOldGroupVersions field's value. +func (s *GetTimeSeriesServiceStatisticsOutput) SetContainsOldGroupVersions(v bool) *GetTimeSeriesServiceStatisticsOutput { + s.ContainsOldGroupVersions = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetTimeSeriesServiceStatisticsOutput) SetNextToken(v string) *GetTimeSeriesServiceStatisticsOutput { + s.NextToken = &v + return s +} + +// SetTimeSeriesServiceStatistics sets the TimeSeriesServiceStatistics field's value. +func (s *GetTimeSeriesServiceStatisticsOutput) SetTimeSeriesServiceStatistics(v []*TimeSeriesServiceStatistics) *GetTimeSeriesServiceStatisticsOutput { + s.TimeSeriesServiceStatistics = v + return s +} + +type GetTraceGraphInput struct { + _ struct{} `type:"structure"` + + // Pagination token. Not used. + NextToken *string `type:"string"` + + // Trace IDs of requests for which to generate a service graph. + // + // TraceIds is a required field + TraceIds []*string `type:"list" required:"true"` +} + +// String returns the string representation +func (s GetTraceGraphInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTraceGraphInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetTraceGraphInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetTraceGraphInput"} + if s.TraceIds == nil { + invalidParams.Add(request.NewErrParamRequired("TraceIds")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetNextToken sets the NextToken field's value. +func (s *GetTraceGraphInput) SetNextToken(v string) *GetTraceGraphInput { + s.NextToken = &v + return s +} + +// SetTraceIds sets the TraceIds field's value. +func (s *GetTraceGraphInput) SetTraceIds(v []*string) *GetTraceGraphInput { + s.TraceIds = v + return s +} + +type GetTraceGraphOutput struct { + _ struct{} `type:"structure"` + + // Pagination token. Not used. + NextToken *string `type:"string"` + + // The services that have processed one of the specified requests. + Services []*Service `type:"list"` +} + +// String returns the string representation +func (s GetTraceGraphOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTraceGraphOutput) GoString() string { + return s.String() +} + +// SetNextToken sets the NextToken field's value. +func (s *GetTraceGraphOutput) SetNextToken(v string) *GetTraceGraphOutput { + s.NextToken = &v + return s +} + +// SetServices sets the Services field's value. +func (s *GetTraceGraphOutput) SetServices(v []*Service) *GetTraceGraphOutput { + s.Services = v + return s +} + +type GetTraceSummariesInput struct { + _ struct{} `type:"structure"` + + // The end of the time frame for which to retrieve traces. + // + // EndTime is a required field + EndTime *time.Time `type:"timestamp" required:"true"` + + // Specify a filter expression to retrieve trace summaries for services or requests + // that meet certain requirements. + FilterExpression *string `type:"string"` + + // Specify the pagination token returned by a previous request to retrieve the + // next page of results. + NextToken *string `type:"string"` + + // Set to true to get summaries for only a subset of available traces. + Sampling *bool `type:"boolean"` + + // A paramater to indicate whether to enable sampling on trace summaries. Input + // parameters are Name and Value. + SamplingStrategy *SamplingStrategy `type:"structure"` + + // The start of the time frame for which to retrieve traces. + // + // StartTime is a required field + StartTime *time.Time `type:"timestamp" required:"true"` + + // A parameter to indicate whether to query trace summaries by TraceId or Event + // time. + TimeRangeType *string `type:"string" enum:"TimeRangeType"` +} + +// String returns the string representation +func (s GetTraceSummariesInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTraceSummariesInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *GetTraceSummariesInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "GetTraceSummariesInput"} + if s.EndTime == nil { + invalidParams.Add(request.NewErrParamRequired("EndTime")) + } + if s.StartTime == nil { + invalidParams.Add(request.NewErrParamRequired("StartTime")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEndTime sets the EndTime field's value. +func (s *GetTraceSummariesInput) SetEndTime(v time.Time) *GetTraceSummariesInput { + s.EndTime = &v + return s +} + +// SetFilterExpression sets the FilterExpression field's value. +func (s *GetTraceSummariesInput) SetFilterExpression(v string) *GetTraceSummariesInput { + s.FilterExpression = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetTraceSummariesInput) SetNextToken(v string) *GetTraceSummariesInput { + s.NextToken = &v + return s +} + +// SetSampling sets the Sampling field's value. +func (s *GetTraceSummariesInput) SetSampling(v bool) *GetTraceSummariesInput { + s.Sampling = &v + return s +} + +// SetSamplingStrategy sets the SamplingStrategy field's value. +func (s *GetTraceSummariesInput) SetSamplingStrategy(v *SamplingStrategy) *GetTraceSummariesInput { + s.SamplingStrategy = v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *GetTraceSummariesInput) SetStartTime(v time.Time) *GetTraceSummariesInput { + s.StartTime = &v + return s +} + +// SetTimeRangeType sets the TimeRangeType field's value. +func (s *GetTraceSummariesInput) SetTimeRangeType(v string) *GetTraceSummariesInput { + s.TimeRangeType = &v + return s +} + +type GetTraceSummariesOutput struct { + _ struct{} `type:"structure"` + + // The start time of this page of results. + ApproximateTime *time.Time `type:"timestamp"` + + // If the requested time frame contained more than one page of results, you + // can use this token to retrieve the next page. The first page contains the + // most most recent results, closest to the end of the time frame. + NextToken *string `type:"string"` + + // Trace IDs and metadata for traces that were found in the specified time frame. + TraceSummaries []*TraceSummary `type:"list"` + + // The total number of traces processed, including traces that did not match + // the specified filter expression. + TracesProcessedCount *int64 `type:"long"` +} + +// String returns the string representation +func (s GetTraceSummariesOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GetTraceSummariesOutput) GoString() string { + return s.String() +} + +// SetApproximateTime sets the ApproximateTime field's value. +func (s *GetTraceSummariesOutput) SetApproximateTime(v time.Time) *GetTraceSummariesOutput { + s.ApproximateTime = &v + return s +} + +// SetNextToken sets the NextToken field's value. +func (s *GetTraceSummariesOutput) SetNextToken(v string) *GetTraceSummariesOutput { + s.NextToken = &v + return s +} + +// SetTraceSummaries sets the TraceSummaries field's value. +func (s *GetTraceSummariesOutput) SetTraceSummaries(v []*TraceSummary) *GetTraceSummariesOutput { + s.TraceSummaries = v + return s +} + +// SetTracesProcessedCount sets the TracesProcessedCount field's value. +func (s *GetTraceSummariesOutput) SetTracesProcessedCount(v int64) *GetTraceSummariesOutput { + s.TracesProcessedCount = &v + return s +} + +// Details and metadata for a group. +type Group struct { + _ struct{} `type:"structure"` + + // The filter expression defining the parameters to include traces. + FilterExpression *string `type:"string"` + + // The ARN of the group generated based on the GroupName. + GroupARN *string `type:"string"` + + // The unique case-sensitive name of the group. + GroupName *string `type:"string"` +} + +// String returns the string representation +func (s Group) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Group) GoString() string { + return s.String() +} + +// SetFilterExpression sets the FilterExpression field's value. +func (s *Group) SetFilterExpression(v string) *Group { + s.FilterExpression = &v + return s +} + +// SetGroupARN sets the GroupARN field's value. +func (s *Group) SetGroupARN(v string) *Group { + s.GroupARN = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *Group) SetGroupName(v string) *Group { + s.GroupName = &v + return s +} + +// Details for a group without metadata. +type GroupSummary struct { + _ struct{} `type:"structure"` + + // The filter expression defining the parameters to include traces. + FilterExpression *string `type:"string"` + + // The ARN of the group generated based on the GroupName. + GroupARN *string `type:"string"` + + // The unique case-sensitive name of the group. + GroupName *string `type:"string"` +} + +// String returns the string representation +func (s GroupSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s GroupSummary) GoString() string { + return s.String() +} + +// SetFilterExpression sets the FilterExpression field's value. +func (s *GroupSummary) SetFilterExpression(v string) *GroupSummary { + s.FilterExpression = &v + return s +} + +// SetGroupARN sets the GroupARN field's value. +func (s *GroupSummary) SetGroupARN(v string) *GroupSummary { + s.GroupARN = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *GroupSummary) SetGroupName(v string) *GroupSummary { + s.GroupName = &v + return s +} + +// An entry in a histogram for a statistic. A histogram maps the range of observed +// values on the X axis, and the prevalence of each value on the Y axis. +type HistogramEntry struct { + _ struct{} `type:"structure"` + + // The prevalence of the entry. + Count *int64 `type:"integer"` + + // The value of the entry. + Value *float64 `type:"double"` +} + +// String returns the string representation +func (s HistogramEntry) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s HistogramEntry) GoString() string { + return s.String() +} + +// SetCount sets the Count field's value. +func (s *HistogramEntry) SetCount(v int64) *HistogramEntry { + s.Count = &v + return s +} + +// SetValue sets the Value field's value. +func (s *HistogramEntry) SetValue(v float64) *HistogramEntry { + s.Value = &v + return s +} + +// Information about an HTTP request. +type Http struct { + _ struct{} `type:"structure"` + + // The IP address of the requestor. + ClientIp *string `type:"string"` + + // The request method. + HttpMethod *string `type:"string"` + + // The response status. + HttpStatus *int64 `type:"integer"` + + // The request URL. + HttpURL *string `type:"string"` + + // The request's user agent string. + UserAgent *string `type:"string"` +} + +// String returns the string representation +func (s Http) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Http) GoString() string { + return s.String() +} + +// SetClientIp sets the ClientIp field's value. +func (s *Http) SetClientIp(v string) *Http { + s.ClientIp = &v + return s +} + +// SetHttpMethod sets the HttpMethod field's value. +func (s *Http) SetHttpMethod(v string) *Http { + s.HttpMethod = &v + return s +} + +// SetHttpStatus sets the HttpStatus field's value. +func (s *Http) SetHttpStatus(v int64) *Http { + s.HttpStatus = &v + return s +} + +// SetHttpURL sets the HttpURL field's value. +func (s *Http) SetHttpURL(v string) *Http { + s.HttpURL = &v + return s +} + +// SetUserAgent sets the UserAgent field's value. +func (s *Http) SetUserAgent(v string) *Http { + s.UserAgent = &v + return s +} + +// A list of EC2 instance IDs corresponding to the segments in a trace. +type InstanceIdDetail struct { + _ struct{} `type:"structure"` + + // The ID of a corresponding EC2 instance. + Id *string `type:"string"` +} + +// String returns the string representation +func (s InstanceIdDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s InstanceIdDetail) GoString() string { + return s.String() +} + +// SetId sets the Id field's value. +func (s *InstanceIdDetail) SetId(v string) *InstanceIdDetail { + s.Id = &v + return s +} + +type PutEncryptionConfigInput struct { + _ struct{} `type:"structure"` + + // An AWS KMS customer master key (CMK) in one of the following formats: + // + // * Alias - The name of the key. For example, alias/MyKey. + // + // * Key ID - The KMS key ID of the key. For example, ae4aa6d49-a4d8-9df9-a475-4ff6d7898456. + // + // * ARN - The full Amazon Resource Name of the key ID or alias. For example, + // arn:aws:kms:us-east-2:123456789012:key/ae4aa6d49-a4d8-9df9-a475-4ff6d7898456. + // Use this format to specify a key in a different account. + // + // Omit this key if you set Type to NONE. + KeyId *string `min:"1" type:"string"` + + // The type of encryption. Set to KMS to use your own key for encryption. Set + // to NONE for default encryption. + // + // Type is a required field + Type *string `type:"string" required:"true" enum:"EncryptionType"` +} + +// String returns the string representation +func (s PutEncryptionConfigInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutEncryptionConfigInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutEncryptionConfigInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PutEncryptionConfigInput"} + if s.KeyId != nil && len(*s.KeyId) < 1 { + invalidParams.Add(request.NewErrParamMinLen("KeyId", 1)) + } + if s.Type == nil { + invalidParams.Add(request.NewErrParamRequired("Type")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetKeyId sets the KeyId field's value. +func (s *PutEncryptionConfigInput) SetKeyId(v string) *PutEncryptionConfigInput { + s.KeyId = &v + return s +} + +// SetType sets the Type field's value. +func (s *PutEncryptionConfigInput) SetType(v string) *PutEncryptionConfigInput { + s.Type = &v + return s +} + +type PutEncryptionConfigOutput struct { + _ struct{} `type:"structure"` + + // The new encryption configuration. + EncryptionConfig *EncryptionConfig `type:"structure"` +} + +// String returns the string representation +func (s PutEncryptionConfigOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutEncryptionConfigOutput) GoString() string { + return s.String() +} + +// SetEncryptionConfig sets the EncryptionConfig field's value. +func (s *PutEncryptionConfigOutput) SetEncryptionConfig(v *EncryptionConfig) *PutEncryptionConfigOutput { + s.EncryptionConfig = v + return s +} + +type PutTelemetryRecordsInput struct { + _ struct{} `type:"structure"` + + EC2InstanceId *string `type:"string"` + + Hostname *string `type:"string"` + + ResourceARN *string `type:"string"` + + // TelemetryRecords is a required field + TelemetryRecords []*TelemetryRecord `type:"list" required:"true"` +} + +// String returns the string representation +func (s PutTelemetryRecordsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutTelemetryRecordsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutTelemetryRecordsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PutTelemetryRecordsInput"} + if s.TelemetryRecords == nil { + invalidParams.Add(request.NewErrParamRequired("TelemetryRecords")) + } + if s.TelemetryRecords != nil { + for i, v := range s.TelemetryRecords { + if v == nil { + continue + } + if err := v.Validate(); err != nil { + invalidParams.AddNested(fmt.Sprintf("%s[%v]", "TelemetryRecords", i), err.(request.ErrInvalidParams)) + } + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetEC2InstanceId sets the EC2InstanceId field's value. +func (s *PutTelemetryRecordsInput) SetEC2InstanceId(v string) *PutTelemetryRecordsInput { + s.EC2InstanceId = &v + return s +} + +// SetHostname sets the Hostname field's value. +func (s *PutTelemetryRecordsInput) SetHostname(v string) *PutTelemetryRecordsInput { + s.Hostname = &v + return s +} + +// SetResourceARN sets the ResourceARN field's value. +func (s *PutTelemetryRecordsInput) SetResourceARN(v string) *PutTelemetryRecordsInput { + s.ResourceARN = &v + return s +} + +// SetTelemetryRecords sets the TelemetryRecords field's value. +func (s *PutTelemetryRecordsInput) SetTelemetryRecords(v []*TelemetryRecord) *PutTelemetryRecordsInput { + s.TelemetryRecords = v + return s +} + +type PutTelemetryRecordsOutput struct { + _ struct{} `type:"structure"` +} + +// String returns the string representation +func (s PutTelemetryRecordsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutTelemetryRecordsOutput) GoString() string { + return s.String() +} + +type PutTraceSegmentsInput struct { + _ struct{} `type:"structure"` + + // A string containing a JSON document defining one or more segments or subsegments. + // + // TraceSegmentDocuments is a required field + TraceSegmentDocuments []*string `type:"list" required:"true"` +} + +// String returns the string representation +func (s PutTraceSegmentsInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutTraceSegmentsInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *PutTraceSegmentsInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "PutTraceSegmentsInput"} + if s.TraceSegmentDocuments == nil { + invalidParams.Add(request.NewErrParamRequired("TraceSegmentDocuments")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetTraceSegmentDocuments sets the TraceSegmentDocuments field's value. +func (s *PutTraceSegmentsInput) SetTraceSegmentDocuments(v []*string) *PutTraceSegmentsInput { + s.TraceSegmentDocuments = v + return s +} + +type PutTraceSegmentsOutput struct { + _ struct{} `type:"structure"` + + // Segments that failed processing. + UnprocessedTraceSegments []*UnprocessedTraceSegment `type:"list"` +} + +// String returns the string representation +func (s PutTraceSegmentsOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s PutTraceSegmentsOutput) GoString() string { + return s.String() +} + +// SetUnprocessedTraceSegments sets the UnprocessedTraceSegments field's value. +func (s *PutTraceSegmentsOutput) SetUnprocessedTraceSegments(v []*UnprocessedTraceSegment) *PutTraceSegmentsOutput { + s.UnprocessedTraceSegments = v + return s +} + +// A list of resources ARNs corresponding to the segments in a trace. +type ResourceARNDetail struct { + _ struct{} `type:"structure"` + + // The ARN of a corresponding resource. + ARN *string `type:"string"` +} + +// String returns the string representation +func (s ResourceARNDetail) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResourceARNDetail) GoString() string { + return s.String() +} + +// SetARN sets the ARN field's value. +func (s *ResourceARNDetail) SetARN(v string) *ResourceARNDetail { + s.ARN = &v + return s +} + +// The root cause information for a response time warning. +type ResponseTimeRootCause struct { + _ struct{} `type:"structure"` + + // A list of corresponding services. A service identifies a segment and contains + // a name, account ID, type, and inferred flag. + Services []*ResponseTimeRootCauseService `type:"list"` +} + +// String returns the string representation +func (s ResponseTimeRootCause) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResponseTimeRootCause) GoString() string { + return s.String() +} + +// SetServices sets the Services field's value. +func (s *ResponseTimeRootCause) SetServices(v []*ResponseTimeRootCauseService) *ResponseTimeRootCause { + s.Services = v + return s +} + +// A collection of segments and corresponding subsegments associated to a response +// time warning. +type ResponseTimeRootCauseEntity struct { + _ struct{} `type:"structure"` + + // The types and messages of the exceptions. + Coverage *float64 `type:"double"` + + // The name of the entity. + Name *string `type:"string"` + + // A flag that denotes a remote subsegment. + Remote *bool `type:"boolean"` +} + +// String returns the string representation +func (s ResponseTimeRootCauseEntity) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResponseTimeRootCauseEntity) GoString() string { + return s.String() +} + +// SetCoverage sets the Coverage field's value. +func (s *ResponseTimeRootCauseEntity) SetCoverage(v float64) *ResponseTimeRootCauseEntity { + s.Coverage = &v + return s +} + +// SetName sets the Name field's value. +func (s *ResponseTimeRootCauseEntity) SetName(v string) *ResponseTimeRootCauseEntity { + s.Name = &v + return s +} + +// SetRemote sets the Remote field's value. +func (s *ResponseTimeRootCauseEntity) SetRemote(v bool) *ResponseTimeRootCauseEntity { + s.Remote = &v + return s +} + +// A collection of fields identifying the service in a response time warning. +type ResponseTimeRootCauseService struct { + _ struct{} `type:"structure"` + + // The account ID associated to the service. + AccountId *string `type:"string"` + + // The path of root cause entities found on the service. + EntityPath []*ResponseTimeRootCauseEntity `type:"list"` + + // A Boolean value indicating if the service is inferred from the trace. + Inferred *bool `type:"boolean"` + + // The service name. + Name *string `type:"string"` + + // A collection of associated service names. + Names []*string `type:"list"` + + // The type associated to the service. + Type *string `type:"string"` +} + +// String returns the string representation +func (s ResponseTimeRootCauseService) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ResponseTimeRootCauseService) GoString() string { + return s.String() +} + +// SetAccountId sets the AccountId field's value. +func (s *ResponseTimeRootCauseService) SetAccountId(v string) *ResponseTimeRootCauseService { + s.AccountId = &v + return s +} + +// SetEntityPath sets the EntityPath field's value. +func (s *ResponseTimeRootCauseService) SetEntityPath(v []*ResponseTimeRootCauseEntity) *ResponseTimeRootCauseService { + s.EntityPath = v + return s +} + +// SetInferred sets the Inferred field's value. +func (s *ResponseTimeRootCauseService) SetInferred(v bool) *ResponseTimeRootCauseService { + s.Inferred = &v + return s +} + +// SetName sets the Name field's value. +func (s *ResponseTimeRootCauseService) SetName(v string) *ResponseTimeRootCauseService { + s.Name = &v + return s +} + +// SetNames sets the Names field's value. +func (s *ResponseTimeRootCauseService) SetNames(v []*string) *ResponseTimeRootCauseService { + s.Names = v + return s +} + +// SetType sets the Type field's value. +func (s *ResponseTimeRootCauseService) SetType(v string) *ResponseTimeRootCauseService { + s.Type = &v + return s +} + +// The exception associated with a root cause. +type RootCauseException struct { + _ struct{} `type:"structure"` + + // The message of the exception. + Message *string `type:"string"` + + // The name of the exception. + Name *string `type:"string"` +} + +// String returns the string representation +func (s RootCauseException) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s RootCauseException) GoString() string { + return s.String() +} + +// SetMessage sets the Message field's value. +func (s *RootCauseException) SetMessage(v string) *RootCauseException { + s.Message = &v + return s +} + +// SetName sets the Name field's value. +func (s *RootCauseException) SetName(v string) *RootCauseException { + s.Name = &v + return s +} + +// A sampling rule that services use to decide whether to instrument a request. +// Rule fields can match properties of the service, or properties of a request. +// The service can ignore rules that don't match its properties. +type SamplingRule struct { + _ struct{} `type:"structure"` + + // Matches attributes derived from the request. + Attributes map[string]*string `type:"map"` + + // The percentage of matching requests to instrument, after the reservoir is + // exhausted. + // + // FixedRate is a required field + FixedRate *float64 `type:"double" required:"true"` + + // Matches the HTTP method of a request. + // + // HTTPMethod is a required field + HTTPMethod *string `type:"string" required:"true"` + + // Matches the hostname from a request URL. + // + // Host is a required field + Host *string `type:"string" required:"true"` + + // The priority of the sampling rule. + // + // Priority is a required field + Priority *int64 `min:"1" type:"integer" required:"true"` + + // A fixed number of matching requests to instrument per second, prior to applying + // the fixed rate. The reservoir is not used directly by services, but applies + // to all services using the rule collectively. + // + // ReservoirSize is a required field + ReservoirSize *int64 `type:"integer" required:"true"` + + // Matches the ARN of the AWS resource on which the service runs. + // + // ResourceARN is a required field + ResourceARN *string `type:"string" required:"true"` + + // The ARN of the sampling rule. Specify a rule by either name or ARN, but not + // both. + RuleARN *string `type:"string"` + + // The name of the sampling rule. Specify a rule by either name or ARN, but + // not both. + RuleName *string `min:"1" type:"string"` + + // Matches the name that the service uses to identify itself in segments. + // + // ServiceName is a required field + ServiceName *string `type:"string" required:"true"` + + // Matches the origin that the service uses to identify its type in segments. + // + // ServiceType is a required field + ServiceType *string `type:"string" required:"true"` + + // Matches the path from a request URL. + // + // URLPath is a required field + URLPath *string `type:"string" required:"true"` + + // The version of the sampling rule format (1). + // + // Version is a required field + Version *int64 `min:"1" type:"integer" required:"true"` +} + +// String returns the string representation +func (s SamplingRule) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SamplingRule) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SamplingRule) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SamplingRule"} + if s.FixedRate == nil { + invalidParams.Add(request.NewErrParamRequired("FixedRate")) + } + if s.HTTPMethod == nil { + invalidParams.Add(request.NewErrParamRequired("HTTPMethod")) + } + if s.Host == nil { + invalidParams.Add(request.NewErrParamRequired("Host")) + } + if s.Priority == nil { + invalidParams.Add(request.NewErrParamRequired("Priority")) + } + if s.Priority != nil && *s.Priority < 1 { + invalidParams.Add(request.NewErrParamMinValue("Priority", 1)) + } + if s.ReservoirSize == nil { + invalidParams.Add(request.NewErrParamRequired("ReservoirSize")) + } + if s.ResourceARN == nil { + invalidParams.Add(request.NewErrParamRequired("ResourceARN")) + } + if s.RuleName != nil && len(*s.RuleName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("RuleName", 1)) + } + if s.ServiceName == nil { + invalidParams.Add(request.NewErrParamRequired("ServiceName")) + } + if s.ServiceType == nil { + invalidParams.Add(request.NewErrParamRequired("ServiceType")) + } + if s.URLPath == nil { + invalidParams.Add(request.NewErrParamRequired("URLPath")) + } + if s.Version == nil { + invalidParams.Add(request.NewErrParamRequired("Version")) + } + if s.Version != nil && *s.Version < 1 { + invalidParams.Add(request.NewErrParamMinValue("Version", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributes sets the Attributes field's value. +func (s *SamplingRule) SetAttributes(v map[string]*string) *SamplingRule { + s.Attributes = v + return s +} + +// SetFixedRate sets the FixedRate field's value. +func (s *SamplingRule) SetFixedRate(v float64) *SamplingRule { + s.FixedRate = &v + return s +} + +// SetHTTPMethod sets the HTTPMethod field's value. +func (s *SamplingRule) SetHTTPMethod(v string) *SamplingRule { + s.HTTPMethod = &v + return s +} + +// SetHost sets the Host field's value. +func (s *SamplingRule) SetHost(v string) *SamplingRule { + s.Host = &v + return s +} + +// SetPriority sets the Priority field's value. +func (s *SamplingRule) SetPriority(v int64) *SamplingRule { + s.Priority = &v + return s +} + +// SetReservoirSize sets the ReservoirSize field's value. +func (s *SamplingRule) SetReservoirSize(v int64) *SamplingRule { + s.ReservoirSize = &v + return s +} + +// SetResourceARN sets the ResourceARN field's value. +func (s *SamplingRule) SetResourceARN(v string) *SamplingRule { + s.ResourceARN = &v + return s +} + +// SetRuleARN sets the RuleARN field's value. +func (s *SamplingRule) SetRuleARN(v string) *SamplingRule { + s.RuleARN = &v + return s +} + +// SetRuleName sets the RuleName field's value. +func (s *SamplingRule) SetRuleName(v string) *SamplingRule { + s.RuleName = &v + return s +} + +// SetServiceName sets the ServiceName field's value. +func (s *SamplingRule) SetServiceName(v string) *SamplingRule { + s.ServiceName = &v + return s +} + +// SetServiceType sets the ServiceType field's value. +func (s *SamplingRule) SetServiceType(v string) *SamplingRule { + s.ServiceType = &v + return s +} + +// SetURLPath sets the URLPath field's value. +func (s *SamplingRule) SetURLPath(v string) *SamplingRule { + s.URLPath = &v + return s +} + +// SetVersion sets the Version field's value. +func (s *SamplingRule) SetVersion(v int64) *SamplingRule { + s.Version = &v + return s +} + +// A SamplingRule and its metadata. +type SamplingRuleRecord struct { + _ struct{} `type:"structure"` + + // When the rule was created. + CreatedAt *time.Time `type:"timestamp"` + + // When the rule was last modified. + ModifiedAt *time.Time `type:"timestamp"` + + // The sampling rule. + SamplingRule *SamplingRule `type:"structure"` +} + +// String returns the string representation +func (s SamplingRuleRecord) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SamplingRuleRecord) GoString() string { + return s.String() +} + +// SetCreatedAt sets the CreatedAt field's value. +func (s *SamplingRuleRecord) SetCreatedAt(v time.Time) *SamplingRuleRecord { + s.CreatedAt = &v + return s +} + +// SetModifiedAt sets the ModifiedAt field's value. +func (s *SamplingRuleRecord) SetModifiedAt(v time.Time) *SamplingRuleRecord { + s.ModifiedAt = &v + return s +} + +// SetSamplingRule sets the SamplingRule field's value. +func (s *SamplingRuleRecord) SetSamplingRule(v *SamplingRule) *SamplingRuleRecord { + s.SamplingRule = v + return s +} + +// A document specifying changes to a sampling rule's configuration. +type SamplingRuleUpdate struct { + _ struct{} `type:"structure"` + + // Matches attributes derived from the request. + Attributes map[string]*string `type:"map"` + + // The percentage of matching requests to instrument, after the reservoir is + // exhausted. + FixedRate *float64 `type:"double"` + + // Matches the HTTP method of a request. + HTTPMethod *string `type:"string"` + + // Matches the hostname from a request URL. + Host *string `type:"string"` + + // The priority of the sampling rule. + Priority *int64 `type:"integer"` + + // A fixed number of matching requests to instrument per second, prior to applying + // the fixed rate. The reservoir is not used directly by services, but applies + // to all services using the rule collectively. + ReservoirSize *int64 `type:"integer"` + + // Matches the ARN of the AWS resource on which the service runs. + ResourceARN *string `type:"string"` + + // The ARN of the sampling rule. Specify a rule by either name or ARN, but not + // both. + RuleARN *string `type:"string"` + + // The name of the sampling rule. Specify a rule by either name or ARN, but + // not both. + RuleName *string `min:"1" type:"string"` + + // Matches the name that the service uses to identify itself in segments. + ServiceName *string `type:"string"` + + // Matches the origin that the service uses to identify its type in segments. + ServiceType *string `type:"string"` + + // Matches the path from a request URL. + URLPath *string `type:"string"` +} + +// String returns the string representation +func (s SamplingRuleUpdate) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SamplingRuleUpdate) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SamplingRuleUpdate) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SamplingRuleUpdate"} + if s.RuleName != nil && len(*s.RuleName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("RuleName", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetAttributes sets the Attributes field's value. +func (s *SamplingRuleUpdate) SetAttributes(v map[string]*string) *SamplingRuleUpdate { + s.Attributes = v + return s +} + +// SetFixedRate sets the FixedRate field's value. +func (s *SamplingRuleUpdate) SetFixedRate(v float64) *SamplingRuleUpdate { + s.FixedRate = &v + return s +} + +// SetHTTPMethod sets the HTTPMethod field's value. +func (s *SamplingRuleUpdate) SetHTTPMethod(v string) *SamplingRuleUpdate { + s.HTTPMethod = &v + return s +} + +// SetHost sets the Host field's value. +func (s *SamplingRuleUpdate) SetHost(v string) *SamplingRuleUpdate { + s.Host = &v + return s +} + +// SetPriority sets the Priority field's value. +func (s *SamplingRuleUpdate) SetPriority(v int64) *SamplingRuleUpdate { + s.Priority = &v + return s +} + +// SetReservoirSize sets the ReservoirSize field's value. +func (s *SamplingRuleUpdate) SetReservoirSize(v int64) *SamplingRuleUpdate { + s.ReservoirSize = &v + return s +} + +// SetResourceARN sets the ResourceARN field's value. +func (s *SamplingRuleUpdate) SetResourceARN(v string) *SamplingRuleUpdate { + s.ResourceARN = &v + return s +} + +// SetRuleARN sets the RuleARN field's value. +func (s *SamplingRuleUpdate) SetRuleARN(v string) *SamplingRuleUpdate { + s.RuleARN = &v + return s +} + +// SetRuleName sets the RuleName field's value. +func (s *SamplingRuleUpdate) SetRuleName(v string) *SamplingRuleUpdate { + s.RuleName = &v + return s +} + +// SetServiceName sets the ServiceName field's value. +func (s *SamplingRuleUpdate) SetServiceName(v string) *SamplingRuleUpdate { + s.ServiceName = &v + return s +} + +// SetServiceType sets the ServiceType field's value. +func (s *SamplingRuleUpdate) SetServiceType(v string) *SamplingRuleUpdate { + s.ServiceType = &v + return s +} + +// SetURLPath sets the URLPath field's value. +func (s *SamplingRuleUpdate) SetURLPath(v string) *SamplingRuleUpdate { + s.URLPath = &v + return s +} + +// Aggregated request sampling data for a sampling rule across all services +// for a 10 second window. +type SamplingStatisticSummary struct { + _ struct{} `type:"structure"` + + // The number of requests recorded with borrowed reservoir quota. + BorrowCount *int64 `type:"integer"` + + // The number of requests that matched the rule. + RequestCount *int64 `type:"integer"` + + // The name of the sampling rule. + RuleName *string `type:"string"` + + // The number of requests recorded. + SampledCount *int64 `type:"integer"` + + // The start time of the reporting window. + Timestamp *time.Time `type:"timestamp"` +} + +// String returns the string representation +func (s SamplingStatisticSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SamplingStatisticSummary) GoString() string { + return s.String() +} + +// SetBorrowCount sets the BorrowCount field's value. +func (s *SamplingStatisticSummary) SetBorrowCount(v int64) *SamplingStatisticSummary { + s.BorrowCount = &v + return s +} + +// SetRequestCount sets the RequestCount field's value. +func (s *SamplingStatisticSummary) SetRequestCount(v int64) *SamplingStatisticSummary { + s.RequestCount = &v + return s +} + +// SetRuleName sets the RuleName field's value. +func (s *SamplingStatisticSummary) SetRuleName(v string) *SamplingStatisticSummary { + s.RuleName = &v + return s +} + +// SetSampledCount sets the SampledCount field's value. +func (s *SamplingStatisticSummary) SetSampledCount(v int64) *SamplingStatisticSummary { + s.SampledCount = &v + return s +} + +// SetTimestamp sets the Timestamp field's value. +func (s *SamplingStatisticSummary) SetTimestamp(v time.Time) *SamplingStatisticSummary { + s.Timestamp = &v + return s +} + +// Request sampling results for a single rule from a service. Results are for +// the last 10 seconds unless the service has been assigned a longer reporting +// interval after a previous call to GetSamplingTargets. +type SamplingStatisticsDocument struct { + _ struct{} `type:"structure"` + + // The number of requests recorded with borrowed reservoir quota. + BorrowCount *int64 `type:"integer"` + + // A unique identifier for the service in hexadecimal. + // + // ClientID is a required field + ClientID *string `min:"24" type:"string" required:"true"` + + // The number of requests that matched the rule. + // + // RequestCount is a required field + RequestCount *int64 `type:"integer" required:"true"` + + // The name of the sampling rule. + // + // RuleName is a required field + RuleName *string `min:"1" type:"string" required:"true"` + + // The number of requests recorded. + // + // SampledCount is a required field + SampledCount *int64 `type:"integer" required:"true"` + + // The current time. + // + // Timestamp is a required field + Timestamp *time.Time `type:"timestamp" required:"true"` +} + +// String returns the string representation +func (s SamplingStatisticsDocument) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SamplingStatisticsDocument) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *SamplingStatisticsDocument) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "SamplingStatisticsDocument"} + if s.ClientID == nil { + invalidParams.Add(request.NewErrParamRequired("ClientID")) + } + if s.ClientID != nil && len(*s.ClientID) < 24 { + invalidParams.Add(request.NewErrParamMinLen("ClientID", 24)) + } + if s.RequestCount == nil { + invalidParams.Add(request.NewErrParamRequired("RequestCount")) + } + if s.RuleName == nil { + invalidParams.Add(request.NewErrParamRequired("RuleName")) + } + if s.RuleName != nil && len(*s.RuleName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("RuleName", 1)) + } + if s.SampledCount == nil { + invalidParams.Add(request.NewErrParamRequired("SampledCount")) + } + if s.Timestamp == nil { + invalidParams.Add(request.NewErrParamRequired("Timestamp")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBorrowCount sets the BorrowCount field's value. +func (s *SamplingStatisticsDocument) SetBorrowCount(v int64) *SamplingStatisticsDocument { + s.BorrowCount = &v + return s +} + +// SetClientID sets the ClientID field's value. +func (s *SamplingStatisticsDocument) SetClientID(v string) *SamplingStatisticsDocument { + s.ClientID = &v + return s +} + +// SetRequestCount sets the RequestCount field's value. +func (s *SamplingStatisticsDocument) SetRequestCount(v int64) *SamplingStatisticsDocument { + s.RequestCount = &v + return s +} + +// SetRuleName sets the RuleName field's value. +func (s *SamplingStatisticsDocument) SetRuleName(v string) *SamplingStatisticsDocument { + s.RuleName = &v + return s +} + +// SetSampledCount sets the SampledCount field's value. +func (s *SamplingStatisticsDocument) SetSampledCount(v int64) *SamplingStatisticsDocument { + s.SampledCount = &v + return s +} + +// SetTimestamp sets the Timestamp field's value. +func (s *SamplingStatisticsDocument) SetTimestamp(v time.Time) *SamplingStatisticsDocument { + s.Timestamp = &v + return s +} + +// The name and value of a sampling rule to apply to a trace summary. +type SamplingStrategy struct { + _ struct{} `type:"structure"` + + // The name of a sampling rule. + Name *string `type:"string" enum:"SamplingStrategyName"` + + // The value of a sampling rule. + Value *float64 `type:"double"` +} + +// String returns the string representation +func (s SamplingStrategy) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SamplingStrategy) GoString() string { + return s.String() +} + +// SetName sets the Name field's value. +func (s *SamplingStrategy) SetName(v string) *SamplingStrategy { + s.Name = &v + return s +} + +// SetValue sets the Value field's value. +func (s *SamplingStrategy) SetValue(v float64) *SamplingStrategy { + s.Value = &v + return s +} + +// Temporary changes to a sampling rule configuration. To meet the global sampling +// target for a rule, X-Ray calculates a new reservoir for each service based +// on the recent sampling results of all services that called GetSamplingTargets. +type SamplingTargetDocument struct { + _ struct{} `type:"structure"` + + // The percentage of matching requests to instrument, after the reservoir is + // exhausted. + FixedRate *float64 `type:"double"` + + // The number of seconds for the service to wait before getting sampling targets + // again. + Interval *int64 `type:"integer"` + + // The number of requests per second that X-Ray allocated this service. + ReservoirQuota *int64 `type:"integer"` + + // When the reservoir quota expires. + ReservoirQuotaTTL *time.Time `type:"timestamp"` + + // The name of the sampling rule. + RuleName *string `type:"string"` +} + +// String returns the string representation +func (s SamplingTargetDocument) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s SamplingTargetDocument) GoString() string { + return s.String() +} + +// SetFixedRate sets the FixedRate field's value. +func (s *SamplingTargetDocument) SetFixedRate(v float64) *SamplingTargetDocument { + s.FixedRate = &v + return s +} + +// SetInterval sets the Interval field's value. +func (s *SamplingTargetDocument) SetInterval(v int64) *SamplingTargetDocument { + s.Interval = &v + return s +} + +// SetReservoirQuota sets the ReservoirQuota field's value. +func (s *SamplingTargetDocument) SetReservoirQuota(v int64) *SamplingTargetDocument { + s.ReservoirQuota = &v + return s +} + +// SetReservoirQuotaTTL sets the ReservoirQuotaTTL field's value. +func (s *SamplingTargetDocument) SetReservoirQuotaTTL(v time.Time) *SamplingTargetDocument { + s.ReservoirQuotaTTL = &v + return s +} + +// SetRuleName sets the RuleName field's value. +func (s *SamplingTargetDocument) SetRuleName(v string) *SamplingTargetDocument { + s.RuleName = &v + return s +} + +// A segment from a trace that has been ingested by the X-Ray service. The segment +// can be compiled from documents uploaded with PutTraceSegments, or an inferred +// segment for a downstream service, generated from a subsegment sent by the +// service that called it. +// +// For the full segment document schema, see AWS X-Ray Segment Documents (https://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html) +// in the AWS X-Ray Developer Guide. +type Segment struct { + _ struct{} `type:"structure"` + + // The segment document. + Document *string `min:"1" type:"string"` + + // The segment's ID. + Id *string `type:"string"` +} + +// String returns the string representation +func (s Segment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Segment) GoString() string { + return s.String() +} + +// SetDocument sets the Document field's value. +func (s *Segment) SetDocument(v string) *Segment { + s.Document = &v + return s +} + +// SetId sets the Id field's value. +func (s *Segment) SetId(v string) *Segment { + s.Id = &v + return s +} + +// Information about an application that processed requests, users that made +// requests, or downstream services, resources and applications that an application +// used. +type Service struct { + _ struct{} `type:"structure"` + + // Identifier of the AWS account in which the service runs. + AccountId *string `type:"string"` + + // A histogram that maps the spread of service durations. + DurationHistogram []*HistogramEntry `type:"list"` + + // Connections to downstream services. + Edges []*Edge `type:"list"` + + // The end time of the last segment that the service generated. + EndTime *time.Time `type:"timestamp"` + + // The canonical name of the service. + Name *string `type:"string"` + + // A list of names for the service, including the canonical name. + Names []*string `type:"list"` + + // Identifier for the service. Unique within the service map. + ReferenceId *int64 `type:"integer"` + + // A histogram that maps the spread of service response times. + ResponseTimeHistogram []*HistogramEntry `type:"list"` + + // Indicates that the service was the first service to process a request. + Root *bool `type:"boolean"` + + // The start time of the first segment that the service generated. + StartTime *time.Time `type:"timestamp"` + + // The service's state. + State *string `type:"string"` + + // Aggregated statistics for the service. + SummaryStatistics *ServiceStatistics `type:"structure"` + + // The type of service. + // + // * AWS Resource - The type of an AWS resource. For example, AWS::EC2::Instance + // for a application running on Amazon EC2 or AWS::DynamoDB::Table for an + // Amazon DynamoDB table that the application used. + // + // * AWS Service - The type of an AWS service. For example, AWS::DynamoDB + // for downstream calls to Amazon DynamoDB that didn't target a specific + // table. + // + // * client - Represents the clients that sent requests to a root service. + // + // * remote - A downstream service of indeterminate type. + Type *string `type:"string"` +} + +// String returns the string representation +func (s Service) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Service) GoString() string { + return s.String() +} + +// SetAccountId sets the AccountId field's value. +func (s *Service) SetAccountId(v string) *Service { + s.AccountId = &v + return s +} + +// SetDurationHistogram sets the DurationHistogram field's value. +func (s *Service) SetDurationHistogram(v []*HistogramEntry) *Service { + s.DurationHistogram = v + return s +} + +// SetEdges sets the Edges field's value. +func (s *Service) SetEdges(v []*Edge) *Service { + s.Edges = v + return s +} + +// SetEndTime sets the EndTime field's value. +func (s *Service) SetEndTime(v time.Time) *Service { + s.EndTime = &v + return s +} + +// SetName sets the Name field's value. +func (s *Service) SetName(v string) *Service { + s.Name = &v + return s +} + +// SetNames sets the Names field's value. +func (s *Service) SetNames(v []*string) *Service { + s.Names = v + return s +} + +// SetReferenceId sets the ReferenceId field's value. +func (s *Service) SetReferenceId(v int64) *Service { + s.ReferenceId = &v + return s +} + +// SetResponseTimeHistogram sets the ResponseTimeHistogram field's value. +func (s *Service) SetResponseTimeHistogram(v []*HistogramEntry) *Service { + s.ResponseTimeHistogram = v + return s +} + +// SetRoot sets the Root field's value. +func (s *Service) SetRoot(v bool) *Service { + s.Root = &v + return s +} + +// SetStartTime sets the StartTime field's value. +func (s *Service) SetStartTime(v time.Time) *Service { + s.StartTime = &v + return s +} + +// SetState sets the State field's value. +func (s *Service) SetState(v string) *Service { + s.State = &v + return s +} + +// SetSummaryStatistics sets the SummaryStatistics field's value. +func (s *Service) SetSummaryStatistics(v *ServiceStatistics) *Service { + s.SummaryStatistics = v + return s +} + +// SetType sets the Type field's value. +func (s *Service) SetType(v string) *Service { + s.Type = &v + return s +} + +type ServiceId struct { + _ struct{} `type:"structure"` + + AccountId *string `type:"string"` + + Name *string `type:"string"` + + Names []*string `type:"list"` + + Type *string `type:"string"` +} + +// String returns the string representation +func (s ServiceId) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ServiceId) GoString() string { + return s.String() +} + +// SetAccountId sets the AccountId field's value. +func (s *ServiceId) SetAccountId(v string) *ServiceId { + s.AccountId = &v + return s +} + +// SetName sets the Name field's value. +func (s *ServiceId) SetName(v string) *ServiceId { + s.Name = &v + return s +} + +// SetNames sets the Names field's value. +func (s *ServiceId) SetNames(v []*string) *ServiceId { + s.Names = v + return s +} + +// SetType sets the Type field's value. +func (s *ServiceId) SetType(v string) *ServiceId { + s.Type = &v + return s +} + +// Response statistics for a service. +type ServiceStatistics struct { + _ struct{} `type:"structure"` + + // Information about requests that failed with a 4xx Client Error status code. + ErrorStatistics *ErrorStatistics `type:"structure"` + + // Information about requests that failed with a 5xx Server Error status code. + FaultStatistics *FaultStatistics `type:"structure"` + + // The number of requests that completed with a 2xx Success status code. + OkCount *int64 `type:"long"` + + // The total number of completed requests. + TotalCount *int64 `type:"long"` + + // The aggregate response time of completed requests. + TotalResponseTime *float64 `type:"double"` +} + +// String returns the string representation +func (s ServiceStatistics) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ServiceStatistics) GoString() string { + return s.String() +} + +// SetErrorStatistics sets the ErrorStatistics field's value. +func (s *ServiceStatistics) SetErrorStatistics(v *ErrorStatistics) *ServiceStatistics { + s.ErrorStatistics = v + return s +} + +// SetFaultStatistics sets the FaultStatistics field's value. +func (s *ServiceStatistics) SetFaultStatistics(v *FaultStatistics) *ServiceStatistics { + s.FaultStatistics = v + return s +} + +// SetOkCount sets the OkCount field's value. +func (s *ServiceStatistics) SetOkCount(v int64) *ServiceStatistics { + s.OkCount = &v + return s +} + +// SetTotalCount sets the TotalCount field's value. +func (s *ServiceStatistics) SetTotalCount(v int64) *ServiceStatistics { + s.TotalCount = &v + return s +} + +// SetTotalResponseTime sets the TotalResponseTime field's value. +func (s *ServiceStatistics) SetTotalResponseTime(v float64) *ServiceStatistics { + s.TotalResponseTime = &v + return s +} + +type TelemetryRecord struct { + _ struct{} `type:"structure"` + + BackendConnectionErrors *BackendConnectionErrors `type:"structure"` + + SegmentsReceivedCount *int64 `type:"integer"` + + SegmentsRejectedCount *int64 `type:"integer"` + + SegmentsSentCount *int64 `type:"integer"` + + SegmentsSpilloverCount *int64 `type:"integer"` + + // Timestamp is a required field + Timestamp *time.Time `type:"timestamp" required:"true"` +} + +// String returns the string representation +func (s TelemetryRecord) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TelemetryRecord) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *TelemetryRecord) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "TelemetryRecord"} + if s.Timestamp == nil { + invalidParams.Add(request.NewErrParamRequired("Timestamp")) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetBackendConnectionErrors sets the BackendConnectionErrors field's value. +func (s *TelemetryRecord) SetBackendConnectionErrors(v *BackendConnectionErrors) *TelemetryRecord { + s.BackendConnectionErrors = v + return s +} + +// SetSegmentsReceivedCount sets the SegmentsReceivedCount field's value. +func (s *TelemetryRecord) SetSegmentsReceivedCount(v int64) *TelemetryRecord { + s.SegmentsReceivedCount = &v + return s +} + +// SetSegmentsRejectedCount sets the SegmentsRejectedCount field's value. +func (s *TelemetryRecord) SetSegmentsRejectedCount(v int64) *TelemetryRecord { + s.SegmentsRejectedCount = &v + return s +} + +// SetSegmentsSentCount sets the SegmentsSentCount field's value. +func (s *TelemetryRecord) SetSegmentsSentCount(v int64) *TelemetryRecord { + s.SegmentsSentCount = &v + return s +} + +// SetSegmentsSpilloverCount sets the SegmentsSpilloverCount field's value. +func (s *TelemetryRecord) SetSegmentsSpilloverCount(v int64) *TelemetryRecord { + s.SegmentsSpilloverCount = &v + return s +} + +// SetTimestamp sets the Timestamp field's value. +func (s *TelemetryRecord) SetTimestamp(v time.Time) *TelemetryRecord { + s.Timestamp = &v + return s +} + +// A list of TimeSeriesStatistic structures. +type TimeSeriesServiceStatistics struct { + _ struct{} `type:"structure"` + + // Response statistics for an edge. + EdgeSummaryStatistics *EdgeStatistics `type:"structure"` + + // The response time histogram for the selected entities. + ResponseTimeHistogram []*HistogramEntry `type:"list"` + + // Response statistics for a service. + ServiceSummaryStatistics *ServiceStatistics `type:"structure"` + + // Timestamp of the window for which statistics are aggregated. + Timestamp *time.Time `type:"timestamp"` +} + +// String returns the string representation +func (s TimeSeriesServiceStatistics) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TimeSeriesServiceStatistics) GoString() string { + return s.String() +} + +// SetEdgeSummaryStatistics sets the EdgeSummaryStatistics field's value. +func (s *TimeSeriesServiceStatistics) SetEdgeSummaryStatistics(v *EdgeStatistics) *TimeSeriesServiceStatistics { + s.EdgeSummaryStatistics = v + return s +} + +// SetResponseTimeHistogram sets the ResponseTimeHistogram field's value. +func (s *TimeSeriesServiceStatistics) SetResponseTimeHistogram(v []*HistogramEntry) *TimeSeriesServiceStatistics { + s.ResponseTimeHistogram = v + return s +} + +// SetServiceSummaryStatistics sets the ServiceSummaryStatistics field's value. +func (s *TimeSeriesServiceStatistics) SetServiceSummaryStatistics(v *ServiceStatistics) *TimeSeriesServiceStatistics { + s.ServiceSummaryStatistics = v + return s +} + +// SetTimestamp sets the Timestamp field's value. +func (s *TimeSeriesServiceStatistics) SetTimestamp(v time.Time) *TimeSeriesServiceStatistics { + s.Timestamp = &v + return s +} + +// A collection of segment documents with matching trace IDs. +type Trace struct { + _ struct{} `type:"structure"` + + // The length of time in seconds between the start time of the root segment + // and the end time of the last segment that completed. + Duration *float64 `type:"double"` + + // The unique identifier for the request that generated the trace's segments + // and subsegments. + Id *string `min:"1" type:"string"` + + // Segment documents for the segments and subsegments that comprise the trace. + Segments []*Segment `type:"list"` +} + +// String returns the string representation +func (s Trace) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s Trace) GoString() string { + return s.String() +} + +// SetDuration sets the Duration field's value. +func (s *Trace) SetDuration(v float64) *Trace { + s.Duration = &v + return s +} + +// SetId sets the Id field's value. +func (s *Trace) SetId(v string) *Trace { + s.Id = &v + return s +} + +// SetSegments sets the Segments field's value. +func (s *Trace) SetSegments(v []*Segment) *Trace { + s.Segments = v + return s +} + +// Metadata generated from the segment documents in a trace. +type TraceSummary struct { + _ struct{} `type:"structure"` + + // Annotations from the trace's segment documents. + Annotations map[string][]*ValueWithServiceIds `type:"map"` + + // A list of availability zones for any zone corresponding to the trace segments. + AvailabilityZones []*AvailabilityZoneDetail `type:"list"` + + // The length of time in seconds between the start time of the root segment + // and the end time of the last segment that completed. + Duration *float64 `type:"double"` + + // The root of a trace. + EntryPoint *ServiceId `type:"structure"` + + // A collection of ErrorRootCause structures corresponding to the trace segments. + ErrorRootCauses []*ErrorRootCause `type:"list"` + + // A collection of FaultRootCause structures corresponding to the the trace + // segments. + FaultRootCauses []*FaultRootCause `type:"list"` + + // One or more of the segment documents has a 400 series error. + HasError *bool `type:"boolean"` + + // One or more of the segment documents has a 500 series error. + HasFault *bool `type:"boolean"` + + // One or more of the segment documents has a 429 throttling error. + HasThrottle *bool `type:"boolean"` + + // Information about the HTTP request served by the trace. + Http *Http `type:"structure"` + + // The unique identifier for the request that generated the trace's segments + // and subsegments. + Id *string `min:"1" type:"string"` + + // A list of EC2 instance IDs for any instance corresponding to the trace segments. + InstanceIds []*InstanceIdDetail `type:"list"` + + // One or more of the segment documents is in progress. + IsPartial *bool `type:"boolean"` + + // The matched time stamp of a defined event. + MatchedEventTime *time.Time `type:"timestamp"` + + // A list of resource ARNs for any resource corresponding to the trace segments. + ResourceARNs []*ResourceARNDetail `type:"list"` + + // The length of time in seconds between the start and end times of the root + // segment. If the service performs work asynchronously, the response time measures + // the time before the response is sent to the user, while the duration measures + // the amount of time before the last traced activity completes. + ResponseTime *float64 `type:"double"` + + // A collection of ResponseTimeRootCause structures corresponding to the trace + // segments. + ResponseTimeRootCauses []*ResponseTimeRootCause `type:"list"` + + // The revision number of a trace. + Revision *int64 `type:"integer"` + + // Service IDs from the trace's segment documents. + ServiceIds []*ServiceId `type:"list"` + + // Users from the trace's segment documents. + Users []*TraceUser `type:"list"` +} + +// String returns the string representation +func (s TraceSummary) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TraceSummary) GoString() string { + return s.String() +} + +// SetAnnotations sets the Annotations field's value. +func (s *TraceSummary) SetAnnotations(v map[string][]*ValueWithServiceIds) *TraceSummary { + s.Annotations = v + return s +} + +// SetAvailabilityZones sets the AvailabilityZones field's value. +func (s *TraceSummary) SetAvailabilityZones(v []*AvailabilityZoneDetail) *TraceSummary { + s.AvailabilityZones = v + return s +} + +// SetDuration sets the Duration field's value. +func (s *TraceSummary) SetDuration(v float64) *TraceSummary { + s.Duration = &v + return s +} + +// SetEntryPoint sets the EntryPoint field's value. +func (s *TraceSummary) SetEntryPoint(v *ServiceId) *TraceSummary { + s.EntryPoint = v + return s +} + +// SetErrorRootCauses sets the ErrorRootCauses field's value. +func (s *TraceSummary) SetErrorRootCauses(v []*ErrorRootCause) *TraceSummary { + s.ErrorRootCauses = v + return s +} + +// SetFaultRootCauses sets the FaultRootCauses field's value. +func (s *TraceSummary) SetFaultRootCauses(v []*FaultRootCause) *TraceSummary { + s.FaultRootCauses = v + return s +} + +// SetHasError sets the HasError field's value. +func (s *TraceSummary) SetHasError(v bool) *TraceSummary { + s.HasError = &v + return s +} + +// SetHasFault sets the HasFault field's value. +func (s *TraceSummary) SetHasFault(v bool) *TraceSummary { + s.HasFault = &v + return s +} + +// SetHasThrottle sets the HasThrottle field's value. +func (s *TraceSummary) SetHasThrottle(v bool) *TraceSummary { + s.HasThrottle = &v + return s +} + +// SetHttp sets the Http field's value. +func (s *TraceSummary) SetHttp(v *Http) *TraceSummary { + s.Http = v + return s +} + +// SetId sets the Id field's value. +func (s *TraceSummary) SetId(v string) *TraceSummary { + s.Id = &v + return s +} + +// SetInstanceIds sets the InstanceIds field's value. +func (s *TraceSummary) SetInstanceIds(v []*InstanceIdDetail) *TraceSummary { + s.InstanceIds = v + return s +} + +// SetIsPartial sets the IsPartial field's value. +func (s *TraceSummary) SetIsPartial(v bool) *TraceSummary { + s.IsPartial = &v + return s +} + +// SetMatchedEventTime sets the MatchedEventTime field's value. +func (s *TraceSummary) SetMatchedEventTime(v time.Time) *TraceSummary { + s.MatchedEventTime = &v + return s +} + +// SetResourceARNs sets the ResourceARNs field's value. +func (s *TraceSummary) SetResourceARNs(v []*ResourceARNDetail) *TraceSummary { + s.ResourceARNs = v + return s +} + +// SetResponseTime sets the ResponseTime field's value. +func (s *TraceSummary) SetResponseTime(v float64) *TraceSummary { + s.ResponseTime = &v + return s +} + +// SetResponseTimeRootCauses sets the ResponseTimeRootCauses field's value. +func (s *TraceSummary) SetResponseTimeRootCauses(v []*ResponseTimeRootCause) *TraceSummary { + s.ResponseTimeRootCauses = v + return s +} + +// SetRevision sets the Revision field's value. +func (s *TraceSummary) SetRevision(v int64) *TraceSummary { + s.Revision = &v + return s +} + +// SetServiceIds sets the ServiceIds field's value. +func (s *TraceSummary) SetServiceIds(v []*ServiceId) *TraceSummary { + s.ServiceIds = v + return s +} + +// SetUsers sets the Users field's value. +func (s *TraceSummary) SetUsers(v []*TraceUser) *TraceSummary { + s.Users = v + return s +} + +// Information about a user recorded in segment documents. +type TraceUser struct { + _ struct{} `type:"structure"` + + // Services that the user's request hit. + ServiceIds []*ServiceId `type:"list"` + + // The user's name. + UserName *string `type:"string"` +} + +// String returns the string representation +func (s TraceUser) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s TraceUser) GoString() string { + return s.String() +} + +// SetServiceIds sets the ServiceIds field's value. +func (s *TraceUser) SetServiceIds(v []*ServiceId) *TraceUser { + s.ServiceIds = v + return s +} + +// SetUserName sets the UserName field's value. +func (s *TraceUser) SetUserName(v string) *TraceUser { + s.UserName = &v + return s +} + +// Sampling statistics from a call to GetSamplingTargets that X-Ray could not +// process. +type UnprocessedStatistics struct { + _ struct{} `type:"structure"` + + // The error code. + ErrorCode *string `type:"string"` + + // The error message. + Message *string `type:"string"` + + // The name of the sampling rule. + RuleName *string `type:"string"` +} + +// String returns the string representation +func (s UnprocessedStatistics) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnprocessedStatistics) GoString() string { + return s.String() +} + +// SetErrorCode sets the ErrorCode field's value. +func (s *UnprocessedStatistics) SetErrorCode(v string) *UnprocessedStatistics { + s.ErrorCode = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *UnprocessedStatistics) SetMessage(v string) *UnprocessedStatistics { + s.Message = &v + return s +} + +// SetRuleName sets the RuleName field's value. +func (s *UnprocessedStatistics) SetRuleName(v string) *UnprocessedStatistics { + s.RuleName = &v + return s +} + +// Information about a segment that failed processing. +type UnprocessedTraceSegment struct { + _ struct{} `type:"structure"` + + // The error that caused processing to fail. + ErrorCode *string `type:"string"` + + // The segment's ID. + Id *string `type:"string"` + + // The error message. + Message *string `type:"string"` +} + +// String returns the string representation +func (s UnprocessedTraceSegment) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UnprocessedTraceSegment) GoString() string { + return s.String() +} + +// SetErrorCode sets the ErrorCode field's value. +func (s *UnprocessedTraceSegment) SetErrorCode(v string) *UnprocessedTraceSegment { + s.ErrorCode = &v + return s +} + +// SetId sets the Id field's value. +func (s *UnprocessedTraceSegment) SetId(v string) *UnprocessedTraceSegment { + s.Id = &v + return s +} + +// SetMessage sets the Message field's value. +func (s *UnprocessedTraceSegment) SetMessage(v string) *UnprocessedTraceSegment { + s.Message = &v + return s +} + +type UpdateGroupInput struct { + _ struct{} `type:"structure"` + + // The updated filter expression defining criteria by which to group traces. + FilterExpression *string `type:"string"` + + // The ARN that was generated upon creation. + GroupARN *string `min:"1" type:"string"` + + // The case-sensitive name of the group. + GroupName *string `min:"1" type:"string"` +} + +// String returns the string representation +func (s UpdateGroupInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateGroupInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateGroupInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateGroupInput"} + if s.GroupARN != nil && len(*s.GroupARN) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupARN", 1)) + } + if s.GroupName != nil && len(*s.GroupName) < 1 { + invalidParams.Add(request.NewErrParamMinLen("GroupName", 1)) + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetFilterExpression sets the FilterExpression field's value. +func (s *UpdateGroupInput) SetFilterExpression(v string) *UpdateGroupInput { + s.FilterExpression = &v + return s +} + +// SetGroupARN sets the GroupARN field's value. +func (s *UpdateGroupInput) SetGroupARN(v string) *UpdateGroupInput { + s.GroupARN = &v + return s +} + +// SetGroupName sets the GroupName field's value. +func (s *UpdateGroupInput) SetGroupName(v string) *UpdateGroupInput { + s.GroupName = &v + return s +} + +type UpdateGroupOutput struct { + _ struct{} `type:"structure"` + + // The group that was updated. Contains the name of the group that was updated, + // the ARN of the group that was updated, and the updated filter expression + // assigned to the group. + Group *Group `type:"structure"` +} + +// String returns the string representation +func (s UpdateGroupOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateGroupOutput) GoString() string { + return s.String() +} + +// SetGroup sets the Group field's value. +func (s *UpdateGroupOutput) SetGroup(v *Group) *UpdateGroupOutput { + s.Group = v + return s +} + +type UpdateSamplingRuleInput struct { + _ struct{} `type:"structure"` + + // The rule and fields to change. + // + // SamplingRuleUpdate is a required field + SamplingRuleUpdate *SamplingRuleUpdate `type:"structure" required:"true"` +} + +// String returns the string representation +func (s UpdateSamplingRuleInput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateSamplingRuleInput) GoString() string { + return s.String() +} + +// Validate inspects the fields of the type to determine if they are valid. +func (s *UpdateSamplingRuleInput) Validate() error { + invalidParams := request.ErrInvalidParams{Context: "UpdateSamplingRuleInput"} + if s.SamplingRuleUpdate == nil { + invalidParams.Add(request.NewErrParamRequired("SamplingRuleUpdate")) + } + if s.SamplingRuleUpdate != nil { + if err := s.SamplingRuleUpdate.Validate(); err != nil { + invalidParams.AddNested("SamplingRuleUpdate", err.(request.ErrInvalidParams)) + } + } + + if invalidParams.Len() > 0 { + return invalidParams + } + return nil +} + +// SetSamplingRuleUpdate sets the SamplingRuleUpdate field's value. +func (s *UpdateSamplingRuleInput) SetSamplingRuleUpdate(v *SamplingRuleUpdate) *UpdateSamplingRuleInput { + s.SamplingRuleUpdate = v + return s +} + +type UpdateSamplingRuleOutput struct { + _ struct{} `type:"structure"` + + // The updated rule definition and metadata. + SamplingRuleRecord *SamplingRuleRecord `type:"structure"` +} + +// String returns the string representation +func (s UpdateSamplingRuleOutput) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s UpdateSamplingRuleOutput) GoString() string { + return s.String() +} + +// SetSamplingRuleRecord sets the SamplingRuleRecord field's value. +func (s *UpdateSamplingRuleOutput) SetSamplingRuleRecord(v *SamplingRuleRecord) *UpdateSamplingRuleOutput { + s.SamplingRuleRecord = v + return s +} + +// Information about a segment annotation. +type ValueWithServiceIds struct { + _ struct{} `type:"structure"` + + // Values of the annotation. + AnnotationValue *AnnotationValue `type:"structure"` + + // Services to which the annotation applies. + ServiceIds []*ServiceId `type:"list"` +} + +// String returns the string representation +func (s ValueWithServiceIds) String() string { + return awsutil.Prettify(s) +} + +// GoString returns the string representation +func (s ValueWithServiceIds) GoString() string { + return s.String() +} + +// SetAnnotationValue sets the AnnotationValue field's value. +func (s *ValueWithServiceIds) SetAnnotationValue(v *AnnotationValue) *ValueWithServiceIds { + s.AnnotationValue = v + return s +} + +// SetServiceIds sets the ServiceIds field's value. +func (s *ValueWithServiceIds) SetServiceIds(v []*ServiceId) *ValueWithServiceIds { + s.ServiceIds = v + return s +} + +const ( + // EncryptionStatusUpdating is a EncryptionStatus enum value + EncryptionStatusUpdating = "UPDATING" + + // EncryptionStatusActive is a EncryptionStatus enum value + EncryptionStatusActive = "ACTIVE" +) + +const ( + // EncryptionTypeNone is a EncryptionType enum value + EncryptionTypeNone = "NONE" + + // EncryptionTypeKms is a EncryptionType enum value + EncryptionTypeKms = "KMS" +) + +const ( + // SamplingStrategyNamePartialScan is a SamplingStrategyName enum value + SamplingStrategyNamePartialScan = "PartialScan" + + // SamplingStrategyNameFixedRate is a SamplingStrategyName enum value + SamplingStrategyNameFixedRate = "FixedRate" +) + +const ( + // TimeRangeTypeTraceId is a TimeRangeType enum value + TimeRangeTypeTraceId = "TraceId" + + // TimeRangeTypeEvent is a TimeRangeType enum value + TimeRangeTypeEvent = "Event" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/xray/doc.go b/vendor/github.com/aws/aws-sdk-go/service/xray/doc.go new file mode 100644 index 00000000..a33a8cc9 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/xray/doc.go @@ -0,0 +1,29 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +// Package xray provides the client and types for making API +// requests to AWS X-Ray. +// +// AWS X-Ray provides APIs for managing debug traces and retrieving service +// maps and other data created by processing those traces. +// +// See https://docs.aws.amazon.com/goto/WebAPI/xray-2016-04-12 for more information on this service. +// +// See xray package documentation for more information. +// https://docs.aws.amazon.com/sdk-for-go/api/service/xray/ +// +// Using the Client +// +// To contact AWS X-Ray with the SDK use the New function to create +// a new service client. With that client you can make API requests to the service. +// These clients are safe to use concurrently. +// +// See the SDK's documentation for more information on how to use the SDK. +// https://docs.aws.amazon.com/sdk-for-go/api/ +// +// See aws.Config documentation for more information on configuring SDK clients. +// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config +// +// See the AWS X-Ray client XRay for more +// information on creating client for this service. +// https://docs.aws.amazon.com/sdk-for-go/api/service/xray/#New +package xray diff --git a/vendor/github.com/aws/aws-sdk-go/service/xray/errors.go b/vendor/github.com/aws/aws-sdk-go/service/xray/errors.go new file mode 100644 index 00000000..7888dd20 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/xray/errors.go @@ -0,0 +1,24 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package xray + +const ( + + // ErrCodeInvalidRequestException for service response error code + // "InvalidRequestException". + // + // The request is missing required parameters or has invalid parameters. + ErrCodeInvalidRequestException = "InvalidRequestException" + + // ErrCodeRuleLimitExceededException for service response error code + // "RuleLimitExceededException". + // + // You have reached the maximum number of sampling rules. + ErrCodeRuleLimitExceededException = "RuleLimitExceededException" + + // ErrCodeThrottledException for service response error code + // "ThrottledException". + // + // The request exceeds the maximum number of requests per second. + ErrCodeThrottledException = "ThrottledException" +) diff --git a/vendor/github.com/aws/aws-sdk-go/service/xray/service.go b/vendor/github.com/aws/aws-sdk-go/service/xray/service.go new file mode 100644 index 00000000..fdc5ea32 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go/service/xray/service.go @@ -0,0 +1,95 @@ +// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT. + +package xray + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/client" + "github.com/aws/aws-sdk-go/aws/client/metadata" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/signer/v4" + "github.com/aws/aws-sdk-go/private/protocol/restjson" +) + +// XRay provides the API operation methods for making requests to +// AWS X-Ray. See this package's package overview docs +// for details on the service. +// +// XRay methods are safe to use concurrently. It is not safe to +// modify mutate any of the struct's properties though. +type XRay struct { + *client.Client +} + +// Used for custom client initialization logic +var initClient func(*client.Client) + +// Used for custom request initialization logic +var initRequest func(*request.Request) + +// Service information constants +const ( + ServiceName = "xray" // Name of service. + EndpointsID = ServiceName // ID to lookup a service endpoint with. + ServiceID = "XRay" // ServiceID is a unique identifer of a specific service. +) + +// New creates a new instance of the XRay client with a session. +// If additional configuration is needed for the client instance use the optional +// aws.Config parameter to add your extra config. +// +// Example: +// // Create a XRay client from just a session. +// svc := xray.New(mySession) +// +// // Create a XRay client with additional configuration +// svc := xray.New(mySession, aws.NewConfig().WithRegion("us-west-2")) +func New(p client.ConfigProvider, cfgs ...*aws.Config) *XRay { + c := p.ClientConfig(EndpointsID, cfgs...) + return newClient(*c.Config, c.Handlers, c.Endpoint, c.SigningRegion, c.SigningName) +} + +// newClient creates, initializes and returns a new service client instance. +func newClient(cfg aws.Config, handlers request.Handlers, endpoint, signingRegion, signingName string) *XRay { + svc := &XRay{ + Client: client.New( + cfg, + metadata.ClientInfo{ + ServiceName: ServiceName, + ServiceID: ServiceID, + SigningName: signingName, + SigningRegion: signingRegion, + Endpoint: endpoint, + APIVersion: "2016-04-12", + }, + handlers, + ), + } + + // Handlers + svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler) + svc.Handlers.Build.PushBackNamed(restjson.BuildHandler) + svc.Handlers.Unmarshal.PushBackNamed(restjson.UnmarshalHandler) + svc.Handlers.UnmarshalMeta.PushBackNamed(restjson.UnmarshalMetaHandler) + svc.Handlers.UnmarshalError.PushBackNamed(restjson.UnmarshalErrorHandler) + + // Run custom client initialization if present + if initClient != nil { + initClient(svc.Client) + } + + return svc +} + +// newRequest creates a new request for a XRay operation and runs any +// custom request initialization. +func (c *XRay) newRequest(op *request.Operation, params, data interface{}) *request.Request { + req := c.NewRequest(op, params, data) + + // Run custom request initialization if present + if initRequest != nil { + initRequest(req) + } + + return req +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/daemoncfg/daemon_config.go b/vendor/github.com/aws/aws-xray-sdk-go/daemoncfg/daemon_config.go new file mode 100644 index 00000000..26f00eee --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/daemoncfg/daemon_config.go @@ -0,0 +1,172 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +package daemoncfg + +import ( + "net" + "os" + "strconv" + "strings" + + log "github.com/cihub/seelog" + + "github.com/pkg/errors" +) + +var addressDelimiter = " " // delimiter between tcp and udp addresses +var udpKey = "udp" +var tcpKey = "tcp" + +/// DaemonEndpoints stores X-Ray daemon configuration about the ip address and port for UDP and TCP port. It gets the address +/// string from "AWS_TRACING_DAEMON_ADDRESS" and then from recorder's configuration for DaemonAddr. +/// A notation of '127.0.0.1:2000' or 'tcp:127.0.0.1:2000 udp:127.0.0.2:2001' or 'udp:127.0.0.1:2000 tcp:127.0.0.2:2001' +/// are both acceptable. The first one means UDP and TCP are running at the same address. +/// Notation 'hostname:2000' or 'tcp:hostname:2000 udp:hostname:2001' or 'udp:hostname:2000 tcp:hostname:2001' are also acceptable. +/// By default it assumes a X-Ray daemon running at 127.0.0.1:2000 listening to both UDP and TCP traffic. +type DaemonEndpoints struct { + // UDPAddr represents UDP endpoint for segments to be sent by emitter. + UDPAddr *net.UDPAddr + // TCPAddr represents TCP endpoint of the daemon to make sampling API calls. + TCPAddr *net.TCPAddr +} + +// GetDaemonEndpoints returns DaemonEndpoints. +func GetDaemonEndpoints() *DaemonEndpoints { + daemonEndpoint, err := GetDaemonEndpointsFromString("") // only environment variable would be parsed + + if err != nil { + panic(err) + } + + if daemonEndpoint == nil { // env variable not set + udpAddr := &net.UDPAddr{ // use default address + IP: net.IPv4(127, 0, 0, 1), + Port: 2000, + } + + tcpAddr := &net.TCPAddr{ // use default address + IP: net.IPv4(127, 0, 0, 1), + Port: 2000, + } + + return &DaemonEndpoints{ + UDPAddr: udpAddr, + TCPAddr: tcpAddr, + } + } + return daemonEndpoint // env variable successfully parsed +} + +// GetDaemonEndpointsFromString parses provided daemon address if the environment variable is invalid or not set. +// DaemonEndpoints is non nil if the env variable or provided address is valid. +func GetDaemonEndpointsFromString(dAddr string) (*DaemonEndpoints, error) { + var daemonAddr string + // Try to get the X-Ray daemon address from an environment variable + if envDaemonAddr := os.Getenv("AWS_XRAY_DAEMON_ADDRESS"); envDaemonAddr != "" { + daemonAddr = envDaemonAddr + log.Infof("using daemon endpoints from environment variable AWS_XRAY_DAEMON_ADDRESS: %v", envDaemonAddr) + } else if dAddr != "" { + daemonAddr = dAddr + } + if daemonAddr != "" { + return resolveAddress(daemonAddr) + } + return nil, nil +} + +func resolveAddress(dAddr string) (*DaemonEndpoints, error) { + addr := strings.Split(dAddr, addressDelimiter) + if len(addr) == 1 { + return parseSingleForm(addr[0]) + } else if len(addr) == 2 { + return parseDoubleForm(addr) + + } else { + return nil, errors.New("invalid daemon address: " + dAddr) + } + + return nil, nil +} + +func parseDoubleForm(addr []string) (*DaemonEndpoints, error) { + addr1 := strings.Split(addr[0], ":") // tcp:127.0.0.1:2000 or udp:127.0.0.1:2000 + addr2 := strings.Split(addr[1], ":") // tcp:127.0.0.1:2000 or udp:127.0.0.1:2000 + + if len(addr1) != 3 || len(addr2) != 3 { + return nil, errors.New("invalid daemon address: " + addr[0] + " " + addr[1]) + } + + // validate ports + _, pErr1 := strconv.Atoi(addr1[2]) + _, pErr2 := strconv.Atoi(addr1[2]) + + if pErr1 != nil || pErr2 != nil { + return nil, errors.New("invalid daemon address port") + } + + addrMap := make(map[string]string) + + addrMap[addr1[0]] = addr1[1] + ":" + addr1[2] + addrMap[addr2[0]] = addr2[1] + ":" + addr2[2] + + if addrMap[udpKey] == "" || addrMap[tcpKey] == "" { // for double form, tcp and udp keywords should be present + return nil, errors.New("invalid daemon address") + } + + udpAddr, uErr := resolveUDPAddr(addrMap[udpKey]) + if uErr != nil { + return nil, uErr + } + + tcpAddr, tErr := resolveTCPAddr(addrMap[tcpKey]) + if tErr != nil { + return nil, tErr + } + + return &DaemonEndpoints{ + UDPAddr: udpAddr, + TCPAddr: tcpAddr, + }, nil +} + +func parseSingleForm(addr string) (*DaemonEndpoints, error) { // format = "ip:port" + a := strings.Split(addr, ":") // 127.0.0.1:2000 + + if len(a) != 2 { + return nil, errors.New("invalid daemon address: " + addr) + } + + // validate port + _, pErr1 := strconv.Atoi(a[1]) + + if pErr1 != nil { + return nil, errors.New("invalid daemon address port") + } + + udpAddr, uErr := resolveUDPAddr(addr) + if uErr != nil { + return nil, uErr + } + tcpAddr, tErr := resolveTCPAddr(addr) + if tErr != nil { + return nil, tErr + } + + return &DaemonEndpoints{ + UDPAddr: udpAddr, + TCPAddr: tcpAddr, + }, nil +} + +func resolveUDPAddr(s string) (*net.UDPAddr, error) { + return net.ResolveUDPAddr(udpKey, s) +} + +func resolveTCPAddr(s string) (*net.TCPAddr, error) { + return net.ResolveTCPAddr(tcpKey, s) +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/internal/plugins/plugin.go b/vendor/github.com/aws/aws-xray-sdk-go/internal/plugins/plugin.go index f19983db..636635d0 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/internal/plugins/plugin.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/internal/plugins/plugin.go @@ -8,8 +8,10 @@ package plugins -import ( - "github.com/aws/aws-sdk-go/aws/ec2metadata" +const ( + EBServiceName = "elastic_beanstalk" + EC2ServiceName = "ec2" + ECSServiceName = "ecs" ) // InstancePluginMetadata points to the PluginMetadata struct. @@ -19,19 +21,33 @@ var InstancePluginMetadata = &PluginMetadata{} // about the AWS infrastructure hosting the traced application. type PluginMetadata struct { - // IdentityDocument records the shape for unmarshaling an - // EC2 instance identity document. - IdentityDocument *ec2metadata.EC2InstanceIdentityDocument + // EC2Metadata records the ec2 instance ID and availability zone. + EC2Metadata *EC2Metadata // BeanstalkMetadata records the Elastic Beanstalk // environment name, version label, and deployment ID. BeanstalkMetadata *BeanstalkMetadata - // ECSContainerName records the ECS container ID. - ECSContainerName string + // ECSMetadata records the ECS container ID. + ECSMetadata *ECSMetadata + + // Origin records original service of the segment. + Origin string +} + +// EC2Metadata provides the shape for unmarshalling EC2 metadata. +type EC2Metadata struct { + InstanceID string `json:"instance_id"` + AvailabilityZone string `json:"availability_zone"` +} + +// ECSMetadata provides the shape for unmarshalling +// ECS metadata. +type ECSMetadata struct { + ContainerName string `json:"container"` } -// BeanstalkMetadata provides the shape for unmarshaling +// BeanstalkMetadata provides the shape for unmarshalling // Elastic Beanstalk environment metadata. type BeanstalkMetadata struct { Environment string `json:"environment_name"` diff --git a/vendor/github.com/aws/aws-xray-sdk-go/resources/DefaultSamplingRules.json b/vendor/github.com/aws/aws-xray-sdk-go/resources/DefaultSamplingRules.json index 4855f43f..57cbd828 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/resources/DefaultSamplingRules.json +++ b/vendor/github.com/aws/aws-xray-sdk-go/resources/DefaultSamplingRules.json @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "default": { "fixed_target": 1, "rate": 0.05 diff --git a/vendor/github.com/aws/aws-xray-sdk-go/resources/ExampleSamplingRules.json b/vendor/github.com/aws/aws-xray-sdk-go/resources/ExampleSamplingRules.json index 18ec2de4..2f76d793 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/resources/ExampleSamplingRules.json +++ b/vendor/github.com/aws/aws-xray-sdk-go/resources/ExampleSamplingRules.json @@ -1,5 +1,5 @@ { - "version": 1, + "version": 2, "default": { "description": "A default rule, as included below, is required in any sampling rules file. (service_name, http_method, and url_path are fixed to '*' for this rule.)", "fixed_target": 1, @@ -9,7 +9,7 @@ { "description": "Example path-based rule below. Rules are evaluated in id-order, the default rule will be used if none match the incoming request. This is a rule for the checkout page.", "id": "1", - "service_name": "*", + "host": "*", "http_method": "*", "url_path": "/checkout", "fixed_target": 10, diff --git a/vendor/github.com/aws/aws-xray-sdk-go/strategy/exception/default_exception_formatting_strategy.go b/vendor/github.com/aws/aws-xray-sdk-go/strategy/exception/default_exception_formatting_strategy.go index 9636a6eb..20dbf1ae 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/strategy/exception/default_exception_formatting_strategy.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/strategy/exception/default_exception_formatting_strategy.go @@ -15,6 +15,7 @@ import ( "runtime" "strings" + "github.com/aws/aws-sdk-go/aws/awserr" "github.com/pkg/errors" ) @@ -23,15 +24,16 @@ type StackTracer interface { StackTrace() []uintptr } -// Exception provides the shape for unmarshaling an exception. +// Exception provides the shape for unmarshalling an exception. type Exception struct { ID string `json:"id,omitempty"` Type string `json:"type,omitempty"` Message string `json:"message,omitempty"` Stack []Stack `json:"stack,omitempty"` + Remote bool `json:"remote,omitempty"` } -// Stack provides the shape for unmarshaling an stack. +// Stack provides the shape for unmarshalling an stack. type Stack struct { Path string `json:"path,omitempty"` Line int `json:"line,omitempty"` @@ -113,10 +115,18 @@ func (dEFS *DefaultFormattingStrategy) Panicf(formatString string, args ...inter // ExceptionFromError takes an error and returns value of Exception func (dEFS *DefaultFormattingStrategy) ExceptionFromError(err error) Exception { + var isRemote bool + if reqErr, ok := err.(awserr.RequestFailure); ok { + // A service error occurs + if reqErr.RequestID() != "" { + isRemote = true + } + } e := Exception{ ID: newExceptionID(), Type: "error", Message: err.Error(), + Remote: isRemote, } if err, ok := err.(*XRayError); ok { diff --git a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/centralized.go b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/centralized.go new file mode 100644 index 00000000..175c4835 --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/centralized.go @@ -0,0 +1,522 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +package sampling + +import ( + crypto "crypto/rand" + "errors" + "fmt" + "strings" + "sync" + "time" + + "github.com/aws/aws-xray-sdk-go/daemoncfg" + "github.com/aws/aws-xray-sdk-go/internal/plugins" + + "github.com/aws/aws-xray-sdk-go/utils" + + xraySvc "github.com/aws/aws-sdk-go/service/xray" + log "github.com/cihub/seelog" +) + +// CentralizedStrategy is an implementation of SamplingStrategy. It +// performs quota-based sampling with X-Ray acting as arbitrator for clients. +// It will fall back to LocalizedStrategy if sampling rules are not available from X-Ray APIS. +type CentralizedStrategy struct { + // List of known centralized sampling rules + manifest *CentralizedManifest + + // Sampling strategy used if centralized manifest is expired + fallback *LocalizedStrategy + + // XRay service proxy used for getting quotas and sampling rules + proxy svcProxy + + // Unique ID used by XRay service to identify this client + clientID string + + // Provides system time + clock utils.Clock + + // Provides random numbers + rand utils.Rand + + // pollerStart, if true represents rule and target pollers are started + pollerStart bool + + // represents daemon endpoints + daemonEndpoints *daemoncfg.DaemonEndpoints + + sync.RWMutex +} + +// svcProxy is the interface for API calls to X-Ray service. +type svcProxy interface { + GetSamplingTargets(s []*xraySvc.SamplingStatisticsDocument) (*xraySvc.GetSamplingTargetsOutput, error) + GetSamplingRules() ([]*xraySvc.SamplingRuleRecord, error) +} + +// NewCentralizedStrategy creates a centralized sampling strategy with a fallback on +// local default rule. +func NewCentralizedStrategy() (*CentralizedStrategy, error) { + fb, err := NewLocalizedStrategy() + if err != nil { + return nil, err + } + + return newCentralizedStrategy(fb) +} + +// NewCentralizedStrategyWithJSONBytes creates a centralized sampling strategy with a fallback on +// local rules specified in the given byte slice. +func NewCentralizedStrategyWithJSONBytes(b []byte) (*CentralizedStrategy, error) { + fb, err := NewLocalizedStrategyFromJSONBytes(b) + if err != nil { + return nil, err + } + + return newCentralizedStrategy(fb) +} + +// NewCentralizedStrategyWithFilePath creates a centralized sampling strategy with a fallback on +// local rules located at the given file path. +func NewCentralizedStrategyWithFilePath(fp string) (*CentralizedStrategy, error) { + fb, err := NewLocalizedStrategyFromFilePath(fp) + if err != nil { + return nil, err + } + + return newCentralizedStrategy(fb) +} + +func newCentralizedStrategy(fb *LocalizedStrategy) (*CentralizedStrategy, error) { + // Generate clientID + var r [12]byte + + _, err := crypto.Read(r[:]) + if err != nil { + return nil, err + } + + id := fmt.Sprintf("%02x", r) + + clock := &utils.DefaultClock{} + rand := &utils.DefaultRand{} + + m := &CentralizedManifest{ + Rules: []*CentralizedRule{}, + Index: map[string]*CentralizedRule{}, + clock: clock, + } + + ss := &CentralizedStrategy{ + manifest: m, + fallback: fb, + clientID: id, + clock: clock, + rand: rand, + } + + return ss, nil +} + +// ShouldTrace determines whether a request should be sampled. It matches the given parameters against +// a list of known rules and uses the matched rule's values to make a decision. +func (ss *CentralizedStrategy) ShouldTrace(request *Request) *Decision { + if !ss.pollerStart { + ss.start() + } + if request.ServiceType == "" { + request.ServiceType = plugins.InstancePluginMetadata.Origin + } + log.Tracef( + "Determining ShouldTrace decision for:\n\thost: %s\n\tpath: %s\n\tmethod: %s\n\tservicename: %s\n\tservicetype: %s", + request.Host, + request.Url, + request.Method, + request.ServiceName, + request.ServiceType, + ) + + // Use fallback if manifest is expired + if ss.manifest.expired() { + log.Trace("Centralized sampling data expired. Using fallback sampling strategy") + + return ss.fallback.ShouldTrace(request) + } + + ss.manifest.RLock() + defer ss.manifest.RUnlock() + + // Match against known rules + for _, r := range ss.manifest.Rules { + + r.RLock() + applicable := r.AppliesTo(request) + r.RUnlock() + + if !applicable { + continue + } + + log.Tracef("Applicable rule: %s", r.ruleName) + + return r.Sample() + } + + // Match against default rule + if r := ss.manifest.Default; r != nil { + log.Tracef("Applicable rule: %s", r.ruleName) + + return r.Sample() + } + + // Use fallback if default rule is unavailable + log.Trace("Centralized default sampling rule unavailable. Using fallback sampling strategy") + + return ss.fallback.ShouldTrace(request) +} + +// start initiates rule and target pollers. +func (ss *CentralizedStrategy) start() { + ss.Lock() + + if !ss.pollerStart { + var er error + ss.proxy, er = NewProxy(ss.daemonEndpoints) + if er != nil { + panic(er) + } + ss.startRulePoller() + ss.startTargetPoller() + } + + ss.pollerStart = true + + ss.Unlock() +} + +// startRulePoller starts rule poller. +func (ss *CentralizedStrategy) startRulePoller() { + // Initial refresh + go func() { + if err := ss.refreshManifest(); err != nil { + log.Tracef("Error occurred during initial refresh of sampling rules. %v", err) + } else { + log.Info("Successfully fetched sampling rules") + } + }() + + // Periodic manifest refresh + go func() { + // Period = 300s, Jitter = 5s + t := utils.NewTimer(300*time.Second, 5*time.Second) + + for range t.C() { + t.Reset() + if err := ss.refreshManifest(); err != nil { + log.Tracef("Error occurred while refreshing sampling rules. %v", err) + } else { + log.Info("Successfully fetched sampling rules") + } + } + }() +} + +// startTargetPoller starts target poller. +func (ss *CentralizedStrategy) startTargetPoller() { + // Periodic quota refresh + go func() { + // Period = 10.1s, Jitter = 100ms + t := utils.NewTimer(10*time.Second+100*time.Millisecond, 100*time.Millisecond) + + for range t.C() { + t.Reset() + if err := ss.refreshTargets(); err != nil { + log.Tracef("Error occurred while refreshing targets for sampling rules. %v", err) + } + } + }() +} + +// refreshManifest refreshes the manifest by calling the XRay service proxy for sampling rules +func (ss *CentralizedStrategy) refreshManifest() (err error) { + // Explicitly recover from panics since this is the entry point for a long-running goroutine + // and we can not allow a panic to propagate to the application code. + defer func() { + if r := recover(); r != nil { + // Resort to bring rules array into consistent state. + ss.manifest.sort() + + err = fmt.Errorf("%v", r) + } + }() + + // Compute 'now' before calling GetSamplingRules to avoid marking manifest as + // fresher than it actually is. + now := ss.clock.Now().Unix() + + // Get sampling rules from proxy + records, err := ss.proxy.GetSamplingRules() + if err != nil { + return + } + + // Set of rules to exclude from pruning + actives := map[*CentralizedRule]bool{} + + // Create missing rules. Update existing ones. + failed := false + for _, record := range records { + // Extract rule from record + svcRule := record.SamplingRule + if svcRule == nil { + log.Trace("Sampling rule missing from sampling rule record.") + failed = true + continue + } + + if svcRule.RuleName == nil { + log.Trace("Sampling rule without rule name is not supported") + failed = true + continue + } + + // Only sampling rule with version 1 is valid + if svcRule.Version == nil { + log.Trace("Sampling rule without version number is not supported: ", *svcRule.RuleName) + failed = true + continue + } + version := *svcRule.Version + if version != int64(1) { + log.Trace("Sampling rule without version 1 is not supported: ", *svcRule.RuleName) + failed = true + continue + } + + if len(svcRule.Attributes) != 0 { + log.Trace("Sampling rule with non nil Attributes is not applicable: ", *svcRule.RuleName) + continue + } + + if svcRule.ResourceARN == nil { + log.Trace("Sampling rule without ResourceARN is not applicable: ", *svcRule.RuleName) + continue + } + + resourceARN := *svcRule.ResourceARN + if resourceARN != "*" { + log.Trace("Sampling rule with ResourceARN not equal to * is not applicable: ", *svcRule.RuleName) + continue + } + + // Create/update rule + r, putErr := ss.manifest.putRule(svcRule) + if putErr != nil { + failed = true + log.Tracef("Error occurred creating/updating rule. %v", putErr) + } else if r != nil { + actives[r] = true + } + } + + // Set err if updates failed + if failed { + err = errors.New("error occurred creating/updating rules") + } + + // Prune inactive rules + ss.manifest.prune(actives) + + // Re-sort to fix matching priorities + ss.manifest.sort() + + // Update refreshedAt timestamp + ss.manifest.Lock() + ss.manifest.refreshedAt = now + ss.manifest.Unlock() + + return +} + +// refreshTargets refreshes targets for sampling rules. It calls the XRay service proxy with sampling +// statistics for the previous interval and receives targets for the next interval. +func (ss *CentralizedStrategy) refreshTargets() (err error) { + // Explicitly recover from panics since this is the entry point for a long-running goroutine + // and we can not allow a panic to propagate to customer code. + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("%v", r) + } + }() + + // Flag indicating batch failure + failed := false + + // Flag indicating whether or not manifest should be refreshed + refresh := false + + // Generate sampling statistics + statistics := ss.snapshots() + + // Do not refresh targets if no statistics to report + if len(statistics) == 0 { + log.Tracef("No statistics to report. Not refreshing sampling targets.") + return nil + } + + // Get sampling targets + output, err := ss.proxy.GetSamplingTargets(statistics) + if err != nil { + return + } + + // Update sampling targets + for _, t := range output.SamplingTargetDocuments { + if err = ss.updateTarget(t); err != nil { + failed = true + log.Tracef("Error occurred updating target for rule. %v", err) + } + } + + // Consume unprocessed statistics messages + for _, s := range output.UnprocessedStatistics { + log.Tracef( + "Error occurred updating sampling target for rule: %s, code: %s, message: %s", + s.RuleName, + s.ErrorCode, + s.Message, + ) + + // Do not set any flags if error is unknown + if s.ErrorCode == nil || s.RuleName == nil { + continue + } + + // Set batch failure if any sampling statistics return 5xx + if strings.HasPrefix(*s.ErrorCode, "5") { + failed = true + } + + // Set refresh flag if any sampling statistics return 4xx + if strings.HasPrefix(*s.ErrorCode, "4") { + refresh = true + } + } + + // Set err if updates failed + if failed { + err = errors.New("error occurred updating sampling targets") + } else { + log.Info("Successfully refreshed sampling targets") + } + + // Set refresh flag if modifiedAt timestamp from remote is greater than ours. + if remote := output.LastRuleModification; remote != nil { + ss.manifest.RLock() + local := ss.manifest.refreshedAt + ss.manifest.RUnlock() + + if remote.Unix() >= local { + refresh = true + } + } + // Perform out-of-band async manifest refresh if flag is set + if refresh { + log.Info("Refreshing sampling rules out-of-band.") + + go func() { + if err = ss.refreshManifest(); err != nil { + log.Tracef("Error occurred refreshing sampling rules out-of-band. %v", err) + } + }() + } + return +} + +// samplingStatistics takes a snapshot of sampling statistics from all rules, resetting +// statistics counters in the process. +func (ss *CentralizedStrategy) snapshots() []*xraySvc.SamplingStatisticsDocument { + statistics := make([]*xraySvc.SamplingStatisticsDocument, 0, len(ss.manifest.Rules)+1) + now := ss.clock.Now().Unix() + + ss.manifest.RLock() + defer ss.manifest.RUnlock() + + // Generate sampling statistics for user-defined rules + for _, r := range ss.manifest.Rules { + if !r.stale(now) { + continue + } + + s := r.snapshot() + s.ClientID = &ss.clientID + + statistics = append(statistics, s) + } + + // Generate sampling statistics for default rule + if r := ss.manifest.Default; r != nil && r.stale(now) { + s := r.snapshot() + s.ClientID = &ss.clientID + + statistics = append(statistics, s) + } + + return statistics +} + +// updateTarget updates sampling targets for the rule specified in the target struct. +func (ss *CentralizedStrategy) updateTarget(t *xraySvc.SamplingTargetDocument) (err error) { + // Pre-emptively dereference xraySvc.SamplingTarget fields and return early on nil values + // A panic in the middle of an update may leave the rule in an inconsistent state. + if t.RuleName == nil { + return errors.New("invalid sampling target. Missing rule name") + } + + if t.FixedRate == nil { + return fmt.Errorf("invalid sampling target for rule %s. Missing fixed rate", *t.RuleName) + } + + // Rule for given target + ss.manifest.RLock() + r, ok := ss.manifest.Index[*t.RuleName] + ss.manifest.RUnlock() + + if !ok { + return fmt.Errorf("rule %s not found", *t.RuleName) + } + + r.Lock() + defer r.Unlock() + + r.reservoir.refreshedAt = ss.clock.Now().Unix() + + // Update non-optional attributes from response + r.Rate = *t.FixedRate + + // Update optional attributes from response + if t.ReservoirQuota != nil { + r.reservoir.quota = *t.ReservoirQuota + } + if t.ReservoirQuotaTTL != nil { + r.reservoir.expiresAt = t.ReservoirQuotaTTL.Unix() + } + if t.Interval != nil { + r.reservoir.interval = *t.Interval + } + + return nil +} + +// LoadDaemonEndpoints configures proxy with the provided endpoint. +func (ss *CentralizedStrategy) LoadDaemonEndpoints(endpoints *daemoncfg.DaemonEndpoints) { + ss.daemonEndpoints = endpoints +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/centralized_sampling_rule_manifest.go b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/centralized_sampling_rule_manifest.go new file mode 100644 index 00000000..9e32da4d --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/centralized_sampling_rule_manifest.go @@ -0,0 +1,294 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +package sampling + +import ( + "fmt" + "sort" + "strings" + "sync" + + xraySvc "github.com/aws/aws-sdk-go/service/xray" + "github.com/aws/aws-xray-sdk-go/utils" +) + +const defaultRule = "Default" +const defaultInterval = int64(10) + +const manifestTTL = 3600 // Seconds + +// CentralizedManifest represents a full sampling ruleset, with a list of +// custom rules and default values for incoming requests that do +// not match any of the provided rules. +type CentralizedManifest struct { + Default *CentralizedRule + Rules []*CentralizedRule + Index map[string]*CentralizedRule + refreshedAt int64 + clock utils.Clock + sync.RWMutex +} + +// putRule updates the named rule if it already exists or creates it if it does not. +// May break ordering of the sorted rules array if it creates a new rule. +func (m *CentralizedManifest) putRule(svcRule *xraySvc.SamplingRule) (r *CentralizedRule, err error) { + defer func() { + if x := recover(); x != nil { + err = fmt.Errorf("%v", x) + } + }() + + name := *svcRule.RuleName + + // Default rule + if name == defaultRule { + m.RLock() + r = m.Default + m.RUnlock() + + // Update rule if already exists + if r != nil { + m.updateDefaultRule(svcRule) + + return + } + + // Create Default rule + r = m.createDefaultRule(svcRule) + + return + } + + // User-defined rule + m.RLock() + r, ok := m.Index[name] + m.RUnlock() + + // Create rule if it does not exist + if !ok { + r = m.createUserRule(svcRule) + + return + } + + // Update existing rule + m.updateUserRule(r, svcRule) + + return +} + +// createUserRule creates a user-defined CentralizedRule, appends it to the sorted array, +// adds it to the index, and returns the newly created rule. +// Appends new rule to the sorted array which may break its ordering. +// Panics if svcRule contains nil pointers +func (m *CentralizedManifest) createUserRule(svcRule *xraySvc.SamplingRule) *CentralizedRule { + // Create CentralizedRule from xraySvc.SamplingRule + clock := &utils.DefaultClock{} + rand := &utils.DefaultRand{} + + p := &Properties{ + ServiceName: *svcRule.ServiceName, + HTTPMethod: *svcRule.HTTPMethod, + URLPath: *svcRule.URLPath, + FixedTarget: *svcRule.ReservoirSize, + Rate: *svcRule.FixedRate, + Host: *svcRule.Host, + } + + r := &reservoir{ + capacity: *svcRule.ReservoirSize, + } + + cr := &CentralizedReservoir{ + reservoir: r, + interval: defaultInterval, + } + + csr := &CentralizedRule{ + ruleName: *svcRule.RuleName, + priority: *svcRule.Priority, + reservoir: cr, + Properties: p, + serviceType: *svcRule.ServiceType, + resourceARN: *svcRule.ResourceARN, + attributes: svcRule.Attributes, + clock: clock, + rand: rand, + } + + m.Lock() + defer m.Unlock() + + // Return early if rule already exists + if r, ok := m.Index[*svcRule.RuleName]; ok { + return r + } + + // Update sorted array + m.Rules = append(m.Rules, csr) + + // Update index + m.Index[*svcRule.RuleName] = csr + + return csr +} + +// updateUserRule updates the properties of the user-defined CentralizedRule using the given +// xraySvc.SamplingRule. +// Panics if svcRule contains nil pointers. +func (m *CentralizedManifest) updateUserRule(r *CentralizedRule, svcRule *xraySvc.SamplingRule) { + // Preemptively dereference xraySvc.SamplingRule fields and panic early on nil pointers. + // A panic in the middle of an update may leave the rule in an inconsistent state. + pr := &Properties{ + ServiceName: *svcRule.ServiceName, + HTTPMethod: *svcRule.HTTPMethod, + URLPath: *svcRule.URLPath, + FixedTarget: *svcRule.ReservoirSize, + Rate: *svcRule.FixedRate, + Host: *svcRule.Host, + } + + p, c := *svcRule.Priority, *svcRule.ReservoirSize + + r.Lock() + defer r.Unlock() + + r.Properties = pr + r.priority = p + r.reservoir.capacity = c + r.serviceType = *svcRule.ServiceType + r.resourceARN = *svcRule.ResourceARN + r.attributes = svcRule.Attributes +} + +// createDefaultRule creates a default CentralizedRule and adds it to the manifest. +// Panics if svcRule contains nil values for FixedRate and ReservoirSize. +func (m *CentralizedManifest) createDefaultRule(svcRule *xraySvc.SamplingRule) *CentralizedRule { + // Create CentralizedRule from xraySvc.SamplingRule + clock := &utils.DefaultClock{} + rand := &utils.DefaultRand{} + + p := &Properties{ + FixedTarget: *svcRule.ReservoirSize, + Rate: *svcRule.FixedRate, + } + + r := &reservoir{ + capacity: *svcRule.ReservoirSize, + } + + cr := &CentralizedReservoir{ + reservoir: r, + interval: defaultInterval, + } + + csr := &CentralizedRule{ + ruleName: *svcRule.RuleName, + reservoir: cr, + Properties: p, + clock: clock, + rand: rand, + } + + m.Lock() + defer m.Unlock() + + // Return early if rule already exists + if d := m.Default; d != nil { + return d + } + + // Update manifest if rule does not exist + m.Default = csr + + // Update index + m.Index[*svcRule.RuleName] = csr + + return csr +} + +// updateDefaultRule updates the properties of the default CentralizedRule using the given +// xraySvc.SamplingRule. +// Panics if svcRule contains nil values for FixedRate and ReservoirSize. +func (m *CentralizedManifest) updateDefaultRule(svcRule *xraySvc.SamplingRule) { + r := m.Default + + // Preemptively dereference xraySvc.SamplingRule fields and panic early on nil pointers. + // A panic in the middle of an update may leave the rule in an inconsistent state. + p := &Properties{ + FixedTarget: *svcRule.ReservoirSize, + Rate: *svcRule.FixedRate, + } + + c := *svcRule.ReservoirSize + + r.Lock() + defer r.Unlock() + + r.Properties = p + r.reservoir.capacity = c +} + +// prune removes all rules in the manifest not present in the given list of active rules. +// Preserves ordering of sorted array. +func (m *CentralizedManifest) prune(actives map[*CentralizedRule]bool) { + m.Lock() + defer m.Unlock() + + // Iterate in reverse order to avoid adjusting index for each deleted rule + for i := len(m.Rules) - 1; i >= 0; i-- { + r := m.Rules[i] + + if _, ok := actives[r]; !ok { + m.deleteRule(i) + } + } +} + +// deleteRule deletes the rule from the array, and the index. +// Assumes write lock is already held. +// Preserves ordering of sorted array. +func (m *CentralizedManifest) deleteRule(idx int) { + // Remove from index + delete(m.Index, m.Rules[idx].ruleName) + + // Delete by reslicing without index + a := append(m.Rules[:idx], m.Rules[idx+1:]...) + + // Set pointer to nil to free capacity from underlying array + m.Rules[len(m.Rules)-1] = nil + + // Assign resliced rules + m.Rules = a +} + +// sort sorts the rule array first by priority and then by rule name. +func (m *CentralizedManifest) sort() { + // Comparison function + less := func(i, j int) bool { + if m.Rules[i].priority == m.Rules[j].priority { + return strings.Compare(m.Rules[i].ruleName, m.Rules[j].ruleName) < 0 + } + return m.Rules[i].priority < m.Rules[j].priority + } + + m.Lock() + defer m.Unlock() + + sort.Slice(m.Rules, less) +} + +// expired returns true if the manifest has not been successfully refreshed in +// 'manifestTTL' seconds. +func (m *CentralizedManifest) expired() bool { + m.RLock() + defer m.RUnlock() + + return m.refreshedAt < m.clock.Now().Unix()-manifestTTL +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/localized.go b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/localized.go index 301fcd45..c27799f5 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/localized.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/localized.go @@ -59,12 +59,12 @@ func NewLocalizedStrategyFromJSONBytes(b []byte) (*LocalizedStrategy, error) { // ShouldTrace consults the LocalizedStrategy's rule set to determine // if the given request should be traced or not. -func (lss *LocalizedStrategy) ShouldTrace(serviceName string, path string, method string) bool { - log.Tracef("Determining ShouldTrace decision for:\n\tserviceName: %s\n\tpath: %s\n\tmethod: %s", serviceName, path, method) +func (lss *LocalizedStrategy) ShouldTrace(rq *Request) *Decision { + log.Tracef("Determining ShouldTrace decision for:\n\thost: %s\n\tpath: %s\n\tmethod: %s", rq.Host, rq.Url, rq.Method) if nil != lss.manifest.Rules { for _, r := range lss.manifest.Rules { - if r.AppliesTo(serviceName, path, method) { - log.Tracef("Applicable rule:\n\tfixed_target: %d\n\trate: %f\n\tservice_name: %s\n\turl_path: %s\n\thttp_method: %s", r.FixedTarget, r.Rate, r.ServiceName, r.URLPath, r.HTTPMethod) + if r.AppliesTo(rq.Host, rq.Url, rq.Method) { + log.Tracef("Applicable rule:\n\tfixed_target: %d\n\trate: %f\n\thost: %s\n\turl_path: %s\n\thttp_method: %s", r.FixedTarget, r.Rate, r.Host, r.URLPath, r.HTTPMethod) return r.Sample() } } diff --git a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/proxy.go b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/proxy.go new file mode 100644 index 00000000..0165cdd2 --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/proxy.go @@ -0,0 +1,94 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +package sampling + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/endpoints" + "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go/aws/session" + xraySvc "github.com/aws/aws-sdk-go/service/xray" + "github.com/aws/aws-xray-sdk-go/daemoncfg" + log "github.com/cihub/seelog" +) + +// proxy is an implementation of svcProxy that forwards requests to the XRay daemon +type proxy struct { + // XRay client for sending unsigned proxied requests to the daemon + xray *xraySvc.XRay +} + +// NewProxy returns a Proxy +func NewProxy(d *daemoncfg.DaemonEndpoints) (svcProxy, error) { + + if d == nil { + d = daemoncfg.GetDaemonEndpoints() + } + log.Infof("X-Ray proxy using address : %v", d.TCPAddr.String()) + url := "http://" + d.TCPAddr.String() + + // Endpoint resolver for proxying requests through the daemon + f := func(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) { + return endpoints.ResolvedEndpoint{ + URL: url, + }, nil + } + + // Dummy session for unsigned requests + sess, err := session.NewSession(&aws.Config{ + Region: aws.String("us-west-1"), + Credentials: credentials.NewStaticCredentials("", "", ""), + EndpointResolver: endpoints.ResolverFunc(f), + }) + + if err != nil { + return nil, err + } + + x := xraySvc.New(sess) + + // Remove Signer and replace with No-Op handler + x.Handlers.Sign.Clear() + x.Handlers.Sign.PushBack(func(*request.Request) { + // Do nothing + }) + + p := &proxy{xray: x} + + return p, nil +} + +// GetSamplingTargets calls the XRay daemon for sampling targets +func (p *proxy) GetSamplingTargets(s []*xraySvc.SamplingStatisticsDocument) (*xraySvc.GetSamplingTargetsOutput, error) { + input := &xraySvc.GetSamplingTargetsInput{ + SamplingStatisticsDocuments: s, + } + + output, err := p.xray.GetSamplingTargets(input) + if err != nil { + return nil, err + } + + return output, nil +} + +// GetSamplingRules calls the XRay daemon for sampling rules +func (p *proxy) GetSamplingRules() ([]*xraySvc.SamplingRuleRecord, error) { + input := &xraySvc.GetSamplingRulesInput{} + + output, err := p.xray.GetSamplingRules(input) + if err != nil { + return nil, err + } + + rules := output.SamplingRuleRecords + + return rules, nil +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/reservoir.go b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/reservoir.go index 8d2fc755..2a017c61 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/reservoir.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/reservoir.go @@ -6,76 +6,104 @@ // // or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +// Reservoirs allow a specified (`perSecond`) amount of `Take()`s per second. package sampling -import ( - "fmt" - "sync" - "sync/atomic" - "time" -) +import "github.com/aws/aws-xray-sdk-go/utils" -var maxRate uint64 = 1e8 +// reservoir is a set of properties common to all reservoirs +type reservoir struct { + // Total size of reservoir + capacity int64 -// Reservoir allows a specified amount of `Take()`s per second. -// Support for atomic operations on uint64 is required. -// More information: https://golang.org/pkg/sync/atomic/#pkg-note-BUG -type Reservoir struct { - maskedCounter uint64 - perSecond uint64 - mutex sync.Mutex // don't use embedded struct to ensure 64 bit alignment for maskedCounter. + // Reservoir consumption for current epoch + used int64 + + // Unix epoch. Reservoir usage is reset every second. + currentEpoch int64 } -// NewReservoir creates a new reservoir with a specified perSecond -// sampling capacity. The maximum supported sampling capacity per -// second is currently 100,000,000. An error is returned if the -// desired capacity is greater than this maximum value. -func NewReservoir(perSecond uint64) (*Reservoir, error) { - if perSecond >= maxRate { - return nil, fmt.Errorf("desired sampling capacity of %d is greater than maximum supported rate %d", perSecond, maxRate) +// CentralizedReservoir is a reservoir distributed among all running instances of the SDK +type CentralizedReservoir struct { + // Quota assigned to client + quota int64 + + // Quota refresh timestamp + refreshedAt int64 + + // Quota expiration timestamp + expiresAt int64 + + // Polling interval for quota + interval int64 + + // True if reservoir has been borrowed from this epoch + borrowed bool + + // Common reservoir properties + *reservoir +} + +// expired returns true if current time is past expiration timestamp. False otherwise. +func (r *CentralizedReservoir) expired(now int64) bool { + return now > r.expiresAt +} + +// borrow returns true if the reservoir has not been borrowed from this epoch +func (r *CentralizedReservoir) borrow(now int64) bool { + if now != r.currentEpoch { + r.reset(now) } - return &Reservoir{ - maskedCounter: 0, - perSecond: perSecond, - }, nil + + s := r.borrowed + r.borrowed = true + + return !s && r.reservoir.capacity != 0 } -// Take returns true when the reservoir has remaining sampling -// capacity for the current epoch. Take returns false when the -// reservoir has no remaining sampling capacity for the current -// epoch. The sampling capacity decrements by one each time -// Take returns true. -func (r *Reservoir) Take() bool { - now := uint64(time.Now().Unix()) - counterNewVal := atomic.AddUint64(&r.maskedCounter, 1) - previousTimestamp := extractTime(counterNewVal) - - if previousTimestamp != now { - r.mutex.Lock() - beforeUpdate := atomic.LoadUint64(&r.maskedCounter) - timestampBeforeUpdate := extractTime(beforeUpdate) - - if timestampBeforeUpdate != now { - valueToSet := timestampToCounter(now) - atomic.StoreUint64(&r.maskedCounter, valueToSet) - } - - counterNewVal = atomic.AddUint64(&r.maskedCounter, 1) - r.mutex.Unlock() +// Take consumes quota from reservoir, if any remains, and returns true. False otherwise. +func (r *CentralizedReservoir) Take(now int64) bool { + if now != r.currentEpoch { + r.reset(now) + } + + // Consume from quota, if available + if r.quota > r.used { + r.used++ + + return true } - newCounterValue := extractCounter(counterNewVal) - return newCounterValue <= r.perSecond + return false } -func extractTime(maskedCounter uint64) uint64 { - return maskedCounter / maxRate +func (r *CentralizedReservoir) reset(now int64) { + r.currentEpoch, r.used, r.borrowed = now, 0, false } -func extractCounter(maskedCounter uint64) uint64 { - return maskedCounter % maxRate +// Reservoir is a reservoir local to the running instance of the SDK +type Reservoir struct { + // Provides system time + clock utils.Clock + + *reservoir } -func timestampToCounter(timestamp uint64) uint64 { - return timestamp * maxRate +// Take attempts to consume a unit from the local reservoir. Returns true if unit taken, false otherwise. +func (r *Reservoir) Take() bool { + // Reset counters if new second + if now := r.clock.Now().Unix(); now != r.currentEpoch { + r.used = 0 + r.currentEpoch = now + } + + // Take from reservoir, if available + if r.used >= r.capacity { + return false + } + + // Increment reservoir usage + r.used++ + + return true } diff --git a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_attributes.go b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_attributes.go new file mode 100644 index 00000000..cd1dc1c4 --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_attributes.go @@ -0,0 +1,23 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +package sampling + +// Decision contains sampling decision and the rule matched for an incoming request +type Decision struct { + Sample bool + Rule *string +} + +// Request represents parameters used to make a sampling decision. +type Request struct { + Host string + Method string + Url string + ServiceName string + ServiceType string +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_rule.go b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_rule.go index ab3fb88d..bc7776dc 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_rule.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_rule.go @@ -9,31 +9,206 @@ package sampling import ( - "math/rand" + "sync" "github.com/aws/aws-xray-sdk-go/pattern" + "github.com/aws/aws-xray-sdk-go/utils" + + xraySvc "github.com/aws/aws-sdk-go/service/xray" + log "github.com/cihub/seelog" ) -// Rule represents a single entry in a sampling ruleset. -type Rule struct { +// Properties is the base set of properties that define a sampling rule. +type Properties struct { ServiceName string `json:"service_name"` + Host string `json:"host"` HTTPMethod string `json:"http_method"` URLPath string `json:"url_path"` - FixedTarget uint64 `json:"fixed_target"` + FixedTarget int64 `json:"fixed_target"` Rate float64 `json:"rate"` - reservoir *Reservoir } -// AppliesTo returns true when the rule applies to the given parameters -func (sr *Rule) AppliesTo(serviceName string, path string, method string) bool { - return pattern.WildcardMatchCaseInsensitive(sr.ServiceName, serviceName) && pattern.WildcardMatchCaseInsensitive(sr.URLPath, path) && pattern.WildcardMatchCaseInsensitive(sr.HTTPMethod, method) +// AppliesTo returns true if the sampling rule matches against given parameters. False Otherwise. +// Assumes lock is already held, if required. +func (p *Properties) AppliesTo(host, path, method string) bool { + return (host == "" || pattern.WildcardMatchCaseInsensitive(p.Host, host)) && + (path == "" || pattern.WildcardMatchCaseInsensitive(p.URLPath, path)) && + (method == "" || pattern.WildcardMatchCaseInsensitive(p.HTTPMethod, method)) +} + +// AppliesTo returns true if the sampling rule matches against given sampling request. False Otherwise. +// Assumes lock is already held, if required. +func (r *CentralizedRule) AppliesTo(request *Request) bool { + return (request.Host == "" || pattern.WildcardMatchCaseInsensitive(r.Host, request.Host)) && + (request.Url == "" || pattern.WildcardMatchCaseInsensitive(r.URLPath, request.Url)) && + (request.Method == "" || pattern.WildcardMatchCaseInsensitive(r.HTTPMethod, request.Method)) && + (request.ServiceName == "" || pattern.WildcardMatchCaseInsensitive(r.ServiceName, request.ServiceName)) && + (request.ServiceType == "" || pattern.WildcardMatchCaseInsensitive(r.serviceType, request.ServiceType)) +} + +// CentralizedRule represents a centralized sampling rule +type CentralizedRule struct { + // Centralized reservoir for keeping track of reservoir usage + reservoir *CentralizedReservoir + + // Rule name identifying this rule + ruleName string + + // Priority of matching against rule + priority int64 + + // Number of requests matched against this rule + requests int64 + + // Number of requests sampled using this rule + sampled int64 + + // Number of requests burrowed + borrows int64 + + // Timestamp for last match against this rule + usedAt int64 + + // Common sampling rule properties + *Properties + + // ServiceType for the sampling rule + serviceType string + + // ResourceARN for the sampling rule + resourceARN string + + // Attributes for the sampling rule + attributes map[string]*string + + // Provides system time + clock utils.Clock + + // Provides random numbers + rand utils.Rand + + sync.RWMutex +} + +// stale returns true if the quota is due for a refresh. False otherwise. +func (r *CentralizedRule) stale(now int64) bool { + r.Lock() + defer r.Unlock() + + return r.requests != 0 && now >= r.reservoir.refreshedAt+r.reservoir.interval } -// Sample returns true when the rule's reservoir is not full or -// when a randomly generated float is less than the rule's rate -func (sr *Rule) Sample() bool { - if sr.reservoir.Take() { +// Sample returns true if the request should be sampled. False otherwise. +func (r *CentralizedRule) Sample() *Decision { + now := r.clock.Now().Unix() + sd := &Decision{ + Rule: &r.ruleName, + } + + r.Lock() + defer r.Unlock() + + r.requests++ + + // Fallback to bernoulli sampling if quota has expired + if r.reservoir.expired(now) { + if r.reservoir.borrow(now) { + log.Tracef( + "Sampling target has expired for rule %s. Borrowing a request.", + r.ruleName, + ) + sd.Sample = true + r.borrows++ + + return sd + } + + log.Tracef( + "Sampling target has expired for rule %s. Using fixed rate.", + r.ruleName, + ) + sd.Sample = r.bernoulliSample() + + return sd + } + + // Take from reservoir quota, if possible + if r.reservoir.Take(now) { + r.sampled++ + sd.Sample = true + + return sd + } + + log.Tracef( + "Sampling target has been exhausted for rule %s. Using fixed rate.", + r.ruleName, + ) + + // Use bernoulli sampling if quota expended + sd.Sample = r.bernoulliSample() + + return sd +} + +// bernoulliSample uses bernoulli sampling rate to make a sampling decision +func (r *CentralizedRule) bernoulliSample() bool { + if r.rand.Float64() < r.Rate { + r.sampled++ + return true } - return rand.Float64() < sr.Rate + + return false +} + +// snapshot takes a snapshot of the sampling statistics counters, returning +// xraySvc.SamplingStatistics. It also resets statistics counters. +func (r *CentralizedRule) snapshot() *xraySvc.SamplingStatisticsDocument { + r.Lock() + + name := &r.ruleName + + // Copy statistics counters since xraySvc.SamplingStatistics expects + // pointers to counters, and ours are mutable. + requests, sampled, borrows := r.requests, r.sampled, r.borrows + + // Reset counters + r.requests, r.sampled, r.borrows = 0, 0, 0 + + r.Unlock() + + now := r.clock.Now() + s := &xraySvc.SamplingStatisticsDocument{ + RequestCount: &requests, + SampledCount: &sampled, + BorrowCount: &borrows, + RuleName: name, + Timestamp: &now, + } + + return s +} + +// Local Sampling Rule +type Rule struct { + reservoir *Reservoir + + // Provides random numbers + rand utils.Rand + + // Common sampling rule properties + *Properties +} + +func (r *Rule) Sample() *Decision { + var sd Decision + + if r.reservoir.Take() { + sd.Sample = true + } else { + sd.Sample = r.rand.Float64() < r.Rate + } + + return &sd } diff --git a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_rule_manifest.go b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_rule_manifest.go index e604d30d..a085ff69 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_rule_manifest.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_rule_manifest.go @@ -13,6 +13,9 @@ import ( "errors" "fmt" "io/ioutil" + "time" + + "github.com/aws/aws-xray-sdk-go/utils" ) // RuleManifest represents a full sampling ruleset, with a list of @@ -28,16 +31,9 @@ type RuleManifest struct { func ManifestFromFilePath(fp string) (*RuleManifest, error) { b, err := ioutil.ReadFile(fp) if err == nil { - s, e := ManifestFromJSONBytes(b) - if e != nil { - return nil, e - } - err = processManifest(s) - if err != nil { - return nil, err - } - return s, nil + return ManifestFromJSONBytes(b) } + return nil, err } @@ -52,42 +48,114 @@ func ManifestFromJSONBytes(b []byte) (*RuleManifest, error) { if err != nil { return nil, err } + + initSamplingRules(s) + return s, nil } -// processManifest returns the provided manifest if valid, -// or an error if the provided manifest is invalid. +// Init local reservoir and add random number generator +func initSamplingRules(srm *RuleManifest) { + // Init user-defined rules + for _, r := range srm.Rules { + r.rand = &utils.DefaultRand{} + + r.reservoir = &Reservoir{ + clock: &utils.DefaultClock{}, + reservoir: &reservoir{ + capacity: r.FixedTarget, + used: 0, + currentEpoch: time.Now().Unix(), + }, + } + } + + // Init default rule + srm.Default.rand = &utils.DefaultRand{} + + srm.Default.reservoir = &Reservoir{ + clock: &utils.DefaultClock{}, + reservoir: &reservoir{ + capacity: srm.Default.FixedTarget, + used: 0, + currentEpoch: time.Now().Unix(), + }, + } +} + +// processManifest returns the provided manifest if valid, or an error if the provided manifest is invalid. func processManifest(srm *RuleManifest) error { if nil == srm { - return errors.New("sampling rule manifest must not be nil") + return errors.New("Sampling rule manifest must not be nil.") } - if 1 != srm.Version { - return fmt.Errorf("sampling rule manifest version %d not supported", srm.Version) + if 1 != srm.Version && 2 != srm.Version { + return errors.New(fmt.Sprintf("Sampling rule manifest version %d not supported.", srm.Version)) } if nil == srm.Default { - return errors.New("sampling rule manifest must include a default rule") + return errors.New("Sampling rule manifest must include a default rule.") } if "" != srm.Default.URLPath || "" != srm.Default.ServiceName || "" != srm.Default.HTTPMethod { - return errors.New("the default rule must not specify values for url_path, service_name, or http_method") + return errors.New("The default rule must not specify values for url_path, service_name, or http_method.") } if srm.Default.FixedTarget < 0 || srm.Default.Rate < 0 { - return errors.New("the default rule must specify non-negative values for fixed_target and rate") + return errors.New("The default rule must specify non-negative values for fixed_target and rate.") } - res, err := NewReservoir(srm.Default.FixedTarget) - if err != nil { - return err + c := &utils.DefaultClock{} + + srm.Default.reservoir = &Reservoir{ + clock: c, + reservoir: &reservoir{ + capacity: srm.Default.FixedTarget, + }, } - srm.Default.reservoir = res if srm.Rules != nil { for _, r := range srm.Rules { - res, err := NewReservoir(r.FixedTarget) - if err != nil { - return err + + if srm.Version == 1 { + err := validateVersion1(r) + if nil != err { + return err + } + r.Host = r.ServiceName // V1 sampling rule contains service name and not host + r.ServiceName = "" + } + + if srm.Version == 2 { + err := validateVersion2(r) + if nil != err { + return err + } + } + + r.reservoir = &Reservoir{ + clock: c, + reservoir: &reservoir{ + capacity: r.FixedTarget, + }, } - r.reservoir = res } } return nil } + +func validateVersion2(rule *Rule) error { + if rule.FixedTarget < 0 || rule.Rate < 0 { + return errors.New("all rules must have non-negative values for fixed_target and rate") + } + if rule.ServiceName != "" || rule.Host == "" || rule.HTTPMethod == "" || rule.URLPath == "" { + return errors.New("all non-default rules must have values for url_path, host, and http_method") + } + return nil +} + +func validateVersion1(rule *Rule) error { + if rule.FixedTarget < 0 || rule.Rate < 0 { + return errors.New("all rules must have non-negative values for fixed_target and rate") + } + if rule.Host != "" || rule.ServiceName == "" || rule.HTTPMethod == "" || rule.URLPath == "" { + return errors.New("all non-default rules must have values for url_path, service_name, and http_method") + } + return nil +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_strategy.go b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_strategy.go index 583dfa39..e419a438 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_strategy.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/strategy/sampling/sampling_strategy.go @@ -10,5 +10,5 @@ package sampling // Strategy provides an interface for implementing trace sampling strategies. type Strategy interface { - ShouldTrace(serviceName string, path string, method string) bool + ShouldTrace(request *Request) *Decision } diff --git a/vendor/github.com/aws/aws-xray-sdk-go/utils/clock.go b/vendor/github.com/aws/aws-xray-sdk-go/utils/clock.go new file mode 100644 index 00000000..30e3cbb5 --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/utils/clock.go @@ -0,0 +1,26 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +package utils + +import ( + "time" +) + +// Clock provides an interface to implement method for getting current time. +type Clock interface { + Now() time.Time +} + +// DefaultClock is an implementation of Clock interface. +type DefaultClock struct{} + +// Now returns current time. +func (t *DefaultClock) Now() time.Time { + return time.Now() +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/utils/mock_clock.go b/vendor/github.com/aws/aws-xray-sdk-go/utils/mock_clock.go new file mode 100644 index 00000000..918603fc --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/utils/mock_clock.go @@ -0,0 +1,31 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +package utils + +import ( + "sync/atomic" + "time" +) + +// MockClock is a struct to record current time. +type MockClock struct { + NowTime int64 +} + +// Now function returns NowTime value. +func (c *MockClock) Now() time.Time { + return time.Unix(c.NowTime, 0) +} + +// Increment is a method to increase current time. +func (c *MockClock) Increment(d int64) time.Time { + t := atomic.AddInt64(&c.NowTime, d) + + return time.Unix(t, 0) +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/utils/mock_rand.go b/vendor/github.com/aws/aws-xray-sdk-go/utils/mock_rand.go new file mode 100644 index 00000000..c6b47553 --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/utils/mock_rand.go @@ -0,0 +1,31 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +package utils + +// MockRand is an implementation of Rand interface. +type MockRand struct { + F64 float64 + Int int + Int64 int64 +} + +// Float64 returns value of F64. +func (r *MockRand) Float64() float64 { + return r.F64 +} + +// Intn returns value of Int. +func (r *MockRand) Intn(n int) int { + return r.Int +} + +// Int63n returns value of Int64. +func (r *MockRand) Int63n(n int64) int64 { + return r.Int64 +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/utils/rand.go b/vendor/github.com/aws/aws-xray-sdk-go/utils/rand.go new file mode 100644 index 00000000..2fe5e80a --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/utils/rand.go @@ -0,0 +1,46 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +package utils + +import ( + "math/rand" + "time" +) + +func init() { + rand.Seed(time.Now().UnixNano()) +} + +// Rand is an interface for a set of methods that return random value. +type Rand interface { + Int63n(n int64) int64 + Intn(n int) int + Float64() float64 +} + +// DefaultRand is an implementation of Rand interface. +type DefaultRand struct{} + +// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n) +// from the default Source. +func (r *DefaultRand) Int63n(n int64) int64 { + return rand.Int63n(n) +} + +// Intn returns, as an int, a non-negative pseudo-random number in [0,n) +// from the default Source. +func (r *DefaultRand) Intn(n int) int { + return rand.Intn(n) +} + +// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0) +// from the default Source. +func (r *DefaultRand) Float64() float64 { + return rand.Float64() +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/utils/timer.go b/vendor/github.com/aws/aws-xray-sdk-go/utils/timer.go new file mode 100644 index 00000000..3009f685 --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/utils/timer.go @@ -0,0 +1,44 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +package utils + +import ( + "math/rand" + "time" +) + +func init() { + rand.Seed(time.Now().UnixNano()) +} + +type timer struct { + t *time.Timer + d time.Duration + jitter time.Duration +} + +func NewTimer(d, jitter time.Duration) *timer { + t := time.NewTimer(d - time.Duration(rand.Int63n(int64(jitter)))) + + jitteredTimer := timer{ + t: t, + d: d, + jitter: jitter, + } + + return &jitteredTimer +} + +func (j *timer) C() <-chan time.Time { + return j.t.C +} + +func (j *timer) Reset() { + j.t.Reset(j.d - time.Duration(rand.Int63n(int64(j.jitter)))) +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/aws.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/aws.go index de19fc30..a5f99852 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/aws.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/aws.go @@ -13,7 +13,6 @@ import ( "context" "encoding/json" "errors" - "fmt" "io/ioutil" "net/http/httptrace" "reflect" @@ -26,6 +25,10 @@ import ( log "github.com/cihub/seelog" ) +const RequestIDKey string = "request_id" +const ExtendedRequestIDKey string = "id_2" +const S3ExtendedRequestIDHeaderKey string = "x-amz-id-2" + type jsonMap struct { object interface{} } @@ -42,6 +45,9 @@ func beginSubsegment(r *request.Request, name string) { func endSubsegment(r *request.Request) { seg := GetSegment(r.HTTPRequest.Context()) + if seg == nil { + return + } seg.Close(r.Error) r.HTTPRequest = r.HTTPRequest.WithContext(context.WithValue(r.HTTPRequest.Context(), ContextKey, seg.parent)) } @@ -50,6 +56,9 @@ var xRayBeforeValidateHandler = request.NamedHandler{ Name: "XRayBeforeValidateHandler", Fn: func(r *request.Request) { ctx, opseg := BeginSubsegment(r.HTTPRequest.Context(), r.ClientInfo.ServiceName) + if opseg == nil { + return + } opseg.Namespace = "aws" marshalctx, _ := BeginSubsegment(ctx, "marshal") @@ -68,8 +77,10 @@ var xRayAfterBuildHandler = request.NamedHandler{ var xRayBeforeSignHandler = request.NamedHandler{ Name: "XRayBeforeSignHandler", Fn: func(r *request.Request) { - ctx, _ := BeginSubsegment(r.HTTPRequest.Context(), fmt.Sprintf("attempt_%d", (r.RetryCount+1))) - + ctx, seg := BeginSubsegment(r.HTTPRequest.Context(), "attempt") + if seg == nil { + return + } ct, _ := NewClientTrace(ctx) r.HTTPRequest = r.HTTPRequest.WithContext(httptrace.WithClientTrace(ctx, ct.httpTrace)) }, @@ -98,7 +109,7 @@ var xRayAfterSendHandler = request.NamedHandler{ var xRayBeforeUnmarshalHandler = request.NamedHandler{ Name: "XRayBeforeUnmarshalHandler", Fn: func(r *request.Request) { - endSubsegment(r) // end attempt_x subsegment + endSubsegment(r) // end attempt subsegment beginSubsegment(r, "unmarshal") }, } @@ -113,7 +124,7 @@ var xRayAfterUnmarshalHandler = request.NamedHandler{ var xRayBeforeRetryHandler = request.NamedHandler{ Name: "XRayBeforeRetryHandler", Fn: func(r *request.Request) { - endSubsegment(r) // end attempt_x subsegment + endSubsegment(r) // end attempt subsegment ctx, _ := BeginSubsegment(r.HTTPRequest.Context(), "wait") r.HTTPRequest = r.HTTPRequest.WithContext(ctx) @@ -188,12 +199,16 @@ func xrayCompleteHandler(filename string) request.NamedHandler { opseg.GetAWS()["region"] = r.ClientInfo.SigningRegion opseg.GetAWS()["operation"] = r.Operation.Name - opseg.GetAWS()["request_id"] = r.RequestID opseg.GetAWS()["retries"] = r.RetryCount + opseg.GetAWS()[RequestIDKey] = r.RequestID if r.HTTPResponse != nil { opseg.GetHTTP().GetResponse().Status = r.HTTPResponse.StatusCode opseg.GetHTTP().GetResponse().ContentLength = int(r.HTTPResponse.ContentLength) + + if extendedRequestID := r.HTTPResponse.Header.Get(S3ExtendedRequestIDHeaderKey); extendedRequestID != "" { + opseg.GetAWS()[ExtendedRequestIDKey] = extendedRequestID + } } if request.IsErrorThrottle(r.Error) { diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/capture.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/capture.go index f23cc476..7362f663 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/capture.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/capture.go @@ -21,15 +21,20 @@ func Capture(ctx context.Context, name string, fn func(context.Context) error) ( defer func() { if seg != nil { seg.Close(err) - } else { - privateCfg.ContextMissingStrategy().ContextMissing(fmt.Sprintf("failed to end subsegment: subsegment '%v' cannot be found.", name)) + cfg := GetRecorder(ctx) + failedMessage := fmt.Sprintf("failed to end subsegment: subsegment '%v' cannot be found.", name) + if cfg != nil && cfg.ContextMissingStrategy != nil { + cfg.ContextMissingStrategy.ContextMissing(failedMessage) + } else { + globalCfg.ContextMissingStrategy().ContextMissing(failedMessage) + } } }() defer func() { if p := recover(); p != nil { - err = privateCfg.ExceptionFormattingStrategy().Panicf("%v", p) + err = seg.ParentSegment.GetConfiguration().ExceptionFormattingStrategy.Panicf("%v", p) panic(p) } }() diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/client.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/client.go index e9844654..a8b35ee8 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/client.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/client.go @@ -10,12 +10,14 @@ package xray import ( "context" + log "github.com/cihub/seelog" "net/http" "net/http/httptrace" "strconv" - log "github.com/cihub/seelog" ) +const emptyHostRename = "empty_host_error" + // Client creates a shallow copy of the provided http client, // defaulting to http.DefaultClient, with roundtripper wrapped // with xray.RoundTripper. @@ -47,8 +49,19 @@ type roundtripper struct { // RoundTrip wraps a single HTTP transaction and add corresponding information into a subsegment. func (rt *roundtripper) RoundTrip(r *http.Request) (*http.Response, error) { + var isEmptyHost bool var resp *http.Response - err := Capture(r.Context(), r.Host, func(ctx context.Context) error { + host := r.Host + if host == "" { + if h := r.URL.Host; h != "" { + host = h + } else { + host = emptyHostRename + isEmptyHost = true + } + } + + err := Capture(r.Context(), host, func(ctx context.Context) error { var err error seg := GetSegment(ctx) if seg == nil { @@ -56,7 +69,7 @@ func (rt *roundtripper) RoundTrip(r *http.Request) (*http.Response, error) { log.Warnf("failed to record HTTP transaction: segment cannot be found.") return err } - + ct, e := NewClientTrace(ctx) if e != nil { return e @@ -64,7 +77,13 @@ func (rt *roundtripper) RoundTrip(r *http.Request) (*http.Response, error) { r = r.WithContext(httptrace.WithClientTrace(ctx, ct.httpTrace)) seg.Lock() - seg.Namespace = "remote" + + if isEmptyHost { + seg.Namespace = "" + } else { + seg.Namespace = "remote" + } + seg.GetHTTP().GetRequest().Method = r.Method seg.GetHTTP().GetRequest().URL = r.URL.String() diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/config.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/config.go index fefa5113..2bce4a85 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/config.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/config.go @@ -9,30 +9,44 @@ package xray import ( + "context" "fmt" "net" "os" "sync" + "github.com/aws/aws-xray-sdk-go/daemoncfg" + "github.com/aws/aws-xray-sdk-go/strategy/ctxmissing" "github.com/aws/aws-xray-sdk-go/strategy/exception" "github.com/aws/aws-xray-sdk-go/strategy/sampling" log "github.com/cihub/seelog" ) -var privateCfg = newPrivateConfig() +// SDKVersion records the current X-Ray Go SDK version. +const SDKVersion = "1.0.0-rc.9" -func newPrivateConfig() *privateConfig { - ret := &privateConfig{ - daemonAddr: &net.UDPAddr{ - IP: net.IPv4(127, 0, 0, 1), - Port: 2000, - }, - logLevel: log.InfoLvl, - logFormat: "%Date(2006-01-02T15:04:05Z07:00) [%Level] %Msg%n", - } +// SDKType records which X-Ray SDK customer uses. +const SDKType = "X-Ray for Go" + +// SDK provides the shape for unmarshalling an SDK struct. +type SDK struct { + Version string `json:"sdk_version,omitempty"` + Type string `json:"sdk,omitempty"` + RuleName string `json:"sampling_rule_name,omitempty"` +} + +var globalCfg = newGlobalConfig() + +func newGlobalConfig() *globalConfig { + ret := &globalConfig{} - ss, err := sampling.NewLocalizedStrategy() + // Set the logging configuration to the defaults + ret.logLevel, ret.logFormat = loadLogConfig("", "") + + ret.daemonAddr = daemoncfg.GetDaemonEndpoints().UDPAddr + + ss, err := sampling.NewCentralizedStrategy() if err != nil { panic(err) } @@ -50,6 +64,12 @@ func newPrivateConfig() *privateConfig { } ret.streamingStrategy = sts + emt, err := NewDefaultEmitter(ret.daemonAddr) + if err != nil { + panic(err) + } + ret.emitter = emt + cm := ctxmissing.NewDefaultRuntimeErrorStrategy() ret.contextMissingStrategy = cm @@ -57,10 +77,11 @@ func newPrivateConfig() *privateConfig { return ret } -type privateConfig struct { +type globalConfig struct { sync.RWMutex daemonAddr *net.UDPAddr + emitter Emitter serviceVersion string samplingStrategy sampling.Strategy streamingStrategy StreamingStrategy @@ -74,6 +95,7 @@ type privateConfig struct { type Config struct { DaemonAddr string ServiceVersion string + Emitter Emitter SamplingStrategy sampling.Strategy StreamingStrategy StreamingStrategy ExceptionFormattingStrategy exception.FormattingStrategy @@ -82,60 +104,109 @@ type Config struct { LogFormat string } +// ContextWithConfig returns context with given configuration settings. +func ContextWithConfig(ctx context.Context, c Config) (context.Context, error) { + var errors exception.MultiError + + daemonEndpoints, er := daemoncfg.GetDaemonEndpointsFromString(c.DaemonAddr) + + if daemonEndpoints != nil { + if c.Emitter != nil { + c.Emitter.RefreshEmitterWithAddress(daemonEndpoints.UDPAddr) + } + if c.SamplingStrategy != nil { + configureStrategy(c.SamplingStrategy, daemonEndpoints) + } + } else if er != nil { + errors = append(errors, er) + } + + cms := os.Getenv("AWS_XRAY_CONTEXT_MISSING") + if cms != "" { + if cms == ctxmissing.RuntimeErrorStrategy { + cm := ctxmissing.NewDefaultRuntimeErrorStrategy() + c.ContextMissingStrategy = cm + } else if cms == ctxmissing.LogErrorStrategy { + cm := ctxmissing.NewDefaultLogErrorStrategy() + c.ContextMissingStrategy = cm + } + } + + loadLogConfig(c.LogLevel, c.LogFormat) + + var err error + switch len(errors) { + case 0: + err = nil + case 1: + err = errors[0] + default: + err = errors + } + + return context.WithValue(ctx, RecorderContextKey{}, &c), err +} + +func configureStrategy(s sampling.Strategy, daemonEndpoints *daemoncfg.DaemonEndpoints) { + if s == nil { + return + } + strategy, ok := s.(*sampling.CentralizedStrategy) + if ok { + strategy.LoadDaemonEndpoints(daemonEndpoints) + } +} + // Configure overrides default configuration options with customer-defined values. func Configure(c Config) error { - privateCfg.Lock() - defer privateCfg.Unlock() + globalCfg.Lock() + defer globalCfg.Unlock() var errors exception.MultiError - var daemonAddress string - if addr := os.Getenv("AWS_XRAY_DAEMON_ADDRESS"); addr != "" { - daemonAddress = addr - } else if c.DaemonAddr != "" { - daemonAddress = c.DaemonAddr + if c.SamplingStrategy != nil { + globalCfg.samplingStrategy = c.SamplingStrategy } - if daemonAddress != "" { - addr, err := net.ResolveUDPAddr("udp", daemonAddress) - if err == nil { - privateCfg.daemonAddr = addr - go refreshEmitter() - } else { - errors = append(errors, err) - } + if c.Emitter != nil { + globalCfg.emitter = c.Emitter } - if c.SamplingStrategy != nil { - privateCfg.samplingStrategy = c.SamplingStrategy + daemonEndpoints, er := daemoncfg.GetDaemonEndpointsFromString(c.DaemonAddr) + if daemonEndpoints != nil { + globalCfg.daemonAddr = daemonEndpoints.UDPAddr + globalCfg.emitter.RefreshEmitterWithAddress(globalCfg.daemonAddr) + configureStrategy(globalCfg.samplingStrategy, daemonEndpoints) + } else if er != nil { + errors = append(errors, er) } if c.ExceptionFormattingStrategy != nil { - privateCfg.exceptionFormattingStrategy = c.ExceptionFormattingStrategy + globalCfg.exceptionFormattingStrategy = c.ExceptionFormattingStrategy } if c.StreamingStrategy != nil { - privateCfg.streamingStrategy = c.StreamingStrategy + globalCfg.streamingStrategy = c.StreamingStrategy } cms := os.Getenv("AWS_XRAY_CONTEXT_MISSING") if cms != "" { if cms == ctxmissing.RuntimeErrorStrategy { cm := ctxmissing.NewDefaultRuntimeErrorStrategy() - privateCfg.contextMissingStrategy = cm + globalCfg.contextMissingStrategy = cm } else if cms == ctxmissing.LogErrorStrategy { cm := ctxmissing.NewDefaultLogErrorStrategy() - privateCfg.contextMissingStrategy = cm + globalCfg.contextMissingStrategy = cm } } else if c.ContextMissingStrategy != nil { - privateCfg.contextMissingStrategy = c.ContextMissingStrategy + globalCfg.contextMissingStrategy = c.ContextMissingStrategy } if c.ServiceVersion != "" { - privateCfg.serviceVersion = c.ServiceVersion + globalCfg.serviceVersion = c.ServiceVersion } - privateCfg.logLevel, privateCfg.logFormat = loadLogConfig(c.LogLevel, c.LogFormat) + globalCfg.logLevel, globalCfg.logFormat = loadLogConfig(c.LogLevel, c.LogFormat) switch len(errors) { case 0: @@ -182,49 +253,49 @@ func loadLogConfig(logLevel string, logFormat string) (log.LogLevel, string) { return level, format } -func (c *privateConfig) DaemonAddr() *net.UDPAddr { +func (c *globalConfig) DaemonAddr() *net.UDPAddr { c.RLock() defer c.RUnlock() return c.daemonAddr } -func (c *privateConfig) SamplingStrategy() sampling.Strategy { +func (c *globalConfig) SamplingStrategy() sampling.Strategy { c.RLock() defer c.RUnlock() return c.samplingStrategy } -func (c *privateConfig) StreamingStrategy() StreamingStrategy { +func (c *globalConfig) StreamingStrategy() StreamingStrategy { c.RLock() defer c.RUnlock() return c.streamingStrategy } -func (c *privateConfig) ExceptionFormattingStrategy() exception.FormattingStrategy { +func (c *globalConfig) ExceptionFormattingStrategy() exception.FormattingStrategy { c.RLock() defer c.RUnlock() return c.exceptionFormattingStrategy } -func (c *privateConfig) ContextMissingStrategy() ctxmissing.Strategy { +func (c *globalConfig) ContextMissingStrategy() ctxmissing.Strategy { c.RLock() defer c.RUnlock() return c.contextMissingStrategy } -func (c *privateConfig) ServiceVersion() string { +func (c *globalConfig) ServiceVersion() string { c.RLock() defer c.RUnlock() return c.serviceVersion } -func (c *privateConfig) LogLevel() log.LogLevel { +func (c *globalConfig) LogLevel() log.LogLevel { c.RLock() defer c.RUnlock() return c.logLevel } -func (c *privateConfig) LogFormat() string { +func (c *globalConfig) LogFormat() string { c.RLock() defer c.RUnlock() return c.logFormat diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/context.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/context.go index abd5a782..58a4eb57 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/context.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/context.go @@ -22,6 +22,18 @@ var ContextKey = new(ContextKeytype) // ErrRetrieveSegment happens when a segment cannot be retrieved var ErrRetrieveSegment = errors.New("unable to retrieve segment") +// RecorderContextKey records the key for Config value. +type RecorderContextKey struct{} + +// GetRecorder returns a pointer to the config struct provided +// in ctx, or nil if no config is set. +func GetRecorder(ctx context.Context) *Config { + if r, ok := ctx.Value(RecorderContextKey{}).(*Config); ok { + return r + } + return nil +} + // GetSegment returns a pointer to the segment or subsegment provided // in ctx, or nil if no segment or subsegment is found. func GetSegment(ctx context.Context) *Segment { diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/default_emitter.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/default_emitter.go new file mode 100644 index 00000000..4211efc2 --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/default_emitter.go @@ -0,0 +1,103 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +package xray + +import ( + "bytes" + "encoding/json" + "net" + "sync" + + log "github.com/cihub/seelog" +) + +// Header is added before sending segments to daemon. +var Header = []byte(`{"format": "json", "version": 1}` + "\n") + +// DefaultEmitter provides the naive implementation of emitting trace entities. +type DefaultEmitter struct { + sync.Mutex + conn *net.UDPConn +} + +// NewDefaultEmitter initializes and returns a +// pointer to an instance of DefaultEmitter. +func NewDefaultEmitter(raddr *net.UDPAddr) (*DefaultEmitter, error) { + initLambda() + d := &DefaultEmitter{} + d.RefreshEmitterWithAddress(raddr) + return d, nil +} + +// RefreshEmitterWithAddress dials UDP based on the input UDP address. +func (de *DefaultEmitter) RefreshEmitterWithAddress(raddr *net.UDPAddr) { + de.Lock() + de.conn, _ = net.DialUDP("udp", nil, raddr) + log.Infof("Emitter using address: %v", raddr) + de.Unlock() +} + +// Emit segment or subsegment if root segment is sampled. +func (de *DefaultEmitter) Emit(seg *Segment) { + if seg == nil || !seg.ParentSegment.Sampled { + return + } + + var logLevel string + if seg.Configuration != nil && seg.Configuration.LogLevel == "trace" { + logLevel = "trace" + } else if globalCfg.logLevel <= log.TraceLvl { + logLevel = "trace" + } + + for _, p := range packSegments(seg, nil) { + if logLevel == "trace" { + b := &bytes.Buffer{} + json.Indent(b, p, "", " ") + log.Trace(b.String()) + } + de.Lock() + _, err := de.conn.Write(append(Header, p...)) + if err != nil { + log.Error(err) + } + de.Unlock() + } +} + +func packSegments(seg *Segment, outSegments [][]byte) [][]byte { + trimSubsegment := func(s *Segment) []byte { + ss := globalCfg.StreamingStrategy() + if seg.ParentSegment.Configuration != nil && seg.ParentSegment.Configuration.StreamingStrategy != nil { + ss = seg.ParentSegment.Configuration.StreamingStrategy + } + for ss.RequiresStreaming(s) { + if len(s.rawSubsegments) == 0 { + break + } + cb := ss.StreamCompletedSubsegments(s) + outSegments = append(outSegments, cb...) + } + b, _ := json.Marshal(s) + return b + } + + for _, s := range seg.rawSubsegments { + outSegments = packSegments(s, outSegments) + if b := trimSubsegment(s); b != nil { + seg.Subsegments = append(seg.Subsegments, b) + } + } + if seg.parent == nil { + if b := trimSubsegment(seg); b != nil { + outSegments = append(outSegments, b) + } + } + return outSegments +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/default_streaming_strategy.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/default_streaming_strategy.go index 0b8fb3fb..d763d313 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/default_streaming_strategy.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/default_streaming_strategy.go @@ -68,11 +68,7 @@ func (dSS *DefaultStreamingStrategy) StreamCompletedSubsegments(seg *Segment) [] // Add extra information into child subsegment child.Lock() - child.TraceID = seg.root().TraceID - child.ParentID = seg.ID - child.Type = "subsegment" - child.parent = nil - child.RequestWasTraced = seg.RequestWasTraced + child.beforeEmitSubsegment(seg) cb, _ := json.Marshal(child) outSegments = append(outSegments, cb) log.Tracef("Streaming subsegment named '%s' from segment tree.", child.Name) diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/emitter.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/emitter.go index cfb381b3..a0e28171 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/emitter.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/emitter.go @@ -8,82 +8,10 @@ package xray -import ( - "bytes" - "encoding/json" - "net" - "sync" +import "net" - log "github.com/cihub/seelog" -) - -// Header is added before sending segments to daemon. -var Header = []byte(`{"format": "json", "version": 1}` + "\n") - -type emitter struct { - sync.Mutex - conn *net.UDPConn -} - -var e = &emitter{} - -func init() { - refreshEmitter() -} - -func refreshEmitter() { - e.Lock() - e.conn, _ = net.DialUDP("udp", nil, privateCfg.DaemonAddr()) - e.Unlock() -} - -func emit(seg *Segment) { - if seg == nil || !seg.Sampled { - return - } - - for _, p := range packSegments(seg, nil) { - if privateCfg.LogLevel() <= log.TraceLvl { - b := &bytes.Buffer{} - json.Indent(b, p, "", " ") - log.Trace(b.String()) - } - e.Lock() - _, err := e.conn.Write(append(Header, p...)) - if err != nil { - log.Error(err) - } - e.Unlock() - } -} - -func packSegments(seg *Segment, outSegments [][]byte) [][]byte { - seg.Lock() - defer seg.Unlock() - - trimSubsegment := func(s *Segment) []byte { - ss := privateCfg.StreamingStrategy() - for ss.RequiresStreaming(s) { - if len(s.rawSubsegments) == 0 { - break - } - cb := ss.StreamCompletedSubsegments(s) - outSegments = append(outSegments, cb...) - } - b, _ := json.Marshal(s) - return b - } - - for _, s := range seg.rawSubsegments { - outSegments = packSegments(s, outSegments) - if b := trimSubsegment(s); b != nil { - seg.Subsegments = append(seg.Subsegments, b) - } - } - if seg.parent == nil { - if b := trimSubsegment(seg); b != nil { - outSegments = append(outSegments, b) - } - } - return outSegments +// Emitter provides an interface for implementing emitting trace entities. +type Emitter interface { + Emit(seg *Segment) + RefreshEmitterWithAddress(raddr *net.UDPAddr) } diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/handler.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/handler.go index b53d885f..2b99c14b 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/handler.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/handler.go @@ -10,12 +10,17 @@ package xray import ( "bytes" + "context" + "net" "net/http" "os" "strconv" "strings" + "github.com/aws/aws-xray-sdk-go/strategy/sampling" + "github.com/aws/aws-xray-sdk-go/header" + "github.com/aws/aws-xray-sdk-go/internal/plugins" "github.com/aws/aws-xray-sdk-go/pattern" log "github.com/cihub/seelog" ) @@ -79,77 +84,98 @@ func (dSN *DynamicSegmentNamer) Name(host string) string { return dSN.FallbackName } +// HandlerWithContext wraps the provided http handler and context to parse +// the incoming headers, add response headers if needed, and sets HTTP +// specific trace fields. HandlerWithContext names the generated segments +// using the provided SegmentNamer. +func HandlerWithContext(ctx context.Context, sn SegmentNamer, h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + name := sn.Name(r.Host) + + traceHeader := header.FromString(r.Header.Get("x-amzn-trace-id")) + + r = r.WithContext(ctx) + c, seg := NewSegmentFromHeader(r.Context(), name, traceHeader) + r = r.WithContext(c) + + httpTrace(seg, h, w, r, traceHeader) + }) +} + // Handler wraps the provided http handler with xray.Capture // using the request's context, parsing the incoming headers, -// adding response headers if needed, and sets HTTP sepecific trace fields. +// adding response headers if needed, and sets HTTP specific trace fields. // Handler names the generated segments using the provided SegmentNamer. func Handler(sn SegmentNamer, h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { name := sn.Name(r.Host) traceHeader := header.FromString(r.Header.Get("x-amzn-trace-id")) - ctx, seg := NewSegmentFromHeader(r.Context(), name, traceHeader) r = r.WithContext(ctx) - seg.Lock() + httpTrace(seg, h, w, r, traceHeader) + }) +} - seg.GetHTTP().GetRequest().Method = r.Method - seg.GetHTTP().GetRequest().URL = r.URL.String() - seg.GetHTTP().GetRequest().ClientIP, seg.GetHTTP().GetRequest().XForwardedFor = clientIP(r) - seg.GetHTTP().GetRequest().UserAgent = r.UserAgent() +func httpTrace(seg *Segment, h http.Handler, w http.ResponseWriter, r *http.Request, traceHeader *header.Header) { + seg.Lock() - trace := parseHeaders(r.Header) - if trace["Root"] != "" { - seg.TraceID = trace["Root"] - seg.RequestWasTraced = true - } - if trace["Parent"] != "" { - seg.ParentID = trace["Parent"] - } - // Don't use the segment's header here as we only want to - // send back the root and possibly sampled values. - var respHeader bytes.Buffer - respHeader.WriteString("Root=") - respHeader.WriteString(seg.TraceID) - switch trace["Sampled"] { - case "0": - seg.Sampled = false - log.Trace("Incoming header decided: Sampled=false") - case "1": - seg.Sampled = true - log.Trace("Incoming header decided: Sampled=true") - default: - seg.Sampled = privateCfg.SamplingStrategy().ShouldTrace(r.Host, r.URL.String(), r.Method) - log.Tracef("SamplingStrategy decided: %t", seg.Sampled) - } - if trace["Sampled"] == "?" { - respHeader.WriteString(";Sampled=") - respHeader.WriteString(strconv.Itoa(btoi(seg.Sampled))) + scheme := "https://" + if r.TLS == nil { + scheme = "http://" + } + seg.GetHTTP().GetRequest().Method = r.Method + seg.GetHTTP().GetRequest().URL = scheme + r.Host + r.URL.Path + seg.GetHTTP().GetRequest().ClientIP, seg.GetHTTP().GetRequest().XForwardedFor = clientIP(r) + seg.GetHTTP().GetRequest().UserAgent = r.UserAgent() + + // Don't use the segment's header here as we only want to + // send back the root and possibly sampled values. + var respHeader bytes.Buffer + respHeader.WriteString("Root=") + respHeader.WriteString(seg.TraceID) + + if traceHeader.SamplingDecision != header.Sampled && traceHeader.SamplingDecision != header.NotSampled { + samplingRequest := &sampling.Request{ + Host: r.Host, + Url: r.URL.Path, + Method: r.Method, + ServiceName: seg.Name, + ServiceType: plugins.InstancePluginMetadata.Origin, } - w.Header().Set("x-amzn-trace-id", respHeader.String()) - seg.Unlock() + sd := seg.ParentSegment.GetConfiguration().SamplingStrategy.ShouldTrace(samplingRequest) + seg.Sampled = sd.Sample + log.Tracef("SamplingStrategy decided: %t", seg.Sampled) + seg.AddRuleName(sd) + } + if traceHeader.SamplingDecision == header.Requested { + respHeader.WriteString(";Sampled=") + respHeader.WriteString(strconv.Itoa(btoi(seg.Sampled))) + } - resp := &responseCapturer{w, 200, 0} - h.ServeHTTP(resp, r) + w.Header().Set("x-amzn-trace-id", respHeader.String()) + seg.Unlock() - seg.Lock() - seg.GetHTTP().GetResponse().Status = resp.status - seg.GetHTTP().GetResponse().ContentLength, _ = strconv.Atoi(resp.Header().Get("Content-Length")) + resp := &responseCapturer{w, 200, 0} + h.ServeHTTP(resp, r) - if resp.status >= 400 && resp.status < 500 { - seg.Error = true - } - if resp.status == 429 { - seg.Throttle = true - } - if resp.status >= 500 && resp.status < 600 { - seg.Fault = true - } - seg.Unlock() - seg.Close(nil) - }) + seg.Lock() + seg.GetHTTP().GetResponse().Status = resp.status + seg.GetHTTP().GetResponse().ContentLength, _ = strconv.Atoi(resp.Header().Get("Content-Length")) + + if resp.status >= 400 && resp.status < 500 { + seg.Error = true + } + if resp.status == 429 { + seg.Throttle = true + } + if resp.status >= 500 && resp.status < 600 { + seg.Fault = true + } + seg.Unlock() + seg.Close(nil) } func clientIP(r *http.Request) (string, bool) { @@ -157,8 +183,11 @@ func clientIP(r *http.Request) (string, bool) { if forwardedFor != "" { return strings.TrimSpace(strings.Split(forwardedFor, ",")[0]), true } - - return r.RemoteAddr, false + ip, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + return r.RemoteAddr, false + } + return ip, false } type responseCapturer struct { @@ -183,18 +212,3 @@ func btoi(b bool) int { } return 0 } - -func parseHeaders(h http.Header) map[string]string { - m := map[string]string{} - s := h.Get("x-amzn-trace-id") - for _, c := range strings.Split(s, ";") { - p := strings.SplitN(c, "=", 2) - k := strings.TrimSpace(p[0]) - v := "" - if len(p) > 1 { - v = strings.TrimSpace(p[1]) - } - m[k] = v - } - return m -} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/httptrace.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/httptrace.go index 22f0ad17..7609afba 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/httptrace.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/httptrace.go @@ -6,6 +6,8 @@ // // or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. +// +build go1.8 + package xray import ( @@ -13,8 +15,10 @@ import ( "crypto/tls" "errors" "net/http/httptrace" + "sync" ) +// HTTPSubsegments is a set of context in different HTTP operation. type HTTPSubsegments struct { opCtx context.Context connCtx context.Context @@ -23,6 +27,13 @@ type HTTPSubsegments struct { tlsCtx context.Context reqCtx context.Context responseCtx context.Context + mu sync.Mutex +} + +// NewHTTPSubsegments creates a new HTTPSubsegments to use in +// httptrace.ClientTrace functions +func NewHTTPSubsegments(opCtx context.Context) *HTTPSubsegments { + return &HTTPSubsegments{opCtx: opCtx} } // GetConn begins a connect subsegment if the HTTP operation @@ -36,7 +47,7 @@ func (xt *HTTPSubsegments) GetConn(hostPort string) { // DNSStart begins a dns subsegment if the HTTP operation // subsegment is still in progress. func (xt *HTTPSubsegments) DNSStart(info httptrace.DNSStartInfo) { - if GetSegment(xt.opCtx).InProgress { + if GetSegment(xt.opCtx).safeInProgress() { xt.dnsCtx, _ = BeginSubsegment(xt.connCtx, "dns") } } @@ -47,7 +58,7 @@ func (xt *HTTPSubsegments) DNSStart(info httptrace.DNSStartInfo) { // and whether or not the call was coalesced is added as // metadata to the dns subsegment. func (xt *HTTPSubsegments) DNSDone(info httptrace.DNSDoneInfo) { - if xt.dnsCtx != nil && GetSegment(xt.opCtx).InProgress { + if xt.dnsCtx != nil && GetSegment(xt.opCtx).safeInProgress() { metadata := make(map[string]interface{}) metadata["addresses"] = info.Addrs metadata["coalesced"] = info.Coalesced @@ -60,7 +71,7 @@ func (xt *HTTPSubsegments) DNSDone(info httptrace.DNSDoneInfo) { // ConnectStart begins a dial subsegment if the HTTP operation // subsegment is still in progress. func (xt *HTTPSubsegments) ConnectStart(network, addr string) { - if GetSegment(xt.opCtx).InProgress { + if GetSegment(xt.opCtx).safeInProgress() { xt.connectCtx, _ = BeginSubsegment(xt.connCtx, "dial") } } @@ -70,7 +81,7 @@ func (xt *HTTPSubsegments) ConnectStart(network, addr string) { // (if any). Information about the network over which the dial // was made is added as metadata to the subsegment. func (xt *HTTPSubsegments) ConnectDone(network, addr string, err error) { - if xt.connectCtx != nil && GetSegment(xt.opCtx).InProgress { + if xt.connectCtx != nil && GetSegment(xt.opCtx).safeInProgress() { metadata := make(map[string]interface{}) metadata["network"] = network @@ -82,7 +93,7 @@ func (xt *HTTPSubsegments) ConnectDone(network, addr string, err error) { // TLSHandshakeStart begins a tls subsegment if the HTTP operation // subsegment is still in progress. func (xt *HTTPSubsegments) TLSHandshakeStart() { - if GetSegment(xt.opCtx).InProgress { + if GetSegment(xt.opCtx).safeInProgress() { xt.tlsCtx, _ = BeginSubsegment(xt.connCtx, "tls") } } @@ -92,7 +103,7 @@ func (xt *HTTPSubsegments) TLSHandshakeStart() { // error value(if any). Information about the tls connection // is added as metadata to the subsegment. func (xt *HTTPSubsegments) TLSHandshakeDone(connState tls.ConnectionState, err error) { - if xt.tlsCtx != nil && GetSegment(xt.opCtx).InProgress { + if xt.tlsCtx != nil && GetSegment(xt.opCtx).safeInProgress() { metadata := make(map[string]interface{}) metadata["did_resume"] = connState.DidResume metadata["negotiated_protocol"] = connState.NegotiatedProtocol @@ -140,18 +151,25 @@ func (xt *HTTPSubsegments) GotConn(info *httptrace.GotConnInfo, err error) { func (xt *HTTPSubsegments) WroteRequest(info httptrace.WroteRequestInfo) { if xt.reqCtx != nil && GetSegment(xt.opCtx).InProgress { GetSegment(xt.reqCtx).Close(info.Err) - xt.responseCtx, _ = BeginSubsegment(xt.opCtx, "response") + resCtx, _ := BeginSubsegment(xt.opCtx, "response") + xt.mu.Lock() + xt.responseCtx = resCtx + xt.mu.Unlock() } } // GotFirstResponseByte closes the response subsegment if the HTTP // operation subsegment is still in progress. func (xt *HTTPSubsegments) GotFirstResponseByte() { - if xt.responseCtx != nil && GetSegment(xt.opCtx).InProgress { - GetSegment(xt.responseCtx).Close(nil) + xt.mu.Lock() + resCtx := xt.responseCtx + xt.mu.Unlock() + if resCtx != nil && GetSegment(xt.opCtx).InProgress { + GetSegment(resCtx).Close(nil) } } +// ClientTrace is a set of pointers of HTTPSubsegments and ClientTrace. type ClientTrace struct { subsegments *HTTPSubsegments httpTrace *httptrace.ClientTrace @@ -166,9 +184,7 @@ func NewClientTrace(opCtx context.Context) (ct *ClientTrace, err error) { return nil, errors.New("opCtx must be non-nil") } - segs := &HTTPSubsegments{ - opCtx: opCtx, - } + segs := NewHTTPSubsegments(opCtx) return &ClientTrace{ subsegments: segs, @@ -205,5 +221,4 @@ func NewClientTrace(opCtx context.Context) (ct *ClientTrace, err error) { }, }, }, nil - } diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/httptrace_go17.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/httptrace_go17.go new file mode 100644 index 00000000..d6c4bd5e --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/httptrace_go17.go @@ -0,0 +1,184 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +// +build !go1.8 + +package xray + +import ( + "context" + "errors" + "net/http/httptrace" +) + +// HTTPSubsegments is a set of context in different HTTP operation. +type HTTPSubsegments struct { + opCtx context.Context + connCtx context.Context + dnsCtx context.Context + connectCtx context.Context + tlsCtx context.Context + reqCtx context.Context + responseCtx context.Context +} + +// NewHTTPSubsegments creates a new HTTPSubsegments to use in +// httptrace.ClientTrace functions +func NewHTTPSubsegments(opCtx context.Context) *HTTPSubsegments { + return &HTTPSubsegments{opCtx: opCtx} +} + +// GetConn begins a connect subsegment if the HTTP operation +// subsegment is still in progress. +func (xt *HTTPSubsegments) GetConn(hostPort string) { + if GetSegment(xt.opCtx).InProgress { + xt.connCtx, _ = BeginSubsegment(xt.opCtx, "connect") + } +} + +// DNSStart begins a dns subsegment if the HTTP operation +// subsegment is still in progress. +func (xt *HTTPSubsegments) DNSStart(info httptrace.DNSStartInfo) { + if GetSegment(xt.opCtx).InProgress { + xt.dnsCtx, _ = BeginSubsegment(xt.connCtx, "dns") + } +} + +// DNSDone closes the dns subsegment if the HTTP operation +// subsegment is still in progress, passing the error value +// (if any). Information about the address values looked up, +// and whether or not the call was coalesced is added as +// metadata to the dns subsegment. +func (xt *HTTPSubsegments) DNSDone(info httptrace.DNSDoneInfo) { + if xt.dnsCtx != nil && GetSegment(xt.opCtx).InProgress { + metadata := make(map[string]interface{}) + metadata["addresses"] = info.Addrs + metadata["coalesced"] = info.Coalesced + + AddMetadataToNamespace(xt.dnsCtx, "http", "dns", metadata) + GetSegment(xt.dnsCtx).Close(info.Err) + } +} + +// ConnectStart begins a dial subsegment if the HTTP operation +// subsegment is still in progress. +func (xt *HTTPSubsegments) ConnectStart(network, addr string) { + if GetSegment(xt.opCtx).InProgress { + xt.connectCtx, _ = BeginSubsegment(xt.connCtx, "dial") + } +} + +// ConnectDone closes the dial subsegment if the HTTP operation +// subsegment is still in progress, passing the error value +// (if any). Information about the network over which the dial +// was made is added as metadata to the subsegment. +func (xt *HTTPSubsegments) ConnectDone(network, addr string, err error) { + if xt.connectCtx != nil && GetSegment(xt.opCtx).InProgress { + metadata := make(map[string]interface{}) + metadata["network"] = network + + AddMetadataToNamespace(xt.connectCtx, "http", "connect", metadata) + GetSegment(xt.connectCtx).Close(err) + } +} + +// GotConn closes the connect subsegment if the HTTP operation +// subsegment is still in progress, passing the error value +// (if any). Information about the connection is added as +// metadata to the subsegment. If the connection is marked as reused, +// the connect subsegment is deleted. +func (xt *HTTPSubsegments) GotConn(info *httptrace.GotConnInfo, err error) { + if xt.connCtx != nil && GetSegment(xt.opCtx).InProgress { // GetConn may not have been called (client_test.TestBadRoundTrip) + if info != nil { + if info.Reused { + GetSegment(xt.opCtx).RemoveSubsegment(GetSegment(xt.connCtx)) + } else { + metadata := make(map[string]interface{}) + metadata["reused"] = info.Reused + metadata["was_idle"] = info.WasIdle + if info.WasIdle { + metadata["idle_time"] = info.IdleTime + } + + AddMetadataToNamespace(xt.connCtx, "http", "connection", metadata) + GetSegment(xt.connCtx).Close(err) + } + } + + if err == nil { + xt.reqCtx, _ = BeginSubsegment(xt.opCtx, "request") + } + + } +} + +// WroteRequest closes the request subsegment if the HTTP operation +// subsegment is still in progress, passing the error value +// (if any). The response subsegment is then begun. +func (xt *HTTPSubsegments) WroteRequest(info httptrace.WroteRequestInfo) { + if xt.reqCtx != nil && GetSegment(xt.opCtx).InProgress { + GetSegment(xt.reqCtx).Close(info.Err) + xt.responseCtx, _ = BeginSubsegment(xt.opCtx, "response") + } +} + +// GotFirstResponseByte closes the response subsegment if the HTTP +// operation subsegment is still in progress. +func (xt *HTTPSubsegments) GotFirstResponseByte() { + if xt.responseCtx != nil && GetSegment(xt.opCtx).InProgress { + GetSegment(xt.responseCtx).Close(nil) + } +} + +// ClientTrace is a set of pointers of HTTPSubsegments and ClientTrace. +type ClientTrace struct { + subsegments *HTTPSubsegments + httpTrace *httptrace.ClientTrace +} + +// NewClientTrace returns an instance of xray.ClientTrace, a wrapper +// around httptrace.ClientTrace. The ClientTrace implementation will +// generate subsegments for connection time, DNS lookup time, TLS +// handshake time, and provides additional information about the HTTP round trip +func NewClientTrace(opCtx context.Context) (ct *ClientTrace, err error) { + if opCtx == nil { + return nil, errors.New("opCtx must be non-nil") + } + + segs := NewHTTPSubsegments(opCtx) + + return &ClientTrace{ + subsegments: segs, + httpTrace: &httptrace.ClientTrace{ + GetConn: func(hostPort string) { + segs.GetConn(hostPort) + }, + DNSStart: func(info httptrace.DNSStartInfo) { + segs.DNSStart(info) + }, + DNSDone: func(info httptrace.DNSDoneInfo) { + segs.DNSDone(info) + }, + ConnectStart: func(network, addr string) { + segs.ConnectStart(network, addr) + }, + ConnectDone: func(network, addr string, err error) { + segs.ConnectDone(network, addr, err) + }, + GotConn: func(info httptrace.GotConnInfo) { + segs.GotConn(&info, nil) + }, + WroteRequest: func(info httptrace.WroteRequestInfo) { + segs.WroteRequest(info) + }, + GotFirstResponseByte: func() { + segs.GotFirstResponseByte() + }, + }, + }, nil +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/lambda.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/lambda.go new file mode 100644 index 00000000..4a66cebc --- /dev/null +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/lambda.go @@ -0,0 +1,91 @@ +// Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at +// +// http://aws.amazon.com/apache2.0/ +// +// or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + +package xray + +import ( + "context" + "os" + "path/filepath" + "time" + + "github.com/aws/aws-xray-sdk-go/header" + log "github.com/cihub/seelog" +) + +// LambdaTraceHeaderKey is key to get trace header from context. +const LambdaTraceHeaderKey string = "x-amzn-trace-id" + +// LambdaTaskRootKey is the key to get Lambda Task Root from environment variable. +const LambdaTaskRootKey string = "LAMBDA_TASK_ROOT" + +// SDKInitializedFileFolder records the location of SDK initialized file. +const SDKInitializedFileFolder string = "/tmp/.aws-xray" + +// SDKInitializedFileName records the SDK initialized file name. +const SDKInitializedFileName string = "initialized" + +func getTraceHeaderFromContext(ctx context.Context) *header.Header { + var traceHeader string + + if traceHeaderValue := ctx.Value(LambdaTraceHeaderKey); traceHeaderValue != nil { + traceHeader = traceHeaderValue.(string) + return header.FromString(traceHeader) + } + return nil +} + +func newFacadeSegment(ctx context.Context) (context.Context, *Segment) { + traceHeader := getTraceHeaderFromContext(ctx) + return BeginFacadeSegment(ctx, "facade", traceHeader) +} + +func getLambdaTaskRoot() string { + return os.Getenv(LambdaTaskRootKey) +} + +func initLambda() { + if getLambdaTaskRoot() != "" { + now := time.Now() + filePath, err := createFile(SDKInitializedFileFolder, SDKInitializedFileName) + if err != nil { + log.Tracef("unable to create file at %s. failed to signal SDK initialization with error: %v", filePath, err) + } else { + e := os.Chtimes(filePath, now, now) + if e != nil { + log.Tracef("unable to write to %s. failed to signal SDK initialization with error: %v", filePath, e) + } + } + } +} + +func createFile(dir string, name string) (string, error) { + fileDir := filepath.FromSlash(dir) + filePath := fileDir + string(os.PathSeparator) + name + + // detect if file exists + var _, err = os.Stat(filePath) + + // create file if not exists + if os.IsNotExist(err) { + e := os.MkdirAll(dir, os.ModePerm) + if e != nil { + return filePath, e + } + var file, err = os.Create(filePath) + if err != nil { + return filePath, err + } + file.Close() + return filePath, nil + } else if err != nil { + return filePath, err + } + + return filePath, nil +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/segment.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/segment.go index b3169ea0..c1ac2c2a 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/segment.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/segment.go @@ -13,6 +13,7 @@ import ( "crypto/rand" "fmt" "os" + "runtime" "time" "github.com/aws/aws-xray-sdk-go/header" @@ -40,8 +41,43 @@ func NewSegmentID() string { return fmt.Sprintf("%02x", r) } +// BeginFacadeSegment creates a Segment for a given name and context. +func BeginFacadeSegment(ctx context.Context, name string, h *header.Header) (context.Context, *Segment) { + seg := basicSegment(name, h) + + cfg := GetRecorder(ctx) + seg.assignConfiguration(cfg) + + return context.WithValue(ctx, ContextKey, seg), seg +} + // BeginSegment creates a Segment for a given name and context. func BeginSegment(ctx context.Context, name string) (context.Context, *Segment) { + seg := basicSegment(name, nil) + + cfg := GetRecorder(ctx) + seg.assignConfiguration(cfg) + + seg.Lock() + defer seg.Unlock() + + seg.addPlugin(plugins.InstancePluginMetadata) + seg.addSDKAndServiceInformation() + if seg.ParentSegment.GetConfiguration().ServiceVersion != "" { + seg.GetService().Version = seg.ParentSegment.GetConfiguration().ServiceVersion + } + + go func() { + select { + case <-ctx.Done(): + seg.handleContextDone() + } + }() + + return context.WithValue(ctx, ContextKey, seg), seg +} + +func basicSegment(name string, h *header.Header) *Segment { if len(name) > 200 { name = name[:200] } @@ -52,30 +88,72 @@ func BeginSegment(ctx context.Context, name string) (context.Context, *Segment) seg.Lock() defer seg.Unlock() - seg.TraceID = NewTraceID() - seg.Sampled = true - seg.addPlugin(plugins.InstancePluginMetadata) - if svcVersion := privateCfg.ServiceVersion(); svcVersion != "" { - seg.GetService().Version = svcVersion - } - seg.ID = NewSegmentID() seg.Name = name seg.StartTime = float64(time.Now().UnixNano()) / float64(time.Second) seg.InProgress = true - go func() { - select { - case <-ctx.Done(): - seg.Lock() - seg.ContextDone = true - seg.Unlock() - if !seg.InProgress && !seg.Emitted { - seg.flush(false) - } + if h == nil { + seg.TraceID = NewTraceID() + seg.ID = NewSegmentID() + seg.Sampled = true + } else { + seg.Facade = true + seg.ID = h.ParentID + seg.TraceID = h.TraceID + seg.Sampled = h.SamplingDecision == header.Sampled + } + + return seg +} + +// assignConfiguration assigns value to seg.Configuration +func (seg *Segment) assignConfiguration(cfg *Config) { + seg.Lock() + if cfg == nil { + seg.GetConfiguration().ContextMissingStrategy = globalCfg.contextMissingStrategy + seg.GetConfiguration().ExceptionFormattingStrategy = globalCfg.exceptionFormattingStrategy + seg.GetConfiguration().SamplingStrategy = globalCfg.samplingStrategy + seg.GetConfiguration().StreamingStrategy = globalCfg.streamingStrategy + seg.GetConfiguration().Emitter = globalCfg.emitter + seg.GetConfiguration().ServiceVersion = globalCfg.serviceVersion + } else { + if cfg.ContextMissingStrategy != nil { + seg.GetConfiguration().ContextMissingStrategy = cfg.ContextMissingStrategy + } else { + seg.GetConfiguration().ContextMissingStrategy = globalCfg.contextMissingStrategy } - }() - return context.WithValue(ctx, ContextKey, seg), seg + if cfg.ExceptionFormattingStrategy != nil { + seg.GetConfiguration().ExceptionFormattingStrategy = cfg.ExceptionFormattingStrategy + } else { + seg.GetConfiguration().ExceptionFormattingStrategy = globalCfg.exceptionFormattingStrategy + } + + if cfg.SamplingStrategy != nil { + seg.GetConfiguration().SamplingStrategy = cfg.SamplingStrategy + } else { + seg.GetConfiguration().SamplingStrategy = globalCfg.samplingStrategy + } + + if cfg.StreamingStrategy != nil { + seg.GetConfiguration().StreamingStrategy = cfg.StreamingStrategy + } else { + seg.GetConfiguration().StreamingStrategy = globalCfg.streamingStrategy + } + + if cfg.Emitter != nil { + seg.GetConfiguration().Emitter = cfg.Emitter + } else { + seg.GetConfiguration().Emitter = globalCfg.emitter + } + + if cfg.ServiceVersion != "" { + seg.GetConfiguration().ServiceVersion = cfg.ServiceVersion + } else { + seg.GetConfiguration().ServiceVersion = globalCfg.serviceVersion + } + } + seg.Unlock() } // BeginSubsegment creates a subsegment for a given name and context. @@ -83,23 +161,42 @@ func BeginSubsegment(ctx context.Context, name string) (context.Context, *Segmen if len(name) > 200 { name = name[:200] } - parent := GetSegment(ctx) - if parent == nil { - privateCfg.ContextMissingStrategy().ContextMissing(fmt.Sprintf("failed to begin subsegment named '%v': segment cannot be found.", name)) - return nil, nil + + parent := &Segment{} + // first time to create facade segment + if getTraceHeaderFromContext(ctx) != nil && GetSegment(ctx) == nil { + _, parent = newFacadeSegment(ctx) + } else { + parent = GetSegment(ctx) + if parent == nil { + cfg := GetRecorder(ctx) + failedMessage := fmt.Sprintf("failed to begin subsegment named '%v': segment cannot be found.", name) + if cfg != nil && cfg.ContextMissingStrategy != nil { + cfg.ContextMissingStrategy.ContextMissing(failedMessage) + } else { + globalCfg.ContextMissingStrategy().ContextMissing(failedMessage) + } + return ctx, nil + } } seg := &Segment{parent: parent} log.Tracef("Beginning subsegment named %s", name) - seg.ParentSegment = parent.ParentSegment - seg.ParentSegment.totalSubSegments++ + seg.Lock() defer seg.Unlock() parent.Lock() + defer parent.Unlock() + + seg.ParentSegment = parent.ParentSegment + if seg.ParentSegment != seg && seg.ParentSegment != parent { + seg.ParentSegment.Lock() + defer seg.ParentSegment.Unlock() + } + seg.ParentSegment.totalSubSegments++ parent.rawSubsegments = append(parent.rawSubsegments, seg) parent.openSegments++ - parent.Unlock() seg.ID = NewSegmentID() seg.Name = name @@ -119,16 +216,25 @@ func NewSegmentFromHeader(ctx context.Context, name string, h *header.Header) (c if h.ParentID != "" { seg.ParentID = h.ParentID } + seg.Sampled = h.SamplingDecision == header.Sampled + switch h.SamplingDecision { + case header.Sampled: + log.Trace("Incoming header decided: Sampled=true") + case header.NotSampled: + log.Trace("Incoming header decided: Sampled=false") + } + seg.IncomingHeader = h + seg.RequestWasTraced = true return con, seg } // Close a segment. func (seg *Segment) Close(err error) { - seg.Lock() + defer seg.Unlock() if seg.parent != nil { log.Tracef("Closing subsegment named %s", seg.Name) } else { @@ -136,13 +242,36 @@ func (seg *Segment) Close(err error) { } seg.EndTime = float64(time.Now().UnixNano()) / float64(time.Second) seg.InProgress = false - seg.Unlock() if err != nil { - seg.AddError(err) + seg.addError(err) + } + + seg.flush() +} + +// CloseAndStream closes a subsegment and sends it. +func (subseg *Segment) CloseAndStream(err error) { + subseg.Lock() + + if subseg.parent != nil { + log.Tracef("Ending subsegment named: %s", subseg.Name) + subseg.EndTime = float64(time.Now().UnixNano()) / float64(time.Second) + subseg.InProgress = false + subseg.Emitted = true + if subseg.parent.RemoveSubsegment(subseg) { + log.Tracef("Removing subsegment named: %s", subseg.Name) + } + } + + if err != nil { + subseg.addError(err) } - seg.flush(false) + subseg.beforeEmitSubsegment(subseg.parent) + subseg.Unlock() + + subseg.emit() } // RemoveSubsegment removes a subsegment child from a segment or subsegment. @@ -164,26 +293,50 @@ func (seg *Segment) RemoveSubsegment(remove *Segment) bool { return false } -func (seg *Segment) flush(decrement bool) { +func (seg *Segment) emit() { + seg.ParentSegment.GetConfiguration().Emitter.Emit(seg) +} + +func (seg *Segment) handleContextDone() { seg.Lock() - if decrement { - seg.openSegments-- + defer seg.Unlock() + + seg.ContextDone = true + if !seg.InProgress && !seg.Emitted { + seg.flush() } - shouldFlush := (seg.openSegments == 0 && seg.EndTime > 0) || seg.ContextDone - seg.Unlock() +} - if shouldFlush { +func (seg *Segment) flush() { + if (seg.openSegments == 0 && seg.EndTime > 0) || seg.ContextDone { if seg.parent == nil { - seg.Lock() seg.Emitted = true - seg.Unlock() - emit(seg) + seg.emit() + } else if seg.parent != nil && seg.parent.Facade { + seg.Emitted = true + seg.beforeEmitSubsegment(seg.parent) + log.Tracef("emit lambda subsegment named: %v", seg.Name) + seg.emit() } else { - seg.parent.flush(true) + seg.parent.safeFlush() } } } +func (seg *Segment) safeFlush() { + seg.Lock() + defer seg.Unlock() + seg.openSegments-- + seg.flush() +} + +func (seg *Segment) safeInProgress() bool { + seg.Lock() + b := seg.InProgress + seg.Unlock() + return b +} + func (seg *Segment) root() *Segment { if seg.parent == nil { return seg @@ -192,28 +345,44 @@ func (seg *Segment) root() *Segment { } func (seg *Segment) addPlugin(metadata *plugins.PluginMetadata) { - //Only called within a seg locked code block + // Only called within a seg locked code block if metadata == nil { return } - if metadata.IdentityDocument != nil { - seg.GetAWS()["account_id"] = metadata.IdentityDocument.AccountID - seg.GetAWS()["instace_id"] = metadata.IdentityDocument.InstanceID - seg.GetAWS()["availability_zone"] = metadata.IdentityDocument.AvailabilityZone + if metadata.EC2Metadata != nil { + seg.GetAWS()[plugins.EC2ServiceName] = metadata.EC2Metadata } - if metadata.ECSContainerName != "" { - seg.GetAWS()["container"] = metadata.ECSContainerName + if metadata.ECSMetadata != nil { + seg.GetAWS()[plugins.ECSServiceName] = metadata.ECSMetadata } if metadata.BeanstalkMetadata != nil { - seg.GetAWS()["environment"] = metadata.BeanstalkMetadata.Environment - seg.GetAWS()["version_label"] = metadata.BeanstalkMetadata.VersionLabel - seg.GetAWS()["deployment_id"] = metadata.BeanstalkMetadata.DeploymentID + seg.GetAWS()[plugins.EBServiceName] = metadata.BeanstalkMetadata + } + + if metadata.Origin != "" { + seg.Origin = metadata.Origin } } +func (seg *Segment) addSDKAndServiceInformation() { + seg.GetAWS()["xray"] = SDK{Version: SDKVersion, Type: SDKType} + + seg.GetService().Compiler = runtime.Compiler + seg.GetService().CompilerVersion = runtime.Version() +} + +func (sub *Segment) beforeEmitSubsegment(seg *Segment) { + // Only called within a subsegment locked code block + sub.TraceID = seg.root().TraceID + sub.ParentID = seg.ID + sub.Type = "subsegment" + sub.RequestWasTraced = seg.RequestWasTraced + sub.parent = nil +} + // AddAnnotation allows adding an annotation to the segment. func (seg *Segment) AddAnnotation(key string, value interface{}) error { switch value.(type) { @@ -267,9 +436,15 @@ func (seg *Segment) AddError(err error) error { seg.Lock() defer seg.Unlock() + seg.addError(err) + + return nil +} + +func (seg *Segment) addError(err error) error { seg.Fault = true seg.GetCause().WorkingDirectory, _ = os.Getwd() - seg.GetCause().Exceptions = append(seg.GetCause().Exceptions, privateCfg.ExceptionFormattingStrategy().ExceptionFromError(err)) + seg.GetCause().Exceptions = append(seg.GetCause().Exceptions, seg.ParentSegment.GetConfiguration().ExceptionFormattingStrategy.ExceptionFromError(err)) return nil } diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/segment_model.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/segment_model.go index 80e85cb0..026cc494 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/segment_model.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/segment_model.go @@ -14,6 +14,7 @@ import ( "github.com/aws/aws-xray-sdk-go/header" "github.com/aws/aws-xray-sdk-go/strategy/exception" + "github.com/aws/aws-xray-sdk-go/strategy/sampling" ) // Segment provides the resource's name, details about the request, and details about the work done. @@ -66,22 +67,28 @@ type Segment struct { // Children Subsegments []json.RawMessage `json:"subsegments,omitempty"` rawSubsegments []*Segment + + // Configuration + Configuration *Config `json:"-"` + + // Lambda + Facade bool `json:"-"` } -// CauseData provides the shape for unmarshaling data that records exception. +// CauseData provides the shape for unmarshalling data that records exception. type CauseData struct { WorkingDirectory string `json:"working_directory,omitempty"` Paths []string `json:"paths,omitempty"` Exceptions []exception.Exception `json:"exceptions,omitempty"` } -// HTTPData provides the shape for unmarshaling request and response data. +// HTTPData provides the shape for unmarshalling request and response data. type HTTPData struct { Request *RequestData `json:"request,omitempty"` Response *ResponseData `json:"response,omitempty"` } -// RequestData provides the shape for unmarshaling request data. +// RequestData provides the shape for unmarshalling request data. type RequestData struct { Method string `json:"method,omitempty"` URL string `json:"url,omitempty"` // http(s)://host/path @@ -91,18 +98,20 @@ type RequestData struct { Traced bool `json:"traced,omitempty"` } -// ResponseData provides the shape for unmarshaling response data. +// ResponseData provides the shape for unmarshalling response data. type ResponseData struct { Status int `json:"status,omitempty"` ContentLength int `json:"content_length,omitempty"` } -// ServiceData provides the shape for unmarshaling service version. +// ServiceData provides the shape for unmarshalling service version. type ServiceData struct { - Version string `json:"version,omitempty"` + Version string `json:"version,omitempty"` + CompilerVersion string `json:"compiler_version,omitempty"` + Compiler string `json:"compiler,omitempty"` } -// SQLData provides the shape for unmarshaling sql data. +// SQLData provides the shape for unmarshalling sql data. type SQLData struct { ConnectionString string `json:"connection_string,omitempty"` URL string `json:"url,omitempty"` // host:port/database @@ -189,3 +198,20 @@ func (d *HTTPData) GetResponse() *ResponseData { } return d.Response } + +// GetConfiguration returns a value of Config. +func (s *Segment) GetConfiguration() *Config { + if s.Configuration == nil { + s.Configuration = &Config{} + } + return s.Configuration +} + +// AddRuleName adds rule name, if present from sampling decision to xray context. +func (s *Segment) AddRuleName(sd *sampling.Decision) { + if sd.Rule != nil { + sdk := s.GetAWS()["xray"].(SDK) + sdk.RuleName = *sd.Rule + s.GetAWS()["xray"] = sdk + } +} diff --git a/vendor/github.com/aws/aws-xray-sdk-go/xray/sql.go b/vendor/github.com/aws/aws-xray-sdk-go/xray/sql.go index d463672f..fb9afa58 100644 --- a/vendor/github.com/aws/aws-xray-sdk-go/xray/sql.go +++ b/vendor/github.com/aws/aws-xray-sdk-go/xray/sql.go @@ -151,6 +151,11 @@ func (db *DB) SetMaxOpenConns(n int) { db.db.SetMaxOpenConns(n) } func (db *DB) populate(ctx context.Context, query string) { seg := GetSegment(ctx) + if seg == nil { + processNilSegment(ctx) + return + } + seg.Lock() seg.Namespace = "remote" seg.GetSQL().ConnectionString = db.connectionString @@ -191,6 +196,12 @@ func (stmt *Stmt) populate(ctx context.Context, query string) { stmt.db.populate(ctx, query) seg := GetSegment(ctx) + + if seg == nil { + processNilSegment(ctx) + return + } + seg.Lock() seg.GetSQL().Preparation = "statement" seg.Unlock() @@ -272,3 +283,13 @@ func stripPasswords(dsn string) string { flush() return res.String() } + +func processNilSegment(ctx context.Context) { + cfg := GetRecorder(ctx) + failedMessage := "failed to get segment from context since segment is nil" + if cfg != nil && cfg.ContextMissingStrategy != nil { + cfg.ContextMissingStrategy.ContextMissing(failedMessage) + } else { + globalCfg.ContextMissingStrategy().ContextMissing(failedMessage) + } +} \ No newline at end of file