1
2
3 package ecr
4
5 import (
6 "context"
7 "errors"
8 "fmt"
9 "github.com/aws/aws-sdk-go-v2/aws"
10 awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
11 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
12 internalauth "github.com/aws/aws-sdk-go-v2/internal/auth"
13 "github.com/aws/aws-sdk-go-v2/service/ecr/types"
14 smithyendpoints "github.com/aws/smithy-go/endpoints"
15 "github.com/aws/smithy-go/middleware"
16 smithytime "github.com/aws/smithy-go/time"
17 smithyhttp "github.com/aws/smithy-go/transport/http"
18 smithywaiter "github.com/aws/smithy-go/waiter"
19 "github.com/jmespath/go-jmespath"
20 "time"
21 )
22
23
24 func (c *Client) DescribeImageScanFindings(ctx context.Context, params *DescribeImageScanFindingsInput, optFns ...func(*Options)) (*DescribeImageScanFindingsOutput, error) {
25 if params == nil {
26 params = &DescribeImageScanFindingsInput{}
27 }
28
29 result, metadata, err := c.invokeOperation(ctx, "DescribeImageScanFindings", params, optFns, c.addOperationDescribeImageScanFindingsMiddlewares)
30 if err != nil {
31 return nil, err
32 }
33
34 out := result.(*DescribeImageScanFindingsOutput)
35 out.ResultMetadata = metadata
36 return out, nil
37 }
38
39 type DescribeImageScanFindingsInput struct {
40
41
42
43
44 ImageId *types.ImageIdentifier
45
46
47
48
49 RepositoryName *string
50
51
52
53
54
55
56
57
58
59 MaxResults *int32
60
61
62
63
64
65
66 NextToken *string
67
68
69
70
71 RegistryId *string
72
73 noSmithyDocumentSerde
74 }
75
76 type DescribeImageScanFindingsOutput struct {
77
78
79 ImageId *types.ImageIdentifier
80
81
82 ImageScanFindings *types.ImageScanFindings
83
84
85 ImageScanStatus *types.ImageScanStatus
86
87
88
89
90
91 NextToken *string
92
93
94 RegistryId *string
95
96
97 RepositoryName *string
98
99
100 ResultMetadata middleware.Metadata
101
102 noSmithyDocumentSerde
103 }
104
105 func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middleware.Stack, options Options) (err error) {
106 err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeImageScanFindings{}, middleware.After)
107 if err != nil {
108 return err
109 }
110 err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpDescribeImageScanFindings{}, middleware.After)
111 if err != nil {
112 return err
113 }
114 if err = addlegacyEndpointContextSetter(stack, options); err != nil {
115 return err
116 }
117 if err = addSetLoggerMiddleware(stack, options); err != nil {
118 return err
119 }
120 if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
121 return err
122 }
123 if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
124 return err
125 }
126 if err = addResolveEndpointMiddleware(stack, options); err != nil {
127 return err
128 }
129 if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
130 return err
131 }
132 if err = addRetryMiddlewares(stack, options); err != nil {
133 return err
134 }
135 if err = addHTTPSignerV4Middleware(stack, options); err != nil {
136 return err
137 }
138 if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
139 return err
140 }
141 if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
142 return err
143 }
144 if err = addClientUserAgent(stack, options); err != nil {
145 return err
146 }
147 if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
148 return err
149 }
150 if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
151 return err
152 }
153 if err = addDescribeImageScanFindingsResolveEndpointMiddleware(stack, options); err != nil {
154 return err
155 }
156 if err = addOpDescribeImageScanFindingsValidationMiddleware(stack); err != nil {
157 return err
158 }
159 if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImageScanFindings(options.Region), middleware.Before); err != nil {
160 return err
161 }
162 if err = awsmiddleware.AddRecursionDetection(stack); err != nil {
163 return err
164 }
165 if err = addRequestIDRetrieverMiddleware(stack); err != nil {
166 return err
167 }
168 if err = addResponseErrorMiddleware(stack); err != nil {
169 return err
170 }
171 if err = addRequestResponseLogging(stack, options); err != nil {
172 return err
173 }
174 if err = addendpointDisableHTTPSMiddleware(stack, options); err != nil {
175 return err
176 }
177 return nil
178 }
179
180
181
182 type DescribeImageScanFindingsAPIClient interface {
183 DescribeImageScanFindings(context.Context, *DescribeImageScanFindingsInput, ...func(*Options)) (*DescribeImageScanFindingsOutput, error)
184 }
185
186 var _ DescribeImageScanFindingsAPIClient = (*Client)(nil)
187
188
189
190 type DescribeImageScanFindingsPaginatorOptions struct {
191
192
193
194
195
196
197
198
199 Limit int32
200
201
202
203 StopOnDuplicateToken bool
204 }
205
206
207 type DescribeImageScanFindingsPaginator struct {
208 options DescribeImageScanFindingsPaginatorOptions
209 client DescribeImageScanFindingsAPIClient
210 params *DescribeImageScanFindingsInput
211 nextToken *string
212 firstPage bool
213 }
214
215
216
217 func NewDescribeImageScanFindingsPaginator(client DescribeImageScanFindingsAPIClient, params *DescribeImageScanFindingsInput, optFns ...func(*DescribeImageScanFindingsPaginatorOptions)) *DescribeImageScanFindingsPaginator {
218 if params == nil {
219 params = &DescribeImageScanFindingsInput{}
220 }
221
222 options := DescribeImageScanFindingsPaginatorOptions{}
223 if params.MaxResults != nil {
224 options.Limit = *params.MaxResults
225 }
226
227 for _, fn := range optFns {
228 fn(&options)
229 }
230
231 return &DescribeImageScanFindingsPaginator{
232 options: options,
233 client: client,
234 params: params,
235 firstPage: true,
236 nextToken: params.NextToken,
237 }
238 }
239
240
241 func (p *DescribeImageScanFindingsPaginator) HasMorePages() bool {
242 return p.firstPage || (p.nextToken != nil && len(*p.nextToken) != 0)
243 }
244
245
246 func (p *DescribeImageScanFindingsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeImageScanFindingsOutput, error) {
247 if !p.HasMorePages() {
248 return nil, fmt.Errorf("no more pages available")
249 }
250
251 params := *p.params
252 params.NextToken = p.nextToken
253
254 var limit *int32
255 if p.options.Limit > 0 {
256 limit = &p.options.Limit
257 }
258 params.MaxResults = limit
259
260 result, err := p.client.DescribeImageScanFindings(ctx, ¶ms, optFns...)
261 if err != nil {
262 return nil, err
263 }
264 p.firstPage = false
265
266 prevToken := p.nextToken
267 p.nextToken = result.NextToken
268
269 if p.options.StopOnDuplicateToken &&
270 prevToken != nil &&
271 p.nextToken != nil &&
272 *prevToken == *p.nextToken {
273 p.nextToken = nil
274 }
275
276 return result, nil
277 }
278
279
280 type ImageScanCompleteWaiterOptions struct {
281
282
283
284
285 APIOptions []func(*middleware.Stack) error
286
287
288
289
290 MinDelay time.Duration
291
292
293
294
295 MaxDelay time.Duration
296
297
298 LogWaitAttempts bool
299
300
301
302
303
304
305
306
307
308 Retryable func(context.Context, *DescribeImageScanFindingsInput, *DescribeImageScanFindingsOutput, error) (bool, error)
309 }
310
311
312 type ImageScanCompleteWaiter struct {
313 client DescribeImageScanFindingsAPIClient
314
315 options ImageScanCompleteWaiterOptions
316 }
317
318
319 func NewImageScanCompleteWaiter(client DescribeImageScanFindingsAPIClient, optFns ...func(*ImageScanCompleteWaiterOptions)) *ImageScanCompleteWaiter {
320 options := ImageScanCompleteWaiterOptions{}
321 options.MinDelay = 5 * time.Second
322 options.MaxDelay = 120 * time.Second
323 options.Retryable = imageScanCompleteStateRetryable
324
325 for _, fn := range optFns {
326 fn(&options)
327 }
328 return &ImageScanCompleteWaiter{
329 client: client,
330 options: options,
331 }
332 }
333
334
335
336
337 func (w *ImageScanCompleteWaiter) Wait(ctx context.Context, params *DescribeImageScanFindingsInput, maxWaitDur time.Duration, optFns ...func(*ImageScanCompleteWaiterOptions)) error {
338 _, err := w.WaitForOutput(ctx, params, maxWaitDur, optFns...)
339 return err
340 }
341
342
343
344
345
346 func (w *ImageScanCompleteWaiter) WaitForOutput(ctx context.Context, params *DescribeImageScanFindingsInput, maxWaitDur time.Duration, optFns ...func(*ImageScanCompleteWaiterOptions)) (*DescribeImageScanFindingsOutput, error) {
347 if maxWaitDur <= 0 {
348 return nil, fmt.Errorf("maximum wait time for waiter must be greater than zero")
349 }
350
351 options := w.options
352 for _, fn := range optFns {
353 fn(&options)
354 }
355
356 if options.MaxDelay <= 0 {
357 options.MaxDelay = 120 * time.Second
358 }
359
360 if options.MinDelay > options.MaxDelay {
361 return nil, fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay)
362 }
363
364 ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur)
365 defer cancelFn()
366
367 logger := smithywaiter.Logger{}
368 remainingTime := maxWaitDur
369
370 var attempt int64
371 for {
372
373 attempt++
374 apiOptions := options.APIOptions
375 start := time.Now()
376
377 if options.LogWaitAttempts {
378 logger.Attempt = attempt
379 apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...)
380 apiOptions = append(apiOptions, logger.AddLogger)
381 }
382
383 out, err := w.client.DescribeImageScanFindings(ctx, params, func(o *Options) {
384 o.APIOptions = append(o.APIOptions, apiOptions...)
385 })
386
387 retryable, err := options.Retryable(ctx, params, out, err)
388 if err != nil {
389 return nil, err
390 }
391 if !retryable {
392 return out, nil
393 }
394
395 remainingTime -= time.Since(start)
396 if remainingTime < options.MinDelay || remainingTime <= 0 {
397 break
398 }
399
400
401 delay, err := smithywaiter.ComputeDelay(
402 attempt, options.MinDelay, options.MaxDelay, remainingTime,
403 )
404 if err != nil {
405 return nil, fmt.Errorf("error computing waiter delay, %w", err)
406 }
407
408 remainingTime -= delay
409
410 if err := smithytime.SleepWithContext(ctx, delay); err != nil {
411 return nil, fmt.Errorf("request cancelled while waiting, %w", err)
412 }
413 }
414 return nil, fmt.Errorf("exceeded max wait time for ImageScanComplete waiter")
415 }
416
417 func imageScanCompleteStateRetryable(ctx context.Context, input *DescribeImageScanFindingsInput, output *DescribeImageScanFindingsOutput, err error) (bool, error) {
418
419 if err == nil {
420 pathValue, err := jmespath.Search("imageScanStatus.status", output)
421 if err != nil {
422 return false, fmt.Errorf("error evaluating waiter state: %w", err)
423 }
424
425 expectedValue := "COMPLETE"
426 value, ok := pathValue.(types.ScanStatus)
427 if !ok {
428 return false, fmt.Errorf("waiter comparator expected types.ScanStatus value, got %T", pathValue)
429 }
430
431 if string(value) == expectedValue {
432 return false, nil
433 }
434 }
435
436 if err == nil {
437 pathValue, err := jmespath.Search("imageScanStatus.status", output)
438 if err != nil {
439 return false, fmt.Errorf("error evaluating waiter state: %w", err)
440 }
441
442 expectedValue := "FAILED"
443 value, ok := pathValue.(types.ScanStatus)
444 if !ok {
445 return false, fmt.Errorf("waiter comparator expected types.ScanStatus value, got %T", pathValue)
446 }
447
448 if string(value) == expectedValue {
449 return false, fmt.Errorf("waiter state transitioned to Failure")
450 }
451 }
452
453 return true, nil
454 }
455
456 func newServiceMetadataMiddleware_opDescribeImageScanFindings(region string) *awsmiddleware.RegisterServiceMetadata {
457 return &awsmiddleware.RegisterServiceMetadata{
458 Region: region,
459 ServiceID: ServiceID,
460 SigningName: "ecr",
461 OperationName: "DescribeImageScanFindings",
462 }
463 }
464
465 type opDescribeImageScanFindingsResolveEndpointMiddleware struct {
466 EndpointResolver EndpointResolverV2
467 BuiltInResolver builtInParameterResolver
468 }
469
470 func (*opDescribeImageScanFindingsResolveEndpointMiddleware) ID() string {
471 return "ResolveEndpointV2"
472 }
473
474 func (m *opDescribeImageScanFindingsResolveEndpointMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
475 out middleware.SerializeOutput, metadata middleware.Metadata, err error,
476 ) {
477 if awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
478 return next.HandleSerialize(ctx, in)
479 }
480
481 req, ok := in.Request.(*smithyhttp.Request)
482 if !ok {
483 return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
484 }
485
486 if m.EndpointResolver == nil {
487 return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil")
488 }
489
490 params := EndpointParameters{}
491
492 m.BuiltInResolver.ResolveBuiltIns(¶ms)
493
494 var resolvedEndpoint smithyendpoints.Endpoint
495 resolvedEndpoint, err = m.EndpointResolver.ResolveEndpoint(ctx, params)
496 if err != nil {
497 return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
498 }
499
500 req.URL = &resolvedEndpoint.URI
501
502 for k := range resolvedEndpoint.Headers {
503 req.Header.Set(
504 k,
505 resolvedEndpoint.Headers.Get(k),
506 )
507 }
508
509 authSchemes, err := internalauth.GetAuthenticationSchemes(&resolvedEndpoint.Properties)
510 if err != nil {
511 var nfe *internalauth.NoAuthenticationSchemesFoundError
512 if errors.As(err, &nfe) {
513
514 signingName := "ecr"
515 signingRegion := m.BuiltInResolver.(*builtInResolver).Region
516 ctx = awsmiddleware.SetSigningName(ctx, signingName)
517 ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion)
518
519 }
520 var ue *internalauth.UnSupportedAuthenticationSchemeSpecifiedError
521 if errors.As(err, &ue) {
522 return out, metadata, fmt.Errorf(
523 "This operation requests signer version(s) %v but the client only supports %v",
524 ue.UnsupportedSchemes,
525 internalauth.SupportedSchemes,
526 )
527 }
528 }
529
530 for _, authScheme := range authSchemes {
531 switch authScheme.(type) {
532 case *internalauth.AuthenticationSchemeV4:
533 v4Scheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4)
534 var signingName, signingRegion string
535 if v4Scheme.SigningName == nil {
536 signingName = "ecr"
537 } else {
538 signingName = *v4Scheme.SigningName
539 }
540 if v4Scheme.SigningRegion == nil {
541 signingRegion = m.BuiltInResolver.(*builtInResolver).Region
542 } else {
543 signingRegion = *v4Scheme.SigningRegion
544 }
545 if v4Scheme.DisableDoubleEncoding != nil {
546
547
548
549 ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4Scheme.DisableDoubleEncoding)
550 }
551 ctx = awsmiddleware.SetSigningName(ctx, signingName)
552 ctx = awsmiddleware.SetSigningRegion(ctx, signingRegion)
553 break
554 case *internalauth.AuthenticationSchemeV4A:
555 v4aScheme, _ := authScheme.(*internalauth.AuthenticationSchemeV4A)
556 if v4aScheme.SigningName == nil {
557 v4aScheme.SigningName = aws.String("ecr")
558 }
559 if v4aScheme.DisableDoubleEncoding != nil {
560
561
562
563 ctx = internalauth.SetDisableDoubleEncoding(ctx, *v4aScheme.DisableDoubleEncoding)
564 }
565 ctx = awsmiddleware.SetSigningName(ctx, *v4aScheme.SigningName)
566 ctx = awsmiddleware.SetSigningRegion(ctx, v4aScheme.SigningRegionSet[0])
567 break
568 case *internalauth.AuthenticationSchemeNone:
569 break
570 }
571 }
572
573 return next.HandleSerialize(ctx, in)
574 }
575
576 func addDescribeImageScanFindingsResolveEndpointMiddleware(stack *middleware.Stack, options Options) error {
577 return stack.Serialize.Insert(&opDescribeImageScanFindingsResolveEndpointMiddleware{
578 EndpointResolver: options.EndpointResolverV2,
579 BuiltInResolver: &builtInResolver{
580 Region: options.Region,
581 UseDualStack: options.EndpointOptions.UseDualStackEndpoint,
582 UseFIPS: options.EndpointOptions.UseFIPSEndpoint,
583 Endpoint: options.BaseEndpoint,
584 },
585 }, "ResolveEndpoint", middleware.After)
586 }
587
View as plain text