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

package cloudformation

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

// Updates a stack as specified in the template. After the call completes
// successfully, the stack update starts. You can check the status of the stack
// through the DescribeStacksaction.
//
// To get a copy of the template for an existing stack, you can use the GetTemplate action.
//
// For more information about updating a stack and monitoring the progress of the
// update, see [Managing Amazon Web Services resources as a single unit with CloudFormation stacks]in the CloudFormation User Guide.
//
// [Managing Amazon Web Services resources as a single unit with CloudFormation stacks]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html
func (c *Client) UpdateStack(ctx context.Context, params *UpdateStackInput, optFns ...func(*Options)) (*UpdateStackOutput, error) {
	if params == nil {
		params = &UpdateStackInput{}
	}

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

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

// The input for an UpdateStack action.
type UpdateStackInput struct {

	// The name or unique stack ID of the stack to update.
	//
	// This member is required.
	StackName *string

	// In some cases, you must explicitly acknowledge that your stack template
	// contains certain capabilities in order for CloudFormation to update the stack.
	//
	//   - CAPABILITY_IAM and CAPABILITY_NAMED_IAM
	//
	// Some stack templates might include resources that can affect permissions in
	//   your Amazon Web Services account, for example, by creating new IAM users. For
	//   those stacks, you must explicitly acknowledge this by specifying one of these
	//   capabilities.
	//
	// The following IAM resources require you to specify either the CAPABILITY_IAM or
	//   CAPABILITY_NAMED_IAM capability.
	//
	//   - If you have IAM resources, you can specify either capability.
	//
	//   - If you have IAM resources with custom names, you must specify
	//   CAPABILITY_NAMED_IAM .
	//
	//   - If you don't specify either of these capabilities, CloudFormation returns
	//   an InsufficientCapabilities error.
	//
	// If your stack template contains these resources, we suggest that you review all
	//   permissions associated with them and edit their permissions if necessary.
	//
	// [AWS::IAM::AccessKey]
	//
	// [AWS::IAM::Group]
	//
	// [AWS::IAM::InstanceProfile]
	//
	// [AWS::IAM::ManagedPolicy]
	//
	// [AWS::IAM::Policy]
	//
	// [AWS::IAM::Role]
	//
	// [AWS::IAM::User]
	//
	// [AWS::IAM::UserToGroupAddition]
	//
	// For more information, see [Acknowledging IAM resources in CloudFormation templates].
	//
	//   - CAPABILITY_AUTO_EXPAND
	//
	// Some template contain macros. Macros perform custom processing on templates;
	//   this can include simple actions like find-and-replace operations, all the way to
	//   extensive transformations of entire templates. Because of this, users typically
	//   create a change set from the processed template, so that they can review the
	//   changes resulting from the macros before actually updating the stack. If your
	//   stack template contains one or more macros, and you choose to update a stack
	//   directly from the processed template, without first reviewing the resulting
	//   changes in a change set, you must acknowledge this capability. This includes the
	//   [AWS::Include]and [AWS::Serverless]transforms, which are macros hosted by CloudFormation.
	//
	// If you want to update a stack from a stack template that contains macros and
	//   nested stacks, you must update the stack directly from the template using this
	//   capability.
	//
	// You should only update stacks directly from a stack template that contains
	//   macros if you know what processing the macro performs.
	//
	// Each macro relies on an underlying Lambda service function for processing stack
	//   templates. Be aware that the Lambda function owner can update the function
	//   operation without CloudFormation being notified.
	//
	// For more information, see [Perform custom processing on CloudFormation templates with template macros].
	//
	// Only one of the Capabilities and ResourceType parameters can be specified.
	//
	// [AWS::IAM::ManagedPolicy]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-managedpolicy.html
	// [AWS::IAM::AccessKey]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-accesskey.html
	// [AWS::Include]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-include.html
	// [AWS::IAM::User]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-user.html
	// [AWS::IAM::InstanceProfile]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-instanceprofile.html
	// [Acknowledging IAM resources in CloudFormation templates]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/control-access-with-iam.html#using-iam-capabilities
	// [Perform custom processing on CloudFormation templates with template macros]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-macros.html
	// [AWS::IAM::Policy]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-policy.html
	// [AWS::IAM::Group]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-group.html
	// [AWS::IAM::UserToGroupAddition]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-usertogroupaddition.html
	// [AWS::IAM::Role]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-role.html
	// [AWS::Serverless]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-serverless.html
	Capabilities []types.Capability

	// A unique identifier for this UpdateStack request. Specify this token if you
	// plan to retry requests so that CloudFormation knows that you're not attempting
	// to update a stack with the same name. You might retry UpdateStack requests to
	// ensure that CloudFormation successfully received them.
	//
	// All events triggered by a given stack operation are assigned the same client
	// request token, which you can use to track operations. For example, if you
	// execute a CreateStack operation with the token token1 , then all the StackEvents
	// generated by that operation will have ClientRequestToken set as token1 .
	//
	// In the console, stack operations display the client request token on the Events
	// tab. Stack operations that are initiated from the console use the token format
	// Console-StackOperation-ID, which helps you easily identify the stack operation .
	// For example, if you create a stack using the console, each stack event would be
	// assigned the same token in the following format:
	// Console-CreateStack-7f59c3cf-00d2-40c7-b2ff-e75db0987002 .
	ClientRequestToken *string

	// Preserve the state of previously provisioned resources when an operation fails.
	//
	// Default: False
	DisableRollback *bool

	// Amazon Simple Notification Service topic Amazon Resource Names (ARNs) that
	// CloudFormation associates with the stack. Specify an empty list to remove all
	// notification topics.
	NotificationARNs []string

	// A list of Parameter structures that specify input parameters for the stack. For
	// more information, see the [Parameter]data type.
	//
	// [Parameter]: https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Parameter.html
	Parameters []types.Parameter

	// Specifies which resource types you can work with, such as AWS::EC2::Instance or
	// Custom::MyCustomInstance .
	//
	// If the list of resource types doesn't include a resource that you're updating,
	// the stack update fails. By default, CloudFormation grants permissions to all
	// resource types. IAM uses this parameter for CloudFormation-specific condition
	// keys in IAM policies. For more information, see [Control CloudFormation access with Identity and Access Management].
	//
	// Only one of the Capabilities and ResourceType parameters can be specified.
	//
	// [Control CloudFormation access with Identity and Access Management]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/control-access-with-iam.html
	ResourceTypes []string

	// When set to true , newly created resources are deleted when the operation rolls
	// back. This includes newly created resources marked with a deletion policy of
	// Retain .
	//
	// Default: false
	RetainExceptOnCreate *bool

	// The Amazon Resource Name (ARN) of an IAM role that CloudFormation assumes to
	// update the stack. CloudFormation uses the role's credentials to make calls on
	// your behalf. CloudFormation always uses this role for all future operations on
	// the stack. Provided that users have permission to operate on the stack,
	// CloudFormation uses this role even if the users don't have permission to pass
	// it. Ensure that the role grants least privilege.
	//
	// If you don't specify a value, CloudFormation uses the role that was previously
	// associated with the stack. If no role is available, CloudFormation uses a
	// temporary session that is generated from your user credentials.
	RoleARN *string

	// The rollback triggers for CloudFormation to monitor during stack creation and
	// updating operations, and for the specified monitoring period afterwards.
	RollbackConfiguration *types.RollbackConfiguration

	// Structure that contains a new stack policy body. You can specify either the
	// StackPolicyBody or the StackPolicyURL parameter, but not both.
	//
	// You might update the stack policy, for example, in order to protect a new
	// resource that you created during a stack update. If you don't specify a stack
	// policy, the current policy that is associated with the stack is unchanged.
	StackPolicyBody *string

	// Structure that contains the temporary overriding stack policy body. You can
	// specify either the StackPolicyDuringUpdateBody or the StackPolicyDuringUpdateURL
	// parameter, but not both.
	//
	// If you want to update protected resources, specify a temporary overriding stack
	// policy during this update. If you don't specify a stack policy, the current
	// policy that is associated with the stack will be used.
	StackPolicyDuringUpdateBody *string

	// Location of a file that contains the temporary overriding stack policy. The URL
	// must point to a policy (max size: 16KB) located in an S3 bucket in the same
	// Region as the stack. The location for an Amazon S3 bucket must start with
	// https:// . URLs from S3 static websites are not supported.
	//
	// You can specify either the StackPolicyDuringUpdateBody or the
	// StackPolicyDuringUpdateURL parameter, but not both.
	//
	// If you want to update protected resources, specify a temporary overriding stack
	// policy during this update. If you don't specify a stack policy, the current
	// policy that is associated with the stack will be used.
	StackPolicyDuringUpdateURL *string

	// Location of a file that contains the updated stack policy. The URL must point
	// to a policy (max size: 16KB) located in an S3 bucket in the same Region as the
	// stack. The location for an Amazon S3 bucket must start with https:// . URLs from
	// S3 static websites are not supported.
	//
	// You can specify either the StackPolicyBody or the StackPolicyURL parameter, but
	// not both.
	//
	// You might update the stack policy, for example, in order to protect a new
	// resource that you created during a stack update. If you don't specify a stack
	// policy, the current policy that is associated with the stack is unchanged.
	StackPolicyURL *string

	// Key-value pairs to associate with this stack. CloudFormation also propagates
	// these tags to supported resources in the stack. You can specify a maximum number
	// of 50 tags.
	//
	// If you don't specify this parameter, CloudFormation doesn't modify the stack's
	// tags. If you specify an empty value, CloudFormation removes all associated tags.
	Tags []types.Tag

	// Structure that contains the template body with a minimum length of 1 byte and a
	// maximum length of 51,200 bytes.
	//
	// Conditional: You must specify only one of the following parameters: TemplateBody
	// , TemplateURL , or set the UsePreviousTemplate to true .
	TemplateBody *string

	// The URL of a file that contains the template body. The URL must point to a
	// template that's located in an Amazon S3 bucket or a Systems Manager document.
	// The location for an Amazon S3 bucket must start with https:// .
	//
	// Conditional: You must specify only one of the following parameters: TemplateBody
	// , TemplateURL , or set the UsePreviousTemplate to true .
	TemplateURL *string

	// Reuse the existing template that is associated with the stack that you are
	// updating.
	//
	// When using templates with the AWS::LanguageExtensions transform, provide the
	// template instead of using UsePreviousTemplate to ensure new parameter values
	// and Systems Manager parameter updates are applied correctly. For more
	// information, see [AWS::LanguageExtensions transform].
	//
	// Conditional: You must specify only one of the following parameters: TemplateBody
	// , TemplateURL , or set the UsePreviousTemplate to true .
	//
	// [AWS::LanguageExtensions transform]: https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/transform-aws-languageextensions.html
	UsePreviousTemplate *bool

	noSmithyDocumentSerde
}

// The output for an UpdateStack action.
type UpdateStackOutput struct {

	// A unique identifier for this update operation that can be used to track the
	// operation's progress and events.
	OperationId *string

	// Unique identifier of the stack.
	StackId *string

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

	noSmithyDocumentSerde
}

func (c *Client) addOperationUpdateStackMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsAwsquery_serializeOpUpdateStack{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsAwsquery_deserializeOpUpdateStack{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "UpdateStack"); 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 = addOpUpdateStackValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdateStack(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_opUpdateStack(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		OperationName: "UpdateStack",
	}
}
