1// Code generated by smithy-go-codegen DO NOT EDIT. 2 3package autoscaling 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/autoscaling/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 "strconv" 17 "time" 18) 19 20// Describes one or more Auto Scaling groups. 21func (c *Client) DescribeAutoScalingGroups(ctx context.Context, params *DescribeAutoScalingGroupsInput, optFns ...func(*Options)) (*DescribeAutoScalingGroupsOutput, error) { 22 if params == nil { 23 params = &DescribeAutoScalingGroupsInput{} 24 } 25 26 result, metadata, err := c.invokeOperation(ctx, "DescribeAutoScalingGroups", params, optFns, addOperationDescribeAutoScalingGroupsMiddlewares) 27 if err != nil { 28 return nil, err 29 } 30 31 out := result.(*DescribeAutoScalingGroupsOutput) 32 out.ResultMetadata = metadata 33 return out, nil 34} 35 36type DescribeAutoScalingGroupsInput struct { 37 38 // The names of the Auto Scaling groups. By default, you can only specify up to 50 39 // names. You can optionally increase this limit using the MaxRecords parameter. If 40 // you omit this parameter, all Auto Scaling groups are described. 41 AutoScalingGroupNames []string 42 43 // The maximum number of items to return with this call. The default value is 50 44 // and the maximum value is 100. 45 MaxRecords *int32 46 47 // The token for the next set of items to return. (You received this token from a 48 // previous call.) 49 NextToken *string 50} 51 52type DescribeAutoScalingGroupsOutput struct { 53 54 // The groups. 55 // 56 // This member is required. 57 AutoScalingGroups []types.AutoScalingGroup 58 59 // A string that indicates that the response contains more items than can be 60 // returned in a single response. To receive additional items, specify this string 61 // for the NextToken value when requesting the next set of items. This value is 62 // null when there are no more items to return. 63 NextToken *string 64 65 // Metadata pertaining to the operation's result. 66 ResultMetadata middleware.Metadata 67} 68 69func addOperationDescribeAutoScalingGroupsMiddlewares(stack *middleware.Stack, options Options) (err error) { 70 err = stack.Serialize.Add(&awsAwsquery_serializeOpDescribeAutoScalingGroups{}, middleware.After) 71 if err != nil { 72 return err 73 } 74 err = stack.Deserialize.Add(&awsAwsquery_deserializeOpDescribeAutoScalingGroups{}, middleware.After) 75 if err != nil { 76 return err 77 } 78 if err = addSetLoggerMiddleware(stack, options); err != nil { 79 return err 80 } 81 if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { 82 return err 83 } 84 if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { 85 return err 86 } 87 if err = addResolveEndpointMiddleware(stack, options); err != nil { 88 return err 89 } 90 if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { 91 return err 92 } 93 if err = addRetryMiddlewares(stack, options); err != nil { 94 return err 95 } 96 if err = addHTTPSignerV4Middleware(stack, options); err != nil { 97 return err 98 } 99 if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { 100 return err 101 } 102 if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { 103 return err 104 } 105 if err = addClientUserAgent(stack); err != nil { 106 return err 107 } 108 if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { 109 return err 110 } 111 if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { 112 return err 113 } 114 if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeAutoScalingGroups(options.Region), middleware.Before); err != nil { 115 return err 116 } 117 if err = addRequestIDRetrieverMiddleware(stack); err != nil { 118 return err 119 } 120 if err = addResponseErrorMiddleware(stack); err != nil { 121 return err 122 } 123 if err = addRequestResponseLogging(stack, options); err != nil { 124 return err 125 } 126 return nil 127} 128 129// DescribeAutoScalingGroupsAPIClient is a client that implements the 130// DescribeAutoScalingGroups operation. 131type DescribeAutoScalingGroupsAPIClient interface { 132 DescribeAutoScalingGroups(context.Context, *DescribeAutoScalingGroupsInput, ...func(*Options)) (*DescribeAutoScalingGroupsOutput, error) 133} 134 135var _ DescribeAutoScalingGroupsAPIClient = (*Client)(nil) 136 137// DescribeAutoScalingGroupsPaginatorOptions is the paginator options for 138// DescribeAutoScalingGroups 139type DescribeAutoScalingGroupsPaginatorOptions struct { 140 // The maximum number of items to return with this call. The default value is 50 141 // and the maximum value is 100. 142 Limit int32 143 144 // Set to true if pagination should stop if the service returns a pagination token 145 // that matches the most recent token provided to the service. 146 StopOnDuplicateToken bool 147} 148 149// DescribeAutoScalingGroupsPaginator is a paginator for DescribeAutoScalingGroups 150type DescribeAutoScalingGroupsPaginator struct { 151 options DescribeAutoScalingGroupsPaginatorOptions 152 client DescribeAutoScalingGroupsAPIClient 153 params *DescribeAutoScalingGroupsInput 154 nextToken *string 155 firstPage bool 156} 157 158// NewDescribeAutoScalingGroupsPaginator returns a new 159// DescribeAutoScalingGroupsPaginator 160func NewDescribeAutoScalingGroupsPaginator(client DescribeAutoScalingGroupsAPIClient, params *DescribeAutoScalingGroupsInput, optFns ...func(*DescribeAutoScalingGroupsPaginatorOptions)) *DescribeAutoScalingGroupsPaginator { 161 if params == nil { 162 params = &DescribeAutoScalingGroupsInput{} 163 } 164 165 options := DescribeAutoScalingGroupsPaginatorOptions{} 166 if params.MaxRecords != nil { 167 options.Limit = *params.MaxRecords 168 } 169 170 for _, fn := range optFns { 171 fn(&options) 172 } 173 174 return &DescribeAutoScalingGroupsPaginator{ 175 options: options, 176 client: client, 177 params: params, 178 firstPage: true, 179 } 180} 181 182// HasMorePages returns a boolean indicating whether more pages are available 183func (p *DescribeAutoScalingGroupsPaginator) HasMorePages() bool { 184 return p.firstPage || p.nextToken != nil 185} 186 187// NextPage retrieves the next DescribeAutoScalingGroups page. 188func (p *DescribeAutoScalingGroupsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeAutoScalingGroupsOutput, error) { 189 if !p.HasMorePages() { 190 return nil, fmt.Errorf("no more pages available") 191 } 192 193 params := *p.params 194 params.NextToken = p.nextToken 195 196 var limit *int32 197 if p.options.Limit > 0 { 198 limit = &p.options.Limit 199 } 200 params.MaxRecords = limit 201 202 result, err := p.client.DescribeAutoScalingGroups(ctx, ¶ms, optFns...) 203 if err != nil { 204 return nil, err 205 } 206 p.firstPage = false 207 208 prevToken := p.nextToken 209 p.nextToken = result.NextToken 210 211 if p.options.StopOnDuplicateToken && prevToken != nil && p.nextToken != nil && *prevToken == *p.nextToken { 212 p.nextToken = nil 213 } 214 215 return result, nil 216} 217 218// GroupExistsWaiterOptions are waiter options for GroupExistsWaiter 219type GroupExistsWaiterOptions struct { 220 221 // Set of options to modify how an operation is invoked. These apply to all 222 // operations invoked for this client. Use functional options on operation call to 223 // modify this list for per operation behavior. 224 APIOptions []func(*middleware.Stack) error 225 226 // MinDelay is the minimum amount of time to delay between retries. If unset, 227 // GroupExistsWaiter will use default minimum delay of 5 seconds. Note that 228 // MinDelay must resolve to a value lesser than or equal to the MaxDelay. 229 MinDelay time.Duration 230 231 // MaxDelay is the maximum amount of time to delay between retries. If unset or set 232 // to zero, GroupExistsWaiter will use default max delay of 120 seconds. Note that 233 // MaxDelay must resolve to value greater than or equal to the MinDelay. 234 MaxDelay time.Duration 235 236 // LogWaitAttempts is used to enable logging for waiter retry attempts 237 LogWaitAttempts bool 238 239 // Retryable is function that can be used to override the service defined 240 // waiter-behavior based on operation output, or returned error. This function is 241 // used by the waiter to decide if a state is retryable or a terminal state. By 242 // default service-modeled logic will populate this option. This option can thus be 243 // used to define a custom waiter state with fall-back to service-modeled waiter 244 // state mutators.The function returns an error in case of a failure state. In case 245 // of retry state, this function returns a bool value of true and nil error, while 246 // in case of success it returns a bool value of false and nil error. 247 Retryable func(context.Context, *DescribeAutoScalingGroupsInput, *DescribeAutoScalingGroupsOutput, error) (bool, error) 248} 249 250// GroupExistsWaiter defines the waiters for GroupExists 251type GroupExistsWaiter struct { 252 client DescribeAutoScalingGroupsAPIClient 253 254 options GroupExistsWaiterOptions 255} 256 257// NewGroupExistsWaiter constructs a GroupExistsWaiter. 258func NewGroupExistsWaiter(client DescribeAutoScalingGroupsAPIClient, optFns ...func(*GroupExistsWaiterOptions)) *GroupExistsWaiter { 259 options := GroupExistsWaiterOptions{} 260 options.MinDelay = 5 * time.Second 261 options.MaxDelay = 120 * time.Second 262 options.Retryable = groupExistsStateRetryable 263 264 for _, fn := range optFns { 265 fn(&options) 266 } 267 return &GroupExistsWaiter{ 268 client: client, 269 options: options, 270 } 271} 272 273// Wait calls the waiter function for GroupExists waiter. The maxWaitDur is the 274// maximum wait duration the waiter will wait. The maxWaitDur is required and must 275// be greater than zero. 276func (w *GroupExistsWaiter) Wait(ctx context.Context, params *DescribeAutoScalingGroupsInput, maxWaitDur time.Duration, optFns ...func(*GroupExistsWaiterOptions)) error { 277 if maxWaitDur <= 0 { 278 return fmt.Errorf("maximum wait time for waiter must be greater than zero") 279 } 280 281 options := w.options 282 for _, fn := range optFns { 283 fn(&options) 284 } 285 286 if options.MaxDelay <= 0 { 287 options.MaxDelay = 120 * time.Second 288 } 289 290 if options.MinDelay > options.MaxDelay { 291 return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay) 292 } 293 294 ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur) 295 defer cancelFn() 296 297 logger := smithywaiter.Logger{} 298 remainingTime := maxWaitDur 299 300 var attempt int64 301 for { 302 303 attempt++ 304 apiOptions := options.APIOptions 305 start := time.Now() 306 307 if options.LogWaitAttempts { 308 logger.Attempt = attempt 309 apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...) 310 apiOptions = append(apiOptions, logger.AddLogger) 311 } 312 313 out, err := w.client.DescribeAutoScalingGroups(ctx, params, func(o *Options) { 314 o.APIOptions = append(o.APIOptions, apiOptions...) 315 }) 316 317 retryable, err := options.Retryable(ctx, params, out, err) 318 if err != nil { 319 return err 320 } 321 if !retryable { 322 return nil 323 } 324 325 remainingTime -= time.Since(start) 326 if remainingTime < options.MinDelay || remainingTime <= 0 { 327 break 328 } 329 330 // compute exponential backoff between waiter retries 331 delay, err := smithywaiter.ComputeDelay( 332 attempt, options.MinDelay, options.MaxDelay, remainingTime, 333 ) 334 if err != nil { 335 return fmt.Errorf("error computing waiter delay, %w", err) 336 } 337 338 remainingTime -= delay 339 // sleep for the delay amount before invoking a request 340 if err := smithytime.SleepWithContext(ctx, delay); err != nil { 341 return fmt.Errorf("request cancelled while waiting, %w", err) 342 } 343 } 344 return fmt.Errorf("exceeded max wait time for GroupExists waiter") 345} 346 347func groupExistsStateRetryable(ctx context.Context, input *DescribeAutoScalingGroupsInput, output *DescribeAutoScalingGroupsOutput, err error) (bool, error) { 348 349 if err == nil { 350 pathValue, err := jmespath.Search("length(AutoScalingGroups) > `0`", output) 351 if err != nil { 352 return false, fmt.Errorf("error evaluating waiter state: %w", err) 353 } 354 355 expectedValue := "true" 356 bv, err := strconv.ParseBool(expectedValue) 357 if err != nil { 358 return false, fmt.Errorf("error parsing boolean from string %w", err) 359 } 360 value, ok := pathValue.(bool) 361 if !ok { 362 return false, fmt.Errorf("waiter comparator expected bool value got %T", pathValue) 363 } 364 365 if value == bv { 366 return false, nil 367 } 368 } 369 370 if err == nil { 371 pathValue, err := jmespath.Search("length(AutoScalingGroups) > `0`", output) 372 if err != nil { 373 return false, fmt.Errorf("error evaluating waiter state: %w", err) 374 } 375 376 expectedValue := "false" 377 bv, err := strconv.ParseBool(expectedValue) 378 if err != nil { 379 return false, fmt.Errorf("error parsing boolean from string %w", err) 380 } 381 value, ok := pathValue.(bool) 382 if !ok { 383 return false, fmt.Errorf("waiter comparator expected bool value got %T", pathValue) 384 } 385 386 if value == bv { 387 return true, nil 388 } 389 } 390 391 return true, nil 392} 393 394// GroupInServiceWaiterOptions are waiter options for GroupInServiceWaiter 395type GroupInServiceWaiterOptions struct { 396 397 // Set of options to modify how an operation is invoked. These apply to all 398 // operations invoked for this client. Use functional options on operation call to 399 // modify this list for per operation behavior. 400 APIOptions []func(*middleware.Stack) error 401 402 // MinDelay is the minimum amount of time to delay between retries. If unset, 403 // GroupInServiceWaiter will use default minimum delay of 15 seconds. Note that 404 // MinDelay must resolve to a value lesser than or equal to the MaxDelay. 405 MinDelay time.Duration 406 407 // MaxDelay is the maximum amount of time to delay between retries. If unset or set 408 // to zero, GroupInServiceWaiter will use default max delay of 120 seconds. Note 409 // that MaxDelay must resolve to value greater than or equal to the MinDelay. 410 MaxDelay time.Duration 411 412 // LogWaitAttempts is used to enable logging for waiter retry attempts 413 LogWaitAttempts bool 414 415 // Retryable is function that can be used to override the service defined 416 // waiter-behavior based on operation output, or returned error. This function is 417 // used by the waiter to decide if a state is retryable or a terminal state. By 418 // default service-modeled logic will populate this option. This option can thus be 419 // used to define a custom waiter state with fall-back to service-modeled waiter 420 // state mutators.The function returns an error in case of a failure state. In case 421 // of retry state, this function returns a bool value of true and nil error, while 422 // in case of success it returns a bool value of false and nil error. 423 Retryable func(context.Context, *DescribeAutoScalingGroupsInput, *DescribeAutoScalingGroupsOutput, error) (bool, error) 424} 425 426// GroupInServiceWaiter defines the waiters for GroupInService 427type GroupInServiceWaiter struct { 428 client DescribeAutoScalingGroupsAPIClient 429 430 options GroupInServiceWaiterOptions 431} 432 433// NewGroupInServiceWaiter constructs a GroupInServiceWaiter. 434func NewGroupInServiceWaiter(client DescribeAutoScalingGroupsAPIClient, optFns ...func(*GroupInServiceWaiterOptions)) *GroupInServiceWaiter { 435 options := GroupInServiceWaiterOptions{} 436 options.MinDelay = 15 * time.Second 437 options.MaxDelay = 120 * time.Second 438 options.Retryable = groupInServiceStateRetryable 439 440 for _, fn := range optFns { 441 fn(&options) 442 } 443 return &GroupInServiceWaiter{ 444 client: client, 445 options: options, 446 } 447} 448 449// Wait calls the waiter function for GroupInService waiter. The maxWaitDur is the 450// maximum wait duration the waiter will wait. The maxWaitDur is required and must 451// be greater than zero. 452func (w *GroupInServiceWaiter) Wait(ctx context.Context, params *DescribeAutoScalingGroupsInput, maxWaitDur time.Duration, optFns ...func(*GroupInServiceWaiterOptions)) error { 453 if maxWaitDur <= 0 { 454 return fmt.Errorf("maximum wait time for waiter must be greater than zero") 455 } 456 457 options := w.options 458 for _, fn := range optFns { 459 fn(&options) 460 } 461 462 if options.MaxDelay <= 0 { 463 options.MaxDelay = 120 * time.Second 464 } 465 466 if options.MinDelay > options.MaxDelay { 467 return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay) 468 } 469 470 ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur) 471 defer cancelFn() 472 473 logger := smithywaiter.Logger{} 474 remainingTime := maxWaitDur 475 476 var attempt int64 477 for { 478 479 attempt++ 480 apiOptions := options.APIOptions 481 start := time.Now() 482 483 if options.LogWaitAttempts { 484 logger.Attempt = attempt 485 apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...) 486 apiOptions = append(apiOptions, logger.AddLogger) 487 } 488 489 out, err := w.client.DescribeAutoScalingGroups(ctx, params, func(o *Options) { 490 o.APIOptions = append(o.APIOptions, apiOptions...) 491 }) 492 493 retryable, err := options.Retryable(ctx, params, out, err) 494 if err != nil { 495 return err 496 } 497 if !retryable { 498 return nil 499 } 500 501 remainingTime -= time.Since(start) 502 if remainingTime < options.MinDelay || remainingTime <= 0 { 503 break 504 } 505 506 // compute exponential backoff between waiter retries 507 delay, err := smithywaiter.ComputeDelay( 508 attempt, options.MinDelay, options.MaxDelay, remainingTime, 509 ) 510 if err != nil { 511 return fmt.Errorf("error computing waiter delay, %w", err) 512 } 513 514 remainingTime -= delay 515 // sleep for the delay amount before invoking a request 516 if err := smithytime.SleepWithContext(ctx, delay); err != nil { 517 return fmt.Errorf("request cancelled while waiting, %w", err) 518 } 519 } 520 return fmt.Errorf("exceeded max wait time for GroupInService waiter") 521} 522 523func groupInServiceStateRetryable(ctx context.Context, input *DescribeAutoScalingGroupsInput, output *DescribeAutoScalingGroupsOutput, err error) (bool, error) { 524 525 if err == nil { 526 pathValue, err := jmespath.Search("contains(AutoScalingGroups[].[length(Instances[?LifecycleState=='InService']) >= MinSize][], `false`)", output) 527 if err != nil { 528 return false, fmt.Errorf("error evaluating waiter state: %w", err) 529 } 530 531 expectedValue := "false" 532 bv, err := strconv.ParseBool(expectedValue) 533 if err != nil { 534 return false, fmt.Errorf("error parsing boolean from string %w", err) 535 } 536 value, ok := pathValue.(bool) 537 if !ok { 538 return false, fmt.Errorf("waiter comparator expected bool value got %T", pathValue) 539 } 540 541 if value == bv { 542 return false, nil 543 } 544 } 545 546 if err == nil { 547 pathValue, err := jmespath.Search("contains(AutoScalingGroups[].[length(Instances[?LifecycleState=='InService']) >= MinSize][], `false`)", output) 548 if err != nil { 549 return false, fmt.Errorf("error evaluating waiter state: %w", err) 550 } 551 552 expectedValue := "true" 553 bv, err := strconv.ParseBool(expectedValue) 554 if err != nil { 555 return false, fmt.Errorf("error parsing boolean from string %w", err) 556 } 557 value, ok := pathValue.(bool) 558 if !ok { 559 return false, fmt.Errorf("waiter comparator expected bool value got %T", pathValue) 560 } 561 562 if value == bv { 563 return true, nil 564 } 565 } 566 567 return true, nil 568} 569 570// GroupNotExistsWaiterOptions are waiter options for GroupNotExistsWaiter 571type GroupNotExistsWaiterOptions struct { 572 573 // Set of options to modify how an operation is invoked. These apply to all 574 // operations invoked for this client. Use functional options on operation call to 575 // modify this list for per operation behavior. 576 APIOptions []func(*middleware.Stack) error 577 578 // MinDelay is the minimum amount of time to delay between retries. If unset, 579 // GroupNotExistsWaiter will use default minimum delay of 15 seconds. Note that 580 // MinDelay must resolve to a value lesser than or equal to the MaxDelay. 581 MinDelay time.Duration 582 583 // MaxDelay is the maximum amount of time to delay between retries. If unset or set 584 // to zero, GroupNotExistsWaiter will use default max delay of 120 seconds. Note 585 // that MaxDelay must resolve to value greater than or equal to the MinDelay. 586 MaxDelay time.Duration 587 588 // LogWaitAttempts is used to enable logging for waiter retry attempts 589 LogWaitAttempts bool 590 591 // Retryable is function that can be used to override the service defined 592 // waiter-behavior based on operation output, or returned error. This function is 593 // used by the waiter to decide if a state is retryable or a terminal state. By 594 // default service-modeled logic will populate this option. This option can thus be 595 // used to define a custom waiter state with fall-back to service-modeled waiter 596 // state mutators.The function returns an error in case of a failure state. In case 597 // of retry state, this function returns a bool value of true and nil error, while 598 // in case of success it returns a bool value of false and nil error. 599 Retryable func(context.Context, *DescribeAutoScalingGroupsInput, *DescribeAutoScalingGroupsOutput, error) (bool, error) 600} 601 602// GroupNotExistsWaiter defines the waiters for GroupNotExists 603type GroupNotExistsWaiter struct { 604 client DescribeAutoScalingGroupsAPIClient 605 606 options GroupNotExistsWaiterOptions 607} 608 609// NewGroupNotExistsWaiter constructs a GroupNotExistsWaiter. 610func NewGroupNotExistsWaiter(client DescribeAutoScalingGroupsAPIClient, optFns ...func(*GroupNotExistsWaiterOptions)) *GroupNotExistsWaiter { 611 options := GroupNotExistsWaiterOptions{} 612 options.MinDelay = 15 * time.Second 613 options.MaxDelay = 120 * time.Second 614 options.Retryable = groupNotExistsStateRetryable 615 616 for _, fn := range optFns { 617 fn(&options) 618 } 619 return &GroupNotExistsWaiter{ 620 client: client, 621 options: options, 622 } 623} 624 625// Wait calls the waiter function for GroupNotExists waiter. The maxWaitDur is the 626// maximum wait duration the waiter will wait. The maxWaitDur is required and must 627// be greater than zero. 628func (w *GroupNotExistsWaiter) Wait(ctx context.Context, params *DescribeAutoScalingGroupsInput, maxWaitDur time.Duration, optFns ...func(*GroupNotExistsWaiterOptions)) error { 629 if maxWaitDur <= 0 { 630 return fmt.Errorf("maximum wait time for waiter must be greater than zero") 631 } 632 633 options := w.options 634 for _, fn := range optFns { 635 fn(&options) 636 } 637 638 if options.MaxDelay <= 0 { 639 options.MaxDelay = 120 * time.Second 640 } 641 642 if options.MinDelay > options.MaxDelay { 643 return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay) 644 } 645 646 ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur) 647 defer cancelFn() 648 649 logger := smithywaiter.Logger{} 650 remainingTime := maxWaitDur 651 652 var attempt int64 653 for { 654 655 attempt++ 656 apiOptions := options.APIOptions 657 start := time.Now() 658 659 if options.LogWaitAttempts { 660 logger.Attempt = attempt 661 apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...) 662 apiOptions = append(apiOptions, logger.AddLogger) 663 } 664 665 out, err := w.client.DescribeAutoScalingGroups(ctx, params, func(o *Options) { 666 o.APIOptions = append(o.APIOptions, apiOptions...) 667 }) 668 669 retryable, err := options.Retryable(ctx, params, out, err) 670 if err != nil { 671 return err 672 } 673 if !retryable { 674 return nil 675 } 676 677 remainingTime -= time.Since(start) 678 if remainingTime < options.MinDelay || remainingTime <= 0 { 679 break 680 } 681 682 // compute exponential backoff between waiter retries 683 delay, err := smithywaiter.ComputeDelay( 684 attempt, options.MinDelay, options.MaxDelay, remainingTime, 685 ) 686 if err != nil { 687 return fmt.Errorf("error computing waiter delay, %w", err) 688 } 689 690 remainingTime -= delay 691 // sleep for the delay amount before invoking a request 692 if err := smithytime.SleepWithContext(ctx, delay); err != nil { 693 return fmt.Errorf("request cancelled while waiting, %w", err) 694 } 695 } 696 return fmt.Errorf("exceeded max wait time for GroupNotExists waiter") 697} 698 699func groupNotExistsStateRetryable(ctx context.Context, input *DescribeAutoScalingGroupsInput, output *DescribeAutoScalingGroupsOutput, err error) (bool, error) { 700 701 if err == nil { 702 pathValue, err := jmespath.Search("length(AutoScalingGroups) > `0`", output) 703 if err != nil { 704 return false, fmt.Errorf("error evaluating waiter state: %w", err) 705 } 706 707 expectedValue := "false" 708 bv, err := strconv.ParseBool(expectedValue) 709 if err != nil { 710 return false, fmt.Errorf("error parsing boolean from string %w", err) 711 } 712 value, ok := pathValue.(bool) 713 if !ok { 714 return false, fmt.Errorf("waiter comparator expected bool value got %T", pathValue) 715 } 716 717 if value == bv { 718 return false, nil 719 } 720 } 721 722 if err == nil { 723 pathValue, err := jmespath.Search("length(AutoScalingGroups) > `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 true, nil 740 } 741 } 742 743 return true, nil 744} 745 746func newServiceMetadataMiddleware_opDescribeAutoScalingGroups(region string) *awsmiddleware.RegisterServiceMetadata { 747 return &awsmiddleware.RegisterServiceMetadata{ 748 Region: region, 749 ServiceID: ServiceID, 750 SigningName: "autoscaling", 751 OperationName: "DescribeAutoScalingGroups", 752 } 753} 754