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

package ssm

import (
	"context"
	"fmt"
	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
	"github.com/aws/aws-sdk-go-v2/service/ssm/types"
	"github.com/aws/smithy-go/middleware"
	smithyhttp "github.com/aws/smithy-go/transport/http"
)

// A State Manager association defines the state that you want to maintain on your
// managed nodes. For example, an association can specify that anti-virus software
// must be installed and running on your managed nodes, or that certain ports must
// be closed. For static targets, the association specifies a schedule for when the
// configuration is reapplied. For dynamic targets, such as an Amazon Web Services
// resource group or an Amazon Web Services autoscaling group, State Manager, a
// tool in Amazon Web Services Systems Manager applies the configuration when new
// managed nodes are added to the group. The association also specifies actions to
// take when applying the configuration. For example, an association for anti-virus
// software might run once a day. If the software isn't installed, then State
// Manager installs it. If the software is installed, but the service isn't
// running, then the association might instruct State Manager to start the service.
func (c *Client) CreateAssociation(ctx context.Context, params *CreateAssociationInput, optFns ...func(*Options)) (*CreateAssociationOutput, error) {
	if params == nil {
		params = &CreateAssociationInput{}
	}

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

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

type CreateAssociationInput struct {

	// The name of the SSM Command document or Automation runbook that contains the
	// configuration information for the managed node.
	//
	// You can specify Amazon Web Services-predefined documents, documents you
	// created, or a document that is shared with you from another Amazon Web Services
	// account.
	//
	// For Systems Manager documents (SSM documents) that are shared with you from
	// other Amazon Web Services accounts, you must specify the complete SSM document
	// ARN, in the following format:
	//
	//     arn:partition:ssm:region:account-id:document/document-name
	//
	// For example:
	//
	//     arn:aws:ssm:us-east-2:12345678912:document/My-Shared-Document
	//
	// For Amazon Web Services-predefined documents and SSM documents you created in
	// your account, you only need to specify the document name. For example,
	// AWS-ApplyPatchBaseline or My-Document .
	//
	// This member is required.
	Name *string

	// The details for the CloudWatch alarm you want to apply to an automation or
	// command.
	AlarmConfiguration *types.AlarmConfiguration

	// By default, when you create a new association, the system runs it immediately
	// after it is created and then according to the schedule you specified and when
	// target changes are detected. Specify true for ApplyOnlyAtCronInterval if you
	// want the association to run only according to the schedule you specified.
	//
	// For more information, see [Understanding when associations are applied to resources] and [>About target updates with Automation runbooks] in the Amazon Web Services Systems Manager User
	// Guide.
	//
	// This parameter isn't supported for rate expressions.
	//
	// [Understanding when associations are applied to resources]: https://docs.aws.amazon.com/systems-manager/latest/userguide/state-manager-about.html#state-manager-about-scheduling
	// [>About target updates with Automation runbooks]: https://docs.aws.amazon.com/systems-manager/latest/userguide/state-manager-about.html#runbook-target-updates
	ApplyOnlyAtCronInterval bool

	// A role used by association to take actions on your behalf. State Manager will
	// assume this role and call required APIs when dispatching configurations to
	// nodes. If not specified, [service-linked role for Systems Manager]will be used by default.
	//
	// It is recommended that you define a custom IAM role so that you have full
	// control of the permissions that State Manager has when taking actions on your
	// behalf.
	//
	// Service-linked role support in State Manager is being phased out. Associations
	// relying on service-linked role may require updates in the future to continue
	// functioning properly.
	//
	// [service-linked role for Systems Manager]: https://docs.aws.amazon.com/systems-manager/latest/userguide/using-service-linked-roles.html
	AssociationDispatchAssumeRole *string

	// Specify a descriptive name for the association.
	AssociationName *string

	// Choose the parameter that will define how your automation will branch out. This
	// target is required for associations that use an Automation runbook and target
	// resources by using rate controls. Automation is a tool in Amazon Web Services
	// Systems Manager.
	AutomationTargetParameterName *string

	// The names of Amazon Resource Names (ARNs) of the Change Calendar type documents
	// you want to gate your associations under. The associations only run when that
	// change calendar is open. For more information, see [Amazon Web Services Systems Manager Change Calendar]in the Amazon Web Services
	// Systems Manager User Guide.
	//
	// [Amazon Web Services Systems Manager Change Calendar]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-change-calendar
	CalendarNames []string

	// The severity level to assign to the association.
	ComplianceSeverity types.AssociationComplianceSeverity

	// The document version you want to associate with the targets. Can be a specific
	// version or the default version.
	//
	// State Manager doesn't support running associations that use a new version of a
	// document if that document is shared from another account. State Manager always
	// runs the default version of a document if shared from another account, even
	// though the Systems Manager console shows that a new version was processed. If
	// you want to run an association using a new version of a document shared form
	// another account, you must set the document version to default .
	DocumentVersion *string

	// The number of hours the association can run before it is canceled. Duration
	// applies to associations that are currently running, and any pending and in
	// progress commands on all targets. If a target was taken offline for the
	// association to run, it is made available again immediately, without a reboot.
	//
	// The Duration parameter applies only when both these conditions are true:
	//
	//   - The association for which you specify a duration is cancelable according to
	//   the parameters of the SSM command document or Automation runbook associated with
	//   this execution.
	//
	//   - The command specifies the [ApplyOnlyAtCronInterval]parameter, which means that the association
	//   doesn't run immediately after it is created, but only according to the specified
	//   schedule.
	//
	// [ApplyOnlyAtCronInterval]: https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_CreateAssociation.html#systemsmanager-CreateAssociation-request-ApplyOnlyAtCronInterval
	Duration *int32

	// The managed node ID.
	//
	// InstanceId has been deprecated. To specify a managed node ID for an
	// association, use the Targets parameter. Requests that include the parameter
	// InstanceID with Systems Manager documents (SSM documents) that use schema
	// version 2.0 or later will fail. In addition, if you use the parameter InstanceId
	// , you can't use the parameters AssociationName , DocumentVersion , MaxErrors ,
	// MaxConcurrency , OutputLocation , or ScheduleExpression . To use these
	// parameters, you must use the Targets parameter.
	InstanceId *string

	// The maximum number of targets allowed to run the association at the same time.
	// You can specify a number, for example 10, or a percentage of the target set, for
	// example 10%. The default value is 100%, which means all targets run the
	// association at the same time.
	//
	// If a new managed node starts and attempts to run an association while Systems
	// Manager is running MaxConcurrency associations, the association is allowed to
	// run. During the next association interval, the new managed node will process its
	// association within the limit specified for MaxConcurrency .
	MaxConcurrency *string

	// The number of errors that are allowed before the system stops sending requests
	// to run the association on additional targets. You can specify either an absolute
	// number of errors, for example 10, or a percentage of the target set, for example
	// 10%. If you specify 3, for example, the system stops sending requests when the
	// fourth error is received. If you specify 0, then the system stops sending
	// requests after the first error is returned. If you run an association on 50
	// managed nodes and set MaxError to 10%, then the system stops sending the
	// request when the sixth error is received.
	//
	// Executions that are already running an association when MaxErrors is reached
	// are allowed to complete, but some of these executions may fail as well. If you
	// need to ensure that there won't be more than max-errors failed executions, set
	// MaxConcurrency to 1 so that executions proceed one at a time.
	MaxErrors *string

	// An Amazon Simple Storage Service (Amazon S3) bucket where you want to store the
	// output details of the request.
	OutputLocation *types.InstanceAssociationOutputLocation

	// The parameters for the runtime configuration of the document.
	Parameters map[string][]string

	// A cron expression when the association will be applied to the targets.
	ScheduleExpression *string

	// Number of days to wait after the scheduled day to run an association. For
	// example, if you specified a cron schedule of cron(0 0 ? * THU#2 *) , you could
	// specify an offset of 3 to run the association each Sunday after the second
	// Thursday of the month. For more information about cron schedules for
	// associations, see [Reference: Cron and rate expressions for Systems Manager]in the Amazon Web Services Systems Manager User Guide.
	//
	// To use offsets, you must specify the ApplyOnlyAtCronInterval parameter. This
	// option tells the system not to run an association immediately after you create
	// it.
	//
	// [Reference: Cron and rate expressions for Systems Manager]: https://docs.aws.amazon.com/systems-manager/latest/userguide/reference-cron-and-rate-expressions.html
	ScheduleOffset *int32

	// The mode for generating association compliance. You can specify AUTO or MANUAL .
	// In AUTO mode, the system uses the status of the association execution to
	// determine the compliance status. If the association execution runs successfully,
	// then the association is COMPLIANT . If the association execution doesn't run
	// successfully, the association is NON-COMPLIANT .
	//
	// In MANUAL mode, you must specify the AssociationId as a parameter for the PutComplianceItems API
	// operation. In this case, compliance data isn't managed by State Manager. It is
	// managed by your direct call to the PutComplianceItemsAPI operation.
	//
	// By default, all associations use AUTO mode.
	SyncCompliance types.AssociationSyncCompliance

	// Adds or overwrites one or more tags for a State Manager association. Tags are
	// metadata that you can assign to your Amazon Web Services resources. Tags enable
	// you to categorize your resources in different ways, for example, by purpose,
	// owner, or environment. Each tag consists of a key and an optional value, both of
	// which you define.
	Tags []types.Tag

	// A location is a combination of Amazon Web Services Regions and Amazon Web
	// Services accounts where you want to run the association. Use this action to
	// create an association in multiple Regions and multiple accounts.
	//
	// The IncludeChildOrganizationUnits parameter is not supported by State Manager.
	TargetLocations []types.TargetLocation

	// A key-value mapping of document parameters to target resources. Both Targets
	// and TargetMaps can't be specified together.
	TargetMaps []map[string][]string

	// The targets for the association. You can target managed nodes by using tags,
	// Amazon Web Services resource groups, all managed nodes in an Amazon Web Services
	// account, or individual managed node IDs. You can target all managed nodes in an
	// Amazon Web Services account by specifying the InstanceIds key with a value of *
	// . For more information about choosing targets for an association, see [Understanding targets and rate controls in State Manager associations]in the
	// Amazon Web Services Systems Manager User Guide.
	//
	// [Understanding targets and rate controls in State Manager associations]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-state-manager-targets-and-rate-controls.html
	Targets []types.Target

	noSmithyDocumentSerde
}

type CreateAssociationOutput struct {

	// Information about the association.
	AssociationDescription *types.AssociationDescription

	// Metadata pertaining to the operation's result.
	ResultMetadata middleware.Metadata

	noSmithyDocumentSerde
}

func (c *Client) addOperationCreateAssociationMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateAssociation{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpCreateAssociation{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "CreateAssociation"); err != nil {
		return fmt.Errorf("add protocol finalizers: %v", err)
	}

	if err = addlegacyEndpointContextSetter(stack, options); err != nil {
		return err
	}
	if err = addSetLoggerMiddleware(stack, options); err != nil {
		return err
	}
	if err = addClientRequestID(stack); 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 = addRetry(stack, options, c); err != nil {
		return err
	}
	if err = addRawResponseToMetadata(stack); err != nil {
		return err
	}
	if err = addRecordResponseTiming(stack); err != nil {
		return err
	}
	if err = addSpanRetryLoop(stack, options); err != nil {
		return err
	}
	if err = addClientUserAgent(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 = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil {
		return err
	}
	if err = addUserAgentRetryMode(stack, options); err != nil {
		return err
	}
	if err = addCredentialSource(stack, options); err != nil {
		return err
	}
	if err = addOpCreateAssociationValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateAssociation(options.Region), middleware.Before); err != nil {
		return err
	}
	if err = addRecursionDetection(stack); 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 = addInterceptBeforeRetryLoop(stack, options); err != nil {
		return err
	}
	if err = addInterceptAttempt(stack, options); err != nil {
		return err
	}
	if err = addInterceptors(stack, options); err != nil {
		return err
	}
	return nil
}

func newServiceMetadataMiddleware_opCreateAssociation(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		OperationName: "CreateAssociation",
	}
}
