1// Code generated by smithy-go-codegen DO NOT EDIT. 2 3package ec2 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/ec2/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// Describes the specified EBS snapshots available to you or all of the EBS 20// snapshots available to you. The snapshots available to you include public 21// snapshots, private snapshots that you own, and private snapshots owned by other 22// AWS accounts for which you have explicit create volume permissions. The create 23// volume permissions fall into the following categories: 24// 25// * public: The owner of 26// the snapshot granted create volume permissions for the snapshot to the all 27// group. All AWS accounts have create volume permissions for these snapshots. 28// 29// * 30// explicit: The owner of the snapshot granted create volume permissions to a 31// specific AWS account. 32// 33// * implicit: An AWS account has implicit create volume 34// permissions for all snapshots it owns. 35// 36// The list of snapshots returned can be 37// filtered by specifying snapshot IDs, snapshot owners, or AWS accounts with 38// create volume permissions. If no options are specified, Amazon EC2 returns all 39// snapshots for which you have create volume permissions. If you specify one or 40// more snapshot IDs, only snapshots that have the specified IDs are returned. If 41// you specify an invalid snapshot ID, an error is returned. If you specify a 42// snapshot ID for which you do not have access, it is not included in the returned 43// results. If you specify one or more snapshot owners using the OwnerIds option, 44// only snapshots from the specified owners and for which you have access are 45// returned. The results can include the AWS account IDs of the specified owners, 46// amazon for snapshots owned by Amazon, or self for snapshots that you own. If you 47// specify a list of restorable users, only snapshots with create snapshot 48// permissions for those users are returned. You can specify AWS account IDs (if 49// you own the snapshots), self for snapshots for which you own or have explicit 50// permissions, or all for public snapshots. If you are describing a long list of 51// snapshots, we recommend that you paginate the output to make the list more 52// manageable. The MaxResults parameter sets the maximum number of results returned 53// in a single page. If the list of results exceeds your MaxResults value, then 54// that number of results is returned along with a NextToken value that can be 55// passed to a subsequent DescribeSnapshots request to retrieve the remaining 56// results. To get the state of fast snapshot restores for a snapshot, use 57// DescribeFastSnapshotRestores. For more information about EBS snapshots, see 58// Amazon EBS snapshots 59// (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSSnapshots.html) in the 60// Amazon Elastic Compute Cloud User Guide. 61func (c *Client) DescribeSnapshots(ctx context.Context, params *DescribeSnapshotsInput, optFns ...func(*Options)) (*DescribeSnapshotsOutput, error) { 62 if params == nil { 63 params = &DescribeSnapshotsInput{} 64 } 65 66 result, metadata, err := c.invokeOperation(ctx, "DescribeSnapshots", params, optFns, addOperationDescribeSnapshotsMiddlewares) 67 if err != nil { 68 return nil, err 69 } 70 71 out := result.(*DescribeSnapshotsOutput) 72 out.ResultMetadata = metadata 73 return out, nil 74} 75 76type DescribeSnapshotsInput struct { 77 78 // Checks whether you have the required permissions for the action, without 79 // actually making the request, and provides an error response. If you have the 80 // required permissions, the error response is DryRunOperation. Otherwise, it is 81 // UnauthorizedOperation. 82 DryRun bool 83 84 // The filters. 85 // 86 // * description - A description of the snapshot. 87 // 88 // * encrypted - 89 // Indicates whether the snapshot is encrypted (true | false) 90 // 91 // * owner-alias - The 92 // owner alias, from an Amazon-maintained list (amazon). This is not the 93 // user-configured AWS account alias set using the IAM console. We recommend that 94 // you use the related parameter instead of this filter. 95 // 96 // * owner-id - The AWS 97 // account ID of the owner. We recommend that you use the related parameter instead 98 // of this filter. 99 // 100 // * progress - The progress of the snapshot, as a percentage (for 101 // example, 80%). 102 // 103 // * snapshot-id - The snapshot ID. 104 // 105 // * start-time - The time stamp 106 // when the snapshot was initiated. 107 // 108 // * status - The status of the snapshot (pending 109 // | completed | error). 110 // 111 // * tag: - The key/value combination of a tag assigned to 112 // the resource. Use the tag key in the filter name and the tag value as the filter 113 // value. For example, to find all resources that have a tag with the key Owner and 114 // the value TeamA, specify tag:Owner for the filter name and TeamA for the filter 115 // value. 116 // 117 // * tag-key - The key of a tag assigned to the resource. Use this filter 118 // to find all resources assigned a tag with a specific key, regardless of the tag 119 // value. 120 // 121 // * volume-id - The ID of the volume the snapshot is for. 122 // 123 // * volume-size - 124 // The size of the volume, in GiB. 125 Filters []types.Filter 126 127 // The maximum number of snapshot results returned by DescribeSnapshots in 128 // paginated output. When this parameter is used, DescribeSnapshots only returns 129 // MaxResults results in a single page along with a NextToken response element. The 130 // remaining results of the initial request can be seen by sending another 131 // DescribeSnapshots request with the returned NextToken value. This value can be 132 // between 5 and 1,000; if MaxResults is given a value larger than 1,000, only 133 // 1,000 results are returned. If this parameter is not used, then 134 // DescribeSnapshots returns all results. You cannot specify this parameter and the 135 // snapshot IDs parameter in the same request. 136 MaxResults int32 137 138 // The NextToken value returned from a previous paginated DescribeSnapshots request 139 // where MaxResults was used and the results exceeded the value of that parameter. 140 // Pagination continues from the end of the previous results that returned the 141 // NextToken value. This value is null when there are no more results to return. 142 NextToken *string 143 144 // Scopes the results to snapshots with the specified owners. You can specify a 145 // combination of AWS account IDs, self, and amazon. 146 OwnerIds []string 147 148 // The IDs of the AWS accounts that can create volumes from the snapshot. 149 RestorableByUserIds []string 150 151 // The snapshot IDs. Default: Describes the snapshots for which you have create 152 // volume permissions. 153 SnapshotIds []string 154} 155 156type DescribeSnapshotsOutput struct { 157 158 // The NextToken value to include in a future DescribeSnapshots request. When the 159 // results of a DescribeSnapshots request exceed MaxResults, this value can be used 160 // to retrieve the next page of results. This value is null when there are no more 161 // results to return. 162 NextToken *string 163 164 // Information about the snapshots. 165 Snapshots []types.Snapshot 166 167 // Metadata pertaining to the operation's result. 168 ResultMetadata middleware.Metadata 169} 170 171func addOperationDescribeSnapshotsMiddlewares(stack *middleware.Stack, options Options) (err error) { 172 err = stack.Serialize.Add(&awsEc2query_serializeOpDescribeSnapshots{}, middleware.After) 173 if err != nil { 174 return err 175 } 176 err = stack.Deserialize.Add(&awsEc2query_deserializeOpDescribeSnapshots{}, middleware.After) 177 if err != nil { 178 return err 179 } 180 if err = addSetLoggerMiddleware(stack, options); err != nil { 181 return err 182 } 183 if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { 184 return err 185 } 186 if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { 187 return err 188 } 189 if err = addResolveEndpointMiddleware(stack, options); err != nil { 190 return err 191 } 192 if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { 193 return err 194 } 195 if err = addRetryMiddlewares(stack, options); err != nil { 196 return err 197 } 198 if err = addHTTPSignerV4Middleware(stack, options); err != nil { 199 return err 200 } 201 if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { 202 return err 203 } 204 if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { 205 return err 206 } 207 if err = addClientUserAgent(stack); err != nil { 208 return err 209 } 210 if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { 211 return err 212 } 213 if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { 214 return err 215 } 216 if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeSnapshots(options.Region), middleware.Before); err != nil { 217 return err 218 } 219 if err = addRequestIDRetrieverMiddleware(stack); err != nil { 220 return err 221 } 222 if err = addResponseErrorMiddleware(stack); err != nil { 223 return err 224 } 225 if err = addRequestResponseLogging(stack, options); err != nil { 226 return err 227 } 228 return nil 229} 230 231// DescribeSnapshotsAPIClient is a client that implements the DescribeSnapshots 232// operation. 233type DescribeSnapshotsAPIClient interface { 234 DescribeSnapshots(context.Context, *DescribeSnapshotsInput, ...func(*Options)) (*DescribeSnapshotsOutput, error) 235} 236 237var _ DescribeSnapshotsAPIClient = (*Client)(nil) 238 239// DescribeSnapshotsPaginatorOptions is the paginator options for DescribeSnapshots 240type DescribeSnapshotsPaginatorOptions struct { 241 // The maximum number of snapshot results returned by DescribeSnapshots in 242 // paginated output. When this parameter is used, DescribeSnapshots only returns 243 // MaxResults results in a single page along with a NextToken response element. The 244 // remaining results of the initial request can be seen by sending another 245 // DescribeSnapshots request with the returned NextToken value. This value can be 246 // between 5 and 1,000; if MaxResults is given a value larger than 1,000, only 247 // 1,000 results are returned. If this parameter is not used, then 248 // DescribeSnapshots returns all results. You cannot specify this parameter and the 249 // snapshot IDs parameter in the same request. 250 Limit int32 251 252 // Set to true if pagination should stop if the service returns a pagination token 253 // that matches the most recent token provided to the service. 254 StopOnDuplicateToken bool 255} 256 257// DescribeSnapshotsPaginator is a paginator for DescribeSnapshots 258type DescribeSnapshotsPaginator struct { 259 options DescribeSnapshotsPaginatorOptions 260 client DescribeSnapshotsAPIClient 261 params *DescribeSnapshotsInput 262 nextToken *string 263 firstPage bool 264} 265 266// NewDescribeSnapshotsPaginator returns a new DescribeSnapshotsPaginator 267func NewDescribeSnapshotsPaginator(client DescribeSnapshotsAPIClient, params *DescribeSnapshotsInput, optFns ...func(*DescribeSnapshotsPaginatorOptions)) *DescribeSnapshotsPaginator { 268 options := DescribeSnapshotsPaginatorOptions{} 269 if params.MaxResults != 0 { 270 options.Limit = params.MaxResults 271 } 272 273 for _, fn := range optFns { 274 fn(&options) 275 } 276 277 if params == nil { 278 params = &DescribeSnapshotsInput{} 279 } 280 281 return &DescribeSnapshotsPaginator{ 282 options: options, 283 client: client, 284 params: params, 285 firstPage: true, 286 } 287} 288 289// HasMorePages returns a boolean indicating whether more pages are available 290func (p *DescribeSnapshotsPaginator) HasMorePages() bool { 291 return p.firstPage || p.nextToken != nil 292} 293 294// NextPage retrieves the next DescribeSnapshots page. 295func (p *DescribeSnapshotsPaginator) NextPage(ctx context.Context, optFns ...func(*Options)) (*DescribeSnapshotsOutput, error) { 296 if !p.HasMorePages() { 297 return nil, fmt.Errorf("no more pages available") 298 } 299 300 params := *p.params 301 params.NextToken = p.nextToken 302 303 params.MaxResults = p.options.Limit 304 305 result, err := p.client.DescribeSnapshots(ctx, ¶ms, optFns...) 306 if err != nil { 307 return nil, err 308 } 309 p.firstPage = false 310 311 prevToken := p.nextToken 312 p.nextToken = result.NextToken 313 314 if p.options.StopOnDuplicateToken && prevToken != nil && p.nextToken != nil && *prevToken == *p.nextToken { 315 p.nextToken = nil 316 } 317 318 return result, nil 319} 320 321// SnapshotCompletedWaiterOptions are waiter options for SnapshotCompletedWaiter 322type SnapshotCompletedWaiterOptions struct { 323 324 // Set of options to modify how an operation is invoked. These apply to all 325 // operations invoked for this client. Use functional options on operation call to 326 // modify this list for per operation behavior. 327 APIOptions []func(*middleware.Stack) error 328 329 // MinDelay is the minimum amount of time to delay between retries. If unset, 330 // SnapshotCompletedWaiter will use default minimum delay of 15 seconds. Note that 331 // MinDelay must resolve to a value lesser than or equal to the MaxDelay. 332 MinDelay time.Duration 333 334 // MaxDelay is the maximum amount of time to delay between retries. If unset or set 335 // to zero, SnapshotCompletedWaiter will use default max delay of 120 seconds. Note 336 // that MaxDelay must resolve to value greater than or equal to the MinDelay. 337 MaxDelay time.Duration 338 339 // LogWaitAttempts is used to enable logging for waiter retry attempts 340 LogWaitAttempts bool 341 342 // Retryable is function that can be used to override the service defined 343 // waiter-behavior based on operation output, or returned error. This function is 344 // used by the waiter to decide if a state is retryable or a terminal state. By 345 // default service-modeled logic will populate this option. This option can thus be 346 // used to define a custom waiter state with fall-back to service-modeled waiter 347 // state mutators.The function returns an error in case of a failure state. In case 348 // of retry state, this function returns a bool value of true and nil error, while 349 // in case of success it returns a bool value of false and nil error. 350 Retryable func(context.Context, *DescribeSnapshotsInput, *DescribeSnapshotsOutput, error) (bool, error) 351} 352 353// SnapshotCompletedWaiter defines the waiters for SnapshotCompleted 354type SnapshotCompletedWaiter struct { 355 client DescribeSnapshotsAPIClient 356 357 options SnapshotCompletedWaiterOptions 358} 359 360// NewSnapshotCompletedWaiter constructs a SnapshotCompletedWaiter. 361func NewSnapshotCompletedWaiter(client DescribeSnapshotsAPIClient, optFns ...func(*SnapshotCompletedWaiterOptions)) *SnapshotCompletedWaiter { 362 options := SnapshotCompletedWaiterOptions{} 363 options.MinDelay = 15 * time.Second 364 options.MaxDelay = 120 * time.Second 365 options.Retryable = snapshotCompletedStateRetryable 366 367 for _, fn := range optFns { 368 fn(&options) 369 } 370 return &SnapshotCompletedWaiter{ 371 client: client, 372 options: options, 373 } 374} 375 376// Wait calls the waiter function for SnapshotCompleted waiter. The maxWaitDur is 377// the maximum wait duration the waiter will wait. The maxWaitDur is required and 378// must be greater than zero. 379func (w *SnapshotCompletedWaiter) Wait(ctx context.Context, params *DescribeSnapshotsInput, maxWaitDur time.Duration, optFns ...func(*SnapshotCompletedWaiterOptions)) error { 380 if maxWaitDur <= 0 { 381 return fmt.Errorf("maximum wait time for waiter must be greater than zero") 382 } 383 384 options := w.options 385 for _, fn := range optFns { 386 fn(&options) 387 } 388 389 if options.MaxDelay <= 0 { 390 options.MaxDelay = 120 * time.Second 391 } 392 393 if options.MinDelay > options.MaxDelay { 394 return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay) 395 } 396 397 ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur) 398 defer cancelFn() 399 400 logger := smithywaiter.Logger{} 401 remainingTime := maxWaitDur 402 403 var attempt int64 404 for { 405 406 attempt++ 407 apiOptions := options.APIOptions 408 start := time.Now() 409 410 if options.LogWaitAttempts { 411 logger.Attempt = attempt 412 apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...) 413 apiOptions = append(apiOptions, logger.AddLogger) 414 } 415 416 out, err := w.client.DescribeSnapshots(ctx, params, func(o *Options) { 417 o.APIOptions = append(o.APIOptions, apiOptions...) 418 }) 419 420 retryable, err := options.Retryable(ctx, params, out, err) 421 if err != nil { 422 return err 423 } 424 if !retryable { 425 return nil 426 } 427 428 remainingTime -= time.Since(start) 429 if remainingTime < options.MinDelay || remainingTime <= 0 { 430 break 431 } 432 433 // compute exponential backoff between waiter retries 434 delay, err := smithywaiter.ComputeDelay( 435 attempt, options.MinDelay, options.MaxDelay, remainingTime, 436 ) 437 if err != nil { 438 return fmt.Errorf("error computing waiter delay, %w", err) 439 } 440 441 remainingTime -= delay 442 // sleep for the delay amount before invoking a request 443 if err := smithytime.SleepWithContext(ctx, delay); err != nil { 444 return fmt.Errorf("request cancelled while waiting, %w", err) 445 } 446 } 447 return fmt.Errorf("exceeded max wait time for SnapshotCompleted waiter") 448} 449 450func snapshotCompletedStateRetryable(ctx context.Context, input *DescribeSnapshotsInput, output *DescribeSnapshotsOutput, err error) (bool, error) { 451 452 if err == nil { 453 pathValue, err := jmespath.Search("Snapshots[].State", output) 454 if err != nil { 455 return false, fmt.Errorf("error evaluating waiter state: %w", err) 456 } 457 458 expectedValue := "completed" 459 var match = true 460 listOfValues, ok := pathValue.([]interface{}) 461 if !ok { 462 return false, fmt.Errorf("waiter comparator expected list got %T", pathValue) 463 } 464 465 if len(listOfValues) == 0 { 466 match = false 467 } 468 for _, v := range listOfValues { 469 value, ok := v.(types.SnapshotState) 470 if !ok { 471 return false, fmt.Errorf("waiter comparator expected types.SnapshotState value, got %T", pathValue) 472 } 473 474 if string(value) != expectedValue { 475 match = false 476 } 477 } 478 479 if match { 480 return false, nil 481 } 482 } 483 484 return true, nil 485} 486 487func newServiceMetadataMiddleware_opDescribeSnapshots(region string) *awsmiddleware.RegisterServiceMetadata { 488 return &awsmiddleware.RegisterServiceMetadata{ 489 Region: region, 490 ServiceID: ServiceID, 491 SigningName: "ec2", 492 OperationName: "DescribeSnapshots", 493 } 494} 495