1// Code generated by smithy-go-codegen DO NOT EDIT. 2 3package rds 4 5import ( 6 "context" 7 "errors" 8 "fmt" 9 awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" 10 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" 11 "github.com/aws/aws-sdk-go-v2/service/rds/types" 12 "github.com/aws/smithy-go/middleware" 13 smithytime "github.com/aws/smithy-go/time" 14 smithyhttp "github.com/aws/smithy-go/transport/http" 15 smithywaiter "github.com/aws/smithy-go/waiter" 16 "github.com/jmespath/go-jmespath" 17 "strconv" 18 "time" 19) 20 21// Returns information about DB cluster snapshots. This API action supports 22// pagination. For more information on Amazon Aurora, see What Is Amazon Aurora? 23// (https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/CHAP_AuroraOverview.html) 24// in the Amazon Aurora User Guide. This action only applies to Aurora DB clusters. 25func (c *Client) DescribeDBClusterSnapshots(ctx context.Context, params *DescribeDBClusterSnapshotsInput, optFns ...func(*Options)) (*DescribeDBClusterSnapshotsOutput, error) { 26 if params == nil { 27 params = &DescribeDBClusterSnapshotsInput{} 28 } 29 30 result, metadata, err := c.invokeOperation(ctx, "DescribeDBClusterSnapshots", params, optFns, addOperationDescribeDBClusterSnapshotsMiddlewares) 31 if err != nil { 32 return nil, err 33 } 34 35 out := result.(*DescribeDBClusterSnapshotsOutput) 36 out.ResultMetadata = metadata 37 return out, nil 38} 39 40// 41type DescribeDBClusterSnapshotsInput struct { 42 43 // The ID of the DB cluster to retrieve the list of DB cluster snapshots for. This 44 // parameter can't be used in conjunction with the DBClusterSnapshotIdentifier 45 // parameter. This parameter isn't case-sensitive. Constraints: 46 // 47 // * If supplied, 48 // must match the identifier of an existing DBCluster. 49 DBClusterIdentifier *string 50 51 // A specific DB cluster snapshot identifier to describe. This parameter can't be 52 // used in conjunction with the DBClusterIdentifier parameter. This value is stored 53 // as a lowercase string. Constraints: 54 // 55 // * If supplied, must match the identifier of 56 // an existing DBClusterSnapshot. 57 // 58 // * If this identifier is for an automated 59 // snapshot, the SnapshotType parameter must also be specified. 60 DBClusterSnapshotIdentifier *string 61 62 // A filter that specifies one or more DB cluster snapshots to describe. Supported 63 // filters: 64 // 65 // * db-cluster-id - Accepts DB cluster identifiers and DB cluster Amazon 66 // Resource Names (ARNs). 67 // 68 // * db-cluster-snapshot-id - Accepts DB cluster snapshot 69 // identifiers. 70 // 71 // * snapshot-type - Accepts types of DB cluster snapshots. 72 // 73 // * engine 74 // - Accepts names of database engines. 75 Filters []types.Filter 76 77 // A value that indicates whether to include manual DB cluster snapshots that are 78 // public and can be copied or restored by any AWS account. By default, the public 79 // snapshots are not included. You can share a manual DB cluster snapshot as public 80 // by using the ModifyDBClusterSnapshotAttribute API action. 81 IncludePublic bool 82 83 // A value that indicates whether to include shared manual DB cluster snapshots 84 // from other AWS accounts that this AWS account has been given permission to copy 85 // or restore. By default, these snapshots are not included. You can give an AWS 86 // account permission to restore a manual DB cluster snapshot from another AWS 87 // account by the ModifyDBClusterSnapshotAttribute API action. 88 IncludeShared bool 89 90 // An optional pagination token provided by a previous DescribeDBClusterSnapshots 91 // request. If this parameter is specified, the response includes only records 92 // beyond the marker, up to the value specified by MaxRecords. 93 Marker *string 94 95 // The maximum number of records to include in the response. If more records exist 96 // than the specified MaxRecords value, a pagination token called a marker is 97 // included in the response so you can retrieve the remaining results. Default: 100 98 // Constraints: Minimum 20, maximum 100. 99 MaxRecords *int32 100 101 // The type of DB cluster snapshots to be returned. You can specify one of the 102 // following values: 103 // 104 // * automated - Return all DB cluster snapshots that have been 105 // automatically taken by Amazon RDS for my AWS account. 106 // 107 // * manual - Return all DB 108 // cluster snapshots that have been taken by my AWS account. 109 // 110 // * shared - Return all 111 // manual DB cluster snapshots that have been shared to my AWS account. 112 // 113 // * public - 114 // Return all DB cluster snapshots that have been marked as public. 115 // 116 // If you don't 117 // specify a SnapshotType value, then both automated and manual DB cluster 118 // snapshots are returned. You can include shared DB cluster snapshots with these 119 // results by enabling the IncludeShared parameter. You can include public DB 120 // cluster snapshots with these results by enabling the IncludePublic parameter. 121 // The IncludeShared and IncludePublic parameters don't apply for SnapshotType 122 // values of manual or automated. The IncludePublic parameter doesn't apply when 123 // SnapshotType is set to shared. The IncludeShared parameter doesn't apply when 124 // SnapshotType is set to public. 125 SnapshotType *string 126} 127 128// Provides a list of DB cluster snapshots for the user as the result of a call to 129// the DescribeDBClusterSnapshots action. 130type DescribeDBClusterSnapshotsOutput struct { 131 132 // Provides a list of DB cluster snapshots for the user. 133 DBClusterSnapshots []types.DBClusterSnapshot 134 135 // An optional pagination token provided by a previous DescribeDBClusterSnapshots 136 // request. If this parameter is specified, the response includes only records 137 // beyond the marker, up to the value specified by MaxRecords. 138 Marker *string 139 140 // Metadata pertaining to the operation's result. 141 ResultMetadata middleware.Metadata 142} 143 144func addOperationDescribeDBClusterSnapshotsMiddlewares(stack *middleware.Stack, options Options) (err error) { 145 err = stack.Serialize.Add(&awsAwsquery_serializeOpDescribeDBClusterSnapshots{}, middleware.After) 146 if err != nil { 147 return err 148 } 149 err = stack.Deserialize.Add(&awsAwsquery_deserializeOpDescribeDBClusterSnapshots{}, middleware.After) 150 if err != nil { 151 return err 152 } 153 if err = addSetLoggerMiddleware(stack, options); err != nil { 154 return err 155 } 156 if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { 157 return err 158 } 159 if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { 160 return err 161 } 162 if err = addResolveEndpointMiddleware(stack, options); err != nil { 163 return err 164 } 165 if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { 166 return err 167 } 168 if err = addRetryMiddlewares(stack, options); err != nil { 169 return err 170 } 171 if err = addHTTPSignerV4Middleware(stack, options); err != nil { 172 return err 173 } 174 if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { 175 return err 176 } 177 if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { 178 return err 179 } 180 if err = addClientUserAgent(stack); err != nil { 181 return err 182 } 183 if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { 184 return err 185 } 186 if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { 187 return err 188 } 189 if err = addOpDescribeDBClusterSnapshotsValidationMiddleware(stack); err != nil { 190 return err 191 } 192 if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeDBClusterSnapshots(options.Region), middleware.Before); err != nil { 193 return err 194 } 195 if err = addRequestIDRetrieverMiddleware(stack); err != nil { 196 return err 197 } 198 if err = addResponseErrorMiddleware(stack); err != nil { 199 return err 200 } 201 if err = addRequestResponseLogging(stack, options); err != nil { 202 return err 203 } 204 return nil 205} 206 207// DescribeDBClusterSnapshotsAPIClient is a client that implements the 208// DescribeDBClusterSnapshots operation. 209type DescribeDBClusterSnapshotsAPIClient interface { 210 DescribeDBClusterSnapshots(context.Context, *DescribeDBClusterSnapshotsInput, ...func(*Options)) (*DescribeDBClusterSnapshotsOutput, error) 211} 212 213var _ DescribeDBClusterSnapshotsAPIClient = (*Client)(nil) 214 215// DescribeDBClusterSnapshotsPaginatorOptions is the paginator options for 216// DescribeDBClusterSnapshots 217type DescribeDBClusterSnapshotsPaginatorOptions struct { 218 // The maximum number of records to include in the response. If more records exist 219 // than the specified MaxRecords value, a pagination token called a marker is 220 // included in the response so you can retrieve the remaining results. Default: 100 221 // Constraints: Minimum 20, maximum 100. 222 Limit int32 223 224 // Set to true if pagination should stop if the service returns a pagination token 225 // that matches the most recent token provided to the service. 226 StopOnDuplicateToken bool 227} 228 229// DescribeDBClusterSnapshotsPaginator is a paginator for 230// DescribeDBClusterSnapshots 231type DescribeDBClusterSnapshotsPaginator struct { 232 options DescribeDBClusterSnapshotsPaginatorOptions 233 client DescribeDBClusterSnapshotsAPIClient 234 params *DescribeDBClusterSnapshotsInput 235 nextToken *string 236 firstPage bool 237} 238 239// NewDescribeDBClusterSnapshotsPaginator returns a new 240// DescribeDBClusterSnapshotsPaginator 241func NewDescribeDBClusterSnapshotsPaginator(client DescribeDBClusterSnapshotsAPIClient, params *DescribeDBClusterSnapshotsInput, optFns ...func(*DescribeDBClusterSnapshotsPaginatorOptions)) *DescribeDBClusterSnapshotsPaginator { 242 options := DescribeDBClusterSnapshotsPaginatorOptions{} 243 if params.MaxRecords != nil { 244 options.Limit = *params.MaxRecords 245 } 246 247 for _, fn := range optFns { 248 fn(&options) 249 } 250 251 if params == nil { 252 params = &DescribeDBClusterSnapshotsInput{} 253 } 254 255 return &DescribeDBClusterSnapshotsPaginator{ 256 options: options, 257 client: client, 258 params: params, 259 firstPage: true, 260 } 261} 262 263// HasMorePages returns a boolean indicating whether more pages are available 264func (p *DescribeDBClusterSnapshotsPaginator) HasMorePages() bool { 265 return p.firstPage || p.nextToken != nil 266} 267 268// NextPage retrieves the next DescribeDBClusterSnapshots page. 269func (p *DescribeDBClusterSnapshotsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeDBClusterSnapshotsOutput, error) { 270 if !p.HasMorePages() { 271 return nil, fmt.Errorf("no more pages available") 272 } 273 274 params := *p.params 275 params.Marker = p.nextToken 276 277 var limit *int32 278 if p.options.Limit > 0 { 279 limit = &p.options.Limit 280 } 281 params.MaxRecords = limit 282 283 result, err := p.client.DescribeDBClusterSnapshots(ctx, ¶ms, optFns...) 284 if err != nil { 285 return nil, err 286 } 287 p.firstPage = false 288 289 prevToken := p.nextToken 290 p.nextToken = result.Marker 291 292 if p.options.StopOnDuplicateToken && prevToken != nil && p.nextToken != nil && *prevToken == *p.nextToken { 293 p.nextToken = nil 294 } 295 296 return result, nil 297} 298 299// DBClusterSnapshotAvailableWaiterOptions are waiter options for 300// DBClusterSnapshotAvailableWaiter 301type DBClusterSnapshotAvailableWaiterOptions struct { 302 303 // Set of options to modify how an operation is invoked. These apply to all 304 // operations invoked for this client. Use functional options on operation call to 305 // modify this list for per operation behavior. 306 APIOptions []func(*middleware.Stack) error 307 308 // MinDelay is the minimum amount of time to delay between retries. If unset, 309 // DBClusterSnapshotAvailableWaiter will use default minimum delay of 30 seconds. 310 // Note that MinDelay must resolve to a value lesser than or equal to the MaxDelay. 311 MinDelay time.Duration 312 313 // MaxDelay is the maximum amount of time to delay between retries. If unset or set 314 // to zero, DBClusterSnapshotAvailableWaiter will use default max delay of 120 315 // seconds. Note that MaxDelay must resolve to value greater than or equal to the 316 // MinDelay. 317 MaxDelay time.Duration 318 319 // LogWaitAttempts is used to enable logging for waiter retry attempts 320 LogWaitAttempts bool 321 322 // Retryable is function that can be used to override the service defined 323 // waiter-behavior based on operation output, or returned error. This function is 324 // used by the waiter to decide if a state is retryable or a terminal state. By 325 // default service-modeled logic will populate this option. This option can thus be 326 // used to define a custom waiter state with fall-back to service-modeled waiter 327 // state mutators.The function returns an error in case of a failure state. In case 328 // of retry state, this function returns a bool value of true and nil error, while 329 // in case of success it returns a bool value of false and nil error. 330 Retryable func(context.Context, *DescribeDBClusterSnapshotsInput, *DescribeDBClusterSnapshotsOutput, error) (bool, error) 331} 332 333// DBClusterSnapshotAvailableWaiter defines the waiters for 334// DBClusterSnapshotAvailable 335type DBClusterSnapshotAvailableWaiter struct { 336 client DescribeDBClusterSnapshotsAPIClient 337 338 options DBClusterSnapshotAvailableWaiterOptions 339} 340 341// NewDBClusterSnapshotAvailableWaiter constructs a 342// DBClusterSnapshotAvailableWaiter. 343func NewDBClusterSnapshotAvailableWaiter(client DescribeDBClusterSnapshotsAPIClient, optFns ...func(*DBClusterSnapshotAvailableWaiterOptions)) *DBClusterSnapshotAvailableWaiter { 344 options := DBClusterSnapshotAvailableWaiterOptions{} 345 options.MinDelay = 30 * time.Second 346 options.MaxDelay = 120 * time.Second 347 options.Retryable = dBClusterSnapshotAvailableStateRetryable 348 349 for _, fn := range optFns { 350 fn(&options) 351 } 352 return &DBClusterSnapshotAvailableWaiter{ 353 client: client, 354 options: options, 355 } 356} 357 358// Wait calls the waiter function for DBClusterSnapshotAvailable waiter. The 359// maxWaitDur is the maximum wait duration the waiter will wait. The maxWaitDur is 360// required and must be greater than zero. 361func (w *DBClusterSnapshotAvailableWaiter) Wait(ctx context.Context, params *DescribeDBClusterSnapshotsInput, maxWaitDur time.Duration, optFns ...func(*DBClusterSnapshotAvailableWaiterOptions)) 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.DescribeDBClusterSnapshots(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 DBClusterSnapshotAvailable waiter") 430} 431 432func dBClusterSnapshotAvailableStateRetryable(ctx context.Context, input *DescribeDBClusterSnapshotsInput, output *DescribeDBClusterSnapshotsOutput, err error) (bool, error) { 433 434 if err == nil { 435 pathValue, err := jmespath.Search("DBClusterSnapshots[].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("DBClusterSnapshots[].Status", output) 468 if err != nil { 469 return false, fmt.Errorf("error evaluating waiter state: %w", err) 470 } 471 472 expectedValue := "deleted" 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("DBClusterSnapshots[].Status", output) 492 if err != nil { 493 return false, fmt.Errorf("error evaluating waiter state: %w", err) 494 } 495 496 expectedValue := "deleting" 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 if err == nil { 515 pathValue, err := jmespath.Search("DBClusterSnapshots[].Status", output) 516 if err != nil { 517 return false, fmt.Errorf("error evaluating waiter state: %w", err) 518 } 519 520 expectedValue := "failed" 521 listOfValues, ok := pathValue.([]interface{}) 522 if !ok { 523 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 524 } 525 526 for _, v := range listOfValues { 527 value, ok := v.(*string) 528 if !ok { 529 return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue) 530 } 531 532 if string(*value) == expectedValue { 533 return false, fmt.Errorf("waiter state transitioned to Failure") 534 } 535 } 536 } 537 538 if err == nil { 539 pathValue, err := jmespath.Search("DBClusterSnapshots[].Status", output) 540 if err != nil { 541 return false, fmt.Errorf("error evaluating waiter state: %w", err) 542 } 543 544 expectedValue := "incompatible-restore" 545 listOfValues, ok := pathValue.([]interface{}) 546 if !ok { 547 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 548 } 549 550 for _, v := range listOfValues { 551 value, ok := v.(*string) 552 if !ok { 553 return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue) 554 } 555 556 if string(*value) == expectedValue { 557 return false, fmt.Errorf("waiter state transitioned to Failure") 558 } 559 } 560 } 561 562 if err == nil { 563 pathValue, err := jmespath.Search("DBClusterSnapshots[].Status", output) 564 if err != nil { 565 return false, fmt.Errorf("error evaluating waiter state: %w", err) 566 } 567 568 expectedValue := "incompatible-parameters" 569 listOfValues, ok := pathValue.([]interface{}) 570 if !ok { 571 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 572 } 573 574 for _, v := range listOfValues { 575 value, ok := v.(*string) 576 if !ok { 577 return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue) 578 } 579 580 if string(*value) == expectedValue { 581 return false, fmt.Errorf("waiter state transitioned to Failure") 582 } 583 } 584 } 585 586 return true, nil 587} 588 589// DBClusterSnapshotDeletedWaiterOptions are waiter options for 590// DBClusterSnapshotDeletedWaiter 591type DBClusterSnapshotDeletedWaiterOptions struct { 592 593 // Set of options to modify how an operation is invoked. These apply to all 594 // operations invoked for this client. Use functional options on operation call to 595 // modify this list for per operation behavior. 596 APIOptions []func(*middleware.Stack) error 597 598 // MinDelay is the minimum amount of time to delay between retries. If unset, 599 // DBClusterSnapshotDeletedWaiter will use default minimum delay of 30 seconds. 600 // Note that MinDelay must resolve to a value lesser than or equal to the MaxDelay. 601 MinDelay time.Duration 602 603 // MaxDelay is the maximum amount of time to delay between retries. If unset or set 604 // to zero, DBClusterSnapshotDeletedWaiter will use default max delay of 120 605 // seconds. Note that MaxDelay must resolve to value greater than or equal to the 606 // MinDelay. 607 MaxDelay time.Duration 608 609 // LogWaitAttempts is used to enable logging for waiter retry attempts 610 LogWaitAttempts bool 611 612 // Retryable is function that can be used to override the service defined 613 // waiter-behavior based on operation output, or returned error. This function is 614 // used by the waiter to decide if a state is retryable or a terminal state. By 615 // default service-modeled logic will populate this option. This option can thus be 616 // used to define a custom waiter state with fall-back to service-modeled waiter 617 // state mutators.The function returns an error in case of a failure state. In case 618 // of retry state, this function returns a bool value of true and nil error, while 619 // in case of success it returns a bool value of false and nil error. 620 Retryable func(context.Context, *DescribeDBClusterSnapshotsInput, *DescribeDBClusterSnapshotsOutput, error) (bool, error) 621} 622 623// DBClusterSnapshotDeletedWaiter defines the waiters for DBClusterSnapshotDeleted 624type DBClusterSnapshotDeletedWaiter struct { 625 client DescribeDBClusterSnapshotsAPIClient 626 627 options DBClusterSnapshotDeletedWaiterOptions 628} 629 630// NewDBClusterSnapshotDeletedWaiter constructs a DBClusterSnapshotDeletedWaiter. 631func NewDBClusterSnapshotDeletedWaiter(client DescribeDBClusterSnapshotsAPIClient, optFns ...func(*DBClusterSnapshotDeletedWaiterOptions)) *DBClusterSnapshotDeletedWaiter { 632 options := DBClusterSnapshotDeletedWaiterOptions{} 633 options.MinDelay = 30 * time.Second 634 options.MaxDelay = 120 * time.Second 635 options.Retryable = dBClusterSnapshotDeletedStateRetryable 636 637 for _, fn := range optFns { 638 fn(&options) 639 } 640 return &DBClusterSnapshotDeletedWaiter{ 641 client: client, 642 options: options, 643 } 644} 645 646// Wait calls the waiter function for DBClusterSnapshotDeleted waiter. The 647// maxWaitDur is the maximum wait duration the waiter will wait. The maxWaitDur is 648// required and must be greater than zero. 649func (w *DBClusterSnapshotDeletedWaiter) Wait(ctx context.Context, params *DescribeDBClusterSnapshotsInput, maxWaitDur time.Duration, optFns ...func(*DBClusterSnapshotDeletedWaiterOptions)) error { 650 if maxWaitDur <= 0 { 651 return fmt.Errorf("maximum wait time for waiter must be greater than zero") 652 } 653 654 options := w.options 655 for _, fn := range optFns { 656 fn(&options) 657 } 658 659 if options.MaxDelay <= 0 { 660 options.MaxDelay = 120 * time.Second 661 } 662 663 if options.MinDelay > options.MaxDelay { 664 return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay) 665 } 666 667 ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur) 668 defer cancelFn() 669 670 logger := smithywaiter.Logger{} 671 remainingTime := maxWaitDur 672 673 var attempt int64 674 for { 675 676 attempt++ 677 apiOptions := options.APIOptions 678 start := time.Now() 679 680 if options.LogWaitAttempts { 681 logger.Attempt = attempt 682 apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...) 683 apiOptions = append(apiOptions, logger.AddLogger) 684 } 685 686 out, err := w.client.DescribeDBClusterSnapshots(ctx, params, func(o *Options) { 687 o.APIOptions = append(o.APIOptions, apiOptions...) 688 }) 689 690 retryable, err := options.Retryable(ctx, params, out, err) 691 if err != nil { 692 return err 693 } 694 if !retryable { 695 return nil 696 } 697 698 remainingTime -= time.Since(start) 699 if remainingTime < options.MinDelay || remainingTime <= 0 { 700 break 701 } 702 703 // compute exponential backoff between waiter retries 704 delay, err := smithywaiter.ComputeDelay( 705 attempt, options.MinDelay, options.MaxDelay, remainingTime, 706 ) 707 if err != nil { 708 return fmt.Errorf("error computing waiter delay, %w", err) 709 } 710 711 remainingTime -= delay 712 // sleep for the delay amount before invoking a request 713 if err := smithytime.SleepWithContext(ctx, delay); err != nil { 714 return fmt.Errorf("request cancelled while waiting, %w", err) 715 } 716 } 717 return fmt.Errorf("exceeded max wait time for DBClusterSnapshotDeleted waiter") 718} 719 720func dBClusterSnapshotDeletedStateRetryable(ctx context.Context, input *DescribeDBClusterSnapshotsInput, output *DescribeDBClusterSnapshotsOutput, err error) (bool, error) { 721 722 if err == nil { 723 pathValue, err := jmespath.Search("length(DBClusterSnapshots) == `0`", output) 724 if err != nil { 725 return false, fmt.Errorf("error evaluating waiter state: %w", err) 726 } 727 728 expectedValue := "true" 729 bv, err := strconv.ParseBool(expectedValue) 730 if err != nil { 731 return false, fmt.Errorf("error parsing boolean from string %w", err) 732 } 733 value, ok := pathValue.(bool) 734 if !ok { 735 return false, fmt.Errorf("waiter comparator expected bool value got %T", pathValue) 736 } 737 738 if value == bv { 739 return false, nil 740 } 741 } 742 743 if err != nil { 744 var errorType *types.DBClusterSnapshotNotFoundFault 745 if errors.As(err, &errorType) { 746 return false, nil 747 } 748 } 749 750 if err == nil { 751 pathValue, err := jmespath.Search("DBClusterSnapshots[].Status", output) 752 if err != nil { 753 return false, fmt.Errorf("error evaluating waiter state: %w", err) 754 } 755 756 expectedValue := "creating" 757 listOfValues, ok := pathValue.([]interface{}) 758 if !ok { 759 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 760 } 761 762 for _, v := range listOfValues { 763 value, ok := v.(*string) 764 if !ok { 765 return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue) 766 } 767 768 if string(*value) == expectedValue { 769 return false, fmt.Errorf("waiter state transitioned to Failure") 770 } 771 } 772 } 773 774 if err == nil { 775 pathValue, err := jmespath.Search("DBClusterSnapshots[].Status", output) 776 if err != nil { 777 return false, fmt.Errorf("error evaluating waiter state: %w", err) 778 } 779 780 expectedValue := "modifying" 781 listOfValues, ok := pathValue.([]interface{}) 782 if !ok { 783 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 784 } 785 786 for _, v := range listOfValues { 787 value, ok := v.(*string) 788 if !ok { 789 return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue) 790 } 791 792 if string(*value) == expectedValue { 793 return false, fmt.Errorf("waiter state transitioned to Failure") 794 } 795 } 796 } 797 798 if err == nil { 799 pathValue, err := jmespath.Search("DBClusterSnapshots[].Status", output) 800 if err != nil { 801 return false, fmt.Errorf("error evaluating waiter state: %w", err) 802 } 803 804 expectedValue := "rebooting" 805 listOfValues, ok := pathValue.([]interface{}) 806 if !ok { 807 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 808 } 809 810 for _, v := range listOfValues { 811 value, ok := v.(*string) 812 if !ok { 813 return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue) 814 } 815 816 if string(*value) == expectedValue { 817 return false, fmt.Errorf("waiter state transitioned to Failure") 818 } 819 } 820 } 821 822 if err == nil { 823 pathValue, err := jmespath.Search("DBClusterSnapshots[].Status", output) 824 if err != nil { 825 return false, fmt.Errorf("error evaluating waiter state: %w", err) 826 } 827 828 expectedValue := "resetting-master-credentials" 829 listOfValues, ok := pathValue.([]interface{}) 830 if !ok { 831 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 832 } 833 834 for _, v := range listOfValues { 835 value, ok := v.(*string) 836 if !ok { 837 return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue) 838 } 839 840 if string(*value) == expectedValue { 841 return false, fmt.Errorf("waiter state transitioned to Failure") 842 } 843 } 844 } 845 846 return true, nil 847} 848 849func newServiceMetadataMiddleware_opDescribeDBClusterSnapshots(region string) *awsmiddleware.RegisterServiceMetadata { 850 return &awsmiddleware.RegisterServiceMetadata{ 851 Region: region, 852 ServiceID: ServiceID, 853 SigningName: "rds", 854 OperationName: "DescribeDBClusterSnapshots", 855 } 856} 857