1// Code generated by smithy-go-codegen DO NOT EDIT.
2
3package neptune
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/neptune/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 information about provisioned instances, and supports pagination. This
20// operation can also return information for Amazon RDS instances and Amazon DocDB
21// instances.
22func (c *Client) DescribeDBInstances(ctx context.Context, params *DescribeDBInstancesInput, optFns ...func(*Options)) (*DescribeDBInstancesOutput, error) {
23	if params == nil {
24		params = &DescribeDBInstancesInput{}
25	}
26
27	result, metadata, err := c.invokeOperation(ctx, "DescribeDBInstances", params, optFns, c.addOperationDescribeDBInstancesMiddlewares)
28	if err != nil {
29		return nil, err
30	}
31
32	out := result.(*DescribeDBInstancesOutput)
33	out.ResultMetadata = metadata
34	return out, nil
35}
36
37type DescribeDBInstancesInput struct {
38
39	// The user-supplied instance identifier. If this parameter is specified,
40	// information from only the specific DB instance is returned. This parameter isn't
41	// case-sensitive. Constraints:
42	//
43	// * If supplied, must match the identifier of an
44	// existing DBInstance.
45	DBInstanceIdentifier *string
46
47	// A filter that specifies one or more DB instances to describe. Supported
48	// filters:
49	//
50	// * db-cluster-id - Accepts DB cluster identifiers and DB cluster Amazon
51	// Resource Names (ARNs). The results list will only include information about the
52	// DB instances associated with the DB clusters identified by these ARNs.
53	//
54	// * engine
55	// - Accepts an engine name (such as neptune), and restricts the results list to DB
56	// instances created by that engine.
57	//
58	// For example, to invoke this API from the
59	// Amazon CLI and filter so that only Neptune DB instances are returned, you could
60	// use the following command:
61	Filters []types.Filter
62
63	// An optional pagination token provided by a previous DescribeDBInstances request.
64	// If this parameter is specified, the response includes only records beyond the
65	// marker, up to the value specified by MaxRecords.
66	Marker *string
67
68	// The maximum number of records to include in the response. If more records exist
69	// than the specified MaxRecords value, a pagination token called a marker is
70	// included in the response so that the remaining results can be retrieved.
71	// Default: 100 Constraints: Minimum 20, maximum 100.
72	MaxRecords *int32
73
74	noSmithyDocumentSerde
75}
76
77type DescribeDBInstancesOutput struct {
78
79	// A list of DBInstance instances.
80	DBInstances []types.DBInstance
81
82	// An optional pagination token provided by a previous request. If this parameter
83	// is specified, the response includes only records beyond the marker, up to the
84	// value specified by MaxRecords .
85	Marker *string
86
87	// Metadata pertaining to the operation's result.
88	ResultMetadata middleware.Metadata
89
90	noSmithyDocumentSerde
91}
92
93func (c *Client) addOperationDescribeDBInstancesMiddlewares(stack *middleware.Stack, options Options) (err error) {
94	err = stack.Serialize.Add(&awsAwsquery_serializeOpDescribeDBInstances{}, middleware.After)
95	if err != nil {
96		return err
97	}
98	err = stack.Deserialize.Add(&awsAwsquery_deserializeOpDescribeDBInstances{}, middleware.After)
99	if err != nil {
100		return err
101	}
102	if err = addSetLoggerMiddleware(stack, options); err != nil {
103		return err
104	}
105	if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
106		return err
107	}
108	if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
109		return err
110	}
111	if err = addResolveEndpointMiddleware(stack, options); err != nil {
112		return err
113	}
114	if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
115		return err
116	}
117	if err = addRetryMiddlewares(stack, options); err != nil {
118		return err
119	}
120	if err = addHTTPSignerV4Middleware(stack, options); err != nil {
121		return err
122	}
123	if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
124		return err
125	}
126	if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
127		return err
128	}
129	if err = addClientUserAgent(stack); err != nil {
130		return err
131	}
132	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
133		return err
134	}
135	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
136		return err
137	}
138	if err = addOpDescribeDBInstancesValidationMiddleware(stack); err != nil {
139		return err
140	}
141	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeDBInstances(options.Region), middleware.Before); err != nil {
142		return err
143	}
144	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
145		return err
146	}
147	if err = addResponseErrorMiddleware(stack); err != nil {
148		return err
149	}
150	if err = addRequestResponseLogging(stack, options); err != nil {
151		return err
152	}
153	return nil
154}
155
156// DescribeDBInstancesAPIClient is a client that implements the DescribeDBInstances
157// operation.
158type DescribeDBInstancesAPIClient interface {
159	DescribeDBInstances(context.Context, *DescribeDBInstancesInput, ...func(*Options)) (*DescribeDBInstancesOutput, error)
160}
161
162var _ DescribeDBInstancesAPIClient = (*Client)(nil)
163
164// DescribeDBInstancesPaginatorOptions is the paginator options for
165// DescribeDBInstances
166type DescribeDBInstancesPaginatorOptions struct {
167	// The maximum number of records to include in the response. If more records exist
168	// than the specified MaxRecords value, a pagination token called a marker is
169	// included in the response so that the remaining results can be retrieved.
170	// Default: 100 Constraints: Minimum 20, maximum 100.
171	Limit int32
172
173	// Set to true if pagination should stop if the service returns a pagination token
174	// that matches the most recent token provided to the service.
175	StopOnDuplicateToken bool
176}
177
178// DescribeDBInstancesPaginator is a paginator for DescribeDBInstances
179type DescribeDBInstancesPaginator struct {
180	options   DescribeDBInstancesPaginatorOptions
181	client    DescribeDBInstancesAPIClient
182	params    *DescribeDBInstancesInput
183	nextToken *string
184	firstPage bool
185}
186
187// NewDescribeDBInstancesPaginator returns a new DescribeDBInstancesPaginator
188func NewDescribeDBInstancesPaginator(client DescribeDBInstancesAPIClient, params *DescribeDBInstancesInput, optFns ...func(*DescribeDBInstancesPaginatorOptions)) *DescribeDBInstancesPaginator {
189	if params == nil {
190		params = &DescribeDBInstancesInput{}
191	}
192
193	options := DescribeDBInstancesPaginatorOptions{}
194	if params.MaxRecords != nil {
195		options.Limit = *params.MaxRecords
196	}
197
198	for _, fn := range optFns {
199		fn(&options)
200	}
201
202	return &DescribeDBInstancesPaginator{
203		options:   options,
204		client:    client,
205		params:    params,
206		firstPage: true,
207	}
208}
209
210// HasMorePages returns a boolean indicating whether more pages are available
211func (p *DescribeDBInstancesPaginator) HasMorePages() bool {
212	return p.firstPage || p.nextToken != nil
213}
214
215// NextPage retrieves the next DescribeDBInstances page.
216func (p *DescribeDBInstancesPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeDBInstancesOutput, error) {
217	if !p.HasMorePages() {
218		return nil, fmt.Errorf("no more pages available")
219	}
220
221	params := *p.params
222	params.Marker = p.nextToken
223
224	var limit *int32
225	if p.options.Limit > 0 {
226		limit = &p.options.Limit
227	}
228	params.MaxRecords = limit
229
230	result, err := p.client.DescribeDBInstances(ctx, &params, optFns...)
231	if err != nil {
232		return nil, err
233	}
234	p.firstPage = false
235
236	prevToken := p.nextToken
237	p.nextToken = result.Marker
238
239	if p.options.StopOnDuplicateToken && prevToken != nil && p.nextToken != nil && *prevToken == *p.nextToken {
240		p.nextToken = nil
241	}
242
243	return result, nil
244}
245
246// DBInstanceAvailableWaiterOptions are waiter options for
247// DBInstanceAvailableWaiter
248type DBInstanceAvailableWaiterOptions struct {
249
250	// Set of options to modify how an operation is invoked. These apply to all
251	// operations invoked for this client. Use functional options on operation call to
252	// modify this list for per operation behavior.
253	APIOptions []func(*middleware.Stack) error
254
255	// MinDelay is the minimum amount of time to delay between retries. If unset,
256	// DBInstanceAvailableWaiter will use default minimum delay of 30 seconds. Note
257	// that MinDelay must resolve to a value lesser than or equal to the MaxDelay.
258	MinDelay time.Duration
259
260	// MaxDelay is the maximum amount of time to delay between retries. If unset or set
261	// to zero, DBInstanceAvailableWaiter will use default max delay of 120 seconds.
262	// Note that MaxDelay must resolve to value greater than or equal to the MinDelay.
263	MaxDelay time.Duration
264
265	// LogWaitAttempts is used to enable logging for waiter retry attempts
266	LogWaitAttempts bool
267
268	// Retryable is function that can be used to override the service defined
269	// waiter-behavior based on operation output, or returned error. This function is
270	// used by the waiter to decide if a state is retryable or a terminal state. By
271	// default service-modeled logic will populate this option. This option can thus be
272	// used to define a custom waiter state with fall-back to service-modeled waiter
273	// state mutators.The function returns an error in case of a failure state. In case
274	// of retry state, this function returns a bool value of true and nil error, while
275	// in case of success it returns a bool value of false and nil error.
276	Retryable func(context.Context, *DescribeDBInstancesInput, *DescribeDBInstancesOutput, error) (bool, error)
277}
278
279// DBInstanceAvailableWaiter defines the waiters for DBInstanceAvailable
280type DBInstanceAvailableWaiter struct {
281	client DescribeDBInstancesAPIClient
282
283	options DBInstanceAvailableWaiterOptions
284}
285
286// NewDBInstanceAvailableWaiter constructs a DBInstanceAvailableWaiter.
287func NewDBInstanceAvailableWaiter(client DescribeDBInstancesAPIClient, optFns ...func(*DBInstanceAvailableWaiterOptions)) *DBInstanceAvailableWaiter {
288	options := DBInstanceAvailableWaiterOptions{}
289	options.MinDelay = 30 * time.Second
290	options.MaxDelay = 120 * time.Second
291	options.Retryable = dBInstanceAvailableStateRetryable
292
293	for _, fn := range optFns {
294		fn(&options)
295	}
296	return &DBInstanceAvailableWaiter{
297		client:  client,
298		options: options,
299	}
300}
301
302// Wait calls the waiter function for DBInstanceAvailable waiter. The maxWaitDur is
303// the maximum wait duration the waiter will wait. The maxWaitDur is required and
304// must be greater than zero.
305func (w *DBInstanceAvailableWaiter) Wait(ctx context.Context, params *DescribeDBInstancesInput, maxWaitDur time.Duration, optFns ...func(*DBInstanceAvailableWaiterOptions)) error {
306	if maxWaitDur <= 0 {
307		return fmt.Errorf("maximum wait time for waiter must be greater than zero")
308	}
309
310	options := w.options
311	for _, fn := range optFns {
312		fn(&options)
313	}
314
315	if options.MaxDelay <= 0 {
316		options.MaxDelay = 120 * time.Second
317	}
318
319	if options.MinDelay > options.MaxDelay {
320		return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay)
321	}
322
323	ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur)
324	defer cancelFn()
325
326	logger := smithywaiter.Logger{}
327	remainingTime := maxWaitDur
328
329	var attempt int64
330	for {
331
332		attempt++
333		apiOptions := options.APIOptions
334		start := time.Now()
335
336		if options.LogWaitAttempts {
337			logger.Attempt = attempt
338			apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...)
339			apiOptions = append(apiOptions, logger.AddLogger)
340		}
341
342		out, err := w.client.DescribeDBInstances(ctx, params, func(o *Options) {
343			o.APIOptions = append(o.APIOptions, apiOptions...)
344		})
345
346		retryable, err := options.Retryable(ctx, params, out, err)
347		if err != nil {
348			return err
349		}
350		if !retryable {
351			return nil
352		}
353
354		remainingTime -= time.Since(start)
355		if remainingTime < options.MinDelay || remainingTime <= 0 {
356			break
357		}
358
359		// compute exponential backoff between waiter retries
360		delay, err := smithywaiter.ComputeDelay(
361			attempt, options.MinDelay, options.MaxDelay, remainingTime,
362		)
363		if err != nil {
364			return fmt.Errorf("error computing waiter delay, %w", err)
365		}
366
367		remainingTime -= delay
368		// sleep for the delay amount before invoking a request
369		if err := smithytime.SleepWithContext(ctx, delay); err != nil {
370			return fmt.Errorf("request cancelled while waiting, %w", err)
371		}
372	}
373	return fmt.Errorf("exceeded max wait time for DBInstanceAvailable waiter")
374}
375
376func dBInstanceAvailableStateRetryable(ctx context.Context, input *DescribeDBInstancesInput, output *DescribeDBInstancesOutput, err error) (bool, error) {
377
378	if err == nil {
379		pathValue, err := jmespath.Search("DBInstances[].DBInstanceStatus", output)
380		if err != nil {
381			return false, fmt.Errorf("error evaluating waiter state: %w", err)
382		}
383
384		expectedValue := "available"
385		var match = true
386		listOfValues, ok := pathValue.([]interface{})
387		if !ok {
388			return false, fmt.Errorf("waiter comparator expected list got %T", pathValue)
389		}
390
391		if len(listOfValues) == 0 {
392			match = false
393		}
394		for _, v := range listOfValues {
395			value, ok := v.(*string)
396			if !ok {
397				return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue)
398			}
399
400			if string(*value) != expectedValue {
401				match = false
402			}
403		}
404
405		if match {
406			return false, nil
407		}
408	}
409
410	if err == nil {
411		pathValue, err := jmespath.Search("DBInstances[].DBInstanceStatus", output)
412		if err != nil {
413			return false, fmt.Errorf("error evaluating waiter state: %w", err)
414		}
415
416		expectedValue := "deleted"
417		listOfValues, ok := pathValue.([]interface{})
418		if !ok {
419			return false, fmt.Errorf("waiter comparator expected list got %T", pathValue)
420		}
421
422		for _, v := range listOfValues {
423			value, ok := v.(*string)
424			if !ok {
425				return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue)
426			}
427
428			if string(*value) == expectedValue {
429				return false, fmt.Errorf("waiter state transitioned to Failure")
430			}
431		}
432	}
433
434	if err == nil {
435		pathValue, err := jmespath.Search("DBInstances[].DBInstanceStatus", output)
436		if err != nil {
437			return false, fmt.Errorf("error evaluating waiter state: %w", err)
438		}
439
440		expectedValue := "deleting"
441		listOfValues, ok := pathValue.([]interface{})
442		if !ok {
443			return false, fmt.Errorf("waiter comparator expected list got %T", pathValue)
444		}
445
446		for _, v := range listOfValues {
447			value, ok := v.(*string)
448			if !ok {
449				return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue)
450			}
451
452			if string(*value) == expectedValue {
453				return false, fmt.Errorf("waiter state transitioned to Failure")
454			}
455		}
456	}
457
458	if err == nil {
459		pathValue, err := jmespath.Search("DBInstances[].DBInstanceStatus", output)
460		if err != nil {
461			return false, fmt.Errorf("error evaluating waiter state: %w", err)
462		}
463
464		expectedValue := "failed"
465		listOfValues, ok := pathValue.([]interface{})
466		if !ok {
467			return false, fmt.Errorf("waiter comparator expected list got %T", pathValue)
468		}
469
470		for _, v := range listOfValues {
471			value, ok := v.(*string)
472			if !ok {
473				return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue)
474			}
475
476			if string(*value) == expectedValue {
477				return false, fmt.Errorf("waiter state transitioned to Failure")
478			}
479		}
480	}
481
482	if err == nil {
483		pathValue, err := jmespath.Search("DBInstances[].DBInstanceStatus", output)
484		if err != nil {
485			return false, fmt.Errorf("error evaluating waiter state: %w", err)
486		}
487
488		expectedValue := "incompatible-restore"
489		listOfValues, ok := pathValue.([]interface{})
490		if !ok {
491			return false, fmt.Errorf("waiter comparator expected list got %T", pathValue)
492		}
493
494		for _, v := range listOfValues {
495			value, ok := v.(*string)
496			if !ok {
497				return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue)
498			}
499
500			if string(*value) == expectedValue {
501				return false, fmt.Errorf("waiter state transitioned to Failure")
502			}
503		}
504	}
505
506	if err == nil {
507		pathValue, err := jmespath.Search("DBInstances[].DBInstanceStatus", output)
508		if err != nil {
509			return false, fmt.Errorf("error evaluating waiter state: %w", err)
510		}
511
512		expectedValue := "incompatible-parameters"
513		listOfValues, ok := pathValue.([]interface{})
514		if !ok {
515			return false, fmt.Errorf("waiter comparator expected list got %T", pathValue)
516		}
517
518		for _, v := range listOfValues {
519			value, ok := v.(*string)
520			if !ok {
521				return false, fmt.Errorf("waiter comparator expected *string value, got %T", pathValue)
522			}
523
524			if string(*value) == expectedValue {
525				return false, fmt.Errorf("waiter state transitioned to Failure")
526			}
527		}
528	}
529
530	return true, nil
531}
532
533func newServiceMetadataMiddleware_opDescribeDBInstances(region string) *awsmiddleware.RegisterServiceMetadata {
534	return &awsmiddleware.RegisterServiceMetadata{
535		Region:        region,
536		ServiceID:     ServiceID,
537		SigningName:   "rds",
538		OperationName: "DescribeDBInstances",
539	}
540}
541