aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@ydb.tech>2023-12-12 21:55:07 +0300
committervitalyisaev <vitalyisaev@ydb.tech>2023-12-12 22:25:10 +0300
commit4967f99474a4040ba150eb04995de06342252718 (patch)
treec9c118836513a8fab6e9fcfb25be5d404338bca7 /vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds
parent2ce9cccb9b0bdd4cd7a3491dc5cbf8687cda51de (diff)
downloadydb-4967f99474a4040ba150eb04995de06342252718.tar.gz
YQ Connector: prepare code base for S3 integration
1. Кодовая база Коннектора переписана с помощью Go дженериков так, чтобы добавление нового источника данных (в частности S3 + csv) максимально переиспользовало имеющийся код (чтобы сохранялась логика нарезания на блоки данных, учёт трафика и пр.) 2. API Connector расширено для работы с S3, но ещё пока не протестировано.
Diffstat (limited to 'vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds')
-rw-r--r--vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/gotest/ya.make5
-rw-r--r--vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go148
-rw-r--r--vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client_test.go228
-rw-r--r--vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/gotest/ya.make5
-rw-r--r--vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go120
-rw-r--r--vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/ya.make16
-rw-r--r--vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/ya.make3
-rw-r--r--vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider.go136
-rw-r--r--vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider_test.go156
-rw-r--r--vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/ya.make16
10 files changed, 833 insertions, 0 deletions
diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/gotest/ya.make b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/gotest/ya.make
new file mode 100644
index 0000000000..47591ee12d
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/gotest/ya.make
@@ -0,0 +1,5 @@
+GO_TEST_FOR(vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds)
+
+LICENSE(Apache-2.0)
+
+END()
diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go
new file mode 100644
index 0000000000..60b8298f86
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client.go
@@ -0,0 +1,148 @@
+package client
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+ "time"
+
+ "github.com/aws/aws-sdk-go-v2/aws"
+ "github.com/aws/aws-sdk-go-v2/aws/middleware"
+ "github.com/aws/aws-sdk-go-v2/aws/retry"
+ awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
+ "github.com/aws/smithy-go"
+ smithymiddleware "github.com/aws/smithy-go/middleware"
+ smithyhttp "github.com/aws/smithy-go/transport/http"
+)
+
+// ServiceID is the client identifer
+const ServiceID = "endpoint-credentials"
+
+// HTTPClient is a client for sending HTTP requests
+type HTTPClient interface {
+ Do(*http.Request) (*http.Response, error)
+}
+
+// Options is the endpoint client configurable options
+type Options struct {
+ // The endpoint to retrieve credentials from
+ Endpoint string
+
+ // The HTTP client to invoke API calls with. Defaults to client's default HTTP
+ // implementation if nil.
+ HTTPClient HTTPClient
+
+ // Retryer guides how HTTP requests should be retried in case of recoverable
+ // failures. When nil the API client will use a default retryer.
+ Retryer aws.Retryer
+
+ // Set of options to modify how the credentials operation is invoked.
+ APIOptions []func(*smithymiddleware.Stack) error
+}
+
+// Copy creates a copy of the API options.
+func (o Options) Copy() Options {
+ to := o
+ to.APIOptions = make([]func(*smithymiddleware.Stack) error, len(o.APIOptions))
+ copy(to.APIOptions, o.APIOptions)
+ return to
+}
+
+// Client is an client for retrieving AWS credentials from an endpoint
+type Client struct {
+ options Options
+}
+
+// New constructs a new Client from the given options
+func New(options Options, optFns ...func(*Options)) *Client {
+ options = options.Copy()
+
+ if options.HTTPClient == nil {
+ options.HTTPClient = awshttp.NewBuildableClient()
+ }
+
+ if options.Retryer == nil {
+ options.Retryer = retry.NewStandard()
+ }
+
+ for _, fn := range optFns {
+ fn(&options)
+ }
+
+ client := &Client{
+ options: options,
+ }
+
+ return client
+}
+
+// GetCredentialsInput is the input to send with the endpoint service to receive credentials.
+type GetCredentialsInput struct {
+ AuthorizationToken string
+}
+
+// GetCredentials retrieves credentials from credential endpoint
+func (c *Client) GetCredentials(ctx context.Context, params *GetCredentialsInput, optFns ...func(*Options)) (*GetCredentialsOutput, error) {
+ stack := smithymiddleware.NewStack("GetCredentials", smithyhttp.NewStackRequest)
+ options := c.options.Copy()
+ for _, fn := range optFns {
+ fn(&options)
+ }
+
+ stack.Serialize.Add(&serializeOpGetCredential{}, smithymiddleware.After)
+ stack.Build.Add(&buildEndpoint{Endpoint: options.Endpoint}, smithymiddleware.After)
+ stack.Deserialize.Add(&deserializeOpGetCredential{}, smithymiddleware.After)
+ retry.AddRetryMiddlewares(stack, retry.AddRetryMiddlewaresOptions{Retryer: options.Retryer})
+ middleware.AddSDKAgentKey(middleware.FeatureMetadata, ServiceID)
+ smithyhttp.AddErrorCloseResponseBodyMiddleware(stack)
+ smithyhttp.AddCloseResponseBodyMiddleware(stack)
+
+ for _, fn := range options.APIOptions {
+ if err := fn(stack); err != nil {
+ return nil, err
+ }
+ }
+
+ handler := smithymiddleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack)
+ result, _, err := handler.Handle(ctx, params)
+ if err != nil {
+ return nil, err
+ }
+
+ return result.(*GetCredentialsOutput), err
+}
+
+// GetCredentialsOutput is the response from the credential endpoint
+type GetCredentialsOutput struct {
+ Expiration *time.Time
+ AccessKeyID string
+ SecretAccessKey string
+ Token string
+}
+
+// EndpointError is an error returned from the endpoint service
+type EndpointError struct {
+ Code string `json:"code"`
+ Message string `json:"message"`
+ Fault smithy.ErrorFault `json:"-"`
+}
+
+// Error is the error mesage string
+func (e *EndpointError) Error() string {
+ return fmt.Sprintf("%s: %s", e.Code, e.Message)
+}
+
+// ErrorCode is the error code returned by the endpoint
+func (e *EndpointError) ErrorCode() string {
+ return e.Code
+}
+
+// ErrorMessage is the error message returned by the endpoint
+func (e *EndpointError) ErrorMessage() string {
+ return e.Message
+}
+
+// ErrorFault indicates error fault classification
+func (e *EndpointError) ErrorFault() smithy.ErrorFault {
+ return e.Fault
+}
diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client_test.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client_test.go
new file mode 100644
index 0000000000..ac7e37524b
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/client_test.go
@@ -0,0 +1,228 @@
+package client
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/http/httptest"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/aws/smithy-go"
+ smithytesting "github.com/aws/smithy-go/testing"
+)
+
+func TestClient_GetCredentials(t *testing.T) {
+ cases := map[string]struct {
+ Token string
+ RelativeURI string
+ ResponseCode int
+ ResponseBody []byte
+ ExpectResult *GetCredentialsOutput
+ ExpectErr bool
+ ValidateRequest func(*testing.T, *http.Request)
+ ValidateError func(*testing.T, error) bool
+ }{
+ "success static": {
+ ResponseCode: 200,
+ ResponseBody: []byte(` {
+ "AccessKeyId" : "FooKey",
+ "SecretAccessKey" : "FooSecret"
+ }`),
+ ExpectResult: &GetCredentialsOutput{
+ AccessKeyID: "FooKey",
+ SecretAccessKey: "FooSecret",
+ },
+ },
+ "success with authorization token": {
+ Token: "MySecretAuthToken",
+ ResponseCode: 200,
+ ResponseBody: []byte(` {
+ "AccessKeyId" : "FooKey",
+ "SecretAccessKey" : "FooSecret"
+ }`),
+ ExpectResult: &GetCredentialsOutput{
+ AccessKeyID: "FooKey",
+ SecretAccessKey: "FooSecret",
+ },
+ },
+ "success refreshable": {
+ Token: "MySecretAuthToken",
+ ResponseCode: 200,
+ ResponseBody: []byte(`{
+ "AccessKeyId": "FooKey",
+ "SecretAccessKey": "FooSecret",
+ "Token": "FooToken",
+ "Expiration": "2016-02-25T06:03:31Z"
+}`),
+ ExpectResult: &GetCredentialsOutput{
+ AccessKeyID: "FooKey",
+ SecretAccessKey: "FooSecret",
+ Token: "FooToken",
+ Expiration: func() *time.Time {
+ t := time.Date(2016, 2, 25, 6, 3, 31, 0, time.UTC)
+ return &t
+ }(),
+ },
+ },
+ "success with additional URI components": {
+ RelativeURI: "/path/to/thing?someKey=someValue",
+ ResponseCode: 200,
+ ResponseBody: []byte(` {
+ "AccessKeyId" : "FooKey",
+ "SecretAccessKey" : "FooSecret"
+ }`),
+ ValidateRequest: func(t *testing.T, r *http.Request) {
+ t.Helper()
+ if e, a := "/path/to/thing", r.URL.Path; e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ if e, a := "someValue", r.URL.Query().Get("someKey"); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ },
+ ExpectResult: &GetCredentialsOutput{
+ AccessKeyID: "FooKey",
+ SecretAccessKey: "FooSecret",
+ },
+ },
+ "json error response client fault": {
+ ResponseCode: 403,
+ ResponseBody: []byte(`{
+ "code": "Unauthorized",
+ "message": "not authorized for endpoint"
+}`),
+ ExpectErr: true,
+ ValidateError: func(t *testing.T, err error) (ok bool) {
+ t.Helper()
+ var apiError smithy.APIError
+ if errors.As(err, &apiError) {
+ if e, a := "Unauthorized", apiError.ErrorCode(); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ ok = false
+ }
+ if e, a := "not authorized for endpoint", apiError.ErrorMessage(); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ ok = false
+ }
+ if e, a := smithy.FaultClient, apiError.ErrorFault(); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ ok = false
+ }
+ } else {
+ t.Errorf("expect %T error type, got %T: %v", apiError, err, err)
+ ok = false
+ }
+ return ok
+ },
+ },
+ "json error response server fault": {
+ ResponseCode: 500,
+ ResponseBody: []byte(`{
+ "code": "InternalError",
+ "message": "an error occurred"
+}`),
+ ExpectErr: true,
+ ValidateError: func(t *testing.T, err error) (ok bool) {
+ t.Helper()
+ var apiError smithy.APIError
+ if errors.As(err, &apiError) {
+ if e, a := "InternalError", apiError.ErrorCode(); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ ok = false
+ }
+ if e, a := "an error occurred", apiError.ErrorMessage(); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ ok = false
+ }
+ if e, a := smithy.FaultServer, apiError.ErrorFault(); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ ok = false
+ }
+ } else {
+ t.Errorf("expect %T error type, got %T: %v", apiError, err, err)
+ ok = false
+ }
+ return ok
+ },
+ },
+ "non-json error response": {
+ ResponseCode: 500,
+ ResponseBody: []byte(`<html><body>unexpected message format</body></html>`),
+ ExpectErr: true,
+ ValidateError: func(t *testing.T, err error) (ok bool) {
+ t.Helper()
+ if e, a := "failed to decode error message", err.Error(); !strings.Contains(a, e) {
+ t.Errorf("expect %v, got %v", e, a)
+ ok = false
+ }
+ return ok
+ },
+ },
+ }
+
+ for name, tt := range cases {
+ t.Run(name, func(t *testing.T) {
+ var actualReq *http.Request
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ actualReq = r.Clone(r.Context())
+ var buf bytes.Buffer
+ if _, err := io.Copy(&buf, r.Body); err != nil {
+ t.Errorf("failed to read r body, %v", err)
+ }
+
+ actualReq.Body = ioutil.NopCloser(bytes.NewReader(buf.Bytes()))
+
+ w.WriteHeader(tt.ResponseCode)
+ w.Write(tt.ResponseBody)
+ }))
+ defer server.Close()
+
+ client := New(Options{Endpoint: server.URL + tt.RelativeURI})
+
+ result, err := client.GetCredentials(context.Background(), &GetCredentialsInput{AuthorizationToken: tt.Token})
+ if (err != nil) != tt.ExpectErr {
+ t.Fatalf("got error %v, but ExpectErr=%v", err, tt.ExpectErr)
+ }
+ if err != nil && tt.ValidateError != nil {
+ if !tt.ValidateError(t, err) {
+ return
+ }
+ }
+
+ if e, a := "application/json", actualReq.Header.Get("Accept"); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+
+ if len(tt.Token) > 0 {
+ if e, a := tt.Token, actualReq.Header.Get("Authorization"); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ }
+
+ if tt.ValidateRequest != nil {
+ tt.ValidateRequest(t, actualReq)
+ }
+
+ if err = smithytesting.CompareValues(tt.ExpectResult, result); err != nil {
+ t.Errorf("expect value match:\n%v", err)
+ }
+ })
+ }
+}
+
+func TestClient_GetCredentials_NoEndpoint(t *testing.T) {
+ client := New(Options{})
+
+ _, err := client.GetCredentials(context.Background(), &GetCredentialsInput{})
+ if err == nil {
+ t.Fatalf("expect error got none")
+ }
+ if e, a := "endpoint not provided", err.Error(); !strings.Contains(a, e) {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+}
diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/gotest/ya.make b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/gotest/ya.make
new file mode 100644
index 0000000000..00dc081f11
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/gotest/ya.make
@@ -0,0 +1,5 @@
+GO_TEST_FOR(vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client)
+
+LICENSE(Apache-2.0)
+
+END()
diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go
new file mode 100644
index 0000000000..40747a53c1
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/middleware.go
@@ -0,0 +1,120 @@
+package client
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "net/url"
+
+ "github.com/aws/smithy-go"
+ smithymiddleware "github.com/aws/smithy-go/middleware"
+ smithyhttp "github.com/aws/smithy-go/transport/http"
+)
+
+type buildEndpoint struct {
+ Endpoint string
+}
+
+func (b *buildEndpoint) ID() string {
+ return "BuildEndpoint"
+}
+
+func (b *buildEndpoint) HandleBuild(ctx context.Context, in smithymiddleware.BuildInput, next smithymiddleware.BuildHandler) (
+ out smithymiddleware.BuildOutput, metadata smithymiddleware.Metadata, err error,
+) {
+ request, ok := in.Request.(*smithyhttp.Request)
+ if !ok {
+ return out, metadata, fmt.Errorf("unknown transport, %T", in.Request)
+ }
+
+ if len(b.Endpoint) == 0 {
+ return out, metadata, fmt.Errorf("endpoint not provided")
+ }
+
+ parsed, err := url.Parse(b.Endpoint)
+ if err != nil {
+ return out, metadata, fmt.Errorf("failed to parse endpoint, %w", err)
+ }
+
+ request.URL = parsed
+
+ return next.HandleBuild(ctx, in)
+}
+
+type serializeOpGetCredential struct{}
+
+func (s *serializeOpGetCredential) ID() string {
+ return "OperationSerializer"
+}
+
+func (s *serializeOpGetCredential) HandleSerialize(ctx context.Context, in smithymiddleware.SerializeInput, next smithymiddleware.SerializeHandler) (
+ out smithymiddleware.SerializeOutput, metadata smithymiddleware.Metadata, err error,
+) {
+ request, ok := in.Request.(*smithyhttp.Request)
+ if !ok {
+ return out, metadata, fmt.Errorf("unknown transport type, %T", in.Request)
+ }
+
+ params, ok := in.Parameters.(*GetCredentialsInput)
+ if !ok {
+ return out, metadata, fmt.Errorf("unknown input parameters, %T", in.Parameters)
+ }
+
+ const acceptHeader = "Accept"
+ request.Header[acceptHeader] = append(request.Header[acceptHeader][:0], "application/json")
+
+ if len(params.AuthorizationToken) > 0 {
+ const authHeader = "Authorization"
+ request.Header[authHeader] = append(request.Header[authHeader][:0], params.AuthorizationToken)
+ }
+
+ return next.HandleSerialize(ctx, in)
+}
+
+type deserializeOpGetCredential struct{}
+
+func (d *deserializeOpGetCredential) ID() string {
+ return "OperationDeserializer"
+}
+
+func (d *deserializeOpGetCredential) HandleDeserialize(ctx context.Context, in smithymiddleware.DeserializeInput, next smithymiddleware.DeserializeHandler) (
+ out smithymiddleware.DeserializeOutput, metadata smithymiddleware.Metadata, err error,
+) {
+ out, metadata, err = next.HandleDeserialize(ctx, in)
+ if err != nil {
+ return out, metadata, err
+ }
+
+ response, ok := out.RawResponse.(*smithyhttp.Response)
+ if !ok {
+ return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)}
+ }
+
+ if response.StatusCode < 200 || response.StatusCode >= 300 {
+ return out, metadata, deserializeError(response)
+ }
+
+ var shape *GetCredentialsOutput
+ if err = json.NewDecoder(response.Body).Decode(&shape); err != nil {
+ return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("failed to deserialize json response, %w", err)}
+ }
+
+ out.Result = shape
+ return out, metadata, err
+}
+
+func deserializeError(response *smithyhttp.Response) error {
+ var errShape *EndpointError
+ err := json.NewDecoder(response.Body).Decode(&errShape)
+ if err != nil {
+ return &smithy.DeserializationError{Err: fmt.Errorf("failed to decode error message, %w", err)}
+ }
+
+ if response.StatusCode >= 500 {
+ errShape.Fault = smithy.FaultServer
+ } else {
+ errShape.Fault = smithy.FaultClient
+ }
+
+ return errShape
+}
diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/ya.make b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/ya.make
new file mode 100644
index 0000000000..19cb81ab0b
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client/ya.make
@@ -0,0 +1,16 @@
+GO_LIBRARY()
+
+LICENSE(Apache-2.0)
+
+SRCS(
+ client.go
+ middleware.go
+)
+
+GO_TEST_SRCS(client_test.go)
+
+END()
+
+RECURSE(
+ gotest
+)
diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/ya.make b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/ya.make
new file mode 100644
index 0000000000..54d997a3b4
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/ya.make
@@ -0,0 +1,3 @@
+RECURSE(
+ client
+)
diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider.go
new file mode 100644
index 0000000000..adc7fc6b00
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider.go
@@ -0,0 +1,136 @@
+// 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 (
+ "context"
+ "fmt"
+ "net/http"
+
+ "github.com/aws/aws-sdk-go-v2/aws"
+ "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/internal/client"
+ "github.com/aws/smithy-go/middleware"
+)
+
+// ProviderName is the name of the credentials provider.
+const ProviderName = `CredentialsEndpointProvider`
+
+type getCredentialsAPIClient interface {
+ GetCredentials(context.Context, *client.GetCredentialsInput, ...func(*client.Options)) (*client.GetCredentialsOutput, error)
+}
+
+// Provider satisfies the aws.CredentialsProvider interface, and is a client to
+// retrieve credentials from an arbitrary endpoint.
+type Provider struct {
+ // The 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
+ // EndpointResolver.
+ client getCredentialsAPIClient
+
+ options Options
+}
+
+// HTTPClient is a client for sending HTTP requests
+type HTTPClient interface {
+ Do(*http.Request) (*http.Response, error)
+}
+
+// Options is structure of configurable options for Provider
+type Options struct {
+ // Endpoint to retrieve credentials from. Required
+ Endpoint string
+
+ // HTTPClient to handle sending HTTP requests to the target endpoint.
+ HTTPClient HTTPClient
+
+ // Set of options to modify how the credentials operation is invoked.
+ APIOptions []func(*middleware.Stack) error
+
+ // The Retryer to be used for determining whether a failed requested should be retried
+ Retryer aws.Retryer
+
+ // Optional authorization token value if set will be used as the value of
+ // the Authorization header of the endpoint credential request.
+ AuthorizationToken string
+}
+
+// New returns a credentials Provider for retrieving AWS credentials
+// from arbitrary endpoint.
+func New(endpoint string, optFns ...func(*Options)) *Provider {
+ o := Options{
+ Endpoint: endpoint,
+ }
+
+ for _, fn := range optFns {
+ fn(&o)
+ }
+
+ p := &Provider{
+ client: client.New(client.Options{
+ HTTPClient: o.HTTPClient,
+ Endpoint: o.Endpoint,
+ APIOptions: o.APIOptions,
+ Retryer: o.Retryer,
+ }),
+ options: o,
+ }
+
+ return p
+}
+
+// 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(ctx context.Context) (aws.Credentials, error) {
+ resp, err := p.getCredentials(ctx)
+ if err != nil {
+ return aws.Credentials{}, fmt.Errorf("failed to load credentials, %w", err)
+ }
+
+ creds := aws.Credentials{
+ AccessKeyID: resp.AccessKeyID,
+ SecretAccessKey: resp.SecretAccessKey,
+ SessionToken: resp.Token,
+ Source: ProviderName,
+ }
+
+ if resp.Expiration != nil {
+ creds.CanExpire = true
+ creds.Expires = *resp.Expiration
+ }
+
+ return creds, nil
+}
+
+func (p *Provider) getCredentials(ctx context.Context) (*client.GetCredentialsOutput, error) {
+ return p.client.GetCredentials(ctx, &client.GetCredentialsInput{AuthorizationToken: p.options.AuthorizationToken})
+}
diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider_test.go b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider_test.go
new file mode 100644
index 0000000000..15a539518a
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider_test.go
@@ -0,0 +1,156 @@
+package endpointcreds_test
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/aws/aws-sdk-go-v2/credentials/endpointcreds"
+ "github.com/aws/aws-sdk-go-v2/internal/sdk"
+ "github.com/aws/smithy-go"
+)
+
+type mockClient func(*http.Request) (*http.Response, error)
+
+func (m mockClient) Do(r *http.Request) (*http.Response, error) {
+ return m(r)
+}
+
+func TestRetrieveRefreshableCredentials(t *testing.T) {
+ orig := sdk.NowTime
+ defer func() { sdk.NowTime = orig }()
+
+ p := endpointcreds.New("http://127.0.0.1", func(o *endpointcreds.Options) {
+ o.HTTPClient = mockClient(func(r *http.Request) (*http.Response, error) {
+ expTime := time.Now().UTC().Add(1 * time.Hour).Format("2006-01-02T15:04:05Z")
+
+ return &http.Response{
+ StatusCode: 200,
+ Body: ioutil.NopCloser(bytes.NewReader([]byte(fmt.Sprintf(`{
+ "AccessKeyID": "AKID",
+ "SecretAccessKey": "SECRET",
+ "Token": "TOKEN",
+ "Expiration": "%s"
+}`, expTime)))),
+ }, nil
+ })
+ })
+ creds, err := p.Retrieve(context.Background())
+
+ if err != nil {
+ t.Fatalf("expect no error, got %v", err)
+ }
+
+ if e, a := "AKID", creds.AccessKeyID; e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ if e, a := "SECRET", creds.SecretAccessKey; e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ if e, a := "TOKEN", creds.SessionToken; e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ if creds.Expired() {
+ t.Errorf("expect not expired")
+ }
+
+ sdk.NowTime = func() time.Time {
+ return time.Now().Add(2 * time.Hour)
+ }
+ if !creds.Expired() {
+ t.Errorf("expect to be expired")
+ }
+}
+
+func TestRetrieveStaticCredentials(t *testing.T) {
+ orig := sdk.NowTime
+ defer func() { sdk.NowTime = orig }()
+
+ p := endpointcreds.New("http://127.0.0.1", func(o *endpointcreds.Options) {
+ o.HTTPClient = mockClient(func(r *http.Request) (*http.Response, error) {
+ return &http.Response{
+ StatusCode: 200,
+ Body: ioutil.NopCloser(bytes.NewReader([]byte(`{
+ "AccessKeyID": "AKID",
+ "SecretAccessKey": "SECRET"
+}`))),
+ }, nil
+ })
+ })
+ creds, err := p.Retrieve(context.Background())
+
+ if err != nil {
+ t.Fatalf("expect no error, got %v", err)
+ }
+
+ if e, a := "AKID", creds.AccessKeyID; e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ if e, a := "SECRET", creds.SecretAccessKey; e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ if v := creds.SessionToken; len(v) != 0 {
+ t.Errorf("expect empty, got %v", v)
+ }
+
+ sdk.NowTime = func() time.Time {
+ return time.Date(3000, 12, 16, 1, 30, 37, 0, time.UTC)
+ }
+
+ if creds.Expired() {
+ t.Errorf("expect not to be expired")
+ }
+}
+
+func TestFailedRetrieveCredentials(t *testing.T) {
+ p := endpointcreds.New("http://127.0.0.1", func(o *endpointcreds.Options) {
+ o.HTTPClient = mockClient(func(r *http.Request) (*http.Response, error) {
+ return &http.Response{
+ StatusCode: 400,
+ Body: ioutil.NopCloser(bytes.NewReader([]byte(`{
+ "code": "Error",
+ "message": "Message"
+}`))),
+ }, nil
+ })
+ })
+ creds, err := p.Retrieve(context.Background())
+
+ if err == nil {
+ t.Fatalf("expect error, got none")
+ }
+
+ if e, a := "failed to load credentials", err.Error(); !strings.Contains(a, e) {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+
+ var apiError smithy.APIError
+ if !errors.As(err, &apiError) {
+ t.Fatalf("expect %T error, got %v", apiError, err)
+ }
+ if e, a := "Error", apiError.ErrorCode(); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+ if e, a := "Message", apiError.ErrorMessage(); e != a {
+ t.Errorf("expect %v, got %v", e, a)
+ }
+
+ if v := creds.AccessKeyID; len(v) != 0 {
+ t.Errorf("expect empty, got %v", v)
+ }
+ if v := creds.SecretAccessKey; len(v) != 0 {
+ t.Errorf("expect empty, got %v", v)
+ }
+ if v := creds.SessionToken; len(v) != 0 {
+ t.Errorf("expect empty, got %v", v)
+ }
+ if creds.Expired() {
+ t.Errorf("expect empty creds not to be expired")
+ }
+}
diff --git a/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/ya.make b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/ya.make
new file mode 100644
index 0000000000..f56107148a
--- /dev/null
+++ b/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/ya.make
@@ -0,0 +1,16 @@
+GO_LIBRARY()
+
+LICENSE(Apache-2.0)
+
+SRCS(
+ provider.go
+)
+
+GO_XTEST_SRCS(provider_test.go)
+
+END()
+
+RECURSE(
+ gotest
+ internal
+)