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

package ssm

import (
	"context"
	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
	"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
	"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 DescribeAssociation API operation and make a note of all optional
// parameters required for your UpdateAssociation call. In order to call this API
// operation, your Identity and Access Management (IAM) user account, group, or
// role must be configured with permission to call the DescribeAssociation API
// 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: <user_arn> isn't authorized to
// perform: ssm:DescribeAssociation on resource: <resource_arn> 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

	// 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 this
	// option if you don't want an association to run immediately after you update it.
	// This parameter isn't supported for rate expressions. If you chose this option
	// when you created an association and later you edit that association or you make
	// changes to the SSM document on which that association is based (by using the
	// Documents page in the console), 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
	// selected this option. If this option wasn't selected, State Manager immediately
	// runs the association. You can reset this option. 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.
	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 capability of 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
	// (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 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 capability of 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
	// (https://docs.aws.amazon.com/systems-manager/latest/userguide/reference-cron-and-rate-expressions.html)
	// 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.
	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 capability of
	// Amazon Web Services Systems Manager. It is managed by your direct call to the
	// PutComplianceItems API 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.
	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) {
	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 = addSetLoggerMiddleware(stack, options); err != nil {
		return err
	}
	if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
		return err
	}
	if err = addResolveEndpointMiddleware(stack, options); err != nil {
		return err
	}
	if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
		return err
	}
	if err = addRetryMiddlewares(stack, options); err != nil {
		return err
	}
	if err = addHTTPSignerV4Middleware(stack, options); err != nil {
		return err
	}
	if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
		return err
	}
	if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
		return err
	}
	if err = addClientUserAgent(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); 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 = addRequestIDRetrieverMiddleware(stack); err != nil {
		return err
	}
	if err = addResponseErrorMiddleware(stack); err != nil {
		return err
	}
	if err = addRequestResponseLogging(stack, options); err != nil {
		return err
	}
	return nil
}

func newServiceMetadataMiddleware_opUpdateAssociation(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		SigningName:   "ssm",
		OperationName: "UpdateAssociation",
	}
}
