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, &params, 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