// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.

package ecr

import (
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awsutil"
	"github.com/aws/aws-sdk-go/aws/request"
	"github.com/aws/aws-sdk-go/private/protocol"
	"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
)

const opBatchCheckLayerAvailability = "BatchCheckLayerAvailability"

// BatchCheckLayerAvailabilityRequest generates a "aws/request.Request" representing the
// client's request for the BatchCheckLayerAvailability operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See BatchCheckLayerAvailability for more information on using the BatchCheckLayerAvailability
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the BatchCheckLayerAvailabilityRequest method.
//    req, resp := client.BatchCheckLayerAvailabilityRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailability
func (c *ECR) BatchCheckLayerAvailabilityRequest(input *BatchCheckLayerAvailabilityInput) (req *request.Request, output *BatchCheckLayerAvailabilityOutput) {
	op := &request.Operation{
		Name:       opBatchCheckLayerAvailability,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &BatchCheckLayerAvailabilityInput{}
	}

	output = &BatchCheckLayerAvailabilityOutput{}
	req = c.newRequest(op, input, output)
	return
}

// BatchCheckLayerAvailability API operation for Amazon EC2 Container Registry.
//
// Check the availability of multiple image layers in a specified registry and
// repository.
//
// This operation is used by the Amazon ECR proxy, and it is not intended for
// general use by customers for pulling and pushing images. In most cases, you
// should use the docker CLI to pull, tag, and push images.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation BatchCheckLayerAvailability for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchCheckLayerAvailability
func (c *ECR) BatchCheckLayerAvailability(input *BatchCheckLayerAvailabilityInput) (*BatchCheckLayerAvailabilityOutput, error) {
	req, out := c.BatchCheckLayerAvailabilityRequest(input)
	return out, req.Send()
}

// BatchCheckLayerAvailabilityWithContext is the same as BatchCheckLayerAvailability with the addition of
// the ability to pass a context and additional request options.
//
// See BatchCheckLayerAvailability for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) BatchCheckLayerAvailabilityWithContext(ctx aws.Context, input *BatchCheckLayerAvailabilityInput, opts ...request.Option) (*BatchCheckLayerAvailabilityOutput, error) {
	req, out := c.BatchCheckLayerAvailabilityRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opBatchDeleteImage = "BatchDeleteImage"

// BatchDeleteImageRequest generates a "aws/request.Request" representing the
// client's request for the BatchDeleteImage operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See BatchDeleteImage for more information on using the BatchDeleteImage
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the BatchDeleteImageRequest method.
//    req, resp := client.BatchDeleteImageRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImage
func (c *ECR) BatchDeleteImageRequest(input *BatchDeleteImageInput) (req *request.Request, output *BatchDeleteImageOutput) {
	op := &request.Operation{
		Name:       opBatchDeleteImage,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &BatchDeleteImageInput{}
	}

	output = &BatchDeleteImageOutput{}
	req = c.newRequest(op, input, output)
	return
}

// BatchDeleteImage API operation for Amazon EC2 Container Registry.
//
// Deletes a list of specified images within a specified repository. Images
// are specified with either imageTag or imageDigest.
//
// You can remove a tag from an image by specifying the image's tag in your
// request. When you remove the last tag from an image, the image is deleted
// from your repository.
//
// You can completely delete an image (and all of its tags) by specifying the
// image's digest in your request.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation BatchDeleteImage for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchDeleteImage
func (c *ECR) BatchDeleteImage(input *BatchDeleteImageInput) (*BatchDeleteImageOutput, error) {
	req, out := c.BatchDeleteImageRequest(input)
	return out, req.Send()
}

// BatchDeleteImageWithContext is the same as BatchDeleteImage with the addition of
// the ability to pass a context and additional request options.
//
// See BatchDeleteImage for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) BatchDeleteImageWithContext(ctx aws.Context, input *BatchDeleteImageInput, opts ...request.Option) (*BatchDeleteImageOutput, error) {
	req, out := c.BatchDeleteImageRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opBatchGetImage = "BatchGetImage"

// BatchGetImageRequest generates a "aws/request.Request" representing the
// client's request for the BatchGetImage operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See BatchGetImage for more information on using the BatchGetImage
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the BatchGetImageRequest method.
//    req, resp := client.BatchGetImageRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImage
func (c *ECR) BatchGetImageRequest(input *BatchGetImageInput) (req *request.Request, output *BatchGetImageOutput) {
	op := &request.Operation{
		Name:       opBatchGetImage,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &BatchGetImageInput{}
	}

	output = &BatchGetImageOutput{}
	req = c.newRequest(op, input, output)
	return
}

// BatchGetImage API operation for Amazon EC2 Container Registry.
//
// Gets detailed information for specified images within a specified repository.
// Images are specified with either imageTag or imageDigest.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation BatchGetImage for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/BatchGetImage
func (c *ECR) BatchGetImage(input *BatchGetImageInput) (*BatchGetImageOutput, error) {
	req, out := c.BatchGetImageRequest(input)
	return out, req.Send()
}

// BatchGetImageWithContext is the same as BatchGetImage with the addition of
// the ability to pass a context and additional request options.
//
// See BatchGetImage for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) BatchGetImageWithContext(ctx aws.Context, input *BatchGetImageInput, opts ...request.Option) (*BatchGetImageOutput, error) {
	req, out := c.BatchGetImageRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCompleteLayerUpload = "CompleteLayerUpload"

// CompleteLayerUploadRequest generates a "aws/request.Request" representing the
// client's request for the CompleteLayerUpload operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CompleteLayerUpload for more information on using the CompleteLayerUpload
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CompleteLayerUploadRequest method.
//    req, resp := client.CompleteLayerUploadRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUpload
func (c *ECR) CompleteLayerUploadRequest(input *CompleteLayerUploadInput) (req *request.Request, output *CompleteLayerUploadOutput) {
	op := &request.Operation{
		Name:       opCompleteLayerUpload,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CompleteLayerUploadInput{}
	}

	output = &CompleteLayerUploadOutput{}
	req = c.newRequest(op, input, output)
	return
}

// CompleteLayerUpload API operation for Amazon EC2 Container Registry.
//
// Informs Amazon ECR that the image layer upload has completed for a specified
// registry, repository name, and upload ID. You can optionally provide a sha256
// digest of the image layer for data validation purposes.
//
// This operation is used by the Amazon ECR proxy, and it is not intended for
// general use by customers for pulling and pushing images. In most cases, you
// should use the docker CLI to pull, tag, and push images.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation CompleteLayerUpload for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeUploadNotFoundException "UploadNotFoundException"
//   The upload could not be found, or the specified upload id is not valid for
//   this repository.
//
//   * ErrCodeInvalidLayerException "InvalidLayerException"
//   The layer digest calculation performed by Amazon ECR upon receipt of the
//   image layer does not match the digest specified.
//
//   * ErrCodeLayerPartTooSmallException "LayerPartTooSmallException"
//   Layer parts must be at least 5 MiB in size.
//
//   * ErrCodeLayerAlreadyExistsException "LayerAlreadyExistsException"
//   The image layer already exists in the associated repository.
//
//   * ErrCodeEmptyUploadException "EmptyUploadException"
//   The specified layer upload does not contain any layer parts.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CompleteLayerUpload
func (c *ECR) CompleteLayerUpload(input *CompleteLayerUploadInput) (*CompleteLayerUploadOutput, error) {
	req, out := c.CompleteLayerUploadRequest(input)
	return out, req.Send()
}

// CompleteLayerUploadWithContext is the same as CompleteLayerUpload with the addition of
// the ability to pass a context and additional request options.
//
// See CompleteLayerUpload for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) CompleteLayerUploadWithContext(ctx aws.Context, input *CompleteLayerUploadInput, opts ...request.Option) (*CompleteLayerUploadOutput, error) {
	req, out := c.CompleteLayerUploadRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateRepository = "CreateRepository"

// CreateRepositoryRequest generates a "aws/request.Request" representing the
// client's request for the CreateRepository operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateRepository for more information on using the CreateRepository
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateRepositoryRequest method.
//    req, resp := client.CreateRepositoryRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepository
func (c *ECR) CreateRepositoryRequest(input *CreateRepositoryInput) (req *request.Request, output *CreateRepositoryOutput) {
	op := &request.Operation{
		Name:       opCreateRepository,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateRepositoryInput{}
	}

	output = &CreateRepositoryOutput{}
	req = c.newRequest(op, input, output)
	return
}

// CreateRepository API operation for Amazon EC2 Container Registry.
//
// Creates an image repository.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation CreateRepository for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeInvalidTagParameterException "InvalidTagParameterException"
//   An invalid parameter has been specified. Tag keys can have a maximum character
//   length of 128 characters, and tag values can have a maximum length of 256
//   characters.
//
//   * ErrCodeTooManyTagsException "TooManyTagsException"
//   The list of tags on the repository is over the limit. The maximum number
//   of tags that can be applied to a repository is 50.
//
//   * ErrCodeRepositoryAlreadyExistsException "RepositoryAlreadyExistsException"
//   The specified repository already exists in the specified registry.
//
//   * ErrCodeLimitExceededException "LimitExceededException"
//   The operation did not succeed because it would have exceeded a service limit
//   for your account. For more information, see Amazon ECR Default Service Limits
//   (http://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html)
//   in the Amazon Elastic Container Registry User Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/CreateRepository
func (c *ECR) CreateRepository(input *CreateRepositoryInput) (*CreateRepositoryOutput, error) {
	req, out := c.CreateRepositoryRequest(input)
	return out, req.Send()
}

// CreateRepositoryWithContext is the same as CreateRepository with the addition of
// the ability to pass a context and additional request options.
//
// See CreateRepository for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) CreateRepositoryWithContext(ctx aws.Context, input *CreateRepositoryInput, opts ...request.Option) (*CreateRepositoryOutput, error) {
	req, out := c.CreateRepositoryRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteLifecyclePolicy = "DeleteLifecyclePolicy"

// DeleteLifecyclePolicyRequest generates a "aws/request.Request" representing the
// client's request for the DeleteLifecyclePolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteLifecyclePolicy for more information on using the DeleteLifecyclePolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteLifecyclePolicyRequest method.
//    req, resp := client.DeleteLifecyclePolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteLifecyclePolicy
func (c *ECR) DeleteLifecyclePolicyRequest(input *DeleteLifecyclePolicyInput) (req *request.Request, output *DeleteLifecyclePolicyOutput) {
	op := &request.Operation{
		Name:       opDeleteLifecyclePolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteLifecyclePolicyInput{}
	}

	output = &DeleteLifecyclePolicyOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DeleteLifecyclePolicy API operation for Amazon EC2 Container Registry.
//
// Deletes the specified lifecycle policy.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation DeleteLifecyclePolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeLifecyclePolicyNotFoundException "LifecyclePolicyNotFoundException"
//   The lifecycle policy could not be found, and no policy is set to the repository.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteLifecyclePolicy
func (c *ECR) DeleteLifecyclePolicy(input *DeleteLifecyclePolicyInput) (*DeleteLifecyclePolicyOutput, error) {
	req, out := c.DeleteLifecyclePolicyRequest(input)
	return out, req.Send()
}

// DeleteLifecyclePolicyWithContext is the same as DeleteLifecyclePolicy with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteLifecyclePolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) DeleteLifecyclePolicyWithContext(ctx aws.Context, input *DeleteLifecyclePolicyInput, opts ...request.Option) (*DeleteLifecyclePolicyOutput, error) {
	req, out := c.DeleteLifecyclePolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteRepository = "DeleteRepository"

// DeleteRepositoryRequest generates a "aws/request.Request" representing the
// client's request for the DeleteRepository operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteRepository for more information on using the DeleteRepository
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteRepositoryRequest method.
//    req, resp := client.DeleteRepositoryRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepository
func (c *ECR) DeleteRepositoryRequest(input *DeleteRepositoryInput) (req *request.Request, output *DeleteRepositoryOutput) {
	op := &request.Operation{
		Name:       opDeleteRepository,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteRepositoryInput{}
	}

	output = &DeleteRepositoryOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DeleteRepository API operation for Amazon EC2 Container Registry.
//
// Deletes an existing image repository. If a repository contains images, you
// must use the force option to delete it.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation DeleteRepository for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeRepositoryNotEmptyException "RepositoryNotEmptyException"
//   The specified repository contains images. To delete a repository that contains
//   images, you must force the deletion with the force parameter.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepository
func (c *ECR) DeleteRepository(input *DeleteRepositoryInput) (*DeleteRepositoryOutput, error) {
	req, out := c.DeleteRepositoryRequest(input)
	return out, req.Send()
}

// DeleteRepositoryWithContext is the same as DeleteRepository with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteRepository for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) DeleteRepositoryWithContext(ctx aws.Context, input *DeleteRepositoryInput, opts ...request.Option) (*DeleteRepositoryOutput, error) {
	req, out := c.DeleteRepositoryRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteRepositoryPolicy = "DeleteRepositoryPolicy"

// DeleteRepositoryPolicyRequest generates a "aws/request.Request" representing the
// client's request for the DeleteRepositoryPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteRepositoryPolicy for more information on using the DeleteRepositoryPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteRepositoryPolicyRequest method.
//    req, resp := client.DeleteRepositoryPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicy
func (c *ECR) DeleteRepositoryPolicyRequest(input *DeleteRepositoryPolicyInput) (req *request.Request, output *DeleteRepositoryPolicyOutput) {
	op := &request.Operation{
		Name:       opDeleteRepositoryPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteRepositoryPolicyInput{}
	}

	output = &DeleteRepositoryPolicyOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DeleteRepositoryPolicy API operation for Amazon EC2 Container Registry.
//
// Deletes the repository policy from a specified repository.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation DeleteRepositoryPolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeRepositoryPolicyNotFoundException "RepositoryPolicyNotFoundException"
//   The specified repository and registry combination does not have an associated
//   repository policy.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DeleteRepositoryPolicy
func (c *ECR) DeleteRepositoryPolicy(input *DeleteRepositoryPolicyInput) (*DeleteRepositoryPolicyOutput, error) {
	req, out := c.DeleteRepositoryPolicyRequest(input)
	return out, req.Send()
}

// DeleteRepositoryPolicyWithContext is the same as DeleteRepositoryPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteRepositoryPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) DeleteRepositoryPolicyWithContext(ctx aws.Context, input *DeleteRepositoryPolicyInput, opts ...request.Option) (*DeleteRepositoryPolicyOutput, error) {
	req, out := c.DeleteRepositoryPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeImages = "DescribeImages"

// DescribeImagesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeImages operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeImages for more information on using the DescribeImages
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeImagesRequest method.
//    req, resp := client.DescribeImagesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImages
func (c *ECR) DescribeImagesRequest(input *DescribeImagesInput) (req *request.Request, output *DescribeImagesOutput) {
	op := &request.Operation{
		Name:       opDescribeImages,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"nextToken"},
			OutputTokens:    []string{"nextToken"},
			LimitToken:      "maxResults",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeImagesInput{}
	}

	output = &DescribeImagesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeImages API operation for Amazon EC2 Container Registry.
//
// Returns metadata about the images in a repository, including image size,
// image tags, and creation date.
//
// Beginning with Docker version 1.9, the Docker client compresses image layers
// before pushing them to a V2 Docker registry. The output of the docker images
// command shows the uncompressed image size, so it may return a larger image
// size than the image sizes returned by DescribeImages.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation DescribeImages for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeImageNotFoundException "ImageNotFoundException"
//   The image requested does not exist in the specified repository.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeImages
func (c *ECR) DescribeImages(input *DescribeImagesInput) (*DescribeImagesOutput, error) {
	req, out := c.DescribeImagesRequest(input)
	return out, req.Send()
}

// DescribeImagesWithContext is the same as DescribeImages with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeImages for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) DescribeImagesWithContext(ctx aws.Context, input *DescribeImagesInput, opts ...request.Option) (*DescribeImagesOutput, error) {
	req, out := c.DescribeImagesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeImagesPages iterates over the pages of a DescribeImages operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeImages method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeImages operation.
//    pageNum := 0
//    err := client.DescribeImagesPages(params,
//        func(page *DescribeImagesOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *ECR) DescribeImagesPages(input *DescribeImagesInput, fn func(*DescribeImagesOutput, bool) bool) error {
	return c.DescribeImagesPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeImagesPagesWithContext same as DescribeImagesPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) DescribeImagesPagesWithContext(ctx aws.Context, input *DescribeImagesInput, fn func(*DescribeImagesOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeImagesInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeImagesRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribeImagesOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opDescribeRepositories = "DescribeRepositories"

// DescribeRepositoriesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeRepositories operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeRepositories for more information on using the DescribeRepositories
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeRepositoriesRequest method.
//    req, resp := client.DescribeRepositoriesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositories
func (c *ECR) DescribeRepositoriesRequest(input *DescribeRepositoriesInput) (req *request.Request, output *DescribeRepositoriesOutput) {
	op := &request.Operation{
		Name:       opDescribeRepositories,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"nextToken"},
			OutputTokens:    []string{"nextToken"},
			LimitToken:      "maxResults",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeRepositoriesInput{}
	}

	output = &DescribeRepositoriesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeRepositories API operation for Amazon EC2 Container Registry.
//
// Describes image repositories in a registry.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation DescribeRepositories for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/DescribeRepositories
func (c *ECR) DescribeRepositories(input *DescribeRepositoriesInput) (*DescribeRepositoriesOutput, error) {
	req, out := c.DescribeRepositoriesRequest(input)
	return out, req.Send()
}

// DescribeRepositoriesWithContext is the same as DescribeRepositories with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeRepositories for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) DescribeRepositoriesWithContext(ctx aws.Context, input *DescribeRepositoriesInput, opts ...request.Option) (*DescribeRepositoriesOutput, error) {
	req, out := c.DescribeRepositoriesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeRepositoriesPages iterates over the pages of a DescribeRepositories operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeRepositories method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeRepositories operation.
//    pageNum := 0
//    err := client.DescribeRepositoriesPages(params,
//        func(page *DescribeRepositoriesOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *ECR) DescribeRepositoriesPages(input *DescribeRepositoriesInput, fn func(*DescribeRepositoriesOutput, bool) bool) error {
	return c.DescribeRepositoriesPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeRepositoriesPagesWithContext same as DescribeRepositoriesPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) DescribeRepositoriesPagesWithContext(ctx aws.Context, input *DescribeRepositoriesInput, fn func(*DescribeRepositoriesOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeRepositoriesInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeRepositoriesRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribeRepositoriesOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opGetAuthorizationToken = "GetAuthorizationToken"

// GetAuthorizationTokenRequest generates a "aws/request.Request" representing the
// client's request for the GetAuthorizationToken operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetAuthorizationToken for more information on using the GetAuthorizationToken
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetAuthorizationTokenRequest method.
//    req, resp := client.GetAuthorizationTokenRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationToken
func (c *ECR) GetAuthorizationTokenRequest(input *GetAuthorizationTokenInput) (req *request.Request, output *GetAuthorizationTokenOutput) {
	op := &request.Operation{
		Name:       opGetAuthorizationToken,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetAuthorizationTokenInput{}
	}

	output = &GetAuthorizationTokenOutput{}
	req = c.newRequest(op, input, output)
	return
}

// GetAuthorizationToken API operation for Amazon EC2 Container Registry.
//
// Retrieves a token that is valid for a specified registry for 12 hours. This
// command allows you to use the docker CLI to push and pull images with Amazon
// ECR. If you do not specify a registry, the default registry is assumed.
//
// The authorizationToken returned for each registry specified is a base64 encoded
// string that can be decoded and used in a docker login command to authenticate
// to a registry. The AWS CLI offers an aws ecr get-login command that simplifies
// the login process.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation GetAuthorizationToken for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetAuthorizationToken
func (c *ECR) GetAuthorizationToken(input *GetAuthorizationTokenInput) (*GetAuthorizationTokenOutput, error) {
	req, out := c.GetAuthorizationTokenRequest(input)
	return out, req.Send()
}

// GetAuthorizationTokenWithContext is the same as GetAuthorizationToken with the addition of
// the ability to pass a context and additional request options.
//
// See GetAuthorizationToken for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) GetAuthorizationTokenWithContext(ctx aws.Context, input *GetAuthorizationTokenInput, opts ...request.Option) (*GetAuthorizationTokenOutput, error) {
	req, out := c.GetAuthorizationTokenRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetDownloadUrlForLayer = "GetDownloadUrlForLayer"

// GetDownloadUrlForLayerRequest generates a "aws/request.Request" representing the
// client's request for the GetDownloadUrlForLayer operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetDownloadUrlForLayer for more information on using the GetDownloadUrlForLayer
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetDownloadUrlForLayerRequest method.
//    req, resp := client.GetDownloadUrlForLayerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayer
func (c *ECR) GetDownloadUrlForLayerRequest(input *GetDownloadUrlForLayerInput) (req *request.Request, output *GetDownloadUrlForLayerOutput) {
	op := &request.Operation{
		Name:       opGetDownloadUrlForLayer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetDownloadUrlForLayerInput{}
	}

	output = &GetDownloadUrlForLayerOutput{}
	req = c.newRequest(op, input, output)
	return
}

// GetDownloadUrlForLayer API operation for Amazon EC2 Container Registry.
//
// Retrieves the pre-signed Amazon S3 download URL corresponding to an image
// layer. You can only get URLs for image layers that are referenced in an image.
//
// This operation is used by the Amazon ECR proxy, and it is not intended for
// general use by customers for pulling and pushing images. In most cases, you
// should use the docker CLI to pull, tag, and push images.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation GetDownloadUrlForLayer for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeLayersNotFoundException "LayersNotFoundException"
//   The specified layers could not be found, or the specified layer is not valid
//   for this repository.
//
//   * ErrCodeLayerInaccessibleException "LayerInaccessibleException"
//   The specified layer is not available because it is not associated with an
//   image. Unassociated image layers may be cleaned up at any time.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetDownloadUrlForLayer
func (c *ECR) GetDownloadUrlForLayer(input *GetDownloadUrlForLayerInput) (*GetDownloadUrlForLayerOutput, error) {
	req, out := c.GetDownloadUrlForLayerRequest(input)
	return out, req.Send()
}

// GetDownloadUrlForLayerWithContext is the same as GetDownloadUrlForLayer with the addition of
// the ability to pass a context and additional request options.
//
// See GetDownloadUrlForLayer for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) GetDownloadUrlForLayerWithContext(ctx aws.Context, input *GetDownloadUrlForLayerInput, opts ...request.Option) (*GetDownloadUrlForLayerOutput, error) {
	req, out := c.GetDownloadUrlForLayerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetLifecyclePolicy = "GetLifecyclePolicy"

// GetLifecyclePolicyRequest generates a "aws/request.Request" representing the
// client's request for the GetLifecyclePolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetLifecyclePolicy for more information on using the GetLifecyclePolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetLifecyclePolicyRequest method.
//    req, resp := client.GetLifecyclePolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicy
func (c *ECR) GetLifecyclePolicyRequest(input *GetLifecyclePolicyInput) (req *request.Request, output *GetLifecyclePolicyOutput) {
	op := &request.Operation{
		Name:       opGetLifecyclePolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetLifecyclePolicyInput{}
	}

	output = &GetLifecyclePolicyOutput{}
	req = c.newRequest(op, input, output)
	return
}

// GetLifecyclePolicy API operation for Amazon EC2 Container Registry.
//
// Retrieves the specified lifecycle policy.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation GetLifecyclePolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeLifecyclePolicyNotFoundException "LifecyclePolicyNotFoundException"
//   The lifecycle policy could not be found, and no policy is set to the repository.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicy
func (c *ECR) GetLifecyclePolicy(input *GetLifecyclePolicyInput) (*GetLifecyclePolicyOutput, error) {
	req, out := c.GetLifecyclePolicyRequest(input)
	return out, req.Send()
}

// GetLifecyclePolicyWithContext is the same as GetLifecyclePolicy with the addition of
// the ability to pass a context and additional request options.
//
// See GetLifecyclePolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) GetLifecyclePolicyWithContext(ctx aws.Context, input *GetLifecyclePolicyInput, opts ...request.Option) (*GetLifecyclePolicyOutput, error) {
	req, out := c.GetLifecyclePolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetLifecyclePolicyPreview = "GetLifecyclePolicyPreview"

// GetLifecyclePolicyPreviewRequest generates a "aws/request.Request" representing the
// client's request for the GetLifecyclePolicyPreview operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetLifecyclePolicyPreview for more information on using the GetLifecyclePolicyPreview
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetLifecyclePolicyPreviewRequest method.
//    req, resp := client.GetLifecyclePolicyPreviewRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyPreview
func (c *ECR) GetLifecyclePolicyPreviewRequest(input *GetLifecyclePolicyPreviewInput) (req *request.Request, output *GetLifecyclePolicyPreviewOutput) {
	op := &request.Operation{
		Name:       opGetLifecyclePolicyPreview,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetLifecyclePolicyPreviewInput{}
	}

	output = &GetLifecyclePolicyPreviewOutput{}
	req = c.newRequest(op, input, output)
	return
}

// GetLifecyclePolicyPreview API operation for Amazon EC2 Container Registry.
//
// Retrieves the results of the specified lifecycle policy preview request.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation GetLifecyclePolicyPreview for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeLifecyclePolicyPreviewNotFoundException "LifecyclePolicyPreviewNotFoundException"
//   There is no dry run for this repository.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetLifecyclePolicyPreview
func (c *ECR) GetLifecyclePolicyPreview(input *GetLifecyclePolicyPreviewInput) (*GetLifecyclePolicyPreviewOutput, error) {
	req, out := c.GetLifecyclePolicyPreviewRequest(input)
	return out, req.Send()
}

// GetLifecyclePolicyPreviewWithContext is the same as GetLifecyclePolicyPreview with the addition of
// the ability to pass a context and additional request options.
//
// See GetLifecyclePolicyPreview for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) GetLifecyclePolicyPreviewWithContext(ctx aws.Context, input *GetLifecyclePolicyPreviewInput, opts ...request.Option) (*GetLifecyclePolicyPreviewOutput, error) {
	req, out := c.GetLifecyclePolicyPreviewRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetRepositoryPolicy = "GetRepositoryPolicy"

// GetRepositoryPolicyRequest generates a "aws/request.Request" representing the
// client's request for the GetRepositoryPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See GetRepositoryPolicy for more information on using the GetRepositoryPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the GetRepositoryPolicyRequest method.
//    req, resp := client.GetRepositoryPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicy
func (c *ECR) GetRepositoryPolicyRequest(input *GetRepositoryPolicyInput) (req *request.Request, output *GetRepositoryPolicyOutput) {
	op := &request.Operation{
		Name:       opGetRepositoryPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetRepositoryPolicyInput{}
	}

	output = &GetRepositoryPolicyOutput{}
	req = c.newRequest(op, input, output)
	return
}

// GetRepositoryPolicy API operation for Amazon EC2 Container Registry.
//
// Retrieves the repository policy for a specified repository.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation GetRepositoryPolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeRepositoryPolicyNotFoundException "RepositoryPolicyNotFoundException"
//   The specified repository and registry combination does not have an associated
//   repository policy.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/GetRepositoryPolicy
func (c *ECR) GetRepositoryPolicy(input *GetRepositoryPolicyInput) (*GetRepositoryPolicyOutput, error) {
	req, out := c.GetRepositoryPolicyRequest(input)
	return out, req.Send()
}

// GetRepositoryPolicyWithContext is the same as GetRepositoryPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See GetRepositoryPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) GetRepositoryPolicyWithContext(ctx aws.Context, input *GetRepositoryPolicyInput, opts ...request.Option) (*GetRepositoryPolicyOutput, error) {
	req, out := c.GetRepositoryPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opInitiateLayerUpload = "InitiateLayerUpload"

// InitiateLayerUploadRequest generates a "aws/request.Request" representing the
// client's request for the InitiateLayerUpload operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See InitiateLayerUpload for more information on using the InitiateLayerUpload
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the InitiateLayerUploadRequest method.
//    req, resp := client.InitiateLayerUploadRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUpload
func (c *ECR) InitiateLayerUploadRequest(input *InitiateLayerUploadInput) (req *request.Request, output *InitiateLayerUploadOutput) {
	op := &request.Operation{
		Name:       opInitiateLayerUpload,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &InitiateLayerUploadInput{}
	}

	output = &InitiateLayerUploadOutput{}
	req = c.newRequest(op, input, output)
	return
}

// InitiateLayerUpload API operation for Amazon EC2 Container Registry.
//
// Notify Amazon ECR that you intend to upload an image layer.
//
// This operation is used by the Amazon ECR proxy, and it is not intended for
// general use by customers for pulling and pushing images. In most cases, you
// should use the docker CLI to pull, tag, and push images.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation InitiateLayerUpload for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/InitiateLayerUpload
func (c *ECR) InitiateLayerUpload(input *InitiateLayerUploadInput) (*InitiateLayerUploadOutput, error) {
	req, out := c.InitiateLayerUploadRequest(input)
	return out, req.Send()
}

// InitiateLayerUploadWithContext is the same as InitiateLayerUpload with the addition of
// the ability to pass a context and additional request options.
//
// See InitiateLayerUpload for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) InitiateLayerUploadWithContext(ctx aws.Context, input *InitiateLayerUploadInput, opts ...request.Option) (*InitiateLayerUploadOutput, error) {
	req, out := c.InitiateLayerUploadRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opListImages = "ListImages"

// ListImagesRequest generates a "aws/request.Request" representing the
// client's request for the ListImages operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See ListImages for more information on using the ListImages
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the ListImagesRequest method.
//    req, resp := client.ListImagesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImages
func (c *ECR) ListImagesRequest(input *ListImagesInput) (req *request.Request, output *ListImagesOutput) {
	op := &request.Operation{
		Name:       opListImages,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"nextToken"},
			OutputTokens:    []string{"nextToken"},
			LimitToken:      "maxResults",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &ListImagesInput{}
	}

	output = &ListImagesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// ListImages API operation for Amazon EC2 Container Registry.
//
// Lists all the image IDs for a given repository.
//
// You can filter images based on whether or not they are tagged by setting
// the tagStatus parameter to TAGGED or UNTAGGED. For example, you can filter
// your results to return only UNTAGGED images and then pipe that result to
// a BatchDeleteImage operation to delete them. Or, you can filter your results
// to return only TAGGED images to list all of the tags in your repository.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation ListImages for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListImages
func (c *ECR) ListImages(input *ListImagesInput) (*ListImagesOutput, error) {
	req, out := c.ListImagesRequest(input)
	return out, req.Send()
}

// ListImagesWithContext is the same as ListImages with the addition of
// the ability to pass a context and additional request options.
//
// See ListImages for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) ListImagesWithContext(ctx aws.Context, input *ListImagesInput, opts ...request.Option) (*ListImagesOutput, error) {
	req, out := c.ListImagesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// ListImagesPages iterates over the pages of a ListImages operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See ListImages method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a ListImages operation.
//    pageNum := 0
//    err := client.ListImagesPages(params,
//        func(page *ListImagesOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *ECR) ListImagesPages(input *ListImagesInput, fn func(*ListImagesOutput, bool) bool) error {
	return c.ListImagesPagesWithContext(aws.BackgroundContext(), input, fn)
}

// ListImagesPagesWithContext same as ListImagesPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) ListImagesPagesWithContext(ctx aws.Context, input *ListImagesInput, fn func(*ListImagesOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *ListImagesInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.ListImagesRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*ListImagesOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opListTagsForResource = "ListTagsForResource"

// ListTagsForResourceRequest generates a "aws/request.Request" representing the
// client's request for the ListTagsForResource operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See ListTagsForResource for more information on using the ListTagsForResource
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the ListTagsForResourceRequest method.
//    req, resp := client.ListTagsForResourceRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListTagsForResource
func (c *ECR) ListTagsForResourceRequest(input *ListTagsForResourceInput) (req *request.Request, output *ListTagsForResourceOutput) {
	op := &request.Operation{
		Name:       opListTagsForResource,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ListTagsForResourceInput{}
	}

	output = &ListTagsForResourceOutput{}
	req = c.newRequest(op, input, output)
	return
}

// ListTagsForResource API operation for Amazon EC2 Container Registry.
//
// List the tags for an Amazon ECR resource.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation ListTagsForResource for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/ListTagsForResource
func (c *ECR) ListTagsForResource(input *ListTagsForResourceInput) (*ListTagsForResourceOutput, error) {
	req, out := c.ListTagsForResourceRequest(input)
	return out, req.Send()
}

// ListTagsForResourceWithContext is the same as ListTagsForResource with the addition of
// the ability to pass a context and additional request options.
//
// See ListTagsForResource for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) ListTagsForResourceWithContext(ctx aws.Context, input *ListTagsForResourceInput, opts ...request.Option) (*ListTagsForResourceOutput, error) {
	req, out := c.ListTagsForResourceRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutImage = "PutImage"

// PutImageRequest generates a "aws/request.Request" representing the
// client's request for the PutImage operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutImage for more information on using the PutImage
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutImageRequest method.
//    req, resp := client.PutImageRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImage
func (c *ECR) PutImageRequest(input *PutImageInput) (req *request.Request, output *PutImageOutput) {
	op := &request.Operation{
		Name:       opPutImage,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutImageInput{}
	}

	output = &PutImageOutput{}
	req = c.newRequest(op, input, output)
	return
}

// PutImage API operation for Amazon EC2 Container Registry.
//
// Creates or updates the image manifest and tags associated with an image.
//
// This operation is used by the Amazon ECR proxy, and it is not intended for
// general use by customers for pulling and pushing images. In most cases, you
// should use the docker CLI to pull, tag, and push images.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation PutImage for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeImageAlreadyExistsException "ImageAlreadyExistsException"
//   The specified image has already been pushed, and there were no changes to
//   the manifest or image tag after the last push.
//
//   * ErrCodeLayersNotFoundException "LayersNotFoundException"
//   The specified layers could not be found, or the specified layer is not valid
//   for this repository.
//
//   * ErrCodeLimitExceededException "LimitExceededException"
//   The operation did not succeed because it would have exceeded a service limit
//   for your account. For more information, see Amazon ECR Default Service Limits
//   (http://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html)
//   in the Amazon Elastic Container Registry User Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutImage
func (c *ECR) PutImage(input *PutImageInput) (*PutImageOutput, error) {
	req, out := c.PutImageRequest(input)
	return out, req.Send()
}

// PutImageWithContext is the same as PutImage with the addition of
// the ability to pass a context and additional request options.
//
// See PutImage for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) PutImageWithContext(ctx aws.Context, input *PutImageInput, opts ...request.Option) (*PutImageOutput, error) {
	req, out := c.PutImageRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutLifecyclePolicy = "PutLifecyclePolicy"

// PutLifecyclePolicyRequest generates a "aws/request.Request" representing the
// client's request for the PutLifecyclePolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutLifecyclePolicy for more information on using the PutLifecyclePolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutLifecyclePolicyRequest method.
//    req, resp := client.PutLifecyclePolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutLifecyclePolicy
func (c *ECR) PutLifecyclePolicyRequest(input *PutLifecyclePolicyInput) (req *request.Request, output *PutLifecyclePolicyOutput) {
	op := &request.Operation{
		Name:       opPutLifecyclePolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutLifecyclePolicyInput{}
	}

	output = &PutLifecyclePolicyOutput{}
	req = c.newRequest(op, input, output)
	return
}

// PutLifecyclePolicy API operation for Amazon EC2 Container Registry.
//
// Creates or updates a lifecycle policy. For information about lifecycle policy
// syntax, see Lifecycle Policy Template (http://docs.aws.amazon.com/AmazonECR/latest/userguide/LifecyclePolicies.html).
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation PutLifecyclePolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/PutLifecyclePolicy
func (c *ECR) PutLifecyclePolicy(input *PutLifecyclePolicyInput) (*PutLifecyclePolicyOutput, error) {
	req, out := c.PutLifecyclePolicyRequest(input)
	return out, req.Send()
}

// PutLifecyclePolicyWithContext is the same as PutLifecyclePolicy with the addition of
// the ability to pass a context and additional request options.
//
// See PutLifecyclePolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) PutLifecyclePolicyWithContext(ctx aws.Context, input *PutLifecyclePolicyInput, opts ...request.Option) (*PutLifecyclePolicyOutput, error) {
	req, out := c.PutLifecyclePolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetRepositoryPolicy = "SetRepositoryPolicy"

// SetRepositoryPolicyRequest generates a "aws/request.Request" representing the
// client's request for the SetRepositoryPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See SetRepositoryPolicy for more information on using the SetRepositoryPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the SetRepositoryPolicyRequest method.
//    req, resp := client.SetRepositoryPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicy
func (c *ECR) SetRepositoryPolicyRequest(input *SetRepositoryPolicyInput) (req *request.Request, output *SetRepositoryPolicyOutput) {
	op := &request.Operation{
		Name:       opSetRepositoryPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetRepositoryPolicyInput{}
	}

	output = &SetRepositoryPolicyOutput{}
	req = c.newRequest(op, input, output)
	return
}

// SetRepositoryPolicy API operation for Amazon EC2 Container Registry.
//
// Applies a repository policy on a specified repository to control access permissions.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation SetRepositoryPolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/SetRepositoryPolicy
func (c *ECR) SetRepositoryPolicy(input *SetRepositoryPolicyInput) (*SetRepositoryPolicyOutput, error) {
	req, out := c.SetRepositoryPolicyRequest(input)
	return out, req.Send()
}

// SetRepositoryPolicyWithContext is the same as SetRepositoryPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See SetRepositoryPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) SetRepositoryPolicyWithContext(ctx aws.Context, input *SetRepositoryPolicyInput, opts ...request.Option) (*SetRepositoryPolicyOutput, error) {
	req, out := c.SetRepositoryPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opStartLifecyclePolicyPreview = "StartLifecyclePolicyPreview"

// StartLifecyclePolicyPreviewRequest generates a "aws/request.Request" representing the
// client's request for the StartLifecyclePolicyPreview operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See StartLifecyclePolicyPreview for more information on using the StartLifecyclePolicyPreview
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the StartLifecyclePolicyPreviewRequest method.
//    req, resp := client.StartLifecyclePolicyPreviewRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/StartLifecyclePolicyPreview
func (c *ECR) StartLifecyclePolicyPreviewRequest(input *StartLifecyclePolicyPreviewInput) (req *request.Request, output *StartLifecyclePolicyPreviewOutput) {
	op := &request.Operation{
		Name:       opStartLifecyclePolicyPreview,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &StartLifecyclePolicyPreviewInput{}
	}

	output = &StartLifecyclePolicyPreviewOutput{}
	req = c.newRequest(op, input, output)
	return
}

// StartLifecyclePolicyPreview API operation for Amazon EC2 Container Registry.
//
// Starts a preview of the specified lifecycle policy. This allows you to see
// the results before creating the lifecycle policy.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation StartLifecyclePolicyPreview for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeLifecyclePolicyNotFoundException "LifecyclePolicyNotFoundException"
//   The lifecycle policy could not be found, and no policy is set to the repository.
//
//   * ErrCodeLifecyclePolicyPreviewInProgressException "LifecyclePolicyPreviewInProgressException"
//   The previous lifecycle policy preview request has not completed. Please try
//   again later.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/StartLifecyclePolicyPreview
func (c *ECR) StartLifecyclePolicyPreview(input *StartLifecyclePolicyPreviewInput) (*StartLifecyclePolicyPreviewOutput, error) {
	req, out := c.StartLifecyclePolicyPreviewRequest(input)
	return out, req.Send()
}

// StartLifecyclePolicyPreviewWithContext is the same as StartLifecyclePolicyPreview with the addition of
// the ability to pass a context and additional request options.
//
// See StartLifecyclePolicyPreview for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) StartLifecyclePolicyPreviewWithContext(ctx aws.Context, input *StartLifecyclePolicyPreviewInput, opts ...request.Option) (*StartLifecyclePolicyPreviewOutput, error) {
	req, out := c.StartLifecyclePolicyPreviewRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opTagResource = "TagResource"

// TagResourceRequest generates a "aws/request.Request" representing the
// client's request for the TagResource operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See TagResource for more information on using the TagResource
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the TagResourceRequest method.
//    req, resp := client.TagResourceRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/TagResource
func (c *ECR) TagResourceRequest(input *TagResourceInput) (req *request.Request, output *TagResourceOutput) {
	op := &request.Operation{
		Name:       opTagResource,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &TagResourceInput{}
	}

	output = &TagResourceOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// TagResource API operation for Amazon EC2 Container Registry.
//
// Adds specified tags to a resource with the specified ARN. Existing tags on
// a resource are not changed if they are not specified in the request parameters.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation TagResource for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeInvalidTagParameterException "InvalidTagParameterException"
//   An invalid parameter has been specified. Tag keys can have a maximum character
//   length of 128 characters, and tag values can have a maximum length of 256
//   characters.
//
//   * ErrCodeTooManyTagsException "TooManyTagsException"
//   The list of tags on the repository is over the limit. The maximum number
//   of tags that can be applied to a repository is 50.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/TagResource
func (c *ECR) TagResource(input *TagResourceInput) (*TagResourceOutput, error) {
	req, out := c.TagResourceRequest(input)
	return out, req.Send()
}

// TagResourceWithContext is the same as TagResource with the addition of
// the ability to pass a context and additional request options.
//
// See TagResource for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) TagResourceWithContext(ctx aws.Context, input *TagResourceInput, opts ...request.Option) (*TagResourceOutput, error) {
	req, out := c.TagResourceRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opUntagResource = "UntagResource"

// UntagResourceRequest generates a "aws/request.Request" representing the
// client's request for the UntagResource operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See UntagResource for more information on using the UntagResource
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the UntagResourceRequest method.
//    req, resp := client.UntagResourceRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UntagResource
func (c *ECR) UntagResourceRequest(input *UntagResourceInput) (req *request.Request, output *UntagResourceOutput) {
	op := &request.Operation{
		Name:       opUntagResource,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &UntagResourceInput{}
	}

	output = &UntagResourceOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(jsonrpc.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// UntagResource API operation for Amazon EC2 Container Registry.
//
// Deletes specified tags from a resource.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation UntagResource for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeInvalidTagParameterException "InvalidTagParameterException"
//   An invalid parameter has been specified. Tag keys can have a maximum character
//   length of 128 characters, and tag values can have a maximum length of 256
//   characters.
//
//   * ErrCodeTooManyTagsException "TooManyTagsException"
//   The list of tags on the repository is over the limit. The maximum number
//   of tags that can be applied to a repository is 50.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UntagResource
func (c *ECR) UntagResource(input *UntagResourceInput) (*UntagResourceOutput, error) {
	req, out := c.UntagResourceRequest(input)
	return out, req.Send()
}

// UntagResourceWithContext is the same as UntagResource with the addition of
// the ability to pass a context and additional request options.
//
// See UntagResource for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) UntagResourceWithContext(ctx aws.Context, input *UntagResourceInput, opts ...request.Option) (*UntagResourceOutput, error) {
	req, out := c.UntagResourceRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opUploadLayerPart = "UploadLayerPart"

// UploadLayerPartRequest generates a "aws/request.Request" representing the
// client's request for the UploadLayerPart operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See UploadLayerPart for more information on using the UploadLayerPart
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the UploadLayerPartRequest method.
//    req, resp := client.UploadLayerPartRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPart
func (c *ECR) UploadLayerPartRequest(input *UploadLayerPartInput) (req *request.Request, output *UploadLayerPartOutput) {
	op := &request.Operation{
		Name:       opUploadLayerPart,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &UploadLayerPartInput{}
	}

	output = &UploadLayerPartOutput{}
	req = c.newRequest(op, input, output)
	return
}

// UploadLayerPart API operation for Amazon EC2 Container Registry.
//
// Uploads an image layer part to Amazon ECR.
//
// This operation is used by the Amazon ECR proxy, and it is not intended for
// general use by customers for pulling and pushing images. In most cases, you
// should use the docker CLI to pull, tag, and push images.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Amazon EC2 Container Registry's
// API operation UploadLayerPart for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeServerException "ServerException"
//   These errors are usually caused by a server-side issue.
//
//   * ErrCodeInvalidParameterException "InvalidParameterException"
//   The specified parameter is invalid. Review the available parameters for the
//   API request.
//
//   * ErrCodeInvalidLayerPartException "InvalidLayerPartException"
//   The layer part size is not valid, or the first byte specified is not consecutive
//   to the last byte of a previous layer part upload.
//
//   * ErrCodeRepositoryNotFoundException "RepositoryNotFoundException"
//   The specified repository could not be found. Check the spelling of the specified
//   repository and ensure that you are performing operations on the correct registry.
//
//   * ErrCodeUploadNotFoundException "UploadNotFoundException"
//   The upload could not be found, or the specified upload id is not valid for
//   this repository.
//
//   * ErrCodeLimitExceededException "LimitExceededException"
//   The operation did not succeed because it would have exceeded a service limit
//   for your account. For more information, see Amazon ECR Default Service Limits
//   (http://docs.aws.amazon.com/AmazonECR/latest/userguide/service_limits.html)
//   in the Amazon Elastic Container Registry User Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/ecr-2015-09-21/UploadLayerPart
func (c *ECR) UploadLayerPart(input *UploadLayerPartInput) (*UploadLayerPartOutput, error) {
	req, out := c.UploadLayerPartRequest(input)
	return out, req.Send()
}

// UploadLayerPartWithContext is the same as UploadLayerPart with the addition of
// the ability to pass a context and additional request options.
//
// See UploadLayerPart for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ECR) UploadLayerPartWithContext(ctx aws.Context, input *UploadLayerPartInput, opts ...request.Option) (*UploadLayerPartOutput, error) {
	req, out := c.UploadLayerPartRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// An object representing authorization data for an Amazon ECR registry.
type AuthorizationData struct {
	_ struct{} `type:"structure"`

	// A base64-encoded string that contains authorization data for the specified
	// Amazon ECR registry. When the string is decoded, it is presented in the format
	// user:password for private registry authentication using docker login.
	AuthorizationToken *string `locationName:"authorizationToken" type:"string"`

	// The Unix time in seconds and milliseconds when the authorization token expires.
	// Authorization tokens are valid for 12 hours.
	ExpiresAt *time.Time `locationName:"expiresAt" type:"timestamp"`

	// The registry URL to use for this authorization token in a docker login command.
	// The Amazon ECR registry URL format is https://aws_account_id.dkr.ecr.region.amazonaws.com.
	// For example, https://012345678910.dkr.ecr.us-east-1.amazonaws.com..
	ProxyEndpoint *string `locationName:"proxyEndpoint" type:"string"`
}

// String returns the string representation
func (s AuthorizationData) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AuthorizationData) GoString() string {
	return s.String()
}

// SetAuthorizationToken sets the AuthorizationToken field's value.
func (s *AuthorizationData) SetAuthorizationToken(v string) *AuthorizationData {
	s.AuthorizationToken = &v
	return s
}

// SetExpiresAt sets the ExpiresAt field's value.
func (s *AuthorizationData) SetExpiresAt(v time.Time) *AuthorizationData {
	s.ExpiresAt = &v
	return s
}

// SetProxyEndpoint sets the ProxyEndpoint field's value.
func (s *AuthorizationData) SetProxyEndpoint(v string) *AuthorizationData {
	s.ProxyEndpoint = &v
	return s
}

type BatchCheckLayerAvailabilityInput struct {
	_ struct{} `type:"structure"`

	// The digests of the image layers to check.
	//
	// LayerDigests is a required field
	LayerDigests []*string `locationName:"layerDigests" min:"1" type:"list" required:"true"`

	// The AWS account ID associated with the registry that contains the image layers
	// to check. If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository that is associated with the image layers to check.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s BatchCheckLayerAvailabilityInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BatchCheckLayerAvailabilityInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *BatchCheckLayerAvailabilityInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "BatchCheckLayerAvailabilityInput"}
	if s.LayerDigests == nil {
		invalidParams.Add(request.NewErrParamRequired("LayerDigests"))
	}
	if s.LayerDigests != nil && len(s.LayerDigests) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LayerDigests", 1))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLayerDigests sets the LayerDigests field's value.
func (s *BatchCheckLayerAvailabilityInput) SetLayerDigests(v []*string) *BatchCheckLayerAvailabilityInput {
	s.LayerDigests = v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *BatchCheckLayerAvailabilityInput) SetRegistryId(v string) *BatchCheckLayerAvailabilityInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *BatchCheckLayerAvailabilityInput) SetRepositoryName(v string) *BatchCheckLayerAvailabilityInput {
	s.RepositoryName = &v
	return s
}

type BatchCheckLayerAvailabilityOutput struct {
	_ struct{} `type:"structure"`

	// Any failures associated with the call.
	Failures []*LayerFailure `locationName:"failures" type:"list"`

	// A list of image layer objects corresponding to the image layer references
	// in the request.
	Layers []*Layer `locationName:"layers" type:"list"`
}

// String returns the string representation
func (s BatchCheckLayerAvailabilityOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BatchCheckLayerAvailabilityOutput) GoString() string {
	return s.String()
}

// SetFailures sets the Failures field's value.
func (s *BatchCheckLayerAvailabilityOutput) SetFailures(v []*LayerFailure) *BatchCheckLayerAvailabilityOutput {
	s.Failures = v
	return s
}

// SetLayers sets the Layers field's value.
func (s *BatchCheckLayerAvailabilityOutput) SetLayers(v []*Layer) *BatchCheckLayerAvailabilityOutput {
	s.Layers = v
	return s
}

// Deletes specified images within a specified repository. Images are specified
// with either the imageTag or imageDigest.
type BatchDeleteImageInput struct {
	_ struct{} `type:"structure"`

	// A list of image ID references that correspond to images to delete. The format
	// of the imageIds reference is imageTag=tag or imageDigest=digest.
	//
	// ImageIds is a required field
	ImageIds []*ImageIdentifier `locationName:"imageIds" min:"1" type:"list" required:"true"`

	// The AWS account ID associated with the registry that contains the image to
	// delete. If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository that contains the image to delete.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s BatchDeleteImageInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BatchDeleteImageInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *BatchDeleteImageInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "BatchDeleteImageInput"}
	if s.ImageIds == nil {
		invalidParams.Add(request.NewErrParamRequired("ImageIds"))
	}
	if s.ImageIds != nil && len(s.ImageIds) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ImageIds", 1))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetImageIds sets the ImageIds field's value.
func (s *BatchDeleteImageInput) SetImageIds(v []*ImageIdentifier) *BatchDeleteImageInput {
	s.ImageIds = v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *BatchDeleteImageInput) SetRegistryId(v string) *BatchDeleteImageInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *BatchDeleteImageInput) SetRepositoryName(v string) *BatchDeleteImageInput {
	s.RepositoryName = &v
	return s
}

type BatchDeleteImageOutput struct {
	_ struct{} `type:"structure"`

	// Any failures associated with the call.
	Failures []*ImageFailure `locationName:"failures" type:"list"`

	// The image IDs of the deleted images.
	ImageIds []*ImageIdentifier `locationName:"imageIds" min:"1" type:"list"`
}

// String returns the string representation
func (s BatchDeleteImageOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BatchDeleteImageOutput) GoString() string {
	return s.String()
}

// SetFailures sets the Failures field's value.
func (s *BatchDeleteImageOutput) SetFailures(v []*ImageFailure) *BatchDeleteImageOutput {
	s.Failures = v
	return s
}

// SetImageIds sets the ImageIds field's value.
func (s *BatchDeleteImageOutput) SetImageIds(v []*ImageIdentifier) *BatchDeleteImageOutput {
	s.ImageIds = v
	return s
}

type BatchGetImageInput struct {
	_ struct{} `type:"structure"`

	// The accepted media types for the request.
	//
	// Valid values: application/vnd.docker.distribution.manifest.v1+json | application/vnd.docker.distribution.manifest.v2+json
	// | application/vnd.oci.image.manifest.v1+json
	AcceptedMediaTypes []*string `locationName:"acceptedMediaTypes" min:"1" type:"list"`

	// A list of image ID references that correspond to images to describe. The
	// format of the imageIds reference is imageTag=tag or imageDigest=digest.
	//
	// ImageIds is a required field
	ImageIds []*ImageIdentifier `locationName:"imageIds" min:"1" type:"list" required:"true"`

	// The AWS account ID associated with the registry that contains the images
	// to describe. If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository that contains the images to describe.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s BatchGetImageInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BatchGetImageInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *BatchGetImageInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "BatchGetImageInput"}
	if s.AcceptedMediaTypes != nil && len(s.AcceptedMediaTypes) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AcceptedMediaTypes", 1))
	}
	if s.ImageIds == nil {
		invalidParams.Add(request.NewErrParamRequired("ImageIds"))
	}
	if s.ImageIds != nil && len(s.ImageIds) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ImageIds", 1))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAcceptedMediaTypes sets the AcceptedMediaTypes field's value.
func (s *BatchGetImageInput) SetAcceptedMediaTypes(v []*string) *BatchGetImageInput {
	s.AcceptedMediaTypes = v
	return s
}

// SetImageIds sets the ImageIds field's value.
func (s *BatchGetImageInput) SetImageIds(v []*ImageIdentifier) *BatchGetImageInput {
	s.ImageIds = v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *BatchGetImageInput) SetRegistryId(v string) *BatchGetImageInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *BatchGetImageInput) SetRepositoryName(v string) *BatchGetImageInput {
	s.RepositoryName = &v
	return s
}

type BatchGetImageOutput struct {
	_ struct{} `type:"structure"`

	// Any failures associated with the call.
	Failures []*ImageFailure `locationName:"failures" type:"list"`

	// A list of image objects corresponding to the image references in the request.
	Images []*Image `locationName:"images" type:"list"`
}

// String returns the string representation
func (s BatchGetImageOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BatchGetImageOutput) GoString() string {
	return s.String()
}

// SetFailures sets the Failures field's value.
func (s *BatchGetImageOutput) SetFailures(v []*ImageFailure) *BatchGetImageOutput {
	s.Failures = v
	return s
}

// SetImages sets the Images field's value.
func (s *BatchGetImageOutput) SetImages(v []*Image) *BatchGetImageOutput {
	s.Images = v
	return s
}

type CompleteLayerUploadInput struct {
	_ struct{} `type:"structure"`

	// The sha256 digest of the image layer.
	//
	// LayerDigests is a required field
	LayerDigests []*string `locationName:"layerDigests" min:"1" type:"list" required:"true"`

	// The AWS account ID associated with the registry to which to upload layers.
	// If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository to associate with the image layer.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`

	// The upload ID from a previous InitiateLayerUpload operation to associate
	// with the image layer.
	//
	// UploadId is a required field
	UploadId *string `locationName:"uploadId" type:"string" required:"true"`
}

// String returns the string representation
func (s CompleteLayerUploadInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CompleteLayerUploadInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CompleteLayerUploadInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CompleteLayerUploadInput"}
	if s.LayerDigests == nil {
		invalidParams.Add(request.NewErrParamRequired("LayerDigests"))
	}
	if s.LayerDigests != nil && len(s.LayerDigests) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LayerDigests", 1))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}
	if s.UploadId == nil {
		invalidParams.Add(request.NewErrParamRequired("UploadId"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLayerDigests sets the LayerDigests field's value.
func (s *CompleteLayerUploadInput) SetLayerDigests(v []*string) *CompleteLayerUploadInput {
	s.LayerDigests = v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *CompleteLayerUploadInput) SetRegistryId(v string) *CompleteLayerUploadInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *CompleteLayerUploadInput) SetRepositoryName(v string) *CompleteLayerUploadInput {
	s.RepositoryName = &v
	return s
}

// SetUploadId sets the UploadId field's value.
func (s *CompleteLayerUploadInput) SetUploadId(v string) *CompleteLayerUploadInput {
	s.UploadId = &v
	return s
}

type CompleteLayerUploadOutput struct {
	_ struct{} `type:"structure"`

	// The sha256 digest of the image layer.
	LayerDigest *string `locationName:"layerDigest" type:"string"`

	// The registry ID associated with the request.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository name associated with the request.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`

	// The upload ID associated with the layer.
	UploadId *string `locationName:"uploadId" type:"string"`
}

// String returns the string representation
func (s CompleteLayerUploadOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CompleteLayerUploadOutput) GoString() string {
	return s.String()
}

// SetLayerDigest sets the LayerDigest field's value.
func (s *CompleteLayerUploadOutput) SetLayerDigest(v string) *CompleteLayerUploadOutput {
	s.LayerDigest = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *CompleteLayerUploadOutput) SetRegistryId(v string) *CompleteLayerUploadOutput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *CompleteLayerUploadOutput) SetRepositoryName(v string) *CompleteLayerUploadOutput {
	s.RepositoryName = &v
	return s
}

// SetUploadId sets the UploadId field's value.
func (s *CompleteLayerUploadOutput) SetUploadId(v string) *CompleteLayerUploadOutput {
	s.UploadId = &v
	return s
}

type CreateRepositoryInput struct {
	_ struct{} `type:"structure"`

	// The name to use for the repository. The repository name may be specified
	// on its own (such as nginx-web-app) or it can be prepended with a namespace
	// to group the repository into a category (such as project-a/nginx-web-app).
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`

	Tags []*Tag `locationName:"tags" type:"list"`
}

// String returns the string representation
func (s CreateRepositoryInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateRepositoryInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateRepositoryInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateRepositoryInput"}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *CreateRepositoryInput) SetRepositoryName(v string) *CreateRepositoryInput {
	s.RepositoryName = &v
	return s
}

// SetTags sets the Tags field's value.
func (s *CreateRepositoryInput) SetTags(v []*Tag) *CreateRepositoryInput {
	s.Tags = v
	return s
}

type CreateRepositoryOutput struct {
	_ struct{} `type:"structure"`

	// The repository that was created.
	Repository *Repository `locationName:"repository" type:"structure"`
}

// String returns the string representation
func (s CreateRepositoryOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateRepositoryOutput) GoString() string {
	return s.String()
}

// SetRepository sets the Repository field's value.
func (s *CreateRepositoryOutput) SetRepository(v *Repository) *CreateRepositoryOutput {
	s.Repository = v
	return s
}

type DeleteLifecyclePolicyInput struct {
	_ struct{} `type:"structure"`

	// The AWS account ID associated with the registry that contains the repository.
	// If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteLifecyclePolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLifecyclePolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteLifecyclePolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteLifecyclePolicyInput"}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetRegistryId sets the RegistryId field's value.
func (s *DeleteLifecyclePolicyInput) SetRegistryId(v string) *DeleteLifecyclePolicyInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *DeleteLifecyclePolicyInput) SetRepositoryName(v string) *DeleteLifecyclePolicyInput {
	s.RepositoryName = &v
	return s
}

type DeleteLifecyclePolicyOutput struct {
	_ struct{} `type:"structure"`

	// The time stamp of the last time that the lifecycle policy was run.
	LastEvaluatedAt *time.Time `locationName:"lastEvaluatedAt" type:"timestamp"`

	// The JSON lifecycle policy text.
	LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"`

	// The registry ID associated with the request.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository name associated with the request.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`
}

// String returns the string representation
func (s DeleteLifecyclePolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLifecyclePolicyOutput) GoString() string {
	return s.String()
}

// SetLastEvaluatedAt sets the LastEvaluatedAt field's value.
func (s *DeleteLifecyclePolicyOutput) SetLastEvaluatedAt(v time.Time) *DeleteLifecyclePolicyOutput {
	s.LastEvaluatedAt = &v
	return s
}

// SetLifecyclePolicyText sets the LifecyclePolicyText field's value.
func (s *DeleteLifecyclePolicyOutput) SetLifecyclePolicyText(v string) *DeleteLifecyclePolicyOutput {
	s.LifecyclePolicyText = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *DeleteLifecyclePolicyOutput) SetRegistryId(v string) *DeleteLifecyclePolicyOutput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *DeleteLifecyclePolicyOutput) SetRepositoryName(v string) *DeleteLifecyclePolicyOutput {
	s.RepositoryName = &v
	return s
}

type DeleteRepositoryInput struct {
	_ struct{} `type:"structure"`

	// If a repository contains images, forces the deletion.
	Force *bool `locationName:"force" type:"boolean"`

	// The AWS account ID associated with the registry that contains the repository
	// to delete. If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository to delete.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteRepositoryInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteRepositoryInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteRepositoryInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteRepositoryInput"}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetForce sets the Force field's value.
func (s *DeleteRepositoryInput) SetForce(v bool) *DeleteRepositoryInput {
	s.Force = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *DeleteRepositoryInput) SetRegistryId(v string) *DeleteRepositoryInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *DeleteRepositoryInput) SetRepositoryName(v string) *DeleteRepositoryInput {
	s.RepositoryName = &v
	return s
}

type DeleteRepositoryOutput struct {
	_ struct{} `type:"structure"`

	// The repository that was deleted.
	Repository *Repository `locationName:"repository" type:"structure"`
}

// String returns the string representation
func (s DeleteRepositoryOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteRepositoryOutput) GoString() string {
	return s.String()
}

// SetRepository sets the Repository field's value.
func (s *DeleteRepositoryOutput) SetRepository(v *Repository) *DeleteRepositoryOutput {
	s.Repository = v
	return s
}

type DeleteRepositoryPolicyInput struct {
	_ struct{} `type:"structure"`

	// The AWS account ID associated with the registry that contains the repository
	// policy to delete. If you do not specify a registry, the default registry
	// is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository that is associated with the repository policy
	// to delete.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteRepositoryPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteRepositoryPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteRepositoryPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteRepositoryPolicyInput"}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetRegistryId sets the RegistryId field's value.
func (s *DeleteRepositoryPolicyInput) SetRegistryId(v string) *DeleteRepositoryPolicyInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *DeleteRepositoryPolicyInput) SetRepositoryName(v string) *DeleteRepositoryPolicyInput {
	s.RepositoryName = &v
	return s
}

type DeleteRepositoryPolicyOutput struct {
	_ struct{} `type:"structure"`

	// The JSON repository policy that was deleted from the repository.
	PolicyText *string `locationName:"policyText" type:"string"`

	// The registry ID associated with the request.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository name associated with the request.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`
}

// String returns the string representation
func (s DeleteRepositoryPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteRepositoryPolicyOutput) GoString() string {
	return s.String()
}

// SetPolicyText sets the PolicyText field's value.
func (s *DeleteRepositoryPolicyOutput) SetPolicyText(v string) *DeleteRepositoryPolicyOutput {
	s.PolicyText = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *DeleteRepositoryPolicyOutput) SetRegistryId(v string) *DeleteRepositoryPolicyOutput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *DeleteRepositoryPolicyOutput) SetRepositoryName(v string) *DeleteRepositoryPolicyOutput {
	s.RepositoryName = &v
	return s
}

// An object representing a filter on a DescribeImages operation.
type DescribeImagesFilter struct {
	_ struct{} `type:"structure"`

	// The tag status with which to filter your DescribeImages results. You can
	// filter results based on whether they are TAGGED or UNTAGGED.
	TagStatus *string `locationName:"tagStatus" type:"string" enum:"TagStatus"`
}

// String returns the string representation
func (s DescribeImagesFilter) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeImagesFilter) GoString() string {
	return s.String()
}

// SetTagStatus sets the TagStatus field's value.
func (s *DescribeImagesFilter) SetTagStatus(v string) *DescribeImagesFilter {
	s.TagStatus = &v
	return s
}

type DescribeImagesInput struct {
	_ struct{} `type:"structure"`

	// The filter key and value with which to filter your DescribeImages results.
	Filter *DescribeImagesFilter `locationName:"filter" type:"structure"`

	// The list of image IDs for the requested repository.
	ImageIds []*ImageIdentifier `locationName:"imageIds" min:"1" type:"list"`

	// The maximum number of repository results returned by DescribeImages in paginated
	// output. When this parameter is used, DescribeImages only returns maxResults
	// results in a single page along with a nextToken response element. The remaining
	// results of the initial request can be seen by sending another DescribeImages
	// request with the returned nextToken value. This value can be between 1 and
	// 1000. If this parameter is not used, then DescribeImages returns up to 100
	// results and a nextToken value, if applicable. This option cannot be used
	// when you specify images with imageIds.
	MaxResults *int64 `locationName:"maxResults" min:"1" type:"integer"`

	// The nextToken value returned from a previous paginated DescribeImages request
	// where maxResults was used and the results exceeded the value of that parameter.
	// Pagination continues from the end of the previous results that returned the
	// nextToken value. This value is null when there are no more results to return.
	// This option cannot be used when you specify images with imageIds.
	NextToken *string `locationName:"nextToken" type:"string"`

	// The AWS account ID associated with the registry that contains the repository
	// in which to describe images. If you do not specify a registry, the default
	// registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// A list of repositories to describe.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s DescribeImagesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeImagesInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeImagesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeImagesInput"}
	if s.ImageIds != nil && len(s.ImageIds) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ImageIds", 1))
	}
	if s.MaxResults != nil && *s.MaxResults < 1 {
		invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetFilter sets the Filter field's value.
func (s *DescribeImagesInput) SetFilter(v *DescribeImagesFilter) *DescribeImagesInput {
	s.Filter = v
	return s
}

// SetImageIds sets the ImageIds field's value.
func (s *DescribeImagesInput) SetImageIds(v []*ImageIdentifier) *DescribeImagesInput {
	s.ImageIds = v
	return s
}

// SetMaxResults sets the MaxResults field's value.
func (s *DescribeImagesInput) SetMaxResults(v int64) *DescribeImagesInput {
	s.MaxResults = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeImagesInput) SetNextToken(v string) *DescribeImagesInput {
	s.NextToken = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *DescribeImagesInput) SetRegistryId(v string) *DescribeImagesInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *DescribeImagesInput) SetRepositoryName(v string) *DescribeImagesInput {
	s.RepositoryName = &v
	return s
}

type DescribeImagesOutput struct {
	_ struct{} `type:"structure"`

	// A list of ImageDetail objects that contain data about the image.
	ImageDetails []*ImageDetail `locationName:"imageDetails" type:"list"`

	// The nextToken value to include in a future DescribeImages request. When the
	// results of a DescribeImages request exceed maxResults, this value can be
	// used to retrieve the next page of results. This value is null when there
	// are no more results to return.
	NextToken *string `locationName:"nextToken" type:"string"`
}

// String returns the string representation
func (s DescribeImagesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeImagesOutput) GoString() string {
	return s.String()
}

// SetImageDetails sets the ImageDetails field's value.
func (s *DescribeImagesOutput) SetImageDetails(v []*ImageDetail) *DescribeImagesOutput {
	s.ImageDetails = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeImagesOutput) SetNextToken(v string) *DescribeImagesOutput {
	s.NextToken = &v
	return s
}

type DescribeRepositoriesInput struct {
	_ struct{} `type:"structure"`

	// The maximum number of repository results returned by DescribeRepositories
	// in paginated output. When this parameter is used, DescribeRepositories only
	// returns maxResults results in a single page along with a nextToken response
	// element. The remaining results of the initial request can be seen by sending
	// another DescribeRepositories request with the returned nextToken value. This
	// value can be between 1 and 1000. If this parameter is not used, then DescribeRepositories
	// returns up to 100 results and a nextToken value, if applicable. This option
	// cannot be used when you specify repositories with repositoryNames.
	MaxResults *int64 `locationName:"maxResults" min:"1" type:"integer"`

	// The nextToken value returned from a previous paginated DescribeRepositories
	// request where maxResults was used and the results exceeded the value of that
	// parameter. Pagination continues from the end of the previous results that
	// returned the nextToken value. This value is null when there are no more results
	// to return. This option cannot be used when you specify repositories with
	// repositoryNames.
	//
	// This token should be treated as an opaque identifier that is only used to
	// retrieve the next items in a list and not for other programmatic purposes.
	NextToken *string `locationName:"nextToken" type:"string"`

	// The AWS account ID associated with the registry that contains the repositories
	// to be described. If you do not specify a registry, the default registry is
	// assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// A list of repositories to describe. If this parameter is omitted, then all
	// repositories in a registry are described.
	RepositoryNames []*string `locationName:"repositoryNames" min:"1" type:"list"`
}

// String returns the string representation
func (s DescribeRepositoriesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeRepositoriesInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeRepositoriesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeRepositoriesInput"}
	if s.MaxResults != nil && *s.MaxResults < 1 {
		invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1))
	}
	if s.RepositoryNames != nil && len(s.RepositoryNames) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryNames", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetMaxResults sets the MaxResults field's value.
func (s *DescribeRepositoriesInput) SetMaxResults(v int64) *DescribeRepositoriesInput {
	s.MaxResults = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeRepositoriesInput) SetNextToken(v string) *DescribeRepositoriesInput {
	s.NextToken = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *DescribeRepositoriesInput) SetRegistryId(v string) *DescribeRepositoriesInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryNames sets the RepositoryNames field's value.
func (s *DescribeRepositoriesInput) SetRepositoryNames(v []*string) *DescribeRepositoriesInput {
	s.RepositoryNames = v
	return s
}

type DescribeRepositoriesOutput struct {
	_ struct{} `type:"structure"`

	// The nextToken value to include in a future DescribeRepositories request.
	// When the results of a DescribeRepositories request exceed maxResults, this
	// value can be used to retrieve the next page of results. This value is null
	// when there are no more results to return.
	NextToken *string `locationName:"nextToken" type:"string"`

	// A list of repository objects corresponding to valid repositories.
	Repositories []*Repository `locationName:"repositories" type:"list"`
}

// String returns the string representation
func (s DescribeRepositoriesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeRepositoriesOutput) GoString() string {
	return s.String()
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeRepositoriesOutput) SetNextToken(v string) *DescribeRepositoriesOutput {
	s.NextToken = &v
	return s
}

// SetRepositories sets the Repositories field's value.
func (s *DescribeRepositoriesOutput) SetRepositories(v []*Repository) *DescribeRepositoriesOutput {
	s.Repositories = v
	return s
}

type GetAuthorizationTokenInput struct {
	_ struct{} `type:"structure"`

	// A list of AWS account IDs that are associated with the registries for which
	// to get authorization tokens. If you do not specify a registry, the default
	// registry is assumed.
	RegistryIds []*string `locationName:"registryIds" min:"1" type:"list"`
}

// String returns the string representation
func (s GetAuthorizationTokenInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetAuthorizationTokenInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetAuthorizationTokenInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "GetAuthorizationTokenInput"}
	if s.RegistryIds != nil && len(s.RegistryIds) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("RegistryIds", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetRegistryIds sets the RegistryIds field's value.
func (s *GetAuthorizationTokenInput) SetRegistryIds(v []*string) *GetAuthorizationTokenInput {
	s.RegistryIds = v
	return s
}

type GetAuthorizationTokenOutput struct {
	_ struct{} `type:"structure"`

	// A list of authorization token data objects that correspond to the registryIds
	// values in the request.
	AuthorizationData []*AuthorizationData `locationName:"authorizationData" type:"list"`
}

// String returns the string representation
func (s GetAuthorizationTokenOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetAuthorizationTokenOutput) GoString() string {
	return s.String()
}

// SetAuthorizationData sets the AuthorizationData field's value.
func (s *GetAuthorizationTokenOutput) SetAuthorizationData(v []*AuthorizationData) *GetAuthorizationTokenOutput {
	s.AuthorizationData = v
	return s
}

type GetDownloadUrlForLayerInput struct {
	_ struct{} `type:"structure"`

	// The digest of the image layer to download.
	//
	// LayerDigest is a required field
	LayerDigest *string `locationName:"layerDigest" type:"string" required:"true"`

	// The AWS account ID associated with the registry that contains the image layer
	// to download. If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository that is associated with the image layer to download.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s GetDownloadUrlForLayerInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetDownloadUrlForLayerInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetDownloadUrlForLayerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "GetDownloadUrlForLayerInput"}
	if s.LayerDigest == nil {
		invalidParams.Add(request.NewErrParamRequired("LayerDigest"))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLayerDigest sets the LayerDigest field's value.
func (s *GetDownloadUrlForLayerInput) SetLayerDigest(v string) *GetDownloadUrlForLayerInput {
	s.LayerDigest = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *GetDownloadUrlForLayerInput) SetRegistryId(v string) *GetDownloadUrlForLayerInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *GetDownloadUrlForLayerInput) SetRepositoryName(v string) *GetDownloadUrlForLayerInput {
	s.RepositoryName = &v
	return s
}

type GetDownloadUrlForLayerOutput struct {
	_ struct{} `type:"structure"`

	// The pre-signed Amazon S3 download URL for the requested layer.
	DownloadUrl *string `locationName:"downloadUrl" type:"string"`

	// The digest of the image layer to download.
	LayerDigest *string `locationName:"layerDigest" type:"string"`
}

// String returns the string representation
func (s GetDownloadUrlForLayerOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetDownloadUrlForLayerOutput) GoString() string {
	return s.String()
}

// SetDownloadUrl sets the DownloadUrl field's value.
func (s *GetDownloadUrlForLayerOutput) SetDownloadUrl(v string) *GetDownloadUrlForLayerOutput {
	s.DownloadUrl = &v
	return s
}

// SetLayerDigest sets the LayerDigest field's value.
func (s *GetDownloadUrlForLayerOutput) SetLayerDigest(v string) *GetDownloadUrlForLayerOutput {
	s.LayerDigest = &v
	return s
}

type GetLifecyclePolicyInput struct {
	_ struct{} `type:"structure"`

	// The AWS account ID associated with the registry that contains the repository.
	// If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s GetLifecyclePolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetLifecyclePolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetLifecyclePolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "GetLifecyclePolicyInput"}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetRegistryId sets the RegistryId field's value.
func (s *GetLifecyclePolicyInput) SetRegistryId(v string) *GetLifecyclePolicyInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *GetLifecyclePolicyInput) SetRepositoryName(v string) *GetLifecyclePolicyInput {
	s.RepositoryName = &v
	return s
}

type GetLifecyclePolicyOutput struct {
	_ struct{} `type:"structure"`

	// The time stamp of the last time that the lifecycle policy was run.
	LastEvaluatedAt *time.Time `locationName:"lastEvaluatedAt" type:"timestamp"`

	// The JSON lifecycle policy text.
	LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"`

	// The registry ID associated with the request.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository name associated with the request.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`
}

// String returns the string representation
func (s GetLifecyclePolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetLifecyclePolicyOutput) GoString() string {
	return s.String()
}

// SetLastEvaluatedAt sets the LastEvaluatedAt field's value.
func (s *GetLifecyclePolicyOutput) SetLastEvaluatedAt(v time.Time) *GetLifecyclePolicyOutput {
	s.LastEvaluatedAt = &v
	return s
}

// SetLifecyclePolicyText sets the LifecyclePolicyText field's value.
func (s *GetLifecyclePolicyOutput) SetLifecyclePolicyText(v string) *GetLifecyclePolicyOutput {
	s.LifecyclePolicyText = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *GetLifecyclePolicyOutput) SetRegistryId(v string) *GetLifecyclePolicyOutput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *GetLifecyclePolicyOutput) SetRepositoryName(v string) *GetLifecyclePolicyOutput {
	s.RepositoryName = &v
	return s
}

type GetLifecyclePolicyPreviewInput struct {
	_ struct{} `type:"structure"`

	// An optional parameter that filters results based on image tag status and
	// all tags, if tagged.
	Filter *LifecyclePolicyPreviewFilter `locationName:"filter" type:"structure"`

	// The list of imageIDs to be included.
	ImageIds []*ImageIdentifier `locationName:"imageIds" min:"1" type:"list"`

	// The maximum number of repository results returned by GetLifecyclePolicyPreviewRequest
	// in  paginated output. When this parameter is used, GetLifecyclePolicyPreviewRequest
	// only returns  maxResults results in a single page along with a nextToken
	// response element. The remaining results of the initial request can be seen
	// by sending  another GetLifecyclePolicyPreviewRequest request with the returned
	// nextToken  value. This value can be between 1 and 1000. If this  parameter
	// is not used, then GetLifecyclePolicyPreviewRequest returns up to  100 results
	// and a nextToken value, if  applicable. This option cannot be used when you
	// specify images with imageIds.
	MaxResults *int64 `locationName:"maxResults" min:"1" type:"integer"`

	// The nextToken value returned from a previous paginated  GetLifecyclePolicyPreviewRequest
	// request where maxResults was used and the  results exceeded the value of
	// that parameter. Pagination continues from the end of the  previous results
	// that returned the nextToken value. This value is  null when there are no
	// more results to return. This option cannot be used when you specify images
	// with imageIds.
	NextToken *string `locationName:"nextToken" type:"string"`

	// The AWS account ID associated with the registry that contains the repository.
	// If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s GetLifecyclePolicyPreviewInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetLifecyclePolicyPreviewInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetLifecyclePolicyPreviewInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "GetLifecyclePolicyPreviewInput"}
	if s.ImageIds != nil && len(s.ImageIds) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ImageIds", 1))
	}
	if s.MaxResults != nil && *s.MaxResults < 1 {
		invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetFilter sets the Filter field's value.
func (s *GetLifecyclePolicyPreviewInput) SetFilter(v *LifecyclePolicyPreviewFilter) *GetLifecyclePolicyPreviewInput {
	s.Filter = v
	return s
}

// SetImageIds sets the ImageIds field's value.
func (s *GetLifecyclePolicyPreviewInput) SetImageIds(v []*ImageIdentifier) *GetLifecyclePolicyPreviewInput {
	s.ImageIds = v
	return s
}

// SetMaxResults sets the MaxResults field's value.
func (s *GetLifecyclePolicyPreviewInput) SetMaxResults(v int64) *GetLifecyclePolicyPreviewInput {
	s.MaxResults = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *GetLifecyclePolicyPreviewInput) SetNextToken(v string) *GetLifecyclePolicyPreviewInput {
	s.NextToken = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *GetLifecyclePolicyPreviewInput) SetRegistryId(v string) *GetLifecyclePolicyPreviewInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *GetLifecyclePolicyPreviewInput) SetRepositoryName(v string) *GetLifecyclePolicyPreviewInput {
	s.RepositoryName = &v
	return s
}

type GetLifecyclePolicyPreviewOutput struct {
	_ struct{} `type:"structure"`

	// The JSON lifecycle policy text.
	LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"`

	// The nextToken value to include in a future GetLifecyclePolicyPreview request.
	// When the results of a GetLifecyclePolicyPreview request exceed maxResults,
	// this value can be used to retrieve the next page of results. This value is
	// null when there are no more results to return.
	NextToken *string `locationName:"nextToken" type:"string"`

	// The results of the lifecycle policy preview request.
	PreviewResults []*LifecyclePolicyPreviewResult `locationName:"previewResults" type:"list"`

	// The registry ID associated with the request.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository name associated with the request.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`

	// The status of the lifecycle policy preview request.
	Status *string `locationName:"status" type:"string" enum:"LifecyclePolicyPreviewStatus"`

	// The list of images that is returned as a result of the action.
	Summary *LifecyclePolicyPreviewSummary `locationName:"summary" type:"structure"`
}

// String returns the string representation
func (s GetLifecyclePolicyPreviewOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetLifecyclePolicyPreviewOutput) GoString() string {
	return s.String()
}

// SetLifecyclePolicyText sets the LifecyclePolicyText field's value.
func (s *GetLifecyclePolicyPreviewOutput) SetLifecyclePolicyText(v string) *GetLifecyclePolicyPreviewOutput {
	s.LifecyclePolicyText = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *GetLifecyclePolicyPreviewOutput) SetNextToken(v string) *GetLifecyclePolicyPreviewOutput {
	s.NextToken = &v
	return s
}

// SetPreviewResults sets the PreviewResults field's value.
func (s *GetLifecyclePolicyPreviewOutput) SetPreviewResults(v []*LifecyclePolicyPreviewResult) *GetLifecyclePolicyPreviewOutput {
	s.PreviewResults = v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *GetLifecyclePolicyPreviewOutput) SetRegistryId(v string) *GetLifecyclePolicyPreviewOutput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *GetLifecyclePolicyPreviewOutput) SetRepositoryName(v string) *GetLifecyclePolicyPreviewOutput {
	s.RepositoryName = &v
	return s
}

// SetStatus sets the Status field's value.
func (s *GetLifecyclePolicyPreviewOutput) SetStatus(v string) *GetLifecyclePolicyPreviewOutput {
	s.Status = &v
	return s
}

// SetSummary sets the Summary field's value.
func (s *GetLifecyclePolicyPreviewOutput) SetSummary(v *LifecyclePolicyPreviewSummary) *GetLifecyclePolicyPreviewOutput {
	s.Summary = v
	return s
}

type GetRepositoryPolicyInput struct {
	_ struct{} `type:"structure"`

	// The AWS account ID associated with the registry that contains the repository.
	// If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository with the policy to retrieve.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s GetRepositoryPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetRepositoryPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *GetRepositoryPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "GetRepositoryPolicyInput"}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetRegistryId sets the RegistryId field's value.
func (s *GetRepositoryPolicyInput) SetRegistryId(v string) *GetRepositoryPolicyInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *GetRepositoryPolicyInput) SetRepositoryName(v string) *GetRepositoryPolicyInput {
	s.RepositoryName = &v
	return s
}

type GetRepositoryPolicyOutput struct {
	_ struct{} `type:"structure"`

	// The JSON repository policy text associated with the repository.
	PolicyText *string `locationName:"policyText" type:"string"`

	// The registry ID associated with the request.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository name associated with the request.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`
}

// String returns the string representation
func (s GetRepositoryPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s GetRepositoryPolicyOutput) GoString() string {
	return s.String()
}

// SetPolicyText sets the PolicyText field's value.
func (s *GetRepositoryPolicyOutput) SetPolicyText(v string) *GetRepositoryPolicyOutput {
	s.PolicyText = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *GetRepositoryPolicyOutput) SetRegistryId(v string) *GetRepositoryPolicyOutput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *GetRepositoryPolicyOutput) SetRepositoryName(v string) *GetRepositoryPolicyOutput {
	s.RepositoryName = &v
	return s
}

// An object representing an Amazon ECR image.
type Image struct {
	_ struct{} `type:"structure"`

	// An object containing the image tag and image digest associated with an image.
	ImageId *ImageIdentifier `locationName:"imageId" type:"structure"`

	// The image manifest associated with the image.
	ImageManifest *string `locationName:"imageManifest" type:"string"`

	// The AWS account ID associated with the registry containing the image.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository associated with the image.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`
}

// String returns the string representation
func (s Image) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Image) GoString() string {
	return s.String()
}

// SetImageId sets the ImageId field's value.
func (s *Image) SetImageId(v *ImageIdentifier) *Image {
	s.ImageId = v
	return s
}

// SetImageManifest sets the ImageManifest field's value.
func (s *Image) SetImageManifest(v string) *Image {
	s.ImageManifest = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *Image) SetRegistryId(v string) *Image {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *Image) SetRepositoryName(v string) *Image {
	s.RepositoryName = &v
	return s
}

// An object that describes an image returned by a DescribeImages operation.
type ImageDetail struct {
	_ struct{} `type:"structure"`

	// The sha256 digest of the image manifest.
	ImageDigest *string `locationName:"imageDigest" type:"string"`

	// The date and time, expressed in standard JavaScript date format, at which
	// the current image was pushed to the repository.
	ImagePushedAt *time.Time `locationName:"imagePushedAt" type:"timestamp"`

	// The size, in bytes, of the image in the repository.
	//
	// Beginning with Docker version 1.9, the Docker client compresses image layers
	// before pushing them to a V2 Docker registry. The output of the docker images
	// command shows the uncompressed image size, so it may return a larger image
	// size than the image sizes returned by DescribeImages.
	ImageSizeInBytes *int64 `locationName:"imageSizeInBytes" type:"long"`

	// The list of tags associated with this image.
	ImageTags []*string `locationName:"imageTags" type:"list"`

	// The AWS account ID associated with the registry to which this image belongs.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository to which this image belongs.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`
}

// String returns the string representation
func (s ImageDetail) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ImageDetail) GoString() string {
	return s.String()
}

// SetImageDigest sets the ImageDigest field's value.
func (s *ImageDetail) SetImageDigest(v string) *ImageDetail {
	s.ImageDigest = &v
	return s
}

// SetImagePushedAt sets the ImagePushedAt field's value.
func (s *ImageDetail) SetImagePushedAt(v time.Time) *ImageDetail {
	s.ImagePushedAt = &v
	return s
}

// SetImageSizeInBytes sets the ImageSizeInBytes field's value.
func (s *ImageDetail) SetImageSizeInBytes(v int64) *ImageDetail {
	s.ImageSizeInBytes = &v
	return s
}

// SetImageTags sets the ImageTags field's value.
func (s *ImageDetail) SetImageTags(v []*string) *ImageDetail {
	s.ImageTags = v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *ImageDetail) SetRegistryId(v string) *ImageDetail {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *ImageDetail) SetRepositoryName(v string) *ImageDetail {
	s.RepositoryName = &v
	return s
}

// An object representing an Amazon ECR image failure.
type ImageFailure struct {
	_ struct{} `type:"structure"`

	// The code associated with the failure.
	FailureCode *string `locationName:"failureCode" type:"string" enum:"ImageFailureCode"`

	// The reason for the failure.
	FailureReason *string `locationName:"failureReason" type:"string"`

	// The image ID associated with the failure.
	ImageId *ImageIdentifier `locationName:"imageId" type:"structure"`
}

// String returns the string representation
func (s ImageFailure) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ImageFailure) GoString() string {
	return s.String()
}

// SetFailureCode sets the FailureCode field's value.
func (s *ImageFailure) SetFailureCode(v string) *ImageFailure {
	s.FailureCode = &v
	return s
}

// SetFailureReason sets the FailureReason field's value.
func (s *ImageFailure) SetFailureReason(v string) *ImageFailure {
	s.FailureReason = &v
	return s
}

// SetImageId sets the ImageId field's value.
func (s *ImageFailure) SetImageId(v *ImageIdentifier) *ImageFailure {
	s.ImageId = v
	return s
}

// An object with identifying information for an Amazon ECR image.
type ImageIdentifier struct {
	_ struct{} `type:"structure"`

	// The sha256 digest of the image manifest.
	ImageDigest *string `locationName:"imageDigest" type:"string"`

	// The tag used for the image.
	ImageTag *string `locationName:"imageTag" type:"string"`
}

// String returns the string representation
func (s ImageIdentifier) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ImageIdentifier) GoString() string {
	return s.String()
}

// SetImageDigest sets the ImageDigest field's value.
func (s *ImageIdentifier) SetImageDigest(v string) *ImageIdentifier {
	s.ImageDigest = &v
	return s
}

// SetImageTag sets the ImageTag field's value.
func (s *ImageIdentifier) SetImageTag(v string) *ImageIdentifier {
	s.ImageTag = &v
	return s
}

type InitiateLayerUploadInput struct {
	_ struct{} `type:"structure"`

	// The AWS account ID associated with the registry to which you intend to upload
	// layers. If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository to which you intend to upload layers.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s InitiateLayerUploadInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s InitiateLayerUploadInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *InitiateLayerUploadInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "InitiateLayerUploadInput"}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetRegistryId sets the RegistryId field's value.
func (s *InitiateLayerUploadInput) SetRegistryId(v string) *InitiateLayerUploadInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *InitiateLayerUploadInput) SetRepositoryName(v string) *InitiateLayerUploadInput {
	s.RepositoryName = &v
	return s
}

type InitiateLayerUploadOutput struct {
	_ struct{} `type:"structure"`

	// The size, in bytes, that Amazon ECR expects future layer part uploads to
	// be.
	PartSize *int64 `locationName:"partSize" type:"long"`

	// The upload ID for the layer upload. This parameter is passed to further UploadLayerPart
	// and CompleteLayerUpload operations.
	UploadId *string `locationName:"uploadId" type:"string"`
}

// String returns the string representation
func (s InitiateLayerUploadOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s InitiateLayerUploadOutput) GoString() string {
	return s.String()
}

// SetPartSize sets the PartSize field's value.
func (s *InitiateLayerUploadOutput) SetPartSize(v int64) *InitiateLayerUploadOutput {
	s.PartSize = &v
	return s
}

// SetUploadId sets the UploadId field's value.
func (s *InitiateLayerUploadOutput) SetUploadId(v string) *InitiateLayerUploadOutput {
	s.UploadId = &v
	return s
}

// An object representing an Amazon ECR image layer.
type Layer struct {
	_ struct{} `type:"structure"`

	// The availability status of the image layer.
	LayerAvailability *string `locationName:"layerAvailability" type:"string" enum:"LayerAvailability"`

	// The sha256 digest of the image layer.
	LayerDigest *string `locationName:"layerDigest" type:"string"`

	// The size, in bytes, of the image layer.
	LayerSize *int64 `locationName:"layerSize" type:"long"`

	// The media type of the layer, such as application/vnd.docker.image.rootfs.diff.tar.gzip
	// or application/vnd.oci.image.layer.v1.tar+gzip.
	MediaType *string `locationName:"mediaType" type:"string"`
}

// String returns the string representation
func (s Layer) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Layer) GoString() string {
	return s.String()
}

// SetLayerAvailability sets the LayerAvailability field's value.
func (s *Layer) SetLayerAvailability(v string) *Layer {
	s.LayerAvailability = &v
	return s
}

// SetLayerDigest sets the LayerDigest field's value.
func (s *Layer) SetLayerDigest(v string) *Layer {
	s.LayerDigest = &v
	return s
}

// SetLayerSize sets the LayerSize field's value.
func (s *Layer) SetLayerSize(v int64) *Layer {
	s.LayerSize = &v
	return s
}

// SetMediaType sets the MediaType field's value.
func (s *Layer) SetMediaType(v string) *Layer {
	s.MediaType = &v
	return s
}

// An object representing an Amazon ECR image layer failure.
type LayerFailure struct {
	_ struct{} `type:"structure"`

	// The failure code associated with the failure.
	FailureCode *string `locationName:"failureCode" type:"string" enum:"LayerFailureCode"`

	// The reason for the failure.
	FailureReason *string `locationName:"failureReason" type:"string"`

	// The layer digest associated with the failure.
	LayerDigest *string `locationName:"layerDigest" type:"string"`
}

// String returns the string representation
func (s LayerFailure) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LayerFailure) GoString() string {
	return s.String()
}

// SetFailureCode sets the FailureCode field's value.
func (s *LayerFailure) SetFailureCode(v string) *LayerFailure {
	s.FailureCode = &v
	return s
}

// SetFailureReason sets the FailureReason field's value.
func (s *LayerFailure) SetFailureReason(v string) *LayerFailure {
	s.FailureReason = &v
	return s
}

// SetLayerDigest sets the LayerDigest field's value.
func (s *LayerFailure) SetLayerDigest(v string) *LayerFailure {
	s.LayerDigest = &v
	return s
}

// The filter for the lifecycle policy preview.
type LifecyclePolicyPreviewFilter struct {
	_ struct{} `type:"structure"`

	// The tag status of the image.
	TagStatus *string `locationName:"tagStatus" type:"string" enum:"TagStatus"`
}

// String returns the string representation
func (s LifecyclePolicyPreviewFilter) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LifecyclePolicyPreviewFilter) GoString() string {
	return s.String()
}

// SetTagStatus sets the TagStatus field's value.
func (s *LifecyclePolicyPreviewFilter) SetTagStatus(v string) *LifecyclePolicyPreviewFilter {
	s.TagStatus = &v
	return s
}

// The result of the lifecycle policy preview.
type LifecyclePolicyPreviewResult struct {
	_ struct{} `type:"structure"`

	// The type of action to be taken.
	Action *LifecyclePolicyRuleAction `locationName:"action" type:"structure"`

	// The priority of the applied rule.
	AppliedRulePriority *int64 `locationName:"appliedRulePriority" min:"1" type:"integer"`

	// The sha256 digest of the image manifest.
	ImageDigest *string `locationName:"imageDigest" type:"string"`

	// The date and time, expressed in standard JavaScript date format, at which
	// the current image was pushed to the repository.
	ImagePushedAt *time.Time `locationName:"imagePushedAt" type:"timestamp"`

	// The list of tags associated with this image.
	ImageTags []*string `locationName:"imageTags" type:"list"`
}

// String returns the string representation
func (s LifecyclePolicyPreviewResult) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LifecyclePolicyPreviewResult) GoString() string {
	return s.String()
}

// SetAction sets the Action field's value.
func (s *LifecyclePolicyPreviewResult) SetAction(v *LifecyclePolicyRuleAction) *LifecyclePolicyPreviewResult {
	s.Action = v
	return s
}

// SetAppliedRulePriority sets the AppliedRulePriority field's value.
func (s *LifecyclePolicyPreviewResult) SetAppliedRulePriority(v int64) *LifecyclePolicyPreviewResult {
	s.AppliedRulePriority = &v
	return s
}

// SetImageDigest sets the ImageDigest field's value.
func (s *LifecyclePolicyPreviewResult) SetImageDigest(v string) *LifecyclePolicyPreviewResult {
	s.ImageDigest = &v
	return s
}

// SetImagePushedAt sets the ImagePushedAt field's value.
func (s *LifecyclePolicyPreviewResult) SetImagePushedAt(v time.Time) *LifecyclePolicyPreviewResult {
	s.ImagePushedAt = &v
	return s
}

// SetImageTags sets the ImageTags field's value.
func (s *LifecyclePolicyPreviewResult) SetImageTags(v []*string) *LifecyclePolicyPreviewResult {
	s.ImageTags = v
	return s
}

// The summary of the lifecycle policy preview request.
type LifecyclePolicyPreviewSummary struct {
	_ struct{} `type:"structure"`

	// The number of expiring images.
	ExpiringImageTotalCount *int64 `locationName:"expiringImageTotalCount" type:"integer"`
}

// String returns the string representation
func (s LifecyclePolicyPreviewSummary) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LifecyclePolicyPreviewSummary) GoString() string {
	return s.String()
}

// SetExpiringImageTotalCount sets the ExpiringImageTotalCount field's value.
func (s *LifecyclePolicyPreviewSummary) SetExpiringImageTotalCount(v int64) *LifecyclePolicyPreviewSummary {
	s.ExpiringImageTotalCount = &v
	return s
}

// The type of action to be taken.
type LifecyclePolicyRuleAction struct {
	_ struct{} `type:"structure"`

	// The type of action to be taken.
	Type *string `locationName:"type" type:"string" enum:"ImageActionType"`
}

// String returns the string representation
func (s LifecyclePolicyRuleAction) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LifecyclePolicyRuleAction) GoString() string {
	return s.String()
}

// SetType sets the Type field's value.
func (s *LifecyclePolicyRuleAction) SetType(v string) *LifecyclePolicyRuleAction {
	s.Type = &v
	return s
}

// An object representing a filter on a ListImages operation.
type ListImagesFilter struct {
	_ struct{} `type:"structure"`

	// The tag status with which to filter your ListImages results. You can filter
	// results based on whether they are TAGGED or UNTAGGED.
	TagStatus *string `locationName:"tagStatus" type:"string" enum:"TagStatus"`
}

// String returns the string representation
func (s ListImagesFilter) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ListImagesFilter) GoString() string {
	return s.String()
}

// SetTagStatus sets the TagStatus field's value.
func (s *ListImagesFilter) SetTagStatus(v string) *ListImagesFilter {
	s.TagStatus = &v
	return s
}

type ListImagesInput struct {
	_ struct{} `type:"structure"`

	// The filter key and value with which to filter your ListImages results.
	Filter *ListImagesFilter `locationName:"filter" type:"structure"`

	// The maximum number of image results returned by ListImages in paginated output.
	// When this parameter is used, ListImages only returns maxResults results in
	// a single page along with a nextToken response element. The remaining results
	// of the initial request can be seen by sending another ListImages request
	// with the returned nextToken value. This value can be between 1 and 1000.
	// If this parameter is not used, then ListImages returns up to 100 results
	// and a nextToken value, if applicable.
	MaxResults *int64 `locationName:"maxResults" min:"1" type:"integer"`

	// The nextToken value returned from a previous paginated ListImages request
	// where maxResults was used and the results exceeded the value of that parameter.
	// Pagination continues from the end of the previous results that returned the
	// nextToken value. This value is null when there are no more results to return.
	//
	// This token should be treated as an opaque identifier that is only used to
	// retrieve the next items in a list and not for other programmatic purposes.
	NextToken *string `locationName:"nextToken" type:"string"`

	// The AWS account ID associated with the registry that contains the repository
	// in which to list images. If you do not specify a registry, the default registry
	// is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository with image IDs to be listed.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s ListImagesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ListImagesInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ListImagesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ListImagesInput"}
	if s.MaxResults != nil && *s.MaxResults < 1 {
		invalidParams.Add(request.NewErrParamMinValue("MaxResults", 1))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetFilter sets the Filter field's value.
func (s *ListImagesInput) SetFilter(v *ListImagesFilter) *ListImagesInput {
	s.Filter = v
	return s
}

// SetMaxResults sets the MaxResults field's value.
func (s *ListImagesInput) SetMaxResults(v int64) *ListImagesInput {
	s.MaxResults = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *ListImagesInput) SetNextToken(v string) *ListImagesInput {
	s.NextToken = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *ListImagesInput) SetRegistryId(v string) *ListImagesInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *ListImagesInput) SetRepositoryName(v string) *ListImagesInput {
	s.RepositoryName = &v
	return s
}

type ListImagesOutput struct {
	_ struct{} `type:"structure"`

	// The list of image IDs for the requested repository.
	ImageIds []*ImageIdentifier `locationName:"imageIds" min:"1" type:"list"`

	// The nextToken value to include in a future ListImages request. When the results
	// of a ListImages request exceed maxResults, this value can be used to retrieve
	// the next page of results. This value is null when there are no more results
	// to return.
	NextToken *string `locationName:"nextToken" type:"string"`
}

// String returns the string representation
func (s ListImagesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ListImagesOutput) GoString() string {
	return s.String()
}

// SetImageIds sets the ImageIds field's value.
func (s *ListImagesOutput) SetImageIds(v []*ImageIdentifier) *ListImagesOutput {
	s.ImageIds = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *ListImagesOutput) SetNextToken(v string) *ListImagesOutput {
	s.NextToken = &v
	return s
}

type ListTagsForResourceInput struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) that identifies the resource for which to
	// list the tags. Currently, the only supported resource is an Amazon ECR repository.
	//
	// ResourceArn is a required field
	ResourceArn *string `locationName:"resourceArn" type:"string" required:"true"`
}

// String returns the string representation
func (s ListTagsForResourceInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ListTagsForResourceInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ListTagsForResourceInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ListTagsForResourceInput"}
	if s.ResourceArn == nil {
		invalidParams.Add(request.NewErrParamRequired("ResourceArn"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetResourceArn sets the ResourceArn field's value.
func (s *ListTagsForResourceInput) SetResourceArn(v string) *ListTagsForResourceInput {
	s.ResourceArn = &v
	return s
}

type ListTagsForResourceOutput struct {
	_ struct{} `type:"structure"`

	// The tags for the resource.
	Tags []*Tag `locationName:"tags" type:"list"`
}

// String returns the string representation
func (s ListTagsForResourceOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ListTagsForResourceOutput) GoString() string {
	return s.String()
}

// SetTags sets the Tags field's value.
func (s *ListTagsForResourceOutput) SetTags(v []*Tag) *ListTagsForResourceOutput {
	s.Tags = v
	return s
}

type PutImageInput struct {
	_ struct{} `type:"structure"`

	// The image manifest corresponding to the image to be uploaded.
	//
	// ImageManifest is a required field
	ImageManifest *string `locationName:"imageManifest" type:"string" required:"true"`

	// The tag to associate with the image. This parameter is required for images
	// that use the Docker Image Manifest V2 Schema 2 or OCI formats.
	ImageTag *string `locationName:"imageTag" type:"string"`

	// The AWS account ID associated with the registry that contains the repository
	// in which to put the image. If you do not specify a registry, the default
	// registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository in which to put the image.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s PutImageInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutImageInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutImageInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutImageInput"}
	if s.ImageManifest == nil {
		invalidParams.Add(request.NewErrParamRequired("ImageManifest"))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetImageManifest sets the ImageManifest field's value.
func (s *PutImageInput) SetImageManifest(v string) *PutImageInput {
	s.ImageManifest = &v
	return s
}

// SetImageTag sets the ImageTag field's value.
func (s *PutImageInput) SetImageTag(v string) *PutImageInput {
	s.ImageTag = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *PutImageInput) SetRegistryId(v string) *PutImageInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *PutImageInput) SetRepositoryName(v string) *PutImageInput {
	s.RepositoryName = &v
	return s
}

type PutImageOutput struct {
	_ struct{} `type:"structure"`

	// Details of the image uploaded.
	Image *Image `locationName:"image" type:"structure"`
}

// String returns the string representation
func (s PutImageOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutImageOutput) GoString() string {
	return s.String()
}

// SetImage sets the Image field's value.
func (s *PutImageOutput) SetImage(v *Image) *PutImageOutput {
	s.Image = v
	return s
}

type PutLifecyclePolicyInput struct {
	_ struct{} `type:"structure"`

	// The JSON repository policy text to apply to the repository.
	//
	// LifecyclePolicyText is a required field
	LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string" required:"true"`

	// The AWS account ID associated with the registry that contains the repository.
	// If you do  not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository to receive the policy.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s PutLifecyclePolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutLifecyclePolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutLifecyclePolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutLifecyclePolicyInput"}
	if s.LifecyclePolicyText == nil {
		invalidParams.Add(request.NewErrParamRequired("LifecyclePolicyText"))
	}
	if s.LifecyclePolicyText != nil && len(*s.LifecyclePolicyText) < 100 {
		invalidParams.Add(request.NewErrParamMinLen("LifecyclePolicyText", 100))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLifecyclePolicyText sets the LifecyclePolicyText field's value.
func (s *PutLifecyclePolicyInput) SetLifecyclePolicyText(v string) *PutLifecyclePolicyInput {
	s.LifecyclePolicyText = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *PutLifecyclePolicyInput) SetRegistryId(v string) *PutLifecyclePolicyInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *PutLifecyclePolicyInput) SetRepositoryName(v string) *PutLifecyclePolicyInput {
	s.RepositoryName = &v
	return s
}

type PutLifecyclePolicyOutput struct {
	_ struct{} `type:"structure"`

	// The JSON repository policy text.
	LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"`

	// The registry ID associated with the request.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository name associated with the request.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`
}

// String returns the string representation
func (s PutLifecyclePolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutLifecyclePolicyOutput) GoString() string {
	return s.String()
}

// SetLifecyclePolicyText sets the LifecyclePolicyText field's value.
func (s *PutLifecyclePolicyOutput) SetLifecyclePolicyText(v string) *PutLifecyclePolicyOutput {
	s.LifecyclePolicyText = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *PutLifecyclePolicyOutput) SetRegistryId(v string) *PutLifecyclePolicyOutput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *PutLifecyclePolicyOutput) SetRepositoryName(v string) *PutLifecyclePolicyOutput {
	s.RepositoryName = &v
	return s
}

// An object representing a repository.
type Repository struct {
	_ struct{} `type:"structure"`

	// The date and time, in JavaScript date format, when the repository was created.
	CreatedAt *time.Time `locationName:"createdAt" type:"timestamp"`

	// The AWS account ID associated with the registry that contains the repository.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The Amazon Resource Name (ARN) that identifies the repository. The ARN contains
	// the arn:aws:ecr namespace, followed by the region of the repository, AWS
	// account ID of the repository owner, repository namespace, and repository
	// name. For example, arn:aws:ecr:region:012345678910:repository/test.
	RepositoryArn *string `locationName:"repositoryArn" type:"string"`

	// The name of the repository.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`

	// The URI for the repository. You can use this URI for Docker push or pull
	// operations.
	RepositoryUri *string `locationName:"repositoryUri" type:"string"`
}

// String returns the string representation
func (s Repository) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Repository) GoString() string {
	return s.String()
}

// SetCreatedAt sets the CreatedAt field's value.
func (s *Repository) SetCreatedAt(v time.Time) *Repository {
	s.CreatedAt = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *Repository) SetRegistryId(v string) *Repository {
	s.RegistryId = &v
	return s
}

// SetRepositoryArn sets the RepositoryArn field's value.
func (s *Repository) SetRepositoryArn(v string) *Repository {
	s.RepositoryArn = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *Repository) SetRepositoryName(v string) *Repository {
	s.RepositoryName = &v
	return s
}

// SetRepositoryUri sets the RepositoryUri field's value.
func (s *Repository) SetRepositoryUri(v string) *Repository {
	s.RepositoryUri = &v
	return s
}

type SetRepositoryPolicyInput struct {
	_ struct{} `type:"structure"`

	// If the policy you are attempting to set on a repository policy would prevent
	// you from setting another policy in the future, you must force the SetRepositoryPolicy
	// operation. This is intended to prevent accidental repository lock outs.
	Force *bool `locationName:"force" type:"boolean"`

	// The JSON repository policy text to apply to the repository.
	//
	// PolicyText is a required field
	PolicyText *string `locationName:"policyText" type:"string" required:"true"`

	// The AWS account ID associated with the registry that contains the repository.
	// If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository to receive the policy.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s SetRepositoryPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetRepositoryPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *SetRepositoryPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "SetRepositoryPolicyInput"}
	if s.PolicyText == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyText"))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetForce sets the Force field's value.
func (s *SetRepositoryPolicyInput) SetForce(v bool) *SetRepositoryPolicyInput {
	s.Force = &v
	return s
}

// SetPolicyText sets the PolicyText field's value.
func (s *SetRepositoryPolicyInput) SetPolicyText(v string) *SetRepositoryPolicyInput {
	s.PolicyText = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *SetRepositoryPolicyInput) SetRegistryId(v string) *SetRepositoryPolicyInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *SetRepositoryPolicyInput) SetRepositoryName(v string) *SetRepositoryPolicyInput {
	s.RepositoryName = &v
	return s
}

type SetRepositoryPolicyOutput struct {
	_ struct{} `type:"structure"`

	// The JSON repository policy text applied to the repository.
	PolicyText *string `locationName:"policyText" type:"string"`

	// The registry ID associated with the request.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository name associated with the request.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`
}

// String returns the string representation
func (s SetRepositoryPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetRepositoryPolicyOutput) GoString() string {
	return s.String()
}

// SetPolicyText sets the PolicyText field's value.
func (s *SetRepositoryPolicyOutput) SetPolicyText(v string) *SetRepositoryPolicyOutput {
	s.PolicyText = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *SetRepositoryPolicyOutput) SetRegistryId(v string) *SetRepositoryPolicyOutput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *SetRepositoryPolicyOutput) SetRepositoryName(v string) *SetRepositoryPolicyOutput {
	s.RepositoryName = &v
	return s
}

type StartLifecyclePolicyPreviewInput struct {
	_ struct{} `type:"structure"`

	// The policy to be evaluated against. If you do not specify a policy, the current
	// policy for the repository is used.
	LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"`

	// The AWS account ID associated with the registry that contains the repository.
	// If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository to be evaluated.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`
}

// String returns the string representation
func (s StartLifecyclePolicyPreviewInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s StartLifecyclePolicyPreviewInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *StartLifecyclePolicyPreviewInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "StartLifecyclePolicyPreviewInput"}
	if s.LifecyclePolicyText != nil && len(*s.LifecyclePolicyText) < 100 {
		invalidParams.Add(request.NewErrParamMinLen("LifecyclePolicyText", 100))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLifecyclePolicyText sets the LifecyclePolicyText field's value.
func (s *StartLifecyclePolicyPreviewInput) SetLifecyclePolicyText(v string) *StartLifecyclePolicyPreviewInput {
	s.LifecyclePolicyText = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *StartLifecyclePolicyPreviewInput) SetRegistryId(v string) *StartLifecyclePolicyPreviewInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *StartLifecyclePolicyPreviewInput) SetRepositoryName(v string) *StartLifecyclePolicyPreviewInput {
	s.RepositoryName = &v
	return s
}

type StartLifecyclePolicyPreviewOutput struct {
	_ struct{} `type:"structure"`

	// The JSON repository policy text.
	LifecyclePolicyText *string `locationName:"lifecyclePolicyText" min:"100" type:"string"`

	// The registry ID associated with the request.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository name associated with the request.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`

	// The status of the lifecycle policy preview request.
	Status *string `locationName:"status" type:"string" enum:"LifecyclePolicyPreviewStatus"`
}

// String returns the string representation
func (s StartLifecyclePolicyPreviewOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s StartLifecyclePolicyPreviewOutput) GoString() string {
	return s.String()
}

// SetLifecyclePolicyText sets the LifecyclePolicyText field's value.
func (s *StartLifecyclePolicyPreviewOutput) SetLifecyclePolicyText(v string) *StartLifecyclePolicyPreviewOutput {
	s.LifecyclePolicyText = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *StartLifecyclePolicyPreviewOutput) SetRegistryId(v string) *StartLifecyclePolicyPreviewOutput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *StartLifecyclePolicyPreviewOutput) SetRepositoryName(v string) *StartLifecyclePolicyPreviewOutput {
	s.RepositoryName = &v
	return s
}

// SetStatus sets the Status field's value.
func (s *StartLifecyclePolicyPreviewOutput) SetStatus(v string) *StartLifecyclePolicyPreviewOutput {
	s.Status = &v
	return s
}

// The metadata that you apply to a resource to help you categorize and organize
// them. Each tag consists of a key and an optional value, both of which you
// define. Tag keys can have a maximum character length of 128 characters, and
// tag values can have a maximum length of 256 characters.
type Tag struct {
	_ struct{} `type:"structure"`

	// One part of a key-value pair that make up a tag. A key is a general label
	// that acts like a category for more specific tag values.
	Key *string `type:"string"`

	// The optional part of a key-value pair that make up a tag. A value acts as
	// a descriptor within a tag category (key).
	Value *string `type:"string"`
}

// String returns the string representation
func (s Tag) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Tag) GoString() string {
	return s.String()
}

// SetKey sets the Key field's value.
func (s *Tag) SetKey(v string) *Tag {
	s.Key = &v
	return s
}

// SetValue sets the Value field's value.
func (s *Tag) SetValue(v string) *Tag {
	s.Value = &v
	return s
}

type TagResourceInput struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) of the the resource to which to add tags.
	// Currently, the only supported resource is an Amazon ECR repository.
	//
	// ResourceArn is a required field
	ResourceArn *string `locationName:"resourceArn" type:"string" required:"true"`

	// The tags to add to the resource. A tag is an array of key-value pairs. Tag
	// keys can have a maximum character length of 128 characters, and tag values
	// can have a maximum length of 256 characters.
	//
	// Tags is a required field
	Tags []*Tag `locationName:"tags" type:"list" required:"true"`
}

// String returns the string representation
func (s TagResourceInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s TagResourceInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *TagResourceInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "TagResourceInput"}
	if s.ResourceArn == nil {
		invalidParams.Add(request.NewErrParamRequired("ResourceArn"))
	}
	if s.Tags == nil {
		invalidParams.Add(request.NewErrParamRequired("Tags"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetResourceArn sets the ResourceArn field's value.
func (s *TagResourceInput) SetResourceArn(v string) *TagResourceInput {
	s.ResourceArn = &v
	return s
}

// SetTags sets the Tags field's value.
func (s *TagResourceInput) SetTags(v []*Tag) *TagResourceInput {
	s.Tags = v
	return s
}

type TagResourceOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s TagResourceOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s TagResourceOutput) GoString() string {
	return s.String()
}

type UntagResourceInput struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) of the resource from which to remove tags.
	// Currently, the only supported resource is an Amazon ECR repository.
	//
	// ResourceArn is a required field
	ResourceArn *string `locationName:"resourceArn" type:"string" required:"true"`

	// The keys of the tags to be removed.
	//
	// TagKeys is a required field
	TagKeys []*string `locationName:"tagKeys" type:"list" required:"true"`
}

// String returns the string representation
func (s UntagResourceInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s UntagResourceInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *UntagResourceInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "UntagResourceInput"}
	if s.ResourceArn == nil {
		invalidParams.Add(request.NewErrParamRequired("ResourceArn"))
	}
	if s.TagKeys == nil {
		invalidParams.Add(request.NewErrParamRequired("TagKeys"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetResourceArn sets the ResourceArn field's value.
func (s *UntagResourceInput) SetResourceArn(v string) *UntagResourceInput {
	s.ResourceArn = &v
	return s
}

// SetTagKeys sets the TagKeys field's value.
func (s *UntagResourceInput) SetTagKeys(v []*string) *UntagResourceInput {
	s.TagKeys = v
	return s
}

type UntagResourceOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s UntagResourceOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s UntagResourceOutput) GoString() string {
	return s.String()
}

type UploadLayerPartInput struct {
	_ struct{} `type:"structure"`

	// The base64-encoded layer part payload.
	//
	// LayerPartBlob is automatically base64 encoded/decoded by the SDK.
	//
	// LayerPartBlob is a required field
	LayerPartBlob []byte `locationName:"layerPartBlob" type:"blob" required:"true"`

	// The integer value of the first byte of the layer part.
	//
	// PartFirstByte is a required field
	PartFirstByte *int64 `locationName:"partFirstByte" type:"long" required:"true"`

	// The integer value of the last byte of the layer part.
	//
	// PartLastByte is a required field
	PartLastByte *int64 `locationName:"partLastByte" type:"long" required:"true"`

	// The AWS account ID associated with the registry to which you are uploading
	// layer parts. If you do not specify a registry, the default registry is assumed.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The name of the repository to which you are uploading layer parts.
	//
	// RepositoryName is a required field
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string" required:"true"`

	// The upload ID from a previous InitiateLayerUpload operation to associate
	// with the layer part upload.
	//
	// UploadId is a required field
	UploadId *string `locationName:"uploadId" type:"string" required:"true"`
}

// String returns the string representation
func (s UploadLayerPartInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s UploadLayerPartInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *UploadLayerPartInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "UploadLayerPartInput"}
	if s.LayerPartBlob == nil {
		invalidParams.Add(request.NewErrParamRequired("LayerPartBlob"))
	}
	if s.PartFirstByte == nil {
		invalidParams.Add(request.NewErrParamRequired("PartFirstByte"))
	}
	if s.PartLastByte == nil {
		invalidParams.Add(request.NewErrParamRequired("PartLastByte"))
	}
	if s.RepositoryName == nil {
		invalidParams.Add(request.NewErrParamRequired("RepositoryName"))
	}
	if s.RepositoryName != nil && len(*s.RepositoryName) < 2 {
		invalidParams.Add(request.NewErrParamMinLen("RepositoryName", 2))
	}
	if s.UploadId == nil {
		invalidParams.Add(request.NewErrParamRequired("UploadId"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLayerPartBlob sets the LayerPartBlob field's value.
func (s *UploadLayerPartInput) SetLayerPartBlob(v []byte) *UploadLayerPartInput {
	s.LayerPartBlob = v
	return s
}

// SetPartFirstByte sets the PartFirstByte field's value.
func (s *UploadLayerPartInput) SetPartFirstByte(v int64) *UploadLayerPartInput {
	s.PartFirstByte = &v
	return s
}

// SetPartLastByte sets the PartLastByte field's value.
func (s *UploadLayerPartInput) SetPartLastByte(v int64) *UploadLayerPartInput {
	s.PartLastByte = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *UploadLayerPartInput) SetRegistryId(v string) *UploadLayerPartInput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *UploadLayerPartInput) SetRepositoryName(v string) *UploadLayerPartInput {
	s.RepositoryName = &v
	return s
}

// SetUploadId sets the UploadId field's value.
func (s *UploadLayerPartInput) SetUploadId(v string) *UploadLayerPartInput {
	s.UploadId = &v
	return s
}

type UploadLayerPartOutput struct {
	_ struct{} `type:"structure"`

	// The integer value of the last byte received in the request.
	LastByteReceived *int64 `locationName:"lastByteReceived" type:"long"`

	// The registry ID associated with the request.
	RegistryId *string `locationName:"registryId" type:"string"`

	// The repository name associated with the request.
	RepositoryName *string `locationName:"repositoryName" min:"2" type:"string"`

	// The upload ID associated with the request.
	UploadId *string `locationName:"uploadId" type:"string"`
}

// String returns the string representation
func (s UploadLayerPartOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s UploadLayerPartOutput) GoString() string {
	return s.String()
}

// SetLastByteReceived sets the LastByteReceived field's value.
func (s *UploadLayerPartOutput) SetLastByteReceived(v int64) *UploadLayerPartOutput {
	s.LastByteReceived = &v
	return s
}

// SetRegistryId sets the RegistryId field's value.
func (s *UploadLayerPartOutput) SetRegistryId(v string) *UploadLayerPartOutput {
	s.RegistryId = &v
	return s
}

// SetRepositoryName sets the RepositoryName field's value.
func (s *UploadLayerPartOutput) SetRepositoryName(v string) *UploadLayerPartOutput {
	s.RepositoryName = &v
	return s
}

// SetUploadId sets the UploadId field's value.
func (s *UploadLayerPartOutput) SetUploadId(v string) *UploadLayerPartOutput {
	s.UploadId = &v
	return s
}

const (
	// ImageActionTypeExpire is a ImageActionType enum value
	ImageActionTypeExpire = "EXPIRE"
)

const (
	// ImageFailureCodeInvalidImageDigest is a ImageFailureCode enum value
	ImageFailureCodeInvalidImageDigest = "InvalidImageDigest"

	// ImageFailureCodeInvalidImageTag is a ImageFailureCode enum value
	ImageFailureCodeInvalidImageTag = "InvalidImageTag"

	// ImageFailureCodeImageTagDoesNotMatchDigest is a ImageFailureCode enum value
	ImageFailureCodeImageTagDoesNotMatchDigest = "ImageTagDoesNotMatchDigest"

	// ImageFailureCodeImageNotFound is a ImageFailureCode enum value
	ImageFailureCodeImageNotFound = "ImageNotFound"

	// ImageFailureCodeMissingDigestAndTag is a ImageFailureCode enum value
	ImageFailureCodeMissingDigestAndTag = "MissingDigestAndTag"
)

const (
	// LayerAvailabilityAvailable is a LayerAvailability enum value
	LayerAvailabilityAvailable = "AVAILABLE"

	// LayerAvailabilityUnavailable is a LayerAvailability enum value
	LayerAvailabilityUnavailable = "UNAVAILABLE"
)

const (
	// LayerFailureCodeInvalidLayerDigest is a LayerFailureCode enum value
	LayerFailureCodeInvalidLayerDigest = "InvalidLayerDigest"

	// LayerFailureCodeMissingLayerDigest is a LayerFailureCode enum value
	LayerFailureCodeMissingLayerDigest = "MissingLayerDigest"
)

const (
	// LifecyclePolicyPreviewStatusInProgress is a LifecyclePolicyPreviewStatus enum value
	LifecyclePolicyPreviewStatusInProgress = "IN_PROGRESS"

	// LifecyclePolicyPreviewStatusComplete is a LifecyclePolicyPreviewStatus enum value
	LifecyclePolicyPreviewStatusComplete = "COMPLETE"

	// LifecyclePolicyPreviewStatusExpired is a LifecyclePolicyPreviewStatus enum value
	LifecyclePolicyPreviewStatusExpired = "EXPIRED"

	// LifecyclePolicyPreviewStatusFailed is a LifecyclePolicyPreviewStatus enum value
	LifecyclePolicyPreviewStatusFailed = "FAILED"
)

const (
	// TagStatusTagged is a TagStatus enum value
	TagStatusTagged = "TAGGED"

	// TagStatusUntagged is a TagStatus enum value
	TagStatusUntagged = "UNTAGGED"

	// TagStatusAny is a TagStatus enum value
	TagStatusAny = "ANY"
)
