1// Code generated by smithy-go-codegen DO NOT EDIT. 2 3package redshift 4 5import ( 6 "context" 7 "fmt" 8 awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" 9 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" 10 "github.com/aws/aws-sdk-go-v2/service/redshift/types" 11 "github.com/aws/smithy-go/middleware" 12 smithytime "github.com/aws/smithy-go/time" 13 smithyhttp "github.com/aws/smithy-go/transport/http" 14 smithywaiter "github.com/aws/smithy-go/waiter" 15 "github.com/jmespath/go-jmespath" 16 "time" 17) 18 19// Returns one or more snapshot objects, which contain metadata about your cluster 20// snapshots. By default, this operation returns information about all snapshots of 21// all clusters that are owned by you AWS customer account. No information is 22// returned for snapshots owned by inactive AWS customer accounts. If you specify 23// both tag keys and tag values in the same request, Amazon Redshift returns all 24// snapshots that match any combination of the specified keys and values. For 25// example, if you have owner and environment for tag keys, and admin and test for 26// tag values, all snapshots that have any combination of those values are 27// returned. Only snapshots that you own are returned in the response; shared 28// snapshots are not returned with the tag key and tag value request parameters. If 29// both tag keys and values are omitted from the request, snapshots are returned 30// regardless of whether they have tag keys or values associated with them. 31func (c *Client) DescribeClusterSnapshots(ctx context.Context, params *DescribeClusterSnapshotsInput, optFns ...func(*Options)) (*DescribeClusterSnapshotsOutput, error) { 32 if params == nil { 33 params = &DescribeClusterSnapshotsInput{} 34 } 35 36 result, metadata, err := c.invokeOperation(ctx, "DescribeClusterSnapshots", params, optFns, addOperationDescribeClusterSnapshotsMiddlewares) 37 if err != nil { 38 return nil, err 39 } 40 41 out := result.(*DescribeClusterSnapshotsOutput) 42 out.ResultMetadata = metadata 43 return out, nil 44} 45 46// 47type DescribeClusterSnapshotsInput struct { 48 49 // A value that indicates whether to return snapshots only for an existing cluster. 50 // You can perform table-level restore only by using a snapshot of an existing 51 // cluster, that is, a cluster that has not been deleted. Values for this parameter 52 // work as follows: 53 // 54 // * If ClusterExists is set to true, ClusterIdentifier is 55 // required. 56 // 57 // * If ClusterExists is set to false and ClusterIdentifier isn't 58 // specified, all snapshots associated with deleted clusters (orphaned snapshots) 59 // are returned. 60 // 61 // * If ClusterExists is set to false and ClusterIdentifier is 62 // specified for a deleted cluster, snapshots associated with that cluster are 63 // returned. 64 // 65 // * If ClusterExists is set to false and ClusterIdentifier is specified 66 // for an existing cluster, no snapshots are returned. 67 ClusterExists *bool 68 69 // The identifier of the cluster which generated the requested snapshots. 70 ClusterIdentifier *string 71 72 // A time value that requests only snapshots created at or before the specified 73 // time. The time value is specified in ISO 8601 format. For more information about 74 // ISO 8601, go to the ISO8601 Wikipedia page. 75 // (http://en.wikipedia.org/wiki/ISO_8601) Example: 2012-07-16T18:00:00Z 76 EndTime *time.Time 77 78 // An optional parameter that specifies the starting point to return a set of 79 // response records. When the results of a DescribeClusterSnapshots request exceed 80 // the value specified in MaxRecords, AWS returns a value in the Marker field of 81 // the response. You can retrieve the next set of response records by providing the 82 // returned marker value in the Marker parameter and retrying the request. 83 Marker *string 84 85 // The maximum number of response records to return in each call. If the number of 86 // remaining response records exceeds the specified MaxRecords value, a value is 87 // returned in a marker field of the response. You can retrieve the next set of 88 // records by retrying the command with the returned marker value. Default: 100 89 // Constraints: minimum 20, maximum 100. 90 MaxRecords *int32 91 92 // The AWS customer account used to create or copy the snapshot. Use this field to 93 // filter the results to snapshots owned by a particular account. To describe 94 // snapshots you own, either specify your AWS customer account, or do not specify 95 // the parameter. 96 OwnerAccount *string 97 98 // The snapshot identifier of the snapshot about which to return information. 99 SnapshotIdentifier *string 100 101 // The type of snapshots for which you are requesting information. By default, 102 // snapshots of all types are returned. Valid Values: automated | manual 103 SnapshotType *string 104 105 // 106 SortingEntities []types.SnapshotSortingEntity 107 108 // A value that requests only snapshots created at or after the specified time. The 109 // time value is specified in ISO 8601 format. For more information about ISO 8601, 110 // go to the ISO8601 Wikipedia page. (http://en.wikipedia.org/wiki/ISO_8601) 111 // Example: 2012-07-16T18:00:00Z 112 StartTime *time.Time 113 114 // A tag key or keys for which you want to return all matching cluster snapshots 115 // that are associated with the specified key or keys. For example, suppose that 116 // you have snapshots that are tagged with keys called owner and environment. If 117 // you specify both of these tag keys in the request, Amazon Redshift returns a 118 // response with the snapshots that have either or both of these tag keys 119 // associated with them. 120 TagKeys []string 121 122 // A tag value or values for which you want to return all matching cluster 123 // snapshots that are associated with the specified tag value or values. For 124 // example, suppose that you have snapshots that are tagged with values called 125 // admin and test. If you specify both of these tag values in the request, Amazon 126 // Redshift returns a response with the snapshots that have either or both of these 127 // tag values associated with them. 128 TagValues []string 129} 130 131// Contains the output from the DescribeClusterSnapshots action. 132type DescribeClusterSnapshotsOutput struct { 133 134 // A value that indicates the starting point for the next set of response records 135 // in a subsequent request. If a value is returned in a response, you can retrieve 136 // the next set of records by providing this returned marker value in the Marker 137 // parameter and retrying the command. If the Marker field is empty, all response 138 // records have been retrieved for the request. 139 Marker *string 140 141 // A list of Snapshot instances. 142 Snapshots []types.Snapshot 143 144 // Metadata pertaining to the operation's result. 145 ResultMetadata middleware.Metadata 146} 147 148func addOperationDescribeClusterSnapshotsMiddlewares(stack *middleware.Stack, options Options) (err error) { 149 err = stack.Serialize.Add(&awsAwsquery_serializeOpDescribeClusterSnapshots{}, middleware.After) 150 if err != nil { 151 return err 152 } 153 err = stack.Deserialize.Add(&awsAwsquery_deserializeOpDescribeClusterSnapshots{}, middleware.After) 154 if err != nil { 155 return err 156 } 157 if err = addSetLoggerMiddleware(stack, options); err != nil { 158 return err 159 } 160 if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { 161 return err 162 } 163 if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { 164 return err 165 } 166 if err = addResolveEndpointMiddleware(stack, options); err != nil { 167 return err 168 } 169 if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { 170 return err 171 } 172 if err = addRetryMiddlewares(stack, options); err != nil { 173 return err 174 } 175 if err = addHTTPSignerV4Middleware(stack, options); err != nil { 176 return err 177 } 178 if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { 179 return err 180 } 181 if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { 182 return err 183 } 184 if err = addClientUserAgent(stack); err != nil { 185 return err 186 } 187 if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { 188 return err 189 } 190 if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { 191 return err 192 } 193 if err = addOpDescribeClusterSnapshotsValidationMiddleware(stack); err != nil { 194 return err 195 } 196 if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeClusterSnapshots(options.Region), middleware.Before); err != nil { 197 return err 198 } 199 if err = addRequestIDRetrieverMiddleware(stack); err != nil { 200 return err 201 } 202 if err = addResponseErrorMiddleware(stack); err != nil { 203 return err 204 } 205 if err = addRequestResponseLogging(stack, options); err != nil { 206 return err 207 } 208 return nil 209} 210 211// DescribeClusterSnapshotsAPIClient is a client that implements the 212// DescribeClusterSnapshots operation. 213type DescribeClusterSnapshotsAPIClient interface { 214 DescribeClusterSnapshots(context.Context, *DescribeClusterSnapshotsInput, ...func(*Options)) (*DescribeClusterSnapshotsOutput, error) 215} 216 217var _ DescribeClusterSnapshotsAPIClient = (*Client)(nil) 218 219// DescribeClusterSnapshotsPaginatorOptions is the paginator options for 220// DescribeClusterSnapshots 221type DescribeClusterSnapshotsPaginatorOptions struct { 222 // The maximum number of response records to return in each call. If the number of 223 // remaining response records exceeds the specified MaxRecords value, a value is 224 // returned in a marker field of the response. You can retrieve the next set of 225 // records by retrying the command with the returned marker value. Default: 100 226 // Constraints: minimum 20, maximum 100. 227 Limit int32 228 229 // Set to true if pagination should stop if the service returns a pagination token 230 // that matches the most recent token provided to the service. 231 StopOnDuplicateToken bool 232} 233 234// DescribeClusterSnapshotsPaginator is a paginator for DescribeClusterSnapshots 235type DescribeClusterSnapshotsPaginator struct { 236 options DescribeClusterSnapshotsPaginatorOptions 237 client DescribeClusterSnapshotsAPIClient 238 params *DescribeClusterSnapshotsInput 239 nextToken *string 240 firstPage bool 241} 242 243// NewDescribeClusterSnapshotsPaginator returns a new 244// DescribeClusterSnapshotsPaginator 245func NewDescribeClusterSnapshotsPaginator(client DescribeClusterSnapshotsAPIClient, params *DescribeClusterSnapshotsInput, optFns ...func(*DescribeClusterSnapshotsPaginatorOptions)) *DescribeClusterSnapshotsPaginator { 246 if params == nil { 247 params = &DescribeClusterSnapshotsInput{} 248 } 249 250 options := DescribeClusterSnapshotsPaginatorOptions{} 251 if params.MaxRecords != nil { 252 options.Limit = *params.MaxRecords 253 } 254 255 for _, fn := range optFns { 256 fn(&options) 257 } 258 259 return &DescribeClusterSnapshotsPaginator{ 260 options: options, 261 client: client, 262 params: params, 263 firstPage: true, 264 } 265} 266 267// HasMorePages returns a boolean indicating whether more pages are available 268func (p *DescribeClusterSnapshotsPaginator) HasMorePages() bool { 269 return p.firstPage || p.nextToken != nil 270} 271 272// NextPage retrieves the next DescribeClusterSnapshots page. 273func (p *DescribeClusterSnapshotsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeClusterSnapshotsOutput, error) { 274 if !p.HasMorePages() { 275 return nil, fmt.Errorf("no more pages available") 276 } 277 278 params := *p.params 279 params.Marker = p.nextToken 280 281 var limit *int32 282 if p.options.Limit > 0 { 283 limit = &p.options.Limit 284 } 285 params.MaxRecords = limit 286 287 result, err := p.client.DescribeClusterSnapshots(ctx, ¶ms, optFns...) 288 if err != nil { 289 return nil, err 290 } 291 p.firstPage = false 292 293 prevToken := p.nextToken 294 p.nextToken = result.Marker 295 296 if p.options.StopOnDuplicateToken && prevToken != nil && p.nextToken != nil && *prevToken == *p.nextToken { 297 p.nextToken = nil 298 } 299 300 return result, nil 301} 302 303// SnapshotAvailableWaiterOptions are waiter options for SnapshotAvailableWaiter 304type SnapshotAvailableWaiterOptions struct { 305 306 // Set of options to modify how an operation is invoked. These apply to all 307 // operations invoked for this client. Use functional options on operation call to 308 // modify this list for per operation behavior. 309 APIOptions []func(*middleware.Stack) error 310 311 // MinDelay is the minimum amount of time to delay between retries. If unset, 312 // SnapshotAvailableWaiter will use default minimum delay of 15 seconds. Note that 313 // MinDelay must resolve to a value lesser than or equal to the MaxDelay. 314 MinDelay time.Duration 315 316 // MaxDelay is the maximum amount of time to delay between retries. If unset or set 317 // to zero, SnapshotAvailableWaiter will use default max delay of 120 seconds. Note 318 // that MaxDelay must resolve to value greater than or equal to the MinDelay. 319 MaxDelay time.Duration 320 321 // LogWaitAttempts is used to enable logging for waiter retry attempts 322 LogWaitAttempts bool 323 324 // Retryable is function that can be used to override the service defined 325 // waiter-behavior based on operation output, or returned error. This function is 326 // used by the waiter to decide if a state is retryable or a terminal state. By 327 // default service-modeled logic will populate this option. This option can thus be 328 // used to define a custom waiter state with fall-back to service-modeled waiter 329 // state mutators.The function returns an error in case of a failure state. In case 330 // of retry state, this function returns a bool value of true and nil error, while 331 // in case of success it returns a bool value of false and nil error. 332 Retryable func(context.Context, *DescribeClusterSnapshotsInput, *DescribeClusterSnapshotsOutput, error) (bool, error) 333} 334 335// SnapshotAvailableWaiter defines the waiters for SnapshotAvailable 336type SnapshotAvailableWaiter struct { 337 client DescribeClusterSnapshotsAPIClient 338 339 options SnapshotAvailableWaiterOptions 340} 341 342// NewSnapshotAvailableWaiter constructs a SnapshotAvailableWaiter. 343func NewSnapshotAvailableWaiter(client DescribeClusterSnapshotsAPIClient, optFns ...func(*SnapshotAvailableWaiterOptions)) *SnapshotAvailableWaiter { 344 options := SnapshotAvailableWaiterOptions{} 345 options.MinDelay = 15 * time.Second 346 options.MaxDelay = 120 * time.Second 347 options.Retryable = snapshotAvailableStateRetryable 348 349 for _, fn := range optFns { 350 fn(&options) 351 } 352 return &SnapshotAvailableWaiter{ 353 client: client, 354 options: options, 355 } 356} 357 358// Wait calls the waiter function for SnapshotAvailable waiter. The maxWaitDur is 359// the maximum wait duration the waiter will wait. The maxWaitDur is required and 360// must be greater than zero. 361func (w *SnapshotAvailableWaiter) Wait(ctx context.Context, params *DescribeClusterSnapshotsInput, maxWaitDur time.Duration, optFns ...func(*SnapshotAvailableWaiterOptions)) error { 362 if maxWaitDur <= 0 { 363 return fmt.Errorf("maximum wait time for waiter must be greater than zero") 364 } 365 366 options := w.options 367 for _, fn := range optFns { 368 fn(&options) 369 } 370 371 if options.MaxDelay <= 0 { 372 options.MaxDelay = 120 * time.Second 373 } 374 375 if options.MinDelay > options.MaxDelay { 376 return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay) 377 } 378 379 ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur) 380 defer cancelFn() 381 382 logger := smithywaiter.Logger{} 383 remainingTime := maxWaitDur 384 385 var attempt int64 386 for { 387 388 attempt++ 389 apiOptions := options.APIOptions 390 start := time.Now() 391 392 if options.LogWaitAttempts { 393 logger.Attempt = attempt 394 apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...) 395 apiOptions = append(apiOptions, logger.AddLogger) 396 } 397 398 out, err := w.client.DescribeClusterSnapshots(ctx, params, func(o *Options) { 399 o.APIOptions = append(o.APIOptions, apiOptions...) 400 }) 401 402 retryable, err := options.Retryable(ctx, params, out, err) 403 if err != nil { 404 return err 405 } 406 if !retryable { 407 return nil 408 } 409 410 remainingTime -= time.Since(start) 411 if remainingTime < options.MinDelay || remainingTime <= 0 { 412 break 413 } 414 415 // compute exponential backoff between waiter retries 416 delay, err := smithywaiter.ComputeDelay( 417 attempt, options.MinDelay, options.MaxDelay, remainingTime, 418 ) 419 if err != nil { 420 return fmt.Errorf("error computing waiter delay, %w", err) 421 } 422 423 remainingTime -= delay 424 // sleep for the delay amount before invoking a request 425 if err := smithytime.SleepWithContext(ctx, delay); err != nil { 426 return fmt.Errorf("request cancelled while waiting, %w", err) 427 } 428 } 429 return fmt.Errorf("exceeded max wait time for SnapshotAvailable waiter") 430} 431 432func snapshotAvailableStateRetryable(ctx context.Context, input *DescribeClusterSnapshotsInput, output *DescribeClusterSnapshotsOutput, err error) (bool, error) { 433 434 if err == nil { 435 pathValue, err := jmespath.Search("Snapshots[].Status", output) 436 if err != nil { 437 return false, fmt.Errorf("error evaluating waiter state: %w", err) 438 } 439 440 expectedValue := "available" 441 var match = true 442 listOfValues, ok := pathValue.([]interface{}) 443 if !ok { 444 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 445 } 446 447 if len(listOfValues) == 0 { 448 match = false 449 } 450 for _, v := range listOfValues { 451 value, ok := v.(*string) 452 if !ok { 453 return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue) 454 } 455 456 if string(*value) != expectedValue { 457 match = false 458 } 459 } 460 461 if match { 462 return false, nil 463 } 464 } 465 466 if err == nil { 467 pathValue, err := jmespath.Search("Snapshots[].Status", output) 468 if err != nil { 469 return false, fmt.Errorf("error evaluating waiter state: %w", err) 470 } 471 472 expectedValue := "failed" 473 listOfValues, ok := pathValue.([]interface{}) 474 if !ok { 475 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 476 } 477 478 for _, v := range listOfValues { 479 value, ok := v.(*string) 480 if !ok { 481 return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue) 482 } 483 484 if string(*value) == expectedValue { 485 return false, fmt.Errorf("waiter state transitioned to Failure") 486 } 487 } 488 } 489 490 if err == nil { 491 pathValue, err := jmespath.Search("Snapshots[].Status", output) 492 if err != nil { 493 return false, fmt.Errorf("error evaluating waiter state: %w", err) 494 } 495 496 expectedValue := "deleted" 497 listOfValues, ok := pathValue.([]interface{}) 498 if !ok { 499 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 500 } 501 502 for _, v := range listOfValues { 503 value, ok := v.(*string) 504 if !ok { 505 return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue) 506 } 507 508 if string(*value) == expectedValue { 509 return false, fmt.Errorf("waiter state transitioned to Failure") 510 } 511 } 512 } 513 514 return true, nil 515} 516 517func newServiceMetadataMiddleware_opDescribeClusterSnapshots(region string) *awsmiddleware.RegisterServiceMetadata { 518 return &awsmiddleware.RegisterServiceMetadata{ 519 Region: region, 520 ServiceID: ServiceID, 521 SigningName: "redshift", 522 OperationName: "DescribeClusterSnapshots", 523 } 524} 525