code.dwrz.net

Go monorepo.
Log | Files | Refs

client.go (4191B)


      1 package client
      2 
      3 import (
      4 	"context"
      5 	"fmt"
      6 	"net/http"
      7 	"time"
      8 
      9 	"github.com/aws/aws-sdk-go-v2/aws"
     10 	"github.com/aws/aws-sdk-go-v2/aws/middleware"
     11 	"github.com/aws/aws-sdk-go-v2/aws/retry"
     12 	awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
     13 	"github.com/aws/smithy-go"
     14 	smithymiddleware "github.com/aws/smithy-go/middleware"
     15 	smithyhttp "github.com/aws/smithy-go/transport/http"
     16 )
     17 
     18 // ServiceID is the client identifer
     19 const ServiceID = "endpoint-credentials"
     20 
     21 // HTTPClient is a client for sending HTTP requests
     22 type HTTPClient interface {
     23 	Do(*http.Request) (*http.Response, error)
     24 }
     25 
     26 // Options is the endpoint client configurable options
     27 type Options struct {
     28 	// The endpoint to retrieve credentials from
     29 	Endpoint string
     30 
     31 	// The HTTP client to invoke API calls with. Defaults to client's default HTTP
     32 	// implementation if nil.
     33 	HTTPClient HTTPClient
     34 
     35 	// Retryer guides how HTTP requests should be retried in case of recoverable
     36 	// failures. When nil the API client will use a default retryer.
     37 	Retryer aws.Retryer
     38 
     39 	// Set of options to modify how the credentials operation is invoked.
     40 	APIOptions []func(*smithymiddleware.Stack) error
     41 }
     42 
     43 // Copy creates a copy of the API options.
     44 func (o Options) Copy() Options {
     45 	to := o
     46 	to.APIOptions = make([]func(*smithymiddleware.Stack) error, len(o.APIOptions))
     47 	copy(to.APIOptions, o.APIOptions)
     48 	return to
     49 }
     50 
     51 // Client is an client for retrieving AWS credentials from an endpoint
     52 type Client struct {
     53 	options Options
     54 }
     55 
     56 // New constructs a new Client from the given options
     57 func New(options Options, optFns ...func(*Options)) *Client {
     58 	options = options.Copy()
     59 
     60 	if options.HTTPClient == nil {
     61 		options.HTTPClient = awshttp.NewBuildableClient()
     62 	}
     63 
     64 	if options.Retryer == nil {
     65 		options.Retryer = retry.NewStandard()
     66 	}
     67 
     68 	for _, fn := range optFns {
     69 		fn(&options)
     70 	}
     71 
     72 	client := &Client{
     73 		options: options,
     74 	}
     75 
     76 	return client
     77 }
     78 
     79 // GetCredentialsInput is the input to send with the endpoint service to receive credentials.
     80 type GetCredentialsInput struct {
     81 	AuthorizationToken string
     82 }
     83 
     84 // GetCredentials retrieves credentials from credential endpoint
     85 func (c *Client) GetCredentials(ctx context.Context, params *GetCredentialsInput, optFns ...func(*Options)) (*GetCredentialsOutput, error) {
     86 	stack := smithymiddleware.NewStack("GetCredentials", smithyhttp.NewStackRequest)
     87 	options := c.options.Copy()
     88 	for _, fn := range optFns {
     89 		fn(&options)
     90 	}
     91 
     92 	stack.Serialize.Add(&serializeOpGetCredential{}, smithymiddleware.After)
     93 	stack.Build.Add(&buildEndpoint{Endpoint: options.Endpoint}, smithymiddleware.After)
     94 	stack.Deserialize.Add(&deserializeOpGetCredential{}, smithymiddleware.After)
     95 	retry.AddRetryMiddlewares(stack, retry.AddRetryMiddlewaresOptions{Retryer: options.Retryer})
     96 	middleware.AddSDKAgentKey(middleware.FeatureMetadata, ServiceID)
     97 	smithyhttp.AddErrorCloseResponseBodyMiddleware(stack)
     98 	smithyhttp.AddCloseResponseBodyMiddleware(stack)
     99 
    100 	for _, fn := range options.APIOptions {
    101 		if err := fn(stack); err != nil {
    102 			return nil, err
    103 		}
    104 	}
    105 
    106 	handler := smithymiddleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack)
    107 	result, _, err := handler.Handle(ctx, params)
    108 	if err != nil {
    109 		return nil, err
    110 	}
    111 
    112 	return result.(*GetCredentialsOutput), err
    113 }
    114 
    115 // GetCredentialsOutput is the response from the credential endpoint
    116 type GetCredentialsOutput struct {
    117 	Expiration      *time.Time
    118 	AccessKeyID     string
    119 	SecretAccessKey string
    120 	Token           string
    121 }
    122 
    123 // EndpointError is an error returned from the endpoint service
    124 type EndpointError struct {
    125 	Code    string            `json:"code"`
    126 	Message string            `json:"message"`
    127 	Fault   smithy.ErrorFault `json:"-"`
    128 }
    129 
    130 // Error is the error mesage string
    131 func (e *EndpointError) Error() string {
    132 	return fmt.Sprintf("%s: %s", e.Code, e.Message)
    133 }
    134 
    135 // ErrorCode is the error code returned by the endpoint
    136 func (e *EndpointError) ErrorCode() string {
    137 	return e.Code
    138 }
    139 
    140 // ErrorMessage is the error message returned by the endpoint
    141 func (e *EndpointError) ErrorMessage() string {
    142 	return e.Message
    143 }
    144 
    145 // ErrorFault indicates error fault classification
    146 func (e *EndpointError) ErrorFault() smithy.ErrorFault {
    147 	return e.Fault
    148 }