1// Code generated by smithy-go-codegen DO NOT EDIT.
2
3package iam
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/iam/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	"time"
17)
18
19// Retrieves information about the specified instance profile, including the
20// instance profile's path, GUID, ARN, and role. For more information about
21// instance profiles, see About Instance Profiles
22// (https://docs.aws.amazon.com/IAM/latest/UserGuide/AboutInstanceProfiles.html) in
23// the IAM User Guide.
24func (c *Client) GetInstanceProfile(ctx context.Context, params *GetInstanceProfileInput, optFns ...func(*Options)) (*GetInstanceProfileOutput, error) {
25	if params == nil {
26		params = &GetInstanceProfileInput{}
27	}
28
29	result, metadata, err := c.invokeOperation(ctx, "GetInstanceProfile", params, optFns, addOperationGetInstanceProfileMiddlewares)
30	if err != nil {
31		return nil, err
32	}
33
34	out := result.(*GetInstanceProfileOutput)
35	out.ResultMetadata = metadata
36	return out, nil
37}
38
39type GetInstanceProfileInput struct {
40
41	// The name of the instance profile to get information about. This parameter allows
42	// (through its regex pattern (http://wikipedia.org/wiki/regex)) a string of
43	// characters consisting of upper and lowercase alphanumeric characters with no
44	// spaces. You can also include any of the following characters: _+=,.@-
45	//
46	// This member is required.
47	InstanceProfileName *string
48}
49
50// Contains the response to a successful GetInstanceProfile request.
51type GetInstanceProfileOutput struct {
52
53	// A structure containing details about the instance profile.
54	//
55	// This member is required.
56	InstanceProfile *types.InstanceProfile
57
58	// Metadata pertaining to the operation's result.
59	ResultMetadata middleware.Metadata
60}
61
62func addOperationGetInstanceProfileMiddlewares(stack *middleware.Stack, options Options) (err error) {
63	err = stack.Serialize.Add(&awsAwsquery_serializeOpGetInstanceProfile{}, middleware.After)
64	if err != nil {
65		return err
66	}
67	err = stack.Deserialize.Add(&awsAwsquery_deserializeOpGetInstanceProfile{}, middleware.After)
68	if err != nil {
69		return err
70	}
71	if err = addSetLoggerMiddleware(stack, options); err != nil {
72		return err
73	}
74	if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
75		return err
76	}
77	if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
78		return err
79	}
80	if err = addResolveEndpointMiddleware(stack, options); err != nil {
81		return err
82	}
83	if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
84		return err
85	}
86	if err = addRetryMiddlewares(stack, options); err != nil {
87		return err
88	}
89	if err = addHTTPSignerV4Middleware(stack, options); err != nil {
90		return err
91	}
92	if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
93		return err
94	}
95	if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
96		return err
97	}
98	if err = addClientUserAgent(stack); err != nil {
99		return err
100	}
101	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
102		return err
103	}
104	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
105		return err
106	}
107	if err = addOpGetInstanceProfileValidationMiddleware(stack); err != nil {
108		return err
109	}
110	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetInstanceProfile(options.Region), middleware.Before); err != nil {
111		return err
112	}
113	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
114		return err
115	}
116	if err = addResponseErrorMiddleware(stack); err != nil {
117		return err
118	}
119	if err = addRequestResponseLogging(stack, options); err != nil {
120		return err
121	}
122	return nil
123}
124
125// GetInstanceProfileAPIClient is a client that implements the GetInstanceProfile
126// operation.
127type GetInstanceProfileAPIClient interface {
128	GetInstanceProfile(context.Context, *GetInstanceProfileInput, ...func(*Options)) (*GetInstanceProfileOutput, error)
129}
130
131var _ GetInstanceProfileAPIClient = (*Client)(nil)
132
133// InstanceProfileExistsWaiterOptions are waiter options for
134// InstanceProfileExistsWaiter
135type InstanceProfileExistsWaiterOptions struct {
136
137	// Set of options to modify how an operation is invoked. These apply to all
138	// operations invoked for this client. Use functional options on operation call to
139	// modify this list for per operation behavior.
140	APIOptions []func(*middleware.Stack) error
141
142	// MinDelay is the minimum amount of time to delay between retries. If unset,
143	// InstanceProfileExistsWaiter will use default minimum delay of 1 seconds. Note
144	// that MinDelay must resolve to a value lesser than or equal to the MaxDelay.
145	MinDelay time.Duration
146
147	// MaxDelay is the maximum amount of time to delay between retries. If unset or set
148	// to zero, InstanceProfileExistsWaiter will use default max delay of 120 seconds.
149	// Note that MaxDelay must resolve to value greater than or equal to the MinDelay.
150	MaxDelay time.Duration
151
152	// LogWaitAttempts is used to enable logging for waiter retry attempts
153	LogWaitAttempts bool
154
155	// Retryable is function that can be used to override the service defined
156	// waiter-behavior based on operation output, or returned error. This function is
157	// used by the waiter to decide if a state is retryable or a terminal state. By
158	// default service-modeled logic will populate this option. This option can thus be
159	// used to define a custom waiter state with fall-back to service-modeled waiter
160	// state mutators.The function returns an error in case of a failure state. In case
161	// of retry state, this function returns a bool value of true and nil error, while
162	// in case of success it returns a bool value of false and nil error.
163	Retryable func(context.Context, *GetInstanceProfileInput, *GetInstanceProfileOutput, error) (bool, error)
164}
165
166// InstanceProfileExistsWaiter defines the waiters for InstanceProfileExists
167type InstanceProfileExistsWaiter struct {
168	client GetInstanceProfileAPIClient
169
170	options InstanceProfileExistsWaiterOptions
171}
172
173// NewInstanceProfileExistsWaiter constructs a InstanceProfileExistsWaiter.
174func NewInstanceProfileExistsWaiter(client GetInstanceProfileAPIClient, optFns ...func(*InstanceProfileExistsWaiterOptions)) *InstanceProfileExistsWaiter {
175	options := InstanceProfileExistsWaiterOptions{}
176	options.MinDelay = 1 * time.Second
177	options.MaxDelay = 120 * time.Second
178	options.Retryable = instanceProfileExistsStateRetryable
179
180	for _, fn := range optFns {
181		fn(&options)
182	}
183	return &InstanceProfileExistsWaiter{
184		client:  client,
185		options: options,
186	}
187}
188
189// Wait calls the waiter function for InstanceProfileExists waiter. The maxWaitDur
190// is the maximum wait duration the waiter will wait. The maxWaitDur is required
191// and must be greater than zero.
192func (w *InstanceProfileExistsWaiter) Wait(ctx context.Context, params *GetInstanceProfileInput, maxWaitDur time.Duration, optFns ...func(*InstanceProfileExistsWaiterOptions)) error {
193	if maxWaitDur <= 0 {
194		return fmt.Errorf("maximum wait time for waiter must be greater than zero")
195	}
196
197	options := w.options
198	for _, fn := range optFns {
199		fn(&options)
200	}
201
202	if options.MaxDelay <= 0 {
203		options.MaxDelay = 120 * time.Second
204	}
205
206	if options.MinDelay > options.MaxDelay {
207		return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay)
208	}
209
210	ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur)
211	defer cancelFn()
212
213	logger := smithywaiter.Logger{}
214	remainingTime := maxWaitDur
215
216	var attempt int64
217	for {
218
219		attempt++
220		apiOptions := options.APIOptions
221		start := time.Now()
222
223		if options.LogWaitAttempts {
224			logger.Attempt = attempt
225			apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...)
226			apiOptions = append(apiOptions, logger.AddLogger)
227		}
228
229		out, err := w.client.GetInstanceProfile(ctx, params, func(o *Options) {
230			o.APIOptions = append(o.APIOptions, apiOptions...)
231		})
232
233		retryable, err := options.Retryable(ctx, params, out, err)
234		if err != nil {
235			return err
236		}
237		if !retryable {
238			return nil
239		}
240
241		remainingTime -= time.Since(start)
242		if remainingTime < options.MinDelay || remainingTime <= 0 {
243			break
244		}
245
246		// compute exponential backoff between waiter retries
247		delay, err := smithywaiter.ComputeDelay(
248			attempt, options.MinDelay, options.MaxDelay, remainingTime,
249		)
250		if err != nil {
251			return fmt.Errorf("error computing waiter delay, %w", err)
252		}
253
254		remainingTime -= delay
255		// sleep for the delay amount before invoking a request
256		if err := smithytime.SleepWithContext(ctx, delay); err != nil {
257			return fmt.Errorf("request cancelled while waiting, %w", err)
258		}
259	}
260	return fmt.Errorf("exceeded max wait time for InstanceProfileExists waiter")
261}
262
263func instanceProfileExistsStateRetryable(ctx context.Context, input *GetInstanceProfileInput, output *GetInstanceProfileOutput, err error) (bool, error) {
264
265	if err == nil {
266		return false, nil
267	}
268
269	if err != nil {
270		var errorType *types.NoSuchEntityException
271		if errors.As(err, &errorType) {
272			return true, nil
273		}
274	}
275
276	return true, nil
277}
278
279func newServiceMetadataMiddleware_opGetInstanceProfile(region string) *awsmiddleware.RegisterServiceMetadata {
280	return &awsmiddleware.RegisterServiceMetadata{
281		Region:        region,
282		ServiceID:     ServiceID,
283		SigningName:   "iam",
284		OperationName: "GetInstanceProfile",
285	}
286}
287