// 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"
)

// Updates an association. You can update the association name and version, the
// document version, schedule, parameters, and Amazon Simple Storage Service
// (Amazon S3) output. When you call UpdateAssociation , the system removes all
// optional parameters from the request and overwrites the association with null
// values for those parameters. This is by design. You must specify all optional
// parameters in the call, even if you are not changing the parameters. This
// includes the Name parameter. Before calling this API action, we recommend that
// you call the DescribeAssociationAPI operation and make a note of all optional parameters required
// for your UpdateAssociation call.
//
// In order to call this API operation, a user, group, or role must be granted
// permission to call the DescribeAssociationAPI operation. If you don't have permission to call
// DescribeAssociation , then you receive the following error: An error occurred
// (AccessDeniedException) when calling the UpdateAssociation operation: User:
// isn't authorized to perform: ssm:DescribeAssociation on resource:
//
// When you update an association, the association immediately runs against the
// specified targets. You can add the ApplyOnlyAtCronInterval parameter to run the
// association during the next schedule run.
func (c *Client) UpdateAssociation(ctx context.Context, params *UpdateAssociationInput, optFns ...func(*Options)) (*UpdateAssociationOutput, error) {
	if params == nil {
		params = &UpdateAssociationInput{}
	}

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

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

type UpdateAssociationInput struct {

	// The ID of the association you want to update.
	//
	// This member is required.
	AssociationId *string

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

	// By default, when you update an association, the system runs it immediately
	// after it is updated and then according to the schedule you specified. Specify
	// true for ApplyOnlyAtCronInterval if you want the association to run only
	// according to the schedule you specified.
	//
	// If you chose this option when you created an association and later you edit
	// that association or you make changes to the Automation runbook or SSM document
	// on which that association is based, State Manager applies the association at the
	// next specified cron interval. For example, if you chose the Latest version of
	// an SSM document when you created an association and you edit the association by
	// choosing a different document version on the Documents page, State Manager
	// applies the association at the next specified cron interval if you previously
	// set ApplyOnlyAtCronInterval to true . If this option wasn't selected, State
	// Manager immediately runs the association.
	//
	// 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.
	//
	// You can reset this parameter. To do so, specify the
	// no-apply-only-at-cron-interval parameter when you update the association from
	// the command line. This parameter forces the association to run immediately after
	// updating it and according to the interval specified.
	//
	// [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

	// The name of the association that you want to update.
	AssociationName *string

	// This parameter is provided for concurrency control purposes. You must specify
	// the latest association version in the service. If you want to ensure that this
	// request succeeds, either specify $LATEST , or omit this parameter.
	AssociationVersion *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 or 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 update for the association.
	//
	// 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 updated, but only according to the specified
	//   schedule.
	//
	// [ApplyOnlyAtCronInterval]: https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_UpdateAssociation.html#systemsmanager-UpdateAssociation-request-ApplyOnlyAtCronInterval
	Duration *int32

	// 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

	// 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 account.
	//
	// For Systems Manager document (SSM document) that are shared with you from other
	// Amazon Web Services accounts, you must specify the complete SSM document ARN, in
	// the following format:
	//
	//     arn:aws: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 .
	Name *string

	// An S3 bucket where you want to store the results of this request.
	OutputLocation *types.InstanceAssociationOutputLocation

	// The parameters you want to update for the association. If you create a
	// parameter using Parameter Store, a tool in Amazon Web Services Systems Manager,
	// you can reference the parameter using {{ssm:parameter-name}} .
	Parameters map[string][]string

	// The cron expression used to schedule the association that you want to update.
	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, a tool
	// in Amazon Web Services Systems Manager. It is managed by your direct call to the
	// PutComplianceItemsAPI operation.
	//
	// By default, all associations use AUTO mode.
	SyncCompliance types.AssociationSyncCompliance

	// 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
	// update 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 of the association.
	Targets []types.Target

	noSmithyDocumentSerde
}

type UpdateAssociationOutput struct {

	// The description of the association that was updated.
	AssociationDescription *types.AssociationDescription

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

	noSmithyDocumentSerde
}

func (c *Client) addOperationUpdateAssociationMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdateAssociation{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdateAssociation{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateAssociation"); 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); 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 = addTimeOffsetBuild(stack, c); err != nil {
		return err
	}
	if err = addUserAgentRetryMode(stack, options); err != nil {
		return err
	}
	if err = addCredentialSource(stack, options); err != nil {
		return err
	}
	if err = addOpUpdateAssociationValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateAssociation(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_opUpdateAssociation(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		OperationName: "UpdateAssociation",
	}
}
