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