client.go 4.1 KB

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