// Code generated by smithy-go-codegen DO NOT EDIT.

package cloudwatch

import (
	"context"
	"github.com/aws/smithy-go/middleware"
	smithyhttp "github.com/aws/smithy-go/transport/http"
)

// Associates an Amazon Web Services Key Management Service (Amazon Web Services
// KMS) customer managed key with the specified dataset. After this operation
// completes, all data published to the dataset is encrypted at rest using the
// specified KMS key. Callers must have kms:Decrypt permission on the key to read
// the encrypted data.
//
// Only the default dataset is supported. The default dataset is implicit for
// every account in every Region — you do not need to create it before calling this
// operation.
//
// You can call AssociateDatasetKmsKey on a dataset that is already associated
// with a KMS key to replace the existing key with a different one. To replace a
// key, the caller must have kms:Decrypt permission on both the current key and
// the new key.
//
// The KMS key that you specify must meet all of the following requirements:
//
//   - It must be a symmetric encryption KMS key (key spec SYMMETRIC_DEFAULT , key
//     usage ENCRYPT_DECRYPT ). Asymmetric keys, HMAC keys, and key material types
//     other than SYMMETRIC_DEFAULT are not supported.
//
//   - It must be enabled and not pending deletion.
//
//   - Its key policy must grant the CloudWatch service principal (
//     cloudwatch.amazonaws.com ) these permissions: kms:DescribeKey ,
//     kms:GenerateDataKey , kms:Encrypt , kms:Decrypt , and kms:ReEncrypt* . Amazon
//     CloudWatch requires these permissions to manage the data on your behalf.
//
//   - The calling principal must have kms:Decrypt permission on the key.
//
//   - It must be specified as a fully qualified key ARN. Key IDs, aliases, and
//     alias ARNs are not accepted.
//
//   - It must be in the same Amazon Web Services Region as the dataset.
//
// Before completing the association, Amazon CloudWatch validates the key by
// performing a series of dry-run KMS operations. Service-principal checks run
// first to verify that the key policy grants the required access to Amazon
// CloudWatch. These checks include kms:DescribeKey , kms:GenerateDataKey ,
// kms:Encrypt , kms:Decrypt , and kms:ReEncrypt* . After those succeed, a
// kms:Decrypt dry-run is run with the caller's credentials to verify that the
// calling principal can use the key. When you are replacing an existing key, the
// caller's kms:Decrypt dry-run is run on the current key first, and only then on
// the new key.
//
// If any of these checks fails, the operation fails and the existing key
// association (if any) remains unchanged. Common failure causes include the key
// being disabled, the key policy not granting the required permissions to Amazon
// CloudWatch, or the caller lacking kms:Decrypt permission on the key.
//
// For more information about using customer managed keys with Amazon CloudWatch,
// see [Encryption at rest with customer managed keys]in the Amazon CloudWatch User Guide.
//
// [Encryption at rest with customer managed keys]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cmk-encryption.html
func (c *Client) AssociateDatasetKmsKey(ctx context.Context, params *AssociateDatasetKmsKeyInput, optFns ...func(*Options)) (*AssociateDatasetKmsKeyOutput, error) {
	if params == nil {
		params = &AssociateDatasetKmsKeyInput{}
	}

	result, metadata, err := c.invokeOperation(ctx, "AssociateDatasetKmsKey", params, optFns, c.addOperationAssociateDatasetKmsKeyMiddlewares)
	if err != nil {
		return nil, err
	}

	out := result.(*AssociateDatasetKmsKeyOutput)
	out.ResultMetadata = metadata
	return out, nil
}

type AssociateDatasetKmsKeyInput struct {

	// Specifies the identifier of the dataset that you want to associate the KMS key
	// with. For the default dataset, you can specify either default or the full
	// dataset Amazon Resource Name (ARN) in the format
	// arn:aws:cloudwatch:Region:account-id:dataset/default .
	//
	// This member is required.
	DatasetIdentifier *string

	// Specifies the Amazon Resource Name (ARN) of the customer managed KMS key to
	// associate with the dataset. The key must be a symmetric encryption KMS key (
	// SYMMETRIC_DEFAULT ) in the same Amazon Web Services Region as the dataset.
	//
	// The ARN must be in the format arn:aws:kms:Region:account-id:key/key-id . Key
	// IDs, aliases, and alias ARNs are not accepted.
	//
	// For more information about KMS key ARNs, see [Key ARN] in the Amazon Web Services Key
	// Management Service Developer Guide.
	//
	// [Key ARN]: https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN
	//
	// This member is required.
	KmsKeyArn *string

	noSmithyDocumentSerde
}

type AssociateDatasetKmsKeyOutput struct {
	// Metadata pertaining to the operation's result.
	ResultMetadata middleware.Metadata

	noSmithyDocumentSerde
}

func (c *Client) addOperationAssociateDatasetKmsKeyMiddlewares(stack *middleware.Stack, options Options) (err error) {
	err = stack.Serialize.Add(&smithyRpcv2cbor_serializeOpAssociateDatasetKmsKey{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&smithyRpcv2cbor_deserializeOpAssociateDatasetKmsKey{}, middleware.After)
	if err != nil {
		return err
	}

	if err = addlegacyEndpointContextSetter(stack, options); err != nil {
		return err
	}
	if err = addComputeContentLength(stack); err != nil {
		return err
	}
	if err = addResolveEndpointMiddleware(stack, options); err != nil {
		return err
	}
	if err = addComputePayloadSHA256(stack); err != nil {
		return err
	}
	if err = addRecordResponseTiming(stack, options); err != nil {
		return err
	}
	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = addUserAgentFeatureProtocolRPCV2CBOR(stack, options); err != nil {
		return err
	}
	if err = addCredentialSource(stack, options); err != nil {
		return err
	}
	if err = addOpAssociateDatasetKmsKeyValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware(options.Region, "AssociateDatasetKmsKey"), middleware.Before); err != nil {
		return err
	}
	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
		return err
	}
	if err = addResponseErrorMiddleware(stack); err != nil {
		return err
	}
	if err = addRequestResponseLogging(stack, options); err != nil {
		return err
	}
	if err = addDisableHTTPSMiddleware(stack, options); err != nil {
		return err
	}
	if err = addInterceptors(stack, options); err != nil {
		return err
	}
	return nil
}
