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

package kms

import (
	"fmt"
	"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 opCancelKeyDeletion = "CancelKeyDeletion"

// CancelKeyDeletionRequest generates a "aws/request.Request" representing the
// client's request for the CancelKeyDeletion 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 CancelKeyDeletion for more information on using the CancelKeyDeletion
// 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 CancelKeyDeletionRequest method.
//    req, resp := client.CancelKeyDeletionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/CancelKeyDeletion
func (c *KMS) CancelKeyDeletionRequest(input *CancelKeyDeletionInput) (req *request.Request, output *CancelKeyDeletionOutput) {
	op := &request.Operation{
		Name:       opCancelKeyDeletion,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CancelKeyDeletionInput{}
	}

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

// CancelKeyDeletion API operation for AWS Key Management Service.
//
// Cancels the deletion of a customer master key (CMK). When this operation
// is successful, the CMK is set to the Disabled state. To enable a CMK, use
// EnableKey. You cannot perform this operation on a CMK in a different AWS
// account.
//
// For more information about scheduling and canceling deletion of a CMK, see
// Deleting Customer Master Keys (http://docs.aws.amazon.com/kms/latest/developerguide/deleting-keys.html)
// in the AWS Key Management Service Developer Guide.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation CancelKeyDeletion for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/CancelKeyDeletion
func (c *KMS) CancelKeyDeletion(input *CancelKeyDeletionInput) (*CancelKeyDeletionOutput, error) {
	req, out := c.CancelKeyDeletionRequest(input)
	return out, req.Send()
}

// CancelKeyDeletionWithContext is the same as CancelKeyDeletion with the addition of
// the ability to pass a context and additional request options.
//
// See CancelKeyDeletion 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 *KMS) CancelKeyDeletionWithContext(ctx aws.Context, input *CancelKeyDeletionInput, opts ...request.Option) (*CancelKeyDeletionOutput, error) {
	req, out := c.CancelKeyDeletionRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opConnectCustomKeyStore = "ConnectCustomKeyStore"

// ConnectCustomKeyStoreRequest generates a "aws/request.Request" representing the
// client's request for the ConnectCustomKeyStore 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 ConnectCustomKeyStore for more information on using the ConnectCustomKeyStore
// 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 ConnectCustomKeyStoreRequest method.
//    req, resp := client.ConnectCustomKeyStoreRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ConnectCustomKeyStore
func (c *KMS) ConnectCustomKeyStoreRequest(input *ConnectCustomKeyStoreInput) (req *request.Request, output *ConnectCustomKeyStoreOutput) {
	op := &request.Operation{
		Name:       opConnectCustomKeyStore,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ConnectCustomKeyStoreInput{}
	}

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

// ConnectCustomKeyStore API operation for AWS Key Management Service.
//
// Connects or reconnects a custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html)
// to its associated AWS CloudHSM cluster.
//
// The custom key store must be connected before you can create customer master
// keys (CMKs) in the key store or use the CMKs it contains. You can disconnect
// and reconnect a custom key store at any time.
//
// To connect a custom key store, its associated AWS CloudHSM cluster must have
// at least one active HSM. To get the number of active HSMs in a cluster, use
// the DescribeClusters (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_DescribeClusters)
// operation. To add HSMs to the cluster, use the CreateHsm (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_CreateHsm)
// operation.
//
// The connection process can take an extended amount of time to complete; up
// to 20 minutes. This operation starts the connection process, but it does
// not wait for it to complete. When it succeeds, this operation quickly returns
// an HTTP 200 response and a JSON object with no properties. However, this
// response does not indicate that the custom key store is connected. To get
// the connection state of the custom key store, use the DescribeCustomKeyStores
// operation.
//
// During the connection process, AWS KMS finds the AWS CloudHSM cluster that
// is associated with the custom key store, creates the connection infrastructure,
// connects to the cluster, logs into the AWS CloudHSM client as the kmsuser
// (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-concepts.html#concept-kmsuser)
// crypto user (CU), and rotates its password.
//
// The ConnectCustomKeyStore operation might fail for various reasons. To find
// the reason, use the DescribeCustomKeyStores operation and see the ConnectionErrorCode
// in the response. For help interpreting the ConnectionErrorCode, see CustomKeyStoresListEntry.
//
// To fix the failure, use the DisconnectCustomKeyStore operation to disconnect
// the custom key store, correct the error, use the UpdateCustomKeyStore operation
// if necessary, and then use ConnectCustomKeyStore again.
//
// If you are having trouble connecting or disconnecting a custom key store,
// see Troubleshooting a Custom Key Store (http://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation ConnectCustomKeyStore for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeCloudHsmClusterNotActiveException "CloudHsmClusterNotActiveException"
//   The request was rejected because the AWS CloudHSM cluster that is associated
//   with the custom key store is not active. Initialize and activate the cluster
//   and try the command again. For detailed instructions, see Getting Started
//   (http://docs.aws.amazon.com/cloudhsm/latest/userguide/getting-started.html)
//   in the AWS CloudHSM User Guide.
//
//   * ErrCodeCustomKeyStoreInvalidStateException "CustomKeyStoreInvalidStateException"
//   The request was rejected because of the ConnectionState of the custom key
//   store. To get the ConnectionState of a custom key store, use the DescribeCustomKeyStores
//   operation.
//
//   This exception is thrown under the following conditions:
//
//      * You requested the CreateKey or GenerateRandom operation in a custom
//      key store that is not connected. These operations are valid only when
//      the custom key store ConnectionState is CONNECTED.
//
//      * You requested the UpdateCustomKeyStore or DeleteCustomKeyStore operation
//      on a custom key store that is not disconnected. This operation is valid
//      only when the custom key store ConnectionState is DISCONNECTED.
//
//      * You requested the ConnectCustomKeyStore operation on a custom key store
//      with a ConnectionState of DISCONNECTING or FAILED. This operation is valid
//      for all other ConnectionState values.
//
//   * ErrCodeCustomKeyStoreNotFoundException "CustomKeyStoreNotFoundException"
//   The request was rejected because AWS KMS cannot find a custom key store with
//   the specified key store name or ID.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeCloudHsmClusterInvalidConfigurationException "CloudHsmClusterInvalidConfigurationException"
//   The request was rejected because the associated AWS CloudHSM cluster did
//   not meet the configuration requirements for a custom key store. The cluster
//   must be configured with private subnets in at least two different Availability
//   Zones in the Region. Also, it must contain at least as many HSMs as the operation
//   requires.
//
//   For the CreateCustomKeyStore, UpdateCustomKeyStore, and CreateKey operations,
//   the AWS CloudHSM cluster must have at least two active HSMs, each in a different
//   Availability Zone. For the ConnectCustomKeyStore operation, the AWS CloudHSM
//   must contain at least one active HSM.
//
//   For information about creating a private subnet for a AWS CloudHSM cluster,
//   see Create a Private Subnet (http://docs.aws.amazon.com/cloudhsm/latest/userguide/create-subnets.html)
//   in the AWS CloudHSM User Guide. To add HSMs, use the AWS CloudHSM CreateHsm
//   (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_CreateHsm.html)
//   operation.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ConnectCustomKeyStore
func (c *KMS) ConnectCustomKeyStore(input *ConnectCustomKeyStoreInput) (*ConnectCustomKeyStoreOutput, error) {
	req, out := c.ConnectCustomKeyStoreRequest(input)
	return out, req.Send()
}

// ConnectCustomKeyStoreWithContext is the same as ConnectCustomKeyStore with the addition of
// the ability to pass a context and additional request options.
//
// See ConnectCustomKeyStore 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 *KMS) ConnectCustomKeyStoreWithContext(ctx aws.Context, input *ConnectCustomKeyStoreInput, opts ...request.Option) (*ConnectCustomKeyStoreOutput, error) {
	req, out := c.ConnectCustomKeyStoreRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateAlias = "CreateAlias"

// CreateAliasRequest generates a "aws/request.Request" representing the
// client's request for the CreateAlias 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 CreateAlias for more information on using the CreateAlias
// 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 CreateAliasRequest method.
//    req, resp := client.CreateAliasRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/CreateAlias
func (c *KMS) CreateAliasRequest(input *CreateAliasInput) (req *request.Request, output *CreateAliasOutput) {
	op := &request.Operation{
		Name:       opCreateAlias,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateAliasInput{}
	}

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

// CreateAlias API operation for AWS Key Management Service.
//
// Creates a display name for a customer master key (CMK). You can use an alias
// to identify a CMK in selected operations, such as Encrypt and GenerateDataKey.
//
// Each CMK can have multiple aliases, but each alias points to only one CMK.
// The alias name must be unique in the AWS account and region. To simplify
// code that runs in multiple regions, use the same alias name, but point it
// to a different CMK in each region.
//
// Because an alias is not a property of a CMK, you can delete and change the
// aliases of a CMK without affecting the CMK. Also, aliases do not appear in
// the response from the DescribeKey operation. To get the aliases of all CMKs,
// use the ListAliases operation.
//
// An alias must start with the word alias followed by a forward slash (alias/).
// The alias name can contain only alphanumeric characters, forward slashes
// (/), underscores (_), and dashes (-). Alias names cannot begin with aws;
// that alias name prefix is reserved by Amazon Web Services (AWS).
//
// The alias and the CMK it is mapped to must be in the same AWS account and
// the same region. You cannot perform this operation on an alias in a different
// AWS account.
//
// To map an existing alias to a different CMK, call UpdateAlias.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation CreateAlias for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeAlreadyExistsException "AlreadyExistsException"
//   The request was rejected because it attempted to create a resource that already
//   exists.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidAliasNameException "InvalidAliasNameException"
//   The request was rejected because the specified alias name is not valid.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeLimitExceededException "LimitExceededException"
//   The request was rejected because a limit was exceeded. For more information,
//   see Limits (http://docs.aws.amazon.com/kms/latest/developerguide/limits.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/CreateAlias
func (c *KMS) CreateAlias(input *CreateAliasInput) (*CreateAliasOutput, error) {
	req, out := c.CreateAliasRequest(input)
	return out, req.Send()
}

// CreateAliasWithContext is the same as CreateAlias with the addition of
// the ability to pass a context and additional request options.
//
// See CreateAlias 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 *KMS) CreateAliasWithContext(ctx aws.Context, input *CreateAliasInput, opts ...request.Option) (*CreateAliasOutput, error) {
	req, out := c.CreateAliasRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateCustomKeyStore = "CreateCustomKeyStore"

// CreateCustomKeyStoreRequest generates a "aws/request.Request" representing the
// client's request for the CreateCustomKeyStore 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 CreateCustomKeyStore for more information on using the CreateCustomKeyStore
// 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 CreateCustomKeyStoreRequest method.
//    req, resp := client.CreateCustomKeyStoreRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/CreateCustomKeyStore
func (c *KMS) CreateCustomKeyStoreRequest(input *CreateCustomKeyStoreInput) (req *request.Request, output *CreateCustomKeyStoreOutput) {
	op := &request.Operation{
		Name:       opCreateCustomKeyStore,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateCustomKeyStoreInput{}
	}

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

// CreateCustomKeyStore API operation for AWS Key Management Service.
//
// Creates a custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html)
// that is associated with an AWS CloudHSM cluster (http://docs.aws.amazon.com/cloudhsm/latest/userguide/clusters.html)
// that you own and manage.
//
// This operation is part of the Custom Key Store feature (http://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// feature in AWS KMS, which combines the convenience and extensive integration
// of AWS KMS with the isolation and control of a single-tenant key store.
//
// When the operation completes successfully, it returns the ID of the new custom
// key store. Before you can use your new custom key store, you need to use
// the ConnectCustomKeyStore operation to connect the new key store to its AWS
// CloudHSM cluster.
//
// The CreateCustomKeyStore operation requires the following elements.
//
//    * You must specify an active AWS CloudHSM cluster in the same account
//    and AWS Region as the custom key store. You can use an existing cluster
//    or create and activate a new AWS CloudHSM cluster (http://docs.aws.amazon.com/cloudhsm/latest/userguide/create-cluster.html)
//    for the key store. AWS KMS does not require exclusive use of the cluster.
//
//    * You must include the content of the trust anchor certificate for the
//    cluster. You created this certificate, and saved it in the customerCA.crt
//    file, when you initialized the cluster (http://docs.aws.amazon.com/cloudhsm/latest/userguide/initialize-cluster.html#sign-csr).
//
//    * You must provide the password of the dedicated kmsuser (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-concepts.html#concept-kmsuser)
//    crypto user (CU) account in the cluster.
//
// Before you create the custom key store, use the createUser (http://docs.aws.amazon.com/cloudhsm/latest/userguide/cloudhsm_mgmt_util-createUser.html)
//    command in cloudhsm_mgmt_util to create a crypto user (CU) named  (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-concepts.html#concept-kmsuser)kmsuserin
//    specified AWS CloudHSM cluster. AWS KMS uses the kmsuser CU account to
//    create and manage key material on your behalf. For instructions, see Create
//    the kmsuser Crypto User (http://docs.aws.amazon.com/kms/latest/developerguide/create-keystore.html#before-keystore)
//    in the AWS Key Management Service Developer Guide.
//
// The AWS CloudHSM cluster that you specify must meet the following requirements.
//
//    * The cluster must be active and be in the same AWS account and Region
//    as the custom key store.
//
//    * Each custom key store must be associated with a different AWS CloudHSM
//    cluster. The cluster cannot be associated with another custom key store
//    or have the same cluster certificate as a cluster that is associated with
//    another custom key store. To view the cluster certificate, use the AWS
//    CloudHSM DescribeClusters (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_DescribeClusters.html)
//    operation. Clusters that share a backup history have the same cluster
//    certificate.
//
//    * The cluster must be configured with subnets in at least two different
//    Availability Zones in the Region. Because AWS CloudHSM is not supported
//    in all Availability Zones, we recommend that the cluster have subnets
//    in all Availability Zones in the Region.
//
//    * The cluster must contain at least two active HSMs, each in a different
//    Availability Zone.
//
// New custom key stores are not automatically connected. After you create your
// custom key store, use the ConnectCustomKeyStore operation to connect the
// custom key store to its associated AWS CloudHSM cluster. Even if you are
// not going to use your custom key store immediately, you might want to connect
// it to verify that all settings are correct and then disconnect it until you
// are ready to use it.
//
// If this operation succeeds, it returns the ID of the new custom key store.
// For help with failures, see Troubleshoot a Custom Key Store (http://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html)
// in the AWS KMS Developer Guide.
//
// 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 AWS Key Management Service's
// API operation CreateCustomKeyStore for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeCloudHsmClusterInUseException "CloudHsmClusterInUseException"
//   The request was rejected because the specified AWS CloudHSM cluster is already
//   associated with a custom key store or it shares a backup history with a cluster
//   that is associated with a custom key store. Each custom key store must be
//   associated with a different AWS CloudHSM cluster.
//
//   Clusters that share a backup history have the same cluster certificate. To
//   view the cluster certificate of a cluster, use the DescribeClusters (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_DescribeClusters.html)
//   operation.
//
//   * ErrCodeCustomKeyStoreNameInUseException "CustomKeyStoreNameInUseException"
//   The request was rejected because the specified custom key store name is already
//   assigned to another custom key store in the account. Try again with a custom
//   key store name that is unique in the account.
//
//   * ErrCodeCloudHsmClusterNotFoundException "CloudHsmClusterNotFoundException"
//   The request was rejected because AWS KMS cannot find the AWS CloudHSM cluster
//   with the specified cluster ID. Retry the request with a different cluster
//   ID.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeCloudHsmClusterNotActiveException "CloudHsmClusterNotActiveException"
//   The request was rejected because the AWS CloudHSM cluster that is associated
//   with the custom key store is not active. Initialize and activate the cluster
//   and try the command again. For detailed instructions, see Getting Started
//   (http://docs.aws.amazon.com/cloudhsm/latest/userguide/getting-started.html)
//   in the AWS CloudHSM User Guide.
//
//   * ErrCodeIncorrectTrustAnchorException "IncorrectTrustAnchorException"
//   The request was rejected because the trust anchor certificate in the request
//   is not the trust anchor certificate for the specified AWS CloudHSM cluster.
//
//   When you initialize the cluster (http://docs.aws.amazon.com/cloudhsm/latest/userguide/initialize-cluster.html#sign-csr),
//   you create the trust anchor certificate and save it in the customerCA.crt
//   file.
//
//   * ErrCodeCloudHsmClusterInvalidConfigurationException "CloudHsmClusterInvalidConfigurationException"
//   The request was rejected because the associated AWS CloudHSM cluster did
//   not meet the configuration requirements for a custom key store. The cluster
//   must be configured with private subnets in at least two different Availability
//   Zones in the Region. Also, it must contain at least as many HSMs as the operation
//   requires.
//
//   For the CreateCustomKeyStore, UpdateCustomKeyStore, and CreateKey operations,
//   the AWS CloudHSM cluster must have at least two active HSMs, each in a different
//   Availability Zone. For the ConnectCustomKeyStore operation, the AWS CloudHSM
//   must contain at least one active HSM.
//
//   For information about creating a private subnet for a AWS CloudHSM cluster,
//   see Create a Private Subnet (http://docs.aws.amazon.com/cloudhsm/latest/userguide/create-subnets.html)
//   in the AWS CloudHSM User Guide. To add HSMs, use the AWS CloudHSM CreateHsm
//   (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_CreateHsm.html)
//   operation.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/CreateCustomKeyStore
func (c *KMS) CreateCustomKeyStore(input *CreateCustomKeyStoreInput) (*CreateCustomKeyStoreOutput, error) {
	req, out := c.CreateCustomKeyStoreRequest(input)
	return out, req.Send()
}

// CreateCustomKeyStoreWithContext is the same as CreateCustomKeyStore with the addition of
// the ability to pass a context and additional request options.
//
// See CreateCustomKeyStore 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 *KMS) CreateCustomKeyStoreWithContext(ctx aws.Context, input *CreateCustomKeyStoreInput, opts ...request.Option) (*CreateCustomKeyStoreOutput, error) {
	req, out := c.CreateCustomKeyStoreRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateGrant = "CreateGrant"

// CreateGrantRequest generates a "aws/request.Request" representing the
// client's request for the CreateGrant 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 CreateGrant for more information on using the CreateGrant
// 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 CreateGrantRequest method.
//    req, resp := client.CreateGrantRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/CreateGrant
func (c *KMS) CreateGrantRequest(input *CreateGrantInput) (req *request.Request, output *CreateGrantOutput) {
	op := &request.Operation{
		Name:       opCreateGrant,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateGrantInput{}
	}

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

// CreateGrant API operation for AWS Key Management Service.
//
// Adds a grant to a customer master key (CMK). The grant specifies who can
// use the CMK and under what conditions. When setting permissions, grants are
// an alternative to key policies.
//
// To perform this operation on a CMK in a different AWS account, specify the
// key ARN in the value of the KeyId parameter. For more information about grants,
// see Grants (http://docs.aws.amazon.com/kms/latest/developerguide/grants.html)
// in the AWS Key Management Service Developer Guide.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation CreateGrant for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDisabledException "DisabledException"
//   The request was rejected because the specified CMK is not enabled.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidGrantTokenException "InvalidGrantTokenException"
//   The request was rejected because the specified grant token is not valid.
//
//   * ErrCodeLimitExceededException "LimitExceededException"
//   The request was rejected because a limit was exceeded. For more information,
//   see Limits (http://docs.aws.amazon.com/kms/latest/developerguide/limits.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/CreateGrant
func (c *KMS) CreateGrant(input *CreateGrantInput) (*CreateGrantOutput, error) {
	req, out := c.CreateGrantRequest(input)
	return out, req.Send()
}

// CreateGrantWithContext is the same as CreateGrant with the addition of
// the ability to pass a context and additional request options.
//
// See CreateGrant 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 *KMS) CreateGrantWithContext(ctx aws.Context, input *CreateGrantInput, opts ...request.Option) (*CreateGrantOutput, error) {
	req, out := c.CreateGrantRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateKey = "CreateKey"

// CreateKeyRequest generates a "aws/request.Request" representing the
// client's request for the CreateKey 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 CreateKey for more information on using the CreateKey
// 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 CreateKeyRequest method.
//    req, resp := client.CreateKeyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/CreateKey
func (c *KMS) CreateKeyRequest(input *CreateKeyInput) (req *request.Request, output *CreateKeyOutput) {
	op := &request.Operation{
		Name:       opCreateKey,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateKeyInput{}
	}

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

// CreateKey API operation for AWS Key Management Service.
//
// Creates a customer master key (CMK) in the caller's AWS account.
//
// You can use a CMK to encrypt small amounts of data (4 KiB or less) directly,
// but CMKs are more commonly used to encrypt data keys, which are used to encrypt
// raw data. For more information about data keys and the difference between
// CMKs and data keys, see the following:
//
//    * The GenerateDataKey operation
//
//    * AWS Key Management Service Concepts (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html)
//    in the AWS Key Management Service Developer Guide
//
// If you plan to import key material (http://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html),
// use the Origin parameter with a value of EXTERNAL to create a CMK with no
// key material.
//
// To create a CMK in a custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html),
// use CustomKeyStoreId parameter to specify the custom key store. You must
// also use the Origin parameter with a value of AWS_CLOUDHSM. The AWS CloudHSM
// cluster that is associated with the custom key store must have at least two
// active HSMs, each in a different Availability Zone in the Region.
//
// You cannot use this operation to create a CMK in a different AWS account.
//
// 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 AWS Key Management Service's
// API operation CreateKey for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocumentException"
//   The request was rejected because the specified policy is not syntactically
//   or semantically correct.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeUnsupportedOperationException "UnsupportedOperationException"
//   The request was rejected because a specified parameter is not supported or
//   a specified resource is not valid for this operation.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeLimitExceededException "LimitExceededException"
//   The request was rejected because a limit was exceeded. For more information,
//   see Limits (http://docs.aws.amazon.com/kms/latest/developerguide/limits.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeTagException "TagException"
//   The request was rejected because one or more tags are not valid.
//
//   * ErrCodeCustomKeyStoreNotFoundException "CustomKeyStoreNotFoundException"
//   The request was rejected because AWS KMS cannot find a custom key store with
//   the specified key store name or ID.
//
//   * ErrCodeCustomKeyStoreInvalidStateException "CustomKeyStoreInvalidStateException"
//   The request was rejected because of the ConnectionState of the custom key
//   store. To get the ConnectionState of a custom key store, use the DescribeCustomKeyStores
//   operation.
//
//   This exception is thrown under the following conditions:
//
//      * You requested the CreateKey or GenerateRandom operation in a custom
//      key store that is not connected. These operations are valid only when
//      the custom key store ConnectionState is CONNECTED.
//
//      * You requested the UpdateCustomKeyStore or DeleteCustomKeyStore operation
//      on a custom key store that is not disconnected. This operation is valid
//      only when the custom key store ConnectionState is DISCONNECTED.
//
//      * You requested the ConnectCustomKeyStore operation on a custom key store
//      with a ConnectionState of DISCONNECTING or FAILED. This operation is valid
//      for all other ConnectionState values.
//
//   * ErrCodeCloudHsmClusterInvalidConfigurationException "CloudHsmClusterInvalidConfigurationException"
//   The request was rejected because the associated AWS CloudHSM cluster did
//   not meet the configuration requirements for a custom key store. The cluster
//   must be configured with private subnets in at least two different Availability
//   Zones in the Region. Also, it must contain at least as many HSMs as the operation
//   requires.
//
//   For the CreateCustomKeyStore, UpdateCustomKeyStore, and CreateKey operations,
//   the AWS CloudHSM cluster must have at least two active HSMs, each in a different
//   Availability Zone. For the ConnectCustomKeyStore operation, the AWS CloudHSM
//   must contain at least one active HSM.
//
//   For information about creating a private subnet for a AWS CloudHSM cluster,
//   see Create a Private Subnet (http://docs.aws.amazon.com/cloudhsm/latest/userguide/create-subnets.html)
//   in the AWS CloudHSM User Guide. To add HSMs, use the AWS CloudHSM CreateHsm
//   (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_CreateHsm.html)
//   operation.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/CreateKey
func (c *KMS) CreateKey(input *CreateKeyInput) (*CreateKeyOutput, error) {
	req, out := c.CreateKeyRequest(input)
	return out, req.Send()
}

// CreateKeyWithContext is the same as CreateKey with the addition of
// the ability to pass a context and additional request options.
//
// See CreateKey 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 *KMS) CreateKeyWithContext(ctx aws.Context, input *CreateKeyInput, opts ...request.Option) (*CreateKeyOutput, error) {
	req, out := c.CreateKeyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDecrypt = "Decrypt"

// DecryptRequest generates a "aws/request.Request" representing the
// client's request for the Decrypt 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 Decrypt for more information on using the Decrypt
// 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 DecryptRequest method.
//    req, resp := client.DecryptRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/Decrypt
func (c *KMS) DecryptRequest(input *DecryptInput) (req *request.Request, output *DecryptOutput) {
	op := &request.Operation{
		Name:       opDecrypt,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DecryptInput{}
	}

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

// Decrypt API operation for AWS Key Management Service.
//
// Decrypts ciphertext. Ciphertext is plaintext that has been previously encrypted
// by using any of the following operations:
//
//    * GenerateDataKey
//
//    * GenerateDataKeyWithoutPlaintext
//
//    * Encrypt
//
// Note that if a caller has been granted access permissions to all keys (through,
// for example, IAM user policies that grant Decrypt permission on all resources),
// then ciphertext encrypted by using keys in other accounts where the key grants
// access to the caller can be decrypted. To remedy this, we recommend that
// you do not grant Decrypt access in an IAM user policy. Instead grant Decrypt
// access only in key policies. If you must grant Decrypt access in an IAM user
// policy, you should scope the resource to specific keys or to specific trusted
// accounts.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation Decrypt for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDisabledException "DisabledException"
//   The request was rejected because the specified CMK is not enabled.
//
//   * ErrCodeInvalidCiphertextException "InvalidCiphertextException"
//   The request was rejected because the specified ciphertext, or additional
//   authenticated data incorporated into the ciphertext, such as the encryption
//   context, is corrupted, missing, or otherwise invalid.
//
//   * ErrCodeKeyUnavailableException "KeyUnavailableException"
//   The request was rejected because the specified CMK was not available. The
//   request can be retried.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidGrantTokenException "InvalidGrantTokenException"
//   The request was rejected because the specified grant token is not valid.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/Decrypt
func (c *KMS) Decrypt(input *DecryptInput) (*DecryptOutput, error) {
	req, out := c.DecryptRequest(input)
	return out, req.Send()
}

// DecryptWithContext is the same as Decrypt with the addition of
// the ability to pass a context and additional request options.
//
// See Decrypt 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 *KMS) DecryptWithContext(ctx aws.Context, input *DecryptInput, opts ...request.Option) (*DecryptOutput, error) {
	req, out := c.DecryptRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteAlias = "DeleteAlias"

// DeleteAliasRequest generates a "aws/request.Request" representing the
// client's request for the DeleteAlias 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 DeleteAlias for more information on using the DeleteAlias
// 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 DeleteAliasRequest method.
//    req, resp := client.DeleteAliasRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DeleteAlias
func (c *KMS) DeleteAliasRequest(input *DeleteAliasInput) (req *request.Request, output *DeleteAliasOutput) {
	op := &request.Operation{
		Name:       opDeleteAlias,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteAliasInput{}
	}

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

// DeleteAlias API operation for AWS Key Management Service.
//
// Deletes the specified alias. You cannot perform this operation on an alias
// in a different AWS account.
//
// Because an alias is not a property of a CMK, you can delete and change the
// aliases of a CMK without affecting the CMK. Also, aliases do not appear in
// the response from the DescribeKey operation. To get the aliases of all CMKs,
// use the ListAliases operation.
//
// Each CMK can have multiple aliases. To change the alias of a CMK, use DeleteAlias
// to delete the current alias and CreateAlias to create a new alias. To associate
// an existing alias with a different customer master key (CMK), call UpdateAlias.
//
// 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 AWS Key Management Service's
// API operation DeleteAlias for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DeleteAlias
func (c *KMS) DeleteAlias(input *DeleteAliasInput) (*DeleteAliasOutput, error) {
	req, out := c.DeleteAliasRequest(input)
	return out, req.Send()
}

// DeleteAliasWithContext is the same as DeleteAlias with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteAlias 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 *KMS) DeleteAliasWithContext(ctx aws.Context, input *DeleteAliasInput, opts ...request.Option) (*DeleteAliasOutput, error) {
	req, out := c.DeleteAliasRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteCustomKeyStore = "DeleteCustomKeyStore"

// DeleteCustomKeyStoreRequest generates a "aws/request.Request" representing the
// client's request for the DeleteCustomKeyStore 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 DeleteCustomKeyStore for more information on using the DeleteCustomKeyStore
// 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 DeleteCustomKeyStoreRequest method.
//    req, resp := client.DeleteCustomKeyStoreRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DeleteCustomKeyStore
func (c *KMS) DeleteCustomKeyStoreRequest(input *DeleteCustomKeyStoreInput) (req *request.Request, output *DeleteCustomKeyStoreOutput) {
	op := &request.Operation{
		Name:       opDeleteCustomKeyStore,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteCustomKeyStoreInput{}
	}

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

// DeleteCustomKeyStore API operation for AWS Key Management Service.
//
// Deletes a custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html).
// This operation does not delete the AWS CloudHSM cluster that is associated
// with the custom key store, or affect any users or keys in the cluster.
//
// The custom key store that you delete cannot contain any AWS KMS customer
// master keys (CMKs) (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys).
// Before deleting the key store, verify that you will never need to use any
// of the CMKs in the key store for any cryptographic operations. Then, use
// ScheduleKeyDeletion to delete the AWS KMS customer master keys (CMKs) from
// the key store. When the scheduled waiting period expires, the ScheduleKeyDeletion
// operation deletes the CMKs. Then it makes a best effort to delete the key
// material from the associated cluster. However, you might need to manually
// delete the orphaned key material (http://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html#fix-keystore-orphaned-key)
// from the cluster and its backups.
//
// After all CMKs are deleted from AWS KMS, use DisconnectCustomKeyStore to
// disconnect the key store from AWS KMS. Then, you can delete the custom key
// store.
//
// Instead of deleting the custom key store, consider using DisconnectCustomKeyStore
// to disconnect it from AWS KMS. While the key store is disconnected, you cannot
// create or use the CMKs in the key store. But, you do not need to delete CMKs
// and you can reconnect a disconnected custom key store at any time.
//
// If the operation succeeds, it returns a JSON object with no properties.
//
// This operation is part of the Custom Key Store feature (http://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// feature in AWS KMS, which combines the convenience and extensive integration
// of AWS KMS with the isolation and control of a single-tenant key store.
//
// 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 AWS Key Management Service's
// API operation DeleteCustomKeyStore for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeCustomKeyStoreHasCMKsException "CustomKeyStoreHasCMKsException"
//   The request was rejected because the custom key store contains AWS KMS customer
//   master keys (CMKs). After verifying that you do not need to use the CMKs,
//   use the ScheduleKeyDeletion operation to delete the CMKs. After they are
//   deleted, you can delete the custom key store.
//
//   * ErrCodeCustomKeyStoreInvalidStateException "CustomKeyStoreInvalidStateException"
//   The request was rejected because of the ConnectionState of the custom key
//   store. To get the ConnectionState of a custom key store, use the DescribeCustomKeyStores
//   operation.
//
//   This exception is thrown under the following conditions:
//
//      * You requested the CreateKey or GenerateRandom operation in a custom
//      key store that is not connected. These operations are valid only when
//      the custom key store ConnectionState is CONNECTED.
//
//      * You requested the UpdateCustomKeyStore or DeleteCustomKeyStore operation
//      on a custom key store that is not disconnected. This operation is valid
//      only when the custom key store ConnectionState is DISCONNECTED.
//
//      * You requested the ConnectCustomKeyStore operation on a custom key store
//      with a ConnectionState of DISCONNECTING or FAILED. This operation is valid
//      for all other ConnectionState values.
//
//   * ErrCodeCustomKeyStoreNotFoundException "CustomKeyStoreNotFoundException"
//   The request was rejected because AWS KMS cannot find a custom key store with
//   the specified key store name or ID.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DeleteCustomKeyStore
func (c *KMS) DeleteCustomKeyStore(input *DeleteCustomKeyStoreInput) (*DeleteCustomKeyStoreOutput, error) {
	req, out := c.DeleteCustomKeyStoreRequest(input)
	return out, req.Send()
}

// DeleteCustomKeyStoreWithContext is the same as DeleteCustomKeyStore with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteCustomKeyStore 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 *KMS) DeleteCustomKeyStoreWithContext(ctx aws.Context, input *DeleteCustomKeyStoreInput, opts ...request.Option) (*DeleteCustomKeyStoreOutput, error) {
	req, out := c.DeleteCustomKeyStoreRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteImportedKeyMaterial = "DeleteImportedKeyMaterial"

// DeleteImportedKeyMaterialRequest generates a "aws/request.Request" representing the
// client's request for the DeleteImportedKeyMaterial 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 DeleteImportedKeyMaterial for more information on using the DeleteImportedKeyMaterial
// 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 DeleteImportedKeyMaterialRequest method.
//    req, resp := client.DeleteImportedKeyMaterialRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DeleteImportedKeyMaterial
func (c *KMS) DeleteImportedKeyMaterialRequest(input *DeleteImportedKeyMaterialInput) (req *request.Request, output *DeleteImportedKeyMaterialOutput) {
	op := &request.Operation{
		Name:       opDeleteImportedKeyMaterial,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteImportedKeyMaterialInput{}
	}

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

// DeleteImportedKeyMaterial API operation for AWS Key Management Service.
//
// Deletes key material that you previously imported. This operation makes the
// specified customer master key (CMK) unusable. For more information about
// importing key material into AWS KMS, see Importing Key Material (http://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html)
// in the AWS Key Management Service Developer Guide. You cannot perform this
// operation on a CMK in a different AWS account.
//
// When the specified CMK is in the PendingDeletion state, this operation does
// not change the CMK's state. Otherwise, it changes the CMK's state to PendingImport.
//
// After you delete key material, you can use ImportKeyMaterial to reimport
// the same key material into the CMK.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation DeleteImportedKeyMaterial for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeUnsupportedOperationException "UnsupportedOperationException"
//   The request was rejected because a specified parameter is not supported or
//   a specified resource is not valid for this operation.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DeleteImportedKeyMaterial
func (c *KMS) DeleteImportedKeyMaterial(input *DeleteImportedKeyMaterialInput) (*DeleteImportedKeyMaterialOutput, error) {
	req, out := c.DeleteImportedKeyMaterialRequest(input)
	return out, req.Send()
}

// DeleteImportedKeyMaterialWithContext is the same as DeleteImportedKeyMaterial with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteImportedKeyMaterial 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 *KMS) DeleteImportedKeyMaterialWithContext(ctx aws.Context, input *DeleteImportedKeyMaterialInput, opts ...request.Option) (*DeleteImportedKeyMaterialOutput, error) {
	req, out := c.DeleteImportedKeyMaterialRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeCustomKeyStores = "DescribeCustomKeyStores"

// DescribeCustomKeyStoresRequest generates a "aws/request.Request" representing the
// client's request for the DescribeCustomKeyStores 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 DescribeCustomKeyStores for more information on using the DescribeCustomKeyStores
// 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 DescribeCustomKeyStoresRequest method.
//    req, resp := client.DescribeCustomKeyStoresRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DescribeCustomKeyStores
func (c *KMS) DescribeCustomKeyStoresRequest(input *DescribeCustomKeyStoresInput) (req *request.Request, output *DescribeCustomKeyStoresOutput) {
	op := &request.Operation{
		Name:       opDescribeCustomKeyStores,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeCustomKeyStoresInput{}
	}

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

// DescribeCustomKeyStores API operation for AWS Key Management Service.
//
// Gets information about custom key stores (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html)
// in the account and region.
//
// This operation is part of the Custom Key Store feature (http://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// feature in AWS KMS, which combines the convenience and extensive integration
// of AWS KMS with the isolation and control of a single-tenant key store.
//
// By default, this operation returns information about all custom key stores
// in the account and region. To get only information about a particular custom
// key store, use either the CustomKeyStoreName or CustomKeyStoreId parameter
// (but not both).
//
// To determine whether the custom key store is connected to its AWS CloudHSM
// cluster, use the ConnectionState element in the response. If an attempt to
// connect the custom key store failed, the ConnectionState value is FAILED
// and the ConnectionErrorCode element in the response indicates the cause of
// the failure. For help interpreting the ConnectionErrorCode, see CustomKeyStoresListEntry.
//
// Custom key stores have a DISCONNECTED connection state if the key store has
// never been connected or you use the DisconnectCustomKeyStore operation to
// disconnect it. If your custom key store state is CONNECTED but you are having
// trouble using it, make sure that its associated AWS CloudHSM cluster is active
// and contains the minimum number of HSMs required for the operation, if any.
//
// For help repairing your custom key store, see the Troubleshooting Custom
// Key Stores (http://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore-html)
// topic in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation DescribeCustomKeyStores for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeCustomKeyStoreNotFoundException "CustomKeyStoreNotFoundException"
//   The request was rejected because AWS KMS cannot find a custom key store with
//   the specified key store name or ID.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DescribeCustomKeyStores
func (c *KMS) DescribeCustomKeyStores(input *DescribeCustomKeyStoresInput) (*DescribeCustomKeyStoresOutput, error) {
	req, out := c.DescribeCustomKeyStoresRequest(input)
	return out, req.Send()
}

// DescribeCustomKeyStoresWithContext is the same as DescribeCustomKeyStores with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeCustomKeyStores 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 *KMS) DescribeCustomKeyStoresWithContext(ctx aws.Context, input *DescribeCustomKeyStoresInput, opts ...request.Option) (*DescribeCustomKeyStoresOutput, error) {
	req, out := c.DescribeCustomKeyStoresRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeKey = "DescribeKey"

// DescribeKeyRequest generates a "aws/request.Request" representing the
// client's request for the DescribeKey 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 DescribeKey for more information on using the DescribeKey
// 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 DescribeKeyRequest method.
//    req, resp := client.DescribeKeyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DescribeKey
func (c *KMS) DescribeKeyRequest(input *DescribeKeyInput) (req *request.Request, output *DescribeKeyOutput) {
	op := &request.Operation{
		Name:       opDescribeKey,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeKeyInput{}
	}

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

// DescribeKey API operation for AWS Key Management Service.
//
// Provides detailed information about the specified customer master key (CMK).
//
// If you use DescribeKey on a predefined AWS alias, that is, an AWS alias with
// no key ID, AWS KMS associates the alias with an AWS managed CMK (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)
// and returns its KeyId and Arn in the response.
//
// To perform this operation on a CMK in a different AWS account, specify the
// key ARN or alias ARN in the value of the KeyId parameter.
//
// 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 AWS Key Management Service's
// API operation DescribeKey for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DescribeKey
func (c *KMS) DescribeKey(input *DescribeKeyInput) (*DescribeKeyOutput, error) {
	req, out := c.DescribeKeyRequest(input)
	return out, req.Send()
}

// DescribeKeyWithContext is the same as DescribeKey with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeKey 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 *KMS) DescribeKeyWithContext(ctx aws.Context, input *DescribeKeyInput, opts ...request.Option) (*DescribeKeyOutput, error) {
	req, out := c.DescribeKeyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDisableKey = "DisableKey"

// DisableKeyRequest generates a "aws/request.Request" representing the
// client's request for the DisableKey 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 DisableKey for more information on using the DisableKey
// 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 DisableKeyRequest method.
//    req, resp := client.DisableKeyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DisableKey
func (c *KMS) DisableKeyRequest(input *DisableKeyInput) (req *request.Request, output *DisableKeyOutput) {
	op := &request.Operation{
		Name:       opDisableKey,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DisableKeyInput{}
	}

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

// DisableKey API operation for AWS Key Management Service.
//
// Sets the state of a customer master key (CMK) to disabled, thereby preventing
// its use for cryptographic operations. You cannot perform this operation on
// a CMK in a different AWS account.
//
// For more information about how key state affects the use of a CMK, see How
// Key State Affects the Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation DisableKey for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DisableKey
func (c *KMS) DisableKey(input *DisableKeyInput) (*DisableKeyOutput, error) {
	req, out := c.DisableKeyRequest(input)
	return out, req.Send()
}

// DisableKeyWithContext is the same as DisableKey with the addition of
// the ability to pass a context and additional request options.
//
// See DisableKey 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 *KMS) DisableKeyWithContext(ctx aws.Context, input *DisableKeyInput, opts ...request.Option) (*DisableKeyOutput, error) {
	req, out := c.DisableKeyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDisableKeyRotation = "DisableKeyRotation"

// DisableKeyRotationRequest generates a "aws/request.Request" representing the
// client's request for the DisableKeyRotation 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 DisableKeyRotation for more information on using the DisableKeyRotation
// 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 DisableKeyRotationRequest method.
//    req, resp := client.DisableKeyRotationRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DisableKeyRotation
func (c *KMS) DisableKeyRotationRequest(input *DisableKeyRotationInput) (req *request.Request, output *DisableKeyRotationOutput) {
	op := &request.Operation{
		Name:       opDisableKeyRotation,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DisableKeyRotationInput{}
	}

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

// DisableKeyRotation API operation for AWS Key Management Service.
//
// Disables automatic rotation of the key material (http://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html)
// for the specified customer master key (CMK). You cannot perform this operation
// on a CMK in a different AWS account.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation DisableKeyRotation for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDisabledException "DisabledException"
//   The request was rejected because the specified CMK is not enabled.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeUnsupportedOperationException "UnsupportedOperationException"
//   The request was rejected because a specified parameter is not supported or
//   a specified resource is not valid for this operation.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DisableKeyRotation
func (c *KMS) DisableKeyRotation(input *DisableKeyRotationInput) (*DisableKeyRotationOutput, error) {
	req, out := c.DisableKeyRotationRequest(input)
	return out, req.Send()
}

// DisableKeyRotationWithContext is the same as DisableKeyRotation with the addition of
// the ability to pass a context and additional request options.
//
// See DisableKeyRotation 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 *KMS) DisableKeyRotationWithContext(ctx aws.Context, input *DisableKeyRotationInput, opts ...request.Option) (*DisableKeyRotationOutput, error) {
	req, out := c.DisableKeyRotationRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDisconnectCustomKeyStore = "DisconnectCustomKeyStore"

// DisconnectCustomKeyStoreRequest generates a "aws/request.Request" representing the
// client's request for the DisconnectCustomKeyStore 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 DisconnectCustomKeyStore for more information on using the DisconnectCustomKeyStore
// 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 DisconnectCustomKeyStoreRequest method.
//    req, resp := client.DisconnectCustomKeyStoreRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DisconnectCustomKeyStore
func (c *KMS) DisconnectCustomKeyStoreRequest(input *DisconnectCustomKeyStoreInput) (req *request.Request, output *DisconnectCustomKeyStoreOutput) {
	op := &request.Operation{
		Name:       opDisconnectCustomKeyStore,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DisconnectCustomKeyStoreInput{}
	}

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

// DisconnectCustomKeyStore API operation for AWS Key Management Service.
//
// Disconnects the custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html)
// from its associated AWS CloudHSM cluster. While a custom key store is disconnected,
// you can manage the custom key store and its customer master keys (CMKs),
// but you cannot create or use CMKs in the custom key store. You can reconnect
// the custom key store at any time.
//
// While a custom key store is disconnected, all attempts to create customer
// master keys (CMKs) in the custom key store or to use existing CMKs in cryptographic
// operations will fail. This action can prevent users from storing and accessing
// sensitive data.
//
// To find the connection state of a custom key store, use the DescribeCustomKeyStoresoperation. To reconnect a custom key store, use the ConnectCustomKeyStoreoperation.
//
// If the operation succeeds, it returns a JSON object with no properties.
//
// This operation is part of the Custom Key Store feature (http://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.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 AWS Key Management Service's
// API operation DisconnectCustomKeyStore for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeCustomKeyStoreInvalidStateException "CustomKeyStoreInvalidStateException"
//   The request was rejected because of the ConnectionState of the custom key
//   store. To get the ConnectionState of a custom key store, use the DescribeCustomKeyStores
//   operation.
//
//   This exception is thrown under the following conditions:
//
//      * You requested the CreateKey or GenerateRandom operation in a custom
//      key store that is not connected. These operations are valid only when
//      the custom key store ConnectionState is CONNECTED.
//
//      * You requested the UpdateCustomKeyStore or DeleteCustomKeyStore operation
//      on a custom key store that is not disconnected. This operation is valid
//      only when the custom key store ConnectionState is DISCONNECTED.
//
//      * You requested the ConnectCustomKeyStore operation on a custom key store
//      with a ConnectionState of DISCONNECTING or FAILED. This operation is valid
//      for all other ConnectionState values.
//
//   * ErrCodeCustomKeyStoreNotFoundException "CustomKeyStoreNotFoundException"
//   The request was rejected because AWS KMS cannot find a custom key store with
//   the specified key store name or ID.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/DisconnectCustomKeyStore
func (c *KMS) DisconnectCustomKeyStore(input *DisconnectCustomKeyStoreInput) (*DisconnectCustomKeyStoreOutput, error) {
	req, out := c.DisconnectCustomKeyStoreRequest(input)
	return out, req.Send()
}

// DisconnectCustomKeyStoreWithContext is the same as DisconnectCustomKeyStore with the addition of
// the ability to pass a context and additional request options.
//
// See DisconnectCustomKeyStore 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 *KMS) DisconnectCustomKeyStoreWithContext(ctx aws.Context, input *DisconnectCustomKeyStoreInput, opts ...request.Option) (*DisconnectCustomKeyStoreOutput, error) {
	req, out := c.DisconnectCustomKeyStoreRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opEnableKey = "EnableKey"

// EnableKeyRequest generates a "aws/request.Request" representing the
// client's request for the EnableKey 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 EnableKey for more information on using the EnableKey
// 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 EnableKeyRequest method.
//    req, resp := client.EnableKeyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/EnableKey
func (c *KMS) EnableKeyRequest(input *EnableKeyInput) (req *request.Request, output *EnableKeyOutput) {
	op := &request.Operation{
		Name:       opEnableKey,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &EnableKeyInput{}
	}

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

// EnableKey API operation for AWS Key Management Service.
//
// Sets the key state of a customer master key (CMK) to enabled. This allows
// you to use the CMK for cryptographic operations. You cannot perform this
// operation on a CMK in a different AWS account.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation EnableKey for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeLimitExceededException "LimitExceededException"
//   The request was rejected because a limit was exceeded. For more information,
//   see Limits (http://docs.aws.amazon.com/kms/latest/developerguide/limits.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/EnableKey
func (c *KMS) EnableKey(input *EnableKeyInput) (*EnableKeyOutput, error) {
	req, out := c.EnableKeyRequest(input)
	return out, req.Send()
}

// EnableKeyWithContext is the same as EnableKey with the addition of
// the ability to pass a context and additional request options.
//
// See EnableKey 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 *KMS) EnableKeyWithContext(ctx aws.Context, input *EnableKeyInput, opts ...request.Option) (*EnableKeyOutput, error) {
	req, out := c.EnableKeyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opEnableKeyRotation = "EnableKeyRotation"

// EnableKeyRotationRequest generates a "aws/request.Request" representing the
// client's request for the EnableKeyRotation 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 EnableKeyRotation for more information on using the EnableKeyRotation
// 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 EnableKeyRotationRequest method.
//    req, resp := client.EnableKeyRotationRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/EnableKeyRotation
func (c *KMS) EnableKeyRotationRequest(input *EnableKeyRotationInput) (req *request.Request, output *EnableKeyRotationOutput) {
	op := &request.Operation{
		Name:       opEnableKeyRotation,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &EnableKeyRotationInput{}
	}

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

// EnableKeyRotation API operation for AWS Key Management Service.
//
// Enables automatic rotation of the key material (http://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html)
// for the specified customer master key (CMK). You cannot perform this operation
// on a CMK in a different AWS account.
//
// You cannot enable automatic rotation of CMKs with imported key material or
// CMKs in a custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html).
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation EnableKeyRotation for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDisabledException "DisabledException"
//   The request was rejected because the specified CMK is not enabled.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeUnsupportedOperationException "UnsupportedOperationException"
//   The request was rejected because a specified parameter is not supported or
//   a specified resource is not valid for this operation.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/EnableKeyRotation
func (c *KMS) EnableKeyRotation(input *EnableKeyRotationInput) (*EnableKeyRotationOutput, error) {
	req, out := c.EnableKeyRotationRequest(input)
	return out, req.Send()
}

// EnableKeyRotationWithContext is the same as EnableKeyRotation with the addition of
// the ability to pass a context and additional request options.
//
// See EnableKeyRotation 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 *KMS) EnableKeyRotationWithContext(ctx aws.Context, input *EnableKeyRotationInput, opts ...request.Option) (*EnableKeyRotationOutput, error) {
	req, out := c.EnableKeyRotationRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opEncrypt = "Encrypt"

// EncryptRequest generates a "aws/request.Request" representing the
// client's request for the Encrypt 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 Encrypt for more information on using the Encrypt
// 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 EncryptRequest method.
//    req, resp := client.EncryptRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/Encrypt
func (c *KMS) EncryptRequest(input *EncryptInput) (req *request.Request, output *EncryptOutput) {
	op := &request.Operation{
		Name:       opEncrypt,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &EncryptInput{}
	}

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

// Encrypt API operation for AWS Key Management Service.
//
// Encrypts plaintext into ciphertext by using a customer master key (CMK).
// The Encrypt operation has two primary use cases:
//
//    * You can encrypt up to 4 kilobytes (4096 bytes) of arbitrary data such
//    as an RSA key, a database password, or other sensitive information.
//
//    * To move encrypted data from one AWS region to another, you can use this
//    operation to encrypt in the new region the plaintext data key that was
//    used to encrypt the data in the original region. This provides you with
//    an encrypted copy of the data key that can be decrypted in the new region
//    and used there to decrypt the encrypted data.
//
// To perform this operation on a CMK in a different AWS account, specify the
// key ARN or alias ARN in the value of the KeyId parameter.
//
// Unless you are moving encrypted data from one region to another, you don't
// use this operation to encrypt a generated data key within a region. To get
// data keys that are already encrypted, call the GenerateDataKey or GenerateDataKeyWithoutPlaintext
// operation. Data keys don't need to be encrypted again by calling Encrypt.
//
// To encrypt data locally in your application, use the GenerateDataKey operation
// to return a plaintext data encryption key and a copy of the key encrypted
// under the CMK of your choosing.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation Encrypt for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDisabledException "DisabledException"
//   The request was rejected because the specified CMK is not enabled.
//
//   * ErrCodeKeyUnavailableException "KeyUnavailableException"
//   The request was rejected because the specified CMK was not available. The
//   request can be retried.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidKeyUsageException "InvalidKeyUsageException"
//   The request was rejected because the specified KeySpec value is not valid.
//
//   * ErrCodeInvalidGrantTokenException "InvalidGrantTokenException"
//   The request was rejected because the specified grant token is not valid.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/Encrypt
func (c *KMS) Encrypt(input *EncryptInput) (*EncryptOutput, error) {
	req, out := c.EncryptRequest(input)
	return out, req.Send()
}

// EncryptWithContext is the same as Encrypt with the addition of
// the ability to pass a context and additional request options.
//
// See Encrypt 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 *KMS) EncryptWithContext(ctx aws.Context, input *EncryptInput, opts ...request.Option) (*EncryptOutput, error) {
	req, out := c.EncryptRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGenerateDataKey = "GenerateDataKey"

// GenerateDataKeyRequest generates a "aws/request.Request" representing the
// client's request for the GenerateDataKey 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 GenerateDataKey for more information on using the GenerateDataKey
// 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 GenerateDataKeyRequest method.
//    req, resp := client.GenerateDataKeyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GenerateDataKey
func (c *KMS) GenerateDataKeyRequest(input *GenerateDataKeyInput) (req *request.Request, output *GenerateDataKeyOutput) {
	op := &request.Operation{
		Name:       opGenerateDataKey,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GenerateDataKeyInput{}
	}

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

// GenerateDataKey API operation for AWS Key Management Service.
//
// Returns a data encryption key that you can use in your application to encrypt
// data locally.
//
// You must specify the customer master key (CMK) under which to generate the
// data key. You must also specify the length of the data key using either the
// KeySpec or NumberOfBytes field. You must specify one field or the other,
// but not both. For common key lengths (128-bit and 256-bit symmetric keys),
// we recommend that you use KeySpec. To perform this operation on a CMK in
// a different AWS account, specify the key ARN or alias ARN in the value of
// the KeyId parameter.
//
// This operation returns a plaintext copy of the data key in the Plaintext
// field of the response, and an encrypted copy of the data key in the CiphertextBlob
// field. The data key is encrypted under the CMK specified in the KeyId field
// of the request.
//
// We recommend that you use the following pattern to encrypt data locally in
// your application:
//
// Use this operation (GenerateDataKey) to get a data encryption key.
//
// Use the plaintext data encryption key (returned in the Plaintext field of
// the response) to encrypt data locally, then erase the plaintext data key
// from memory.
//
// Store the encrypted data key (returned in the CiphertextBlob field of the
// response) alongside the locally encrypted data.
//
// To decrypt data locally:
//
// Use the Decrypt operation to decrypt the encrypted data key into a plaintext
// copy of the data key.
//
// Use the plaintext data key to decrypt data locally, then erase the plaintext
// data key from memory.
//
// To return only an encrypted copy of the data key, use GenerateDataKeyWithoutPlaintext.
// To return a random byte string that is cryptographically secure, use GenerateRandom.
//
// If you use the optional EncryptionContext field, you must store at least
// enough information to be able to reconstruct the full encryption context
// when you later send the ciphertext to the Decrypt operation. It is a good
// practice to choose an encryption context that you can reconstruct on the
// fly to better secure the ciphertext. For more information, see Encryption
// Context (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html)
// in the AWS Key Management Service Developer Guide.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation GenerateDataKey for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDisabledException "DisabledException"
//   The request was rejected because the specified CMK is not enabled.
//
//   * ErrCodeKeyUnavailableException "KeyUnavailableException"
//   The request was rejected because the specified CMK was not available. The
//   request can be retried.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidKeyUsageException "InvalidKeyUsageException"
//   The request was rejected because the specified KeySpec value is not valid.
//
//   * ErrCodeInvalidGrantTokenException "InvalidGrantTokenException"
//   The request was rejected because the specified grant token is not valid.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GenerateDataKey
func (c *KMS) GenerateDataKey(input *GenerateDataKeyInput) (*GenerateDataKeyOutput, error) {
	req, out := c.GenerateDataKeyRequest(input)
	return out, req.Send()
}

// GenerateDataKeyWithContext is the same as GenerateDataKey with the addition of
// the ability to pass a context and additional request options.
//
// See GenerateDataKey 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 *KMS) GenerateDataKeyWithContext(ctx aws.Context, input *GenerateDataKeyInput, opts ...request.Option) (*GenerateDataKeyOutput, error) {
	req, out := c.GenerateDataKeyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGenerateDataKeyWithoutPlaintext = "GenerateDataKeyWithoutPlaintext"

// GenerateDataKeyWithoutPlaintextRequest generates a "aws/request.Request" representing the
// client's request for the GenerateDataKeyWithoutPlaintext 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 GenerateDataKeyWithoutPlaintext for more information on using the GenerateDataKeyWithoutPlaintext
// 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 GenerateDataKeyWithoutPlaintextRequest method.
//    req, resp := client.GenerateDataKeyWithoutPlaintextRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GenerateDataKeyWithoutPlaintext
func (c *KMS) GenerateDataKeyWithoutPlaintextRequest(input *GenerateDataKeyWithoutPlaintextInput) (req *request.Request, output *GenerateDataKeyWithoutPlaintextOutput) {
	op := &request.Operation{
		Name:       opGenerateDataKeyWithoutPlaintext,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GenerateDataKeyWithoutPlaintextInput{}
	}

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

// GenerateDataKeyWithoutPlaintext API operation for AWS Key Management Service.
//
// Returns a data encryption key encrypted under a customer master key (CMK).
// This operation is identical to GenerateDataKey but returns only the encrypted
// copy of the data key.
//
// To perform this operation on a CMK in a different AWS account, specify the
// key ARN or alias ARN in the value of the KeyId parameter.
//
// This operation is useful in a system that has multiple components with different
// degrees of trust. For example, consider a system that stores encrypted data
// in containers. Each container stores the encrypted data and an encrypted
// copy of the data key. One component of the system, called the control plane,
// creates new containers. When it creates a new container, it uses this operation
// (GenerateDataKeyWithoutPlaintext) to get an encrypted data key and then stores
// it in the container. Later, a different component of the system, called the
// data plane, puts encrypted data into the containers. To do this, it passes
// the encrypted data key to the Decrypt operation, then uses the returned plaintext
// data key to encrypt data, and finally stores the encrypted data in the container.
// In this system, the control plane never sees the plaintext data key.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation GenerateDataKeyWithoutPlaintext for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDisabledException "DisabledException"
//   The request was rejected because the specified CMK is not enabled.
//
//   * ErrCodeKeyUnavailableException "KeyUnavailableException"
//   The request was rejected because the specified CMK was not available. The
//   request can be retried.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidKeyUsageException "InvalidKeyUsageException"
//   The request was rejected because the specified KeySpec value is not valid.
//
//   * ErrCodeInvalidGrantTokenException "InvalidGrantTokenException"
//   The request was rejected because the specified grant token is not valid.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GenerateDataKeyWithoutPlaintext
func (c *KMS) GenerateDataKeyWithoutPlaintext(input *GenerateDataKeyWithoutPlaintextInput) (*GenerateDataKeyWithoutPlaintextOutput, error) {
	req, out := c.GenerateDataKeyWithoutPlaintextRequest(input)
	return out, req.Send()
}

// GenerateDataKeyWithoutPlaintextWithContext is the same as GenerateDataKeyWithoutPlaintext with the addition of
// the ability to pass a context and additional request options.
//
// See GenerateDataKeyWithoutPlaintext 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 *KMS) GenerateDataKeyWithoutPlaintextWithContext(ctx aws.Context, input *GenerateDataKeyWithoutPlaintextInput, opts ...request.Option) (*GenerateDataKeyWithoutPlaintextOutput, error) {
	req, out := c.GenerateDataKeyWithoutPlaintextRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGenerateRandom = "GenerateRandom"

// GenerateRandomRequest generates a "aws/request.Request" representing the
// client's request for the GenerateRandom 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 GenerateRandom for more information on using the GenerateRandom
// 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 GenerateRandomRequest method.
//    req, resp := client.GenerateRandomRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GenerateRandom
func (c *KMS) GenerateRandomRequest(input *GenerateRandomInput) (req *request.Request, output *GenerateRandomOutput) {
	op := &request.Operation{
		Name:       opGenerateRandom,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GenerateRandomInput{}
	}

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

// GenerateRandom API operation for AWS Key Management Service.
//
// Returns a random byte string that is cryptographically secure.
//
// By default, the random byte string is generated in AWS KMS. To generate the
// byte string in the AWS CloudHSM cluster that is associated with a custom
// key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html),
// specify the custom key store ID.
//
// For more information about entropy and random number generation, see the
// AWS Key Management Service Cryptographic Details (https://d0.awsstatic.com/whitepapers/KMS-Cryptographic-Details.pdf)
// whitepaper.
//
// 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 AWS Key Management Service's
// API operation GenerateRandom for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeCustomKeyStoreNotFoundException "CustomKeyStoreNotFoundException"
//   The request was rejected because AWS KMS cannot find a custom key store with
//   the specified key store name or ID.
//
//   * ErrCodeCustomKeyStoreInvalidStateException "CustomKeyStoreInvalidStateException"
//   The request was rejected because of the ConnectionState of the custom key
//   store. To get the ConnectionState of a custom key store, use the DescribeCustomKeyStores
//   operation.
//
//   This exception is thrown under the following conditions:
//
//      * You requested the CreateKey or GenerateRandom operation in a custom
//      key store that is not connected. These operations are valid only when
//      the custom key store ConnectionState is CONNECTED.
//
//      * You requested the UpdateCustomKeyStore or DeleteCustomKeyStore operation
//      on a custom key store that is not disconnected. This operation is valid
//      only when the custom key store ConnectionState is DISCONNECTED.
//
//      * You requested the ConnectCustomKeyStore operation on a custom key store
//      with a ConnectionState of DISCONNECTING or FAILED. This operation is valid
//      for all other ConnectionState values.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GenerateRandom
func (c *KMS) GenerateRandom(input *GenerateRandomInput) (*GenerateRandomOutput, error) {
	req, out := c.GenerateRandomRequest(input)
	return out, req.Send()
}

// GenerateRandomWithContext is the same as GenerateRandom with the addition of
// the ability to pass a context and additional request options.
//
// See GenerateRandom 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 *KMS) GenerateRandomWithContext(ctx aws.Context, input *GenerateRandomInput, opts ...request.Option) (*GenerateRandomOutput, error) {
	req, out := c.GenerateRandomRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetKeyPolicy = "GetKeyPolicy"

// GetKeyPolicyRequest generates a "aws/request.Request" representing the
// client's request for the GetKeyPolicy 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 GetKeyPolicy for more information on using the GetKeyPolicy
// 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 GetKeyPolicyRequest method.
//    req, resp := client.GetKeyPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GetKeyPolicy
func (c *KMS) GetKeyPolicyRequest(input *GetKeyPolicyInput) (req *request.Request, output *GetKeyPolicyOutput) {
	op := &request.Operation{
		Name:       opGetKeyPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetKeyPolicyInput{}
	}

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

// GetKeyPolicy API operation for AWS Key Management Service.
//
// Gets a key policy attached to the specified customer master key (CMK). You
// cannot perform this operation on a CMK in a different AWS account.
//
// 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 AWS Key Management Service's
// API operation GetKeyPolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GetKeyPolicy
func (c *KMS) GetKeyPolicy(input *GetKeyPolicyInput) (*GetKeyPolicyOutput, error) {
	req, out := c.GetKeyPolicyRequest(input)
	return out, req.Send()
}

// GetKeyPolicyWithContext is the same as GetKeyPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See GetKeyPolicy 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 *KMS) GetKeyPolicyWithContext(ctx aws.Context, input *GetKeyPolicyInput, opts ...request.Option) (*GetKeyPolicyOutput, error) {
	req, out := c.GetKeyPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetKeyRotationStatus = "GetKeyRotationStatus"

// GetKeyRotationStatusRequest generates a "aws/request.Request" representing the
// client's request for the GetKeyRotationStatus 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 GetKeyRotationStatus for more information on using the GetKeyRotationStatus
// 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 GetKeyRotationStatusRequest method.
//    req, resp := client.GetKeyRotationStatusRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GetKeyRotationStatus
func (c *KMS) GetKeyRotationStatusRequest(input *GetKeyRotationStatusInput) (req *request.Request, output *GetKeyRotationStatusOutput) {
	op := &request.Operation{
		Name:       opGetKeyRotationStatus,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetKeyRotationStatusInput{}
	}

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

// GetKeyRotationStatus API operation for AWS Key Management Service.
//
// Gets a Boolean value that indicates whether automatic rotation of the key
// material (http://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html)
// is enabled for the specified customer master key (CMK).
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
//    * Disabled: The key rotation status does not change when you disable a
//    CMK. However, while the CMK is disabled, AWS KMS does not rotate the backing
//    key.
//
//    * Pending deletion: While a CMK is pending deletion, its key rotation
//    status is false and AWS KMS does not rotate the backing key. If you cancel
//    the deletion, the original key rotation status is restored.
//
// To perform this operation on a CMK in a different AWS account, specify the
// key ARN in the value of the KeyId parameter.
//
// 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 AWS Key Management Service's
// API operation GetKeyRotationStatus for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeUnsupportedOperationException "UnsupportedOperationException"
//   The request was rejected because a specified parameter is not supported or
//   a specified resource is not valid for this operation.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GetKeyRotationStatus
func (c *KMS) GetKeyRotationStatus(input *GetKeyRotationStatusInput) (*GetKeyRotationStatusOutput, error) {
	req, out := c.GetKeyRotationStatusRequest(input)
	return out, req.Send()
}

// GetKeyRotationStatusWithContext is the same as GetKeyRotationStatus with the addition of
// the ability to pass a context and additional request options.
//
// See GetKeyRotationStatus 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 *KMS) GetKeyRotationStatusWithContext(ctx aws.Context, input *GetKeyRotationStatusInput, opts ...request.Option) (*GetKeyRotationStatusOutput, error) {
	req, out := c.GetKeyRotationStatusRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opGetParametersForImport = "GetParametersForImport"

// GetParametersForImportRequest generates a "aws/request.Request" representing the
// client's request for the GetParametersForImport 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 GetParametersForImport for more information on using the GetParametersForImport
// 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 GetParametersForImportRequest method.
//    req, resp := client.GetParametersForImportRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GetParametersForImport
func (c *KMS) GetParametersForImportRequest(input *GetParametersForImportInput) (req *request.Request, output *GetParametersForImportOutput) {
	op := &request.Operation{
		Name:       opGetParametersForImport,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &GetParametersForImportInput{}
	}

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

// GetParametersForImport API operation for AWS Key Management Service.
//
// Returns the items you need in order to import key material into AWS KMS from
// your existing key management infrastructure. For more information about importing
// key material into AWS KMS, see Importing Key Material (http://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html)
// in the AWS Key Management Service Developer Guide.
//
// You must specify the key ID of the customer master key (CMK) into which you
// will import key material. This CMK's Origin must be EXTERNAL. You must also
// specify the wrapping algorithm and type of wrapping key (public key) that
// you will use to encrypt the key material. You cannot perform this operation
// on a CMK in a different AWS account.
//
// This operation returns a public key and an import token. Use the public key
// to encrypt the key material. Store the import token to send with a subsequent
// ImportKeyMaterial request. The public key and import token from the same
// response must be used together. These items are valid for 24 hours. When
// they expire, they cannot be used for a subsequent ImportKeyMaterial request.
// To get new ones, send another GetParametersForImport request.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation GetParametersForImport for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeUnsupportedOperationException "UnsupportedOperationException"
//   The request was rejected because a specified parameter is not supported or
//   a specified resource is not valid for this operation.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/GetParametersForImport
func (c *KMS) GetParametersForImport(input *GetParametersForImportInput) (*GetParametersForImportOutput, error) {
	req, out := c.GetParametersForImportRequest(input)
	return out, req.Send()
}

// GetParametersForImportWithContext is the same as GetParametersForImport with the addition of
// the ability to pass a context and additional request options.
//
// See GetParametersForImport 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 *KMS) GetParametersForImportWithContext(ctx aws.Context, input *GetParametersForImportInput, opts ...request.Option) (*GetParametersForImportOutput, error) {
	req, out := c.GetParametersForImportRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opImportKeyMaterial = "ImportKeyMaterial"

// ImportKeyMaterialRequest generates a "aws/request.Request" representing the
// client's request for the ImportKeyMaterial 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 ImportKeyMaterial for more information on using the ImportKeyMaterial
// 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 ImportKeyMaterialRequest method.
//    req, resp := client.ImportKeyMaterialRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ImportKeyMaterial
func (c *KMS) ImportKeyMaterialRequest(input *ImportKeyMaterialInput) (req *request.Request, output *ImportKeyMaterialOutput) {
	op := &request.Operation{
		Name:       opImportKeyMaterial,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ImportKeyMaterialInput{}
	}

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

// ImportKeyMaterial API operation for AWS Key Management Service.
//
// Imports key material into an existing AWS KMS customer master key (CMK) that
// was created without key material. You cannot perform this operation on a
// CMK in a different AWS account. For more information about creating CMKs
// with no key material and then importing key material, see Importing Key Material
// (http://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html)
// in the AWS Key Management Service Developer Guide.
//
// Before using this operation, call GetParametersForImport. Its response includes
// a public key and an import token. Use the public key to encrypt the key material.
// Then, submit the import token from the same GetParametersForImport response.
//
// When calling this operation, you must specify the following values:
//
//    * The key ID or key ARN of a CMK with no key material. Its Origin must
//    be EXTERNAL.
//
// To create a CMK with no key material, call CreateKey and set the value of
//    its Origin parameter to EXTERNAL. To get the Origin of a CMK, call DescribeKey.)
//
//    * The encrypted key material. To get the public key to encrypt the key
//    material, call GetParametersForImport.
//
//    * The import token that GetParametersForImport returned. This token and
//    the public key used to encrypt the key material must have come from the
//    same response.
//
//    * Whether the key material expires and if so, when. If you set an expiration
//    date, you can change it only by reimporting the same key material and
//    specifying a new expiration date. If the key material expires, AWS KMS
//    deletes the key material and the CMK becomes unusable. To use the CMK
//    again, you must reimport the same key material.
//
// When this operation is successful, the key state of the CMK changes from
// PendingImport to Enabled, and you can use the CMK. After you successfully
// import key material into a CMK, you can reimport the same key material into
// that CMK, but you cannot import different key material.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation ImportKeyMaterial for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeUnsupportedOperationException "UnsupportedOperationException"
//   The request was rejected because a specified parameter is not supported or
//   a specified resource is not valid for this operation.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeInvalidCiphertextException "InvalidCiphertextException"
//   The request was rejected because the specified ciphertext, or additional
//   authenticated data incorporated into the ciphertext, such as the encryption
//   context, is corrupted, missing, or otherwise invalid.
//
//   * ErrCodeIncorrectKeyMaterialException "IncorrectKeyMaterialException"
//   The request was rejected because the provided key material is invalid or
//   is not the same key material that was previously imported into this customer
//   master key (CMK).
//
//   * ErrCodeExpiredImportTokenException "ExpiredImportTokenException"
//   The request was rejected because the provided import token is expired. Use
//   GetParametersForImport to get a new import token and public key, use the
//   new public key to encrypt the key material, and then try the request again.
//
//   * ErrCodeInvalidImportTokenException "InvalidImportTokenException"
//   The request was rejected because the provided import token is invalid or
//   is associated with a different customer master key (CMK).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ImportKeyMaterial
func (c *KMS) ImportKeyMaterial(input *ImportKeyMaterialInput) (*ImportKeyMaterialOutput, error) {
	req, out := c.ImportKeyMaterialRequest(input)
	return out, req.Send()
}

// ImportKeyMaterialWithContext is the same as ImportKeyMaterial with the addition of
// the ability to pass a context and additional request options.
//
// See ImportKeyMaterial 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 *KMS) ImportKeyMaterialWithContext(ctx aws.Context, input *ImportKeyMaterialInput, opts ...request.Option) (*ImportKeyMaterialOutput, error) {
	req, out := c.ImportKeyMaterialRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opListAliases = "ListAliases"

// ListAliasesRequest generates a "aws/request.Request" representing the
// client's request for the ListAliases 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 ListAliases for more information on using the ListAliases
// 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 ListAliasesRequest method.
//    req, resp := client.ListAliasesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListAliases
func (c *KMS) ListAliasesRequest(input *ListAliasesInput) (req *request.Request, output *ListAliasesOutput) {
	op := &request.Operation{
		Name:       opListAliases,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"Marker"},
			OutputTokens:    []string{"NextMarker"},
			LimitToken:      "Limit",
			TruncationToken: "Truncated",
		},
	}

	if input == nil {
		input = &ListAliasesInput{}
	}

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

// ListAliases API operation for AWS Key Management Service.
//
// Gets a list of all aliases in the caller's AWS account and region. You cannot
// list aliases in other accounts. For more information about aliases, see CreateAlias.
//
// By default, the ListAliases command returns all aliases in the account and
// region. To get only the aliases that point to a particular customer master
// key (CMK), use the KeyId parameter.
//
// The ListAliases response might include several aliases have no TargetKeyId
// field. These are predefined aliases that AWS has created but has not yet
// associated with a CMK. Aliases that AWS creates in your account, including
// predefined aliases, do not count against your AWS KMS aliases limit (http://docs.aws.amazon.com/kms/latest/developerguide/limits.html#aliases-limit).
//
// 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 AWS Key Management Service's
// API operation ListAliases for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidMarkerException "InvalidMarkerException"
//   The request was rejected because the marker that specifies where pagination
//   should next begin is not valid.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListAliases
func (c *KMS) ListAliases(input *ListAliasesInput) (*ListAliasesOutput, error) {
	req, out := c.ListAliasesRequest(input)
	return out, req.Send()
}

// ListAliasesWithContext is the same as ListAliases with the addition of
// the ability to pass a context and additional request options.
//
// See ListAliases 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 *KMS) ListAliasesWithContext(ctx aws.Context, input *ListAliasesInput, opts ...request.Option) (*ListAliasesOutput, error) {
	req, out := c.ListAliasesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// ListAliasesPages iterates over the pages of a ListAliases operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See ListAliases 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 ListAliases operation.
//    pageNum := 0
//    err := client.ListAliasesPages(params,
//        func(page *ListAliasesOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *KMS) ListAliasesPages(input *ListAliasesInput, fn func(*ListAliasesOutput, bool) bool) error {
	return c.ListAliasesPagesWithContext(aws.BackgroundContext(), input, fn)
}

// ListAliasesPagesWithContext same as ListAliasesPages 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 *KMS) ListAliasesPagesWithContext(ctx aws.Context, input *ListAliasesInput, fn func(*ListAliasesOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *ListAliasesInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.ListAliasesRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

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

const opListGrants = "ListGrants"

// ListGrantsRequest generates a "aws/request.Request" representing the
// client's request for the ListGrants 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 ListGrants for more information on using the ListGrants
// 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 ListGrantsRequest method.
//    req, resp := client.ListGrantsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListGrants
func (c *KMS) ListGrantsRequest(input *ListGrantsInput) (req *request.Request, output *ListGrantsResponse) {
	op := &request.Operation{
		Name:       opListGrants,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"Marker"},
			OutputTokens:    []string{"NextMarker"},
			LimitToken:      "Limit",
			TruncationToken: "Truncated",
		},
	}

	if input == nil {
		input = &ListGrantsInput{}
	}

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

// ListGrants API operation for AWS Key Management Service.
//
// Gets a list of all grants for the specified customer master key (CMK).
//
// To perform this operation on a CMK in a different AWS account, specify the
// key ARN in the value of the KeyId parameter.
//
// 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 AWS Key Management Service's
// API operation ListGrants for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidMarkerException "InvalidMarkerException"
//   The request was rejected because the marker that specifies where pagination
//   should next begin is not valid.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListGrants
func (c *KMS) ListGrants(input *ListGrantsInput) (*ListGrantsResponse, error) {
	req, out := c.ListGrantsRequest(input)
	return out, req.Send()
}

// ListGrantsWithContext is the same as ListGrants with the addition of
// the ability to pass a context and additional request options.
//
// See ListGrants 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 *KMS) ListGrantsWithContext(ctx aws.Context, input *ListGrantsInput, opts ...request.Option) (*ListGrantsResponse, error) {
	req, out := c.ListGrantsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// ListGrantsPages iterates over the pages of a ListGrants operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See ListGrants 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 ListGrants operation.
//    pageNum := 0
//    err := client.ListGrantsPages(params,
//        func(page *ListGrantsResponse, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *KMS) ListGrantsPages(input *ListGrantsInput, fn func(*ListGrantsResponse, bool) bool) error {
	return c.ListGrantsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// ListGrantsPagesWithContext same as ListGrantsPages 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 *KMS) ListGrantsPagesWithContext(ctx aws.Context, input *ListGrantsInput, fn func(*ListGrantsResponse, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *ListGrantsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.ListGrantsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

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

const opListKeyPolicies = "ListKeyPolicies"

// ListKeyPoliciesRequest generates a "aws/request.Request" representing the
// client's request for the ListKeyPolicies 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 ListKeyPolicies for more information on using the ListKeyPolicies
// 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 ListKeyPoliciesRequest method.
//    req, resp := client.ListKeyPoliciesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListKeyPolicies
func (c *KMS) ListKeyPoliciesRequest(input *ListKeyPoliciesInput) (req *request.Request, output *ListKeyPoliciesOutput) {
	op := &request.Operation{
		Name:       opListKeyPolicies,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"Marker"},
			OutputTokens:    []string{"NextMarker"},
			LimitToken:      "Limit",
			TruncationToken: "Truncated",
		},
	}

	if input == nil {
		input = &ListKeyPoliciesInput{}
	}

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

// ListKeyPolicies API operation for AWS Key Management Service.
//
// Gets the names of the key policies that are attached to a customer master
// key (CMK). This operation is designed to get policy names that you can use
// in a GetKeyPolicy operation. However, the only valid policy name is default.
// You cannot perform this operation on a CMK in a different AWS account.
//
// 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 AWS Key Management Service's
// API operation ListKeyPolicies for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListKeyPolicies
func (c *KMS) ListKeyPolicies(input *ListKeyPoliciesInput) (*ListKeyPoliciesOutput, error) {
	req, out := c.ListKeyPoliciesRequest(input)
	return out, req.Send()
}

// ListKeyPoliciesWithContext is the same as ListKeyPolicies with the addition of
// the ability to pass a context and additional request options.
//
// See ListKeyPolicies 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 *KMS) ListKeyPoliciesWithContext(ctx aws.Context, input *ListKeyPoliciesInput, opts ...request.Option) (*ListKeyPoliciesOutput, error) {
	req, out := c.ListKeyPoliciesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// ListKeyPoliciesPages iterates over the pages of a ListKeyPolicies operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See ListKeyPolicies 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 ListKeyPolicies operation.
//    pageNum := 0
//    err := client.ListKeyPoliciesPages(params,
//        func(page *ListKeyPoliciesOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *KMS) ListKeyPoliciesPages(input *ListKeyPoliciesInput, fn func(*ListKeyPoliciesOutput, bool) bool) error {
	return c.ListKeyPoliciesPagesWithContext(aws.BackgroundContext(), input, fn)
}

// ListKeyPoliciesPagesWithContext same as ListKeyPoliciesPages 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 *KMS) ListKeyPoliciesPagesWithContext(ctx aws.Context, input *ListKeyPoliciesInput, fn func(*ListKeyPoliciesOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *ListKeyPoliciesInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.ListKeyPoliciesRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

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

const opListKeys = "ListKeys"

// ListKeysRequest generates a "aws/request.Request" representing the
// client's request for the ListKeys 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 ListKeys for more information on using the ListKeys
// 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 ListKeysRequest method.
//    req, resp := client.ListKeysRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListKeys
func (c *KMS) ListKeysRequest(input *ListKeysInput) (req *request.Request, output *ListKeysOutput) {
	op := &request.Operation{
		Name:       opListKeys,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"Marker"},
			OutputTokens:    []string{"NextMarker"},
			LimitToken:      "Limit",
			TruncationToken: "Truncated",
		},
	}

	if input == nil {
		input = &ListKeysInput{}
	}

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

// ListKeys API operation for AWS Key Management Service.
//
// Gets a list of all customer master keys (CMKs) in the caller's AWS account
// and region.
//
// 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 AWS Key Management Service's
// API operation ListKeys for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidMarkerException "InvalidMarkerException"
//   The request was rejected because the marker that specifies where pagination
//   should next begin is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListKeys
func (c *KMS) ListKeys(input *ListKeysInput) (*ListKeysOutput, error) {
	req, out := c.ListKeysRequest(input)
	return out, req.Send()
}

// ListKeysWithContext is the same as ListKeys with the addition of
// the ability to pass a context and additional request options.
//
// See ListKeys 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 *KMS) ListKeysWithContext(ctx aws.Context, input *ListKeysInput, opts ...request.Option) (*ListKeysOutput, error) {
	req, out := c.ListKeysRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// ListKeysPages iterates over the pages of a ListKeys operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See ListKeys 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 ListKeys operation.
//    pageNum := 0
//    err := client.ListKeysPages(params,
//        func(page *ListKeysOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *KMS) ListKeysPages(input *ListKeysInput, fn func(*ListKeysOutput, bool) bool) error {
	return c.ListKeysPagesWithContext(aws.BackgroundContext(), input, fn)
}

// ListKeysPagesWithContext same as ListKeysPages 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 *KMS) ListKeysPagesWithContext(ctx aws.Context, input *ListKeysInput, fn func(*ListKeysOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *ListKeysInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.ListKeysRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

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

const opListResourceTags = "ListResourceTags"

// ListResourceTagsRequest generates a "aws/request.Request" representing the
// client's request for the ListResourceTags 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 ListResourceTags for more information on using the ListResourceTags
// 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 ListResourceTagsRequest method.
//    req, resp := client.ListResourceTagsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListResourceTags
func (c *KMS) ListResourceTagsRequest(input *ListResourceTagsInput) (req *request.Request, output *ListResourceTagsOutput) {
	op := &request.Operation{
		Name:       opListResourceTags,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ListResourceTagsInput{}
	}

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

// ListResourceTags API operation for AWS Key Management Service.
//
// Returns a list of all tags for the specified customer master key (CMK).
//
// You cannot perform this operation on a CMK in a different AWS account.
//
// 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 AWS Key Management Service's
// API operation ListResourceTags for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeInvalidMarkerException "InvalidMarkerException"
//   The request was rejected because the marker that specifies where pagination
//   should next begin is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListResourceTags
func (c *KMS) ListResourceTags(input *ListResourceTagsInput) (*ListResourceTagsOutput, error) {
	req, out := c.ListResourceTagsRequest(input)
	return out, req.Send()
}

// ListResourceTagsWithContext is the same as ListResourceTags with the addition of
// the ability to pass a context and additional request options.
//
// See ListResourceTags 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 *KMS) ListResourceTagsWithContext(ctx aws.Context, input *ListResourceTagsInput, opts ...request.Option) (*ListResourceTagsOutput, error) {
	req, out := c.ListResourceTagsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opListRetirableGrants = "ListRetirableGrants"

// ListRetirableGrantsRequest generates a "aws/request.Request" representing the
// client's request for the ListRetirableGrants 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 ListRetirableGrants for more information on using the ListRetirableGrants
// 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 ListRetirableGrantsRequest method.
//    req, resp := client.ListRetirableGrantsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListRetirableGrants
func (c *KMS) ListRetirableGrantsRequest(input *ListRetirableGrantsInput) (req *request.Request, output *ListGrantsResponse) {
	op := &request.Operation{
		Name:       opListRetirableGrants,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ListRetirableGrantsInput{}
	}

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

// ListRetirableGrants API operation for AWS Key Management Service.
//
// Returns a list of all grants for which the grant's RetiringPrincipal matches
// the one specified.
//
// A typical use is to list all grants that you are able to retire. To retire
// a grant, use RetireGrant.
//
// 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 AWS Key Management Service's
// API operation ListRetirableGrants for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidMarkerException "InvalidMarkerException"
//   The request was rejected because the marker that specifies where pagination
//   should next begin is not valid.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ListRetirableGrants
func (c *KMS) ListRetirableGrants(input *ListRetirableGrantsInput) (*ListGrantsResponse, error) {
	req, out := c.ListRetirableGrantsRequest(input)
	return out, req.Send()
}

// ListRetirableGrantsWithContext is the same as ListRetirableGrants with the addition of
// the ability to pass a context and additional request options.
//
// See ListRetirableGrants 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 *KMS) ListRetirableGrantsWithContext(ctx aws.Context, input *ListRetirableGrantsInput, opts ...request.Option) (*ListGrantsResponse, error) {
	req, out := c.ListRetirableGrantsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutKeyPolicy = "PutKeyPolicy"

// PutKeyPolicyRequest generates a "aws/request.Request" representing the
// client's request for the PutKeyPolicy 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 PutKeyPolicy for more information on using the PutKeyPolicy
// 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 PutKeyPolicyRequest method.
//    req, resp := client.PutKeyPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/PutKeyPolicy
func (c *KMS) PutKeyPolicyRequest(input *PutKeyPolicyInput) (req *request.Request, output *PutKeyPolicyOutput) {
	op := &request.Operation{
		Name:       opPutKeyPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutKeyPolicyInput{}
	}

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

// PutKeyPolicy API operation for AWS Key Management Service.
//
// Attaches a key policy to the specified customer master key (CMK). You cannot
// perform this operation on a CMK in a different AWS account.
//
// For more information about key policies, see Key Policies (http://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation PutKeyPolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeMalformedPolicyDocumentException "MalformedPolicyDocumentException"
//   The request was rejected because the specified policy is not syntactically
//   or semantically correct.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeUnsupportedOperationException "UnsupportedOperationException"
//   The request was rejected because a specified parameter is not supported or
//   a specified resource is not valid for this operation.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeLimitExceededException "LimitExceededException"
//   The request was rejected because a limit was exceeded. For more information,
//   see Limits (http://docs.aws.amazon.com/kms/latest/developerguide/limits.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/PutKeyPolicy
func (c *KMS) PutKeyPolicy(input *PutKeyPolicyInput) (*PutKeyPolicyOutput, error) {
	req, out := c.PutKeyPolicyRequest(input)
	return out, req.Send()
}

// PutKeyPolicyWithContext is the same as PutKeyPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See PutKeyPolicy 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 *KMS) PutKeyPolicyWithContext(ctx aws.Context, input *PutKeyPolicyInput, opts ...request.Option) (*PutKeyPolicyOutput, error) {
	req, out := c.PutKeyPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opReEncrypt = "ReEncrypt"

// ReEncryptRequest generates a "aws/request.Request" representing the
// client's request for the ReEncrypt 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 ReEncrypt for more information on using the ReEncrypt
// 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 ReEncryptRequest method.
//    req, resp := client.ReEncryptRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ReEncrypt
func (c *KMS) ReEncryptRequest(input *ReEncryptInput) (req *request.Request, output *ReEncryptOutput) {
	op := &request.Operation{
		Name:       opReEncrypt,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ReEncryptInput{}
	}

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

// ReEncrypt API operation for AWS Key Management Service.
//
// Encrypts data on the server side with a new customer master key (CMK) without
// exposing the plaintext of the data on the client side. The data is first
// decrypted and then reencrypted. You can also use this operation to change
// the encryption context of a ciphertext.
//
// You can reencrypt data using CMKs in different AWS accounts.
//
// Unlike other operations, ReEncrypt is authorized twice, once as ReEncryptFrom
// on the source CMK and once as ReEncryptTo on the destination CMK. We recommend
// that you include the "kms:ReEncrypt*" permission in your key policies (http://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html)
// to permit reencryption from or to the CMK. This permission is automatically
// included in the key policy when you create a CMK through the console, but
// you must include it manually when you create a CMK programmatically or when
// you set a key policy with the PutKeyPolicy operation.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation ReEncrypt for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDisabledException "DisabledException"
//   The request was rejected because the specified CMK is not enabled.
//
//   * ErrCodeInvalidCiphertextException "InvalidCiphertextException"
//   The request was rejected because the specified ciphertext, or additional
//   authenticated data incorporated into the ciphertext, such as the encryption
//   context, is corrupted, missing, or otherwise invalid.
//
//   * ErrCodeKeyUnavailableException "KeyUnavailableException"
//   The request was rejected because the specified CMK was not available. The
//   request can be retried.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidKeyUsageException "InvalidKeyUsageException"
//   The request was rejected because the specified KeySpec value is not valid.
//
//   * ErrCodeInvalidGrantTokenException "InvalidGrantTokenException"
//   The request was rejected because the specified grant token is not valid.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ReEncrypt
func (c *KMS) ReEncrypt(input *ReEncryptInput) (*ReEncryptOutput, error) {
	req, out := c.ReEncryptRequest(input)
	return out, req.Send()
}

// ReEncryptWithContext is the same as ReEncrypt with the addition of
// the ability to pass a context and additional request options.
//
// See ReEncrypt 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 *KMS) ReEncryptWithContext(ctx aws.Context, input *ReEncryptInput, opts ...request.Option) (*ReEncryptOutput, error) {
	req, out := c.ReEncryptRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opRetireGrant = "RetireGrant"

// RetireGrantRequest generates a "aws/request.Request" representing the
// client's request for the RetireGrant 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 RetireGrant for more information on using the RetireGrant
// 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 RetireGrantRequest method.
//    req, resp := client.RetireGrantRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/RetireGrant
func (c *KMS) RetireGrantRequest(input *RetireGrantInput) (req *request.Request, output *RetireGrantOutput) {
	op := &request.Operation{
		Name:       opRetireGrant,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &RetireGrantInput{}
	}

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

// RetireGrant API operation for AWS Key Management Service.
//
// Retires a grant. To clean up, you can retire a grant when you're done using
// it. You should revoke a grant when you intend to actively deny operations
// that depend on it. The following are permitted to call this API:
//
//    * The AWS account (root user) under which the grant was created
//
//    * The RetiringPrincipal, if present in the grant
//
//    * The GranteePrincipal, if RetireGrant is an operation specified in the
//    grant
//
// You must identify the grant to retire by its grant token or by a combination
// of the grant ID and the Amazon Resource Name (ARN) of the customer master
// key (CMK). A grant token is a unique variable-length base64-encoded string.
// A grant ID is a 64 character unique identifier of a grant. The CreateGrant
// operation returns both.
//
// 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 AWS Key Management Service's
// API operation RetireGrant for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeInvalidGrantTokenException "InvalidGrantTokenException"
//   The request was rejected because the specified grant token is not valid.
//
//   * ErrCodeInvalidGrantIdException "InvalidGrantIdException"
//   The request was rejected because the specified GrantId is not valid.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/RetireGrant
func (c *KMS) RetireGrant(input *RetireGrantInput) (*RetireGrantOutput, error) {
	req, out := c.RetireGrantRequest(input)
	return out, req.Send()
}

// RetireGrantWithContext is the same as RetireGrant with the addition of
// the ability to pass a context and additional request options.
//
// See RetireGrant 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 *KMS) RetireGrantWithContext(ctx aws.Context, input *RetireGrantInput, opts ...request.Option) (*RetireGrantOutput, error) {
	req, out := c.RetireGrantRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opRevokeGrant = "RevokeGrant"

// RevokeGrantRequest generates a "aws/request.Request" representing the
// client's request for the RevokeGrant 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 RevokeGrant for more information on using the RevokeGrant
// 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 RevokeGrantRequest method.
//    req, resp := client.RevokeGrantRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/RevokeGrant
func (c *KMS) RevokeGrantRequest(input *RevokeGrantInput) (req *request.Request, output *RevokeGrantOutput) {
	op := &request.Operation{
		Name:       opRevokeGrant,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &RevokeGrantInput{}
	}

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

// RevokeGrant API operation for AWS Key Management Service.
//
// Revokes the specified grant for the specified customer master key (CMK).
// You can revoke a grant to actively deny operations that depend on it.
//
// To perform this operation on a CMK in a different AWS account, specify the
// key ARN in the value of the KeyId parameter.
//
// 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 AWS Key Management Service's
// API operation RevokeGrant for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeInvalidGrantIdException "InvalidGrantIdException"
//   The request was rejected because the specified GrantId is not valid.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/RevokeGrant
func (c *KMS) RevokeGrant(input *RevokeGrantInput) (*RevokeGrantOutput, error) {
	req, out := c.RevokeGrantRequest(input)
	return out, req.Send()
}

// RevokeGrantWithContext is the same as RevokeGrant with the addition of
// the ability to pass a context and additional request options.
//
// See RevokeGrant 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 *KMS) RevokeGrantWithContext(ctx aws.Context, input *RevokeGrantInput, opts ...request.Option) (*RevokeGrantOutput, error) {
	req, out := c.RevokeGrantRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opScheduleKeyDeletion = "ScheduleKeyDeletion"

// ScheduleKeyDeletionRequest generates a "aws/request.Request" representing the
// client's request for the ScheduleKeyDeletion 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 ScheduleKeyDeletion for more information on using the ScheduleKeyDeletion
// 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 ScheduleKeyDeletionRequest method.
//    req, resp := client.ScheduleKeyDeletionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ScheduleKeyDeletion
func (c *KMS) ScheduleKeyDeletionRequest(input *ScheduleKeyDeletionInput) (req *request.Request, output *ScheduleKeyDeletionOutput) {
	op := &request.Operation{
		Name:       opScheduleKeyDeletion,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ScheduleKeyDeletionInput{}
	}

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

// ScheduleKeyDeletion API operation for AWS Key Management Service.
//
// Schedules the deletion of a customer master key (CMK). You may provide a
// waiting period, specified in days, before deletion occurs. If you do not
// provide a waiting period, the default period of 30 days is used. When this
// operation is successful, the key state of the CMK changes to PendingDeletion.
// Before the waiting period ends, you can use CancelKeyDeletion to cancel the
// deletion of the CMK. After the waiting period ends, AWS KMS deletes the CMK
// and all AWS KMS data associated with it, including all aliases that refer
// to it.
//
// Deleting a CMK is a destructive and potentially dangerous operation. When
// a CMK is deleted, all data that was encrypted under the CMK is unrecoverable.
// To prevent the use of a CMK without deleting it, use DisableKey.
//
// If you schedule deletion of a CMK from a custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html),
// when the waiting period expires, ScheduleKeyDeletion deletes the CMK from
// AWS KMS. Then AWS KMS makes a best effort to delete the key material from
// the associated AWS CloudHSM cluster. However, you might need to manually
// delete the orphaned key material (http://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html#fix-keystore-orphaned-key)
// from the cluster and its backups.
//
// You cannot perform this operation on a CMK in a different AWS account.
//
// For more information about scheduling a CMK for deletion, see Deleting Customer
// Master Keys (http://docs.aws.amazon.com/kms/latest/developerguide/deleting-keys.html)
// in the AWS Key Management Service Developer Guide.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation ScheduleKeyDeletion for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/ScheduleKeyDeletion
func (c *KMS) ScheduleKeyDeletion(input *ScheduleKeyDeletionInput) (*ScheduleKeyDeletionOutput, error) {
	req, out := c.ScheduleKeyDeletionRequest(input)
	return out, req.Send()
}

// ScheduleKeyDeletionWithContext is the same as ScheduleKeyDeletion with the addition of
// the ability to pass a context and additional request options.
//
// See ScheduleKeyDeletion 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 *KMS) ScheduleKeyDeletionWithContext(ctx aws.Context, input *ScheduleKeyDeletionInput, opts ...request.Option) (*ScheduleKeyDeletionOutput, error) {
	req, out := c.ScheduleKeyDeletionRequest(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/kms-2014-11-01/TagResource
func (c *KMS) 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 AWS Key Management Service.
//
// Adds or edits tags for a customer master key (CMK). You cannot perform this
// operation on a CMK in a different AWS account.
//
// Each tag consists of a tag key and a tag value. Tag keys and tag values are
// both required, but tag values can be empty (null) strings.
//
// You can only use a tag key once for each CMK. If you use the tag key again,
// AWS KMS replaces the current tag value with the specified value.
//
// For information about the rules that apply to tag keys and tag values, see
// User-Defined Tag Restrictions (http://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/allocation-tag-restrictions.html)
// in the AWS Billing and Cost Management User Guide.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation TagResource for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeLimitExceededException "LimitExceededException"
//   The request was rejected because a limit was exceeded. For more information,
//   see Limits (http://docs.aws.amazon.com/kms/latest/developerguide/limits.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeTagException "TagException"
//   The request was rejected because one or more tags are not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/TagResource
func (c *KMS) 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 *KMS) 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/kms-2014-11-01/UntagResource
func (c *KMS) 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 AWS Key Management Service.
//
// Removes the specified tags from the specified customer master key (CMK).
// You cannot perform this operation on a CMK in a different AWS account.
//
// To remove a tag, specify the tag key. To change the tag value of an existing
// tag key, use TagResource.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation UntagResource for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
//   * ErrCodeTagException "TagException"
//   The request was rejected because one or more tags are not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/UntagResource
func (c *KMS) 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 *KMS) 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 opUpdateAlias = "UpdateAlias"

// UpdateAliasRequest generates a "aws/request.Request" representing the
// client's request for the UpdateAlias 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 UpdateAlias for more information on using the UpdateAlias
// 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 UpdateAliasRequest method.
//    req, resp := client.UpdateAliasRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/UpdateAlias
func (c *KMS) UpdateAliasRequest(input *UpdateAliasInput) (req *request.Request, output *UpdateAliasOutput) {
	op := &request.Operation{
		Name:       opUpdateAlias,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &UpdateAliasInput{}
	}

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

// UpdateAlias API operation for AWS Key Management Service.
//
// Associates an existing alias with a different customer master key (CMK).
// Each CMK can have multiple aliases, but the aliases must be unique within
// the account and region. You cannot perform this operation on an alias in
// a different AWS account.
//
// This operation works only on existing aliases. To change the alias of a CMK
// to a new value, use CreateAlias to create a new alias and DeleteAlias to
// delete the old alias.
//
// Because an alias is not a property of a CMK, you can create, update, and
// delete the aliases of a CMK without affecting the CMK. Also, aliases do not
// appear in the response from the DescribeKey operation. To get the aliases
// of all CMKs in the account, use the ListAliases operation.
//
// An alias name can contain only alphanumeric characters, forward slashes (/),
// underscores (_), and dashes (-). An alias must start with the word alias
// followed by a forward slash (alias/). The alias name can contain only alphanumeric
// characters, forward slashes (/), underscores (_), and dashes (-). Alias names
// cannot begin with aws; that alias name prefix is reserved by Amazon Web Services
// (AWS).
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation UpdateAlias for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/UpdateAlias
func (c *KMS) UpdateAlias(input *UpdateAliasInput) (*UpdateAliasOutput, error) {
	req, out := c.UpdateAliasRequest(input)
	return out, req.Send()
}

// UpdateAliasWithContext is the same as UpdateAlias with the addition of
// the ability to pass a context and additional request options.
//
// See UpdateAlias 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 *KMS) UpdateAliasWithContext(ctx aws.Context, input *UpdateAliasInput, opts ...request.Option) (*UpdateAliasOutput, error) {
	req, out := c.UpdateAliasRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opUpdateCustomKeyStore = "UpdateCustomKeyStore"

// UpdateCustomKeyStoreRequest generates a "aws/request.Request" representing the
// client's request for the UpdateCustomKeyStore 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 UpdateCustomKeyStore for more information on using the UpdateCustomKeyStore
// 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 UpdateCustomKeyStoreRequest method.
//    req, resp := client.UpdateCustomKeyStoreRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/UpdateCustomKeyStore
func (c *KMS) UpdateCustomKeyStoreRequest(input *UpdateCustomKeyStoreInput) (req *request.Request, output *UpdateCustomKeyStoreOutput) {
	op := &request.Operation{
		Name:       opUpdateCustomKeyStore,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &UpdateCustomKeyStoreInput{}
	}

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

// UpdateCustomKeyStore API operation for AWS Key Management Service.
//
// Changes the properties of a custom key store. Use the CustomKeyStoreId parameter
// to identify the custom key store you want to edit. Use the remaining parameters
// to change the properties of the custom key store.
//
// You can only update a custom key store that is disconnected. To disconnect
// the custom key store, use DisconnectCustomKeyStore. To reconnect the custom
// key store after the update completes, use ConnectCustomKeyStore. To find
// the connection state of a custom key store, use the DescribeCustomKeyStores
// operation.
//
// Use the NewCustomKeyStoreName parameter to change the friendly name of the
// custom key store to the value that you specify.
//
// Use the KeyStorePassword parameter tell AWS KMS the current password of the
// kmsuser (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-concepts.html#concept-kmsuser)
// crypto user (CU) in the associated AWS CloudHSM cluster. You can use this
// parameter to fix connection failures that occur when AWS KMS cannot log into
// the associated cluster because the kmsuser password has changed. This value
// does not change the password in the AWS CloudHSM cluster.
//
// Use the CloudHsmClusterId parameter to associate the custom key store with
// a related AWS CloudHSM cluster, that is, a cluster that shares a backup history
// with the original cluster. You can use this parameter to repair a custom
// key store if its AWS CloudHSM cluster becomes corrupted or is deleted, or
// when you need to create or restore a cluster from a backup.
//
// The cluster ID must identify a AWS CloudHSM cluster with the following requirements.
//
//    * The cluster must be active and be in the same AWS account and Region
//    as the custom key store.
//
//    * The cluster must have the same cluster certificate as the original cluster.
//    You cannot use this parameter to associate the custom key store with an
//    unrelated cluster. To view the cluster certificate, use the AWS CloudHSM
//    DescribeClusters (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_DescribeClusters.html)
//    operation. Clusters that share a backup history have the same cluster
//    certificate.
//
//    * The cluster must be configured with subnets in at least two different
//    Availability Zones in the Region. Because AWS CloudHSM is not supported
//    in all Availability Zones, we recommend that the cluster have subnets
//    in all Availability Zones in the Region.
//
//    * The cluster must contain at least two active HSMs, each in a different
//    Availability Zone.
//
// If the operation succeeds, it returns a JSON object with no properties.
//
// This operation is part of the Custom Key Store feature (http://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
// feature in AWS KMS, which combines the convenience and extensive integration
// of AWS KMS with the isolation and control of a single-tenant key store.
//
// 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 AWS Key Management Service's
// API operation UpdateCustomKeyStore for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeCustomKeyStoreNotFoundException "CustomKeyStoreNotFoundException"
//   The request was rejected because AWS KMS cannot find a custom key store with
//   the specified key store name or ID.
//
//   * ErrCodeCloudHsmClusterNotFoundException "CloudHsmClusterNotFoundException"
//   The request was rejected because AWS KMS cannot find the AWS CloudHSM cluster
//   with the specified cluster ID. Retry the request with a different cluster
//   ID.
//
//   * ErrCodeCloudHsmClusterNotRelatedException "CloudHsmClusterNotRelatedException"
//   The request was rejected because the specified AWS CloudHSM cluster has a
//   different cluster certificate than the original cluster. You cannot use the
//   operation to specify an unrelated cluster.
//
//   Specify a cluster that shares a backup history with the original cluster.
//   This includes clusters that were created from a backup of the current cluster,
//   and clusters that were created from the same backup that produced the current
//   cluster.
//
//   Clusters that share a backup history have the same cluster certificate. To
//   view the cluster certificate of a cluster, use the DescribeClusters (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_DescribeClusters.html)
//   operation.
//
//   * ErrCodeCustomKeyStoreInvalidStateException "CustomKeyStoreInvalidStateException"
//   The request was rejected because of the ConnectionState of the custom key
//   store. To get the ConnectionState of a custom key store, use the DescribeCustomKeyStores
//   operation.
//
//   This exception is thrown under the following conditions:
//
//      * You requested the CreateKey or GenerateRandom operation in a custom
//      key store that is not connected. These operations are valid only when
//      the custom key store ConnectionState is CONNECTED.
//
//      * You requested the UpdateCustomKeyStore or DeleteCustomKeyStore operation
//      on a custom key store that is not disconnected. This operation is valid
//      only when the custom key store ConnectionState is DISCONNECTED.
//
//      * You requested the ConnectCustomKeyStore operation on a custom key store
//      with a ConnectionState of DISCONNECTING or FAILED. This operation is valid
//      for all other ConnectionState values.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeCloudHsmClusterNotActiveException "CloudHsmClusterNotActiveException"
//   The request was rejected because the AWS CloudHSM cluster that is associated
//   with the custom key store is not active. Initialize and activate the cluster
//   and try the command again. For detailed instructions, see Getting Started
//   (http://docs.aws.amazon.com/cloudhsm/latest/userguide/getting-started.html)
//   in the AWS CloudHSM User Guide.
//
//   * ErrCodeCloudHsmClusterInvalidConfigurationException "CloudHsmClusterInvalidConfigurationException"
//   The request was rejected because the associated AWS CloudHSM cluster did
//   not meet the configuration requirements for a custom key store. The cluster
//   must be configured with private subnets in at least two different Availability
//   Zones in the Region. Also, it must contain at least as many HSMs as the operation
//   requires.
//
//   For the CreateCustomKeyStore, UpdateCustomKeyStore, and CreateKey operations,
//   the AWS CloudHSM cluster must have at least two active HSMs, each in a different
//   Availability Zone. For the ConnectCustomKeyStore operation, the AWS CloudHSM
//   must contain at least one active HSM.
//
//   For information about creating a private subnet for a AWS CloudHSM cluster,
//   see Create a Private Subnet (http://docs.aws.amazon.com/cloudhsm/latest/userguide/create-subnets.html)
//   in the AWS CloudHSM User Guide. To add HSMs, use the AWS CloudHSM CreateHsm
//   (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_CreateHsm.html)
//   operation.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/UpdateCustomKeyStore
func (c *KMS) UpdateCustomKeyStore(input *UpdateCustomKeyStoreInput) (*UpdateCustomKeyStoreOutput, error) {
	req, out := c.UpdateCustomKeyStoreRequest(input)
	return out, req.Send()
}

// UpdateCustomKeyStoreWithContext is the same as UpdateCustomKeyStore with the addition of
// the ability to pass a context and additional request options.
//
// See UpdateCustomKeyStore 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 *KMS) UpdateCustomKeyStoreWithContext(ctx aws.Context, input *UpdateCustomKeyStoreInput, opts ...request.Option) (*UpdateCustomKeyStoreOutput, error) {
	req, out := c.UpdateCustomKeyStoreRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opUpdateKeyDescription = "UpdateKeyDescription"

// UpdateKeyDescriptionRequest generates a "aws/request.Request" representing the
// client's request for the UpdateKeyDescription 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 UpdateKeyDescription for more information on using the UpdateKeyDescription
// 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 UpdateKeyDescriptionRequest method.
//    req, resp := client.UpdateKeyDescriptionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/UpdateKeyDescription
func (c *KMS) UpdateKeyDescriptionRequest(input *UpdateKeyDescriptionInput) (req *request.Request, output *UpdateKeyDescriptionOutput) {
	op := &request.Operation{
		Name:       opUpdateKeyDescription,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &UpdateKeyDescriptionInput{}
	}

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

// UpdateKeyDescription API operation for AWS Key Management Service.
//
// Updates the description of a customer master key (CMK). To see the decription
// of a CMK, use DescribeKey.
//
// You cannot perform this operation on a CMK in a different AWS account.
//
// The result of this operation varies with the key state of the CMK. For details,
// see How Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
// in the AWS Key Management Service Developer Guide.
//
// 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 AWS Key Management Service's
// API operation UpdateKeyDescription for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeNotFoundException "NotFoundException"
//   The request was rejected because the specified entity or resource could not
//   be found.
//
//   * ErrCodeInvalidArnException "InvalidArnException"
//   The request was rejected because a specified ARN was not valid.
//
//   * ErrCodeDependencyTimeoutException "DependencyTimeoutException"
//   The system timed out while trying to fulfill the request. The request can
//   be retried.
//
//   * ErrCodeInternalException "KMSInternalException"
//   The request was rejected because an internal exception occurred. The request
//   can be retried.
//
//   * ErrCodeInvalidStateException "KMSInvalidStateException"
//   The request was rejected because the state of the specified resource is not
//   valid for this request.
//
//   For more information about how key state affects the use of a CMK, see How
//   Key State Affects Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
//   in the AWS Key Management Service Developer Guide.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/kms-2014-11-01/UpdateKeyDescription
func (c *KMS) UpdateKeyDescription(input *UpdateKeyDescriptionInput) (*UpdateKeyDescriptionOutput, error) {
	req, out := c.UpdateKeyDescriptionRequest(input)
	return out, req.Send()
}

// UpdateKeyDescriptionWithContext is the same as UpdateKeyDescription with the addition of
// the ability to pass a context and additional request options.
//
// See UpdateKeyDescription 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 *KMS) UpdateKeyDescriptionWithContext(ctx aws.Context, input *UpdateKeyDescriptionInput, opts ...request.Option) (*UpdateKeyDescriptionOutput, error) {
	req, out := c.UpdateKeyDescriptionRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// Contains information about an alias.
type AliasListEntry struct {
	_ struct{} `type:"structure"`

	// String that contains the key ARN.
	AliasArn *string `min:"20" type:"string"`

	// String that contains the alias.
	AliasName *string `min:"1" type:"string"`

	// String that contains the key identifier referred to by the alias.
	TargetKeyId *string `min:"1" type:"string"`
}

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

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

// SetAliasArn sets the AliasArn field's value.
func (s *AliasListEntry) SetAliasArn(v string) *AliasListEntry {
	s.AliasArn = &v
	return s
}

// SetAliasName sets the AliasName field's value.
func (s *AliasListEntry) SetAliasName(v string) *AliasListEntry {
	s.AliasName = &v
	return s
}

// SetTargetKeyId sets the TargetKeyId field's value.
func (s *AliasListEntry) SetTargetKeyId(v string) *AliasListEntry {
	s.TargetKeyId = &v
	return s
}

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

	// The unique identifier for the customer master key (CMK) for which to cancel
	// deletion.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *CancelKeyDeletionInput) SetKeyId(v string) *CancelKeyDeletionInput {
	s.KeyId = &v
	return s
}

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

	// The unique identifier of the master key for which deletion is canceled.
	KeyId *string `min:"1" type:"string"`
}

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

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

// SetKeyId sets the KeyId field's value.
func (s *CancelKeyDeletionOutput) SetKeyId(v string) *CancelKeyDeletionOutput {
	s.KeyId = &v
	return s
}

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

	// Enter the key store ID of the custom key store that you want to connect.
	// To find the ID of a custom key store, use the DescribeCustomKeyStores operation.
	//
	// CustomKeyStoreId is a required field
	CustomKeyStoreId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetCustomKeyStoreId sets the CustomKeyStoreId field's value.
func (s *ConnectCustomKeyStoreInput) SetCustomKeyStoreId(v string) *ConnectCustomKeyStoreInput {
	s.CustomKeyStoreId = &v
	return s
}

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

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

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

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

	// String that contains the display name. The name must start with the word
	// "alias" followed by a forward slash (alias/). Aliases that begin with "alias/AWS"
	// are reserved.
	//
	// AliasName is a required field
	AliasName *string `min:"1" type:"string" required:"true"`

	// Identifies the CMK for which you are creating the alias. This value cannot
	// be an alias.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// TargetKeyId is a required field
	TargetKeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetAliasName sets the AliasName field's value.
func (s *CreateAliasInput) SetAliasName(v string) *CreateAliasInput {
	s.AliasName = &v
	return s
}

// SetTargetKeyId sets the TargetKeyId field's value.
func (s *CreateAliasInput) SetTargetKeyId(v string) *CreateAliasInput {
	s.TargetKeyId = &v
	return s
}

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

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

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

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

	// Identifies the AWS CloudHSM cluster for the custom key store. Enter the cluster
	// ID of any active AWS CloudHSM cluster that is not already associated with
	// a custom key store. To find the cluster ID, use the DescribeClusters (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_DescribeClusters.html)
	// operation.
	//
	// CloudHsmClusterId is a required field
	CloudHsmClusterId *string `min:"19" type:"string" required:"true"`

	// Specifies a friendly name for the custom key store. The name must be unique
	// in your AWS account.
	//
	// CustomKeyStoreName is a required field
	CustomKeyStoreName *string `min:"1" type:"string" required:"true"`

	// Enter the password of the kmsuser (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-concepts.html#concept-kmsuser)
	// crypto user (CU) account in the specified AWS CloudHSM cluster. AWS KMS logs
	// into the cluster as this user to manage key material on your behalf.
	//
	// This parameter tells AWS KMS the kmsuser account password; it does not change
	// the password in the AWS CloudHSM cluster.
	//
	// KeyStorePassword is a required field
	KeyStorePassword *string `min:"1" type:"string" required:"true" sensitive:"true"`

	// Enter the content of the trust anchor certificate for the cluster. This is
	// the content of the customerCA.crt file that you created when you initialized
	// the cluster (http://docs.aws.amazon.com/cloudhsm/latest/userguide/initialize-cluster.html).
	//
	// TrustAnchorCertificate is a required field
	TrustAnchorCertificate *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetCloudHsmClusterId sets the CloudHsmClusterId field's value.
func (s *CreateCustomKeyStoreInput) SetCloudHsmClusterId(v string) *CreateCustomKeyStoreInput {
	s.CloudHsmClusterId = &v
	return s
}

// SetCustomKeyStoreName sets the CustomKeyStoreName field's value.
func (s *CreateCustomKeyStoreInput) SetCustomKeyStoreName(v string) *CreateCustomKeyStoreInput {
	s.CustomKeyStoreName = &v
	return s
}

// SetKeyStorePassword sets the KeyStorePassword field's value.
func (s *CreateCustomKeyStoreInput) SetKeyStorePassword(v string) *CreateCustomKeyStoreInput {
	s.KeyStorePassword = &v
	return s
}

// SetTrustAnchorCertificate sets the TrustAnchorCertificate field's value.
func (s *CreateCustomKeyStoreInput) SetTrustAnchorCertificate(v string) *CreateCustomKeyStoreInput {
	s.TrustAnchorCertificate = &v
	return s
}

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

	// A unique identifier for the new custom key store.
	CustomKeyStoreId *string `min:"1" type:"string"`
}

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

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

// SetCustomKeyStoreId sets the CustomKeyStoreId field's value.
func (s *CreateCustomKeyStoreOutput) SetCustomKeyStoreId(v string) *CreateCustomKeyStoreOutput {
	s.CustomKeyStoreId = &v
	return s
}

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

	// A structure that you can use to allow certain operations in the grant only
	// when the desired encryption context is present. For more information about
	// encryption context, see Encryption Context (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html)
	// in the AWS Key Management Service Developer Guide.
	Constraints *GrantConstraints `type:"structure"`

	// A list of grant tokens.
	//
	// For more information, see Grant Tokens (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token)
	// in the AWS Key Management Service Developer Guide.
	GrantTokens []*string `type:"list"`

	// The principal that is given permission to perform the operations that the
	// grant permits.
	//
	// To specify the principal, use the Amazon Resource Name (ARN) (http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
	// of an AWS principal. Valid AWS principals include AWS accounts (root), IAM
	// users, IAM roles, federated users, and assumed role users. For examples of
	// the ARN syntax to use for specifying a principal, see AWS Identity and Access
	// Management (IAM) (http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-iam)
	// in the Example ARNs section of the AWS General Reference.
	//
	// GranteePrincipal is a required field
	GranteePrincipal *string `min:"1" type:"string" required:"true"`

	// The unique identifier for the customer master key (CMK) that the grant applies
	// to.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK. To specify
	// a CMK in a different AWS account, you must use the key ARN.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// A friendly name for identifying the grant. Use this value to prevent unintended
	// creation of duplicate grants when retrying this request.
	//
	// When this value is absent, all CreateGrant requests result in a new grant
	// with a unique GrantId even if all the supplied parameters are identical.
	// This can result in unintended duplicates when you retry the CreateGrant request.
	//
	// When this value is present, you can retry a CreateGrant request with identical
	// parameters; if the grant already exists, the original GrantId is returned
	// without creating a new grant. Note that the returned grant token is unique
	// with every CreateGrant request, even when a duplicate GrantId is returned.
	// All grant tokens obtained in this way can be used interchangeably.
	Name *string `min:"1" type:"string"`

	// A list of operations that the grant permits.
	//
	// Operations is a required field
	Operations []*string `type:"list" required:"true"`

	// The principal that is given permission to retire the grant by using RetireGrant
	// operation.
	//
	// To specify the principal, use the Amazon Resource Name (ARN) (http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
	// of an AWS principal. Valid AWS principals include AWS accounts (root), IAM
	// users, federated users, and assumed role users. For examples of the ARN syntax
	// to use for specifying a principal, see AWS Identity and Access Management
	// (IAM) (http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-iam)
	// in the Example ARNs section of the AWS General Reference.
	RetiringPrincipal *string `min:"1" type:"string"`
}

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

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

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

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

// SetConstraints sets the Constraints field's value.
func (s *CreateGrantInput) SetConstraints(v *GrantConstraints) *CreateGrantInput {
	s.Constraints = v
	return s
}

// SetGrantTokens sets the GrantTokens field's value.
func (s *CreateGrantInput) SetGrantTokens(v []*string) *CreateGrantInput {
	s.GrantTokens = v
	return s
}

// SetGranteePrincipal sets the GranteePrincipal field's value.
func (s *CreateGrantInput) SetGranteePrincipal(v string) *CreateGrantInput {
	s.GranteePrincipal = &v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *CreateGrantInput) SetKeyId(v string) *CreateGrantInput {
	s.KeyId = &v
	return s
}

// SetName sets the Name field's value.
func (s *CreateGrantInput) SetName(v string) *CreateGrantInput {
	s.Name = &v
	return s
}

// SetOperations sets the Operations field's value.
func (s *CreateGrantInput) SetOperations(v []*string) *CreateGrantInput {
	s.Operations = v
	return s
}

// SetRetiringPrincipal sets the RetiringPrincipal field's value.
func (s *CreateGrantInput) SetRetiringPrincipal(v string) *CreateGrantInput {
	s.RetiringPrincipal = &v
	return s
}

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

	// The unique identifier for the grant.
	//
	// You can use the GrantId in a subsequent RetireGrant or RevokeGrant operation.
	GrantId *string `min:"1" type:"string"`

	// The grant token.
	//
	// For more information, see Grant Tokens (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token)
	// in the AWS Key Management Service Developer Guide.
	GrantToken *string `min:"1" type:"string"`
}

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

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

// SetGrantId sets the GrantId field's value.
func (s *CreateGrantOutput) SetGrantId(v string) *CreateGrantOutput {
	s.GrantId = &v
	return s
}

// SetGrantToken sets the GrantToken field's value.
func (s *CreateGrantOutput) SetGrantToken(v string) *CreateGrantOutput {
	s.GrantToken = &v
	return s
}

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

	// A flag to indicate whether to bypass the key policy lockout safety check.
	//
	// Setting this value to true increases the risk that the CMK becomes unmanageable.
	// Do not set this value to true indiscriminately.
	//
	// For more information, refer to the scenario in the Default Key Policy (http://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default-allow-root-enable-iam)
	// section in the AWS Key Management Service Developer Guide.
	//
	// Use this parameter only when you include a policy in the request and you
	// intend to prevent the principal that is making the request from making a
	// subsequent PutKeyPolicy request on the CMK.
	//
	// The default value is false.
	BypassPolicyLockoutSafetyCheck *bool `type:"boolean"`

	// Creates the CMK in the specified custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html)
	// and the key material in its associated AWS CloudHSM cluster. To create a
	// CMK in a custom key store, you must also specify the Origin parameter with
	// a value of AWS_CLOUDHSM. The AWS CloudHSM cluster that is associated with
	// the custom key store must have at least two active HSMs, each in a different
	// Availability Zone in the Region.
	//
	// To find the ID of a custom key store, use the DescribeCustomKeyStores operation.
	//
	// The response includes the custom key store ID and the ID of the AWS CloudHSM
	// cluster.
	//
	// This operation is part of the Custom Key Store feature (http://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html)
	// feature in AWS KMS, which combines the convenience and extensive integration
	// of AWS KMS with the isolation and control of a single-tenant key store.
	CustomKeyStoreId *string `min:"1" type:"string"`

	// A description of the CMK.
	//
	// Use a description that helps you decide whether the CMK is appropriate for
	// a task.
	Description *string `type:"string"`

	// The intended use of the CMK.
	//
	// You can use CMKs only for symmetric encryption and decryption.
	KeyUsage *string `type:"string" enum:"KeyUsageType"`

	// The source of the CMK's key material. You cannot change the origin after
	// you create the CMK.
	//
	// The default is AWS_KMS, which means AWS KMS creates the key material in its
	// own key store.
	//
	// When the parameter value is EXTERNAL, AWS KMS creates a CMK without key material
	// so that you can import key material from your existing key management infrastructure.
	// For more information about importing key material into AWS KMS, see Importing
	// Key Material (http://docs.aws.amazon.com/kms/latest/developerguide/importing-keys.html)
	// in the AWS Key Management Service Developer Guide.
	//
	// When the parameter value is AWS_CLOUDHSM, AWS KMS creates the CMK in a AWS
	// KMS custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html)
	// and creates its key material in the associated AWS CloudHSM cluster. You
	// must also use the CustomKeyStoreId parameter to identify the custom key store.
	Origin *string `type:"string" enum:"OriginType"`

	// The key policy to attach to the CMK.
	//
	// If you provide a key policy, it must meet the following criteria:
	//
	//    * If you don't set BypassPolicyLockoutSafetyCheck to true, the key policy
	//    must allow the principal that is making the CreateKey request to make
	//    a subsequent PutKeyPolicy request on the CMK. This reduces the risk that
	//    the CMK becomes unmanageable. For more information, refer to the scenario
	//    in the Default Key Policy (http://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default-allow-root-enable-iam)
	//    section of the AWS Key Management Service Developer Guide.
	//
	//    * Each statement in the key policy must contain one or more principals.
	//    The principals in the key policy must exist and be visible to AWS KMS.
	//    When you create a new AWS principal (for example, an IAM user or role),
	//    you might need to enforce a delay before including the new principal in
	//    a key policy because the new principal might not be immediately visible
	//    to AWS KMS. For more information, see Changes that I make are not always
	//    immediately visible (http://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_eventual-consistency)
	//    in the AWS Identity and Access Management User Guide.
	//
	// If you do not provide a key policy, AWS KMS attaches a default key policy
	// to the CMK. For more information, see Default Key Policy (http://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default)
	// in the AWS Key Management Service Developer Guide.
	//
	// The key policy size limit is 32 kilobytes (32768 bytes).
	Policy *string `min:"1" type:"string"`

	// One or more tags. Each tag consists of a tag key and a tag value. Tag keys
	// and tag values are both required, but tag values can be empty (null) strings.
	//
	// Use this parameter to tag the CMK when it is created. Alternately, you can
	// omit this parameter and instead tag the CMK after it is created using TagResource.
	Tags []*Tag `type:"list"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateKeyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateKeyInput"}
	if s.CustomKeyStoreId != nil && len(*s.CustomKeyStoreId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("CustomKeyStoreId", 1))
	}
	if s.Policy != nil && len(*s.Policy) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Policy", 1))
	}
	if s.Tags != nil {
		for i, v := range s.Tags {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
			}
		}
	}

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

// SetBypassPolicyLockoutSafetyCheck sets the BypassPolicyLockoutSafetyCheck field's value.
func (s *CreateKeyInput) SetBypassPolicyLockoutSafetyCheck(v bool) *CreateKeyInput {
	s.BypassPolicyLockoutSafetyCheck = &v
	return s
}

// SetCustomKeyStoreId sets the CustomKeyStoreId field's value.
func (s *CreateKeyInput) SetCustomKeyStoreId(v string) *CreateKeyInput {
	s.CustomKeyStoreId = &v
	return s
}

// SetDescription sets the Description field's value.
func (s *CreateKeyInput) SetDescription(v string) *CreateKeyInput {
	s.Description = &v
	return s
}

// SetKeyUsage sets the KeyUsage field's value.
func (s *CreateKeyInput) SetKeyUsage(v string) *CreateKeyInput {
	s.KeyUsage = &v
	return s
}

// SetOrigin sets the Origin field's value.
func (s *CreateKeyInput) SetOrigin(v string) *CreateKeyInput {
	s.Origin = &v
	return s
}

// SetPolicy sets the Policy field's value.
func (s *CreateKeyInput) SetPolicy(v string) *CreateKeyInput {
	s.Policy = &v
	return s
}

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

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

	// Metadata associated with the CMK.
	KeyMetadata *KeyMetadata `type:"structure"`
}

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

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

// SetKeyMetadata sets the KeyMetadata field's value.
func (s *CreateKeyOutput) SetKeyMetadata(v *KeyMetadata) *CreateKeyOutput {
	s.KeyMetadata = v
	return s
}

// Contains information about each custom key store in the custom key store
// list.
type CustomKeyStoresListEntry struct {
	_ struct{} `type:"structure"`

	// A unique identifier for the AWS CloudHSM cluster that is associated with
	// the custom key store.
	CloudHsmClusterId *string `min:"19" type:"string"`

	// Describes the connection error. Valid values are:
	//
	//    * CLUSTER_NOT_FOUND - AWS KMS cannot find the AWS CloudHSM cluster with
	//    the specified cluster ID.
	//
	//    * INSUFFICIENT_CLOUDHSM_HSMS - The associated AWS CloudHSM cluster does
	//    not contain any active HSMs. To connect a custom key store to its AWS
	//    CloudHSM cluster, the cluster must contain at least one active HSM.
	//
	//    * INVALID_CREDENTIALS - AWS KMS does not have the correct password for
	//    the kmsuser crypto user in the AWS CloudHSM cluster.
	//
	//    * NETWORK_ERRORS - Network errors are preventing AWS KMS from connecting
	//    to the custom key store.
	//
	//    * USER_LOCKED_OUT - The kmsuser CU account is locked out of the associated
	//    AWS CloudHSM cluster due to too many failed password attempts. Before
	//    you can connect your custom key store to its AWS CloudHSM cluster, you
	//    must change the kmsuser account password and update the password value
	//    for the custom key store.
	//
	// For help with connection failures, see Troubleshooting Custom Key Stores
	// (http://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html)
	// in the AWS Key Management Service Developer Guide.
	ConnectionErrorCode *string `type:"string" enum:"ConnectionErrorCodeType"`

	// Indicates whether the custom key store is connected to its AWS CloudHSM cluster.
	//
	// You can create and use CMKs in your custom key stores only when its connection
	// state is CONNECTED.
	//
	// The value is DISCONNECTED if the key store has never been connected or you
	// use the DisconnectCustomKeyStore operation to disconnect it. If the value
	// is CONNECTED but you are having trouble using the custom key store, make
	// sure that its associated AWS CloudHSM cluster is active and contains at least
	// one active HSM.
	//
	// A value of FAILED indicates that an attempt to connect was unsuccessful.
	// For help resolving a connection failure, see Troubleshooting a Custom Key
	// Store (http://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html)
	// in the AWS Key Management Service Developer Guide.
	ConnectionState *string `type:"string" enum:"ConnectionStateType"`

	// The date and time when the custom key store was created.
	CreationDate *time.Time `type:"timestamp"`

	// A unique identifier for the custom key store.
	CustomKeyStoreId *string `min:"1" type:"string"`

	// The user-specified friendly name for the custom key store.
	CustomKeyStoreName *string `min:"1" type:"string"`

	// The trust anchor certificate of the associated AWS CloudHSM cluster. When
	// you initialize the cluster (http://docs.aws.amazon.com/cloudhsm/latest/userguide/initialize-cluster.html#sign-csr),
	// you create this certificate and save it in the customerCA.crt file.
	TrustAnchorCertificate *string `min:"1" type:"string"`
}

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

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

// SetCloudHsmClusterId sets the CloudHsmClusterId field's value.
func (s *CustomKeyStoresListEntry) SetCloudHsmClusterId(v string) *CustomKeyStoresListEntry {
	s.CloudHsmClusterId = &v
	return s
}

// SetConnectionErrorCode sets the ConnectionErrorCode field's value.
func (s *CustomKeyStoresListEntry) SetConnectionErrorCode(v string) *CustomKeyStoresListEntry {
	s.ConnectionErrorCode = &v
	return s
}

// SetConnectionState sets the ConnectionState field's value.
func (s *CustomKeyStoresListEntry) SetConnectionState(v string) *CustomKeyStoresListEntry {
	s.ConnectionState = &v
	return s
}

// SetCreationDate sets the CreationDate field's value.
func (s *CustomKeyStoresListEntry) SetCreationDate(v time.Time) *CustomKeyStoresListEntry {
	s.CreationDate = &v
	return s
}

// SetCustomKeyStoreId sets the CustomKeyStoreId field's value.
func (s *CustomKeyStoresListEntry) SetCustomKeyStoreId(v string) *CustomKeyStoresListEntry {
	s.CustomKeyStoreId = &v
	return s
}

// SetCustomKeyStoreName sets the CustomKeyStoreName field's value.
func (s *CustomKeyStoresListEntry) SetCustomKeyStoreName(v string) *CustomKeyStoresListEntry {
	s.CustomKeyStoreName = &v
	return s
}

// SetTrustAnchorCertificate sets the TrustAnchorCertificate field's value.
func (s *CustomKeyStoresListEntry) SetTrustAnchorCertificate(v string) *CustomKeyStoresListEntry {
	s.TrustAnchorCertificate = &v
	return s
}

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

	// Ciphertext to be decrypted. The blob includes metadata.
	//
	// CiphertextBlob is automatically base64 encoded/decoded by the SDK.
	//
	// CiphertextBlob is a required field
	CiphertextBlob []byte `min:"1" type:"blob" required:"true"`

	// The encryption context. If this was specified in the Encrypt function, it
	// must be specified here or the decryption operation will fail. For more information,
	// see Encryption Context (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html).
	EncryptionContext map[string]*string `type:"map"`

	// A list of grant tokens.
	//
	// For more information, see Grant Tokens (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token)
	// in the AWS Key Management Service Developer Guide.
	GrantTokens []*string `type:"list"`
}

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

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

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

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

// SetCiphertextBlob sets the CiphertextBlob field's value.
func (s *DecryptInput) SetCiphertextBlob(v []byte) *DecryptInput {
	s.CiphertextBlob = v
	return s
}

// SetEncryptionContext sets the EncryptionContext field's value.
func (s *DecryptInput) SetEncryptionContext(v map[string]*string) *DecryptInput {
	s.EncryptionContext = v
	return s
}

// SetGrantTokens sets the GrantTokens field's value.
func (s *DecryptInput) SetGrantTokens(v []*string) *DecryptInput {
	s.GrantTokens = v
	return s
}

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

	// ARN of the key used to perform the decryption. This value is returned if
	// no errors are encountered during the operation.
	KeyId *string `min:"1" type:"string"`

	// Decrypted plaintext data. When you use the HTTP API or the AWS CLI, the value
	// is Base64-encdoded. Otherwise, it is not encoded.
	//
	// Plaintext is automatically base64 encoded/decoded by the SDK.
	Plaintext []byte `min:"1" type:"blob" sensitive:"true"`
}

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

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

// SetKeyId sets the KeyId field's value.
func (s *DecryptOutput) SetKeyId(v string) *DecryptOutput {
	s.KeyId = &v
	return s
}

// SetPlaintext sets the Plaintext field's value.
func (s *DecryptOutput) SetPlaintext(v []byte) *DecryptOutput {
	s.Plaintext = v
	return s
}

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

	// The alias to be deleted. The name must start with the word "alias" followed
	// by a forward slash (alias/). Aliases that begin with "alias/aws" are reserved.
	//
	// AliasName is a required field
	AliasName *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetAliasName sets the AliasName field's value.
func (s *DeleteAliasInput) SetAliasName(v string) *DeleteAliasInput {
	s.AliasName = &v
	return s
}

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

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

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

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

	// Enter the ID of the custom key store you want to delete. To find the ID of
	// a custom key store, use the DescribeCustomKeyStores operation.
	//
	// CustomKeyStoreId is a required field
	CustomKeyStoreId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetCustomKeyStoreId sets the CustomKeyStoreId field's value.
func (s *DeleteCustomKeyStoreInput) SetCustomKeyStoreId(v string) *DeleteCustomKeyStoreInput {
	s.CustomKeyStoreId = &v
	return s
}

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

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

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

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

	// The identifier of the CMK whose key material to delete. The CMK's Origin
	// must be EXTERNAL.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *DeleteImportedKeyMaterialInput) SetKeyId(v string) *DeleteImportedKeyMaterialInput {
	s.KeyId = &v
	return s
}

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

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

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

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

	// Gets only information about the specified custom key store. Enter the key
	// store ID.
	//
	// By default, this operation gets information about all custom key stores in
	// the account and region. To limit the output to a particular custom key store,
	// you can use either the CustomKeyStoreId or CustomKeyStoreName parameter,
	// but not both.
	CustomKeyStoreId *string `min:"1" type:"string"`

	// Gets only information about the specified custom key store. Enter the friendly
	// name of the custom key store.
	//
	// By default, this operation gets information about all custom key stores in
	// the account and region. To limit the output to a particular custom key store,
	// you can use either the CustomKeyStoreId or CustomKeyStoreName parameter,
	// but not both.
	CustomKeyStoreName *string `min:"1" type:"string"`

	// Use this parameter to specify the maximum number of items to return. When
	// this value is present, AWS KMS does not return more than the specified number
	// of items, but it might return fewer.
	Limit *int64 `min:"1" type:"integer"`

	// Use this parameter in a subsequent request after you receive a response with
	// truncated results. Set it to the value of NextMarker from the truncated response
	// you just received.
	Marker *string `min:"1" type:"string"`
}

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

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

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

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

// SetCustomKeyStoreId sets the CustomKeyStoreId field's value.
func (s *DescribeCustomKeyStoresInput) SetCustomKeyStoreId(v string) *DescribeCustomKeyStoresInput {
	s.CustomKeyStoreId = &v
	return s
}

// SetCustomKeyStoreName sets the CustomKeyStoreName field's value.
func (s *DescribeCustomKeyStoresInput) SetCustomKeyStoreName(v string) *DescribeCustomKeyStoresInput {
	s.CustomKeyStoreName = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *DescribeCustomKeyStoresInput) SetLimit(v int64) *DescribeCustomKeyStoresInput {
	s.Limit = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *DescribeCustomKeyStoresInput) SetMarker(v string) *DescribeCustomKeyStoresInput {
	s.Marker = &v
	return s
}

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

	// Contains metadata about each custom key store.
	CustomKeyStores []*CustomKeyStoresListEntry `type:"list"`

	// When Truncated is true, this element is present and contains the value to
	// use for the Marker parameter in a subsequent request.
	NextMarker *string `min:"1" type:"string"`

	// A flag that indicates whether there are more items in the list. When this
	// value is true, the list in this response is truncated. To get more items,
	// pass the value of the NextMarker element in this response to the Marker parameter
	// in a subsequent request.
	Truncated *bool `type:"boolean"`
}

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

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

// SetCustomKeyStores sets the CustomKeyStores field's value.
func (s *DescribeCustomKeyStoresOutput) SetCustomKeyStores(v []*CustomKeyStoresListEntry) *DescribeCustomKeyStoresOutput {
	s.CustomKeyStores = v
	return s
}

// SetNextMarker sets the NextMarker field's value.
func (s *DescribeCustomKeyStoresOutput) SetNextMarker(v string) *DescribeCustomKeyStoresOutput {
	s.NextMarker = &v
	return s
}

// SetTruncated sets the Truncated field's value.
func (s *DescribeCustomKeyStoresOutput) SetTruncated(v bool) *DescribeCustomKeyStoresOutput {
	s.Truncated = &v
	return s
}

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

	// A list of grant tokens.
	//
	// For more information, see Grant Tokens (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token)
	// in the AWS Key Management Service Developer Guide.
	GrantTokens []*string `type:"list"`

	// Describes the specified customer master key (CMK).
	//
	// If you specify a predefined AWS alias (an AWS alias with no key ID), KMS
	// associates the alias with an AWS managed CMK (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)
	// and returns its KeyId and Arn in the response.
	//
	// To specify a CMK, use its key ID, Amazon Resource Name (ARN), alias name,
	// or alias ARN. When using an alias name, prefix it with "alias/". To specify
	// a CMK in a different AWS account, you must use the key ARN or alias ARN.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Alias name: alias/ExampleAlias
	//
	//    * Alias ARN: arn:aws:kms:us-east-2:111122223333:alias/ExampleAlias
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey. To
	// get the alias name and alias ARN, use ListAliases.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetGrantTokens sets the GrantTokens field's value.
func (s *DescribeKeyInput) SetGrantTokens(v []*string) *DescribeKeyInput {
	s.GrantTokens = v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *DescribeKeyInput) SetKeyId(v string) *DescribeKeyInput {
	s.KeyId = &v
	return s
}

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

	// Metadata associated with the key.
	KeyMetadata *KeyMetadata `type:"structure"`
}

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

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

// SetKeyMetadata sets the KeyMetadata field's value.
func (s *DescribeKeyOutput) SetKeyMetadata(v *KeyMetadata) *DescribeKeyOutput {
	s.KeyMetadata = v
	return s
}

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

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *DisableKeyInput) SetKeyId(v string) *DisableKeyInput {
	s.KeyId = &v
	return s
}

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

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

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

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

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *DisableKeyRotationInput) SetKeyId(v string) *DisableKeyRotationInput {
	s.KeyId = &v
	return s
}

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

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

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

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

	// Enter the ID of the custom key store you want to disconnect. To find the
	// ID of a custom key store, use the DescribeCustomKeyStores operation.
	//
	// CustomKeyStoreId is a required field
	CustomKeyStoreId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetCustomKeyStoreId sets the CustomKeyStoreId field's value.
func (s *DisconnectCustomKeyStoreInput) SetCustomKeyStoreId(v string) *DisconnectCustomKeyStoreInput {
	s.CustomKeyStoreId = &v
	return s
}

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

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

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

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

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *EnableKeyInput) SetKeyId(v string) *EnableKeyInput {
	s.KeyId = &v
	return s
}

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

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

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

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

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *EnableKeyRotationInput) SetKeyId(v string) *EnableKeyRotationInput {
	s.KeyId = &v
	return s
}

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

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

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

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

	// Name-value pair that specifies the encryption context to be used for authenticated
	// encryption. If used here, the same value must be supplied to the Decrypt
	// API or decryption will fail. For more information, see Encryption Context
	// (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html).
	EncryptionContext map[string]*string `type:"map"`

	// A list of grant tokens.
	//
	// For more information, see Grant Tokens (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token)
	// in the AWS Key Management Service Developer Guide.
	GrantTokens []*string `type:"list"`

	// A unique identifier for the customer master key (CMK).
	//
	// To specify a CMK, use its key ID, Amazon Resource Name (ARN), alias name,
	// or alias ARN. When using an alias name, prefix it with "alias/". To specify
	// a CMK in a different AWS account, you must use the key ARN or alias ARN.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Alias name: alias/ExampleAlias
	//
	//    * Alias ARN: arn:aws:kms:us-east-2:111122223333:alias/ExampleAlias
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey. To
	// get the alias name and alias ARN, use ListAliases.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// Data to be encrypted.
	//
	// Plaintext is automatically base64 encoded/decoded by the SDK.
	//
	// Plaintext is a required field
	Plaintext []byte `min:"1" type:"blob" required:"true" sensitive:"true"`
}

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

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

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

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

// SetEncryptionContext sets the EncryptionContext field's value.
func (s *EncryptInput) SetEncryptionContext(v map[string]*string) *EncryptInput {
	s.EncryptionContext = v
	return s
}

// SetGrantTokens sets the GrantTokens field's value.
func (s *EncryptInput) SetGrantTokens(v []*string) *EncryptInput {
	s.GrantTokens = v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *EncryptInput) SetKeyId(v string) *EncryptInput {
	s.KeyId = &v
	return s
}

// SetPlaintext sets the Plaintext field's value.
func (s *EncryptInput) SetPlaintext(v []byte) *EncryptInput {
	s.Plaintext = v
	return s
}

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

	// The encrypted plaintext. When you use the HTTP API or the AWS CLI, the value
	// is Base64-encdoded. Otherwise, it is not encoded.
	//
	// CiphertextBlob is automatically base64 encoded/decoded by the SDK.
	CiphertextBlob []byte `min:"1" type:"blob"`

	// The ID of the key used during encryption.
	KeyId *string `min:"1" type:"string"`
}

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

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

// SetCiphertextBlob sets the CiphertextBlob field's value.
func (s *EncryptOutput) SetCiphertextBlob(v []byte) *EncryptOutput {
	s.CiphertextBlob = v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *EncryptOutput) SetKeyId(v string) *EncryptOutput {
	s.KeyId = &v
	return s
}

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

	// A set of key-value pairs that represents additional authenticated data.
	//
	// For more information, see Encryption Context (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html)
	// in the AWS Key Management Service Developer Guide.
	EncryptionContext map[string]*string `type:"map"`

	// A list of grant tokens.
	//
	// For more information, see Grant Tokens (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token)
	// in the AWS Key Management Service Developer Guide.
	GrantTokens []*string `type:"list"`

	// The identifier of the CMK under which to generate and encrypt the data encryption
	// key.
	//
	// To specify a CMK, use its key ID, Amazon Resource Name (ARN), alias name,
	// or alias ARN. When using an alias name, prefix it with "alias/". To specify
	// a CMK in a different AWS account, you must use the key ARN or alias ARN.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Alias name: alias/ExampleAlias
	//
	//    * Alias ARN: arn:aws:kms:us-east-2:111122223333:alias/ExampleAlias
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey. To
	// get the alias name and alias ARN, use ListAliases.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// The length of the data encryption key. Use AES_128 to generate a 128-bit
	// symmetric key, or AES_256 to generate a 256-bit symmetric key.
	KeySpec *string `type:"string" enum:"DataKeySpec"`

	// The length of the data encryption key in bytes. For example, use the value
	// 64 to generate a 512-bit data key (64 bytes is 512 bits). For common key
	// lengths (128-bit and 256-bit symmetric keys), we recommend that you use the
	// KeySpec field instead of this one.
	NumberOfBytes *int64 `min:"1" type:"integer"`
}

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

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

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

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

// SetEncryptionContext sets the EncryptionContext field's value.
func (s *GenerateDataKeyInput) SetEncryptionContext(v map[string]*string) *GenerateDataKeyInput {
	s.EncryptionContext = v
	return s
}

// SetGrantTokens sets the GrantTokens field's value.
func (s *GenerateDataKeyInput) SetGrantTokens(v []*string) *GenerateDataKeyInput {
	s.GrantTokens = v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *GenerateDataKeyInput) SetKeyId(v string) *GenerateDataKeyInput {
	s.KeyId = &v
	return s
}

// SetKeySpec sets the KeySpec field's value.
func (s *GenerateDataKeyInput) SetKeySpec(v string) *GenerateDataKeyInput {
	s.KeySpec = &v
	return s
}

// SetNumberOfBytes sets the NumberOfBytes field's value.
func (s *GenerateDataKeyInput) SetNumberOfBytes(v int64) *GenerateDataKeyInput {
	s.NumberOfBytes = &v
	return s
}

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

	// The encrypted data encryption key. When you use the HTTP API or the AWS CLI,
	// the value is Base64-encdoded. Otherwise, it is not encoded.
	//
	// CiphertextBlob is automatically base64 encoded/decoded by the SDK.
	CiphertextBlob []byte `min:"1" type:"blob"`

	// The identifier of the CMK under which the data encryption key was generated
	// and encrypted.
	KeyId *string `min:"1" type:"string"`

	// The data encryption key. When you use the HTTP API or the AWS CLI, the value
	// is Base64-encdoded. Otherwise, it is not encoded. Use this data key for local
	// encryption and decryption, then remove it from memory as soon as possible.
	//
	// Plaintext is automatically base64 encoded/decoded by the SDK.
	Plaintext []byte `min:"1" type:"blob" sensitive:"true"`
}

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

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

// SetCiphertextBlob sets the CiphertextBlob field's value.
func (s *GenerateDataKeyOutput) SetCiphertextBlob(v []byte) *GenerateDataKeyOutput {
	s.CiphertextBlob = v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *GenerateDataKeyOutput) SetKeyId(v string) *GenerateDataKeyOutput {
	s.KeyId = &v
	return s
}

// SetPlaintext sets the Plaintext field's value.
func (s *GenerateDataKeyOutput) SetPlaintext(v []byte) *GenerateDataKeyOutput {
	s.Plaintext = v
	return s
}

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

	// A set of key-value pairs that represents additional authenticated data.
	//
	// For more information, see Encryption Context (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html)
	// in the AWS Key Management Service Developer Guide.
	EncryptionContext map[string]*string `type:"map"`

	// A list of grant tokens.
	//
	// For more information, see Grant Tokens (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token)
	// in the AWS Key Management Service Developer Guide.
	GrantTokens []*string `type:"list"`

	// The identifier of the customer master key (CMK) under which to generate and
	// encrypt the data encryption key.
	//
	// To specify a CMK, use its key ID, Amazon Resource Name (ARN), alias name,
	// or alias ARN. When using an alias name, prefix it with "alias/". To specify
	// a CMK in a different AWS account, you must use the key ARN or alias ARN.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Alias name: alias/ExampleAlias
	//
	//    * Alias ARN: arn:aws:kms:us-east-2:111122223333:alias/ExampleAlias
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey. To
	// get the alias name and alias ARN, use ListAliases.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// The length of the data encryption key. Use AES_128 to generate a 128-bit
	// symmetric key, or AES_256 to generate a 256-bit symmetric key.
	KeySpec *string `type:"string" enum:"DataKeySpec"`

	// The length of the data encryption key in bytes. For example, use the value
	// 64 to generate a 512-bit data key (64 bytes is 512 bits). For common key
	// lengths (128-bit and 256-bit symmetric keys), we recommend that you use the
	// KeySpec field instead of this one.
	NumberOfBytes *int64 `min:"1" type:"integer"`
}

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

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

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

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

// SetEncryptionContext sets the EncryptionContext field's value.
func (s *GenerateDataKeyWithoutPlaintextInput) SetEncryptionContext(v map[string]*string) *GenerateDataKeyWithoutPlaintextInput {
	s.EncryptionContext = v
	return s
}

// SetGrantTokens sets the GrantTokens field's value.
func (s *GenerateDataKeyWithoutPlaintextInput) SetGrantTokens(v []*string) *GenerateDataKeyWithoutPlaintextInput {
	s.GrantTokens = v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *GenerateDataKeyWithoutPlaintextInput) SetKeyId(v string) *GenerateDataKeyWithoutPlaintextInput {
	s.KeyId = &v
	return s
}

// SetKeySpec sets the KeySpec field's value.
func (s *GenerateDataKeyWithoutPlaintextInput) SetKeySpec(v string) *GenerateDataKeyWithoutPlaintextInput {
	s.KeySpec = &v
	return s
}

// SetNumberOfBytes sets the NumberOfBytes field's value.
func (s *GenerateDataKeyWithoutPlaintextInput) SetNumberOfBytes(v int64) *GenerateDataKeyWithoutPlaintextInput {
	s.NumberOfBytes = &v
	return s
}

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

	// The encrypted data encryption key. When you use the HTTP API or the AWS CLI,
	// the value is Base64-encdoded. Otherwise, it is not encoded.
	//
	// CiphertextBlob is automatically base64 encoded/decoded by the SDK.
	CiphertextBlob []byte `min:"1" type:"blob"`

	// The identifier of the CMK under which the data encryption key was generated
	// and encrypted.
	KeyId *string `min:"1" type:"string"`
}

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

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

// SetCiphertextBlob sets the CiphertextBlob field's value.
func (s *GenerateDataKeyWithoutPlaintextOutput) SetCiphertextBlob(v []byte) *GenerateDataKeyWithoutPlaintextOutput {
	s.CiphertextBlob = v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *GenerateDataKeyWithoutPlaintextOutput) SetKeyId(v string) *GenerateDataKeyWithoutPlaintextOutput {
	s.KeyId = &v
	return s
}

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

	// Generates the random byte string in the AWS CloudHSM cluster that is associated
	// with the specified custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html).
	// To find the ID of a custom key store, use the DescribeCustomKeyStores operation.
	CustomKeyStoreId *string `min:"1" type:"string"`

	// The length of the byte string.
	NumberOfBytes *int64 `min:"1" type:"integer"`
}

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

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

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

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

// SetCustomKeyStoreId sets the CustomKeyStoreId field's value.
func (s *GenerateRandomInput) SetCustomKeyStoreId(v string) *GenerateRandomInput {
	s.CustomKeyStoreId = &v
	return s
}

// SetNumberOfBytes sets the NumberOfBytes field's value.
func (s *GenerateRandomInput) SetNumberOfBytes(v int64) *GenerateRandomInput {
	s.NumberOfBytes = &v
	return s
}

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

	// The random byte string. When you use the HTTP API or the AWS CLI, the value
	// is Base64-encdoded. Otherwise, it is not encoded.
	//
	// Plaintext is automatically base64 encoded/decoded by the SDK.
	Plaintext []byte `min:"1" type:"blob" sensitive:"true"`
}

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

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

// SetPlaintext sets the Plaintext field's value.
func (s *GenerateRandomOutput) SetPlaintext(v []byte) *GenerateRandomOutput {
	s.Plaintext = v
	return s
}

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

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// Specifies the name of the key policy. The only valid name is default. To
	// get the names of key policies, use ListKeyPolicies.
	//
	// PolicyName is a required field
	PolicyName *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *GetKeyPolicyInput) SetKeyId(v string) *GetKeyPolicyInput {
	s.KeyId = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *GetKeyPolicyInput) SetPolicyName(v string) *GetKeyPolicyInput {
	s.PolicyName = &v
	return s
}

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

	// A key policy document in JSON format.
	Policy *string `min:"1" type:"string"`
}

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

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

// SetPolicy sets the Policy field's value.
func (s *GetKeyPolicyOutput) SetPolicy(v string) *GetKeyPolicyOutput {
	s.Policy = &v
	return s
}

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

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK. To specify
	// a CMK in a different AWS account, you must use the key ARN.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *GetKeyRotationStatusInput) SetKeyId(v string) *GetKeyRotationStatusInput {
	s.KeyId = &v
	return s
}

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

	// A Boolean value that specifies whether key rotation is enabled.
	KeyRotationEnabled *bool `type:"boolean"`
}

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

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

// SetKeyRotationEnabled sets the KeyRotationEnabled field's value.
func (s *GetKeyRotationStatusOutput) SetKeyRotationEnabled(v bool) *GetKeyRotationStatusOutput {
	s.KeyRotationEnabled = &v
	return s
}

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

	// The identifier of the CMK into which you will import key material. The CMK's
	// Origin must be EXTERNAL.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// The algorithm you will use to encrypt the key material before importing it
	// with ImportKeyMaterial. For more information, see Encrypt the Key Material
	// (http://docs.aws.amazon.com/kms/latest/developerguide/importing-keys-encrypt-key-material.html)
	// in the AWS Key Management Service Developer Guide.
	//
	// WrappingAlgorithm is a required field
	WrappingAlgorithm *string `type:"string" required:"true" enum:"AlgorithmSpec"`

	// The type of wrapping key (public key) to return in the response. Only 2048-bit
	// RSA public keys are supported.
	//
	// WrappingKeySpec is a required field
	WrappingKeySpec *string `type:"string" required:"true" enum:"WrappingKeySpec"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *GetParametersForImportInput) SetKeyId(v string) *GetParametersForImportInput {
	s.KeyId = &v
	return s
}

// SetWrappingAlgorithm sets the WrappingAlgorithm field's value.
func (s *GetParametersForImportInput) SetWrappingAlgorithm(v string) *GetParametersForImportInput {
	s.WrappingAlgorithm = &v
	return s
}

// SetWrappingKeySpec sets the WrappingKeySpec field's value.
func (s *GetParametersForImportInput) SetWrappingKeySpec(v string) *GetParametersForImportInput {
	s.WrappingKeySpec = &v
	return s
}

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

	// The import token to send in a subsequent ImportKeyMaterial request.
	//
	// ImportToken is automatically base64 encoded/decoded by the SDK.
	ImportToken []byte `min:"1" type:"blob"`

	// The identifier of the CMK to use in a subsequent ImportKeyMaterial request.
	// This is the same CMK specified in the GetParametersForImport request.
	KeyId *string `min:"1" type:"string"`

	// The time at which the import token and public key are no longer valid. After
	// this time, you cannot use them to make an ImportKeyMaterial request and you
	// must send another GetParametersForImport request to get new ones.
	ParametersValidTo *time.Time `type:"timestamp"`

	// The public key to use to encrypt the key material before importing it with
	// ImportKeyMaterial.
	//
	// PublicKey is automatically base64 encoded/decoded by the SDK.
	PublicKey []byte `min:"1" type:"blob" sensitive:"true"`
}

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

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

// SetImportToken sets the ImportToken field's value.
func (s *GetParametersForImportOutput) SetImportToken(v []byte) *GetParametersForImportOutput {
	s.ImportToken = v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *GetParametersForImportOutput) SetKeyId(v string) *GetParametersForImportOutput {
	s.KeyId = &v
	return s
}

// SetParametersValidTo sets the ParametersValidTo field's value.
func (s *GetParametersForImportOutput) SetParametersValidTo(v time.Time) *GetParametersForImportOutput {
	s.ParametersValidTo = &v
	return s
}

// SetPublicKey sets the PublicKey field's value.
func (s *GetParametersForImportOutput) SetPublicKey(v []byte) *GetParametersForImportOutput {
	s.PublicKey = v
	return s
}

// A structure that you can use to allow certain operations in the grant only
// when the desired encryption context is present. For more information about
// encryption context, see Encryption Context (http://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html)
// in the AWS Key Management Service Developer Guide.
//
// Grant constraints apply only to operations that accept encryption context
// as input. For example, the DescribeKey operation does not accept encryption
// context as input. A grant that allows the DescribeKey operation does so regardless
// of the grant constraints. In constrast, the Encrypt operation accepts encryption
// context as input. A grant that allows the Encrypt operation does so only
// when the encryption context of the Encrypt operation satisfies the grant
// constraints.
type GrantConstraints struct {
	_ struct{} `type:"structure"`

	// A list of key-value pairs that must be present in the encryption context
	// of certain subsequent operations that the grant allows. When certain subsequent
	// operations allowed by the grant include encryption context that matches this
	// list, the grant allows the operation. Otherwise, the grant does not allow
	// the operation.
	EncryptionContextEquals map[string]*string `type:"map"`

	// A list of key-value pairs, all of which must be present in the encryption
	// context of certain subsequent operations that the grant allows. When certain
	// subsequent operations allowed by the grant include encryption context that
	// matches this list or is a superset of this list, the grant allows the operation.
	// Otherwise, the grant does not allow the operation.
	EncryptionContextSubset map[string]*string `type:"map"`
}

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

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

// SetEncryptionContextEquals sets the EncryptionContextEquals field's value.
func (s *GrantConstraints) SetEncryptionContextEquals(v map[string]*string) *GrantConstraints {
	s.EncryptionContextEquals = v
	return s
}

// SetEncryptionContextSubset sets the EncryptionContextSubset field's value.
func (s *GrantConstraints) SetEncryptionContextSubset(v map[string]*string) *GrantConstraints {
	s.EncryptionContextSubset = v
	return s
}

// Contains information about an entry in a list of grants.
type GrantListEntry struct {
	_ struct{} `type:"structure"`

	// A list of key-value pairs that must be present in the encryption context
	// of certain subsequent operations that the grant allows.
	Constraints *GrantConstraints `type:"structure"`

	// The date and time when the grant was created.
	CreationDate *time.Time `type:"timestamp"`

	// The unique identifier for the grant.
	GrantId *string `min:"1" type:"string"`

	// The principal that receives the grant's permissions.
	GranteePrincipal *string `min:"1" type:"string"`

	// The AWS account under which the grant was issued.
	IssuingAccount *string `min:"1" type:"string"`

	// The unique identifier for the customer master key (CMK) to which the grant
	// applies.
	KeyId *string `min:"1" type:"string"`

	// The friendly name that identifies the grant. If a name was provided in the
	// CreateGrant request, that name is returned. Otherwise this value is null.
	Name *string `min:"1" type:"string"`

	// The list of operations permitted by the grant.
	Operations []*string `type:"list"`

	// The principal that can retire the grant.
	RetiringPrincipal *string `min:"1" type:"string"`
}

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

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

// SetConstraints sets the Constraints field's value.
func (s *GrantListEntry) SetConstraints(v *GrantConstraints) *GrantListEntry {
	s.Constraints = v
	return s
}

// SetCreationDate sets the CreationDate field's value.
func (s *GrantListEntry) SetCreationDate(v time.Time) *GrantListEntry {
	s.CreationDate = &v
	return s
}

// SetGrantId sets the GrantId field's value.
func (s *GrantListEntry) SetGrantId(v string) *GrantListEntry {
	s.GrantId = &v
	return s
}

// SetGranteePrincipal sets the GranteePrincipal field's value.
func (s *GrantListEntry) SetGranteePrincipal(v string) *GrantListEntry {
	s.GranteePrincipal = &v
	return s
}

// SetIssuingAccount sets the IssuingAccount field's value.
func (s *GrantListEntry) SetIssuingAccount(v string) *GrantListEntry {
	s.IssuingAccount = &v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *GrantListEntry) SetKeyId(v string) *GrantListEntry {
	s.KeyId = &v
	return s
}

// SetName sets the Name field's value.
func (s *GrantListEntry) SetName(v string) *GrantListEntry {
	s.Name = &v
	return s
}

// SetOperations sets the Operations field's value.
func (s *GrantListEntry) SetOperations(v []*string) *GrantListEntry {
	s.Operations = v
	return s
}

// SetRetiringPrincipal sets the RetiringPrincipal field's value.
func (s *GrantListEntry) SetRetiringPrincipal(v string) *GrantListEntry {
	s.RetiringPrincipal = &v
	return s
}

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

	// The encrypted key material to import. It must be encrypted with the public
	// key that you received in the response to a previous GetParametersForImport
	// request, using the wrapping algorithm that you specified in that request.
	//
	// EncryptedKeyMaterial is automatically base64 encoded/decoded by the SDK.
	//
	// EncryptedKeyMaterial is a required field
	EncryptedKeyMaterial []byte `min:"1" type:"blob" required:"true"`

	// Specifies whether the key material expires. The default is KEY_MATERIAL_EXPIRES,
	// in which case you must include the ValidTo parameter. When this parameter
	// is set to KEY_MATERIAL_DOES_NOT_EXPIRE, you must omit the ValidTo parameter.
	ExpirationModel *string `type:"string" enum:"ExpirationModelType"`

	// The import token that you received in the response to a previous GetParametersForImport
	// request. It must be from the same response that contained the public key
	// that you used to encrypt the key material.
	//
	// ImportToken is automatically base64 encoded/decoded by the SDK.
	//
	// ImportToken is a required field
	ImportToken []byte `min:"1" type:"blob" required:"true"`

	// The identifier of the CMK to import the key material into. The CMK's Origin
	// must be EXTERNAL.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// The time at which the imported key material expires. When the key material
	// expires, AWS KMS deletes the key material and the CMK becomes unusable. You
	// must omit this parameter when the ExpirationModel parameter is set to KEY_MATERIAL_DOES_NOT_EXPIRE.
	// Otherwise it is required.
	ValidTo *time.Time `type:"timestamp"`
}

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

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

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

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

// SetEncryptedKeyMaterial sets the EncryptedKeyMaterial field's value.
func (s *ImportKeyMaterialInput) SetEncryptedKeyMaterial(v []byte) *ImportKeyMaterialInput {
	s.EncryptedKeyMaterial = v
	return s
}

// SetExpirationModel sets the ExpirationModel field's value.
func (s *ImportKeyMaterialInput) SetExpirationModel(v string) *ImportKeyMaterialInput {
	s.ExpirationModel = &v
	return s
}

// SetImportToken sets the ImportToken field's value.
func (s *ImportKeyMaterialInput) SetImportToken(v []byte) *ImportKeyMaterialInput {
	s.ImportToken = v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *ImportKeyMaterialInput) SetKeyId(v string) *ImportKeyMaterialInput {
	s.KeyId = &v
	return s
}

// SetValidTo sets the ValidTo field's value.
func (s *ImportKeyMaterialInput) SetValidTo(v time.Time) *ImportKeyMaterialInput {
	s.ValidTo = &v
	return s
}

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

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

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

// Contains information about each entry in the key list.
type KeyListEntry struct {
	_ struct{} `type:"structure"`

	// ARN of the key.
	KeyArn *string `min:"20" type:"string"`

	// Unique identifier of the key.
	KeyId *string `min:"1" type:"string"`
}

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

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

// SetKeyArn sets the KeyArn field's value.
func (s *KeyListEntry) SetKeyArn(v string) *KeyListEntry {
	s.KeyArn = &v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *KeyListEntry) SetKeyId(v string) *KeyListEntry {
	s.KeyId = &v
	return s
}

// Contains metadata about a customer master key (CMK).
//
// This data type is used as a response element for the CreateKey and DescribeKey
// operations.
type KeyMetadata struct {
	_ struct{} `type:"structure"`

	// The twelve-digit account ID of the AWS account that owns the CMK.
	AWSAccountId *string `type:"string"`

	// The Amazon Resource Name (ARN) of the CMK. For examples, see AWS Key Management
	// Service (AWS KMS) (http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-kms)
	// in the Example ARNs section of the AWS General Reference.
	Arn *string `min:"20" type:"string"`

	// The cluster ID of the AWS CloudHSM cluster that contains the key material
	// for the CMK. When you create a CMK in a custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html),
	// AWS KMS creates the key material for the CMK in the associated AWS CloudHSM
	// cluster. This value is present only when the CMK is created in a custom key
	// store.
	CloudHsmClusterId *string `min:"19" type:"string"`

	// The date and time when the CMK was created.
	CreationDate *time.Time `type:"timestamp"`

	// A unique identifier for the custom key store (http://docs.aws.amazon.com/kms/latest/developerguide/key-store-overview.html)
	// that contains the CMK. This value is present only when the CMK is created
	// in a custom key store.
	CustomKeyStoreId *string `min:"1" type:"string"`

	// The date and time after which AWS KMS deletes the CMK. This value is present
	// only when KeyState is PendingDeletion.
	DeletionDate *time.Time `type:"timestamp"`

	// The description of the CMK.
	Description *string `type:"string"`

	// Specifies whether the CMK is enabled. When KeyState is Enabled this value
	// is true, otherwise it is false.
	Enabled *bool `type:"boolean"`

	// Specifies whether the CMK's key material expires. This value is present only
	// when Origin is EXTERNAL, otherwise this value is omitted.
	ExpirationModel *string `type:"string" enum:"ExpirationModelType"`

	// The globally unique identifier for the CMK.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// The CMK's manager. CMKs are either customer-managed or AWS-managed. For more
	// information about the difference, see Customer Master Keys (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)
	// in the AWS Key Management Service Developer Guide.
	KeyManager *string `type:"string" enum:"KeyManagerType"`

	// The state of the CMK.
	//
	// For more information about how key state affects the use of a CMK, see How
	// Key State Affects the Use of a Customer Master Key (http://docs.aws.amazon.com/kms/latest/developerguide/key-state.html)
	// in the AWS Key Management Service Developer Guide.
	KeyState *string `type:"string" enum:"KeyState"`

	// The cryptographic operations for which you can use the CMK. Currently the
	// only allowed value is ENCRYPT_DECRYPT, which means you can use the CMK for
	// the Encrypt and Decrypt operations.
	KeyUsage *string `type:"string" enum:"KeyUsageType"`

	// The source of the CMK's key material. When this value is AWS_KMS, AWS KMS
	// created the key material. When this value is EXTERNAL, the key material was
	// imported from your existing key management infrastructure or the CMK lacks
	// key material. When this value is AWS_CLOUDHSM, the key material was created
	// in the AWS CloudHSM cluster associated with a custom key store.
	Origin *string `type:"string" enum:"OriginType"`

	// The time at which the imported key material expires. When the key material
	// expires, AWS KMS deletes the key material and the CMK becomes unusable. This
	// value is present only for CMKs whose Origin is EXTERNAL and whose ExpirationModel
	// is KEY_MATERIAL_EXPIRES, otherwise this value is omitted.
	ValidTo *time.Time `type:"timestamp"`
}

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

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

// SetAWSAccountId sets the AWSAccountId field's value.
func (s *KeyMetadata) SetAWSAccountId(v string) *KeyMetadata {
	s.AWSAccountId = &v
	return s
}

// SetArn sets the Arn field's value.
func (s *KeyMetadata) SetArn(v string) *KeyMetadata {
	s.Arn = &v
	return s
}

// SetCloudHsmClusterId sets the CloudHsmClusterId field's value.
func (s *KeyMetadata) SetCloudHsmClusterId(v string) *KeyMetadata {
	s.CloudHsmClusterId = &v
	return s
}

// SetCreationDate sets the CreationDate field's value.
func (s *KeyMetadata) SetCreationDate(v time.Time) *KeyMetadata {
	s.CreationDate = &v
	return s
}

// SetCustomKeyStoreId sets the CustomKeyStoreId field's value.
func (s *KeyMetadata) SetCustomKeyStoreId(v string) *KeyMetadata {
	s.CustomKeyStoreId = &v
	return s
}

// SetDeletionDate sets the DeletionDate field's value.
func (s *KeyMetadata) SetDeletionDate(v time.Time) *KeyMetadata {
	s.DeletionDate = &v
	return s
}

// SetDescription sets the Description field's value.
func (s *KeyMetadata) SetDescription(v string) *KeyMetadata {
	s.Description = &v
	return s
}

// SetEnabled sets the Enabled field's value.
func (s *KeyMetadata) SetEnabled(v bool) *KeyMetadata {
	s.Enabled = &v
	return s
}

// SetExpirationModel sets the ExpirationModel field's value.
func (s *KeyMetadata) SetExpirationModel(v string) *KeyMetadata {
	s.ExpirationModel = &v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *KeyMetadata) SetKeyId(v string) *KeyMetadata {
	s.KeyId = &v
	return s
}

// SetKeyManager sets the KeyManager field's value.
func (s *KeyMetadata) SetKeyManager(v string) *KeyMetadata {
	s.KeyManager = &v
	return s
}

// SetKeyState sets the KeyState field's value.
func (s *KeyMetadata) SetKeyState(v string) *KeyMetadata {
	s.KeyState = &v
	return s
}

// SetKeyUsage sets the KeyUsage field's value.
func (s *KeyMetadata) SetKeyUsage(v string) *KeyMetadata {
	s.KeyUsage = &v
	return s
}

// SetOrigin sets the Origin field's value.
func (s *KeyMetadata) SetOrigin(v string) *KeyMetadata {
	s.Origin = &v
	return s
}

// SetValidTo sets the ValidTo field's value.
func (s *KeyMetadata) SetValidTo(v time.Time) *KeyMetadata {
	s.ValidTo = &v
	return s
}

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

	// Lists only aliases that refer to the specified CMK. The value of this parameter
	// can be the ID or Amazon Resource Name (ARN) of a CMK in the caller's account
	// and region. You cannot use an alias name or alias ARN in this value.
	//
	// This parameter is optional. If you omit it, ListAliases returns all aliases
	// in the account and region.
	KeyId *string `min:"1" type:"string"`

	// Use this parameter to specify the maximum number of items to return. When
	// this value is present, AWS KMS does not return more than the specified number
	// of items, but it might return fewer.
	//
	// This value is optional. If you include a value, it must be between 1 and
	// 100, inclusive. If you do not include a value, it defaults to 50.
	Limit *int64 `min:"1" type:"integer"`

	// Use this parameter in a subsequent request after you receive a response with
	// truncated results. Set it to the value of NextMarker from the truncated response
	// you just received.
	Marker *string `min:"1" type:"string"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *ListAliasesInput) SetKeyId(v string) *ListAliasesInput {
	s.KeyId = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *ListAliasesInput) SetLimit(v int64) *ListAliasesInput {
	s.Limit = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *ListAliasesInput) SetMarker(v string) *ListAliasesInput {
	s.Marker = &v
	return s
}

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

	// A list of aliases.
	Aliases []*AliasListEntry `type:"list"`

	// When Truncated is true, this element is present and contains the value to
	// use for the Marker parameter in a subsequent request.
	NextMarker *string `min:"1" type:"string"`

	// A flag that indicates whether there are more items in the list. When this
	// value is true, the list in this response is truncated. To get more items,
	// pass the value of the NextMarker element in this response to the Marker parameter
	// in a subsequent request.
	Truncated *bool `type:"boolean"`
}

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

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

// SetAliases sets the Aliases field's value.
func (s *ListAliasesOutput) SetAliases(v []*AliasListEntry) *ListAliasesOutput {
	s.Aliases = v
	return s
}

// SetNextMarker sets the NextMarker field's value.
func (s *ListAliasesOutput) SetNextMarker(v string) *ListAliasesOutput {
	s.NextMarker = &v
	return s
}

// SetTruncated sets the Truncated field's value.
func (s *ListAliasesOutput) SetTruncated(v bool) *ListAliasesOutput {
	s.Truncated = &v
	return s
}

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

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK. To specify
	// a CMK in a different AWS account, you must use the key ARN.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// Use this parameter to specify the maximum number of items to return. When
	// this value is present, AWS KMS does not return more than the specified number
	// of items, but it might return fewer.
	//
	// This value is optional. If you include a value, it must be between 1 and
	// 100, inclusive. If you do not include a value, it defaults to 50.
	Limit *int64 `min:"1" type:"integer"`

	// Use this parameter in a subsequent request after you receive a response with
	// truncated results. Set it to the value of NextMarker from the truncated response
	// you just received.
	Marker *string `min:"1" type:"string"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *ListGrantsInput) SetKeyId(v string) *ListGrantsInput {
	s.KeyId = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *ListGrantsInput) SetLimit(v int64) *ListGrantsInput {
	s.Limit = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *ListGrantsInput) SetMarker(v string) *ListGrantsInput {
	s.Marker = &v
	return s
}

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

	// A list of grants.
	Grants []*GrantListEntry `type:"list"`

	// When Truncated is true, this element is present and contains the value to
	// use for the Marker parameter in a subsequent request.
	NextMarker *string `min:"1" type:"string"`

	// A flag that indicates whether there are more items in the list. When this
	// value is true, the list in this response is truncated. To get more items,
	// pass the value of the NextMarker element in this response to the Marker parameter
	// in a subsequent request.
	Truncated *bool `type:"boolean"`
}

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

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

// SetGrants sets the Grants field's value.
func (s *ListGrantsResponse) SetGrants(v []*GrantListEntry) *ListGrantsResponse {
	s.Grants = v
	return s
}

// SetNextMarker sets the NextMarker field's value.
func (s *ListGrantsResponse) SetNextMarker(v string) *ListGrantsResponse {
	s.NextMarker = &v
	return s
}

// SetTruncated sets the Truncated field's value.
func (s *ListGrantsResponse) SetTruncated(v bool) *ListGrantsResponse {
	s.Truncated = &v
	return s
}

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

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// Use this parameter to specify the maximum number of items to return. When
	// this value is present, AWS KMS does not return more than the specified number
	// of items, but it might return fewer.
	//
	// This value is optional. If you include a value, it must be between 1 and
	// 1000, inclusive. If you do not include a value, it defaults to 100.
	//
	// Currently only 1 policy can be attached to a key.
	Limit *int64 `min:"1" type:"integer"`

	// Use this parameter in a subsequent request after you receive a response with
	// truncated results. Set it to the value of NextMarker from the truncated response
	// you just received.
	Marker *string `min:"1" type:"string"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *ListKeyPoliciesInput) SetKeyId(v string) *ListKeyPoliciesInput {
	s.KeyId = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *ListKeyPoliciesInput) SetLimit(v int64) *ListKeyPoliciesInput {
	s.Limit = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *ListKeyPoliciesInput) SetMarker(v string) *ListKeyPoliciesInput {
	s.Marker = &v
	return s
}

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

	// When Truncated is true, this element is present and contains the value to
	// use for the Marker parameter in a subsequent request.
	NextMarker *string `min:"1" type:"string"`

	// A list of key policy names. Currently, there is only one key policy per CMK
	// and it is always named default.
	PolicyNames []*string `type:"list"`

	// A flag that indicates whether there are more items in the list. When this
	// value is true, the list in this response is truncated. To get more items,
	// pass the value of the NextMarker element in this response to the Marker parameter
	// in a subsequent request.
	Truncated *bool `type:"boolean"`
}

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

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

// SetNextMarker sets the NextMarker field's value.
func (s *ListKeyPoliciesOutput) SetNextMarker(v string) *ListKeyPoliciesOutput {
	s.NextMarker = &v
	return s
}

// SetPolicyNames sets the PolicyNames field's value.
func (s *ListKeyPoliciesOutput) SetPolicyNames(v []*string) *ListKeyPoliciesOutput {
	s.PolicyNames = v
	return s
}

// SetTruncated sets the Truncated field's value.
func (s *ListKeyPoliciesOutput) SetTruncated(v bool) *ListKeyPoliciesOutput {
	s.Truncated = &v
	return s
}

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

	// Use this parameter to specify the maximum number of items to return. When
	// this value is present, AWS KMS does not return more than the specified number
	// of items, but it might return fewer.
	//
	// This value is optional. If you include a value, it must be between 1 and
	// 1000, inclusive. If you do not include a value, it defaults to 100.
	Limit *int64 `min:"1" type:"integer"`

	// Use this parameter in a subsequent request after you receive a response with
	// truncated results. Set it to the value of NextMarker from the truncated response
	// you just received.
	Marker *string `min:"1" type:"string"`
}

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

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

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

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

// SetLimit sets the Limit field's value.
func (s *ListKeysInput) SetLimit(v int64) *ListKeysInput {
	s.Limit = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *ListKeysInput) SetMarker(v string) *ListKeysInput {
	s.Marker = &v
	return s
}

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

	// A list of customer master keys (CMKs).
	Keys []*KeyListEntry `type:"list"`

	// When Truncated is true, this element is present and contains the value to
	// use for the Marker parameter in a subsequent request.
	NextMarker *string `min:"1" type:"string"`

	// A flag that indicates whether there are more items in the list. When this
	// value is true, the list in this response is truncated. To get more items,
	// pass the value of the NextMarker element in this response to the Marker parameter
	// in a subsequent request.
	Truncated *bool `type:"boolean"`
}

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

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

// SetKeys sets the Keys field's value.
func (s *ListKeysOutput) SetKeys(v []*KeyListEntry) *ListKeysOutput {
	s.Keys = v
	return s
}

// SetNextMarker sets the NextMarker field's value.
func (s *ListKeysOutput) SetNextMarker(v string) *ListKeysOutput {
	s.NextMarker = &v
	return s
}

// SetTruncated sets the Truncated field's value.
func (s *ListKeysOutput) SetTruncated(v bool) *ListKeysOutput {
	s.Truncated = &v
	return s
}

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

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// Use this parameter to specify the maximum number of items to return. When
	// this value is present, AWS KMS does not return more than the specified number
	// of items, but it might return fewer.
	//
	// This value is optional. If you include a value, it must be between 1 and
	// 50, inclusive. If you do not include a value, it defaults to 50.
	Limit *int64 `min:"1" type:"integer"`

	// Use this parameter in a subsequent request after you receive a response with
	// truncated results. Set it to the value of NextMarker from the truncated response
	// you just received.
	//
	// Do not attempt to construct this value. Use only the value of NextMarker
	// from the truncated response you just received.
	Marker *string `min:"1" type:"string"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *ListResourceTagsInput) SetKeyId(v string) *ListResourceTagsInput {
	s.KeyId = &v
	return s
}

// SetLimit sets the Limit field's value.
func (s *ListResourceTagsInput) SetLimit(v int64) *ListResourceTagsInput {
	s.Limit = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *ListResourceTagsInput) SetMarker(v string) *ListResourceTagsInput {
	s.Marker = &v
	return s
}

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

	// When Truncated is true, this element is present and contains the value to
	// use for the Marker parameter in a subsequent request.
	//
	// Do not assume or infer any information from this value.
	NextMarker *string `min:"1" type:"string"`

	// A list of tags. Each tag consists of a tag key and a tag value.
	Tags []*Tag `type:"list"`

	// A flag that indicates whether there are more items in the list. When this
	// value is true, the list in this response is truncated. To get more items,
	// pass the value of the NextMarker element in this response to the Marker parameter
	// in a subsequent request.
	Truncated *bool `type:"boolean"`
}

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

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

// SetNextMarker sets the NextMarker field's value.
func (s *ListResourceTagsOutput) SetNextMarker(v string) *ListResourceTagsOutput {
	s.NextMarker = &v
	return s
}

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

// SetTruncated sets the Truncated field's value.
func (s *ListResourceTagsOutput) SetTruncated(v bool) *ListResourceTagsOutput {
	s.Truncated = &v
	return s
}

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

	// Use this parameter to specify the maximum number of items to return. When
	// this value is present, AWS KMS does not return more than the specified number
	// of items, but it might return fewer.
	//
	// This value is optional. If you include a value, it must be between 1 and
	// 100, inclusive. If you do not include a value, it defaults to 50.
	Limit *int64 `min:"1" type:"integer"`

	// Use this parameter in a subsequent request after you receive a response with
	// truncated results. Set it to the value of NextMarker from the truncated response
	// you just received.
	Marker *string `min:"1" type:"string"`

	// The retiring principal for which to list grants.
	//
	// To specify the retiring principal, use the Amazon Resource Name (ARN) (http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html)
	// of an AWS principal. Valid AWS principals include AWS accounts (root), IAM
	// users, federated users, and assumed role users. For examples of the ARN syntax
	// for specifying a principal, see AWS Identity and Access Management (IAM)
	// (http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-iam)
	// in the Example ARNs section of the Amazon Web Services General Reference.
	//
	// RetiringPrincipal is a required field
	RetiringPrincipal *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetLimit sets the Limit field's value.
func (s *ListRetirableGrantsInput) SetLimit(v int64) *ListRetirableGrantsInput {
	s.Limit = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *ListRetirableGrantsInput) SetMarker(v string) *ListRetirableGrantsInput {
	s.Marker = &v
	return s
}

// SetRetiringPrincipal sets the RetiringPrincipal field's value.
func (s *ListRetirableGrantsInput) SetRetiringPrincipal(v string) *ListRetirableGrantsInput {
	s.RetiringPrincipal = &v
	return s
}

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

	// A flag to indicate whether to bypass the key policy lockout safety check.
	//
	// Setting this value to true increases the risk that the CMK becomes unmanageable.
	// Do not set this value to true indiscriminately.
	//
	// For more information, refer to the scenario in the Default Key Policy (http://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default-allow-root-enable-iam)
	// section in the AWS Key Management Service Developer Guide.
	//
	// Use this parameter only when you intend to prevent the principal that is
	// making the request from making a subsequent PutKeyPolicy request on the CMK.
	//
	// The default value is false.
	BypassPolicyLockoutSafetyCheck *bool `type:"boolean"`

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// The key policy to attach to the CMK.
	//
	// The key policy must meet the following criteria:
	//
	//    * If you don't set BypassPolicyLockoutSafetyCheck to true, the key policy
	//    must allow the principal that is making the PutKeyPolicy request to make
	//    a subsequent PutKeyPolicy request on the CMK. This reduces the risk that
	//    the CMK becomes unmanageable. For more information, refer to the scenario
	//    in the Default Key Policy (http://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default-allow-root-enable-iam)
	//    section of the AWS Key Management Service Developer Guide.
	//
	//    * Each statement in the key policy must contain one or more principals.
	//    The principals in the key policy must exist and be visible to AWS KMS.
	//    When you create a new AWS principal (for example, an IAM user or role),
	//    you might need to enforce a delay before including the new principal in
	//    a key policy because the new principal might not be immediately visible
	//    to AWS KMS. For more information, see Changes that I make are not always
	//    immediately visible (http://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_general.html#troubleshoot_general_eventual-consistency)
	//    in the AWS Identity and Access Management User Guide.
	//
	// The key policy size limit is 32 kilobytes (32768 bytes).
	//
	// Policy is a required field
	Policy *string `min:"1" type:"string" required:"true"`

	// The name of the key policy. The only valid value is default.
	//
	// PolicyName is a required field
	PolicyName *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetBypassPolicyLockoutSafetyCheck sets the BypassPolicyLockoutSafetyCheck field's value.
func (s *PutKeyPolicyInput) SetBypassPolicyLockoutSafetyCheck(v bool) *PutKeyPolicyInput {
	s.BypassPolicyLockoutSafetyCheck = &v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *PutKeyPolicyInput) SetKeyId(v string) *PutKeyPolicyInput {
	s.KeyId = &v
	return s
}

// SetPolicy sets the Policy field's value.
func (s *PutKeyPolicyInput) SetPolicy(v string) *PutKeyPolicyInput {
	s.Policy = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *PutKeyPolicyInput) SetPolicyName(v string) *PutKeyPolicyInput {
	s.PolicyName = &v
	return s
}

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

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

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

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

	// Ciphertext of the data to reencrypt.
	//
	// CiphertextBlob is automatically base64 encoded/decoded by the SDK.
	//
	// CiphertextBlob is a required field
	CiphertextBlob []byte `min:"1" type:"blob" required:"true"`

	// Encryption context to use when the data is reencrypted.
	DestinationEncryptionContext map[string]*string `type:"map"`

	// A unique identifier for the CMK that is used to reencrypt the data.
	//
	// To specify a CMK, use its key ID, Amazon Resource Name (ARN), alias name,
	// or alias ARN. When using an alias name, prefix it with "alias/". To specify
	// a CMK in a different AWS account, you must use the key ARN or alias ARN.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Alias name: alias/ExampleAlias
	//
	//    * Alias ARN: arn:aws:kms:us-east-2:111122223333:alias/ExampleAlias
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey. To
	// get the alias name and alias ARN, use ListAliases.
	//
	// DestinationKeyId is a required field
	DestinationKeyId *string `min:"1" type:"string" required:"true"`

	// A list of grant tokens.
	//
	// For more information, see Grant Tokens (http://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#grant_token)
	// in the AWS Key Management Service Developer Guide.
	GrantTokens []*string `type:"list"`

	// Encryption context used to encrypt and decrypt the data specified in the
	// CiphertextBlob parameter.
	SourceEncryptionContext map[string]*string `type:"map"`
}

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

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

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

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

// SetCiphertextBlob sets the CiphertextBlob field's value.
func (s *ReEncryptInput) SetCiphertextBlob(v []byte) *ReEncryptInput {
	s.CiphertextBlob = v
	return s
}

// SetDestinationEncryptionContext sets the DestinationEncryptionContext field's value.
func (s *ReEncryptInput) SetDestinationEncryptionContext(v map[string]*string) *ReEncryptInput {
	s.DestinationEncryptionContext = v
	return s
}

// SetDestinationKeyId sets the DestinationKeyId field's value.
func (s *ReEncryptInput) SetDestinationKeyId(v string) *ReEncryptInput {
	s.DestinationKeyId = &v
	return s
}

// SetGrantTokens sets the GrantTokens field's value.
func (s *ReEncryptInput) SetGrantTokens(v []*string) *ReEncryptInput {
	s.GrantTokens = v
	return s
}

// SetSourceEncryptionContext sets the SourceEncryptionContext field's value.
func (s *ReEncryptInput) SetSourceEncryptionContext(v map[string]*string) *ReEncryptInput {
	s.SourceEncryptionContext = v
	return s
}

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

	// The reencrypted data. When you use the HTTP API or the AWS CLI, the value
	// is Base64-encdoded. Otherwise, it is not encoded.
	//
	// CiphertextBlob is automatically base64 encoded/decoded by the SDK.
	CiphertextBlob []byte `min:"1" type:"blob"`

	// Unique identifier of the CMK used to reencrypt the data.
	KeyId *string `min:"1" type:"string"`

	// Unique identifier of the CMK used to originally encrypt the data.
	SourceKeyId *string `min:"1" type:"string"`
}

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

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

// SetCiphertextBlob sets the CiphertextBlob field's value.
func (s *ReEncryptOutput) SetCiphertextBlob(v []byte) *ReEncryptOutput {
	s.CiphertextBlob = v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *ReEncryptOutput) SetKeyId(v string) *ReEncryptOutput {
	s.KeyId = &v
	return s
}

// SetSourceKeyId sets the SourceKeyId field's value.
func (s *ReEncryptOutput) SetSourceKeyId(v string) *ReEncryptOutput {
	s.SourceKeyId = &v
	return s
}

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

	// Unique identifier of the grant to retire. The grant ID is returned in the
	// response to a CreateGrant operation.
	//
	//    * Grant ID Example - 0123456789012345678901234567890123456789012345678901234567890123
	GrantId *string `min:"1" type:"string"`

	// Token that identifies the grant to be retired.
	GrantToken *string `min:"1" type:"string"`

	// The Amazon Resource Name (ARN) of the CMK associated with the grant.
	//
	// For example: arn:aws:kms:us-east-2:444455556666:key/1234abcd-12ab-34cd-56ef-1234567890ab
	KeyId *string `min:"1" type:"string"`
}

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

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

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

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

// SetGrantId sets the GrantId field's value.
func (s *RetireGrantInput) SetGrantId(v string) *RetireGrantInput {
	s.GrantId = &v
	return s
}

// SetGrantToken sets the GrantToken field's value.
func (s *RetireGrantInput) SetGrantToken(v string) *RetireGrantInput {
	s.GrantToken = &v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *RetireGrantInput) SetKeyId(v string) *RetireGrantInput {
	s.KeyId = &v
	return s
}

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

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

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

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

	// Identifier of the grant to be revoked.
	//
	// GrantId is a required field
	GrantId *string `min:"1" type:"string" required:"true"`

	// A unique identifier for the customer master key associated with the grant.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK. To specify
	// a CMK in a different AWS account, you must use the key ARN.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetGrantId sets the GrantId field's value.
func (s *RevokeGrantInput) SetGrantId(v string) *RevokeGrantInput {
	s.GrantId = &v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *RevokeGrantInput) SetKeyId(v string) *RevokeGrantInput {
	s.KeyId = &v
	return s
}

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

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

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

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

	// The unique identifier of the customer master key (CMK) to delete.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// The waiting period, specified in number of days. After the waiting period
	// ends, AWS KMS deletes the customer master key (CMK).
	//
	// This value is optional. If you include a value, it must be between 7 and
	// 30, inclusive. If you do not include a value, it defaults to 30.
	PendingWindowInDays *int64 `min:"1" type:"integer"`
}

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

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

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

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

// SetKeyId sets the KeyId field's value.
func (s *ScheduleKeyDeletionInput) SetKeyId(v string) *ScheduleKeyDeletionInput {
	s.KeyId = &v
	return s
}

// SetPendingWindowInDays sets the PendingWindowInDays field's value.
func (s *ScheduleKeyDeletionInput) SetPendingWindowInDays(v int64) *ScheduleKeyDeletionInput {
	s.PendingWindowInDays = &v
	return s
}

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

	// The date and time after which AWS KMS deletes the customer master key (CMK).
	DeletionDate *time.Time `type:"timestamp"`

	// The unique identifier of the customer master key (CMK) for which deletion
	// is scheduled.
	KeyId *string `min:"1" type:"string"`
}

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

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

// SetDeletionDate sets the DeletionDate field's value.
func (s *ScheduleKeyDeletionOutput) SetDeletionDate(v time.Time) *ScheduleKeyDeletionOutput {
	s.DeletionDate = &v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *ScheduleKeyDeletionOutput) SetKeyId(v string) *ScheduleKeyDeletionOutput {
	s.KeyId = &v
	return s
}

// A key-value pair. A tag consists of a tag key and a tag value. Tag keys and
// tag values are both required, but tag values can be empty (null) strings.
//
// For information about the rules that apply to tag keys and tag values, see
// User-Defined Tag Restrictions (http://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/allocation-tag-restrictions.html)
// in the AWS Billing and Cost Management User Guide.
type Tag struct {
	_ struct{} `type:"structure"`

	// The key of the tag.
	//
	// TagKey is a required field
	TagKey *string `min:"1" type:"string" required:"true"`

	// The value of the tag.
	//
	// TagValue is a required field
	TagValue *string `type:"string" required:"true"`
}

// 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()
}

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

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

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

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

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

	// A unique identifier for the CMK you are tagging.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// One or more tags. Each tag consists of a tag key and a tag value.
	//
	// Tags is a required field
	Tags []*Tag `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.KeyId == nil {
		invalidParams.Add(request.NewErrParamRequired("KeyId"))
	}
	if s.KeyId != nil && len(*s.KeyId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("KeyId", 1))
	}
	if s.Tags == nil {
		invalidParams.Add(request.NewErrParamRequired("Tags"))
	}
	if s.Tags != nil {
		for i, v := range s.Tags {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
			}
		}
	}

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

// SetKeyId sets the KeyId field's value.
func (s *TagResourceInput) SetKeyId(v string) *TagResourceInput {
	s.KeyId = &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"`

	// A unique identifier for the CMK from which you are removing tags.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`

	// One or more tag keys. Specify only the tag keys, not the tag values.
	//
	// TagKeys is a required field
	TagKeys []*string `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.KeyId == nil {
		invalidParams.Add(request.NewErrParamRequired("KeyId"))
	}
	if s.KeyId != nil && len(*s.KeyId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("KeyId", 1))
	}
	if s.TagKeys == nil {
		invalidParams.Add(request.NewErrParamRequired("TagKeys"))
	}

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

// SetKeyId sets the KeyId field's value.
func (s *UntagResourceInput) SetKeyId(v string) *UntagResourceInput {
	s.KeyId = &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 UpdateAliasInput struct {
	_ struct{} `type:"structure"`

	// String that contains the name of the alias to be modified. The name must
	// start with the word "alias" followed by a forward slash (alias/). Aliases
	// that begin with "alias/aws" are reserved.
	//
	// AliasName is a required field
	AliasName *string `min:"1" type:"string" required:"true"`

	// Unique identifier of the customer master key to be mapped to the alias.
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// To verify that the alias is mapped to the correct CMK, use ListAliases.
	//
	// TargetKeyId is a required field
	TargetKeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetAliasName sets the AliasName field's value.
func (s *UpdateAliasInput) SetAliasName(v string) *UpdateAliasInput {
	s.AliasName = &v
	return s
}

// SetTargetKeyId sets the TargetKeyId field's value.
func (s *UpdateAliasInput) SetTargetKeyId(v string) *UpdateAliasInput {
	s.TargetKeyId = &v
	return s
}

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

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

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

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

	// Associates the custom key store with a related AWS CloudHSM cluster.
	//
	// Enter the cluster ID of the cluster that you used to create the custom key
	// store or a cluster that shares a backup history with the original cluster.
	// You cannot use this parameter to associate a custom key store with a different
	// cluster.
	//
	// Clusters that share a backup history have the same cluster certificate. To
	// view the cluster certificate of a cluster, use the DescribeClusters (http://docs.aws.amazon.com/cloudhsm/latest/APIReference/API_DescribeClusters.html)
	// operation.
	CloudHsmClusterId *string `min:"19" type:"string"`

	// Identifies the custom key store that you want to update. Enter the ID of
	// the custom key store. To find the ID of a custom key store, use the DescribeCustomKeyStores
	// operation.
	//
	// CustomKeyStoreId is a required field
	CustomKeyStoreId *string `min:"1" type:"string" required:"true"`

	// Enter the current password of the kmsuser crypto user (CU) in the AWS CloudHSM
	// cluster that is associated with the custom key store.
	//
	// This parameter tells AWS KMS the current password of the kmsuser crypto user
	// (CU). It does not set or change the password of any users in the AWS CloudHSM
	// cluster.
	KeyStorePassword *string `min:"1" type:"string" sensitive:"true"`

	// Changes the friendly name of the custom key store to the value that you specify.
	// The custom key store name must be unique in the AWS account.
	NewCustomKeyStoreName *string `min:"1" type:"string"`
}

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

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

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

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

// SetCloudHsmClusterId sets the CloudHsmClusterId field's value.
func (s *UpdateCustomKeyStoreInput) SetCloudHsmClusterId(v string) *UpdateCustomKeyStoreInput {
	s.CloudHsmClusterId = &v
	return s
}

// SetCustomKeyStoreId sets the CustomKeyStoreId field's value.
func (s *UpdateCustomKeyStoreInput) SetCustomKeyStoreId(v string) *UpdateCustomKeyStoreInput {
	s.CustomKeyStoreId = &v
	return s
}

// SetKeyStorePassword sets the KeyStorePassword field's value.
func (s *UpdateCustomKeyStoreInput) SetKeyStorePassword(v string) *UpdateCustomKeyStoreInput {
	s.KeyStorePassword = &v
	return s
}

// SetNewCustomKeyStoreName sets the NewCustomKeyStoreName field's value.
func (s *UpdateCustomKeyStoreInput) SetNewCustomKeyStoreName(v string) *UpdateCustomKeyStoreInput {
	s.NewCustomKeyStoreName = &v
	return s
}

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

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

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

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

	// New description for the CMK.
	//
	// Description is a required field
	Description *string `type:"string" required:"true"`

	// A unique identifier for the customer master key (CMK).
	//
	// Specify the key ID or the Amazon Resource Name (ARN) of the CMK.
	//
	// For example:
	//
	//    * Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
	//
	//    * Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
	//
	// To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey.
	//
	// KeyId is a required field
	KeyId *string `min:"1" type:"string" required:"true"`
}

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

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

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

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

// SetDescription sets the Description field's value.
func (s *UpdateKeyDescriptionInput) SetDescription(v string) *UpdateKeyDescriptionInput {
	s.Description = &v
	return s
}

// SetKeyId sets the KeyId field's value.
func (s *UpdateKeyDescriptionInput) SetKeyId(v string) *UpdateKeyDescriptionInput {
	s.KeyId = &v
	return s
}

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

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

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

const (
	// AlgorithmSpecRsaesPkcs1V15 is a AlgorithmSpec enum value
	AlgorithmSpecRsaesPkcs1V15 = "RSAES_PKCS1_V1_5"

	// AlgorithmSpecRsaesOaepSha1 is a AlgorithmSpec enum value
	AlgorithmSpecRsaesOaepSha1 = "RSAES_OAEP_SHA_1"

	// AlgorithmSpecRsaesOaepSha256 is a AlgorithmSpec enum value
	AlgorithmSpecRsaesOaepSha256 = "RSAES_OAEP_SHA_256"
)

const (
	// ConnectionErrorCodeTypeInvalidCredentials is a ConnectionErrorCodeType enum value
	ConnectionErrorCodeTypeInvalidCredentials = "INVALID_CREDENTIALS"

	// ConnectionErrorCodeTypeClusterNotFound is a ConnectionErrorCodeType enum value
	ConnectionErrorCodeTypeClusterNotFound = "CLUSTER_NOT_FOUND"

	// ConnectionErrorCodeTypeNetworkErrors is a ConnectionErrorCodeType enum value
	ConnectionErrorCodeTypeNetworkErrors = "NETWORK_ERRORS"

	// ConnectionErrorCodeTypeInsufficientCloudhsmHsms is a ConnectionErrorCodeType enum value
	ConnectionErrorCodeTypeInsufficientCloudhsmHsms = "INSUFFICIENT_CLOUDHSM_HSMS"

	// ConnectionErrorCodeTypeUserLockedOut is a ConnectionErrorCodeType enum value
	ConnectionErrorCodeTypeUserLockedOut = "USER_LOCKED_OUT"
)

const (
	// ConnectionStateTypeConnected is a ConnectionStateType enum value
	ConnectionStateTypeConnected = "CONNECTED"

	// ConnectionStateTypeConnecting is a ConnectionStateType enum value
	ConnectionStateTypeConnecting = "CONNECTING"

	// ConnectionStateTypeFailed is a ConnectionStateType enum value
	ConnectionStateTypeFailed = "FAILED"

	// ConnectionStateTypeDisconnected is a ConnectionStateType enum value
	ConnectionStateTypeDisconnected = "DISCONNECTED"

	// ConnectionStateTypeDisconnecting is a ConnectionStateType enum value
	ConnectionStateTypeDisconnecting = "DISCONNECTING"
)

const (
	// DataKeySpecAes256 is a DataKeySpec enum value
	DataKeySpecAes256 = "AES_256"

	// DataKeySpecAes128 is a DataKeySpec enum value
	DataKeySpecAes128 = "AES_128"
)

const (
	// ExpirationModelTypeKeyMaterialExpires is a ExpirationModelType enum value
	ExpirationModelTypeKeyMaterialExpires = "KEY_MATERIAL_EXPIRES"

	// ExpirationModelTypeKeyMaterialDoesNotExpire is a ExpirationModelType enum value
	ExpirationModelTypeKeyMaterialDoesNotExpire = "KEY_MATERIAL_DOES_NOT_EXPIRE"
)

const (
	// GrantOperationDecrypt is a GrantOperation enum value
	GrantOperationDecrypt = "Decrypt"

	// GrantOperationEncrypt is a GrantOperation enum value
	GrantOperationEncrypt = "Encrypt"

	// GrantOperationGenerateDataKey is a GrantOperation enum value
	GrantOperationGenerateDataKey = "GenerateDataKey"

	// GrantOperationGenerateDataKeyWithoutPlaintext is a GrantOperation enum value
	GrantOperationGenerateDataKeyWithoutPlaintext = "GenerateDataKeyWithoutPlaintext"

	// GrantOperationReEncryptFrom is a GrantOperation enum value
	GrantOperationReEncryptFrom = "ReEncryptFrom"

	// GrantOperationReEncryptTo is a GrantOperation enum value
	GrantOperationReEncryptTo = "ReEncryptTo"

	// GrantOperationCreateGrant is a GrantOperation enum value
	GrantOperationCreateGrant = "CreateGrant"

	// GrantOperationRetireGrant is a GrantOperation enum value
	GrantOperationRetireGrant = "RetireGrant"

	// GrantOperationDescribeKey is a GrantOperation enum value
	GrantOperationDescribeKey = "DescribeKey"
)

const (
	// KeyManagerTypeAws is a KeyManagerType enum value
	KeyManagerTypeAws = "AWS"

	// KeyManagerTypeCustomer is a KeyManagerType enum value
	KeyManagerTypeCustomer = "CUSTOMER"
)

const (
	// KeyStateEnabled is a KeyState enum value
	KeyStateEnabled = "Enabled"

	// KeyStateDisabled is a KeyState enum value
	KeyStateDisabled = "Disabled"

	// KeyStatePendingDeletion is a KeyState enum value
	KeyStatePendingDeletion = "PendingDeletion"

	// KeyStatePendingImport is a KeyState enum value
	KeyStatePendingImport = "PendingImport"

	// KeyStateUnavailable is a KeyState enum value
	KeyStateUnavailable = "Unavailable"
)

const (
	// KeyUsageTypeEncryptDecrypt is a KeyUsageType enum value
	KeyUsageTypeEncryptDecrypt = "ENCRYPT_DECRYPT"
)

const (
	// OriginTypeAwsKms is a OriginType enum value
	OriginTypeAwsKms = "AWS_KMS"

	// OriginTypeExternal is a OriginType enum value
	OriginTypeExternal = "EXTERNAL"

	// OriginTypeAwsCloudhsm is a OriginType enum value
	OriginTypeAwsCloudhsm = "AWS_CLOUDHSM"
)

const (
	// WrappingKeySpecRsa2048 is a WrappingKeySpec enum value
	WrappingKeySpecRsa2048 = "RSA_2048"
)
