VictoriaMetrics/vendor/github.com/aws/aws-sdk-go-v2/credentials/endpointcreds/provider.go
Zakhar Bessarab 5b7e8d1309
vmbackup: update AWS SDK to v2 (#3174)
* lib/backup/s3remote: update AWS SDK to v2

* Update lib/backup/s3remote/s3.go

Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>

* lib/backup/s3remote: refactor error handling

Co-authored-by: Aliaksandr Valialkin <valyala@victoriametrics.com>
2022-10-01 17:13:04 +03:00

137 lines
3.9 KiB
Go

// 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})
}