1// Code generated by smithy-go-codegen DO NOT EDIT. 2 3package cloudformation 4 5import ( 6 "context" 7 cryptorand "crypto/rand" 8 "github.com/aws/aws-sdk-go-v2/aws" 9 awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" 10 "github.com/aws/aws-sdk-go-v2/aws/retry" 11 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" 12 awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" 13 smithy "github.com/aws/smithy-go" 14 "github.com/aws/smithy-go/logging" 15 "github.com/aws/smithy-go/middleware" 16 smithyrand "github.com/aws/smithy-go/rand" 17 smithyhttp "github.com/aws/smithy-go/transport/http" 18 "net/http" 19 "time" 20) 21 22const ServiceID = "CloudFormation" 23const ServiceAPIVersion = "2010-05-15" 24 25// Client provides the API client to make operations call for AWS CloudFormation. 26type Client struct { 27 options Options 28} 29 30// New returns an initialized Client based on the functional options. Provide 31// additional functional options to further configure the behavior of the client, 32// such as changing the client's endpoint or adding custom middleware behavior. 33func New(options Options, optFns ...func(*Options)) *Client { 34 options = options.Copy() 35 36 resolveDefaultLogger(&options) 37 38 resolveRetryer(&options) 39 40 resolveHTTPClient(&options) 41 42 resolveHTTPSignerV4(&options) 43 44 resolveDefaultEndpointConfiguration(&options) 45 46 resolveIdempotencyTokenProvider(&options) 47 48 for _, fn := range optFns { 49 fn(&options) 50 } 51 52 client := &Client{ 53 options: options, 54 } 55 56 return client 57} 58 59type Options struct { 60 // Set of options to modify how an operation is invoked. These apply to all 61 // operations invoked for this client. Use functional options on operation call to 62 // modify this list for per operation behavior. 63 APIOptions []func(*middleware.Stack) error 64 65 // Configures the events that will be sent to the configured logger. 66 ClientLogMode aws.ClientLogMode 67 68 // The credentials object to use when signing requests. 69 Credentials aws.CredentialsProvider 70 71 // The endpoint options to be used when attempting to resolve an endpoint. 72 EndpointOptions EndpointResolverOptions 73 74 // The service endpoint resolver. 75 EndpointResolver EndpointResolver 76 77 // Signature Version 4 (SigV4) Signer 78 HTTPSignerV4 HTTPSignerV4 79 80 // Provides idempotency tokens values that will be automatically populated into 81 // idempotent API operations. 82 IdempotencyTokenProvider IdempotencyTokenProvider 83 84 // The logger writer interface to write logging messages to. 85 Logger logging.Logger 86 87 // The region to send requests to. (Required) 88 Region string 89 90 // Retryer guides how HTTP requests should be retried in case of recoverable 91 // failures. When nil the API client will use a default retryer. 92 Retryer aws.Retryer 93 94 // The HTTP client to invoke API calls with. Defaults to client's default HTTP 95 // implementation if nil. 96 HTTPClient HTTPClient 97} 98 99// WithAPIOptions returns a functional option for setting the Client's APIOptions 100// option. 101func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { 102 return func(o *Options) { 103 o.APIOptions = append(o.APIOptions, optFns...) 104 } 105} 106 107// WithEndpointResolver returns a functional option for setting the Client's 108// EndpointResolver option. 109func WithEndpointResolver(v EndpointResolver) func(*Options) { 110 return func(o *Options) { 111 o.EndpointResolver = v 112 } 113} 114 115type HTTPClient interface { 116 Do(*http.Request) (*http.Response, error) 117} 118 119// Copy creates a clone where the APIOptions list is deep copied. 120func (o Options) Copy() Options { 121 to := o 122 to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) 123 copy(to.APIOptions, o.APIOptions) 124 return to 125} 126func (c *Client) invokeOperation(ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error) (result interface{}, metadata middleware.Metadata, err error) { 127 ctx = middleware.ClearStackValues(ctx) 128 stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) 129 options := c.options.Copy() 130 for _, fn := range optFns { 131 fn(&options) 132 } 133 134 for _, fn := range stackFns { 135 if err := fn(stack, options); err != nil { 136 return nil, metadata, err 137 } 138 } 139 140 for _, fn := range options.APIOptions { 141 if err := fn(stack); err != nil { 142 return nil, metadata, err 143 } 144 } 145 146 handler := middleware.DecorateHandler(smithyhttp.NewClientHandler(options.HTTPClient), stack) 147 result, metadata, err = handler.Handle(ctx, params) 148 if err != nil { 149 err = &smithy.OperationError{ 150 ServiceID: ServiceID, 151 OperationName: opID, 152 Err: err, 153 } 154 } 155 return result, metadata, err 156} 157 158func resolveDefaultLogger(o *Options) { 159 if o.Logger != nil { 160 return 161 } 162 o.Logger = logging.Nop{} 163} 164 165func addSetLoggerMiddleware(stack *middleware.Stack, o Options) error { 166 return middleware.AddSetLoggerMiddleware(stack, o.Logger) 167} 168 169// NewFromConfig returns a new client from the provided config. 170func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { 171 opts := Options{ 172 Region: cfg.Region, 173 HTTPClient: cfg.HTTPClient, 174 Credentials: cfg.Credentials, 175 APIOptions: cfg.APIOptions, 176 Logger: cfg.Logger, 177 ClientLogMode: cfg.ClientLogMode, 178 } 179 resolveAWSRetryerProvider(cfg, &opts) 180 resolveAWSEndpointResolver(cfg, &opts) 181 return New(opts, optFns...) 182} 183 184func resolveHTTPClient(o *Options) { 185 if o.HTTPClient != nil { 186 return 187 } 188 o.HTTPClient = awshttp.NewBuildableClient() 189} 190 191func resolveRetryer(o *Options) { 192 if o.Retryer != nil { 193 return 194 } 195 o.Retryer = retry.NewStandard() 196} 197 198func resolveAWSRetryerProvider(cfg aws.Config, o *Options) { 199 if cfg.Retryer == nil { 200 return 201 } 202 o.Retryer = cfg.Retryer() 203} 204 205func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { 206 if cfg.EndpointResolver == nil { 207 return 208 } 209 o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, NewDefaultEndpointResolver()) 210} 211 212func addClientUserAgent(stack *middleware.Stack) error { 213 return awsmiddleware.AddRequestUserAgentMiddleware(stack) 214} 215 216func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error { 217 mw := v4.NewSignHTTPRequestMiddleware(v4.SignHTTPRequestMiddlewareOptions{ 218 CredentialsProvider: o.Credentials, 219 Signer: o.HTTPSignerV4, 220 LogSigning: o.ClientLogMode.IsSigning(), 221 }) 222 return stack.Finalize.Add(mw, middleware.After) 223} 224 225type HTTPSignerV4 interface { 226 SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error 227} 228 229func resolveHTTPSignerV4(o *Options) { 230 if o.HTTPSignerV4 != nil { 231 return 232 } 233 o.HTTPSignerV4 = newDefaultV4Signer(*o) 234} 235 236func newDefaultV4Signer(o Options) *v4.Signer { 237 return v4.NewSigner(func(so *v4.SignerOptions) { 238 so.Logger = o.Logger 239 so.LogSigning = o.ClientLogMode.IsSigning() 240 }) 241} 242 243func resolveIdempotencyTokenProvider(o *Options) { 244 if o.IdempotencyTokenProvider != nil { 245 return 246 } 247 o.IdempotencyTokenProvider = smithyrand.NewUUIDIdempotencyToken(cryptorand.Reader) 248} 249 250func addRetryMiddlewares(stack *middleware.Stack, o Options) error { 251 mo := retry.AddRetryMiddlewaresOptions{ 252 Retryer: o.Retryer, 253 LogRetryAttempts: o.ClientLogMode.IsRetries(), 254 } 255 return retry.AddRetryMiddlewares(stack, mo) 256} 257 258// IdempotencyTokenProvider interface for providing idempotency token 259type IdempotencyTokenProvider interface { 260 GetIdempotencyToken() (string, error) 261} 262 263func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error { 264 return awsmiddleware.AddRequestIDRetrieverMiddleware(stack) 265} 266 267func addResponseErrorMiddleware(stack *middleware.Stack) error { 268 return awshttp.AddResponseErrorMiddleware(stack) 269} 270 271func addRequestResponseLogging(stack *middleware.Stack, o Options) error { 272 return stack.Deserialize.Add(&smithyhttp.RequestResponseLogger{ 273 LogRequest: o.ClientLogMode.IsRequest(), 274 LogRequestWithBody: o.ClientLogMode.IsRequestWithBody(), 275 LogResponse: o.ClientLogMode.IsResponse(), 276 LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), 277 }, middleware.After) 278} 279