// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.

package autoscaling

import (
	"fmt"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awsutil"
	"github.com/aws/aws-sdk-go/aws/request"
	"github.com/aws/aws-sdk-go/private/protocol"
	"github.com/aws/aws-sdk-go/private/protocol/query"
)

const opAttachInstances = "AttachInstances"

// AttachInstancesRequest generates a "aws/request.Request" representing the
// client's request for the AttachInstances operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See AttachInstances for more information on using the AttachInstances
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the AttachInstancesRequest method.
//    req, resp := client.AttachInstancesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/AttachInstances
func (c *AutoScaling) AttachInstancesRequest(input *AttachInstancesInput) (req *request.Request, output *AttachInstancesOutput) {
	op := &request.Operation{
		Name:       opAttachInstances,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AttachInstancesInput{}
	}

	output = &AttachInstancesOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// AttachInstances API operation for Auto Scaling.
//
// Attaches one or more EC2 instances to the specified Auto Scaling group.
//
// When you attach instances, Amazon EC2 Auto Scaling increases the desired
// capacity of the group by the number of instances being attached. If the number
// of instances being attached plus the desired capacity of the group exceeds
// the maximum size of the group, the operation fails.
//
// If there is a Classic Load Balancer attached to your Auto Scaling group,
// the instances are also registered with the load balancer. If there are target
// groups attached to your Auto Scaling group, the instances are also registered
// with the target groups.
//
// For more information, see Attach EC2 Instances to Your Auto Scaling Group
// (http://docs.aws.amazon.com/autoscaling/ec2/userguide/attach-instance-asg.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation AttachInstances for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeServiceLinkedRoleFailure "ServiceLinkedRoleFailure"
//   The service-linked role is not yet ready for use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/AttachInstances
func (c *AutoScaling) AttachInstances(input *AttachInstancesInput) (*AttachInstancesOutput, error) {
	req, out := c.AttachInstancesRequest(input)
	return out, req.Send()
}

// AttachInstancesWithContext is the same as AttachInstances with the addition of
// the ability to pass a context and additional request options.
//
// See AttachInstances for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) AttachInstancesWithContext(ctx aws.Context, input *AttachInstancesInput, opts ...request.Option) (*AttachInstancesOutput, error) {
	req, out := c.AttachInstancesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opAttachLoadBalancerTargetGroups = "AttachLoadBalancerTargetGroups"

// AttachLoadBalancerTargetGroupsRequest generates a "aws/request.Request" representing the
// client's request for the AttachLoadBalancerTargetGroups operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See AttachLoadBalancerTargetGroups for more information on using the AttachLoadBalancerTargetGroups
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the AttachLoadBalancerTargetGroupsRequest method.
//    req, resp := client.AttachLoadBalancerTargetGroupsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/AttachLoadBalancerTargetGroups
func (c *AutoScaling) AttachLoadBalancerTargetGroupsRequest(input *AttachLoadBalancerTargetGroupsInput) (req *request.Request, output *AttachLoadBalancerTargetGroupsOutput) {
	op := &request.Operation{
		Name:       opAttachLoadBalancerTargetGroups,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AttachLoadBalancerTargetGroupsInput{}
	}

	output = &AttachLoadBalancerTargetGroupsOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// AttachLoadBalancerTargetGroups API operation for Auto Scaling.
//
// Attaches one or more target groups to the specified Auto Scaling group.
//
// To describe the target groups for an Auto Scaling group, use DescribeLoadBalancerTargetGroups.
// To detach the target group from the Auto Scaling group, use DetachLoadBalancerTargetGroups.
//
// For more information, see Attach a Load Balancer to Your Auto Scaling Group
// (http://docs.aws.amazon.com/autoscaling/ec2/userguide/attach-load-balancer-asg.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation AttachLoadBalancerTargetGroups for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeServiceLinkedRoleFailure "ServiceLinkedRoleFailure"
//   The service-linked role is not yet ready for use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/AttachLoadBalancerTargetGroups
func (c *AutoScaling) AttachLoadBalancerTargetGroups(input *AttachLoadBalancerTargetGroupsInput) (*AttachLoadBalancerTargetGroupsOutput, error) {
	req, out := c.AttachLoadBalancerTargetGroupsRequest(input)
	return out, req.Send()
}

// AttachLoadBalancerTargetGroupsWithContext is the same as AttachLoadBalancerTargetGroups with the addition of
// the ability to pass a context and additional request options.
//
// See AttachLoadBalancerTargetGroups for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) AttachLoadBalancerTargetGroupsWithContext(ctx aws.Context, input *AttachLoadBalancerTargetGroupsInput, opts ...request.Option) (*AttachLoadBalancerTargetGroupsOutput, error) {
	req, out := c.AttachLoadBalancerTargetGroupsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opAttachLoadBalancers = "AttachLoadBalancers"

// AttachLoadBalancersRequest generates a "aws/request.Request" representing the
// client's request for the AttachLoadBalancers operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See AttachLoadBalancers for more information on using the AttachLoadBalancers
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the AttachLoadBalancersRequest method.
//    req, resp := client.AttachLoadBalancersRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/AttachLoadBalancers
func (c *AutoScaling) AttachLoadBalancersRequest(input *AttachLoadBalancersInput) (req *request.Request, output *AttachLoadBalancersOutput) {
	op := &request.Operation{
		Name:       opAttachLoadBalancers,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AttachLoadBalancersInput{}
	}

	output = &AttachLoadBalancersOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// AttachLoadBalancers API operation for Auto Scaling.
//
// Attaches one or more Classic Load Balancers to the specified Auto Scaling
// group.
//
// To attach an Application Load Balancer instead, see AttachLoadBalancerTargetGroups.
//
// To describe the load balancers for an Auto Scaling group, use DescribeLoadBalancers.
// To detach the load balancer from the Auto Scaling group, use DetachLoadBalancers.
//
// For more information, see Attach a Load Balancer to Your Auto Scaling Group
// (http://docs.aws.amazon.com/autoscaling/ec2/userguide/attach-load-balancer-asg.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation AttachLoadBalancers for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeServiceLinkedRoleFailure "ServiceLinkedRoleFailure"
//   The service-linked role is not yet ready for use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/AttachLoadBalancers
func (c *AutoScaling) AttachLoadBalancers(input *AttachLoadBalancersInput) (*AttachLoadBalancersOutput, error) {
	req, out := c.AttachLoadBalancersRequest(input)
	return out, req.Send()
}

// AttachLoadBalancersWithContext is the same as AttachLoadBalancers with the addition of
// the ability to pass a context and additional request options.
//
// See AttachLoadBalancers for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) AttachLoadBalancersWithContext(ctx aws.Context, input *AttachLoadBalancersInput, opts ...request.Option) (*AttachLoadBalancersOutput, error) {
	req, out := c.AttachLoadBalancersRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opBatchDeleteScheduledAction = "BatchDeleteScheduledAction"

// BatchDeleteScheduledActionRequest generates a "aws/request.Request" representing the
// client's request for the BatchDeleteScheduledAction operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See BatchDeleteScheduledAction for more information on using the BatchDeleteScheduledAction
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the BatchDeleteScheduledActionRequest method.
//    req, resp := client.BatchDeleteScheduledActionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/BatchDeleteScheduledAction
func (c *AutoScaling) BatchDeleteScheduledActionRequest(input *BatchDeleteScheduledActionInput) (req *request.Request, output *BatchDeleteScheduledActionOutput) {
	op := &request.Operation{
		Name:       opBatchDeleteScheduledAction,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &BatchDeleteScheduledActionInput{}
	}

	output = &BatchDeleteScheduledActionOutput{}
	req = c.newRequest(op, input, output)
	return
}

// BatchDeleteScheduledAction API operation for Auto Scaling.
//
// Deletes one or more scheduled actions for the specified Auto Scaling group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation BatchDeleteScheduledAction for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/BatchDeleteScheduledAction
func (c *AutoScaling) BatchDeleteScheduledAction(input *BatchDeleteScheduledActionInput) (*BatchDeleteScheduledActionOutput, error) {
	req, out := c.BatchDeleteScheduledActionRequest(input)
	return out, req.Send()
}

// BatchDeleteScheduledActionWithContext is the same as BatchDeleteScheduledAction with the addition of
// the ability to pass a context and additional request options.
//
// See BatchDeleteScheduledAction for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) BatchDeleteScheduledActionWithContext(ctx aws.Context, input *BatchDeleteScheduledActionInput, opts ...request.Option) (*BatchDeleteScheduledActionOutput, error) {
	req, out := c.BatchDeleteScheduledActionRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opBatchPutScheduledUpdateGroupAction = "BatchPutScheduledUpdateGroupAction"

// BatchPutScheduledUpdateGroupActionRequest generates a "aws/request.Request" representing the
// client's request for the BatchPutScheduledUpdateGroupAction operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See BatchPutScheduledUpdateGroupAction for more information on using the BatchPutScheduledUpdateGroupAction
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the BatchPutScheduledUpdateGroupActionRequest method.
//    req, resp := client.BatchPutScheduledUpdateGroupActionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/BatchPutScheduledUpdateGroupAction
func (c *AutoScaling) BatchPutScheduledUpdateGroupActionRequest(input *BatchPutScheduledUpdateGroupActionInput) (req *request.Request, output *BatchPutScheduledUpdateGroupActionOutput) {
	op := &request.Operation{
		Name:       opBatchPutScheduledUpdateGroupAction,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &BatchPutScheduledUpdateGroupActionInput{}
	}

	output = &BatchPutScheduledUpdateGroupActionOutput{}
	req = c.newRequest(op, input, output)
	return
}

// BatchPutScheduledUpdateGroupAction API operation for Auto Scaling.
//
// Creates or updates one or more scheduled scaling actions for an Auto Scaling
// group. If you leave a parameter unspecified when updating a scheduled scaling
// action, the corresponding value remains unchanged.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation BatchPutScheduledUpdateGroupAction for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAlreadyExistsFault "AlreadyExists"
//   You already have an Auto Scaling group or launch configuration with this
//   name.
//
//   * ErrCodeLimitExceededFault "LimitExceeded"
//   You have already reached a limit for your Auto Scaling resources (for example,
//   groups, launch configurations, or lifecycle hooks). For more information,
//   see DescribeAccountLimits.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/BatchPutScheduledUpdateGroupAction
func (c *AutoScaling) BatchPutScheduledUpdateGroupAction(input *BatchPutScheduledUpdateGroupActionInput) (*BatchPutScheduledUpdateGroupActionOutput, error) {
	req, out := c.BatchPutScheduledUpdateGroupActionRequest(input)
	return out, req.Send()
}

// BatchPutScheduledUpdateGroupActionWithContext is the same as BatchPutScheduledUpdateGroupAction with the addition of
// the ability to pass a context and additional request options.
//
// See BatchPutScheduledUpdateGroupAction for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) BatchPutScheduledUpdateGroupActionWithContext(ctx aws.Context, input *BatchPutScheduledUpdateGroupActionInput, opts ...request.Option) (*BatchPutScheduledUpdateGroupActionOutput, error) {
	req, out := c.BatchPutScheduledUpdateGroupActionRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCompleteLifecycleAction = "CompleteLifecycleAction"

// CompleteLifecycleActionRequest generates a "aws/request.Request" representing the
// client's request for the CompleteLifecycleAction operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CompleteLifecycleAction for more information on using the CompleteLifecycleAction
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CompleteLifecycleActionRequest method.
//    req, resp := client.CompleteLifecycleActionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/CompleteLifecycleAction
func (c *AutoScaling) CompleteLifecycleActionRequest(input *CompleteLifecycleActionInput) (req *request.Request, output *CompleteLifecycleActionOutput) {
	op := &request.Operation{
		Name:       opCompleteLifecycleAction,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CompleteLifecycleActionInput{}
	}

	output = &CompleteLifecycleActionOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// CompleteLifecycleAction API operation for Auto Scaling.
//
// Completes the lifecycle action for the specified token or instance with the
// specified result.
//
// This step is a part of the procedure for adding a lifecycle hook to an Auto
// Scaling group:
//
// (Optional) Create a Lambda function and a rule that allows CloudWatch Events
// to invoke your Lambda function when Amazon EC2 Auto Scaling launches or terminates
// instances.
//
// (Optional) Create a notification target and an IAM role. The target can be
// either an Amazon SQS queue or an Amazon SNS topic. The role allows Amazon
// EC2 Auto Scaling to publish lifecycle notifications to the target.
//
// Create the lifecycle hook. Specify whether the hook is used when the instances
// launch or terminate.
//
// If you need more time, record the lifecycle action heartbeat to keep the
// instance in a pending state.
//
// If you finish before the timeout period ends, complete the lifecycle action.
//
// For more information, see Auto Scaling Lifecycle (http://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroupLifecycle.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation CompleteLifecycleAction for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/CompleteLifecycleAction
func (c *AutoScaling) CompleteLifecycleAction(input *CompleteLifecycleActionInput) (*CompleteLifecycleActionOutput, error) {
	req, out := c.CompleteLifecycleActionRequest(input)
	return out, req.Send()
}

// CompleteLifecycleActionWithContext is the same as CompleteLifecycleAction with the addition of
// the ability to pass a context and additional request options.
//
// See CompleteLifecycleAction for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) CompleteLifecycleActionWithContext(ctx aws.Context, input *CompleteLifecycleActionInput, opts ...request.Option) (*CompleteLifecycleActionOutput, error) {
	req, out := c.CompleteLifecycleActionRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateAutoScalingGroup = "CreateAutoScalingGroup"

// CreateAutoScalingGroupRequest generates a "aws/request.Request" representing the
// client's request for the CreateAutoScalingGroup operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateAutoScalingGroup for more information on using the CreateAutoScalingGroup
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateAutoScalingGroupRequest method.
//    req, resp := client.CreateAutoScalingGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/CreateAutoScalingGroup
func (c *AutoScaling) CreateAutoScalingGroupRequest(input *CreateAutoScalingGroupInput) (req *request.Request, output *CreateAutoScalingGroupOutput) {
	op := &request.Operation{
		Name:       opCreateAutoScalingGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateAutoScalingGroupInput{}
	}

	output = &CreateAutoScalingGroupOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// CreateAutoScalingGroup API operation for Auto Scaling.
//
// Creates an Auto Scaling group with the specified name and attributes.
//
// If you exceed your maximum limit of Auto Scaling groups, the call fails.
// For information about viewing this limit, see DescribeAccountLimits. For
// information about updating this limit, see Auto Scaling Limits (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-account-limits.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// For more information, see Auto Scaling Groups (http://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroup.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation CreateAutoScalingGroup for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAlreadyExistsFault "AlreadyExists"
//   You already have an Auto Scaling group or launch configuration with this
//   name.
//
//   * ErrCodeLimitExceededFault "LimitExceeded"
//   You have already reached a limit for your Auto Scaling resources (for example,
//   groups, launch configurations, or lifecycle hooks). For more information,
//   see DescribeAccountLimits.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeServiceLinkedRoleFailure "ServiceLinkedRoleFailure"
//   The service-linked role is not yet ready for use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/CreateAutoScalingGroup
func (c *AutoScaling) CreateAutoScalingGroup(input *CreateAutoScalingGroupInput) (*CreateAutoScalingGroupOutput, error) {
	req, out := c.CreateAutoScalingGroupRequest(input)
	return out, req.Send()
}

// CreateAutoScalingGroupWithContext is the same as CreateAutoScalingGroup with the addition of
// the ability to pass a context and additional request options.
//
// See CreateAutoScalingGroup for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) CreateAutoScalingGroupWithContext(ctx aws.Context, input *CreateAutoScalingGroupInput, opts ...request.Option) (*CreateAutoScalingGroupOutput, error) {
	req, out := c.CreateAutoScalingGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateLaunchConfiguration = "CreateLaunchConfiguration"

// CreateLaunchConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the CreateLaunchConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateLaunchConfiguration for more information on using the CreateLaunchConfiguration
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateLaunchConfigurationRequest method.
//    req, resp := client.CreateLaunchConfigurationRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/CreateLaunchConfiguration
func (c *AutoScaling) CreateLaunchConfigurationRequest(input *CreateLaunchConfigurationInput) (req *request.Request, output *CreateLaunchConfigurationOutput) {
	op := &request.Operation{
		Name:       opCreateLaunchConfiguration,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateLaunchConfigurationInput{}
	}

	output = &CreateLaunchConfigurationOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// CreateLaunchConfiguration API operation for Auto Scaling.
//
// Creates a launch configuration.
//
// If you exceed your maximum limit of launch configurations, the call fails.
// For information about viewing this limit, see DescribeAccountLimits. For
// information about updating this limit, see Auto Scaling Limits (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-account-limits.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// For more information, see Launch Configurations (http://docs.aws.amazon.com/autoscaling/ec2/userguide/LaunchConfiguration.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation CreateLaunchConfiguration for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAlreadyExistsFault "AlreadyExists"
//   You already have an Auto Scaling group or launch configuration with this
//   name.
//
//   * ErrCodeLimitExceededFault "LimitExceeded"
//   You have already reached a limit for your Auto Scaling resources (for example,
//   groups, launch configurations, or lifecycle hooks). For more information,
//   see DescribeAccountLimits.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/CreateLaunchConfiguration
func (c *AutoScaling) CreateLaunchConfiguration(input *CreateLaunchConfigurationInput) (*CreateLaunchConfigurationOutput, error) {
	req, out := c.CreateLaunchConfigurationRequest(input)
	return out, req.Send()
}

// CreateLaunchConfigurationWithContext is the same as CreateLaunchConfiguration with the addition of
// the ability to pass a context and additional request options.
//
// See CreateLaunchConfiguration for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) CreateLaunchConfigurationWithContext(ctx aws.Context, input *CreateLaunchConfigurationInput, opts ...request.Option) (*CreateLaunchConfigurationOutput, error) {
	req, out := c.CreateLaunchConfigurationRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateOrUpdateTags = "CreateOrUpdateTags"

// CreateOrUpdateTagsRequest generates a "aws/request.Request" representing the
// client's request for the CreateOrUpdateTags operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateOrUpdateTags for more information on using the CreateOrUpdateTags
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateOrUpdateTagsRequest method.
//    req, resp := client.CreateOrUpdateTagsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/CreateOrUpdateTags
func (c *AutoScaling) CreateOrUpdateTagsRequest(input *CreateOrUpdateTagsInput) (req *request.Request, output *CreateOrUpdateTagsOutput) {
	op := &request.Operation{
		Name:       opCreateOrUpdateTags,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateOrUpdateTagsInput{}
	}

	output = &CreateOrUpdateTagsOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// CreateOrUpdateTags API operation for Auto Scaling.
//
// Creates or updates tags for the specified Auto Scaling group.
//
// When you specify a tag with a key that already exists, the operation overwrites
// the previous tag definition, and you do not get an error message.
//
// For more information, see Tagging Auto Scaling Groups and Instances (http://docs.aws.amazon.com/autoscaling/ec2/userguide/autoscaling-tagging.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation CreateOrUpdateTags for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLimitExceededFault "LimitExceeded"
//   You have already reached a limit for your Auto Scaling resources (for example,
//   groups, launch configurations, or lifecycle hooks). For more information,
//   see DescribeAccountLimits.
//
//   * ErrCodeAlreadyExistsFault "AlreadyExists"
//   You already have an Auto Scaling group or launch configuration with this
//   name.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeResourceInUseFault "ResourceInUse"
//   The operation can't be performed because the resource is in use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/CreateOrUpdateTags
func (c *AutoScaling) CreateOrUpdateTags(input *CreateOrUpdateTagsInput) (*CreateOrUpdateTagsOutput, error) {
	req, out := c.CreateOrUpdateTagsRequest(input)
	return out, req.Send()
}

// CreateOrUpdateTagsWithContext is the same as CreateOrUpdateTags with the addition of
// the ability to pass a context and additional request options.
//
// See CreateOrUpdateTags for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) CreateOrUpdateTagsWithContext(ctx aws.Context, input *CreateOrUpdateTagsInput, opts ...request.Option) (*CreateOrUpdateTagsOutput, error) {
	req, out := c.CreateOrUpdateTagsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteAutoScalingGroup = "DeleteAutoScalingGroup"

// DeleteAutoScalingGroupRequest generates a "aws/request.Request" representing the
// client's request for the DeleteAutoScalingGroup operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteAutoScalingGroup for more information on using the DeleteAutoScalingGroup
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteAutoScalingGroupRequest method.
//    req, resp := client.DeleteAutoScalingGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteAutoScalingGroup
func (c *AutoScaling) DeleteAutoScalingGroupRequest(input *DeleteAutoScalingGroupInput) (req *request.Request, output *DeleteAutoScalingGroupOutput) {
	op := &request.Operation{
		Name:       opDeleteAutoScalingGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteAutoScalingGroupInput{}
	}

	output = &DeleteAutoScalingGroupOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeleteAutoScalingGroup API operation for Auto Scaling.
//
// Deletes the specified Auto Scaling group.
//
// If the group has instances or scaling activities in progress, you must specify
// the option to force the deletion in order for it to succeed.
//
// If the group has policies, deleting the group deletes the policies, the underlying
// alarm actions, and any alarm that no longer has an associated action.
//
// To remove instances from the Auto Scaling group before deleting it, call
// DetachInstances with the list of instances and the option to decrement the
// desired capacity. This ensures that Amazon EC2 Auto Scaling does not launch
// replacement instances.
//
// To terminate all instances before deleting the Auto Scaling group, call UpdateAutoScalingGroup
// and set the minimum size and desired capacity of the Auto Scaling group to
// zero.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DeleteAutoScalingGroup for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeScalingActivityInProgressFault "ScalingActivityInProgress"
//   The operation can't be performed because there are scaling activities in
//   progress.
//
//   * ErrCodeResourceInUseFault "ResourceInUse"
//   The operation can't be performed because the resource is in use.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteAutoScalingGroup
func (c *AutoScaling) DeleteAutoScalingGroup(input *DeleteAutoScalingGroupInput) (*DeleteAutoScalingGroupOutput, error) {
	req, out := c.DeleteAutoScalingGroupRequest(input)
	return out, req.Send()
}

// DeleteAutoScalingGroupWithContext is the same as DeleteAutoScalingGroup with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteAutoScalingGroup for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DeleteAutoScalingGroupWithContext(ctx aws.Context, input *DeleteAutoScalingGroupInput, opts ...request.Option) (*DeleteAutoScalingGroupOutput, error) {
	req, out := c.DeleteAutoScalingGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteLaunchConfiguration = "DeleteLaunchConfiguration"

// DeleteLaunchConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the DeleteLaunchConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteLaunchConfiguration for more information on using the DeleteLaunchConfiguration
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteLaunchConfigurationRequest method.
//    req, resp := client.DeleteLaunchConfigurationRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteLaunchConfiguration
func (c *AutoScaling) DeleteLaunchConfigurationRequest(input *DeleteLaunchConfigurationInput) (req *request.Request, output *DeleteLaunchConfigurationOutput) {
	op := &request.Operation{
		Name:       opDeleteLaunchConfiguration,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteLaunchConfigurationInput{}
	}

	output = &DeleteLaunchConfigurationOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeleteLaunchConfiguration API operation for Auto Scaling.
//
// Deletes the specified launch configuration.
//
// The launch configuration must not be attached to an Auto Scaling group. When
// this call completes, the launch configuration is no longer available for
// use.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DeleteLaunchConfiguration for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceInUseFault "ResourceInUse"
//   The operation can't be performed because the resource is in use.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteLaunchConfiguration
func (c *AutoScaling) DeleteLaunchConfiguration(input *DeleteLaunchConfigurationInput) (*DeleteLaunchConfigurationOutput, error) {
	req, out := c.DeleteLaunchConfigurationRequest(input)
	return out, req.Send()
}

// DeleteLaunchConfigurationWithContext is the same as DeleteLaunchConfiguration with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteLaunchConfiguration for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DeleteLaunchConfigurationWithContext(ctx aws.Context, input *DeleteLaunchConfigurationInput, opts ...request.Option) (*DeleteLaunchConfigurationOutput, error) {
	req, out := c.DeleteLaunchConfigurationRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteLifecycleHook = "DeleteLifecycleHook"

// DeleteLifecycleHookRequest generates a "aws/request.Request" representing the
// client's request for the DeleteLifecycleHook operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteLifecycleHook for more information on using the DeleteLifecycleHook
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteLifecycleHookRequest method.
//    req, resp := client.DeleteLifecycleHookRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteLifecycleHook
func (c *AutoScaling) DeleteLifecycleHookRequest(input *DeleteLifecycleHookInput) (req *request.Request, output *DeleteLifecycleHookOutput) {
	op := &request.Operation{
		Name:       opDeleteLifecycleHook,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteLifecycleHookInput{}
	}

	output = &DeleteLifecycleHookOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeleteLifecycleHook API operation for Auto Scaling.
//
// Deletes the specified lifecycle hook.
//
// If there are any outstanding lifecycle actions, they are completed first
// (ABANDON for launching instances, CONTINUE for terminating instances).
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DeleteLifecycleHook for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteLifecycleHook
func (c *AutoScaling) DeleteLifecycleHook(input *DeleteLifecycleHookInput) (*DeleteLifecycleHookOutput, error) {
	req, out := c.DeleteLifecycleHookRequest(input)
	return out, req.Send()
}

// DeleteLifecycleHookWithContext is the same as DeleteLifecycleHook with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteLifecycleHook for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DeleteLifecycleHookWithContext(ctx aws.Context, input *DeleteLifecycleHookInput, opts ...request.Option) (*DeleteLifecycleHookOutput, error) {
	req, out := c.DeleteLifecycleHookRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteNotificationConfiguration = "DeleteNotificationConfiguration"

// DeleteNotificationConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the DeleteNotificationConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteNotificationConfiguration for more information on using the DeleteNotificationConfiguration
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteNotificationConfigurationRequest method.
//    req, resp := client.DeleteNotificationConfigurationRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteNotificationConfiguration
func (c *AutoScaling) DeleteNotificationConfigurationRequest(input *DeleteNotificationConfigurationInput) (req *request.Request, output *DeleteNotificationConfigurationOutput) {
	op := &request.Operation{
		Name:       opDeleteNotificationConfiguration,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteNotificationConfigurationInput{}
	}

	output = &DeleteNotificationConfigurationOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeleteNotificationConfiguration API operation for Auto Scaling.
//
// Deletes the specified notification.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DeleteNotificationConfiguration for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteNotificationConfiguration
func (c *AutoScaling) DeleteNotificationConfiguration(input *DeleteNotificationConfigurationInput) (*DeleteNotificationConfigurationOutput, error) {
	req, out := c.DeleteNotificationConfigurationRequest(input)
	return out, req.Send()
}

// DeleteNotificationConfigurationWithContext is the same as DeleteNotificationConfiguration with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteNotificationConfiguration for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DeleteNotificationConfigurationWithContext(ctx aws.Context, input *DeleteNotificationConfigurationInput, opts ...request.Option) (*DeleteNotificationConfigurationOutput, error) {
	req, out := c.DeleteNotificationConfigurationRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeletePolicy = "DeletePolicy"

// DeletePolicyRequest generates a "aws/request.Request" representing the
// client's request for the DeletePolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeletePolicy for more information on using the DeletePolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeletePolicyRequest method.
//    req, resp := client.DeletePolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeletePolicy
func (c *AutoScaling) DeletePolicyRequest(input *DeletePolicyInput) (req *request.Request, output *DeletePolicyOutput) {
	op := &request.Operation{
		Name:       opDeletePolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeletePolicyInput{}
	}

	output = &DeletePolicyOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeletePolicy API operation for Auto Scaling.
//
// Deletes the specified Auto Scaling policy.
//
// Deleting a policy deletes the underlying alarm action, but does not delete
// the alarm, even if it no longer has an associated action.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DeletePolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeServiceLinkedRoleFailure "ServiceLinkedRoleFailure"
//   The service-linked role is not yet ready for use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeletePolicy
func (c *AutoScaling) DeletePolicy(input *DeletePolicyInput) (*DeletePolicyOutput, error) {
	req, out := c.DeletePolicyRequest(input)
	return out, req.Send()
}

// DeletePolicyWithContext is the same as DeletePolicy with the addition of
// the ability to pass a context and additional request options.
//
// See DeletePolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DeletePolicyWithContext(ctx aws.Context, input *DeletePolicyInput, opts ...request.Option) (*DeletePolicyOutput, error) {
	req, out := c.DeletePolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteScheduledAction = "DeleteScheduledAction"

// DeleteScheduledActionRequest generates a "aws/request.Request" representing the
// client's request for the DeleteScheduledAction operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteScheduledAction for more information on using the DeleteScheduledAction
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteScheduledActionRequest method.
//    req, resp := client.DeleteScheduledActionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteScheduledAction
func (c *AutoScaling) DeleteScheduledActionRequest(input *DeleteScheduledActionInput) (req *request.Request, output *DeleteScheduledActionOutput) {
	op := &request.Operation{
		Name:       opDeleteScheduledAction,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteScheduledActionInput{}
	}

	output = &DeleteScheduledActionOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeleteScheduledAction API operation for Auto Scaling.
//
// Deletes the specified scheduled action.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DeleteScheduledAction for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteScheduledAction
func (c *AutoScaling) DeleteScheduledAction(input *DeleteScheduledActionInput) (*DeleteScheduledActionOutput, error) {
	req, out := c.DeleteScheduledActionRequest(input)
	return out, req.Send()
}

// DeleteScheduledActionWithContext is the same as DeleteScheduledAction with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteScheduledAction for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DeleteScheduledActionWithContext(ctx aws.Context, input *DeleteScheduledActionInput, opts ...request.Option) (*DeleteScheduledActionOutput, error) {
	req, out := c.DeleteScheduledActionRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteTags = "DeleteTags"

// DeleteTagsRequest generates a "aws/request.Request" representing the
// client's request for the DeleteTags operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteTags for more information on using the DeleteTags
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteTagsRequest method.
//    req, resp := client.DeleteTagsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteTags
func (c *AutoScaling) DeleteTagsRequest(input *DeleteTagsInput) (req *request.Request, output *DeleteTagsOutput) {
	op := &request.Operation{
		Name:       opDeleteTags,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteTagsInput{}
	}

	output = &DeleteTagsOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeleteTags API operation for Auto Scaling.
//
// Deletes the specified tags.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DeleteTags for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeResourceInUseFault "ResourceInUse"
//   The operation can't be performed because the resource is in use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DeleteTags
func (c *AutoScaling) DeleteTags(input *DeleteTagsInput) (*DeleteTagsOutput, error) {
	req, out := c.DeleteTagsRequest(input)
	return out, req.Send()
}

// DeleteTagsWithContext is the same as DeleteTags with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteTags for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DeleteTagsWithContext(ctx aws.Context, input *DeleteTagsInput, opts ...request.Option) (*DeleteTagsOutput, error) {
	req, out := c.DeleteTagsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeAccountLimits = "DescribeAccountLimits"

// DescribeAccountLimitsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeAccountLimits operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeAccountLimits for more information on using the DescribeAccountLimits
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeAccountLimitsRequest method.
//    req, resp := client.DescribeAccountLimitsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeAccountLimits
func (c *AutoScaling) DescribeAccountLimitsRequest(input *DescribeAccountLimitsInput) (req *request.Request, output *DescribeAccountLimitsOutput) {
	op := &request.Operation{
		Name:       opDescribeAccountLimits,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeAccountLimitsInput{}
	}

	output = &DescribeAccountLimitsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeAccountLimits API operation for Auto Scaling.
//
// Describes the current Auto Scaling resource limits for your AWS account.
//
// For information about requesting an increase in these limits, see Auto Scaling
// Limits (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-account-limits.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeAccountLimits for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeAccountLimits
func (c *AutoScaling) DescribeAccountLimits(input *DescribeAccountLimitsInput) (*DescribeAccountLimitsOutput, error) {
	req, out := c.DescribeAccountLimitsRequest(input)
	return out, req.Send()
}

// DescribeAccountLimitsWithContext is the same as DescribeAccountLimits with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeAccountLimits for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeAccountLimitsWithContext(ctx aws.Context, input *DescribeAccountLimitsInput, opts ...request.Option) (*DescribeAccountLimitsOutput, error) {
	req, out := c.DescribeAccountLimitsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeAdjustmentTypes = "DescribeAdjustmentTypes"

// DescribeAdjustmentTypesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeAdjustmentTypes operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeAdjustmentTypes for more information on using the DescribeAdjustmentTypes
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeAdjustmentTypesRequest method.
//    req, resp := client.DescribeAdjustmentTypesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeAdjustmentTypes
func (c *AutoScaling) DescribeAdjustmentTypesRequest(input *DescribeAdjustmentTypesInput) (req *request.Request, output *DescribeAdjustmentTypesOutput) {
	op := &request.Operation{
		Name:       opDescribeAdjustmentTypes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeAdjustmentTypesInput{}
	}

	output = &DescribeAdjustmentTypesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeAdjustmentTypes API operation for Auto Scaling.
//
// Describes the policy adjustment types for use with PutScalingPolicy.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeAdjustmentTypes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeAdjustmentTypes
func (c *AutoScaling) DescribeAdjustmentTypes(input *DescribeAdjustmentTypesInput) (*DescribeAdjustmentTypesOutput, error) {
	req, out := c.DescribeAdjustmentTypesRequest(input)
	return out, req.Send()
}

// DescribeAdjustmentTypesWithContext is the same as DescribeAdjustmentTypes with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeAdjustmentTypes for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeAdjustmentTypesWithContext(ctx aws.Context, input *DescribeAdjustmentTypesInput, opts ...request.Option) (*DescribeAdjustmentTypesOutput, error) {
	req, out := c.DescribeAdjustmentTypesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeAutoScalingGroups = "DescribeAutoScalingGroups"

// DescribeAutoScalingGroupsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeAutoScalingGroups operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeAutoScalingGroups for more information on using the DescribeAutoScalingGroups
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeAutoScalingGroupsRequest method.
//    req, resp := client.DescribeAutoScalingGroupsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeAutoScalingGroups
func (c *AutoScaling) DescribeAutoScalingGroupsRequest(input *DescribeAutoScalingGroupsInput) (req *request.Request, output *DescribeAutoScalingGroupsOutput) {
	op := &request.Operation{
		Name:       opDescribeAutoScalingGroups,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"NextToken"},
			OutputTokens:    []string{"NextToken"},
			LimitToken:      "MaxRecords",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeAutoScalingGroupsInput{}
	}

	output = &DescribeAutoScalingGroupsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeAutoScalingGroups API operation for Auto Scaling.
//
// Describes one or more Auto Scaling groups.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeAutoScalingGroups for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidNextToken "InvalidNextToken"
//   The NextToken value is not valid.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeAutoScalingGroups
func (c *AutoScaling) DescribeAutoScalingGroups(input *DescribeAutoScalingGroupsInput) (*DescribeAutoScalingGroupsOutput, error) {
	req, out := c.DescribeAutoScalingGroupsRequest(input)
	return out, req.Send()
}

// DescribeAutoScalingGroupsWithContext is the same as DescribeAutoScalingGroups with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeAutoScalingGroups for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeAutoScalingGroupsWithContext(ctx aws.Context, input *DescribeAutoScalingGroupsInput, opts ...request.Option) (*DescribeAutoScalingGroupsOutput, error) {
	req, out := c.DescribeAutoScalingGroupsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeAutoScalingGroupsPages iterates over the pages of a DescribeAutoScalingGroups operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeAutoScalingGroups method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeAutoScalingGroups operation.
//    pageNum := 0
//    err := client.DescribeAutoScalingGroupsPages(params,
//        func(page *DescribeAutoScalingGroupsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *AutoScaling) DescribeAutoScalingGroupsPages(input *DescribeAutoScalingGroupsInput, fn func(*DescribeAutoScalingGroupsOutput, bool) bool) error {
	return c.DescribeAutoScalingGroupsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeAutoScalingGroupsPagesWithContext same as DescribeAutoScalingGroupsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeAutoScalingGroupsPagesWithContext(ctx aws.Context, input *DescribeAutoScalingGroupsInput, fn func(*DescribeAutoScalingGroupsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeAutoScalingGroupsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeAutoScalingGroupsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribeAutoScalingGroupsOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opDescribeAutoScalingInstances = "DescribeAutoScalingInstances"

// DescribeAutoScalingInstancesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeAutoScalingInstances operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeAutoScalingInstances for more information on using the DescribeAutoScalingInstances
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeAutoScalingInstancesRequest method.
//    req, resp := client.DescribeAutoScalingInstancesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeAutoScalingInstances
func (c *AutoScaling) DescribeAutoScalingInstancesRequest(input *DescribeAutoScalingInstancesInput) (req *request.Request, output *DescribeAutoScalingInstancesOutput) {
	op := &request.Operation{
		Name:       opDescribeAutoScalingInstances,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"NextToken"},
			OutputTokens:    []string{"NextToken"},
			LimitToken:      "MaxRecords",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeAutoScalingInstancesInput{}
	}

	output = &DescribeAutoScalingInstancesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeAutoScalingInstances API operation for Auto Scaling.
//
// Describes one or more Auto Scaling instances.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeAutoScalingInstances for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidNextToken "InvalidNextToken"
//   The NextToken value is not valid.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeAutoScalingInstances
func (c *AutoScaling) DescribeAutoScalingInstances(input *DescribeAutoScalingInstancesInput) (*DescribeAutoScalingInstancesOutput, error) {
	req, out := c.DescribeAutoScalingInstancesRequest(input)
	return out, req.Send()
}

// DescribeAutoScalingInstancesWithContext is the same as DescribeAutoScalingInstances with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeAutoScalingInstances for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeAutoScalingInstancesWithContext(ctx aws.Context, input *DescribeAutoScalingInstancesInput, opts ...request.Option) (*DescribeAutoScalingInstancesOutput, error) {
	req, out := c.DescribeAutoScalingInstancesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeAutoScalingInstancesPages iterates over the pages of a DescribeAutoScalingInstances operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeAutoScalingInstances method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeAutoScalingInstances operation.
//    pageNum := 0
//    err := client.DescribeAutoScalingInstancesPages(params,
//        func(page *DescribeAutoScalingInstancesOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *AutoScaling) DescribeAutoScalingInstancesPages(input *DescribeAutoScalingInstancesInput, fn func(*DescribeAutoScalingInstancesOutput, bool) bool) error {
	return c.DescribeAutoScalingInstancesPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeAutoScalingInstancesPagesWithContext same as DescribeAutoScalingInstancesPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeAutoScalingInstancesPagesWithContext(ctx aws.Context, input *DescribeAutoScalingInstancesInput, fn func(*DescribeAutoScalingInstancesOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeAutoScalingInstancesInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeAutoScalingInstancesRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribeAutoScalingInstancesOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opDescribeAutoScalingNotificationTypes = "DescribeAutoScalingNotificationTypes"

// DescribeAutoScalingNotificationTypesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeAutoScalingNotificationTypes operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeAutoScalingNotificationTypes for more information on using the DescribeAutoScalingNotificationTypes
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeAutoScalingNotificationTypesRequest method.
//    req, resp := client.DescribeAutoScalingNotificationTypesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeAutoScalingNotificationTypes
func (c *AutoScaling) DescribeAutoScalingNotificationTypesRequest(input *DescribeAutoScalingNotificationTypesInput) (req *request.Request, output *DescribeAutoScalingNotificationTypesOutput) {
	op := &request.Operation{
		Name:       opDescribeAutoScalingNotificationTypes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeAutoScalingNotificationTypesInput{}
	}

	output = &DescribeAutoScalingNotificationTypesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeAutoScalingNotificationTypes API operation for Auto Scaling.
//
// Describes the notification types that are supported by Amazon EC2 Auto Scaling.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeAutoScalingNotificationTypes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeAutoScalingNotificationTypes
func (c *AutoScaling) DescribeAutoScalingNotificationTypes(input *DescribeAutoScalingNotificationTypesInput) (*DescribeAutoScalingNotificationTypesOutput, error) {
	req, out := c.DescribeAutoScalingNotificationTypesRequest(input)
	return out, req.Send()
}

// DescribeAutoScalingNotificationTypesWithContext is the same as DescribeAutoScalingNotificationTypes with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeAutoScalingNotificationTypes for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeAutoScalingNotificationTypesWithContext(ctx aws.Context, input *DescribeAutoScalingNotificationTypesInput, opts ...request.Option) (*DescribeAutoScalingNotificationTypesOutput, error) {
	req, out := c.DescribeAutoScalingNotificationTypesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeLaunchConfigurations = "DescribeLaunchConfigurations"

// DescribeLaunchConfigurationsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLaunchConfigurations operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLaunchConfigurations for more information on using the DescribeLaunchConfigurations
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLaunchConfigurationsRequest method.
//    req, resp := client.DescribeLaunchConfigurationsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeLaunchConfigurations
func (c *AutoScaling) DescribeLaunchConfigurationsRequest(input *DescribeLaunchConfigurationsInput) (req *request.Request, output *DescribeLaunchConfigurationsOutput) {
	op := &request.Operation{
		Name:       opDescribeLaunchConfigurations,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"NextToken"},
			OutputTokens:    []string{"NextToken"},
			LimitToken:      "MaxRecords",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeLaunchConfigurationsInput{}
	}

	output = &DescribeLaunchConfigurationsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeLaunchConfigurations API operation for Auto Scaling.
//
// Describes one or more launch configurations.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeLaunchConfigurations for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidNextToken "InvalidNextToken"
//   The NextToken value is not valid.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeLaunchConfigurations
func (c *AutoScaling) DescribeLaunchConfigurations(input *DescribeLaunchConfigurationsInput) (*DescribeLaunchConfigurationsOutput, error) {
	req, out := c.DescribeLaunchConfigurationsRequest(input)
	return out, req.Send()
}

// DescribeLaunchConfigurationsWithContext is the same as DescribeLaunchConfigurations with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLaunchConfigurations for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeLaunchConfigurationsWithContext(ctx aws.Context, input *DescribeLaunchConfigurationsInput, opts ...request.Option) (*DescribeLaunchConfigurationsOutput, error) {
	req, out := c.DescribeLaunchConfigurationsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeLaunchConfigurationsPages iterates over the pages of a DescribeLaunchConfigurations operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeLaunchConfigurations method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeLaunchConfigurations operation.
//    pageNum := 0
//    err := client.DescribeLaunchConfigurationsPages(params,
//        func(page *DescribeLaunchConfigurationsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *AutoScaling) DescribeLaunchConfigurationsPages(input *DescribeLaunchConfigurationsInput, fn func(*DescribeLaunchConfigurationsOutput, bool) bool) error {
	return c.DescribeLaunchConfigurationsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeLaunchConfigurationsPagesWithContext same as DescribeLaunchConfigurationsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeLaunchConfigurationsPagesWithContext(ctx aws.Context, input *DescribeLaunchConfigurationsInput, fn func(*DescribeLaunchConfigurationsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeLaunchConfigurationsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeLaunchConfigurationsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribeLaunchConfigurationsOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opDescribeLifecycleHookTypes = "DescribeLifecycleHookTypes"

// DescribeLifecycleHookTypesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLifecycleHookTypes operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLifecycleHookTypes for more information on using the DescribeLifecycleHookTypes
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLifecycleHookTypesRequest method.
//    req, resp := client.DescribeLifecycleHookTypesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeLifecycleHookTypes
func (c *AutoScaling) DescribeLifecycleHookTypesRequest(input *DescribeLifecycleHookTypesInput) (req *request.Request, output *DescribeLifecycleHookTypesOutput) {
	op := &request.Operation{
		Name:       opDescribeLifecycleHookTypes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeLifecycleHookTypesInput{}
	}

	output = &DescribeLifecycleHookTypesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeLifecycleHookTypes API operation for Auto Scaling.
//
// Describes the available types of lifecycle hooks.
//
// The following hook types are supported:
//
//    * autoscaling:EC2_INSTANCE_LAUNCHING
//
//    * autoscaling:EC2_INSTANCE_TERMINATING
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeLifecycleHookTypes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeLifecycleHookTypes
func (c *AutoScaling) DescribeLifecycleHookTypes(input *DescribeLifecycleHookTypesInput) (*DescribeLifecycleHookTypesOutput, error) {
	req, out := c.DescribeLifecycleHookTypesRequest(input)
	return out, req.Send()
}

// DescribeLifecycleHookTypesWithContext is the same as DescribeLifecycleHookTypes with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLifecycleHookTypes for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeLifecycleHookTypesWithContext(ctx aws.Context, input *DescribeLifecycleHookTypesInput, opts ...request.Option) (*DescribeLifecycleHookTypesOutput, error) {
	req, out := c.DescribeLifecycleHookTypesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeLifecycleHooks = "DescribeLifecycleHooks"

// DescribeLifecycleHooksRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLifecycleHooks operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLifecycleHooks for more information on using the DescribeLifecycleHooks
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLifecycleHooksRequest method.
//    req, resp := client.DescribeLifecycleHooksRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeLifecycleHooks
func (c *AutoScaling) DescribeLifecycleHooksRequest(input *DescribeLifecycleHooksInput) (req *request.Request, output *DescribeLifecycleHooksOutput) {
	op := &request.Operation{
		Name:       opDescribeLifecycleHooks,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeLifecycleHooksInput{}
	}

	output = &DescribeLifecycleHooksOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeLifecycleHooks API operation for Auto Scaling.
//
// Describes the lifecycle hooks for the specified Auto Scaling group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeLifecycleHooks for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeLifecycleHooks
func (c *AutoScaling) DescribeLifecycleHooks(input *DescribeLifecycleHooksInput) (*DescribeLifecycleHooksOutput, error) {
	req, out := c.DescribeLifecycleHooksRequest(input)
	return out, req.Send()
}

// DescribeLifecycleHooksWithContext is the same as DescribeLifecycleHooks with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLifecycleHooks for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeLifecycleHooksWithContext(ctx aws.Context, input *DescribeLifecycleHooksInput, opts ...request.Option) (*DescribeLifecycleHooksOutput, error) {
	req, out := c.DescribeLifecycleHooksRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeLoadBalancerTargetGroups = "DescribeLoadBalancerTargetGroups"

// DescribeLoadBalancerTargetGroupsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLoadBalancerTargetGroups operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLoadBalancerTargetGroups for more information on using the DescribeLoadBalancerTargetGroups
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLoadBalancerTargetGroupsRequest method.
//    req, resp := client.DescribeLoadBalancerTargetGroupsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeLoadBalancerTargetGroups
func (c *AutoScaling) DescribeLoadBalancerTargetGroupsRequest(input *DescribeLoadBalancerTargetGroupsInput) (req *request.Request, output *DescribeLoadBalancerTargetGroupsOutput) {
	op := &request.Operation{
		Name:       opDescribeLoadBalancerTargetGroups,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeLoadBalancerTargetGroupsInput{}
	}

	output = &DescribeLoadBalancerTargetGroupsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeLoadBalancerTargetGroups API operation for Auto Scaling.
//
// Describes the target groups for the specified Auto Scaling group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeLoadBalancerTargetGroups for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeLoadBalancerTargetGroups
func (c *AutoScaling) DescribeLoadBalancerTargetGroups(input *DescribeLoadBalancerTargetGroupsInput) (*DescribeLoadBalancerTargetGroupsOutput, error) {
	req, out := c.DescribeLoadBalancerTargetGroupsRequest(input)
	return out, req.Send()
}

// DescribeLoadBalancerTargetGroupsWithContext is the same as DescribeLoadBalancerTargetGroups with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLoadBalancerTargetGroups for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeLoadBalancerTargetGroupsWithContext(ctx aws.Context, input *DescribeLoadBalancerTargetGroupsInput, opts ...request.Option) (*DescribeLoadBalancerTargetGroupsOutput, error) {
	req, out := c.DescribeLoadBalancerTargetGroupsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeLoadBalancers = "DescribeLoadBalancers"

// DescribeLoadBalancersRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLoadBalancers operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLoadBalancers for more information on using the DescribeLoadBalancers
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLoadBalancersRequest method.
//    req, resp := client.DescribeLoadBalancersRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeLoadBalancers
func (c *AutoScaling) DescribeLoadBalancersRequest(input *DescribeLoadBalancersInput) (req *request.Request, output *DescribeLoadBalancersOutput) {
	op := &request.Operation{
		Name:       opDescribeLoadBalancers,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeLoadBalancersInput{}
	}

	output = &DescribeLoadBalancersOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeLoadBalancers API operation for Auto Scaling.
//
// Describes the load balancers for the specified Auto Scaling group.
//
// This operation describes only Classic Load Balancers. If you have Application
// Load Balancers, use DescribeLoadBalancerTargetGroups instead.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeLoadBalancers for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeLoadBalancers
func (c *AutoScaling) DescribeLoadBalancers(input *DescribeLoadBalancersInput) (*DescribeLoadBalancersOutput, error) {
	req, out := c.DescribeLoadBalancersRequest(input)
	return out, req.Send()
}

// DescribeLoadBalancersWithContext is the same as DescribeLoadBalancers with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLoadBalancers for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeLoadBalancersWithContext(ctx aws.Context, input *DescribeLoadBalancersInput, opts ...request.Option) (*DescribeLoadBalancersOutput, error) {
	req, out := c.DescribeLoadBalancersRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeMetricCollectionTypes = "DescribeMetricCollectionTypes"

// DescribeMetricCollectionTypesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeMetricCollectionTypes operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeMetricCollectionTypes for more information on using the DescribeMetricCollectionTypes
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeMetricCollectionTypesRequest method.
//    req, resp := client.DescribeMetricCollectionTypesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeMetricCollectionTypes
func (c *AutoScaling) DescribeMetricCollectionTypesRequest(input *DescribeMetricCollectionTypesInput) (req *request.Request, output *DescribeMetricCollectionTypesOutput) {
	op := &request.Operation{
		Name:       opDescribeMetricCollectionTypes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeMetricCollectionTypesInput{}
	}

	output = &DescribeMetricCollectionTypesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeMetricCollectionTypes API operation for Auto Scaling.
//
// Describes the available CloudWatch metrics for Amazon EC2 Auto Scaling.
//
// The GroupStandbyInstances metric is not returned by default. You must explicitly
// request this metric when calling EnableMetricsCollection.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeMetricCollectionTypes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeMetricCollectionTypes
func (c *AutoScaling) DescribeMetricCollectionTypes(input *DescribeMetricCollectionTypesInput) (*DescribeMetricCollectionTypesOutput, error) {
	req, out := c.DescribeMetricCollectionTypesRequest(input)
	return out, req.Send()
}

// DescribeMetricCollectionTypesWithContext is the same as DescribeMetricCollectionTypes with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeMetricCollectionTypes for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeMetricCollectionTypesWithContext(ctx aws.Context, input *DescribeMetricCollectionTypesInput, opts ...request.Option) (*DescribeMetricCollectionTypesOutput, error) {
	req, out := c.DescribeMetricCollectionTypesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeNotificationConfigurations = "DescribeNotificationConfigurations"

// DescribeNotificationConfigurationsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeNotificationConfigurations operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeNotificationConfigurations for more information on using the DescribeNotificationConfigurations
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeNotificationConfigurationsRequest method.
//    req, resp := client.DescribeNotificationConfigurationsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeNotificationConfigurations
func (c *AutoScaling) DescribeNotificationConfigurationsRequest(input *DescribeNotificationConfigurationsInput) (req *request.Request, output *DescribeNotificationConfigurationsOutput) {
	op := &request.Operation{
		Name:       opDescribeNotificationConfigurations,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"NextToken"},
			OutputTokens:    []string{"NextToken"},
			LimitToken:      "MaxRecords",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeNotificationConfigurationsInput{}
	}

	output = &DescribeNotificationConfigurationsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeNotificationConfigurations API operation for Auto Scaling.
//
// Describes the notification actions associated with the specified Auto Scaling
// group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeNotificationConfigurations for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidNextToken "InvalidNextToken"
//   The NextToken value is not valid.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeNotificationConfigurations
func (c *AutoScaling) DescribeNotificationConfigurations(input *DescribeNotificationConfigurationsInput) (*DescribeNotificationConfigurationsOutput, error) {
	req, out := c.DescribeNotificationConfigurationsRequest(input)
	return out, req.Send()
}

// DescribeNotificationConfigurationsWithContext is the same as DescribeNotificationConfigurations with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeNotificationConfigurations for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeNotificationConfigurationsWithContext(ctx aws.Context, input *DescribeNotificationConfigurationsInput, opts ...request.Option) (*DescribeNotificationConfigurationsOutput, error) {
	req, out := c.DescribeNotificationConfigurationsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeNotificationConfigurationsPages iterates over the pages of a DescribeNotificationConfigurations operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeNotificationConfigurations method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeNotificationConfigurations operation.
//    pageNum := 0
//    err := client.DescribeNotificationConfigurationsPages(params,
//        func(page *DescribeNotificationConfigurationsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *AutoScaling) DescribeNotificationConfigurationsPages(input *DescribeNotificationConfigurationsInput, fn func(*DescribeNotificationConfigurationsOutput, bool) bool) error {
	return c.DescribeNotificationConfigurationsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeNotificationConfigurationsPagesWithContext same as DescribeNotificationConfigurationsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeNotificationConfigurationsPagesWithContext(ctx aws.Context, input *DescribeNotificationConfigurationsInput, fn func(*DescribeNotificationConfigurationsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeNotificationConfigurationsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeNotificationConfigurationsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribeNotificationConfigurationsOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opDescribePolicies = "DescribePolicies"

// DescribePoliciesRequest generates a "aws/request.Request" representing the
// client's request for the DescribePolicies operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribePolicies for more information on using the DescribePolicies
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribePoliciesRequest method.
//    req, resp := client.DescribePoliciesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribePolicies
func (c *AutoScaling) DescribePoliciesRequest(input *DescribePoliciesInput) (req *request.Request, output *DescribePoliciesOutput) {
	op := &request.Operation{
		Name:       opDescribePolicies,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"NextToken"},
			OutputTokens:    []string{"NextToken"},
			LimitToken:      "MaxRecords",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribePoliciesInput{}
	}

	output = &DescribePoliciesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribePolicies API operation for Auto Scaling.
//
// Describes the policies for the specified Auto Scaling group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribePolicies for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidNextToken "InvalidNextToken"
//   The NextToken value is not valid.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeServiceLinkedRoleFailure "ServiceLinkedRoleFailure"
//   The service-linked role is not yet ready for use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribePolicies
func (c *AutoScaling) DescribePolicies(input *DescribePoliciesInput) (*DescribePoliciesOutput, error) {
	req, out := c.DescribePoliciesRequest(input)
	return out, req.Send()
}

// DescribePoliciesWithContext is the same as DescribePolicies with the addition of
// the ability to pass a context and additional request options.
//
// See DescribePolicies for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribePoliciesWithContext(ctx aws.Context, input *DescribePoliciesInput, opts ...request.Option) (*DescribePoliciesOutput, error) {
	req, out := c.DescribePoliciesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribePoliciesPages iterates over the pages of a DescribePolicies operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribePolicies method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribePolicies operation.
//    pageNum := 0
//    err := client.DescribePoliciesPages(params,
//        func(page *DescribePoliciesOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *AutoScaling) DescribePoliciesPages(input *DescribePoliciesInput, fn func(*DescribePoliciesOutput, bool) bool) error {
	return c.DescribePoliciesPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribePoliciesPagesWithContext same as DescribePoliciesPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribePoliciesPagesWithContext(ctx aws.Context, input *DescribePoliciesInput, fn func(*DescribePoliciesOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribePoliciesInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribePoliciesRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribePoliciesOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opDescribeScalingActivities = "DescribeScalingActivities"

// DescribeScalingActivitiesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeScalingActivities operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeScalingActivities for more information on using the DescribeScalingActivities
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeScalingActivitiesRequest method.
//    req, resp := client.DescribeScalingActivitiesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeScalingActivities
func (c *AutoScaling) DescribeScalingActivitiesRequest(input *DescribeScalingActivitiesInput) (req *request.Request, output *DescribeScalingActivitiesOutput) {
	op := &request.Operation{
		Name:       opDescribeScalingActivities,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"NextToken"},
			OutputTokens:    []string{"NextToken"},
			LimitToken:      "MaxRecords",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeScalingActivitiesInput{}
	}

	output = &DescribeScalingActivitiesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeScalingActivities API operation for Auto Scaling.
//
// Describes one or more scaling activities for the specified Auto Scaling group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeScalingActivities for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidNextToken "InvalidNextToken"
//   The NextToken value is not valid.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeScalingActivities
func (c *AutoScaling) DescribeScalingActivities(input *DescribeScalingActivitiesInput) (*DescribeScalingActivitiesOutput, error) {
	req, out := c.DescribeScalingActivitiesRequest(input)
	return out, req.Send()
}

// DescribeScalingActivitiesWithContext is the same as DescribeScalingActivities with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeScalingActivities for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeScalingActivitiesWithContext(ctx aws.Context, input *DescribeScalingActivitiesInput, opts ...request.Option) (*DescribeScalingActivitiesOutput, error) {
	req, out := c.DescribeScalingActivitiesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeScalingActivitiesPages iterates over the pages of a DescribeScalingActivities operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeScalingActivities method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeScalingActivities operation.
//    pageNum := 0
//    err := client.DescribeScalingActivitiesPages(params,
//        func(page *DescribeScalingActivitiesOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *AutoScaling) DescribeScalingActivitiesPages(input *DescribeScalingActivitiesInput, fn func(*DescribeScalingActivitiesOutput, bool) bool) error {
	return c.DescribeScalingActivitiesPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeScalingActivitiesPagesWithContext same as DescribeScalingActivitiesPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeScalingActivitiesPagesWithContext(ctx aws.Context, input *DescribeScalingActivitiesInput, fn func(*DescribeScalingActivitiesOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeScalingActivitiesInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeScalingActivitiesRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribeScalingActivitiesOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opDescribeScalingProcessTypes = "DescribeScalingProcessTypes"

// DescribeScalingProcessTypesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeScalingProcessTypes operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeScalingProcessTypes for more information on using the DescribeScalingProcessTypes
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeScalingProcessTypesRequest method.
//    req, resp := client.DescribeScalingProcessTypesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeScalingProcessTypes
func (c *AutoScaling) DescribeScalingProcessTypesRequest(input *DescribeScalingProcessTypesInput) (req *request.Request, output *DescribeScalingProcessTypesOutput) {
	op := &request.Operation{
		Name:       opDescribeScalingProcessTypes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeScalingProcessTypesInput{}
	}

	output = &DescribeScalingProcessTypesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeScalingProcessTypes API operation for Auto Scaling.
//
// Describes the scaling process types for use with ResumeProcesses and SuspendProcesses.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeScalingProcessTypes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeScalingProcessTypes
func (c *AutoScaling) DescribeScalingProcessTypes(input *DescribeScalingProcessTypesInput) (*DescribeScalingProcessTypesOutput, error) {
	req, out := c.DescribeScalingProcessTypesRequest(input)
	return out, req.Send()
}

// DescribeScalingProcessTypesWithContext is the same as DescribeScalingProcessTypes with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeScalingProcessTypes for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeScalingProcessTypesWithContext(ctx aws.Context, input *DescribeScalingProcessTypesInput, opts ...request.Option) (*DescribeScalingProcessTypesOutput, error) {
	req, out := c.DescribeScalingProcessTypesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeScheduledActions = "DescribeScheduledActions"

// DescribeScheduledActionsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeScheduledActions operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeScheduledActions for more information on using the DescribeScheduledActions
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeScheduledActionsRequest method.
//    req, resp := client.DescribeScheduledActionsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeScheduledActions
func (c *AutoScaling) DescribeScheduledActionsRequest(input *DescribeScheduledActionsInput) (req *request.Request, output *DescribeScheduledActionsOutput) {
	op := &request.Operation{
		Name:       opDescribeScheduledActions,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"NextToken"},
			OutputTokens:    []string{"NextToken"},
			LimitToken:      "MaxRecords",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeScheduledActionsInput{}
	}

	output = &DescribeScheduledActionsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeScheduledActions API operation for Auto Scaling.
//
// Describes the actions scheduled for your Auto Scaling group that haven't
// run. To describe the actions that have already run, use DescribeScalingActivities.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeScheduledActions for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidNextToken "InvalidNextToken"
//   The NextToken value is not valid.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeScheduledActions
func (c *AutoScaling) DescribeScheduledActions(input *DescribeScheduledActionsInput) (*DescribeScheduledActionsOutput, error) {
	req, out := c.DescribeScheduledActionsRequest(input)
	return out, req.Send()
}

// DescribeScheduledActionsWithContext is the same as DescribeScheduledActions with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeScheduledActions for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeScheduledActionsWithContext(ctx aws.Context, input *DescribeScheduledActionsInput, opts ...request.Option) (*DescribeScheduledActionsOutput, error) {
	req, out := c.DescribeScheduledActionsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeScheduledActionsPages iterates over the pages of a DescribeScheduledActions operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeScheduledActions method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeScheduledActions operation.
//    pageNum := 0
//    err := client.DescribeScheduledActionsPages(params,
//        func(page *DescribeScheduledActionsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *AutoScaling) DescribeScheduledActionsPages(input *DescribeScheduledActionsInput, fn func(*DescribeScheduledActionsOutput, bool) bool) error {
	return c.DescribeScheduledActionsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeScheduledActionsPagesWithContext same as DescribeScheduledActionsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeScheduledActionsPagesWithContext(ctx aws.Context, input *DescribeScheduledActionsInput, fn func(*DescribeScheduledActionsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeScheduledActionsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeScheduledActionsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribeScheduledActionsOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opDescribeTags = "DescribeTags"

// DescribeTagsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeTags operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeTags for more information on using the DescribeTags
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeTagsRequest method.
//    req, resp := client.DescribeTagsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeTags
func (c *AutoScaling) DescribeTagsRequest(input *DescribeTagsInput) (req *request.Request, output *DescribeTagsOutput) {
	op := &request.Operation{
		Name:       opDescribeTags,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"NextToken"},
			OutputTokens:    []string{"NextToken"},
			LimitToken:      "MaxRecords",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeTagsInput{}
	}

	output = &DescribeTagsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeTags API operation for Auto Scaling.
//
// Describes the specified tags.
//
// You can use filters to limit the results. For example, you can query for
// the tags for a specific Auto Scaling group. You can specify multiple values
// for a filter. A tag must match at least one of the specified values for it
// to be included in the results.
//
// You can also specify multiple filters. The result includes information for
// a particular tag only if it matches all the filters. If there's no match,
// no special message is returned.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeTags for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidNextToken "InvalidNextToken"
//   The NextToken value is not valid.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeTags
func (c *AutoScaling) DescribeTags(input *DescribeTagsInput) (*DescribeTagsOutput, error) {
	req, out := c.DescribeTagsRequest(input)
	return out, req.Send()
}

// DescribeTagsWithContext is the same as DescribeTags with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeTags for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeTagsWithContext(ctx aws.Context, input *DescribeTagsInput, opts ...request.Option) (*DescribeTagsOutput, error) {
	req, out := c.DescribeTagsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeTagsPages iterates over the pages of a DescribeTags operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeTags method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeTags operation.
//    pageNum := 0
//    err := client.DescribeTagsPages(params,
//        func(page *DescribeTagsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *AutoScaling) DescribeTagsPages(input *DescribeTagsInput, fn func(*DescribeTagsOutput, bool) bool) error {
	return c.DescribeTagsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeTagsPagesWithContext same as DescribeTagsPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeTagsPagesWithContext(ctx aws.Context, input *DescribeTagsInput, fn func(*DescribeTagsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeTagsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeTagsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribeTagsOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opDescribeTerminationPolicyTypes = "DescribeTerminationPolicyTypes"

// DescribeTerminationPolicyTypesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeTerminationPolicyTypes operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeTerminationPolicyTypes for more information on using the DescribeTerminationPolicyTypes
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeTerminationPolicyTypesRequest method.
//    req, resp := client.DescribeTerminationPolicyTypesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeTerminationPolicyTypes
func (c *AutoScaling) DescribeTerminationPolicyTypesRequest(input *DescribeTerminationPolicyTypesInput) (req *request.Request, output *DescribeTerminationPolicyTypesOutput) {
	op := &request.Operation{
		Name:       opDescribeTerminationPolicyTypes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeTerminationPolicyTypesInput{}
	}

	output = &DescribeTerminationPolicyTypesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeTerminationPolicyTypes API operation for Auto Scaling.
//
// Describes the termination policies supported by Amazon EC2 Auto Scaling.
//
// For more information, see Controlling Which Auto Scaling Instances Terminate
// During Scale In (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DescribeTerminationPolicyTypes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DescribeTerminationPolicyTypes
func (c *AutoScaling) DescribeTerminationPolicyTypes(input *DescribeTerminationPolicyTypesInput) (*DescribeTerminationPolicyTypesOutput, error) {
	req, out := c.DescribeTerminationPolicyTypesRequest(input)
	return out, req.Send()
}

// DescribeTerminationPolicyTypesWithContext is the same as DescribeTerminationPolicyTypes with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeTerminationPolicyTypes for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DescribeTerminationPolicyTypesWithContext(ctx aws.Context, input *DescribeTerminationPolicyTypesInput, opts ...request.Option) (*DescribeTerminationPolicyTypesOutput, error) {
	req, out := c.DescribeTerminationPolicyTypesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDetachInstances = "DetachInstances"

// DetachInstancesRequest generates a "aws/request.Request" representing the
// client's request for the DetachInstances operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DetachInstances for more information on using the DetachInstances
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DetachInstancesRequest method.
//    req, resp := client.DetachInstancesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DetachInstances
func (c *AutoScaling) DetachInstancesRequest(input *DetachInstancesInput) (req *request.Request, output *DetachInstancesOutput) {
	op := &request.Operation{
		Name:       opDetachInstances,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DetachInstancesInput{}
	}

	output = &DetachInstancesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DetachInstances API operation for Auto Scaling.
//
// Removes one or more instances from the specified Auto Scaling group.
//
// After the instances are detached, you can manage them independent of the
// Auto Scaling group.
//
// If you do not specify the option to decrement the desired capacity, Amazon
// EC2 Auto Scaling launches instances to replace the ones that are detached.
//
// If there is a Classic Load Balancer attached to the Auto Scaling group, the
// instances are deregistered from the load balancer. If there are target groups
// attached to the Auto Scaling group, the instances are deregistered from the
// target groups.
//
// For more information, see Detach EC2 Instances from Your Auto Scaling Group
// (http://docs.aws.amazon.com/autoscaling/ec2/userguide/detach-instance-asg.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DetachInstances for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DetachInstances
func (c *AutoScaling) DetachInstances(input *DetachInstancesInput) (*DetachInstancesOutput, error) {
	req, out := c.DetachInstancesRequest(input)
	return out, req.Send()
}

// DetachInstancesWithContext is the same as DetachInstances with the addition of
// the ability to pass a context and additional request options.
//
// See DetachInstances for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DetachInstancesWithContext(ctx aws.Context, input *DetachInstancesInput, opts ...request.Option) (*DetachInstancesOutput, error) {
	req, out := c.DetachInstancesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDetachLoadBalancerTargetGroups = "DetachLoadBalancerTargetGroups"

// DetachLoadBalancerTargetGroupsRequest generates a "aws/request.Request" representing the
// client's request for the DetachLoadBalancerTargetGroups operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DetachLoadBalancerTargetGroups for more information on using the DetachLoadBalancerTargetGroups
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DetachLoadBalancerTargetGroupsRequest method.
//    req, resp := client.DetachLoadBalancerTargetGroupsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DetachLoadBalancerTargetGroups
func (c *AutoScaling) DetachLoadBalancerTargetGroupsRequest(input *DetachLoadBalancerTargetGroupsInput) (req *request.Request, output *DetachLoadBalancerTargetGroupsOutput) {
	op := &request.Operation{
		Name:       opDetachLoadBalancerTargetGroups,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DetachLoadBalancerTargetGroupsInput{}
	}

	output = &DetachLoadBalancerTargetGroupsOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DetachLoadBalancerTargetGroups API operation for Auto Scaling.
//
// Detaches one or more target groups from the specified Auto Scaling group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DetachLoadBalancerTargetGroups for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DetachLoadBalancerTargetGroups
func (c *AutoScaling) DetachLoadBalancerTargetGroups(input *DetachLoadBalancerTargetGroupsInput) (*DetachLoadBalancerTargetGroupsOutput, error) {
	req, out := c.DetachLoadBalancerTargetGroupsRequest(input)
	return out, req.Send()
}

// DetachLoadBalancerTargetGroupsWithContext is the same as DetachLoadBalancerTargetGroups with the addition of
// the ability to pass a context and additional request options.
//
// See DetachLoadBalancerTargetGroups for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DetachLoadBalancerTargetGroupsWithContext(ctx aws.Context, input *DetachLoadBalancerTargetGroupsInput, opts ...request.Option) (*DetachLoadBalancerTargetGroupsOutput, error) {
	req, out := c.DetachLoadBalancerTargetGroupsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDetachLoadBalancers = "DetachLoadBalancers"

// DetachLoadBalancersRequest generates a "aws/request.Request" representing the
// client's request for the DetachLoadBalancers operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DetachLoadBalancers for more information on using the DetachLoadBalancers
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DetachLoadBalancersRequest method.
//    req, resp := client.DetachLoadBalancersRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DetachLoadBalancers
func (c *AutoScaling) DetachLoadBalancersRequest(input *DetachLoadBalancersInput) (req *request.Request, output *DetachLoadBalancersOutput) {
	op := &request.Operation{
		Name:       opDetachLoadBalancers,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DetachLoadBalancersInput{}
	}

	output = &DetachLoadBalancersOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DetachLoadBalancers API operation for Auto Scaling.
//
// Detaches one or more Classic Load Balancers from the specified Auto Scaling
// group.
//
// This operation detaches only Classic Load Balancers. If you have Application
// Load Balancers, use DetachLoadBalancerTargetGroups instead.
//
// When you detach a load balancer, it enters the Removing state while deregistering
// the instances in the group. When all instances are deregistered, then you
// can no longer describe the load balancer using DescribeLoadBalancers. The
// instances remain running.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DetachLoadBalancers for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DetachLoadBalancers
func (c *AutoScaling) DetachLoadBalancers(input *DetachLoadBalancersInput) (*DetachLoadBalancersOutput, error) {
	req, out := c.DetachLoadBalancersRequest(input)
	return out, req.Send()
}

// DetachLoadBalancersWithContext is the same as DetachLoadBalancers with the addition of
// the ability to pass a context and additional request options.
//
// See DetachLoadBalancers for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DetachLoadBalancersWithContext(ctx aws.Context, input *DetachLoadBalancersInput, opts ...request.Option) (*DetachLoadBalancersOutput, error) {
	req, out := c.DetachLoadBalancersRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDisableMetricsCollection = "DisableMetricsCollection"

// DisableMetricsCollectionRequest generates a "aws/request.Request" representing the
// client's request for the DisableMetricsCollection operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DisableMetricsCollection for more information on using the DisableMetricsCollection
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DisableMetricsCollectionRequest method.
//    req, resp := client.DisableMetricsCollectionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DisableMetricsCollection
func (c *AutoScaling) DisableMetricsCollectionRequest(input *DisableMetricsCollectionInput) (req *request.Request, output *DisableMetricsCollectionOutput) {
	op := &request.Operation{
		Name:       opDisableMetricsCollection,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DisableMetricsCollectionInput{}
	}

	output = &DisableMetricsCollectionOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DisableMetricsCollection API operation for Auto Scaling.
//
// Disables group metrics for the specified Auto Scaling group.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation DisableMetricsCollection for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/DisableMetricsCollection
func (c *AutoScaling) DisableMetricsCollection(input *DisableMetricsCollectionInput) (*DisableMetricsCollectionOutput, error) {
	req, out := c.DisableMetricsCollectionRequest(input)
	return out, req.Send()
}

// DisableMetricsCollectionWithContext is the same as DisableMetricsCollection with the addition of
// the ability to pass a context and additional request options.
//
// See DisableMetricsCollection for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) DisableMetricsCollectionWithContext(ctx aws.Context, input *DisableMetricsCollectionInput, opts ...request.Option) (*DisableMetricsCollectionOutput, error) {
	req, out := c.DisableMetricsCollectionRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opEnableMetricsCollection = "EnableMetricsCollection"

// EnableMetricsCollectionRequest generates a "aws/request.Request" representing the
// client's request for the EnableMetricsCollection operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See EnableMetricsCollection for more information on using the EnableMetricsCollection
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the EnableMetricsCollectionRequest method.
//    req, resp := client.EnableMetricsCollectionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/EnableMetricsCollection
func (c *AutoScaling) EnableMetricsCollectionRequest(input *EnableMetricsCollectionInput) (req *request.Request, output *EnableMetricsCollectionOutput) {
	op := &request.Operation{
		Name:       opEnableMetricsCollection,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &EnableMetricsCollectionInput{}
	}

	output = &EnableMetricsCollectionOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// EnableMetricsCollection API operation for Auto Scaling.
//
// Enables group metrics for the specified Auto Scaling group. For more information,
// see Monitoring Your Auto Scaling Groups and Instances (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-monitoring.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation EnableMetricsCollection for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/EnableMetricsCollection
func (c *AutoScaling) EnableMetricsCollection(input *EnableMetricsCollectionInput) (*EnableMetricsCollectionOutput, error) {
	req, out := c.EnableMetricsCollectionRequest(input)
	return out, req.Send()
}

// EnableMetricsCollectionWithContext is the same as EnableMetricsCollection with the addition of
// the ability to pass a context and additional request options.
//
// See EnableMetricsCollection for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) EnableMetricsCollectionWithContext(ctx aws.Context, input *EnableMetricsCollectionInput, opts ...request.Option) (*EnableMetricsCollectionOutput, error) {
	req, out := c.EnableMetricsCollectionRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opEnterStandby = "EnterStandby"

// EnterStandbyRequest generates a "aws/request.Request" representing the
// client's request for the EnterStandby operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See EnterStandby for more information on using the EnterStandby
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the EnterStandbyRequest method.
//    req, resp := client.EnterStandbyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/EnterStandby
func (c *AutoScaling) EnterStandbyRequest(input *EnterStandbyInput) (req *request.Request, output *EnterStandbyOutput) {
	op := &request.Operation{
		Name:       opEnterStandby,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &EnterStandbyInput{}
	}

	output = &EnterStandbyOutput{}
	req = c.newRequest(op, input, output)
	return
}

// EnterStandby API operation for Auto Scaling.
//
// Moves the specified instances into the standby state.
//
// For more information, see Temporarily Removing Instances from Your Auto Scaling
// Group (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-enter-exit-standby.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation EnterStandby for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/EnterStandby
func (c *AutoScaling) EnterStandby(input *EnterStandbyInput) (*EnterStandbyOutput, error) {
	req, out := c.EnterStandbyRequest(input)
	return out, req.Send()
}

// EnterStandbyWithContext is the same as EnterStandby with the addition of
// the ability to pass a context and additional request options.
//
// See EnterStandby for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) EnterStandbyWithContext(ctx aws.Context, input *EnterStandbyInput, opts ...request.Option) (*EnterStandbyOutput, error) {
	req, out := c.EnterStandbyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opExecutePolicy = "ExecutePolicy"

// ExecutePolicyRequest generates a "aws/request.Request" representing the
// client's request for the ExecutePolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See ExecutePolicy for more information on using the ExecutePolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the ExecutePolicyRequest method.
//    req, resp := client.ExecutePolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/ExecutePolicy
func (c *AutoScaling) ExecutePolicyRequest(input *ExecutePolicyInput) (req *request.Request, output *ExecutePolicyOutput) {
	op := &request.Operation{
		Name:       opExecutePolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ExecutePolicyInput{}
	}

	output = &ExecutePolicyOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// ExecutePolicy API operation for Auto Scaling.
//
// Executes the specified policy.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation ExecutePolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeScalingActivityInProgressFault "ScalingActivityInProgress"
//   The operation can't be performed because there are scaling activities in
//   progress.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/ExecutePolicy
func (c *AutoScaling) ExecutePolicy(input *ExecutePolicyInput) (*ExecutePolicyOutput, error) {
	req, out := c.ExecutePolicyRequest(input)
	return out, req.Send()
}

// ExecutePolicyWithContext is the same as ExecutePolicy with the addition of
// the ability to pass a context and additional request options.
//
// See ExecutePolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) ExecutePolicyWithContext(ctx aws.Context, input *ExecutePolicyInput, opts ...request.Option) (*ExecutePolicyOutput, error) {
	req, out := c.ExecutePolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opExitStandby = "ExitStandby"

// ExitStandbyRequest generates a "aws/request.Request" representing the
// client's request for the ExitStandby operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See ExitStandby for more information on using the ExitStandby
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the ExitStandbyRequest method.
//    req, resp := client.ExitStandbyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/ExitStandby
func (c *AutoScaling) ExitStandbyRequest(input *ExitStandbyInput) (req *request.Request, output *ExitStandbyOutput) {
	op := &request.Operation{
		Name:       opExitStandby,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ExitStandbyInput{}
	}

	output = &ExitStandbyOutput{}
	req = c.newRequest(op, input, output)
	return
}

// ExitStandby API operation for Auto Scaling.
//
// Moves the specified instances out of the standby state.
//
// For more information, see Temporarily Removing Instances from Your Auto Scaling
// Group (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-enter-exit-standby.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation ExitStandby for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/ExitStandby
func (c *AutoScaling) ExitStandby(input *ExitStandbyInput) (*ExitStandbyOutput, error) {
	req, out := c.ExitStandbyRequest(input)
	return out, req.Send()
}

// ExitStandbyWithContext is the same as ExitStandby with the addition of
// the ability to pass a context and additional request options.
//
// See ExitStandby for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) ExitStandbyWithContext(ctx aws.Context, input *ExitStandbyInput, opts ...request.Option) (*ExitStandbyOutput, error) {
	req, out := c.ExitStandbyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutLifecycleHook = "PutLifecycleHook"

// PutLifecycleHookRequest generates a "aws/request.Request" representing the
// client's request for the PutLifecycleHook operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutLifecycleHook for more information on using the PutLifecycleHook
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutLifecycleHookRequest method.
//    req, resp := client.PutLifecycleHookRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/PutLifecycleHook
func (c *AutoScaling) PutLifecycleHookRequest(input *PutLifecycleHookInput) (req *request.Request, output *PutLifecycleHookOutput) {
	op := &request.Operation{
		Name:       opPutLifecycleHook,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutLifecycleHookInput{}
	}

	output = &PutLifecycleHookOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// PutLifecycleHook API operation for Auto Scaling.
//
// Creates or updates a lifecycle hook for the specified Auto Scaling group.
//
// A lifecycle hook tells Amazon EC2 Auto Scaling to perform an action on an
// instance that is not actively in service; for example, either when the instance
// launches or before the instance terminates.
//
// This step is a part of the procedure for adding a lifecycle hook to an Auto
// Scaling group:
//
// (Optional) Create a Lambda function and a rule that allows CloudWatch Events
// to invoke your Lambda function when Amazon EC2 Auto Scaling launches or terminates
// instances.
//
// (Optional) Create a notification target and an IAM role. The target can be
// either an Amazon SQS queue or an Amazon SNS topic. The role allows Amazon
// EC2 Auto Scaling to publish lifecycle notifications to the target.
//
// Create the lifecycle hook. Specify whether the hook is used when the instances
// launch or terminate.
//
// If you need more time, record the lifecycle action heartbeat to keep the
// instance in a pending state.
//
// If you finish before the timeout period ends, complete the lifecycle action.
//
// For more information, see Auto Scaling Lifecycle Hooks (http://docs.aws.amazon.com/autoscaling/ec2/userguide/lifecycle-hooks.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// If you exceed your maximum limit of lifecycle hooks, which by default is
// 50 per Auto Scaling group, the call fails. For information about updating
// this limit, see AWS Service Limits (http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html)
// in the Amazon Web Services General Reference.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation PutLifecycleHook for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLimitExceededFault "LimitExceeded"
//   You have already reached a limit for your Auto Scaling resources (for example,
//   groups, launch configurations, or lifecycle hooks). For more information,
//   see DescribeAccountLimits.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/PutLifecycleHook
func (c *AutoScaling) PutLifecycleHook(input *PutLifecycleHookInput) (*PutLifecycleHookOutput, error) {
	req, out := c.PutLifecycleHookRequest(input)
	return out, req.Send()
}

// PutLifecycleHookWithContext is the same as PutLifecycleHook with the addition of
// the ability to pass a context and additional request options.
//
// See PutLifecycleHook for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) PutLifecycleHookWithContext(ctx aws.Context, input *PutLifecycleHookInput, opts ...request.Option) (*PutLifecycleHookOutput, error) {
	req, out := c.PutLifecycleHookRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutNotificationConfiguration = "PutNotificationConfiguration"

// PutNotificationConfigurationRequest generates a "aws/request.Request" representing the
// client's request for the PutNotificationConfiguration operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutNotificationConfiguration for more information on using the PutNotificationConfiguration
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutNotificationConfigurationRequest method.
//    req, resp := client.PutNotificationConfigurationRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/PutNotificationConfiguration
func (c *AutoScaling) PutNotificationConfigurationRequest(input *PutNotificationConfigurationInput) (req *request.Request, output *PutNotificationConfigurationOutput) {
	op := &request.Operation{
		Name:       opPutNotificationConfiguration,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutNotificationConfigurationInput{}
	}

	output = &PutNotificationConfigurationOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// PutNotificationConfiguration API operation for Auto Scaling.
//
// Configures an Auto Scaling group to send notifications when specified events
// take place. Subscribers to the specified topic can have messages delivered
// to an endpoint such as a web server or an email address.
//
// This configuration overwrites any existing configuration.
//
// For more information, see Getting SNS Notifications When Your Auto Scaling
// Group Scales (http://docs.aws.amazon.com/autoscaling/ec2/userguide/ASGettingNotifications.html)
// in the Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation PutNotificationConfiguration for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLimitExceededFault "LimitExceeded"
//   You have already reached a limit for your Auto Scaling resources (for example,
//   groups, launch configurations, or lifecycle hooks). For more information,
//   see DescribeAccountLimits.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeServiceLinkedRoleFailure "ServiceLinkedRoleFailure"
//   The service-linked role is not yet ready for use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/PutNotificationConfiguration
func (c *AutoScaling) PutNotificationConfiguration(input *PutNotificationConfigurationInput) (*PutNotificationConfigurationOutput, error) {
	req, out := c.PutNotificationConfigurationRequest(input)
	return out, req.Send()
}

// PutNotificationConfigurationWithContext is the same as PutNotificationConfiguration with the addition of
// the ability to pass a context and additional request options.
//
// See PutNotificationConfiguration for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) PutNotificationConfigurationWithContext(ctx aws.Context, input *PutNotificationConfigurationInput, opts ...request.Option) (*PutNotificationConfigurationOutput, error) {
	req, out := c.PutNotificationConfigurationRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutScalingPolicy = "PutScalingPolicy"

// PutScalingPolicyRequest generates a "aws/request.Request" representing the
// client's request for the PutScalingPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutScalingPolicy for more information on using the PutScalingPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutScalingPolicyRequest method.
//    req, resp := client.PutScalingPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/PutScalingPolicy
func (c *AutoScaling) PutScalingPolicyRequest(input *PutScalingPolicyInput) (req *request.Request, output *PutScalingPolicyOutput) {
	op := &request.Operation{
		Name:       opPutScalingPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutScalingPolicyInput{}
	}

	output = &PutScalingPolicyOutput{}
	req = c.newRequest(op, input, output)
	return
}

// PutScalingPolicy API operation for Auto Scaling.
//
// Creates or updates a policy for an Auto Scaling group. To update an existing
// policy, use the existing policy name and set the parameters to change. Any
// existing parameter not changed in an update to an existing policy is not
// changed in this update request.
//
// If you exceed your maximum limit of step adjustments, which by default is
// 20 per region, the call fails. For information about updating this limit,
// see AWS Service Limits (http://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html)
// in the Amazon Web Services General Reference.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation PutScalingPolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLimitExceededFault "LimitExceeded"
//   You have already reached a limit for your Auto Scaling resources (for example,
//   groups, launch configurations, or lifecycle hooks). For more information,
//   see DescribeAccountLimits.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeServiceLinkedRoleFailure "ServiceLinkedRoleFailure"
//   The service-linked role is not yet ready for use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/PutScalingPolicy
func (c *AutoScaling) PutScalingPolicy(input *PutScalingPolicyInput) (*PutScalingPolicyOutput, error) {
	req, out := c.PutScalingPolicyRequest(input)
	return out, req.Send()
}

// PutScalingPolicyWithContext is the same as PutScalingPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See PutScalingPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) PutScalingPolicyWithContext(ctx aws.Context, input *PutScalingPolicyInput, opts ...request.Option) (*PutScalingPolicyOutput, error) {
	req, out := c.PutScalingPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opPutScheduledUpdateGroupAction = "PutScheduledUpdateGroupAction"

// PutScheduledUpdateGroupActionRequest generates a "aws/request.Request" representing the
// client's request for the PutScheduledUpdateGroupAction operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See PutScheduledUpdateGroupAction for more information on using the PutScheduledUpdateGroupAction
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the PutScheduledUpdateGroupActionRequest method.
//    req, resp := client.PutScheduledUpdateGroupActionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/PutScheduledUpdateGroupAction
func (c *AutoScaling) PutScheduledUpdateGroupActionRequest(input *PutScheduledUpdateGroupActionInput) (req *request.Request, output *PutScheduledUpdateGroupActionOutput) {
	op := &request.Operation{
		Name:       opPutScheduledUpdateGroupAction,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &PutScheduledUpdateGroupActionInput{}
	}

	output = &PutScheduledUpdateGroupActionOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// PutScheduledUpdateGroupAction API operation for Auto Scaling.
//
// Creates or updates a scheduled scaling action for an Auto Scaling group.
// If you leave a parameter unspecified when updating a scheduled scaling action,
// the corresponding value remains unchanged.
//
// For more information, see Scheduled Scaling (http://docs.aws.amazon.com/autoscaling/ec2/userguide/schedule_time.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation PutScheduledUpdateGroupAction for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAlreadyExistsFault "AlreadyExists"
//   You already have an Auto Scaling group or launch configuration with this
//   name.
//
//   * ErrCodeLimitExceededFault "LimitExceeded"
//   You have already reached a limit for your Auto Scaling resources (for example,
//   groups, launch configurations, or lifecycle hooks). For more information,
//   see DescribeAccountLimits.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/PutScheduledUpdateGroupAction
func (c *AutoScaling) PutScheduledUpdateGroupAction(input *PutScheduledUpdateGroupActionInput) (*PutScheduledUpdateGroupActionOutput, error) {
	req, out := c.PutScheduledUpdateGroupActionRequest(input)
	return out, req.Send()
}

// PutScheduledUpdateGroupActionWithContext is the same as PutScheduledUpdateGroupAction with the addition of
// the ability to pass a context and additional request options.
//
// See PutScheduledUpdateGroupAction for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) PutScheduledUpdateGroupActionWithContext(ctx aws.Context, input *PutScheduledUpdateGroupActionInput, opts ...request.Option) (*PutScheduledUpdateGroupActionOutput, error) {
	req, out := c.PutScheduledUpdateGroupActionRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opRecordLifecycleActionHeartbeat = "RecordLifecycleActionHeartbeat"

// RecordLifecycleActionHeartbeatRequest generates a "aws/request.Request" representing the
// client's request for the RecordLifecycleActionHeartbeat operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See RecordLifecycleActionHeartbeat for more information on using the RecordLifecycleActionHeartbeat
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the RecordLifecycleActionHeartbeatRequest method.
//    req, resp := client.RecordLifecycleActionHeartbeatRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/RecordLifecycleActionHeartbeat
func (c *AutoScaling) RecordLifecycleActionHeartbeatRequest(input *RecordLifecycleActionHeartbeatInput) (req *request.Request, output *RecordLifecycleActionHeartbeatOutput) {
	op := &request.Operation{
		Name:       opRecordLifecycleActionHeartbeat,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &RecordLifecycleActionHeartbeatInput{}
	}

	output = &RecordLifecycleActionHeartbeatOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// RecordLifecycleActionHeartbeat API operation for Auto Scaling.
//
// Records a heartbeat for the lifecycle action associated with the specified
// token or instance. This extends the timeout by the length of time defined
// using PutLifecycleHook.
//
// This step is a part of the procedure for adding a lifecycle hook to an Auto
// Scaling group:
//
// (Optional) Create a Lambda function and a rule that allows CloudWatch Events
// to invoke your Lambda function when Amazon EC2 Auto Scaling launches or terminates
// instances.
//
// (Optional) Create a notification target and an IAM role. The target can be
// either an Amazon SQS queue or an Amazon SNS topic. The role allows Amazon
// EC2 Auto Scaling to publish lifecycle notifications to the target.
//
// Create the lifecycle hook. Specify whether the hook is used when the instances
// launch or terminate.
//
// If you need more time, record the lifecycle action heartbeat to keep the
// instance in a pending state.
//
// If you finish before the timeout period ends, complete the lifecycle action.
//
// For more information, see Auto Scaling Lifecycle (http://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroupLifecycle.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation RecordLifecycleActionHeartbeat for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/RecordLifecycleActionHeartbeat
func (c *AutoScaling) RecordLifecycleActionHeartbeat(input *RecordLifecycleActionHeartbeatInput) (*RecordLifecycleActionHeartbeatOutput, error) {
	req, out := c.RecordLifecycleActionHeartbeatRequest(input)
	return out, req.Send()
}

// RecordLifecycleActionHeartbeatWithContext is the same as RecordLifecycleActionHeartbeat with the addition of
// the ability to pass a context and additional request options.
//
// See RecordLifecycleActionHeartbeat for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) RecordLifecycleActionHeartbeatWithContext(ctx aws.Context, input *RecordLifecycleActionHeartbeatInput, opts ...request.Option) (*RecordLifecycleActionHeartbeatOutput, error) {
	req, out := c.RecordLifecycleActionHeartbeatRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opResumeProcesses = "ResumeProcesses"

// ResumeProcessesRequest generates a "aws/request.Request" representing the
// client's request for the ResumeProcesses operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See ResumeProcesses for more information on using the ResumeProcesses
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the ResumeProcessesRequest method.
//    req, resp := client.ResumeProcessesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/ResumeProcesses
func (c *AutoScaling) ResumeProcessesRequest(input *ScalingProcessQuery) (req *request.Request, output *ResumeProcessesOutput) {
	op := &request.Operation{
		Name:       opResumeProcesses,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ScalingProcessQuery{}
	}

	output = &ResumeProcessesOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// ResumeProcesses API operation for Auto Scaling.
//
// Resumes the specified suspended automatic scaling processes, or all suspended
// process, for the specified Auto Scaling group.
//
// For more information, see Suspending and Resuming Scaling Processes (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-suspend-resume-processes.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation ResumeProcesses for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceInUseFault "ResourceInUse"
//   The operation can't be performed because the resource is in use.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/ResumeProcesses
func (c *AutoScaling) ResumeProcesses(input *ScalingProcessQuery) (*ResumeProcessesOutput, error) {
	req, out := c.ResumeProcessesRequest(input)
	return out, req.Send()
}

// ResumeProcessesWithContext is the same as ResumeProcesses with the addition of
// the ability to pass a context and additional request options.
//
// See ResumeProcesses for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) ResumeProcessesWithContext(ctx aws.Context, input *ScalingProcessQuery, opts ...request.Option) (*ResumeProcessesOutput, error) {
	req, out := c.ResumeProcessesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetDesiredCapacity = "SetDesiredCapacity"

// SetDesiredCapacityRequest generates a "aws/request.Request" representing the
// client's request for the SetDesiredCapacity operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See SetDesiredCapacity for more information on using the SetDesiredCapacity
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the SetDesiredCapacityRequest method.
//    req, resp := client.SetDesiredCapacityRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/SetDesiredCapacity
func (c *AutoScaling) SetDesiredCapacityRequest(input *SetDesiredCapacityInput) (req *request.Request, output *SetDesiredCapacityOutput) {
	op := &request.Operation{
		Name:       opSetDesiredCapacity,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetDesiredCapacityInput{}
	}

	output = &SetDesiredCapacityOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// SetDesiredCapacity API operation for Auto Scaling.
//
// Sets the size of the specified Auto Scaling group.
//
// For more information about desired capacity, see What Is Amazon EC2 Auto
// Scaling? (http://docs.aws.amazon.com/autoscaling/ec2/userguide/WhatIsAutoScaling.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation SetDesiredCapacity for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeScalingActivityInProgressFault "ScalingActivityInProgress"
//   The operation can't be performed because there are scaling activities in
//   progress.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/SetDesiredCapacity
func (c *AutoScaling) SetDesiredCapacity(input *SetDesiredCapacityInput) (*SetDesiredCapacityOutput, error) {
	req, out := c.SetDesiredCapacityRequest(input)
	return out, req.Send()
}

// SetDesiredCapacityWithContext is the same as SetDesiredCapacity with the addition of
// the ability to pass a context and additional request options.
//
// See SetDesiredCapacity for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) SetDesiredCapacityWithContext(ctx aws.Context, input *SetDesiredCapacityInput, opts ...request.Option) (*SetDesiredCapacityOutput, error) {
	req, out := c.SetDesiredCapacityRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetInstanceHealth = "SetInstanceHealth"

// SetInstanceHealthRequest generates a "aws/request.Request" representing the
// client's request for the SetInstanceHealth operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See SetInstanceHealth for more information on using the SetInstanceHealth
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the SetInstanceHealthRequest method.
//    req, resp := client.SetInstanceHealthRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/SetInstanceHealth
func (c *AutoScaling) SetInstanceHealthRequest(input *SetInstanceHealthInput) (req *request.Request, output *SetInstanceHealthOutput) {
	op := &request.Operation{
		Name:       opSetInstanceHealth,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetInstanceHealthInput{}
	}

	output = &SetInstanceHealthOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// SetInstanceHealth API operation for Auto Scaling.
//
// Sets the health status of the specified instance.
//
// For more information, see Health Checks (http://docs.aws.amazon.com/autoscaling/ec2/userguide/healthcheck.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation SetInstanceHealth for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/SetInstanceHealth
func (c *AutoScaling) SetInstanceHealth(input *SetInstanceHealthInput) (*SetInstanceHealthOutput, error) {
	req, out := c.SetInstanceHealthRequest(input)
	return out, req.Send()
}

// SetInstanceHealthWithContext is the same as SetInstanceHealth with the addition of
// the ability to pass a context and additional request options.
//
// See SetInstanceHealth for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) SetInstanceHealthWithContext(ctx aws.Context, input *SetInstanceHealthInput, opts ...request.Option) (*SetInstanceHealthOutput, error) {
	req, out := c.SetInstanceHealthRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetInstanceProtection = "SetInstanceProtection"

// SetInstanceProtectionRequest generates a "aws/request.Request" representing the
// client's request for the SetInstanceProtection operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See SetInstanceProtection for more information on using the SetInstanceProtection
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the SetInstanceProtectionRequest method.
//    req, resp := client.SetInstanceProtectionRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/SetInstanceProtection
func (c *AutoScaling) SetInstanceProtectionRequest(input *SetInstanceProtectionInput) (req *request.Request, output *SetInstanceProtectionOutput) {
	op := &request.Operation{
		Name:       opSetInstanceProtection,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetInstanceProtectionInput{}
	}

	output = &SetInstanceProtectionOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// SetInstanceProtection API operation for Auto Scaling.
//
// Updates the instance protection settings of the specified instances.
//
// For more information, see Instance Protection (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html#instance-protection)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation SetInstanceProtection for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLimitExceededFault "LimitExceeded"
//   You have already reached a limit for your Auto Scaling resources (for example,
//   groups, launch configurations, or lifecycle hooks). For more information,
//   see DescribeAccountLimits.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/SetInstanceProtection
func (c *AutoScaling) SetInstanceProtection(input *SetInstanceProtectionInput) (*SetInstanceProtectionOutput, error) {
	req, out := c.SetInstanceProtectionRequest(input)
	return out, req.Send()
}

// SetInstanceProtectionWithContext is the same as SetInstanceProtection with the addition of
// the ability to pass a context and additional request options.
//
// See SetInstanceProtection for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) SetInstanceProtectionWithContext(ctx aws.Context, input *SetInstanceProtectionInput, opts ...request.Option) (*SetInstanceProtectionOutput, error) {
	req, out := c.SetInstanceProtectionRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSuspendProcesses = "SuspendProcesses"

// SuspendProcessesRequest generates a "aws/request.Request" representing the
// client's request for the SuspendProcesses operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See SuspendProcesses for more information on using the SuspendProcesses
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the SuspendProcessesRequest method.
//    req, resp := client.SuspendProcessesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/SuspendProcesses
func (c *AutoScaling) SuspendProcessesRequest(input *ScalingProcessQuery) (req *request.Request, output *SuspendProcessesOutput) {
	op := &request.Operation{
		Name:       opSuspendProcesses,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ScalingProcessQuery{}
	}

	output = &SuspendProcessesOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// SuspendProcesses API operation for Auto Scaling.
//
// Suspends the specified automatic scaling processes, or all processes, for
// the specified Auto Scaling group.
//
// If you suspend either the Launch or Terminate process types, it can prevent
// other process types from functioning properly.
//
// To resume processes that have been suspended, use ResumeProcesses.
//
// For more information, see Suspending and Resuming Scaling Processes (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-suspend-resume-processes.html)
// in the Amazon EC2 Auto Scaling User Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation SuspendProcesses for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceInUseFault "ResourceInUse"
//   The operation can't be performed because the resource is in use.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/SuspendProcesses
func (c *AutoScaling) SuspendProcesses(input *ScalingProcessQuery) (*SuspendProcessesOutput, error) {
	req, out := c.SuspendProcessesRequest(input)
	return out, req.Send()
}

// SuspendProcessesWithContext is the same as SuspendProcesses with the addition of
// the ability to pass a context and additional request options.
//
// See SuspendProcesses for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) SuspendProcessesWithContext(ctx aws.Context, input *ScalingProcessQuery, opts ...request.Option) (*SuspendProcessesOutput, error) {
	req, out := c.SuspendProcessesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opTerminateInstanceInAutoScalingGroup = "TerminateInstanceInAutoScalingGroup"

// TerminateInstanceInAutoScalingGroupRequest generates a "aws/request.Request" representing the
// client's request for the TerminateInstanceInAutoScalingGroup operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See TerminateInstanceInAutoScalingGroup for more information on using the TerminateInstanceInAutoScalingGroup
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the TerminateInstanceInAutoScalingGroupRequest method.
//    req, resp := client.TerminateInstanceInAutoScalingGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/TerminateInstanceInAutoScalingGroup
func (c *AutoScaling) TerminateInstanceInAutoScalingGroupRequest(input *TerminateInstanceInAutoScalingGroupInput) (req *request.Request, output *TerminateInstanceInAutoScalingGroupOutput) {
	op := &request.Operation{
		Name:       opTerminateInstanceInAutoScalingGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &TerminateInstanceInAutoScalingGroupInput{}
	}

	output = &TerminateInstanceInAutoScalingGroupOutput{}
	req = c.newRequest(op, input, output)
	return
}

// TerminateInstanceInAutoScalingGroup API operation for Auto Scaling.
//
// Terminates the specified instance and optionally adjusts the desired group
// size.
//
// This call simply makes a termination request. The instance is not terminated
// immediately.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation TerminateInstanceInAutoScalingGroup for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeScalingActivityInProgressFault "ScalingActivityInProgress"
//   The operation can't be performed because there are scaling activities in
//   progress.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/TerminateInstanceInAutoScalingGroup
func (c *AutoScaling) TerminateInstanceInAutoScalingGroup(input *TerminateInstanceInAutoScalingGroupInput) (*TerminateInstanceInAutoScalingGroupOutput, error) {
	req, out := c.TerminateInstanceInAutoScalingGroupRequest(input)
	return out, req.Send()
}

// TerminateInstanceInAutoScalingGroupWithContext is the same as TerminateInstanceInAutoScalingGroup with the addition of
// the ability to pass a context and additional request options.
//
// See TerminateInstanceInAutoScalingGroup for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) TerminateInstanceInAutoScalingGroupWithContext(ctx aws.Context, input *TerminateInstanceInAutoScalingGroupInput, opts ...request.Option) (*TerminateInstanceInAutoScalingGroupOutput, error) {
	req, out := c.TerminateInstanceInAutoScalingGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opUpdateAutoScalingGroup = "UpdateAutoScalingGroup"

// UpdateAutoScalingGroupRequest generates a "aws/request.Request" representing the
// client's request for the UpdateAutoScalingGroup operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See UpdateAutoScalingGroup for more information on using the UpdateAutoScalingGroup
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the UpdateAutoScalingGroupRequest method.
//    req, resp := client.UpdateAutoScalingGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/UpdateAutoScalingGroup
func (c *AutoScaling) UpdateAutoScalingGroupRequest(input *UpdateAutoScalingGroupInput) (req *request.Request, output *UpdateAutoScalingGroupOutput) {
	op := &request.Operation{
		Name:       opUpdateAutoScalingGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &UpdateAutoScalingGroupInput{}
	}

	output = &UpdateAutoScalingGroupOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// UpdateAutoScalingGroup API operation for Auto Scaling.
//
// Updates the configuration for the specified Auto Scaling group.
//
// The new settings take effect on any scaling activities after this call returns.
// Scaling activities that are currently in progress aren't affected.
//
// To update an Auto Scaling group with a launch configuration with InstanceMonitoring
// set to false, you must first disable the collection of group metrics. Otherwise,
// you get an error. If you have previously enabled the collection of group
// metrics, you can disable it using DisableMetricsCollection.
//
// Note the following:
//
//    * If you specify a new value for MinSize without specifying a value for
//    DesiredCapacity, and the new MinSize is larger than the current size of
//    the group, we implicitly call SetDesiredCapacity to set the size of the
//    group to the new value of MinSize.
//
//    * If you specify a new value for MaxSize without specifying a value for
//    DesiredCapacity, and the new MaxSize is smaller than the current size
//    of the group, we implicitly call SetDesiredCapacity to set the size of
//    the group to the new value of MaxSize.
//
//    * All other optional parameters are left unchanged if not specified.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Auto Scaling's
// API operation UpdateAutoScalingGroup for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeScalingActivityInProgressFault "ScalingActivityInProgress"
//   The operation can't be performed because there are scaling activities in
//   progress.
//
//   * ErrCodeResourceContentionFault "ResourceContention"
//   You already have a pending update to an Auto Scaling resource (for example,
//   a group, instance, or load balancer).
//
//   * ErrCodeServiceLinkedRoleFailure "ServiceLinkedRoleFailure"
//   The service-linked role is not yet ready for use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/autoscaling-2011-01-01/UpdateAutoScalingGroup
func (c *AutoScaling) UpdateAutoScalingGroup(input *UpdateAutoScalingGroupInput) (*UpdateAutoScalingGroupOutput, error) {
	req, out := c.UpdateAutoScalingGroupRequest(input)
	return out, req.Send()
}

// UpdateAutoScalingGroupWithContext is the same as UpdateAutoScalingGroup with the addition of
// the ability to pass a context and additional request options.
//
// See UpdateAutoScalingGroup for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *AutoScaling) UpdateAutoScalingGroupWithContext(ctx aws.Context, input *UpdateAutoScalingGroupInput, opts ...request.Option) (*UpdateAutoScalingGroupOutput, error) {
	req, out := c.UpdateAutoScalingGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// Describes scaling activity, which is a long-running process that represents
// a change to your Auto Scaling group, such as changing its size or replacing
// an instance.
type Activity struct {
	_ struct{} `type:"structure"`

	// The ID of the activity.
	//
	// ActivityId is a required field
	ActivityId *string `type:"string" required:"true"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The reason the activity began.
	//
	// Cause is a required field
	Cause *string `min:"1" type:"string" required:"true"`

	// A friendly, more verbose description of the activity.
	Description *string `type:"string"`

	// The details about the activity.
	Details *string `type:"string"`

	// The end time of the activity.
	EndTime *time.Time `type:"timestamp"`

	// A value between 0 and 100 that indicates the progress of the activity.
	Progress *int64 `type:"integer"`

	// The start time of the activity.
	//
	// StartTime is a required field
	StartTime *time.Time `type:"timestamp" required:"true"`

	// The current status of the activity.
	//
	// StatusCode is a required field
	StatusCode *string `type:"string" required:"true" enum:"ScalingActivityStatusCode"`

	// A friendly, more verbose description of the activity status.
	StatusMessage *string `min:"1" type:"string"`
}

// String returns the string representation
func (s Activity) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Activity) GoString() string {
	return s.String()
}

// SetActivityId sets the ActivityId field's value.
func (s *Activity) SetActivityId(v string) *Activity {
	s.ActivityId = &v
	return s
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *Activity) SetAutoScalingGroupName(v string) *Activity {
	s.AutoScalingGroupName = &v
	return s
}

// SetCause sets the Cause field's value.
func (s *Activity) SetCause(v string) *Activity {
	s.Cause = &v
	return s
}

// SetDescription sets the Description field's value.
func (s *Activity) SetDescription(v string) *Activity {
	s.Description = &v
	return s
}

// SetDetails sets the Details field's value.
func (s *Activity) SetDetails(v string) *Activity {
	s.Details = &v
	return s
}

// SetEndTime sets the EndTime field's value.
func (s *Activity) SetEndTime(v time.Time) *Activity {
	s.EndTime = &v
	return s
}

// SetProgress sets the Progress field's value.
func (s *Activity) SetProgress(v int64) *Activity {
	s.Progress = &v
	return s
}

// SetStartTime sets the StartTime field's value.
func (s *Activity) SetStartTime(v time.Time) *Activity {
	s.StartTime = &v
	return s
}

// SetStatusCode sets the StatusCode field's value.
func (s *Activity) SetStatusCode(v string) *Activity {
	s.StatusCode = &v
	return s
}

// SetStatusMessage sets the StatusMessage field's value.
func (s *Activity) SetStatusMessage(v string) *Activity {
	s.StatusMessage = &v
	return s
}

// Describes a policy adjustment type.
//
// For more information, see Dynamic Scaling (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-scale-based-on-demand.html)
// in the Amazon EC2 Auto Scaling User Guide.
type AdjustmentType struct {
	_ struct{} `type:"structure"`

	// The policy adjustment type. The valid values are ChangeInCapacity, ExactCapacity,
	// and PercentChangeInCapacity.
	AdjustmentType *string `min:"1" type:"string"`
}

// String returns the string representation
func (s AdjustmentType) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AdjustmentType) GoString() string {
	return s.String()
}

// SetAdjustmentType sets the AdjustmentType field's value.
func (s *AdjustmentType) SetAdjustmentType(v string) *AdjustmentType {
	s.AdjustmentType = &v
	return s
}

// Describes an alarm.
type Alarm struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) of the alarm.
	AlarmARN *string `min:"1" type:"string"`

	// The name of the alarm.
	AlarmName *string `min:"1" type:"string"`
}

// String returns the string representation
func (s Alarm) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Alarm) GoString() string {
	return s.String()
}

// SetAlarmARN sets the AlarmARN field's value.
func (s *Alarm) SetAlarmARN(v string) *Alarm {
	s.AlarmARN = &v
	return s
}

// SetAlarmName sets the AlarmName field's value.
func (s *Alarm) SetAlarmName(v string) *Alarm {
	s.AlarmName = &v
	return s
}

type AttachInstancesInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The IDs of the instances. You can specify up to 20 instances.
	InstanceIds []*string `type:"list"`
}

// String returns the string representation
func (s AttachInstancesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AttachInstancesInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *AttachInstancesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AttachInstancesInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *AttachInstancesInput) SetAutoScalingGroupName(v string) *AttachInstancesInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetInstanceIds sets the InstanceIds field's value.
func (s *AttachInstancesInput) SetInstanceIds(v []*string) *AttachInstancesInput {
	s.InstanceIds = v
	return s
}

type AttachInstancesOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s AttachInstancesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AttachInstancesOutput) GoString() string {
	return s.String()
}

type AttachLoadBalancerTargetGroupsInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The Amazon Resource Names (ARN) of the target groups. You can specify up
	// to 10 target groups.
	//
	// TargetGroupARNs is a required field
	TargetGroupARNs []*string `type:"list" required:"true"`
}

// String returns the string representation
func (s AttachLoadBalancerTargetGroupsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AttachLoadBalancerTargetGroupsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *AttachLoadBalancerTargetGroupsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AttachLoadBalancerTargetGroupsInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.TargetGroupARNs == nil {
		invalidParams.Add(request.NewErrParamRequired("TargetGroupARNs"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *AttachLoadBalancerTargetGroupsInput) SetAutoScalingGroupName(v string) *AttachLoadBalancerTargetGroupsInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetTargetGroupARNs sets the TargetGroupARNs field's value.
func (s *AttachLoadBalancerTargetGroupsInput) SetTargetGroupARNs(v []*string) *AttachLoadBalancerTargetGroupsInput {
	s.TargetGroupARNs = v
	return s
}

type AttachLoadBalancerTargetGroupsOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s AttachLoadBalancerTargetGroupsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AttachLoadBalancerTargetGroupsOutput) GoString() string {
	return s.String()
}

type AttachLoadBalancersInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The names of the load balancers. You can specify up to 10 load balancers.
	//
	// LoadBalancerNames is a required field
	LoadBalancerNames []*string `type:"list" required:"true"`
}

// String returns the string representation
func (s AttachLoadBalancersInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AttachLoadBalancersInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *AttachLoadBalancersInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AttachLoadBalancersInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.LoadBalancerNames == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerNames"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *AttachLoadBalancersInput) SetAutoScalingGroupName(v string) *AttachLoadBalancersInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetLoadBalancerNames sets the LoadBalancerNames field's value.
func (s *AttachLoadBalancersInput) SetLoadBalancerNames(v []*string) *AttachLoadBalancersInput {
	s.LoadBalancerNames = v
	return s
}

type AttachLoadBalancersOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s AttachLoadBalancersOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AttachLoadBalancersOutput) GoString() string {
	return s.String()
}

type BatchDeleteScheduledActionInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The names of the scheduled actions to delete. The maximum number allowed
	// is 50.
	//
	// ScheduledActionNames is a required field
	ScheduledActionNames []*string `type:"list" required:"true"`
}

// String returns the string representation
func (s BatchDeleteScheduledActionInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BatchDeleteScheduledActionInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *BatchDeleteScheduledActionInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "BatchDeleteScheduledActionInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.ScheduledActionNames == nil {
		invalidParams.Add(request.NewErrParamRequired("ScheduledActionNames"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *BatchDeleteScheduledActionInput) SetAutoScalingGroupName(v string) *BatchDeleteScheduledActionInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetScheduledActionNames sets the ScheduledActionNames field's value.
func (s *BatchDeleteScheduledActionInput) SetScheduledActionNames(v []*string) *BatchDeleteScheduledActionInput {
	s.ScheduledActionNames = v
	return s
}

type BatchDeleteScheduledActionOutput struct {
	_ struct{} `type:"structure"`

	// The names of the scheduled actions that could not be deleted, including an
	// error message.
	FailedScheduledActions []*FailedScheduledUpdateGroupActionRequest `type:"list"`
}

// String returns the string representation
func (s BatchDeleteScheduledActionOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BatchDeleteScheduledActionOutput) GoString() string {
	return s.String()
}

// SetFailedScheduledActions sets the FailedScheduledActions field's value.
func (s *BatchDeleteScheduledActionOutput) SetFailedScheduledActions(v []*FailedScheduledUpdateGroupActionRequest) *BatchDeleteScheduledActionOutput {
	s.FailedScheduledActions = v
	return s
}

type BatchPutScheduledUpdateGroupActionInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// One or more scheduled actions. The maximum number allowed is 50.
	//
	// ScheduledUpdateGroupActions is a required field
	ScheduledUpdateGroupActions []*ScheduledUpdateGroupActionRequest `type:"list" required:"true"`
}

// String returns the string representation
func (s BatchPutScheduledUpdateGroupActionInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BatchPutScheduledUpdateGroupActionInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *BatchPutScheduledUpdateGroupActionInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "BatchPutScheduledUpdateGroupActionInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.ScheduledUpdateGroupActions == nil {
		invalidParams.Add(request.NewErrParamRequired("ScheduledUpdateGroupActions"))
	}
	if s.ScheduledUpdateGroupActions != nil {
		for i, v := range s.ScheduledUpdateGroupActions {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "ScheduledUpdateGroupActions", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *BatchPutScheduledUpdateGroupActionInput) SetAutoScalingGroupName(v string) *BatchPutScheduledUpdateGroupActionInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetScheduledUpdateGroupActions sets the ScheduledUpdateGroupActions field's value.
func (s *BatchPutScheduledUpdateGroupActionInput) SetScheduledUpdateGroupActions(v []*ScheduledUpdateGroupActionRequest) *BatchPutScheduledUpdateGroupActionInput {
	s.ScheduledUpdateGroupActions = v
	return s
}

type BatchPutScheduledUpdateGroupActionOutput struct {
	_ struct{} `type:"structure"`

	// The names of the scheduled actions that could not be created or updated,
	// including an error message.
	FailedScheduledUpdateGroupActions []*FailedScheduledUpdateGroupActionRequest `type:"list"`
}

// String returns the string representation
func (s BatchPutScheduledUpdateGroupActionOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BatchPutScheduledUpdateGroupActionOutput) GoString() string {
	return s.String()
}

// SetFailedScheduledUpdateGroupActions sets the FailedScheduledUpdateGroupActions field's value.
func (s *BatchPutScheduledUpdateGroupActionOutput) SetFailedScheduledUpdateGroupActions(v []*FailedScheduledUpdateGroupActionRequest) *BatchPutScheduledUpdateGroupActionOutput {
	s.FailedScheduledUpdateGroupActions = v
	return s
}

// Describes a block device mapping.
type BlockDeviceMapping struct {
	_ struct{} `type:"structure"`

	// The device name exposed to the EC2 instance (for example, /dev/sdh or xvdh).
	//
	// DeviceName is a required field
	DeviceName *string `min:"1" type:"string" required:"true"`

	// The information about the Amazon EBS volume.
	Ebs *Ebs `type:"structure"`

	// Suppresses a device mapping.
	//
	// If this parameter is true for the root device, the instance might fail the
	// EC2 health check. In that case, Amazon EC2 Auto Scaling launches a replacement
	// instance.
	NoDevice *bool `type:"boolean"`

	// The name of the virtual device (for example, ephemeral0).
	VirtualName *string `min:"1" type:"string"`
}

// String returns the string representation
func (s BlockDeviceMapping) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BlockDeviceMapping) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *BlockDeviceMapping) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "BlockDeviceMapping"}
	if s.DeviceName == nil {
		invalidParams.Add(request.NewErrParamRequired("DeviceName"))
	}
	if s.DeviceName != nil && len(*s.DeviceName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("DeviceName", 1))
	}
	if s.VirtualName != nil && len(*s.VirtualName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("VirtualName", 1))
	}
	if s.Ebs != nil {
		if err := s.Ebs.Validate(); err != nil {
			invalidParams.AddNested("Ebs", err.(request.ErrInvalidParams))
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetDeviceName sets the DeviceName field's value.
func (s *BlockDeviceMapping) SetDeviceName(v string) *BlockDeviceMapping {
	s.DeviceName = &v
	return s
}

// SetEbs sets the Ebs field's value.
func (s *BlockDeviceMapping) SetEbs(v *Ebs) *BlockDeviceMapping {
	s.Ebs = v
	return s
}

// SetNoDevice sets the NoDevice field's value.
func (s *BlockDeviceMapping) SetNoDevice(v bool) *BlockDeviceMapping {
	s.NoDevice = &v
	return s
}

// SetVirtualName sets the VirtualName field's value.
func (s *BlockDeviceMapping) SetVirtualName(v string) *BlockDeviceMapping {
	s.VirtualName = &v
	return s
}

type CompleteLifecycleActionInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The ID of the instance.
	InstanceId *string `min:"1" type:"string"`

	// The action for the group to take. This parameter can be either CONTINUE or
	// ABANDON.
	//
	// LifecycleActionResult is a required field
	LifecycleActionResult *string `type:"string" required:"true"`

	// A universally unique identifier (UUID) that identifies a specific lifecycle
	// action associated with an instance. Amazon EC2 Auto Scaling sends this token
	// to the notification target you specified when you created the lifecycle hook.
	LifecycleActionToken *string `min:"36" type:"string"`

	// The name of the lifecycle hook.
	//
	// LifecycleHookName is a required field
	LifecycleHookName *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s CompleteLifecycleActionInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CompleteLifecycleActionInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CompleteLifecycleActionInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CompleteLifecycleActionInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.InstanceId != nil && len(*s.InstanceId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("InstanceId", 1))
	}
	if s.LifecycleActionResult == nil {
		invalidParams.Add(request.NewErrParamRequired("LifecycleActionResult"))
	}
	if s.LifecycleActionToken != nil && len(*s.LifecycleActionToken) < 36 {
		invalidParams.Add(request.NewErrParamMinLen("LifecycleActionToken", 36))
	}
	if s.LifecycleHookName == nil {
		invalidParams.Add(request.NewErrParamRequired("LifecycleHookName"))
	}
	if s.LifecycleHookName != nil && len(*s.LifecycleHookName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LifecycleHookName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *CompleteLifecycleActionInput) SetAutoScalingGroupName(v string) *CompleteLifecycleActionInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetInstanceId sets the InstanceId field's value.
func (s *CompleteLifecycleActionInput) SetInstanceId(v string) *CompleteLifecycleActionInput {
	s.InstanceId = &v
	return s
}

// SetLifecycleActionResult sets the LifecycleActionResult field's value.
func (s *CompleteLifecycleActionInput) SetLifecycleActionResult(v string) *CompleteLifecycleActionInput {
	s.LifecycleActionResult = &v
	return s
}

// SetLifecycleActionToken sets the LifecycleActionToken field's value.
func (s *CompleteLifecycleActionInput) SetLifecycleActionToken(v string) *CompleteLifecycleActionInput {
	s.LifecycleActionToken = &v
	return s
}

// SetLifecycleHookName sets the LifecycleHookName field's value.
func (s *CompleteLifecycleActionInput) SetLifecycleHookName(v string) *CompleteLifecycleActionInput {
	s.LifecycleHookName = &v
	return s
}

type CompleteLifecycleActionOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CompleteLifecycleActionOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CompleteLifecycleActionOutput) GoString() string {
	return s.String()
}

type CreateAutoScalingGroupInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group. This name must be unique within the scope
	// of your AWS account.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// One or more Availability Zones for the group. This parameter is optional
	// if you specify one or more subnets.
	AvailabilityZones []*string `min:"1" type:"list"`

	// The amount of time, in seconds, after a scaling activity completes before
	// another scaling activity can start. The default is 300.
	//
	// For more information, see Scaling Cooldowns (http://docs.aws.amazon.com/autoscaling/ec2/userguide/Cooldown.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	DefaultCooldown *int64 `type:"integer"`

	// The number of EC2 instances that should be running in the group. This number
	// must be greater than or equal to the minimum size of the group and less than
	// or equal to the maximum size of the group. If you do not specify a desired
	// capacity, the default is the minimum size of the group.
	DesiredCapacity *int64 `type:"integer"`

	// The amount of time, in seconds, that Amazon EC2 Auto Scaling waits before
	// checking the health status of an EC2 instance that has come into service.
	// During this time, any health check failures for the instance are ignored.
	// The default is 0.
	//
	// This parameter is required if you are adding an ELB health check.
	//
	// For more information, see Health Checks (http://docs.aws.amazon.com/autoscaling/ec2/userguide/healthcheck.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	HealthCheckGracePeriod *int64 `type:"integer"`

	// The service to use for the health checks. The valid values are EC2 and ELB.
	//
	// By default, health checks use Amazon EC2 instance status checks to determine
	// the health of an instance. For more information, see Health Checks (http://docs.aws.amazon.com/autoscaling/ec2/userguide/healthcheck.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	HealthCheckType *string `min:"1" type:"string"`

	// The ID of the instance used to create a launch configuration for the group.
	// This parameter, a launch configuration, a launch template, or a mixed instances
	// policy must be specified.
	//
	// When you specify an ID of an instance, Amazon EC2 Auto Scaling creates a
	// new launch configuration and associates it with the group. This launch configuration
	// derives its attributes from the specified instance, except for the block
	// device mapping.
	//
	// For more information, see Create an Auto Scaling Group Using an EC2 Instance
	// (http://docs.aws.amazon.com/autoscaling/ec2/userguide/create-asg-from-instance.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	InstanceId *string `min:"1" type:"string"`

	// The name of the launch configuration. This parameter, a launch template,
	// a mixed instances policy, or an EC2 instance must be specified.
	LaunchConfigurationName *string `min:"1" type:"string"`

	// The launch template to use to launch instances. This parameter, a launch
	// configuration, a mixed instances policy, or an EC2 instance must be specified.
	LaunchTemplate *LaunchTemplateSpecification `type:"structure"`

	// One or more lifecycle hooks.
	LifecycleHookSpecificationList []*LifecycleHookSpecification `type:"list"`

	// One or more Classic Load Balancers. To specify an Application Load Balancer,
	// use TargetGroupARNs instead.
	//
	// For more information, see Using a Load Balancer With an Auto Scaling Group
	// (http://docs.aws.amazon.com/autoscaling/ec2/userguide/create-asg-from-instance.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	LoadBalancerNames []*string `type:"list"`

	// The maximum size of the group.
	//
	// MaxSize is a required field
	MaxSize *int64 `type:"integer" required:"true"`

	// The minimum size of the group.
	//
	// MinSize is a required field
	MinSize *int64 `type:"integer" required:"true"`

	// The mixed instances policy to use to launch instances. This parameter, a
	// launch template, a launch configuration, or an EC2 instance must be specified.
	MixedInstancesPolicy *MixedInstancesPolicy `type:"structure"`

	// Indicates whether newly launched instances are protected from termination
	// by Auto Scaling when scaling in.
	NewInstancesProtectedFromScaleIn *bool `type:"boolean"`

	// The name of the placement group into which to launch your instances, if any.
	// For more information, see Placement Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	PlacementGroup *string `min:"1" type:"string"`

	// The Amazon Resource Name (ARN) of the service-linked role that the Auto Scaling
	// group uses to call other AWS services on your behalf. By default, Amazon
	// EC2 Auto Scaling uses a service-linked role named AWSServiceRoleForAutoScaling,
	// which it creates if it does not exist.
	ServiceLinkedRoleARN *string `min:"1" type:"string"`

	// One or more tags.
	//
	// For more information, see Tagging Auto Scaling Groups and Instances (http://docs.aws.amazon.com/autoscaling/ec2/userguide/autoscaling-tagging.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	Tags []*Tag `type:"list"`

	// The Amazon Resource Names (ARN) of the target groups.
	TargetGroupARNs []*string `type:"list"`

	// One or more termination policies used to select the instance to terminate.
	// These policies are executed in the order that they are listed.
	//
	// For more information, see Controlling Which Instances Auto Scaling Terminates
	// During Scale In (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html)
	// in the Auto Scaling User Guide.
	TerminationPolicies []*string `type:"list"`

	// A comma-separated list of subnet identifiers for your virtual private cloud
	// (VPC).
	//
	// If you specify subnets and Availability Zones with this call, ensure that
	// the subnets' Availability Zones match the Availability Zones specified.
	//
	// For more information, see Launching Auto Scaling Instances in a VPC (http://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-in-vpc.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	VPCZoneIdentifier *string `min:"1" type:"string"`
}

// String returns the string representation
func (s CreateAutoScalingGroupInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateAutoScalingGroupInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateAutoScalingGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateAutoScalingGroupInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.AvailabilityZones != nil && len(s.AvailabilityZones) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AvailabilityZones", 1))
	}
	if s.HealthCheckType != nil && len(*s.HealthCheckType) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("HealthCheckType", 1))
	}
	if s.InstanceId != nil && len(*s.InstanceId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("InstanceId", 1))
	}
	if s.LaunchConfigurationName != nil && len(*s.LaunchConfigurationName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LaunchConfigurationName", 1))
	}
	if s.MaxSize == nil {
		invalidParams.Add(request.NewErrParamRequired("MaxSize"))
	}
	if s.MinSize == nil {
		invalidParams.Add(request.NewErrParamRequired("MinSize"))
	}
	if s.PlacementGroup != nil && len(*s.PlacementGroup) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("PlacementGroup", 1))
	}
	if s.ServiceLinkedRoleARN != nil && len(*s.ServiceLinkedRoleARN) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ServiceLinkedRoleARN", 1))
	}
	if s.VPCZoneIdentifier != nil && len(*s.VPCZoneIdentifier) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("VPCZoneIdentifier", 1))
	}
	if s.LaunchTemplate != nil {
		if err := s.LaunchTemplate.Validate(); err != nil {
			invalidParams.AddNested("LaunchTemplate", err.(request.ErrInvalidParams))
		}
	}
	if s.LifecycleHookSpecificationList != nil {
		for i, v := range s.LifecycleHookSpecificationList {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "LifecycleHookSpecificationList", i), err.(request.ErrInvalidParams))
			}
		}
	}
	if s.MixedInstancesPolicy != nil {
		if err := s.MixedInstancesPolicy.Validate(); err != nil {
			invalidParams.AddNested("MixedInstancesPolicy", err.(request.ErrInvalidParams))
		}
	}
	if s.Tags != nil {
		for i, v := range s.Tags {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *CreateAutoScalingGroupInput) SetAutoScalingGroupName(v string) *CreateAutoScalingGroupInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetAvailabilityZones sets the AvailabilityZones field's value.
func (s *CreateAutoScalingGroupInput) SetAvailabilityZones(v []*string) *CreateAutoScalingGroupInput {
	s.AvailabilityZones = v
	return s
}

// SetDefaultCooldown sets the DefaultCooldown field's value.
func (s *CreateAutoScalingGroupInput) SetDefaultCooldown(v int64) *CreateAutoScalingGroupInput {
	s.DefaultCooldown = &v
	return s
}

// SetDesiredCapacity sets the DesiredCapacity field's value.
func (s *CreateAutoScalingGroupInput) SetDesiredCapacity(v int64) *CreateAutoScalingGroupInput {
	s.DesiredCapacity = &v
	return s
}

// SetHealthCheckGracePeriod sets the HealthCheckGracePeriod field's value.
func (s *CreateAutoScalingGroupInput) SetHealthCheckGracePeriod(v int64) *CreateAutoScalingGroupInput {
	s.HealthCheckGracePeriod = &v
	return s
}

// SetHealthCheckType sets the HealthCheckType field's value.
func (s *CreateAutoScalingGroupInput) SetHealthCheckType(v string) *CreateAutoScalingGroupInput {
	s.HealthCheckType = &v
	return s
}

// SetInstanceId sets the InstanceId field's value.
func (s *CreateAutoScalingGroupInput) SetInstanceId(v string) *CreateAutoScalingGroupInput {
	s.InstanceId = &v
	return s
}

// SetLaunchConfigurationName sets the LaunchConfigurationName field's value.
func (s *CreateAutoScalingGroupInput) SetLaunchConfigurationName(v string) *CreateAutoScalingGroupInput {
	s.LaunchConfigurationName = &v
	return s
}

// SetLaunchTemplate sets the LaunchTemplate field's value.
func (s *CreateAutoScalingGroupInput) SetLaunchTemplate(v *LaunchTemplateSpecification) *CreateAutoScalingGroupInput {
	s.LaunchTemplate = v
	return s
}

// SetLifecycleHookSpecificationList sets the LifecycleHookSpecificationList field's value.
func (s *CreateAutoScalingGroupInput) SetLifecycleHookSpecificationList(v []*LifecycleHookSpecification) *CreateAutoScalingGroupInput {
	s.LifecycleHookSpecificationList = v
	return s
}

// SetLoadBalancerNames sets the LoadBalancerNames field's value.
func (s *CreateAutoScalingGroupInput) SetLoadBalancerNames(v []*string) *CreateAutoScalingGroupInput {
	s.LoadBalancerNames = v
	return s
}

// SetMaxSize sets the MaxSize field's value.
func (s *CreateAutoScalingGroupInput) SetMaxSize(v int64) *CreateAutoScalingGroupInput {
	s.MaxSize = &v
	return s
}

// SetMinSize sets the MinSize field's value.
func (s *CreateAutoScalingGroupInput) SetMinSize(v int64) *CreateAutoScalingGroupInput {
	s.MinSize = &v
	return s
}

// SetMixedInstancesPolicy sets the MixedInstancesPolicy field's value.
func (s *CreateAutoScalingGroupInput) SetMixedInstancesPolicy(v *MixedInstancesPolicy) *CreateAutoScalingGroupInput {
	s.MixedInstancesPolicy = v
	return s
}

// SetNewInstancesProtectedFromScaleIn sets the NewInstancesProtectedFromScaleIn field's value.
func (s *CreateAutoScalingGroupInput) SetNewInstancesProtectedFromScaleIn(v bool) *CreateAutoScalingGroupInput {
	s.NewInstancesProtectedFromScaleIn = &v
	return s
}

// SetPlacementGroup sets the PlacementGroup field's value.
func (s *CreateAutoScalingGroupInput) SetPlacementGroup(v string) *CreateAutoScalingGroupInput {
	s.PlacementGroup = &v
	return s
}

// SetServiceLinkedRoleARN sets the ServiceLinkedRoleARN field's value.
func (s *CreateAutoScalingGroupInput) SetServiceLinkedRoleARN(v string) *CreateAutoScalingGroupInput {
	s.ServiceLinkedRoleARN = &v
	return s
}

// SetTags sets the Tags field's value.
func (s *CreateAutoScalingGroupInput) SetTags(v []*Tag) *CreateAutoScalingGroupInput {
	s.Tags = v
	return s
}

// SetTargetGroupARNs sets the TargetGroupARNs field's value.
func (s *CreateAutoScalingGroupInput) SetTargetGroupARNs(v []*string) *CreateAutoScalingGroupInput {
	s.TargetGroupARNs = v
	return s
}

// SetTerminationPolicies sets the TerminationPolicies field's value.
func (s *CreateAutoScalingGroupInput) SetTerminationPolicies(v []*string) *CreateAutoScalingGroupInput {
	s.TerminationPolicies = v
	return s
}

// SetVPCZoneIdentifier sets the VPCZoneIdentifier field's value.
func (s *CreateAutoScalingGroupInput) SetVPCZoneIdentifier(v string) *CreateAutoScalingGroupInput {
	s.VPCZoneIdentifier = &v
	return s
}

type CreateAutoScalingGroupOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CreateAutoScalingGroupOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateAutoScalingGroupOutput) GoString() string {
	return s.String()
}

type CreateLaunchConfigurationInput struct {
	_ struct{} `type:"structure"`

	// Used for groups that launch instances into a virtual private cloud (VPC).
	// Specifies whether to assign a public IP address to each instance. For more
	// information, see Launching Auto Scaling Instances in a VPC (http://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-in-vpc.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	//
	// If you specify this parameter, be sure to specify at least one subnet when
	// you create your group.
	//
	// Default: If the instance is launched into a default subnet, the default is
	// to assign a public IP address. If the instance is launched into a nondefault
	// subnet, the default is not to assign a public IP address.
	AssociatePublicIpAddress *bool `type:"boolean"`

	// One or more mappings that specify how block devices are exposed to the instance.
	// For more information, see Block Device Mapping (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/block-device-mapping-concepts.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	BlockDeviceMappings []*BlockDeviceMapping `type:"list"`

	// The ID of a ClassicLink-enabled VPC to link your EC2-Classic instances to.
	// This parameter is supported only if you are launching EC2-Classic instances.
	// For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	ClassicLinkVPCId *string `min:"1" type:"string"`

	// The IDs of one or more security groups for the specified ClassicLink-enabled
	// VPC. This parameter is required if you specify a ClassicLink-enabled VPC,
	// and is not supported otherwise. For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	ClassicLinkVPCSecurityGroups []*string `type:"list"`

	// Indicates whether the instance is optimized for Amazon EBS I/O. By default,
	// the instance is not optimized for EBS I/O. The optimization provides dedicated
	// throughput to Amazon EBS and an optimized configuration stack to provide
	// optimal I/O performance. This optimization is not available with all instance
	// types. Additional usage charges apply. For more information, see Amazon EBS-Optimized
	// Instances (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSOptimized.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	EbsOptimized *bool `type:"boolean"`

	// The name or the Amazon Resource Name (ARN) of the instance profile associated
	// with the IAM role for the instance.
	//
	// EC2 instances launched with an IAM role automatically have AWS security credentials
	// available. You can use IAM roles with Amazon EC2 Auto Scaling to automatically
	// enable applications running on your EC2 instances to securely access other
	// AWS resources. For more information, see Launch Auto Scaling Instances with
	// an IAM Role (http://docs.aws.amazon.com/autoscaling/ec2/userguide/us-iam-role.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	IamInstanceProfile *string `min:"1" type:"string"`

	// The ID of the Amazon Machine Image (AMI) to use to launch your EC2 instances.
	//
	// If you do not specify InstanceId, you must specify ImageId.
	//
	// For more information, see Finding an AMI (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/finding-an-ami.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	ImageId *string `min:"1" type:"string"`

	// The ID of the instance to use to create the launch configuration. The new
	// launch configuration derives attributes from the instance, except for the
	// block device mapping.
	//
	// If you do not specify InstanceId, you must specify both ImageId and InstanceType.
	//
	// To create a launch configuration with a block device mapping or override
	// any other instance attributes, specify them as part of the same request.
	//
	// For more information, see Create a Launch Configuration Using an EC2 Instance
	// (http://docs.aws.amazon.com/autoscaling/ec2/userguide/create-lc-with-instanceID.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	InstanceId *string `min:"1" type:"string"`

	// Enables detailed monitoring (true) or basic monitoring (false) for the Auto
	// Scaling instances. The default is true.
	InstanceMonitoring *InstanceMonitoring `type:"structure"`

	// The instance type of the EC2 instance.
	//
	// If you do not specify InstanceId, you must specify InstanceType.
	//
	// For information about available instance types, see Available Instance Types
	// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#AvailableInstanceTypes)
	// in the Amazon Elastic Compute Cloud User Guide.
	InstanceType *string `min:"1" type:"string"`

	// The ID of the kernel associated with the AMI.
	KernelId *string `min:"1" type:"string"`

	// The name of the key pair. For more information, see Amazon EC2 Key Pairs
	// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html) in
	// the Amazon Elastic Compute Cloud User Guide.
	KeyName *string `min:"1" type:"string"`

	// The name of the launch configuration. This name must be unique within the
	// scope of your AWS account.
	//
	// LaunchConfigurationName is a required field
	LaunchConfigurationName *string `min:"1" type:"string" required:"true"`

	// The tenancy of the instance. An instance with a tenancy of dedicated runs
	// on single-tenant hardware and can only be launched into a VPC.
	//
	// To launch Dedicated Instances into a shared tenancy VPC (a VPC with the instance
	// placement tenancy attribute set to default), you must set the value of this
	// parameter to dedicated.
	//
	// If you specify this parameter, be sure to specify at least one subnet when
	// you create your group.
	//
	// For more information, see Launching Auto Scaling Instances in a VPC (http://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-in-vpc.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	//
	// Valid values: default | dedicated
	PlacementTenancy *string `min:"1" type:"string"`

	// The ID of the RAM disk associated with the AMI.
	RamdiskId *string `min:"1" type:"string"`

	// One or more security groups with which to associate the instances.
	//
	// If your instances are launched in EC2-Classic, you can either specify security
	// group names or the security group IDs. For more information, see Amazon EC2
	// Security Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	//
	// If your instances are launched into a VPC, specify security group IDs. For
	// more information, see Security Groups for Your VPC (http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_SecurityGroups.html)
	// in the Amazon Virtual Private Cloud User Guide.
	SecurityGroups []*string `type:"list"`

	// The maximum hourly price to be paid for any Spot Instance launched to fulfill
	// the request. Spot Instances are launched when the price you specify exceeds
	// the current Spot market price. For more information, see Launching Spot Instances
	// in Your Auto Scaling Group (http://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-launch-spot-instances.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	SpotPrice *string `min:"1" type:"string"`

	// The user data to make available to the launched EC2 instances. For more information,
	// see Instance Metadata and User Data (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	UserData *string `type:"string"`
}

// String returns the string representation
func (s CreateLaunchConfigurationInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLaunchConfigurationInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateLaunchConfigurationInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateLaunchConfigurationInput"}
	if s.ClassicLinkVPCId != nil && len(*s.ClassicLinkVPCId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ClassicLinkVPCId", 1))
	}
	if s.IamInstanceProfile != nil && len(*s.IamInstanceProfile) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("IamInstanceProfile", 1))
	}
	if s.ImageId != nil && len(*s.ImageId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ImageId", 1))
	}
	if s.InstanceId != nil && len(*s.InstanceId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("InstanceId", 1))
	}
	if s.InstanceType != nil && len(*s.InstanceType) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("InstanceType", 1))
	}
	if s.KernelId != nil && len(*s.KernelId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("KernelId", 1))
	}
	if s.KeyName != nil && len(*s.KeyName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("KeyName", 1))
	}
	if s.LaunchConfigurationName == nil {
		invalidParams.Add(request.NewErrParamRequired("LaunchConfigurationName"))
	}
	if s.LaunchConfigurationName != nil && len(*s.LaunchConfigurationName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LaunchConfigurationName", 1))
	}
	if s.PlacementTenancy != nil && len(*s.PlacementTenancy) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("PlacementTenancy", 1))
	}
	if s.RamdiskId != nil && len(*s.RamdiskId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("RamdiskId", 1))
	}
	if s.SpotPrice != nil && len(*s.SpotPrice) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("SpotPrice", 1))
	}
	if s.BlockDeviceMappings != nil {
		for i, v := range s.BlockDeviceMappings {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "BlockDeviceMappings", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAssociatePublicIpAddress sets the AssociatePublicIpAddress field's value.
func (s *CreateLaunchConfigurationInput) SetAssociatePublicIpAddress(v bool) *CreateLaunchConfigurationInput {
	s.AssociatePublicIpAddress = &v
	return s
}

// SetBlockDeviceMappings sets the BlockDeviceMappings field's value.
func (s *CreateLaunchConfigurationInput) SetBlockDeviceMappings(v []*BlockDeviceMapping) *CreateLaunchConfigurationInput {
	s.BlockDeviceMappings = v
	return s
}

// SetClassicLinkVPCId sets the ClassicLinkVPCId field's value.
func (s *CreateLaunchConfigurationInput) SetClassicLinkVPCId(v string) *CreateLaunchConfigurationInput {
	s.ClassicLinkVPCId = &v
	return s
}

// SetClassicLinkVPCSecurityGroups sets the ClassicLinkVPCSecurityGroups field's value.
func (s *CreateLaunchConfigurationInput) SetClassicLinkVPCSecurityGroups(v []*string) *CreateLaunchConfigurationInput {
	s.ClassicLinkVPCSecurityGroups = v
	return s
}

// SetEbsOptimized sets the EbsOptimized field's value.
func (s *CreateLaunchConfigurationInput) SetEbsOptimized(v bool) *CreateLaunchConfigurationInput {
	s.EbsOptimized = &v
	return s
}

// SetIamInstanceProfile sets the IamInstanceProfile field's value.
func (s *CreateLaunchConfigurationInput) SetIamInstanceProfile(v string) *CreateLaunchConfigurationInput {
	s.IamInstanceProfile = &v
	return s
}

// SetImageId sets the ImageId field's value.
func (s *CreateLaunchConfigurationInput) SetImageId(v string) *CreateLaunchConfigurationInput {
	s.ImageId = &v
	return s
}

// SetInstanceId sets the InstanceId field's value.
func (s *CreateLaunchConfigurationInput) SetInstanceId(v string) *CreateLaunchConfigurationInput {
	s.InstanceId = &v
	return s
}

// SetInstanceMonitoring sets the InstanceMonitoring field's value.
func (s *CreateLaunchConfigurationInput) SetInstanceMonitoring(v *InstanceMonitoring) *CreateLaunchConfigurationInput {
	s.InstanceMonitoring = v
	return s
}

// SetInstanceType sets the InstanceType field's value.
func (s *CreateLaunchConfigurationInput) SetInstanceType(v string) *CreateLaunchConfigurationInput {
	s.InstanceType = &v
	return s
}

// SetKernelId sets the KernelId field's value.
func (s *CreateLaunchConfigurationInput) SetKernelId(v string) *CreateLaunchConfigurationInput {
	s.KernelId = &v
	return s
}

// SetKeyName sets the KeyName field's value.
func (s *CreateLaunchConfigurationInput) SetKeyName(v string) *CreateLaunchConfigurationInput {
	s.KeyName = &v
	return s
}

// SetLaunchConfigurationName sets the LaunchConfigurationName field's value.
func (s *CreateLaunchConfigurationInput) SetLaunchConfigurationName(v string) *CreateLaunchConfigurationInput {
	s.LaunchConfigurationName = &v
	return s
}

// SetPlacementTenancy sets the PlacementTenancy field's value.
func (s *CreateLaunchConfigurationInput) SetPlacementTenancy(v string) *CreateLaunchConfigurationInput {
	s.PlacementTenancy = &v
	return s
}

// SetRamdiskId sets the RamdiskId field's value.
func (s *CreateLaunchConfigurationInput) SetRamdiskId(v string) *CreateLaunchConfigurationInput {
	s.RamdiskId = &v
	return s
}

// SetSecurityGroups sets the SecurityGroups field's value.
func (s *CreateLaunchConfigurationInput) SetSecurityGroups(v []*string) *CreateLaunchConfigurationInput {
	s.SecurityGroups = v
	return s
}

// SetSpotPrice sets the SpotPrice field's value.
func (s *CreateLaunchConfigurationInput) SetSpotPrice(v string) *CreateLaunchConfigurationInput {
	s.SpotPrice = &v
	return s
}

// SetUserData sets the UserData field's value.
func (s *CreateLaunchConfigurationInput) SetUserData(v string) *CreateLaunchConfigurationInput {
	s.UserData = &v
	return s
}

type CreateLaunchConfigurationOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CreateLaunchConfigurationOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLaunchConfigurationOutput) GoString() string {
	return s.String()
}

type CreateOrUpdateTagsInput struct {
	_ struct{} `type:"structure"`

	// One or more tags.
	//
	// Tags is a required field
	Tags []*Tag `type:"list" required:"true"`
}

// String returns the string representation
func (s CreateOrUpdateTagsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateOrUpdateTagsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateOrUpdateTagsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateOrUpdateTagsInput"}
	if s.Tags == nil {
		invalidParams.Add(request.NewErrParamRequired("Tags"))
	}
	if s.Tags != nil {
		for i, v := range s.Tags {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetTags sets the Tags field's value.
func (s *CreateOrUpdateTagsInput) SetTags(v []*Tag) *CreateOrUpdateTagsInput {
	s.Tags = v
	return s
}

type CreateOrUpdateTagsOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CreateOrUpdateTagsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateOrUpdateTagsOutput) GoString() string {
	return s.String()
}

// Configures a customized metric for a target tracking policy.
type CustomizedMetricSpecification struct {
	_ struct{} `type:"structure"`

	// The dimensions of the metric.
	Dimensions []*MetricDimension `type:"list"`

	// The name of the metric.
	//
	// MetricName is a required field
	MetricName *string `type:"string" required:"true"`

	// The namespace of the metric.
	//
	// Namespace is a required field
	Namespace *string `type:"string" required:"true"`

	// The statistic of the metric.
	//
	// Statistic is a required field
	Statistic *string `type:"string" required:"true" enum:"MetricStatistic"`

	// The unit of the metric.
	Unit *string `type:"string"`
}

// String returns the string representation
func (s CustomizedMetricSpecification) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CustomizedMetricSpecification) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CustomizedMetricSpecification) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CustomizedMetricSpecification"}
	if s.MetricName == nil {
		invalidParams.Add(request.NewErrParamRequired("MetricName"))
	}
	if s.Namespace == nil {
		invalidParams.Add(request.NewErrParamRequired("Namespace"))
	}
	if s.Statistic == nil {
		invalidParams.Add(request.NewErrParamRequired("Statistic"))
	}
	if s.Dimensions != nil {
		for i, v := range s.Dimensions {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Dimensions", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetDimensions sets the Dimensions field's value.
func (s *CustomizedMetricSpecification) SetDimensions(v []*MetricDimension) *CustomizedMetricSpecification {
	s.Dimensions = v
	return s
}

// SetMetricName sets the MetricName field's value.
func (s *CustomizedMetricSpecification) SetMetricName(v string) *CustomizedMetricSpecification {
	s.MetricName = &v
	return s
}

// SetNamespace sets the Namespace field's value.
func (s *CustomizedMetricSpecification) SetNamespace(v string) *CustomizedMetricSpecification {
	s.Namespace = &v
	return s
}

// SetStatistic sets the Statistic field's value.
func (s *CustomizedMetricSpecification) SetStatistic(v string) *CustomizedMetricSpecification {
	s.Statistic = &v
	return s
}

// SetUnit sets the Unit field's value.
func (s *CustomizedMetricSpecification) SetUnit(v string) *CustomizedMetricSpecification {
	s.Unit = &v
	return s
}

type DeleteAutoScalingGroupInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// Specifies that the group is to be deleted along with all instances associated
	// with the group, without waiting for all instances to be terminated. This
	// parameter also deletes any lifecycle actions associated with the group.
	ForceDelete *bool `type:"boolean"`
}

// String returns the string representation
func (s DeleteAutoScalingGroupInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteAutoScalingGroupInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteAutoScalingGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteAutoScalingGroupInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DeleteAutoScalingGroupInput) SetAutoScalingGroupName(v string) *DeleteAutoScalingGroupInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetForceDelete sets the ForceDelete field's value.
func (s *DeleteAutoScalingGroupInput) SetForceDelete(v bool) *DeleteAutoScalingGroupInput {
	s.ForceDelete = &v
	return s
}

type DeleteAutoScalingGroupOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteAutoScalingGroupOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteAutoScalingGroupOutput) GoString() string {
	return s.String()
}

type DeleteLaunchConfigurationInput struct {
	_ struct{} `type:"structure"`

	// The name of the launch configuration.
	//
	// LaunchConfigurationName is a required field
	LaunchConfigurationName *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteLaunchConfigurationInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLaunchConfigurationInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteLaunchConfigurationInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteLaunchConfigurationInput"}
	if s.LaunchConfigurationName == nil {
		invalidParams.Add(request.NewErrParamRequired("LaunchConfigurationName"))
	}
	if s.LaunchConfigurationName != nil && len(*s.LaunchConfigurationName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LaunchConfigurationName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLaunchConfigurationName sets the LaunchConfigurationName field's value.
func (s *DeleteLaunchConfigurationInput) SetLaunchConfigurationName(v string) *DeleteLaunchConfigurationInput {
	s.LaunchConfigurationName = &v
	return s
}

type DeleteLaunchConfigurationOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteLaunchConfigurationOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLaunchConfigurationOutput) GoString() string {
	return s.String()
}

type DeleteLifecycleHookInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The name of the lifecycle hook.
	//
	// LifecycleHookName is a required field
	LifecycleHookName *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteLifecycleHookInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLifecycleHookInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteLifecycleHookInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteLifecycleHookInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.LifecycleHookName == nil {
		invalidParams.Add(request.NewErrParamRequired("LifecycleHookName"))
	}
	if s.LifecycleHookName != nil && len(*s.LifecycleHookName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LifecycleHookName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DeleteLifecycleHookInput) SetAutoScalingGroupName(v string) *DeleteLifecycleHookInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetLifecycleHookName sets the LifecycleHookName field's value.
func (s *DeleteLifecycleHookInput) SetLifecycleHookName(v string) *DeleteLifecycleHookInput {
	s.LifecycleHookName = &v
	return s
}

type DeleteLifecycleHookOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteLifecycleHookOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLifecycleHookOutput) GoString() string {
	return s.String()
}

type DeleteNotificationConfigurationInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The Amazon Resource Name (ARN) of the Amazon Simple Notification Service
	// (Amazon SNS) topic.
	//
	// TopicARN is a required field
	TopicARN *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteNotificationConfigurationInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteNotificationConfigurationInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteNotificationConfigurationInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteNotificationConfigurationInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.TopicARN == nil {
		invalidParams.Add(request.NewErrParamRequired("TopicARN"))
	}
	if s.TopicARN != nil && len(*s.TopicARN) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("TopicARN", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DeleteNotificationConfigurationInput) SetAutoScalingGroupName(v string) *DeleteNotificationConfigurationInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetTopicARN sets the TopicARN field's value.
func (s *DeleteNotificationConfigurationInput) SetTopicARN(v string) *DeleteNotificationConfigurationInput {
	s.TopicARN = &v
	return s
}

type DeleteNotificationConfigurationOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteNotificationConfigurationOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteNotificationConfigurationOutput) GoString() string {
	return s.String()
}

type DeletePolicyInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	AutoScalingGroupName *string `min:"1" type:"string"`

	// The name or Amazon Resource Name (ARN) of the policy.
	//
	// PolicyName is a required field
	PolicyName *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeletePolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeletePolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeletePolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeletePolicyInput"}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.PolicyName == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyName"))
	}
	if s.PolicyName != nil && len(*s.PolicyName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("PolicyName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DeletePolicyInput) SetAutoScalingGroupName(v string) *DeletePolicyInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *DeletePolicyInput) SetPolicyName(v string) *DeletePolicyInput {
	s.PolicyName = &v
	return s
}

type DeletePolicyOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeletePolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeletePolicyOutput) GoString() string {
	return s.String()
}

type DeleteScheduledActionInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The name of the action to delete.
	//
	// ScheduledActionName is a required field
	ScheduledActionName *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteScheduledActionInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteScheduledActionInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteScheduledActionInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteScheduledActionInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.ScheduledActionName == nil {
		invalidParams.Add(request.NewErrParamRequired("ScheduledActionName"))
	}
	if s.ScheduledActionName != nil && len(*s.ScheduledActionName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ScheduledActionName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DeleteScheduledActionInput) SetAutoScalingGroupName(v string) *DeleteScheduledActionInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetScheduledActionName sets the ScheduledActionName field's value.
func (s *DeleteScheduledActionInput) SetScheduledActionName(v string) *DeleteScheduledActionInput {
	s.ScheduledActionName = &v
	return s
}

type DeleteScheduledActionOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteScheduledActionOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteScheduledActionOutput) GoString() string {
	return s.String()
}

type DeleteTagsInput struct {
	_ struct{} `type:"structure"`

	// One or more tags.
	//
	// Tags is a required field
	Tags []*Tag `type:"list" required:"true"`
}

// String returns the string representation
func (s DeleteTagsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteTagsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteTagsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteTagsInput"}
	if s.Tags == nil {
		invalidParams.Add(request.NewErrParamRequired("Tags"))
	}
	if s.Tags != nil {
		for i, v := range s.Tags {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetTags sets the Tags field's value.
func (s *DeleteTagsInput) SetTags(v []*Tag) *DeleteTagsInput {
	s.Tags = v
	return s
}

type DeleteTagsOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteTagsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteTagsOutput) GoString() string {
	return s.String()
}

type DescribeAccountLimitsInput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DescribeAccountLimitsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAccountLimitsInput) GoString() string {
	return s.String()
}

type DescribeAccountLimitsOutput struct {
	_ struct{} `type:"structure"`

	// The maximum number of groups allowed for your AWS account. The default limit
	// is 20 per region.
	MaxNumberOfAutoScalingGroups *int64 `type:"integer"`

	// The maximum number of launch configurations allowed for your AWS account.
	// The default limit is 100 per region.
	MaxNumberOfLaunchConfigurations *int64 `type:"integer"`

	// The current number of groups for your AWS account.
	NumberOfAutoScalingGroups *int64 `type:"integer"`

	// The current number of launch configurations for your AWS account.
	NumberOfLaunchConfigurations *int64 `type:"integer"`
}

// String returns the string representation
func (s DescribeAccountLimitsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAccountLimitsOutput) GoString() string {
	return s.String()
}

// SetMaxNumberOfAutoScalingGroups sets the MaxNumberOfAutoScalingGroups field's value.
func (s *DescribeAccountLimitsOutput) SetMaxNumberOfAutoScalingGroups(v int64) *DescribeAccountLimitsOutput {
	s.MaxNumberOfAutoScalingGroups = &v
	return s
}

// SetMaxNumberOfLaunchConfigurations sets the MaxNumberOfLaunchConfigurations field's value.
func (s *DescribeAccountLimitsOutput) SetMaxNumberOfLaunchConfigurations(v int64) *DescribeAccountLimitsOutput {
	s.MaxNumberOfLaunchConfigurations = &v
	return s
}

// SetNumberOfAutoScalingGroups sets the NumberOfAutoScalingGroups field's value.
func (s *DescribeAccountLimitsOutput) SetNumberOfAutoScalingGroups(v int64) *DescribeAccountLimitsOutput {
	s.NumberOfAutoScalingGroups = &v
	return s
}

// SetNumberOfLaunchConfigurations sets the NumberOfLaunchConfigurations field's value.
func (s *DescribeAccountLimitsOutput) SetNumberOfLaunchConfigurations(v int64) *DescribeAccountLimitsOutput {
	s.NumberOfLaunchConfigurations = &v
	return s
}

type DescribeAdjustmentTypesInput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DescribeAdjustmentTypesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAdjustmentTypesInput) GoString() string {
	return s.String()
}

type DescribeAdjustmentTypesOutput struct {
	_ struct{} `type:"structure"`

	// The policy adjustment types.
	AdjustmentTypes []*AdjustmentType `type:"list"`
}

// String returns the string representation
func (s DescribeAdjustmentTypesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAdjustmentTypesOutput) GoString() string {
	return s.String()
}

// SetAdjustmentTypes sets the AdjustmentTypes field's value.
func (s *DescribeAdjustmentTypesOutput) SetAdjustmentTypes(v []*AdjustmentType) *DescribeAdjustmentTypesOutput {
	s.AdjustmentTypes = v
	return s
}

type DescribeAutoScalingGroupsInput struct {
	_ struct{} `type:"structure"`

	// The names of the Auto Scaling groups. You can specify up to MaxRecords names.
	// If you omit this parameter, all Auto Scaling groups are described.
	AutoScalingGroupNames []*string `type:"list"`

	// The maximum number of items to return with this call. The default value is
	// 50 and the maximum value is 100.
	MaxRecords *int64 `type:"integer"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeAutoScalingGroupsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAutoScalingGroupsInput) GoString() string {
	return s.String()
}

// SetAutoScalingGroupNames sets the AutoScalingGroupNames field's value.
func (s *DescribeAutoScalingGroupsInput) SetAutoScalingGroupNames(v []*string) *DescribeAutoScalingGroupsInput {
	s.AutoScalingGroupNames = v
	return s
}

// SetMaxRecords sets the MaxRecords field's value.
func (s *DescribeAutoScalingGroupsInput) SetMaxRecords(v int64) *DescribeAutoScalingGroupsInput {
	s.MaxRecords = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeAutoScalingGroupsInput) SetNextToken(v string) *DescribeAutoScalingGroupsInput {
	s.NextToken = &v
	return s
}

type DescribeAutoScalingGroupsOutput struct {
	_ struct{} `type:"structure"`

	// The groups.
	//
	// AutoScalingGroups is a required field
	AutoScalingGroups []*Group `type:"list" required:"true"`

	// The token to use when requesting the next set of items. If there are no additional
	// items to return, the string is empty.
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeAutoScalingGroupsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAutoScalingGroupsOutput) GoString() string {
	return s.String()
}

// SetAutoScalingGroups sets the AutoScalingGroups field's value.
func (s *DescribeAutoScalingGroupsOutput) SetAutoScalingGroups(v []*Group) *DescribeAutoScalingGroupsOutput {
	s.AutoScalingGroups = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeAutoScalingGroupsOutput) SetNextToken(v string) *DescribeAutoScalingGroupsOutput {
	s.NextToken = &v
	return s
}

type DescribeAutoScalingInstancesInput struct {
	_ struct{} `type:"structure"`

	// The IDs of the instances. You can specify up to MaxRecords IDs. If you omit
	// this parameter, all Auto Scaling instances are described. If you specify
	// an ID that does not exist, it is ignored with no error.
	InstanceIds []*string `type:"list"`

	// The maximum number of items to return with this call. The default value is
	// 50 and the maximum value is 50.
	MaxRecords *int64 `type:"integer"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeAutoScalingInstancesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAutoScalingInstancesInput) GoString() string {
	return s.String()
}

// SetInstanceIds sets the InstanceIds field's value.
func (s *DescribeAutoScalingInstancesInput) SetInstanceIds(v []*string) *DescribeAutoScalingInstancesInput {
	s.InstanceIds = v
	return s
}

// SetMaxRecords sets the MaxRecords field's value.
func (s *DescribeAutoScalingInstancesInput) SetMaxRecords(v int64) *DescribeAutoScalingInstancesInput {
	s.MaxRecords = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeAutoScalingInstancesInput) SetNextToken(v string) *DescribeAutoScalingInstancesInput {
	s.NextToken = &v
	return s
}

type DescribeAutoScalingInstancesOutput struct {
	_ struct{} `type:"structure"`

	// The instances.
	AutoScalingInstances []*InstanceDetails `type:"list"`

	// The token to use when requesting the next set of items. If there are no additional
	// items to return, the string is empty.
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeAutoScalingInstancesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAutoScalingInstancesOutput) GoString() string {
	return s.String()
}

// SetAutoScalingInstances sets the AutoScalingInstances field's value.
func (s *DescribeAutoScalingInstancesOutput) SetAutoScalingInstances(v []*InstanceDetails) *DescribeAutoScalingInstancesOutput {
	s.AutoScalingInstances = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeAutoScalingInstancesOutput) SetNextToken(v string) *DescribeAutoScalingInstancesOutput {
	s.NextToken = &v
	return s
}

type DescribeAutoScalingNotificationTypesInput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DescribeAutoScalingNotificationTypesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAutoScalingNotificationTypesInput) GoString() string {
	return s.String()
}

type DescribeAutoScalingNotificationTypesOutput struct {
	_ struct{} `type:"structure"`

	// The notification types.
	AutoScalingNotificationTypes []*string `type:"list"`
}

// String returns the string representation
func (s DescribeAutoScalingNotificationTypesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAutoScalingNotificationTypesOutput) GoString() string {
	return s.String()
}

// SetAutoScalingNotificationTypes sets the AutoScalingNotificationTypes field's value.
func (s *DescribeAutoScalingNotificationTypesOutput) SetAutoScalingNotificationTypes(v []*string) *DescribeAutoScalingNotificationTypesOutput {
	s.AutoScalingNotificationTypes = v
	return s
}

type DescribeLaunchConfigurationsInput struct {
	_ struct{} `type:"structure"`

	// The launch configuration names. If you omit this parameter, all launch configurations
	// are described.
	LaunchConfigurationNames []*string `type:"list"`

	// The maximum number of items to return with this call. The default value is
	// 50 and the maximum value is 100.
	MaxRecords *int64 `type:"integer"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeLaunchConfigurationsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLaunchConfigurationsInput) GoString() string {
	return s.String()
}

// SetLaunchConfigurationNames sets the LaunchConfigurationNames field's value.
func (s *DescribeLaunchConfigurationsInput) SetLaunchConfigurationNames(v []*string) *DescribeLaunchConfigurationsInput {
	s.LaunchConfigurationNames = v
	return s
}

// SetMaxRecords sets the MaxRecords field's value.
func (s *DescribeLaunchConfigurationsInput) SetMaxRecords(v int64) *DescribeLaunchConfigurationsInput {
	s.MaxRecords = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeLaunchConfigurationsInput) SetNextToken(v string) *DescribeLaunchConfigurationsInput {
	s.NextToken = &v
	return s
}

type DescribeLaunchConfigurationsOutput struct {
	_ struct{} `type:"structure"`

	// The launch configurations.
	//
	// LaunchConfigurations is a required field
	LaunchConfigurations []*LaunchConfiguration `type:"list" required:"true"`

	// The token to use when requesting the next set of items. If there are no additional
	// items to return, the string is empty.
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeLaunchConfigurationsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLaunchConfigurationsOutput) GoString() string {
	return s.String()
}

// SetLaunchConfigurations sets the LaunchConfigurations field's value.
func (s *DescribeLaunchConfigurationsOutput) SetLaunchConfigurations(v []*LaunchConfiguration) *DescribeLaunchConfigurationsOutput {
	s.LaunchConfigurations = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeLaunchConfigurationsOutput) SetNextToken(v string) *DescribeLaunchConfigurationsOutput {
	s.NextToken = &v
	return s
}

type DescribeLifecycleHookTypesInput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DescribeLifecycleHookTypesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLifecycleHookTypesInput) GoString() string {
	return s.String()
}

type DescribeLifecycleHookTypesOutput struct {
	_ struct{} `type:"structure"`

	// The lifecycle hook types.
	LifecycleHookTypes []*string `type:"list"`
}

// String returns the string representation
func (s DescribeLifecycleHookTypesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLifecycleHookTypesOutput) GoString() string {
	return s.String()
}

// SetLifecycleHookTypes sets the LifecycleHookTypes field's value.
func (s *DescribeLifecycleHookTypesOutput) SetLifecycleHookTypes(v []*string) *DescribeLifecycleHookTypesOutput {
	s.LifecycleHookTypes = v
	return s
}

type DescribeLifecycleHooksInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The names of one or more lifecycle hooks. If you omit this parameter, all
	// lifecycle hooks are described.
	LifecycleHookNames []*string `type:"list"`
}

// String returns the string representation
func (s DescribeLifecycleHooksInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLifecycleHooksInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeLifecycleHooksInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeLifecycleHooksInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DescribeLifecycleHooksInput) SetAutoScalingGroupName(v string) *DescribeLifecycleHooksInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetLifecycleHookNames sets the LifecycleHookNames field's value.
func (s *DescribeLifecycleHooksInput) SetLifecycleHookNames(v []*string) *DescribeLifecycleHooksInput {
	s.LifecycleHookNames = v
	return s
}

type DescribeLifecycleHooksOutput struct {
	_ struct{} `type:"structure"`

	// The lifecycle hooks for the specified group.
	LifecycleHooks []*LifecycleHook `type:"list"`
}

// String returns the string representation
func (s DescribeLifecycleHooksOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLifecycleHooksOutput) GoString() string {
	return s.String()
}

// SetLifecycleHooks sets the LifecycleHooks field's value.
func (s *DescribeLifecycleHooksOutput) SetLifecycleHooks(v []*LifecycleHook) *DescribeLifecycleHooksOutput {
	s.LifecycleHooks = v
	return s
}

type DescribeLoadBalancerTargetGroupsInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The maximum number of items to return with this call. The default value is
	// 100 and the maximum value is 100.
	MaxRecords *int64 `type:"integer"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeLoadBalancerTargetGroupsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancerTargetGroupsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeLoadBalancerTargetGroupsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeLoadBalancerTargetGroupsInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DescribeLoadBalancerTargetGroupsInput) SetAutoScalingGroupName(v string) *DescribeLoadBalancerTargetGroupsInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetMaxRecords sets the MaxRecords field's value.
func (s *DescribeLoadBalancerTargetGroupsInput) SetMaxRecords(v int64) *DescribeLoadBalancerTargetGroupsInput {
	s.MaxRecords = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeLoadBalancerTargetGroupsInput) SetNextToken(v string) *DescribeLoadBalancerTargetGroupsInput {
	s.NextToken = &v
	return s
}

type DescribeLoadBalancerTargetGroupsOutput struct {
	_ struct{} `type:"structure"`

	// Information about the target groups.
	LoadBalancerTargetGroups []*LoadBalancerTargetGroupState `type:"list"`

	// The token to use when requesting the next set of items. If there are no additional
	// items to return, the string is empty.
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeLoadBalancerTargetGroupsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancerTargetGroupsOutput) GoString() string {
	return s.String()
}

// SetLoadBalancerTargetGroups sets the LoadBalancerTargetGroups field's value.
func (s *DescribeLoadBalancerTargetGroupsOutput) SetLoadBalancerTargetGroups(v []*LoadBalancerTargetGroupState) *DescribeLoadBalancerTargetGroupsOutput {
	s.LoadBalancerTargetGroups = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeLoadBalancerTargetGroupsOutput) SetNextToken(v string) *DescribeLoadBalancerTargetGroupsOutput {
	s.NextToken = &v
	return s
}

type DescribeLoadBalancersInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The maximum number of items to return with this call. The default value is
	// 100 and the maximum value is 100.
	MaxRecords *int64 `type:"integer"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeLoadBalancersInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancersInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeLoadBalancersInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeLoadBalancersInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DescribeLoadBalancersInput) SetAutoScalingGroupName(v string) *DescribeLoadBalancersInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetMaxRecords sets the MaxRecords field's value.
func (s *DescribeLoadBalancersInput) SetMaxRecords(v int64) *DescribeLoadBalancersInput {
	s.MaxRecords = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeLoadBalancersInput) SetNextToken(v string) *DescribeLoadBalancersInput {
	s.NextToken = &v
	return s
}

type DescribeLoadBalancersOutput struct {
	_ struct{} `type:"structure"`

	// The load balancers.
	LoadBalancers []*LoadBalancerState `type:"list"`

	// The token to use when requesting the next set of items. If there are no additional
	// items to return, the string is empty.
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeLoadBalancersOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancersOutput) GoString() string {
	return s.String()
}

// SetLoadBalancers sets the LoadBalancers field's value.
func (s *DescribeLoadBalancersOutput) SetLoadBalancers(v []*LoadBalancerState) *DescribeLoadBalancersOutput {
	s.LoadBalancers = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeLoadBalancersOutput) SetNextToken(v string) *DescribeLoadBalancersOutput {
	s.NextToken = &v
	return s
}

type DescribeMetricCollectionTypesInput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DescribeMetricCollectionTypesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeMetricCollectionTypesInput) GoString() string {
	return s.String()
}

type DescribeMetricCollectionTypesOutput struct {
	_ struct{} `type:"structure"`

	// The granularities for the metrics.
	Granularities []*MetricGranularityType `type:"list"`

	// One or more metrics.
	Metrics []*MetricCollectionType `type:"list"`
}

// String returns the string representation
func (s DescribeMetricCollectionTypesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeMetricCollectionTypesOutput) GoString() string {
	return s.String()
}

// SetGranularities sets the Granularities field's value.
func (s *DescribeMetricCollectionTypesOutput) SetGranularities(v []*MetricGranularityType) *DescribeMetricCollectionTypesOutput {
	s.Granularities = v
	return s
}

// SetMetrics sets the Metrics field's value.
func (s *DescribeMetricCollectionTypesOutput) SetMetrics(v []*MetricCollectionType) *DescribeMetricCollectionTypesOutput {
	s.Metrics = v
	return s
}

type DescribeNotificationConfigurationsInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	AutoScalingGroupNames []*string `type:"list"`

	// The maximum number of items to return with this call. The default value is
	// 50 and the maximum value is 100.
	MaxRecords *int64 `type:"integer"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeNotificationConfigurationsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeNotificationConfigurationsInput) GoString() string {
	return s.String()
}

// SetAutoScalingGroupNames sets the AutoScalingGroupNames field's value.
func (s *DescribeNotificationConfigurationsInput) SetAutoScalingGroupNames(v []*string) *DescribeNotificationConfigurationsInput {
	s.AutoScalingGroupNames = v
	return s
}

// SetMaxRecords sets the MaxRecords field's value.
func (s *DescribeNotificationConfigurationsInput) SetMaxRecords(v int64) *DescribeNotificationConfigurationsInput {
	s.MaxRecords = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeNotificationConfigurationsInput) SetNextToken(v string) *DescribeNotificationConfigurationsInput {
	s.NextToken = &v
	return s
}

type DescribeNotificationConfigurationsOutput struct {
	_ struct{} `type:"structure"`

	// The token to use when requesting the next set of items. If there are no additional
	// items to return, the string is empty.
	NextToken *string `type:"string"`

	// The notification configurations.
	//
	// NotificationConfigurations is a required field
	NotificationConfigurations []*NotificationConfiguration `type:"list" required:"true"`
}

// String returns the string representation
func (s DescribeNotificationConfigurationsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeNotificationConfigurationsOutput) GoString() string {
	return s.String()
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeNotificationConfigurationsOutput) SetNextToken(v string) *DescribeNotificationConfigurationsOutput {
	s.NextToken = &v
	return s
}

// SetNotificationConfigurations sets the NotificationConfigurations field's value.
func (s *DescribeNotificationConfigurationsOutput) SetNotificationConfigurations(v []*NotificationConfiguration) *DescribeNotificationConfigurationsOutput {
	s.NotificationConfigurations = v
	return s
}

type DescribePoliciesInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	AutoScalingGroupName *string `min:"1" type:"string"`

	// The maximum number of items to be returned with each call. The default value
	// is 50 and the maximum value is 100.
	MaxRecords *int64 `type:"integer"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `type:"string"`

	// The names of one or more policies. If you omit this parameter, all policies
	// are described. If a group name is provided, the results are limited to that
	// group. This list is limited to 50 items. If you specify an unknown policy
	// name, it is ignored with no error.
	PolicyNames []*string `type:"list"`

	// One or more policy types. Valid values are SimpleScaling and StepScaling.
	PolicyTypes []*string `type:"list"`
}

// String returns the string representation
func (s DescribePoliciesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribePoliciesInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribePoliciesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribePoliciesInput"}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DescribePoliciesInput) SetAutoScalingGroupName(v string) *DescribePoliciesInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetMaxRecords sets the MaxRecords field's value.
func (s *DescribePoliciesInput) SetMaxRecords(v int64) *DescribePoliciesInput {
	s.MaxRecords = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribePoliciesInput) SetNextToken(v string) *DescribePoliciesInput {
	s.NextToken = &v
	return s
}

// SetPolicyNames sets the PolicyNames field's value.
func (s *DescribePoliciesInput) SetPolicyNames(v []*string) *DescribePoliciesInput {
	s.PolicyNames = v
	return s
}

// SetPolicyTypes sets the PolicyTypes field's value.
func (s *DescribePoliciesInput) SetPolicyTypes(v []*string) *DescribePoliciesInput {
	s.PolicyTypes = v
	return s
}

type DescribePoliciesOutput struct {
	_ struct{} `type:"structure"`

	// The token to use when requesting the next set of items. If there are no additional
	// items to return, the string is empty.
	NextToken *string `type:"string"`

	// The scaling policies.
	ScalingPolicies []*ScalingPolicy `type:"list"`
}

// String returns the string representation
func (s DescribePoliciesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribePoliciesOutput) GoString() string {
	return s.String()
}

// SetNextToken sets the NextToken field's value.
func (s *DescribePoliciesOutput) SetNextToken(v string) *DescribePoliciesOutput {
	s.NextToken = &v
	return s
}

// SetScalingPolicies sets the ScalingPolicies field's value.
func (s *DescribePoliciesOutput) SetScalingPolicies(v []*ScalingPolicy) *DescribePoliciesOutput {
	s.ScalingPolicies = v
	return s
}

type DescribeScalingActivitiesInput struct {
	_ struct{} `type:"structure"`

	// The activity IDs of the desired scaling activities. You can specify up to
	// 50 IDs. If you omit this parameter, all activities for the past six weeks
	// are described. If unknown activities are requested, they are ignored with
	// no error. If you specify an Auto Scaling group, the results are limited to
	// that group.
	ActivityIds []*string `type:"list"`

	// The name of the Auto Scaling group.
	AutoScalingGroupName *string `min:"1" type:"string"`

	// The maximum number of items to return with this call. The default value is
	// 100 and the maximum value is 100.
	MaxRecords *int64 `type:"integer"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeScalingActivitiesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeScalingActivitiesInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeScalingActivitiesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeScalingActivitiesInput"}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetActivityIds sets the ActivityIds field's value.
func (s *DescribeScalingActivitiesInput) SetActivityIds(v []*string) *DescribeScalingActivitiesInput {
	s.ActivityIds = v
	return s
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DescribeScalingActivitiesInput) SetAutoScalingGroupName(v string) *DescribeScalingActivitiesInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetMaxRecords sets the MaxRecords field's value.
func (s *DescribeScalingActivitiesInput) SetMaxRecords(v int64) *DescribeScalingActivitiesInput {
	s.MaxRecords = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeScalingActivitiesInput) SetNextToken(v string) *DescribeScalingActivitiesInput {
	s.NextToken = &v
	return s
}

type DescribeScalingActivitiesOutput struct {
	_ struct{} `type:"structure"`

	// The scaling activities. Activities are sorted by start time. Activities still
	// in progress are described first.
	//
	// Activities is a required field
	Activities []*Activity `type:"list" required:"true"`

	// The token to use when requesting the next set of items. If there are no additional
	// items to return, the string is empty.
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeScalingActivitiesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeScalingActivitiesOutput) GoString() string {
	return s.String()
}

// SetActivities sets the Activities field's value.
func (s *DescribeScalingActivitiesOutput) SetActivities(v []*Activity) *DescribeScalingActivitiesOutput {
	s.Activities = v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeScalingActivitiesOutput) SetNextToken(v string) *DescribeScalingActivitiesOutput {
	s.NextToken = &v
	return s
}

type DescribeScalingProcessTypesInput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DescribeScalingProcessTypesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeScalingProcessTypesInput) GoString() string {
	return s.String()
}

type DescribeScalingProcessTypesOutput struct {
	_ struct{} `type:"structure"`

	// The names of the process types.
	Processes []*ProcessType `type:"list"`
}

// String returns the string representation
func (s DescribeScalingProcessTypesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeScalingProcessTypesOutput) GoString() string {
	return s.String()
}

// SetProcesses sets the Processes field's value.
func (s *DescribeScalingProcessTypesOutput) SetProcesses(v []*ProcessType) *DescribeScalingProcessTypesOutput {
	s.Processes = v
	return s
}

type DescribeScheduledActionsInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	AutoScalingGroupName *string `min:"1" type:"string"`

	// The latest scheduled start time to return. If scheduled action names are
	// provided, this parameter is ignored.
	EndTime *time.Time `type:"timestamp"`

	// The maximum number of items to return with this call. The default value is
	// 50 and the maximum value is 100.
	MaxRecords *int64 `type:"integer"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `type:"string"`

	// The names of one or more scheduled actions. You can specify up to 50 actions.
	// If you omit this parameter, all scheduled actions are described. If you specify
	// an unknown scheduled action, it is ignored with no error.
	ScheduledActionNames []*string `type:"list"`

	// The earliest scheduled start time to return. If scheduled action names are
	// provided, this parameter is ignored.
	StartTime *time.Time `type:"timestamp"`
}

// String returns the string representation
func (s DescribeScheduledActionsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeScheduledActionsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeScheduledActionsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeScheduledActionsInput"}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DescribeScheduledActionsInput) SetAutoScalingGroupName(v string) *DescribeScheduledActionsInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetEndTime sets the EndTime field's value.
func (s *DescribeScheduledActionsInput) SetEndTime(v time.Time) *DescribeScheduledActionsInput {
	s.EndTime = &v
	return s
}

// SetMaxRecords sets the MaxRecords field's value.
func (s *DescribeScheduledActionsInput) SetMaxRecords(v int64) *DescribeScheduledActionsInput {
	s.MaxRecords = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeScheduledActionsInput) SetNextToken(v string) *DescribeScheduledActionsInput {
	s.NextToken = &v
	return s
}

// SetScheduledActionNames sets the ScheduledActionNames field's value.
func (s *DescribeScheduledActionsInput) SetScheduledActionNames(v []*string) *DescribeScheduledActionsInput {
	s.ScheduledActionNames = v
	return s
}

// SetStartTime sets the StartTime field's value.
func (s *DescribeScheduledActionsInput) SetStartTime(v time.Time) *DescribeScheduledActionsInput {
	s.StartTime = &v
	return s
}

type DescribeScheduledActionsOutput struct {
	_ struct{} `type:"structure"`

	// The token to use when requesting the next set of items. If there are no additional
	// items to return, the string is empty.
	NextToken *string `type:"string"`

	// The scheduled actions.
	ScheduledUpdateGroupActions []*ScheduledUpdateGroupAction `type:"list"`
}

// String returns the string representation
func (s DescribeScheduledActionsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeScheduledActionsOutput) GoString() string {
	return s.String()
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeScheduledActionsOutput) SetNextToken(v string) *DescribeScheduledActionsOutput {
	s.NextToken = &v
	return s
}

// SetScheduledUpdateGroupActions sets the ScheduledUpdateGroupActions field's value.
func (s *DescribeScheduledActionsOutput) SetScheduledUpdateGroupActions(v []*ScheduledUpdateGroupAction) *DescribeScheduledActionsOutput {
	s.ScheduledUpdateGroupActions = v
	return s
}

type DescribeTagsInput struct {
	_ struct{} `type:"structure"`

	// One or more filters to scope the tags to return. The maximum number of filters
	// per filter type (for example, auto-scaling-group) is 1000.
	Filters []*Filter `type:"list"`

	// The maximum number of items to return with this call. The default value is
	// 50 and the maximum value is 100.
	MaxRecords *int64 `type:"integer"`

	// The token for the next set of items to return. (You received this token from
	// a previous call.)
	NextToken *string `type:"string"`
}

// String returns the string representation
func (s DescribeTagsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeTagsInput) GoString() string {
	return s.String()
}

// SetFilters sets the Filters field's value.
func (s *DescribeTagsInput) SetFilters(v []*Filter) *DescribeTagsInput {
	s.Filters = v
	return s
}

// SetMaxRecords sets the MaxRecords field's value.
func (s *DescribeTagsInput) SetMaxRecords(v int64) *DescribeTagsInput {
	s.MaxRecords = &v
	return s
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeTagsInput) SetNextToken(v string) *DescribeTagsInput {
	s.NextToken = &v
	return s
}

type DescribeTagsOutput struct {
	_ struct{} `type:"structure"`

	// The token to use when requesting the next set of items. If there are no additional
	// items to return, the string is empty.
	NextToken *string `type:"string"`

	// One or more tags.
	Tags []*TagDescription `type:"list"`
}

// String returns the string representation
func (s DescribeTagsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeTagsOutput) GoString() string {
	return s.String()
}

// SetNextToken sets the NextToken field's value.
func (s *DescribeTagsOutput) SetNextToken(v string) *DescribeTagsOutput {
	s.NextToken = &v
	return s
}

// SetTags sets the Tags field's value.
func (s *DescribeTagsOutput) SetTags(v []*TagDescription) *DescribeTagsOutput {
	s.Tags = v
	return s
}

type DescribeTerminationPolicyTypesInput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DescribeTerminationPolicyTypesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeTerminationPolicyTypesInput) GoString() string {
	return s.String()
}

type DescribeTerminationPolicyTypesOutput struct {
	_ struct{} `type:"structure"`

	// The termination policies supported by Amazon EC2 Auto Scaling: OldestInstance,
	// OldestLaunchConfiguration, NewestInstance, ClosestToNextInstanceHour, Default,
	// OldestLaunchTemplate, and AllocationStrategy. Currently, the OldestLaunchTemplate
	// and AllocationStrategy policies are only supported for Auto Scaling groups
	// with MixedInstancesPolicy.
	TerminationPolicyTypes []*string `type:"list"`
}

// String returns the string representation
func (s DescribeTerminationPolicyTypesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeTerminationPolicyTypesOutput) GoString() string {
	return s.String()
}

// SetTerminationPolicyTypes sets the TerminationPolicyTypes field's value.
func (s *DescribeTerminationPolicyTypesOutput) SetTerminationPolicyTypes(v []*string) *DescribeTerminationPolicyTypesOutput {
	s.TerminationPolicyTypes = v
	return s
}

type DetachInstancesInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The IDs of the instances. You can specify up to 20 instances.
	InstanceIds []*string `type:"list"`

	// Indicates whether the Auto Scaling group decrements the desired capacity
	// value by the number of instances detached.
	//
	// ShouldDecrementDesiredCapacity is a required field
	ShouldDecrementDesiredCapacity *bool `type:"boolean" required:"true"`
}

// String returns the string representation
func (s DetachInstancesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DetachInstancesInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DetachInstancesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DetachInstancesInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.ShouldDecrementDesiredCapacity == nil {
		invalidParams.Add(request.NewErrParamRequired("ShouldDecrementDesiredCapacity"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DetachInstancesInput) SetAutoScalingGroupName(v string) *DetachInstancesInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetInstanceIds sets the InstanceIds field's value.
func (s *DetachInstancesInput) SetInstanceIds(v []*string) *DetachInstancesInput {
	s.InstanceIds = v
	return s
}

// SetShouldDecrementDesiredCapacity sets the ShouldDecrementDesiredCapacity field's value.
func (s *DetachInstancesInput) SetShouldDecrementDesiredCapacity(v bool) *DetachInstancesInput {
	s.ShouldDecrementDesiredCapacity = &v
	return s
}

type DetachInstancesOutput struct {
	_ struct{} `type:"structure"`

	// The activities related to detaching the instances from the Auto Scaling group.
	Activities []*Activity `type:"list"`
}

// String returns the string representation
func (s DetachInstancesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DetachInstancesOutput) GoString() string {
	return s.String()
}

// SetActivities sets the Activities field's value.
func (s *DetachInstancesOutput) SetActivities(v []*Activity) *DetachInstancesOutput {
	s.Activities = v
	return s
}

type DetachLoadBalancerTargetGroupsInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The Amazon Resource Names (ARN) of the target groups. You can specify up
	// to 10 target groups.
	//
	// TargetGroupARNs is a required field
	TargetGroupARNs []*string `type:"list" required:"true"`
}

// String returns the string representation
func (s DetachLoadBalancerTargetGroupsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DetachLoadBalancerTargetGroupsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DetachLoadBalancerTargetGroupsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DetachLoadBalancerTargetGroupsInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.TargetGroupARNs == nil {
		invalidParams.Add(request.NewErrParamRequired("TargetGroupARNs"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DetachLoadBalancerTargetGroupsInput) SetAutoScalingGroupName(v string) *DetachLoadBalancerTargetGroupsInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetTargetGroupARNs sets the TargetGroupARNs field's value.
func (s *DetachLoadBalancerTargetGroupsInput) SetTargetGroupARNs(v []*string) *DetachLoadBalancerTargetGroupsInput {
	s.TargetGroupARNs = v
	return s
}

type DetachLoadBalancerTargetGroupsOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DetachLoadBalancerTargetGroupsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DetachLoadBalancerTargetGroupsOutput) GoString() string {
	return s.String()
}

type DetachLoadBalancersInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The names of the load balancers. You can specify up to 10 load balancers.
	//
	// LoadBalancerNames is a required field
	LoadBalancerNames []*string `type:"list" required:"true"`
}

// String returns the string representation
func (s DetachLoadBalancersInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DetachLoadBalancersInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DetachLoadBalancersInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DetachLoadBalancersInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.LoadBalancerNames == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerNames"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DetachLoadBalancersInput) SetAutoScalingGroupName(v string) *DetachLoadBalancersInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetLoadBalancerNames sets the LoadBalancerNames field's value.
func (s *DetachLoadBalancersInput) SetLoadBalancerNames(v []*string) *DetachLoadBalancersInput {
	s.LoadBalancerNames = v
	return s
}

type DetachLoadBalancersOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DetachLoadBalancersOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DetachLoadBalancersOutput) GoString() string {
	return s.String()
}

type DisableMetricsCollectionInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// One or more of the following metrics. If you omit this parameter, all metrics
	// are disabled.
	//
	//    * GroupMinSize
	//
	//    * GroupMaxSize
	//
	//    * GroupDesiredCapacity
	//
	//    * GroupInServiceInstances
	//
	//    * GroupPendingInstances
	//
	//    * GroupStandbyInstances
	//
	//    * GroupTerminatingInstances
	//
	//    * GroupTotalInstances
	Metrics []*string `type:"list"`
}

// String returns the string representation
func (s DisableMetricsCollectionInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DisableMetricsCollectionInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DisableMetricsCollectionInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DisableMetricsCollectionInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *DisableMetricsCollectionInput) SetAutoScalingGroupName(v string) *DisableMetricsCollectionInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetMetrics sets the Metrics field's value.
func (s *DisableMetricsCollectionInput) SetMetrics(v []*string) *DisableMetricsCollectionInput {
	s.Metrics = v
	return s
}

type DisableMetricsCollectionOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DisableMetricsCollectionOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DisableMetricsCollectionOutput) GoString() string {
	return s.String()
}

// Describes an Amazon EBS volume.
type Ebs struct {
	_ struct{} `type:"structure"`

	// Indicates whether the volume is deleted on instance termination. The default
	// is true.
	DeleteOnTermination *bool `type:"boolean"`

	// Indicates whether the volume should be encrypted. Encrypted EBS volumes must
	// be attached to instances that support Amazon EBS encryption. Volumes that
	// are created from encrypted snapshots are automatically encrypted. There is
	// no way to create an encrypted volume from an unencrypted snapshot or an unencrypted
	// volume from an encrypted snapshot. For more information, see Amazon EBS Encryption
	// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html) in
	// the Amazon Elastic Compute Cloud User Guide.
	Encrypted *bool `type:"boolean"`

	// The number of I/O operations per second (IOPS) to provision for the volume.
	//
	// Constraint: Required when the volume type is io1.
	Iops *int64 `min:"100" type:"integer"`

	// The ID of the snapshot.
	SnapshotId *string `min:"1" type:"string"`

	// The volume size, in GiB. For standard volumes, specify a value from 1 to
	// 1,024. For io1 volumes, specify a value from 4 to 16,384. For gp2 volumes,
	// specify a value from 1 to 16,384. If you specify a snapshot, the volume size
	// must be equal to or larger than the snapshot size.
	//
	// Default: If you create a volume from a snapshot and you don't specify a volume
	// size, the default is the snapshot size.
	VolumeSize *int64 `min:"1" type:"integer"`

	// The volume type. For more information, see Amazon EBS Volume Types (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	//
	// Valid values: standard | io1 | gp2
	VolumeType *string `min:"1" type:"string"`
}

// String returns the string representation
func (s Ebs) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Ebs) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *Ebs) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "Ebs"}
	if s.Iops != nil && *s.Iops < 100 {
		invalidParams.Add(request.NewErrParamMinValue("Iops", 100))
	}
	if s.SnapshotId != nil && len(*s.SnapshotId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("SnapshotId", 1))
	}
	if s.VolumeSize != nil && *s.VolumeSize < 1 {
		invalidParams.Add(request.NewErrParamMinValue("VolumeSize", 1))
	}
	if s.VolumeType != nil && len(*s.VolumeType) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("VolumeType", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetDeleteOnTermination sets the DeleteOnTermination field's value.
func (s *Ebs) SetDeleteOnTermination(v bool) *Ebs {
	s.DeleteOnTermination = &v
	return s
}

// SetEncrypted sets the Encrypted field's value.
func (s *Ebs) SetEncrypted(v bool) *Ebs {
	s.Encrypted = &v
	return s
}

// SetIops sets the Iops field's value.
func (s *Ebs) SetIops(v int64) *Ebs {
	s.Iops = &v
	return s
}

// SetSnapshotId sets the SnapshotId field's value.
func (s *Ebs) SetSnapshotId(v string) *Ebs {
	s.SnapshotId = &v
	return s
}

// SetVolumeSize sets the VolumeSize field's value.
func (s *Ebs) SetVolumeSize(v int64) *Ebs {
	s.VolumeSize = &v
	return s
}

// SetVolumeType sets the VolumeType field's value.
func (s *Ebs) SetVolumeType(v string) *Ebs {
	s.VolumeType = &v
	return s
}

type EnableMetricsCollectionInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The granularity to associate with the metrics to collect. The only valid
	// value is 1Minute.
	//
	// Granularity is a required field
	Granularity *string `min:"1" type:"string" required:"true"`

	// One or more of the following metrics. If you omit this parameter, all metrics
	// are enabled.
	//
	//    * GroupMinSize
	//
	//    * GroupMaxSize
	//
	//    * GroupDesiredCapacity
	//
	//    * GroupInServiceInstances
	//
	//    * GroupPendingInstances
	//
	//    * GroupStandbyInstances
	//
	//    * GroupTerminatingInstances
	//
	//    * GroupTotalInstances
	Metrics []*string `type:"list"`
}

// String returns the string representation
func (s EnableMetricsCollectionInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s EnableMetricsCollectionInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *EnableMetricsCollectionInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "EnableMetricsCollectionInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.Granularity == nil {
		invalidParams.Add(request.NewErrParamRequired("Granularity"))
	}
	if s.Granularity != nil && len(*s.Granularity) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Granularity", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *EnableMetricsCollectionInput) SetAutoScalingGroupName(v string) *EnableMetricsCollectionInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetGranularity sets the Granularity field's value.
func (s *EnableMetricsCollectionInput) SetGranularity(v string) *EnableMetricsCollectionInput {
	s.Granularity = &v
	return s
}

// SetMetrics sets the Metrics field's value.
func (s *EnableMetricsCollectionInput) SetMetrics(v []*string) *EnableMetricsCollectionInput {
	s.Metrics = v
	return s
}

type EnableMetricsCollectionOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s EnableMetricsCollectionOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s EnableMetricsCollectionOutput) GoString() string {
	return s.String()
}

// Describes an enabled metric.
type EnabledMetric struct {
	_ struct{} `type:"structure"`

	// The granularity of the metric. The only valid value is 1Minute.
	Granularity *string `min:"1" type:"string"`

	// One of the following metrics:
	//
	//    * GroupMinSize
	//
	//    * GroupMaxSize
	//
	//    * GroupDesiredCapacity
	//
	//    * GroupInServiceInstances
	//
	//    * GroupPendingInstances
	//
	//    * GroupStandbyInstances
	//
	//    * GroupTerminatingInstances
	//
	//    * GroupTotalInstances
	Metric *string `min:"1" type:"string"`
}

// String returns the string representation
func (s EnabledMetric) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s EnabledMetric) GoString() string {
	return s.String()
}

// SetGranularity sets the Granularity field's value.
func (s *EnabledMetric) SetGranularity(v string) *EnabledMetric {
	s.Granularity = &v
	return s
}

// SetMetric sets the Metric field's value.
func (s *EnabledMetric) SetMetric(v string) *EnabledMetric {
	s.Metric = &v
	return s
}

type EnterStandbyInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The IDs of the instances. You can specify up to 20 instances.
	InstanceIds []*string `type:"list"`

	// Indicates whether to decrement the desired capacity of the Auto Scaling group
	// by the number of instances moved to Standby mode.
	//
	// ShouldDecrementDesiredCapacity is a required field
	ShouldDecrementDesiredCapacity *bool `type:"boolean" required:"true"`
}

// String returns the string representation
func (s EnterStandbyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s EnterStandbyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *EnterStandbyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "EnterStandbyInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.ShouldDecrementDesiredCapacity == nil {
		invalidParams.Add(request.NewErrParamRequired("ShouldDecrementDesiredCapacity"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *EnterStandbyInput) SetAutoScalingGroupName(v string) *EnterStandbyInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetInstanceIds sets the InstanceIds field's value.
func (s *EnterStandbyInput) SetInstanceIds(v []*string) *EnterStandbyInput {
	s.InstanceIds = v
	return s
}

// SetShouldDecrementDesiredCapacity sets the ShouldDecrementDesiredCapacity field's value.
func (s *EnterStandbyInput) SetShouldDecrementDesiredCapacity(v bool) *EnterStandbyInput {
	s.ShouldDecrementDesiredCapacity = &v
	return s
}

type EnterStandbyOutput struct {
	_ struct{} `type:"structure"`

	// The activities related to moving instances into Standby mode.
	Activities []*Activity `type:"list"`
}

// String returns the string representation
func (s EnterStandbyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s EnterStandbyOutput) GoString() string {
	return s.String()
}

// SetActivities sets the Activities field's value.
func (s *EnterStandbyOutput) SetActivities(v []*Activity) *EnterStandbyOutput {
	s.Activities = v
	return s
}

type ExecutePolicyInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	AutoScalingGroupName *string `min:"1" type:"string"`

	// The breach threshold for the alarm.
	//
	// This parameter is required if the policy type is StepScaling and not supported
	// otherwise.
	BreachThreshold *float64 `type:"double"`

	// Indicates whether Amazon EC2 Auto Scaling waits for the cooldown period to
	// complete before executing the policy.
	//
	// This parameter is not supported if the policy type is StepScaling.
	//
	// For more information, see Scaling Cooldowns (http://docs.aws.amazon.com/autoscaling/ec2/userguide/Cooldown.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	HonorCooldown *bool `type:"boolean"`

	// The metric value to compare to BreachThreshold. This enables you to execute
	// a policy of type StepScaling and determine which step adjustment to use.
	// For example, if the breach threshold is 50 and you want to use a step adjustment
	// with a lower bound of 0 and an upper bound of 10, you can set the metric
	// value to 59.
	//
	// If you specify a metric value that doesn't correspond to a step adjustment
	// for the policy, the call returns an error.
	//
	// This parameter is required if the policy type is StepScaling and not supported
	// otherwise.
	MetricValue *float64 `type:"double"`

	// The name or ARN of the policy.
	//
	// PolicyName is a required field
	PolicyName *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s ExecutePolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ExecutePolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ExecutePolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ExecutePolicyInput"}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.PolicyName == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyName"))
	}
	if s.PolicyName != nil && len(*s.PolicyName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("PolicyName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *ExecutePolicyInput) SetAutoScalingGroupName(v string) *ExecutePolicyInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetBreachThreshold sets the BreachThreshold field's value.
func (s *ExecutePolicyInput) SetBreachThreshold(v float64) *ExecutePolicyInput {
	s.BreachThreshold = &v
	return s
}

// SetHonorCooldown sets the HonorCooldown field's value.
func (s *ExecutePolicyInput) SetHonorCooldown(v bool) *ExecutePolicyInput {
	s.HonorCooldown = &v
	return s
}

// SetMetricValue sets the MetricValue field's value.
func (s *ExecutePolicyInput) SetMetricValue(v float64) *ExecutePolicyInput {
	s.MetricValue = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *ExecutePolicyInput) SetPolicyName(v string) *ExecutePolicyInput {
	s.PolicyName = &v
	return s
}

type ExecutePolicyOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s ExecutePolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ExecutePolicyOutput) GoString() string {
	return s.String()
}

type ExitStandbyInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The IDs of the instances. You can specify up to 20 instances.
	InstanceIds []*string `type:"list"`
}

// String returns the string representation
func (s ExitStandbyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ExitStandbyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ExitStandbyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ExitStandbyInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *ExitStandbyInput) SetAutoScalingGroupName(v string) *ExitStandbyInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetInstanceIds sets the InstanceIds field's value.
func (s *ExitStandbyInput) SetInstanceIds(v []*string) *ExitStandbyInput {
	s.InstanceIds = v
	return s
}

type ExitStandbyOutput struct {
	_ struct{} `type:"structure"`

	// The activities related to moving instances out of Standby mode.
	Activities []*Activity `type:"list"`
}

// String returns the string representation
func (s ExitStandbyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ExitStandbyOutput) GoString() string {
	return s.String()
}

// SetActivities sets the Activities field's value.
func (s *ExitStandbyOutput) SetActivities(v []*Activity) *ExitStandbyOutput {
	s.Activities = v
	return s
}

// Describes a scheduled action that could not be created, updated, or deleted.
type FailedScheduledUpdateGroupActionRequest struct {
	_ struct{} `type:"structure"`

	// The error code.
	ErrorCode *string `min:"1" type:"string"`

	// The error message accompanying the error code.
	ErrorMessage *string `type:"string"`

	// The name of the scheduled action.
	//
	// ScheduledActionName is a required field
	ScheduledActionName *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s FailedScheduledUpdateGroupActionRequest) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s FailedScheduledUpdateGroupActionRequest) GoString() string {
	return s.String()
}

// SetErrorCode sets the ErrorCode field's value.
func (s *FailedScheduledUpdateGroupActionRequest) SetErrorCode(v string) *FailedScheduledUpdateGroupActionRequest {
	s.ErrorCode = &v
	return s
}

// SetErrorMessage sets the ErrorMessage field's value.
func (s *FailedScheduledUpdateGroupActionRequest) SetErrorMessage(v string) *FailedScheduledUpdateGroupActionRequest {
	s.ErrorMessage = &v
	return s
}

// SetScheduledActionName sets the ScheduledActionName field's value.
func (s *FailedScheduledUpdateGroupActionRequest) SetScheduledActionName(v string) *FailedScheduledUpdateGroupActionRequest {
	s.ScheduledActionName = &v
	return s
}

// Describes a filter.
type Filter struct {
	_ struct{} `type:"structure"`

	// The name of the filter. The valid values are: "auto-scaling-group", "key",
	// "value", and "propagate-at-launch".
	Name *string `type:"string"`

	// The value of the filter.
	Values []*string `type:"list"`
}

// String returns the string representation
func (s Filter) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Filter) GoString() string {
	return s.String()
}

// SetName sets the Name field's value.
func (s *Filter) SetName(v string) *Filter {
	s.Name = &v
	return s
}

// SetValues sets the Values field's value.
func (s *Filter) SetValues(v []*string) *Filter {
	s.Values = v
	return s
}

// Describes an Auto Scaling group.
type Group struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) of the Auto Scaling group.
	AutoScalingGroupARN *string `min:"1" type:"string"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// One or more Availability Zones for the group.
	//
	// AvailabilityZones is a required field
	AvailabilityZones []*string `min:"1" type:"list" required:"true"`

	// The date and time the group was created.
	//
	// CreatedTime is a required field
	CreatedTime *time.Time `type:"timestamp" required:"true"`

	// The amount of time, in seconds, after a scaling activity completes before
	// another scaling activity can start.
	//
	// DefaultCooldown is a required field
	DefaultCooldown *int64 `type:"integer" required:"true"`

	// The desired size of the group.
	//
	// DesiredCapacity is a required field
	DesiredCapacity *int64 `type:"integer" required:"true"`

	// The metrics enabled for the group.
	EnabledMetrics []*EnabledMetric `type:"list"`

	// The amount of time, in seconds, that Amazon EC2 Auto Scaling waits before
	// checking the health status of an EC2 instance that has come into service.
	HealthCheckGracePeriod *int64 `type:"integer"`

	// The service to use for the health checks. The valid values are EC2 and ELB.
	//
	// HealthCheckType is a required field
	HealthCheckType *string `min:"1" type:"string" required:"true"`

	// The EC2 instances associated with the group.
	Instances []*Instance `type:"list"`

	// The name of the associated launch configuration.
	LaunchConfigurationName *string `min:"1" type:"string"`

	// The launch template for the group.
	LaunchTemplate *LaunchTemplateSpecification `type:"structure"`

	// One or more load balancers associated with the group.
	LoadBalancerNames []*string `type:"list"`

	// The maximum size of the group.
	//
	// MaxSize is a required field
	MaxSize *int64 `type:"integer" required:"true"`

	// The minimum size of the group.
	//
	// MinSize is a required field
	MinSize *int64 `type:"integer" required:"true"`

	// The mixed instances policy for the group.
	MixedInstancesPolicy *MixedInstancesPolicy `type:"structure"`

	// Indicates whether newly launched instances are protected from termination
	// by Auto Scaling when scaling in.
	NewInstancesProtectedFromScaleIn *bool `type:"boolean"`

	// The name of the placement group into which to launch your instances, if any.
	// For more information, see Placement Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	PlacementGroup *string `min:"1" type:"string"`

	// The Amazon Resource Name (ARN) of the service-linked role that the Auto Scaling
	// group uses to call other AWS services on your behalf.
	ServiceLinkedRoleARN *string `min:"1" type:"string"`

	// The current state of the group when DeleteAutoScalingGroup is in progress.
	Status *string `min:"1" type:"string"`

	// The suspended processes associated with the group.
	SuspendedProcesses []*SuspendedProcess `type:"list"`

	// The tags for the group.
	Tags []*TagDescription `type:"list"`

	// The Amazon Resource Names (ARN) of the target groups for your load balancer.
	TargetGroupARNs []*string `type:"list"`

	// The termination policies for the group.
	TerminationPolicies []*string `type:"list"`

	// One or more subnet IDs, if applicable, separated by commas.
	//
	// If you specify VPCZoneIdentifier and AvailabilityZones, ensure that the Availability
	// Zones of the subnets match the values for AvailabilityZones.
	VPCZoneIdentifier *string `min:"1" type:"string"`
}

// String returns the string representation
func (s Group) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Group) GoString() string {
	return s.String()
}

// SetAutoScalingGroupARN sets the AutoScalingGroupARN field's value.
func (s *Group) SetAutoScalingGroupARN(v string) *Group {
	s.AutoScalingGroupARN = &v
	return s
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *Group) SetAutoScalingGroupName(v string) *Group {
	s.AutoScalingGroupName = &v
	return s
}

// SetAvailabilityZones sets the AvailabilityZones field's value.
func (s *Group) SetAvailabilityZones(v []*string) *Group {
	s.AvailabilityZones = v
	return s
}

// SetCreatedTime sets the CreatedTime field's value.
func (s *Group) SetCreatedTime(v time.Time) *Group {
	s.CreatedTime = &v
	return s
}

// SetDefaultCooldown sets the DefaultCooldown field's value.
func (s *Group) SetDefaultCooldown(v int64) *Group {
	s.DefaultCooldown = &v
	return s
}

// SetDesiredCapacity sets the DesiredCapacity field's value.
func (s *Group) SetDesiredCapacity(v int64) *Group {
	s.DesiredCapacity = &v
	return s
}

// SetEnabledMetrics sets the EnabledMetrics field's value.
func (s *Group) SetEnabledMetrics(v []*EnabledMetric) *Group {
	s.EnabledMetrics = v
	return s
}

// SetHealthCheckGracePeriod sets the HealthCheckGracePeriod field's value.
func (s *Group) SetHealthCheckGracePeriod(v int64) *Group {
	s.HealthCheckGracePeriod = &v
	return s
}

// SetHealthCheckType sets the HealthCheckType field's value.
func (s *Group) SetHealthCheckType(v string) *Group {
	s.HealthCheckType = &v
	return s
}

// SetInstances sets the Instances field's value.
func (s *Group) SetInstances(v []*Instance) *Group {
	s.Instances = v
	return s
}

// SetLaunchConfigurationName sets the LaunchConfigurationName field's value.
func (s *Group) SetLaunchConfigurationName(v string) *Group {
	s.LaunchConfigurationName = &v
	return s
}

// SetLaunchTemplate sets the LaunchTemplate field's value.
func (s *Group) SetLaunchTemplate(v *LaunchTemplateSpecification) *Group {
	s.LaunchTemplate = v
	return s
}

// SetLoadBalancerNames sets the LoadBalancerNames field's value.
func (s *Group) SetLoadBalancerNames(v []*string) *Group {
	s.LoadBalancerNames = v
	return s
}

// SetMaxSize sets the MaxSize field's value.
func (s *Group) SetMaxSize(v int64) *Group {
	s.MaxSize = &v
	return s
}

// SetMinSize sets the MinSize field's value.
func (s *Group) SetMinSize(v int64) *Group {
	s.MinSize = &v
	return s
}

// SetMixedInstancesPolicy sets the MixedInstancesPolicy field's value.
func (s *Group) SetMixedInstancesPolicy(v *MixedInstancesPolicy) *Group {
	s.MixedInstancesPolicy = v
	return s
}

// SetNewInstancesProtectedFromScaleIn sets the NewInstancesProtectedFromScaleIn field's value.
func (s *Group) SetNewInstancesProtectedFromScaleIn(v bool) *Group {
	s.NewInstancesProtectedFromScaleIn = &v
	return s
}

// SetPlacementGroup sets the PlacementGroup field's value.
func (s *Group) SetPlacementGroup(v string) *Group {
	s.PlacementGroup = &v
	return s
}

// SetServiceLinkedRoleARN sets the ServiceLinkedRoleARN field's value.
func (s *Group) SetServiceLinkedRoleARN(v string) *Group {
	s.ServiceLinkedRoleARN = &v
	return s
}

// SetStatus sets the Status field's value.
func (s *Group) SetStatus(v string) *Group {
	s.Status = &v
	return s
}

// SetSuspendedProcesses sets the SuspendedProcesses field's value.
func (s *Group) SetSuspendedProcesses(v []*SuspendedProcess) *Group {
	s.SuspendedProcesses = v
	return s
}

// SetTags sets the Tags field's value.
func (s *Group) SetTags(v []*TagDescription) *Group {
	s.Tags = v
	return s
}

// SetTargetGroupARNs sets the TargetGroupARNs field's value.
func (s *Group) SetTargetGroupARNs(v []*string) *Group {
	s.TargetGroupARNs = v
	return s
}

// SetTerminationPolicies sets the TerminationPolicies field's value.
func (s *Group) SetTerminationPolicies(v []*string) *Group {
	s.TerminationPolicies = v
	return s
}

// SetVPCZoneIdentifier sets the VPCZoneIdentifier field's value.
func (s *Group) SetVPCZoneIdentifier(v string) *Group {
	s.VPCZoneIdentifier = &v
	return s
}

// Describes an EC2 instance.
type Instance struct {
	_ struct{} `type:"structure"`

	// The Availability Zone in which the instance is running.
	//
	// AvailabilityZone is a required field
	AvailabilityZone *string `min:"1" type:"string" required:"true"`

	// The last reported health status of the instance. "Healthy" means that the
	// instance is healthy and should remain in service. "Unhealthy" means that
	// the instance is unhealthy and that Amazon EC2 Auto Scaling should terminate
	// and replace it.
	//
	// HealthStatus is a required field
	HealthStatus *string `min:"1" type:"string" required:"true"`

	// The ID of the instance.
	//
	// InstanceId is a required field
	InstanceId *string `min:"1" type:"string" required:"true"`

	// The launch configuration associated with the instance.
	LaunchConfigurationName *string `min:"1" type:"string"`

	// The launch template for the instance.
	LaunchTemplate *LaunchTemplateSpecification `type:"structure"`

	// A description of the current lifecycle state. The Quarantined state is not
	// used.
	//
	// LifecycleState is a required field
	LifecycleState *string `type:"string" required:"true" enum:"LifecycleState"`

	// Indicates whether the instance is protected from termination by Amazon EC2
	// Auto Scaling when scaling in.
	//
	// ProtectedFromScaleIn is a required field
	ProtectedFromScaleIn *bool `type:"boolean" required:"true"`
}

// String returns the string representation
func (s Instance) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Instance) GoString() string {
	return s.String()
}

// SetAvailabilityZone sets the AvailabilityZone field's value.
func (s *Instance) SetAvailabilityZone(v string) *Instance {
	s.AvailabilityZone = &v
	return s
}

// SetHealthStatus sets the HealthStatus field's value.
func (s *Instance) SetHealthStatus(v string) *Instance {
	s.HealthStatus = &v
	return s
}

// SetInstanceId sets the InstanceId field's value.
func (s *Instance) SetInstanceId(v string) *Instance {
	s.InstanceId = &v
	return s
}

// SetLaunchConfigurationName sets the LaunchConfigurationName field's value.
func (s *Instance) SetLaunchConfigurationName(v string) *Instance {
	s.LaunchConfigurationName = &v
	return s
}

// SetLaunchTemplate sets the LaunchTemplate field's value.
func (s *Instance) SetLaunchTemplate(v *LaunchTemplateSpecification) *Instance {
	s.LaunchTemplate = v
	return s
}

// SetLifecycleState sets the LifecycleState field's value.
func (s *Instance) SetLifecycleState(v string) *Instance {
	s.LifecycleState = &v
	return s
}

// SetProtectedFromScaleIn sets the ProtectedFromScaleIn field's value.
func (s *Instance) SetProtectedFromScaleIn(v bool) *Instance {
	s.ProtectedFromScaleIn = &v
	return s
}

// Describes an EC2 instance associated with an Auto Scaling group.
type InstanceDetails struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group for the instance.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The Availability Zone for the instance.
	//
	// AvailabilityZone is a required field
	AvailabilityZone *string `min:"1" type:"string" required:"true"`

	// The last reported health status of this instance. "Healthy" means that the
	// instance is healthy and should remain in service. "Unhealthy" means that
	// the instance is unhealthy and Amazon EC2 Auto Scaling should terminate and
	// replace it.
	//
	// HealthStatus is a required field
	HealthStatus *string `min:"1" type:"string" required:"true"`

	// The ID of the instance.
	//
	// InstanceId is a required field
	InstanceId *string `min:"1" type:"string" required:"true"`

	// The launch configuration used to launch the instance. This value is not available
	// if you attached the instance to the Auto Scaling group.
	LaunchConfigurationName *string `min:"1" type:"string"`

	// The launch template for the instance.
	LaunchTemplate *LaunchTemplateSpecification `type:"structure"`

	// The lifecycle state for the instance. For more information, see Auto Scaling
	// Lifecycle (http://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroupLifecycle.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	//
	// LifecycleState is a required field
	LifecycleState *string `min:"1" type:"string" required:"true"`

	// Indicates whether the instance is protected from termination by Amazon EC2
	// Auto Scaling when scaling in.
	//
	// ProtectedFromScaleIn is a required field
	ProtectedFromScaleIn *bool `type:"boolean" required:"true"`
}

// String returns the string representation
func (s InstanceDetails) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s InstanceDetails) GoString() string {
	return s.String()
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *InstanceDetails) SetAutoScalingGroupName(v string) *InstanceDetails {
	s.AutoScalingGroupName = &v
	return s
}

// SetAvailabilityZone sets the AvailabilityZone field's value.
func (s *InstanceDetails) SetAvailabilityZone(v string) *InstanceDetails {
	s.AvailabilityZone = &v
	return s
}

// SetHealthStatus sets the HealthStatus field's value.
func (s *InstanceDetails) SetHealthStatus(v string) *InstanceDetails {
	s.HealthStatus = &v
	return s
}

// SetInstanceId sets the InstanceId field's value.
func (s *InstanceDetails) SetInstanceId(v string) *InstanceDetails {
	s.InstanceId = &v
	return s
}

// SetLaunchConfigurationName sets the LaunchConfigurationName field's value.
func (s *InstanceDetails) SetLaunchConfigurationName(v string) *InstanceDetails {
	s.LaunchConfigurationName = &v
	return s
}

// SetLaunchTemplate sets the LaunchTemplate field's value.
func (s *InstanceDetails) SetLaunchTemplate(v *LaunchTemplateSpecification) *InstanceDetails {
	s.LaunchTemplate = v
	return s
}

// SetLifecycleState sets the LifecycleState field's value.
func (s *InstanceDetails) SetLifecycleState(v string) *InstanceDetails {
	s.LifecycleState = &v
	return s
}

// SetProtectedFromScaleIn sets the ProtectedFromScaleIn field's value.
func (s *InstanceDetails) SetProtectedFromScaleIn(v bool) *InstanceDetails {
	s.ProtectedFromScaleIn = &v
	return s
}

// Describes whether detailed monitoring is enabled for the Auto Scaling instances.
type InstanceMonitoring struct {
	_ struct{} `type:"structure"`

	// If true, detailed monitoring is enabled. Otherwise, basic monitoring is enabled.
	Enabled *bool `type:"boolean"`
}

// String returns the string representation
func (s InstanceMonitoring) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s InstanceMonitoring) GoString() string {
	return s.String()
}

// SetEnabled sets the Enabled field's value.
func (s *InstanceMonitoring) SetEnabled(v bool) *InstanceMonitoring {
	s.Enabled = &v
	return s
}

// Describes an instances distribution for an Auto Scaling group with MixedInstancesPolicy.
//
// The instances distribution specifies the distribution of On-Demand Instances
// and Spot Instances, the maximum price to pay for Spot Instances, and how
// the Auto Scaling group allocates instance types.
type InstancesDistribution struct {
	_ struct{} `type:"structure"`

	// Indicates how to allocate instance types to fulfill On-Demand capacity.
	//
	// The only valid value is prioritized, which is also the default value. This
	// strategy uses the order of instance types in the Overrides array of LaunchTemplate
	// to define the launch priority of each instance type. The first instance type
	// in the array is prioritized higher than the last. If all your On-Demand capacity
	// cannot be fulfilled using your highest priority instance, then the Auto Scaling
	// groups launches the remaining capacity using the second priority instance
	// type, and so on.
	OnDemandAllocationStrategy *string `type:"string"`

	// The minimum amount of the Auto Scaling group's capacity that must be fulfilled
	// by On-Demand Instances. This base portion is provisioned first as your group
	// scales.
	//
	// The default value is 0. If you leave this parameter set to 0, On-Demand Instances
	// are launched as a percentage of the Auto Scaling group's desired capacity,
	// per the OnDemandPercentageAboveBaseCapacity setting.
	OnDemandBaseCapacity *int64 `type:"integer"`

	// Controls the percentages of On-Demand Instances and Spot Instances for your
	// additional capacity beyond OnDemandBaseCapacity.
	//
	// The range is 0–100. The default value is 100. If you leave this parameter
	// set to 100, the percentages are 100% for On-Demand Instances and 0% for Spot
	// Instances.
	OnDemandPercentageAboveBaseCapacity *int64 `type:"integer"`

	// Indicates how to allocate Spot capacity across Spot pools.
	//
	// The only valid value is lowest-price, which is also the default value. The
	// Auto Scaling group selects the cheapest Spot pools and evenly allocates your
	// Spot capacity across the number of Spot pools that you specify.
	SpotAllocationStrategy *string `type:"string"`

	// The number of Spot pools to use to allocate your Spot capacity. The Spot
	// pools are determined from the different instance types in the Overrides array
	// of LaunchTemplate.
	//
	// The range is 1–20 and the default is 2.
	SpotInstancePools *int64 `type:"integer"`

	// The maximum price per unit hour that you are willing to pay for a Spot Instance.
	// If you leave this value blank (which is the default), the maximum Spot price
	// is set at the On-Demand price.
	SpotMaxPrice *string `min:"1" type:"string"`
}

// String returns the string representation
func (s InstancesDistribution) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s InstancesDistribution) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *InstancesDistribution) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "InstancesDistribution"}
	if s.SpotMaxPrice != nil && len(*s.SpotMaxPrice) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("SpotMaxPrice", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetOnDemandAllocationStrategy sets the OnDemandAllocationStrategy field's value.
func (s *InstancesDistribution) SetOnDemandAllocationStrategy(v string) *InstancesDistribution {
	s.OnDemandAllocationStrategy = &v
	return s
}

// SetOnDemandBaseCapacity sets the OnDemandBaseCapacity field's value.
func (s *InstancesDistribution) SetOnDemandBaseCapacity(v int64) *InstancesDistribution {
	s.OnDemandBaseCapacity = &v
	return s
}

// SetOnDemandPercentageAboveBaseCapacity sets the OnDemandPercentageAboveBaseCapacity field's value.
func (s *InstancesDistribution) SetOnDemandPercentageAboveBaseCapacity(v int64) *InstancesDistribution {
	s.OnDemandPercentageAboveBaseCapacity = &v
	return s
}

// SetSpotAllocationStrategy sets the SpotAllocationStrategy field's value.
func (s *InstancesDistribution) SetSpotAllocationStrategy(v string) *InstancesDistribution {
	s.SpotAllocationStrategy = &v
	return s
}

// SetSpotInstancePools sets the SpotInstancePools field's value.
func (s *InstancesDistribution) SetSpotInstancePools(v int64) *InstancesDistribution {
	s.SpotInstancePools = &v
	return s
}

// SetSpotMaxPrice sets the SpotMaxPrice field's value.
func (s *InstancesDistribution) SetSpotMaxPrice(v string) *InstancesDistribution {
	s.SpotMaxPrice = &v
	return s
}

// Describes a launch configuration.
type LaunchConfiguration struct {
	_ struct{} `type:"structure"`

	// [EC2-VPC] Indicates whether to assign a public IP address to each instance.
	AssociatePublicIpAddress *bool `type:"boolean"`

	// A block device mapping, which specifies the block devices for the instance.
	BlockDeviceMappings []*BlockDeviceMapping `type:"list"`

	// The ID of a ClassicLink-enabled VPC to link your EC2-Classic instances to.
	// This parameter can only be used if you are launching EC2-Classic instances.
	// For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	ClassicLinkVPCId *string `min:"1" type:"string"`

	// The IDs of one or more security groups for the VPC specified in ClassicLinkVPCId.
	// This parameter is required if you specify a ClassicLink-enabled VPC, and
	// cannot be used otherwise. For more information, see ClassicLink (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/vpc-classiclink.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	ClassicLinkVPCSecurityGroups []*string `type:"list"`

	// The creation date and time for the launch configuration.
	//
	// CreatedTime is a required field
	CreatedTime *time.Time `type:"timestamp" required:"true"`

	// Controls whether the instance is optimized for EBS I/O (true) or not (false).
	EbsOptimized *bool `type:"boolean"`

	// The name or Amazon Resource Name (ARN) of the instance profile associated
	// with the IAM role for the instance.
	IamInstanceProfile *string `min:"1" type:"string"`

	// The ID of the Amazon Machine Image (AMI).
	//
	// ImageId is a required field
	ImageId *string `min:"1" type:"string" required:"true"`

	// Controls whether instances in this group are launched with detailed (true)
	// or basic (false) monitoring.
	InstanceMonitoring *InstanceMonitoring `type:"structure"`

	// The instance type for the instances.
	//
	// InstanceType is a required field
	InstanceType *string `min:"1" type:"string" required:"true"`

	// The ID of the kernel associated with the AMI.
	KernelId *string `min:"1" type:"string"`

	// The name of the key pair.
	KeyName *string `min:"1" type:"string"`

	// The Amazon Resource Name (ARN) of the launch configuration.
	LaunchConfigurationARN *string `min:"1" type:"string"`

	// The name of the launch configuration.
	//
	// LaunchConfigurationName is a required field
	LaunchConfigurationName *string `min:"1" type:"string" required:"true"`

	// The tenancy of the instance, either default or dedicated. An instance with
	// dedicated tenancy runs in an isolated, single-tenant hardware and can only
	// be launched into a VPC.
	PlacementTenancy *string `min:"1" type:"string"`

	// The ID of the RAM disk associated with the AMI.
	RamdiskId *string `min:"1" type:"string"`

	// The security groups to associate with the instances.
	SecurityGroups []*string `type:"list"`

	// The price to bid when launching Spot Instances.
	SpotPrice *string `min:"1" type:"string"`

	// The user data available to the instances.
	UserData *string `type:"string"`
}

// String returns the string representation
func (s LaunchConfiguration) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LaunchConfiguration) GoString() string {
	return s.String()
}

// SetAssociatePublicIpAddress sets the AssociatePublicIpAddress field's value.
func (s *LaunchConfiguration) SetAssociatePublicIpAddress(v bool) *LaunchConfiguration {
	s.AssociatePublicIpAddress = &v
	return s
}

// SetBlockDeviceMappings sets the BlockDeviceMappings field's value.
func (s *LaunchConfiguration) SetBlockDeviceMappings(v []*BlockDeviceMapping) *LaunchConfiguration {
	s.BlockDeviceMappings = v
	return s
}

// SetClassicLinkVPCId sets the ClassicLinkVPCId field's value.
func (s *LaunchConfiguration) SetClassicLinkVPCId(v string) *LaunchConfiguration {
	s.ClassicLinkVPCId = &v
	return s
}

// SetClassicLinkVPCSecurityGroups sets the ClassicLinkVPCSecurityGroups field's value.
func (s *LaunchConfiguration) SetClassicLinkVPCSecurityGroups(v []*string) *LaunchConfiguration {
	s.ClassicLinkVPCSecurityGroups = v
	return s
}

// SetCreatedTime sets the CreatedTime field's value.
func (s *LaunchConfiguration) SetCreatedTime(v time.Time) *LaunchConfiguration {
	s.CreatedTime = &v
	return s
}

// SetEbsOptimized sets the EbsOptimized field's value.
func (s *LaunchConfiguration) SetEbsOptimized(v bool) *LaunchConfiguration {
	s.EbsOptimized = &v
	return s
}

// SetIamInstanceProfile sets the IamInstanceProfile field's value.
func (s *LaunchConfiguration) SetIamInstanceProfile(v string) *LaunchConfiguration {
	s.IamInstanceProfile = &v
	return s
}

// SetImageId sets the ImageId field's value.
func (s *LaunchConfiguration) SetImageId(v string) *LaunchConfiguration {
	s.ImageId = &v
	return s
}

// SetInstanceMonitoring sets the InstanceMonitoring field's value.
func (s *LaunchConfiguration) SetInstanceMonitoring(v *InstanceMonitoring) *LaunchConfiguration {
	s.InstanceMonitoring = v
	return s
}

// SetInstanceType sets the InstanceType field's value.
func (s *LaunchConfiguration) SetInstanceType(v string) *LaunchConfiguration {
	s.InstanceType = &v
	return s
}

// SetKernelId sets the KernelId field's value.
func (s *LaunchConfiguration) SetKernelId(v string) *LaunchConfiguration {
	s.KernelId = &v
	return s
}

// SetKeyName sets the KeyName field's value.
func (s *LaunchConfiguration) SetKeyName(v string) *LaunchConfiguration {
	s.KeyName = &v
	return s
}

// SetLaunchConfigurationARN sets the LaunchConfigurationARN field's value.
func (s *LaunchConfiguration) SetLaunchConfigurationARN(v string) *LaunchConfiguration {
	s.LaunchConfigurationARN = &v
	return s
}

// SetLaunchConfigurationName sets the LaunchConfigurationName field's value.
func (s *LaunchConfiguration) SetLaunchConfigurationName(v string) *LaunchConfiguration {
	s.LaunchConfigurationName = &v
	return s
}

// SetPlacementTenancy sets the PlacementTenancy field's value.
func (s *LaunchConfiguration) SetPlacementTenancy(v string) *LaunchConfiguration {
	s.PlacementTenancy = &v
	return s
}

// SetRamdiskId sets the RamdiskId field's value.
func (s *LaunchConfiguration) SetRamdiskId(v string) *LaunchConfiguration {
	s.RamdiskId = &v
	return s
}

// SetSecurityGroups sets the SecurityGroups field's value.
func (s *LaunchConfiguration) SetSecurityGroups(v []*string) *LaunchConfiguration {
	s.SecurityGroups = v
	return s
}

// SetSpotPrice sets the SpotPrice field's value.
func (s *LaunchConfiguration) SetSpotPrice(v string) *LaunchConfiguration {
	s.SpotPrice = &v
	return s
}

// SetUserData sets the UserData field's value.
func (s *LaunchConfiguration) SetUserData(v string) *LaunchConfiguration {
	s.UserData = &v
	return s
}

// Describes a launch template and overrides.
//
// The overrides are used to override the instance type specified by the launch
// template with multiple instance types that can be used to launch On-Demand
// Instances and Spot Instances.
type LaunchTemplate struct {
	_ struct{} `type:"structure"`

	// The launch template to use. You must specify either the launch template ID
	// or launch template name in the request.
	LaunchTemplateSpecification *LaunchTemplateSpecification `type:"structure"`

	// Any parameters that you specify override the same parameters in the launch
	// template. Currently, the only supported override is instance type.
	//
	// You must specify between 2 and 20 overrides.
	Overrides []*LaunchTemplateOverrides `type:"list"`
}

// String returns the string representation
func (s LaunchTemplate) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LaunchTemplate) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *LaunchTemplate) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "LaunchTemplate"}
	if s.LaunchTemplateSpecification != nil {
		if err := s.LaunchTemplateSpecification.Validate(); err != nil {
			invalidParams.AddNested("LaunchTemplateSpecification", err.(request.ErrInvalidParams))
		}
	}
	if s.Overrides != nil {
		for i, v := range s.Overrides {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Overrides", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLaunchTemplateSpecification sets the LaunchTemplateSpecification field's value.
func (s *LaunchTemplate) SetLaunchTemplateSpecification(v *LaunchTemplateSpecification) *LaunchTemplate {
	s.LaunchTemplateSpecification = v
	return s
}

// SetOverrides sets the Overrides field's value.
func (s *LaunchTemplate) SetOverrides(v []*LaunchTemplateOverrides) *LaunchTemplate {
	s.Overrides = v
	return s
}

// Describes an override for a launch template.
type LaunchTemplateOverrides struct {
	_ struct{} `type:"structure"`

	// The instance type.
	//
	// For information about available instance types, see Available Instance Types
	// (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-types.html#AvailableInstanceTypes)
	// in the Amazon Elastic Compute Cloud User Guide.
	InstanceType *string `min:"1" type:"string"`
}

// String returns the string representation
func (s LaunchTemplateOverrides) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LaunchTemplateOverrides) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *LaunchTemplateOverrides) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "LaunchTemplateOverrides"}
	if s.InstanceType != nil && len(*s.InstanceType) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("InstanceType", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetInstanceType sets the InstanceType field's value.
func (s *LaunchTemplateOverrides) SetInstanceType(v string) *LaunchTemplateOverrides {
	s.InstanceType = &v
	return s
}

// Describes a launch template and the launch template version.
//
// The launch template that is specified must be configured for use with an
// Auto Scaling group. For more information, see Creating a Launch Template
// for an Auto Scaling group (http://docs.aws.amazon.com/autoscaling/ec2/userguide/create-launch-template.html)
// in the Amazon EC2 Auto Scaling User Guide.
type LaunchTemplateSpecification struct {
	_ struct{} `type:"structure"`

	// The ID of the launch template. You must specify either a template ID or a
	// template name.
	LaunchTemplateId *string `min:"1" type:"string"`

	// The name of the launch template. You must specify either a template name
	// or a template ID.
	LaunchTemplateName *string `min:"3" type:"string"`

	// The version number, $Latest, or $Default. If the value is $Latest, Amazon
	// EC2 Auto Scaling selects the latest version of the launch template when launching
	// instances. If the value is $Default, Amazon EC2 Auto Scaling selects the
	// default version of the launch template when launching instances. The default
	// value is $Default.
	Version *string `min:"1" type:"string"`
}

// String returns the string representation
func (s LaunchTemplateSpecification) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LaunchTemplateSpecification) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *LaunchTemplateSpecification) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "LaunchTemplateSpecification"}
	if s.LaunchTemplateId != nil && len(*s.LaunchTemplateId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LaunchTemplateId", 1))
	}
	if s.LaunchTemplateName != nil && len(*s.LaunchTemplateName) < 3 {
		invalidParams.Add(request.NewErrParamMinLen("LaunchTemplateName", 3))
	}
	if s.Version != nil && len(*s.Version) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Version", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLaunchTemplateId sets the LaunchTemplateId field's value.
func (s *LaunchTemplateSpecification) SetLaunchTemplateId(v string) *LaunchTemplateSpecification {
	s.LaunchTemplateId = &v
	return s
}

// SetLaunchTemplateName sets the LaunchTemplateName field's value.
func (s *LaunchTemplateSpecification) SetLaunchTemplateName(v string) *LaunchTemplateSpecification {
	s.LaunchTemplateName = &v
	return s
}

// SetVersion sets the Version field's value.
func (s *LaunchTemplateSpecification) SetVersion(v string) *LaunchTemplateSpecification {
	s.Version = &v
	return s
}

// Describes a lifecycle hook, which tells Amazon EC2 Auto Scaling that you
// want to perform an action whenever it launches instances or whenever it terminates
// instances.
//
// For more information, see Lifecycle Hooks (http://docs.aws.amazon.com/autoscaling/ec2/userguide/lifecycle-hooks.html)
// in the Amazon EC2 Auto Scaling User Guide.
type LifecycleHook struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group for the lifecycle hook.
	AutoScalingGroupName *string `min:"1" type:"string"`

	// Defines the action the Auto Scaling group should take when the lifecycle
	// hook timeout elapses or if an unexpected failure occurs. The valid values
	// are CONTINUE and ABANDON. The default value is CONTINUE.
	DefaultResult *string `type:"string"`

	// The maximum time, in seconds, that an instance can remain in a Pending:Wait
	// or Terminating:Wait state. The maximum is 172800 seconds (48 hours) or 100
	// times HeartbeatTimeout, whichever is smaller.
	GlobalTimeout *int64 `type:"integer"`

	// The maximum time, in seconds, that can elapse before the lifecycle hook times
	// out. If the lifecycle hook times out, Amazon EC2 Auto Scaling performs the
	// default action. You can prevent the lifecycle hook from timing out by calling
	// RecordLifecycleActionHeartbeat.
	HeartbeatTimeout *int64 `type:"integer"`

	// The name of the lifecycle hook.
	LifecycleHookName *string `min:"1" type:"string"`

	// The state of the EC2 instance to which to attach the lifecycle hook. The
	// following are possible values:
	//
	//    * autoscaling:EC2_INSTANCE_LAUNCHING
	//
	//    * autoscaling:EC2_INSTANCE_TERMINATING
	LifecycleTransition *string `type:"string"`

	// Additional information that you want to include any time Amazon EC2 Auto
	// Scaling sends a message to the notification target.
	NotificationMetadata *string `min:"1" type:"string"`

	// The ARN of the target that Amazon EC2 Auto Scaling sends notifications to
	// when an instance is in the transition state for the lifecycle hook. The notification
	// target can be either an SQS queue or an SNS topic.
	NotificationTargetARN *string `min:"1" type:"string"`

	// The ARN of the IAM role that allows the Auto Scaling group to publish to
	// the specified notification target.
	RoleARN *string `min:"1" type:"string"`
}

// String returns the string representation
func (s LifecycleHook) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LifecycleHook) GoString() string {
	return s.String()
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *LifecycleHook) SetAutoScalingGroupName(v string) *LifecycleHook {
	s.AutoScalingGroupName = &v
	return s
}

// SetDefaultResult sets the DefaultResult field's value.
func (s *LifecycleHook) SetDefaultResult(v string) *LifecycleHook {
	s.DefaultResult = &v
	return s
}

// SetGlobalTimeout sets the GlobalTimeout field's value.
func (s *LifecycleHook) SetGlobalTimeout(v int64) *LifecycleHook {
	s.GlobalTimeout = &v
	return s
}

// SetHeartbeatTimeout sets the HeartbeatTimeout field's value.
func (s *LifecycleHook) SetHeartbeatTimeout(v int64) *LifecycleHook {
	s.HeartbeatTimeout = &v
	return s
}

// SetLifecycleHookName sets the LifecycleHookName field's value.
func (s *LifecycleHook) SetLifecycleHookName(v string) *LifecycleHook {
	s.LifecycleHookName = &v
	return s
}

// SetLifecycleTransition sets the LifecycleTransition field's value.
func (s *LifecycleHook) SetLifecycleTransition(v string) *LifecycleHook {
	s.LifecycleTransition = &v
	return s
}

// SetNotificationMetadata sets the NotificationMetadata field's value.
func (s *LifecycleHook) SetNotificationMetadata(v string) *LifecycleHook {
	s.NotificationMetadata = &v
	return s
}

// SetNotificationTargetARN sets the NotificationTargetARN field's value.
func (s *LifecycleHook) SetNotificationTargetARN(v string) *LifecycleHook {
	s.NotificationTargetARN = &v
	return s
}

// SetRoleARN sets the RoleARN field's value.
func (s *LifecycleHook) SetRoleARN(v string) *LifecycleHook {
	s.RoleARN = &v
	return s
}

// Describes a lifecycle hook, which tells Amazon EC2 Auto Scaling that you
// want to perform an action whenever it launches instances or whenever it terminates
// instances.
//
// For more information, see Lifecycle Hooks (http://docs.aws.amazon.com/autoscaling/ec2/userguide/lifecycle-hooks.html)
// in the Amazon EC2 Auto Scaling User Guide.
type LifecycleHookSpecification struct {
	_ struct{} `type:"structure"`

	// Defines the action the Auto Scaling group should take when the lifecycle
	// hook timeout elapses or if an unexpected failure occurs. The valid values
	// are CONTINUE and ABANDON.
	DefaultResult *string `type:"string"`

	// The maximum time, in seconds, that can elapse before the lifecycle hook times
	// out. If the lifecycle hook times out, Amazon EC2 Auto Scaling performs the
	// default action. You can prevent the lifecycle hook from timing out by calling
	// RecordLifecycleActionHeartbeat.
	HeartbeatTimeout *int64 `type:"integer"`

	// The name of the lifecycle hook.
	//
	// LifecycleHookName is a required field
	LifecycleHookName *string `min:"1" type:"string" required:"true"`

	// The state of the EC2 instance to which you want to attach the lifecycle hook.
	// The possible values are:
	//
	//    * autoscaling:EC2_INSTANCE_LAUNCHING
	//
	//    * autoscaling:EC2_INSTANCE_TERMINATING
	//
	// LifecycleTransition is a required field
	LifecycleTransition *string `type:"string" required:"true"`

	// Additional information that you want to include any time Amazon EC2 Auto
	// Scaling sends a message to the notification target.
	NotificationMetadata *string `min:"1" type:"string"`

	// The ARN of the target that Amazon EC2 Auto Scaling sends notifications to
	// when an instance is in the transition state for the lifecycle hook. The notification
	// target can be either an SQS queue or an SNS topic.
	NotificationTargetARN *string `type:"string"`

	// The ARN of the IAM role that allows the Auto Scaling group to publish to
	// the specified notification target.
	RoleARN *string `min:"1" type:"string"`
}

// String returns the string representation
func (s LifecycleHookSpecification) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LifecycleHookSpecification) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *LifecycleHookSpecification) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "LifecycleHookSpecification"}
	if s.LifecycleHookName == nil {
		invalidParams.Add(request.NewErrParamRequired("LifecycleHookName"))
	}
	if s.LifecycleHookName != nil && len(*s.LifecycleHookName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LifecycleHookName", 1))
	}
	if s.LifecycleTransition == nil {
		invalidParams.Add(request.NewErrParamRequired("LifecycleTransition"))
	}
	if s.NotificationMetadata != nil && len(*s.NotificationMetadata) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("NotificationMetadata", 1))
	}
	if s.RoleARN != nil && len(*s.RoleARN) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("RoleARN", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetDefaultResult sets the DefaultResult field's value.
func (s *LifecycleHookSpecification) SetDefaultResult(v string) *LifecycleHookSpecification {
	s.DefaultResult = &v
	return s
}

// SetHeartbeatTimeout sets the HeartbeatTimeout field's value.
func (s *LifecycleHookSpecification) SetHeartbeatTimeout(v int64) *LifecycleHookSpecification {
	s.HeartbeatTimeout = &v
	return s
}

// SetLifecycleHookName sets the LifecycleHookName field's value.
func (s *LifecycleHookSpecification) SetLifecycleHookName(v string) *LifecycleHookSpecification {
	s.LifecycleHookName = &v
	return s
}

// SetLifecycleTransition sets the LifecycleTransition field's value.
func (s *LifecycleHookSpecification) SetLifecycleTransition(v string) *LifecycleHookSpecification {
	s.LifecycleTransition = &v
	return s
}

// SetNotificationMetadata sets the NotificationMetadata field's value.
func (s *LifecycleHookSpecification) SetNotificationMetadata(v string) *LifecycleHookSpecification {
	s.NotificationMetadata = &v
	return s
}

// SetNotificationTargetARN sets the NotificationTargetARN field's value.
func (s *LifecycleHookSpecification) SetNotificationTargetARN(v string) *LifecycleHookSpecification {
	s.NotificationTargetARN = &v
	return s
}

// SetRoleARN sets the RoleARN field's value.
func (s *LifecycleHookSpecification) SetRoleARN(v string) *LifecycleHookSpecification {
	s.RoleARN = &v
	return s
}

// Describes the state of a Classic Load Balancer.
//
// If you specify a load balancer when creating the Auto Scaling group, the
// state of the load balancer is InService.
//
// If you attach a load balancer to an existing Auto Scaling group, the initial
// state is Adding. The state transitions to Added after all instances in the
// group are registered with the load balancer. If Elastic Load Balancing health
// checks are enabled for the load balancer, the state transitions to InService
// after at least one instance in the group passes the health check. If EC2
// health checks are enabled instead, the load balancer remains in the Added
// state.
type LoadBalancerState struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	LoadBalancerName *string `min:"1" type:"string"`

	// One of the following load balancer states:
	//
	//    * Adding - The instances in the group are being registered with the load
	//    balancer.
	//
	//    * Added - All instances in the group are registered with the load balancer.
	//
	//    * InService - At least one instance in the group passed an ELB health
	//    check.
	//
	//    * Removing - The instances in the group are being deregistered from the
	//    load balancer. If connection draining is enabled, Elastic Load Balancing
	//    waits for in-flight requests to complete before deregistering the instances.
	//
	//    * Removed - All instances in the group are deregistered from the load
	//    balancer.
	State *string `min:"1" type:"string"`
}

// String returns the string representation
func (s LoadBalancerState) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LoadBalancerState) GoString() string {
	return s.String()
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *LoadBalancerState) SetLoadBalancerName(v string) *LoadBalancerState {
	s.LoadBalancerName = &v
	return s
}

// SetState sets the State field's value.
func (s *LoadBalancerState) SetState(v string) *LoadBalancerState {
	s.State = &v
	return s
}

// Describes the state of a target group.
//
// If you attach a target group to an existing Auto Scaling group, the initial
// state is Adding. The state transitions to Added after all Auto Scaling instances
// are registered with the target group. If Elastic Load Balancing health checks
// are enabled, the state transitions to InService after at least one Auto Scaling
// instance passes the health check. If EC2 health checks are enabled instead,
// the target group remains in the Added state.
type LoadBalancerTargetGroupState struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) of the target group.
	LoadBalancerTargetGroupARN *string `min:"1" type:"string"`

	// The state of the target group.
	//
	//    * Adding - The Auto Scaling instances are being registered with the target
	//    group.
	//
	//    * Added - All Auto Scaling instances are registered with the target group.
	//
	//    * InService - At least one Auto Scaling instance passed an ELB health
	//    check.
	//
	//    * Removing - The Auto Scaling instances are being deregistered from the
	//    target group. If connection draining is enabled, Elastic Load Balancing
	//    waits for in-flight requests to complete before deregistering the instances.
	//
	//    * Removed - All Auto Scaling instances are deregistered from the target
	//    group.
	State *string `min:"1" type:"string"`
}

// String returns the string representation
func (s LoadBalancerTargetGroupState) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LoadBalancerTargetGroupState) GoString() string {
	return s.String()
}

// SetLoadBalancerTargetGroupARN sets the LoadBalancerTargetGroupARN field's value.
func (s *LoadBalancerTargetGroupState) SetLoadBalancerTargetGroupARN(v string) *LoadBalancerTargetGroupState {
	s.LoadBalancerTargetGroupARN = &v
	return s
}

// SetState sets the State field's value.
func (s *LoadBalancerTargetGroupState) SetState(v string) *LoadBalancerTargetGroupState {
	s.State = &v
	return s
}

// Describes a metric.
type MetricCollectionType struct {
	_ struct{} `type:"structure"`

	// One of the following metrics:
	//
	//    * GroupMinSize
	//
	//    * GroupMaxSize
	//
	//    * GroupDesiredCapacity
	//
	//    * GroupInServiceInstances
	//
	//    * GroupPendingInstances
	//
	//    * GroupStandbyInstances
	//
	//    * GroupTerminatingInstances
	//
	//    * GroupTotalInstances
	Metric *string `min:"1" type:"string"`
}

// String returns the string representation
func (s MetricCollectionType) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s MetricCollectionType) GoString() string {
	return s.String()
}

// SetMetric sets the Metric field's value.
func (s *MetricCollectionType) SetMetric(v string) *MetricCollectionType {
	s.Metric = &v
	return s
}

// Describes the dimension of a metric.
type MetricDimension struct {
	_ struct{} `type:"structure"`

	// The name of the dimension.
	//
	// Name is a required field
	Name *string `type:"string" required:"true"`

	// The value of the dimension.
	//
	// Value is a required field
	Value *string `type:"string" required:"true"`
}

// String returns the string representation
func (s MetricDimension) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s MetricDimension) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *MetricDimension) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "MetricDimension"}
	if s.Name == nil {
		invalidParams.Add(request.NewErrParamRequired("Name"))
	}
	if s.Value == nil {
		invalidParams.Add(request.NewErrParamRequired("Value"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetName sets the Name field's value.
func (s *MetricDimension) SetName(v string) *MetricDimension {
	s.Name = &v
	return s
}

// SetValue sets the Value field's value.
func (s *MetricDimension) SetValue(v string) *MetricDimension {
	s.Value = &v
	return s
}

// Describes a granularity of a metric.
type MetricGranularityType struct {
	_ struct{} `type:"structure"`

	// The granularity. The only valid value is 1Minute.
	Granularity *string `min:"1" type:"string"`
}

// String returns the string representation
func (s MetricGranularityType) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s MetricGranularityType) GoString() string {
	return s.String()
}

// SetGranularity sets the Granularity field's value.
func (s *MetricGranularityType) SetGranularity(v string) *MetricGranularityType {
	s.Granularity = &v
	return s
}

// Describes a mixed instances policy for an Auto Scaling group. With mixed
// instances, your Auto Scaling group can provision a combination of On-Demand
// Instances and Spot Instances across multiple instance types. For more information,
// see Using Multiple Instance Types and Purchase Options (http://docs.aws.amazon.com/autoscaling/ec2/userguide/AutoScalingGroup.html#asg-purchase-options)
// in the Amazon EC2 Auto Scaling User Guide.
//
// When you create your Auto Scaling group, you can specify a launch configuration
// or template as a parameter for the top-level object, or you can specify a
// mixed instances policy, but not both at the same time.
type MixedInstancesPolicy struct {
	_ struct{} `type:"structure"`

	// The instances distribution to use.
	//
	// If you leave this parameter unspecified when creating the group, the default
	// values are used.
	InstancesDistribution *InstancesDistribution `type:"structure"`

	// The launch template and overrides.
	//
	// This parameter is required when creating an Auto Scaling group with a mixed
	// instances policy, but is not required when updating the group.
	LaunchTemplate *LaunchTemplate `type:"structure"`
}

// String returns the string representation
func (s MixedInstancesPolicy) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s MixedInstancesPolicy) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *MixedInstancesPolicy) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "MixedInstancesPolicy"}
	if s.InstancesDistribution != nil {
		if err := s.InstancesDistribution.Validate(); err != nil {
			invalidParams.AddNested("InstancesDistribution", err.(request.ErrInvalidParams))
		}
	}
	if s.LaunchTemplate != nil {
		if err := s.LaunchTemplate.Validate(); err != nil {
			invalidParams.AddNested("LaunchTemplate", err.(request.ErrInvalidParams))
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetInstancesDistribution sets the InstancesDistribution field's value.
func (s *MixedInstancesPolicy) SetInstancesDistribution(v *InstancesDistribution) *MixedInstancesPolicy {
	s.InstancesDistribution = v
	return s
}

// SetLaunchTemplate sets the LaunchTemplate field's value.
func (s *MixedInstancesPolicy) SetLaunchTemplate(v *LaunchTemplate) *MixedInstancesPolicy {
	s.LaunchTemplate = v
	return s
}

// Describes a notification.
type NotificationConfiguration struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	AutoScalingGroupName *string `min:"1" type:"string"`

	// One of the following event notification types:
	//
	//    * autoscaling:EC2_INSTANCE_LAUNCH
	//
	//    * autoscaling:EC2_INSTANCE_LAUNCH_ERROR
	//
	//    * autoscaling:EC2_INSTANCE_TERMINATE
	//
	//    * autoscaling:EC2_INSTANCE_TERMINATE_ERROR
	//
	//    * autoscaling:TEST_NOTIFICATION
	NotificationType *string `min:"1" type:"string"`

	// The Amazon Resource Name (ARN) of the Amazon Simple Notification Service
	// (Amazon SNS) topic.
	TopicARN *string `min:"1" type:"string"`
}

// String returns the string representation
func (s NotificationConfiguration) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s NotificationConfiguration) GoString() string {
	return s.String()
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *NotificationConfiguration) SetAutoScalingGroupName(v string) *NotificationConfiguration {
	s.AutoScalingGroupName = &v
	return s
}

// SetNotificationType sets the NotificationType field's value.
func (s *NotificationConfiguration) SetNotificationType(v string) *NotificationConfiguration {
	s.NotificationType = &v
	return s
}

// SetTopicARN sets the TopicARN field's value.
func (s *NotificationConfiguration) SetTopicARN(v string) *NotificationConfiguration {
	s.TopicARN = &v
	return s
}

// Configures a predefined metric for a target tracking policy.
type PredefinedMetricSpecification struct {
	_ struct{} `type:"structure"`

	// The metric type.
	//
	// PredefinedMetricType is a required field
	PredefinedMetricType *string `type:"string" required:"true" enum:"MetricType"`

	// Identifies the resource associated with the metric type. The following predefined
	// metrics are available:
	//
	//    * ASGAverageCPUUtilization - Average CPU utilization of the Auto Scaling
	//    group.
	//
	//    * ASGAverageNetworkIn - Average number of bytes received on all network
	//    interfaces by the Auto Scaling group.
	//
	//    * ASGAverageNetworkOut - Average number of bytes sent out on all network
	//    interfaces by the Auto Scaling group.
	//
	//    * ALBRequestCountPerTarget - Number of requests completed per target in
	//    an Application Load Balancer target group.
	//
	// For predefined metric types ASGAverageCPUUtilization, ASGAverageNetworkIn,
	// and ASGAverageNetworkOut, the parameter must not be specified as the resource
	// associated with the metric type is the Auto Scaling group. For predefined
	// metric type ALBRequestCountPerTarget, the parameter must be specified in
	// the format: app/load-balancer-name/load-balancer-id/targetgroup/target-group-name/target-group-id,
	// where app/load-balancer-name/load-balancer-id is the final portion of the
	// load balancer ARN, and targetgroup/target-group-name/target-group-id is the
	// final portion of the target group ARN. The target group must be attached
	// to the Auto Scaling group.
	ResourceLabel *string `min:"1" type:"string"`
}

// String returns the string representation
func (s PredefinedMetricSpecification) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PredefinedMetricSpecification) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PredefinedMetricSpecification) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PredefinedMetricSpecification"}
	if s.PredefinedMetricType == nil {
		invalidParams.Add(request.NewErrParamRequired("PredefinedMetricType"))
	}
	if s.ResourceLabel != nil && len(*s.ResourceLabel) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ResourceLabel", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetPredefinedMetricType sets the PredefinedMetricType field's value.
func (s *PredefinedMetricSpecification) SetPredefinedMetricType(v string) *PredefinedMetricSpecification {
	s.PredefinedMetricType = &v
	return s
}

// SetResourceLabel sets the ResourceLabel field's value.
func (s *PredefinedMetricSpecification) SetResourceLabel(v string) *PredefinedMetricSpecification {
	s.ResourceLabel = &v
	return s
}

// Describes a process type.
//
// For more information, see Scaling Processes (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-suspend-resume-processes.html#process-types)
// in the Amazon EC2 Auto Scaling User Guide.
type ProcessType struct {
	_ struct{} `type:"structure"`

	// One of the following processes:
	//
	//    * Launch
	//
	//    * Terminate
	//
	//    * AddToLoadBalancer
	//
	//    * AlarmNotification
	//
	//    * AZRebalance
	//
	//    * HealthCheck
	//
	//    * ReplaceUnhealthy
	//
	//    * ScheduledActions
	//
	// ProcessName is a required field
	ProcessName *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s ProcessType) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ProcessType) GoString() string {
	return s.String()
}

// SetProcessName sets the ProcessName field's value.
func (s *ProcessType) SetProcessName(v string) *ProcessType {
	s.ProcessName = &v
	return s
}

type PutLifecycleHookInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// Defines the action the Auto Scaling group should take when the lifecycle
	// hook timeout elapses or if an unexpected failure occurs. This parameter can
	// be either CONTINUE or ABANDON. The default value is ABANDON.
	DefaultResult *string `type:"string"`

	// The maximum time, in seconds, that can elapse before the lifecycle hook times
	// out. The range is from 30 to 7200 seconds. The default is 3600 seconds (1
	// hour).
	//
	// If the lifecycle hook times out, Amazon EC2 Auto Scaling performs the default
	// action. You can prevent the lifecycle hook from timing out by calling RecordLifecycleActionHeartbeat.
	HeartbeatTimeout *int64 `type:"integer"`

	// The name of the lifecycle hook.
	//
	// LifecycleHookName is a required field
	LifecycleHookName *string `min:"1" type:"string" required:"true"`

	// The instance state to which you want to attach the lifecycle hook. The possible
	// values are:
	//
	//    * autoscaling:EC2_INSTANCE_LAUNCHING
	//
	//    * autoscaling:EC2_INSTANCE_TERMINATING
	//
	// This parameter is required for new lifecycle hooks, but optional when updating
	// existing hooks.
	LifecycleTransition *string `type:"string"`

	// Contains additional information that you want to include any time Amazon
	// EC2 Auto Scaling sends a message to the notification target.
	NotificationMetadata *string `min:"1" type:"string"`

	// The ARN of the notification target that Amazon EC2 Auto Scaling uses to notify
	// you when an instance is in the transition state for the lifecycle hook. This
	// target can be either an SQS queue or an SNS topic. If you specify an empty
	// string, this overrides the current ARN.
	//
	// This operation uses the JSON format when sending notifications to an Amazon
	// SQS queue, and an email key-value pair format when sending notifications
	// to an Amazon SNS topic.
	//
	// When you specify a notification target, Amazon EC2 Auto Scaling sends it
	// a test message. Test messages contain the following additional key-value
	// pair: "Event": "autoscaling:TEST_NOTIFICATION".
	NotificationTargetARN *string `type:"string"`

	// The ARN of the IAM role that allows the Auto Scaling group to publish to
	// the specified notification target.
	//
	// This parameter is required for new lifecycle hooks, but optional when updating
	// existing hooks.
	RoleARN *string `min:"1" type:"string"`
}

// String returns the string representation
func (s PutLifecycleHookInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutLifecycleHookInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutLifecycleHookInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutLifecycleHookInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.LifecycleHookName == nil {
		invalidParams.Add(request.NewErrParamRequired("LifecycleHookName"))
	}
	if s.LifecycleHookName != nil && len(*s.LifecycleHookName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LifecycleHookName", 1))
	}
	if s.NotificationMetadata != nil && len(*s.NotificationMetadata) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("NotificationMetadata", 1))
	}
	if s.RoleARN != nil && len(*s.RoleARN) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("RoleARN", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *PutLifecycleHookInput) SetAutoScalingGroupName(v string) *PutLifecycleHookInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetDefaultResult sets the DefaultResult field's value.
func (s *PutLifecycleHookInput) SetDefaultResult(v string) *PutLifecycleHookInput {
	s.DefaultResult = &v
	return s
}

// SetHeartbeatTimeout sets the HeartbeatTimeout field's value.
func (s *PutLifecycleHookInput) SetHeartbeatTimeout(v int64) *PutLifecycleHookInput {
	s.HeartbeatTimeout = &v
	return s
}

// SetLifecycleHookName sets the LifecycleHookName field's value.
func (s *PutLifecycleHookInput) SetLifecycleHookName(v string) *PutLifecycleHookInput {
	s.LifecycleHookName = &v
	return s
}

// SetLifecycleTransition sets the LifecycleTransition field's value.
func (s *PutLifecycleHookInput) SetLifecycleTransition(v string) *PutLifecycleHookInput {
	s.LifecycleTransition = &v
	return s
}

// SetNotificationMetadata sets the NotificationMetadata field's value.
func (s *PutLifecycleHookInput) SetNotificationMetadata(v string) *PutLifecycleHookInput {
	s.NotificationMetadata = &v
	return s
}

// SetNotificationTargetARN sets the NotificationTargetARN field's value.
func (s *PutLifecycleHookInput) SetNotificationTargetARN(v string) *PutLifecycleHookInput {
	s.NotificationTargetARN = &v
	return s
}

// SetRoleARN sets the RoleARN field's value.
func (s *PutLifecycleHookInput) SetRoleARN(v string) *PutLifecycleHookInput {
	s.RoleARN = &v
	return s
}

type PutLifecycleHookOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s PutLifecycleHookOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutLifecycleHookOutput) GoString() string {
	return s.String()
}

type PutNotificationConfigurationInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The type of event that causes the notification to be sent. For more information
	// about notification types supported by Amazon EC2 Auto Scaling, see DescribeAutoScalingNotificationTypes.
	//
	// NotificationTypes is a required field
	NotificationTypes []*string `type:"list" required:"true"`

	// The Amazon Resource Name (ARN) of the Amazon Simple Notification Service
	// (Amazon SNS) topic.
	//
	// TopicARN is a required field
	TopicARN *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s PutNotificationConfigurationInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutNotificationConfigurationInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutNotificationConfigurationInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutNotificationConfigurationInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.NotificationTypes == nil {
		invalidParams.Add(request.NewErrParamRequired("NotificationTypes"))
	}
	if s.TopicARN == nil {
		invalidParams.Add(request.NewErrParamRequired("TopicARN"))
	}
	if s.TopicARN != nil && len(*s.TopicARN) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("TopicARN", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *PutNotificationConfigurationInput) SetAutoScalingGroupName(v string) *PutNotificationConfigurationInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetNotificationTypes sets the NotificationTypes field's value.
func (s *PutNotificationConfigurationInput) SetNotificationTypes(v []*string) *PutNotificationConfigurationInput {
	s.NotificationTypes = v
	return s
}

// SetTopicARN sets the TopicARN field's value.
func (s *PutNotificationConfigurationInput) SetTopicARN(v string) *PutNotificationConfigurationInput {
	s.TopicARN = &v
	return s
}

type PutNotificationConfigurationOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s PutNotificationConfigurationOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutNotificationConfigurationOutput) GoString() string {
	return s.String()
}

type PutScalingPolicyInput struct {
	_ struct{} `type:"structure"`

	// The adjustment type. The valid values are ChangeInCapacity, ExactCapacity,
	// and PercentChangeInCapacity.
	//
	// This parameter is supported if the policy type is SimpleScaling or StepScaling.
	//
	// For more information, see Dynamic Scaling (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-scale-based-on-demand.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	AdjustmentType *string `min:"1" type:"string"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The amount of time, in seconds, after a scaling activity completes and before
	// the next scaling activity can start. If this parameter is not specified,
	// the default cooldown period for the group applies.
	//
	// This parameter is supported if the policy type is SimpleScaling.
	//
	// For more information, see Scaling Cooldowns (http://docs.aws.amazon.com/autoscaling/ec2/userguide/Cooldown.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	Cooldown *int64 `type:"integer"`

	// The estimated time, in seconds, until a newly launched instance can contribute
	// to the CloudWatch metrics. The default is to use the value specified for
	// the default cooldown period for the group.
	//
	// This parameter is supported if the policy type is StepScaling or TargetTrackingScaling.
	EstimatedInstanceWarmup *int64 `type:"integer"`

	// The aggregation type for the CloudWatch metrics. The valid values are Minimum,
	// Maximum, and Average. If the aggregation type is null, the value is treated
	// as Average.
	//
	// This parameter is supported if the policy type is StepScaling.
	MetricAggregationType *string `min:"1" type:"string"`

	// The minimum number of instances to scale. If the value of AdjustmentType
	// is PercentChangeInCapacity, the scaling policy changes the DesiredCapacity
	// of the Auto Scaling group by at least this many instances. Otherwise, the
	// error is ValidationError.
	//
	// This parameter is supported if the policy type is SimpleScaling or StepScaling.
	MinAdjustmentMagnitude *int64 `type:"integer"`

	// Available for backward compatibility. Use MinAdjustmentMagnitude instead.
	MinAdjustmentStep *int64 `deprecated:"true" type:"integer"`

	// The name of the policy.
	//
	// PolicyName is a required field
	PolicyName *string `min:"1" type:"string" required:"true"`

	// The policy type. The valid values are SimpleScaling, StepScaling, and TargetTrackingScaling.
	// If the policy type is null, the value is treated as SimpleScaling.
	PolicyType *string `min:"1" type:"string"`

	// The amount by which to scale, based on the specified adjustment type. A positive
	// value adds to the current capacity while a negative number removes from the
	// current capacity.
	//
	// This parameter is required if the policy type is SimpleScaling and not supported
	// otherwise.
	ScalingAdjustment *int64 `type:"integer"`

	// A set of adjustments that enable you to scale based on the size of the alarm
	// breach.
	//
	// This parameter is required if the policy type is StepScaling and not supported
	// otherwise.
	StepAdjustments []*StepAdjustment `type:"list"`

	// A target tracking policy.
	//
	// This parameter is required if the policy type is TargetTrackingScaling and
	// not supported otherwise.
	TargetTrackingConfiguration *TargetTrackingConfiguration `type:"structure"`
}

// String returns the string representation
func (s PutScalingPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutScalingPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutScalingPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutScalingPolicyInput"}
	if s.AdjustmentType != nil && len(*s.AdjustmentType) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AdjustmentType", 1))
	}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.MetricAggregationType != nil && len(*s.MetricAggregationType) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("MetricAggregationType", 1))
	}
	if s.PolicyName == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyName"))
	}
	if s.PolicyName != nil && len(*s.PolicyName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("PolicyName", 1))
	}
	if s.PolicyType != nil && len(*s.PolicyType) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("PolicyType", 1))
	}
	if s.StepAdjustments != nil {
		for i, v := range s.StepAdjustments {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "StepAdjustments", i), err.(request.ErrInvalidParams))
			}
		}
	}
	if s.TargetTrackingConfiguration != nil {
		if err := s.TargetTrackingConfiguration.Validate(); err != nil {
			invalidParams.AddNested("TargetTrackingConfiguration", err.(request.ErrInvalidParams))
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAdjustmentType sets the AdjustmentType field's value.
func (s *PutScalingPolicyInput) SetAdjustmentType(v string) *PutScalingPolicyInput {
	s.AdjustmentType = &v
	return s
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *PutScalingPolicyInput) SetAutoScalingGroupName(v string) *PutScalingPolicyInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetCooldown sets the Cooldown field's value.
func (s *PutScalingPolicyInput) SetCooldown(v int64) *PutScalingPolicyInput {
	s.Cooldown = &v
	return s
}

// SetEstimatedInstanceWarmup sets the EstimatedInstanceWarmup field's value.
func (s *PutScalingPolicyInput) SetEstimatedInstanceWarmup(v int64) *PutScalingPolicyInput {
	s.EstimatedInstanceWarmup = &v
	return s
}

// SetMetricAggregationType sets the MetricAggregationType field's value.
func (s *PutScalingPolicyInput) SetMetricAggregationType(v string) *PutScalingPolicyInput {
	s.MetricAggregationType = &v
	return s
}

// SetMinAdjustmentMagnitude sets the MinAdjustmentMagnitude field's value.
func (s *PutScalingPolicyInput) SetMinAdjustmentMagnitude(v int64) *PutScalingPolicyInput {
	s.MinAdjustmentMagnitude = &v
	return s
}

// SetMinAdjustmentStep sets the MinAdjustmentStep field's value.
func (s *PutScalingPolicyInput) SetMinAdjustmentStep(v int64) *PutScalingPolicyInput {
	s.MinAdjustmentStep = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *PutScalingPolicyInput) SetPolicyName(v string) *PutScalingPolicyInput {
	s.PolicyName = &v
	return s
}

// SetPolicyType sets the PolicyType field's value.
func (s *PutScalingPolicyInput) SetPolicyType(v string) *PutScalingPolicyInput {
	s.PolicyType = &v
	return s
}

// SetScalingAdjustment sets the ScalingAdjustment field's value.
func (s *PutScalingPolicyInput) SetScalingAdjustment(v int64) *PutScalingPolicyInput {
	s.ScalingAdjustment = &v
	return s
}

// SetStepAdjustments sets the StepAdjustments field's value.
func (s *PutScalingPolicyInput) SetStepAdjustments(v []*StepAdjustment) *PutScalingPolicyInput {
	s.StepAdjustments = v
	return s
}

// SetTargetTrackingConfiguration sets the TargetTrackingConfiguration field's value.
func (s *PutScalingPolicyInput) SetTargetTrackingConfiguration(v *TargetTrackingConfiguration) *PutScalingPolicyInput {
	s.TargetTrackingConfiguration = v
	return s
}

// Contains the output of PutScalingPolicy.
type PutScalingPolicyOutput struct {
	_ struct{} `type:"structure"`

	// The CloudWatch alarms created for the target tracking policy.
	Alarms []*Alarm `type:"list"`

	// The Amazon Resource Name (ARN) of the policy.
	PolicyARN *string `min:"1" type:"string"`
}

// String returns the string representation
func (s PutScalingPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutScalingPolicyOutput) GoString() string {
	return s.String()
}

// SetAlarms sets the Alarms field's value.
func (s *PutScalingPolicyOutput) SetAlarms(v []*Alarm) *PutScalingPolicyOutput {
	s.Alarms = v
	return s
}

// SetPolicyARN sets the PolicyARN field's value.
func (s *PutScalingPolicyOutput) SetPolicyARN(v string) *PutScalingPolicyOutput {
	s.PolicyARN = &v
	return s
}

type PutScheduledUpdateGroupActionInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The number of EC2 instances that should be running in the group.
	DesiredCapacity *int64 `type:"integer"`

	// The time for the recurring schedule to end. Amazon EC2 Auto Scaling does
	// not perform the action after this time.
	EndTime *time.Time `type:"timestamp"`

	// The maximum size for the Auto Scaling group.
	MaxSize *int64 `type:"integer"`

	// The minimum size for the Auto Scaling group.
	MinSize *int64 `type:"integer"`

	// The recurring schedule for this action, in Unix cron syntax format. For more
	// information about this format, see Crontab (http://crontab.org).
	Recurrence *string `min:"1" type:"string"`

	// The name of this scaling action.
	//
	// ScheduledActionName is a required field
	ScheduledActionName *string `min:"1" type:"string" required:"true"`

	// The time for this action to start, in "YYYY-MM-DDThh:mm:ssZ" format in UTC/GMT
	// only (for example, 2014-06-01T00:00:00Z).
	//
	// If you specify Recurrence and StartTime, Amazon EC2 Auto Scaling performs
	// the action at this time, and then performs the action based on the specified
	// recurrence.
	//
	// If you try to schedule your action in the past, Amazon EC2 Auto Scaling returns
	// an error message.
	StartTime *time.Time `type:"timestamp"`

	// This parameter is deprecated.
	Time *time.Time `type:"timestamp"`
}

// String returns the string representation
func (s PutScheduledUpdateGroupActionInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutScheduledUpdateGroupActionInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *PutScheduledUpdateGroupActionInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "PutScheduledUpdateGroupActionInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.Recurrence != nil && len(*s.Recurrence) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Recurrence", 1))
	}
	if s.ScheduledActionName == nil {
		invalidParams.Add(request.NewErrParamRequired("ScheduledActionName"))
	}
	if s.ScheduledActionName != nil && len(*s.ScheduledActionName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ScheduledActionName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *PutScheduledUpdateGroupActionInput) SetAutoScalingGroupName(v string) *PutScheduledUpdateGroupActionInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetDesiredCapacity sets the DesiredCapacity field's value.
func (s *PutScheduledUpdateGroupActionInput) SetDesiredCapacity(v int64) *PutScheduledUpdateGroupActionInput {
	s.DesiredCapacity = &v
	return s
}

// SetEndTime sets the EndTime field's value.
func (s *PutScheduledUpdateGroupActionInput) SetEndTime(v time.Time) *PutScheduledUpdateGroupActionInput {
	s.EndTime = &v
	return s
}

// SetMaxSize sets the MaxSize field's value.
func (s *PutScheduledUpdateGroupActionInput) SetMaxSize(v int64) *PutScheduledUpdateGroupActionInput {
	s.MaxSize = &v
	return s
}

// SetMinSize sets the MinSize field's value.
func (s *PutScheduledUpdateGroupActionInput) SetMinSize(v int64) *PutScheduledUpdateGroupActionInput {
	s.MinSize = &v
	return s
}

// SetRecurrence sets the Recurrence field's value.
func (s *PutScheduledUpdateGroupActionInput) SetRecurrence(v string) *PutScheduledUpdateGroupActionInput {
	s.Recurrence = &v
	return s
}

// SetScheduledActionName sets the ScheduledActionName field's value.
func (s *PutScheduledUpdateGroupActionInput) SetScheduledActionName(v string) *PutScheduledUpdateGroupActionInput {
	s.ScheduledActionName = &v
	return s
}

// SetStartTime sets the StartTime field's value.
func (s *PutScheduledUpdateGroupActionInput) SetStartTime(v time.Time) *PutScheduledUpdateGroupActionInput {
	s.StartTime = &v
	return s
}

// SetTime sets the Time field's value.
func (s *PutScheduledUpdateGroupActionInput) SetTime(v time.Time) *PutScheduledUpdateGroupActionInput {
	s.Time = &v
	return s
}

type PutScheduledUpdateGroupActionOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s PutScheduledUpdateGroupActionOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PutScheduledUpdateGroupActionOutput) GoString() string {
	return s.String()
}

type RecordLifecycleActionHeartbeatInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The ID of the instance.
	InstanceId *string `min:"1" type:"string"`

	// A token that uniquely identifies a specific lifecycle action associated with
	// an instance. Amazon EC2 Auto Scaling sends this token to the notification
	// target that you specified when you created the lifecycle hook.
	LifecycleActionToken *string `min:"36" type:"string"`

	// The name of the lifecycle hook.
	//
	// LifecycleHookName is a required field
	LifecycleHookName *string `min:"1" type:"string" required:"true"`
}

// String returns the string representation
func (s RecordLifecycleActionHeartbeatInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s RecordLifecycleActionHeartbeatInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *RecordLifecycleActionHeartbeatInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "RecordLifecycleActionHeartbeatInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.InstanceId != nil && len(*s.InstanceId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("InstanceId", 1))
	}
	if s.LifecycleActionToken != nil && len(*s.LifecycleActionToken) < 36 {
		invalidParams.Add(request.NewErrParamMinLen("LifecycleActionToken", 36))
	}
	if s.LifecycleHookName == nil {
		invalidParams.Add(request.NewErrParamRequired("LifecycleHookName"))
	}
	if s.LifecycleHookName != nil && len(*s.LifecycleHookName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LifecycleHookName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *RecordLifecycleActionHeartbeatInput) SetAutoScalingGroupName(v string) *RecordLifecycleActionHeartbeatInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetInstanceId sets the InstanceId field's value.
func (s *RecordLifecycleActionHeartbeatInput) SetInstanceId(v string) *RecordLifecycleActionHeartbeatInput {
	s.InstanceId = &v
	return s
}

// SetLifecycleActionToken sets the LifecycleActionToken field's value.
func (s *RecordLifecycleActionHeartbeatInput) SetLifecycleActionToken(v string) *RecordLifecycleActionHeartbeatInput {
	s.LifecycleActionToken = &v
	return s
}

// SetLifecycleHookName sets the LifecycleHookName field's value.
func (s *RecordLifecycleActionHeartbeatInput) SetLifecycleHookName(v string) *RecordLifecycleActionHeartbeatInput {
	s.LifecycleHookName = &v
	return s
}

type RecordLifecycleActionHeartbeatOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s RecordLifecycleActionHeartbeatOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s RecordLifecycleActionHeartbeatOutput) GoString() string {
	return s.String()
}

type ResumeProcessesOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s ResumeProcessesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ResumeProcessesOutput) GoString() string {
	return s.String()
}

// Describes a scaling policy.
type ScalingPolicy struct {
	_ struct{} `type:"structure"`

	// The adjustment type, which specifies how ScalingAdjustment is interpreted.
	// Valid values are ChangeInCapacity, ExactCapacity, and PercentChangeInCapacity.
	AdjustmentType *string `min:"1" type:"string"`

	// The CloudWatch alarms related to the policy.
	Alarms []*Alarm `type:"list"`

	// The name of the Auto Scaling group.
	AutoScalingGroupName *string `min:"1" type:"string"`

	// The amount of time, in seconds, after a scaling activity completes before
	// any further dynamic scaling activities can start.
	Cooldown *int64 `type:"integer"`

	// The estimated time, in seconds, until a newly launched instance can contribute
	// to the CloudWatch metrics.
	EstimatedInstanceWarmup *int64 `type:"integer"`

	// The aggregation type for the CloudWatch metrics. Valid values are Minimum,
	// Maximum, and Average.
	MetricAggregationType *string `min:"1" type:"string"`

	// The minimum number of instances to scale. If the value of AdjustmentType
	// is PercentChangeInCapacity, the scaling policy changes the DesiredCapacity
	// of the Auto Scaling group by at least this many instances. Otherwise, the
	// error is ValidationError.
	MinAdjustmentMagnitude *int64 `type:"integer"`

	// Available for backward compatibility. Use MinAdjustmentMagnitude instead.
	MinAdjustmentStep *int64 `deprecated:"true" type:"integer"`

	// The Amazon Resource Name (ARN) of the policy.
	PolicyARN *string `min:"1" type:"string"`

	// The name of the scaling policy.
	PolicyName *string `min:"1" type:"string"`

	// The policy type. Valid values are SimpleScaling and StepScaling.
	PolicyType *string `min:"1" type:"string"`

	// The amount by which to scale, based on the specified adjustment type. A positive
	// value adds to the current capacity while a negative number removes from the
	// current capacity.
	ScalingAdjustment *int64 `type:"integer"`

	// A set of adjustments that enable you to scale based on the size of the alarm
	// breach.
	StepAdjustments []*StepAdjustment `type:"list"`

	// A target tracking policy.
	TargetTrackingConfiguration *TargetTrackingConfiguration `type:"structure"`
}

// String returns the string representation
func (s ScalingPolicy) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ScalingPolicy) GoString() string {
	return s.String()
}

// SetAdjustmentType sets the AdjustmentType field's value.
func (s *ScalingPolicy) SetAdjustmentType(v string) *ScalingPolicy {
	s.AdjustmentType = &v
	return s
}

// SetAlarms sets the Alarms field's value.
func (s *ScalingPolicy) SetAlarms(v []*Alarm) *ScalingPolicy {
	s.Alarms = v
	return s
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *ScalingPolicy) SetAutoScalingGroupName(v string) *ScalingPolicy {
	s.AutoScalingGroupName = &v
	return s
}

// SetCooldown sets the Cooldown field's value.
func (s *ScalingPolicy) SetCooldown(v int64) *ScalingPolicy {
	s.Cooldown = &v
	return s
}

// SetEstimatedInstanceWarmup sets the EstimatedInstanceWarmup field's value.
func (s *ScalingPolicy) SetEstimatedInstanceWarmup(v int64) *ScalingPolicy {
	s.EstimatedInstanceWarmup = &v
	return s
}

// SetMetricAggregationType sets the MetricAggregationType field's value.
func (s *ScalingPolicy) SetMetricAggregationType(v string) *ScalingPolicy {
	s.MetricAggregationType = &v
	return s
}

// SetMinAdjustmentMagnitude sets the MinAdjustmentMagnitude field's value.
func (s *ScalingPolicy) SetMinAdjustmentMagnitude(v int64) *ScalingPolicy {
	s.MinAdjustmentMagnitude = &v
	return s
}

// SetMinAdjustmentStep sets the MinAdjustmentStep field's value.
func (s *ScalingPolicy) SetMinAdjustmentStep(v int64) *ScalingPolicy {
	s.MinAdjustmentStep = &v
	return s
}

// SetPolicyARN sets the PolicyARN field's value.
func (s *ScalingPolicy) SetPolicyARN(v string) *ScalingPolicy {
	s.PolicyARN = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *ScalingPolicy) SetPolicyName(v string) *ScalingPolicy {
	s.PolicyName = &v
	return s
}

// SetPolicyType sets the PolicyType field's value.
func (s *ScalingPolicy) SetPolicyType(v string) *ScalingPolicy {
	s.PolicyType = &v
	return s
}

// SetScalingAdjustment sets the ScalingAdjustment field's value.
func (s *ScalingPolicy) SetScalingAdjustment(v int64) *ScalingPolicy {
	s.ScalingAdjustment = &v
	return s
}

// SetStepAdjustments sets the StepAdjustments field's value.
func (s *ScalingPolicy) SetStepAdjustments(v []*StepAdjustment) *ScalingPolicy {
	s.StepAdjustments = v
	return s
}

// SetTargetTrackingConfiguration sets the TargetTrackingConfiguration field's value.
func (s *ScalingPolicy) SetTargetTrackingConfiguration(v *TargetTrackingConfiguration) *ScalingPolicy {
	s.TargetTrackingConfiguration = v
	return s
}

type ScalingProcessQuery struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// One or more of the following processes. If you omit this parameter, all processes
	// are specified.
	//
	//    * Launch
	//
	//    * Terminate
	//
	//    * HealthCheck
	//
	//    * ReplaceUnhealthy
	//
	//    * AZRebalance
	//
	//    * AlarmNotification
	//
	//    * ScheduledActions
	//
	//    * AddToLoadBalancer
	ScalingProcesses []*string `type:"list"`
}

// String returns the string representation
func (s ScalingProcessQuery) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ScalingProcessQuery) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ScalingProcessQuery) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ScalingProcessQuery"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *ScalingProcessQuery) SetAutoScalingGroupName(v string) *ScalingProcessQuery {
	s.AutoScalingGroupName = &v
	return s
}

// SetScalingProcesses sets the ScalingProcesses field's value.
func (s *ScalingProcessQuery) SetScalingProcesses(v []*string) *ScalingProcessQuery {
	s.ScalingProcesses = v
	return s
}

// Describes a scheduled scaling action. Used in response to DescribeScheduledActions.
type ScheduledUpdateGroupAction struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	AutoScalingGroupName *string `min:"1" type:"string"`

	// The number of instances you prefer to maintain in the group.
	DesiredCapacity *int64 `type:"integer"`

	// The date and time that the action is scheduled to end. This date and time
	// can be up to one month in the future.
	EndTime *time.Time `type:"timestamp"`

	// The maximum size of the group.
	MaxSize *int64 `type:"integer"`

	// The minimum size of the group.
	MinSize *int64 `type:"integer"`

	// The recurring schedule for the action.
	Recurrence *string `min:"1" type:"string"`

	// The Amazon Resource Name (ARN) of the scheduled action.
	ScheduledActionARN *string `min:"1" type:"string"`

	// The name of the scheduled action.
	ScheduledActionName *string `min:"1" type:"string"`

	// The date and time that the action is scheduled to begin. This date and time
	// can be up to one month in the future.
	//
	// When StartTime and EndTime are specified with Recurrence, they form the boundaries
	// of when the recurring action starts and stops.
	StartTime *time.Time `type:"timestamp"`

	// This parameter is deprecated.
	Time *time.Time `type:"timestamp"`
}

// String returns the string representation
func (s ScheduledUpdateGroupAction) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ScheduledUpdateGroupAction) GoString() string {
	return s.String()
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *ScheduledUpdateGroupAction) SetAutoScalingGroupName(v string) *ScheduledUpdateGroupAction {
	s.AutoScalingGroupName = &v
	return s
}

// SetDesiredCapacity sets the DesiredCapacity field's value.
func (s *ScheduledUpdateGroupAction) SetDesiredCapacity(v int64) *ScheduledUpdateGroupAction {
	s.DesiredCapacity = &v
	return s
}

// SetEndTime sets the EndTime field's value.
func (s *ScheduledUpdateGroupAction) SetEndTime(v time.Time) *ScheduledUpdateGroupAction {
	s.EndTime = &v
	return s
}

// SetMaxSize sets the MaxSize field's value.
func (s *ScheduledUpdateGroupAction) SetMaxSize(v int64) *ScheduledUpdateGroupAction {
	s.MaxSize = &v
	return s
}

// SetMinSize sets the MinSize field's value.
func (s *ScheduledUpdateGroupAction) SetMinSize(v int64) *ScheduledUpdateGroupAction {
	s.MinSize = &v
	return s
}

// SetRecurrence sets the Recurrence field's value.
func (s *ScheduledUpdateGroupAction) SetRecurrence(v string) *ScheduledUpdateGroupAction {
	s.Recurrence = &v
	return s
}

// SetScheduledActionARN sets the ScheduledActionARN field's value.
func (s *ScheduledUpdateGroupAction) SetScheduledActionARN(v string) *ScheduledUpdateGroupAction {
	s.ScheduledActionARN = &v
	return s
}

// SetScheduledActionName sets the ScheduledActionName field's value.
func (s *ScheduledUpdateGroupAction) SetScheduledActionName(v string) *ScheduledUpdateGroupAction {
	s.ScheduledActionName = &v
	return s
}

// SetStartTime sets the StartTime field's value.
func (s *ScheduledUpdateGroupAction) SetStartTime(v time.Time) *ScheduledUpdateGroupAction {
	s.StartTime = &v
	return s
}

// SetTime sets the Time field's value.
func (s *ScheduledUpdateGroupAction) SetTime(v time.Time) *ScheduledUpdateGroupAction {
	s.Time = &v
	return s
}

// Describes one or more scheduled scaling action updates for a specified Auto
// Scaling group. Used in combination with BatchPutScheduledUpdateGroupAction.
//
// When updating a scheduled scaling action, all optional parameters are left
// unchanged if not specified.
type ScheduledUpdateGroupActionRequest struct {
	_ struct{} `type:"structure"`

	// The number of EC2 instances that should be running in the group.
	DesiredCapacity *int64 `type:"integer"`

	// The time for the recurring schedule to end. Amazon EC2 Auto Scaling does
	// not perform the action after this time.
	EndTime *time.Time `type:"timestamp"`

	// The maximum size of the group.
	MaxSize *int64 `type:"integer"`

	// The minimum size of the group.
	MinSize *int64 `type:"integer"`

	// The recurring schedule for the action, in Unix cron syntax format. For more
	// information about this format, see Crontab (http://crontab.org).
	Recurrence *string `min:"1" type:"string"`

	// The name of the scaling action.
	//
	// ScheduledActionName is a required field
	ScheduledActionName *string `min:"1" type:"string" required:"true"`

	// The time for the action to start, in "YYYY-MM-DDThh:mm:ssZ" format in UTC/GMT
	// only (for example, 2014-06-01T00:00:00Z).
	//
	// If you specify Recurrence and StartTime, Amazon EC2 Auto Scaling performs
	// the action at this time, and then performs the action based on the specified
	// recurrence.
	//
	// If you try to schedule the action in the past, Amazon EC2 Auto Scaling returns
	// an error message.
	StartTime *time.Time `type:"timestamp"`
}

// String returns the string representation
func (s ScheduledUpdateGroupActionRequest) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ScheduledUpdateGroupActionRequest) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ScheduledUpdateGroupActionRequest) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ScheduledUpdateGroupActionRequest"}
	if s.Recurrence != nil && len(*s.Recurrence) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Recurrence", 1))
	}
	if s.ScheduledActionName == nil {
		invalidParams.Add(request.NewErrParamRequired("ScheduledActionName"))
	}
	if s.ScheduledActionName != nil && len(*s.ScheduledActionName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ScheduledActionName", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetDesiredCapacity sets the DesiredCapacity field's value.
func (s *ScheduledUpdateGroupActionRequest) SetDesiredCapacity(v int64) *ScheduledUpdateGroupActionRequest {
	s.DesiredCapacity = &v
	return s
}

// SetEndTime sets the EndTime field's value.
func (s *ScheduledUpdateGroupActionRequest) SetEndTime(v time.Time) *ScheduledUpdateGroupActionRequest {
	s.EndTime = &v
	return s
}

// SetMaxSize sets the MaxSize field's value.
func (s *ScheduledUpdateGroupActionRequest) SetMaxSize(v int64) *ScheduledUpdateGroupActionRequest {
	s.MaxSize = &v
	return s
}

// SetMinSize sets the MinSize field's value.
func (s *ScheduledUpdateGroupActionRequest) SetMinSize(v int64) *ScheduledUpdateGroupActionRequest {
	s.MinSize = &v
	return s
}

// SetRecurrence sets the Recurrence field's value.
func (s *ScheduledUpdateGroupActionRequest) SetRecurrence(v string) *ScheduledUpdateGroupActionRequest {
	s.Recurrence = &v
	return s
}

// SetScheduledActionName sets the ScheduledActionName field's value.
func (s *ScheduledUpdateGroupActionRequest) SetScheduledActionName(v string) *ScheduledUpdateGroupActionRequest {
	s.ScheduledActionName = &v
	return s
}

// SetStartTime sets the StartTime field's value.
func (s *ScheduledUpdateGroupActionRequest) SetStartTime(v time.Time) *ScheduledUpdateGroupActionRequest {
	s.StartTime = &v
	return s
}

type SetDesiredCapacityInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// The number of EC2 instances that should be running in the Auto Scaling group.
	//
	// DesiredCapacity is a required field
	DesiredCapacity *int64 `type:"integer" required:"true"`

	// Indicates whether Amazon EC2 Auto Scaling waits for the cooldown period to
	// complete before initiating a scaling activity to set your Auto Scaling group
	// to its new capacity. By default, Amazon EC2 Auto Scaling does not honor the
	// cooldown period during manual scaling activities.
	HonorCooldown *bool `type:"boolean"`
}

// String returns the string representation
func (s SetDesiredCapacityInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetDesiredCapacityInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *SetDesiredCapacityInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "SetDesiredCapacityInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.DesiredCapacity == nil {
		invalidParams.Add(request.NewErrParamRequired("DesiredCapacity"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *SetDesiredCapacityInput) SetAutoScalingGroupName(v string) *SetDesiredCapacityInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetDesiredCapacity sets the DesiredCapacity field's value.
func (s *SetDesiredCapacityInput) SetDesiredCapacity(v int64) *SetDesiredCapacityInput {
	s.DesiredCapacity = &v
	return s
}

// SetHonorCooldown sets the HonorCooldown field's value.
func (s *SetDesiredCapacityInput) SetHonorCooldown(v bool) *SetDesiredCapacityInput {
	s.HonorCooldown = &v
	return s
}

type SetDesiredCapacityOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s SetDesiredCapacityOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetDesiredCapacityOutput) GoString() string {
	return s.String()
}

type SetInstanceHealthInput struct {
	_ struct{} `type:"structure"`

	// The health status of the instance. Set to Healthy to have the instance remain
	// in service. Set to Unhealthy to have the instance be out of service. Amazon
	// EC2 Auto Scaling terminates and replaces the unhealthy instance.
	//
	// HealthStatus is a required field
	HealthStatus *string `min:"1" type:"string" required:"true"`

	// The ID of the instance.
	//
	// InstanceId is a required field
	InstanceId *string `min:"1" type:"string" required:"true"`

	// If the Auto Scaling group of the specified instance has a HealthCheckGracePeriod
	// specified for the group, by default, this call respects the grace period.
	// Set this to False, to have the call not respect the grace period associated
	// with the group.
	//
	// For more information about the health check grace period, see CreateAutoScalingGroup.
	ShouldRespectGracePeriod *bool `type:"boolean"`
}

// String returns the string representation
func (s SetInstanceHealthInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetInstanceHealthInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *SetInstanceHealthInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "SetInstanceHealthInput"}
	if s.HealthStatus == nil {
		invalidParams.Add(request.NewErrParamRequired("HealthStatus"))
	}
	if s.HealthStatus != nil && len(*s.HealthStatus) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("HealthStatus", 1))
	}
	if s.InstanceId == nil {
		invalidParams.Add(request.NewErrParamRequired("InstanceId"))
	}
	if s.InstanceId != nil && len(*s.InstanceId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("InstanceId", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetHealthStatus sets the HealthStatus field's value.
func (s *SetInstanceHealthInput) SetHealthStatus(v string) *SetInstanceHealthInput {
	s.HealthStatus = &v
	return s
}

// SetInstanceId sets the InstanceId field's value.
func (s *SetInstanceHealthInput) SetInstanceId(v string) *SetInstanceHealthInput {
	s.InstanceId = &v
	return s
}

// SetShouldRespectGracePeriod sets the ShouldRespectGracePeriod field's value.
func (s *SetInstanceHealthInput) SetShouldRespectGracePeriod(v bool) *SetInstanceHealthInput {
	s.ShouldRespectGracePeriod = &v
	return s
}

type SetInstanceHealthOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s SetInstanceHealthOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetInstanceHealthOutput) GoString() string {
	return s.String()
}

type SetInstanceProtectionInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// One or more instance IDs.
	//
	// InstanceIds is a required field
	InstanceIds []*string `type:"list" required:"true"`

	// Indicates whether the instance is protected from termination by Amazon EC2
	// Auto Scaling when scaling in.
	//
	// ProtectedFromScaleIn is a required field
	ProtectedFromScaleIn *bool `type:"boolean" required:"true"`
}

// String returns the string representation
func (s SetInstanceProtectionInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetInstanceProtectionInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *SetInstanceProtectionInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "SetInstanceProtectionInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.InstanceIds == nil {
		invalidParams.Add(request.NewErrParamRequired("InstanceIds"))
	}
	if s.ProtectedFromScaleIn == nil {
		invalidParams.Add(request.NewErrParamRequired("ProtectedFromScaleIn"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *SetInstanceProtectionInput) SetAutoScalingGroupName(v string) *SetInstanceProtectionInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetInstanceIds sets the InstanceIds field's value.
func (s *SetInstanceProtectionInput) SetInstanceIds(v []*string) *SetInstanceProtectionInput {
	s.InstanceIds = v
	return s
}

// SetProtectedFromScaleIn sets the ProtectedFromScaleIn field's value.
func (s *SetInstanceProtectionInput) SetProtectedFromScaleIn(v bool) *SetInstanceProtectionInput {
	s.ProtectedFromScaleIn = &v
	return s
}

type SetInstanceProtectionOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s SetInstanceProtectionOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetInstanceProtectionOutput) GoString() string {
	return s.String()
}

// Describes an adjustment based on the difference between the value of the
// aggregated CloudWatch metric and the breach threshold that you've defined
// for the alarm.
//
// For the following examples, suppose that you have an alarm with a breach
// threshold of 50:
//
//    * To trigger the adjustment when the metric is greater than or equal to
//    50 and less than 60, specify a lower bound of 0 and an upper bound of
//    10.
//
//    * To trigger the adjustment when the metric is greater than 40 and less
//    than or equal to 50, specify a lower bound of -10 and an upper bound of
//    0.
//
// There are a few rules for the step adjustments for your step policy:
//
//    * The ranges of your step adjustments can't overlap or have a gap.
//
//    * At most, one step adjustment can have a null lower bound. If one step
//    adjustment has a negative lower bound, then there must be a step adjustment
//    with a null lower bound.
//
//    * At most, one step adjustment can have a null upper bound. If one step
//    adjustment has a positive upper bound, then there must be a step adjustment
//    with a null upper bound.
//
//    * The upper and lower bound can't be null in the same step adjustment.
type StepAdjustment struct {
	_ struct{} `type:"structure"`

	// The lower bound for the difference between the alarm threshold and the CloudWatch
	// metric. If the metric value is above the breach threshold, the lower bound
	// is inclusive (the metric must be greater than or equal to the threshold plus
	// the lower bound). Otherwise, it is exclusive (the metric must be greater
	// than the threshold plus the lower bound). A null value indicates negative
	// infinity.
	MetricIntervalLowerBound *float64 `type:"double"`

	// The upper bound for the difference between the alarm threshold and the CloudWatch
	// metric. If the metric value is above the breach threshold, the upper bound
	// is exclusive (the metric must be less than the threshold plus the upper bound).
	// Otherwise, it is inclusive (the metric must be less than or equal to the
	// threshold plus the upper bound). A null value indicates positive infinity.
	//
	// The upper bound must be greater than the lower bound.
	MetricIntervalUpperBound *float64 `type:"double"`

	// The amount by which to scale, based on the specified adjustment type. A positive
	// value adds to the current capacity while a negative number removes from the
	// current capacity.
	//
	// ScalingAdjustment is a required field
	ScalingAdjustment *int64 `type:"integer" required:"true"`
}

// String returns the string representation
func (s StepAdjustment) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s StepAdjustment) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *StepAdjustment) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "StepAdjustment"}
	if s.ScalingAdjustment == nil {
		invalidParams.Add(request.NewErrParamRequired("ScalingAdjustment"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetMetricIntervalLowerBound sets the MetricIntervalLowerBound field's value.
func (s *StepAdjustment) SetMetricIntervalLowerBound(v float64) *StepAdjustment {
	s.MetricIntervalLowerBound = &v
	return s
}

// SetMetricIntervalUpperBound sets the MetricIntervalUpperBound field's value.
func (s *StepAdjustment) SetMetricIntervalUpperBound(v float64) *StepAdjustment {
	s.MetricIntervalUpperBound = &v
	return s
}

// SetScalingAdjustment sets the ScalingAdjustment field's value.
func (s *StepAdjustment) SetScalingAdjustment(v int64) *StepAdjustment {
	s.ScalingAdjustment = &v
	return s
}

type SuspendProcessesOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s SuspendProcessesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SuspendProcessesOutput) GoString() string {
	return s.String()
}

// Describes an automatic scaling process that has been suspended. For more
// information, see ProcessType.
type SuspendedProcess struct {
	_ struct{} `type:"structure"`

	// The name of the suspended process.
	ProcessName *string `min:"1" type:"string"`

	// The reason that the process was suspended.
	SuspensionReason *string `min:"1" type:"string"`
}

// String returns the string representation
func (s SuspendedProcess) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SuspendedProcess) GoString() string {
	return s.String()
}

// SetProcessName sets the ProcessName field's value.
func (s *SuspendedProcess) SetProcessName(v string) *SuspendedProcess {
	s.ProcessName = &v
	return s
}

// SetSuspensionReason sets the SuspensionReason field's value.
func (s *SuspendedProcess) SetSuspensionReason(v string) *SuspendedProcess {
	s.SuspensionReason = &v
	return s
}

// Describes a tag for an Auto Scaling group.
type Tag struct {
	_ struct{} `type:"structure"`

	// The tag key.
	//
	// Key is a required field
	Key *string `min:"1" type:"string" required:"true"`

	// Determines whether the tag is added to new instances as they are launched
	// in the group.
	PropagateAtLaunch *bool `type:"boolean"`

	// The name of the group.
	ResourceId *string `type:"string"`

	// The type of resource. The only supported value is auto-scaling-group.
	ResourceType *string `type:"string"`

	// The tag value.
	Value *string `type:"string"`
}

// String returns the string representation
func (s Tag) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Tag) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *Tag) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "Tag"}
	if s.Key == nil {
		invalidParams.Add(request.NewErrParamRequired("Key"))
	}
	if s.Key != nil && len(*s.Key) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetKey sets the Key field's value.
func (s *Tag) SetKey(v string) *Tag {
	s.Key = &v
	return s
}

// SetPropagateAtLaunch sets the PropagateAtLaunch field's value.
func (s *Tag) SetPropagateAtLaunch(v bool) *Tag {
	s.PropagateAtLaunch = &v
	return s
}

// SetResourceId sets the ResourceId field's value.
func (s *Tag) SetResourceId(v string) *Tag {
	s.ResourceId = &v
	return s
}

// SetResourceType sets the ResourceType field's value.
func (s *Tag) SetResourceType(v string) *Tag {
	s.ResourceType = &v
	return s
}

// SetValue sets the Value field's value.
func (s *Tag) SetValue(v string) *Tag {
	s.Value = &v
	return s
}

// Describes a tag for an Auto Scaling group.
type TagDescription struct {
	_ struct{} `type:"structure"`

	// The tag key.
	Key *string `min:"1" type:"string"`

	// Determines whether the tag is added to new instances as they are launched
	// in the group.
	PropagateAtLaunch *bool `type:"boolean"`

	// The name of the group.
	ResourceId *string `type:"string"`

	// The type of resource. The only supported value is auto-scaling-group.
	ResourceType *string `type:"string"`

	// The tag value.
	Value *string `type:"string"`
}

// String returns the string representation
func (s TagDescription) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s TagDescription) GoString() string {
	return s.String()
}

// SetKey sets the Key field's value.
func (s *TagDescription) SetKey(v string) *TagDescription {
	s.Key = &v
	return s
}

// SetPropagateAtLaunch sets the PropagateAtLaunch field's value.
func (s *TagDescription) SetPropagateAtLaunch(v bool) *TagDescription {
	s.PropagateAtLaunch = &v
	return s
}

// SetResourceId sets the ResourceId field's value.
func (s *TagDescription) SetResourceId(v string) *TagDescription {
	s.ResourceId = &v
	return s
}

// SetResourceType sets the ResourceType field's value.
func (s *TagDescription) SetResourceType(v string) *TagDescription {
	s.ResourceType = &v
	return s
}

// SetValue sets the Value field's value.
func (s *TagDescription) SetValue(v string) *TagDescription {
	s.Value = &v
	return s
}

// Represents a target tracking policy configuration.
type TargetTrackingConfiguration struct {
	_ struct{} `type:"structure"`

	// A customized metric.
	CustomizedMetricSpecification *CustomizedMetricSpecification `type:"structure"`

	// Indicates whether scaling in by the target tracking policy is disabled. If
	// scaling in is disabled, the target tracking policy doesn't remove instances
	// from the Auto Scaling group. Otherwise, the target tracking policy can remove
	// instances from the Auto Scaling group. The default is disabled.
	DisableScaleIn *bool `type:"boolean"`

	// A predefined metric. You can specify either a predefined metric or a customized
	// metric.
	PredefinedMetricSpecification *PredefinedMetricSpecification `type:"structure"`

	// The target value for the metric.
	//
	// TargetValue is a required field
	TargetValue *float64 `type:"double" required:"true"`
}

// String returns the string representation
func (s TargetTrackingConfiguration) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s TargetTrackingConfiguration) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *TargetTrackingConfiguration) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "TargetTrackingConfiguration"}
	if s.TargetValue == nil {
		invalidParams.Add(request.NewErrParamRequired("TargetValue"))
	}
	if s.CustomizedMetricSpecification != nil {
		if err := s.CustomizedMetricSpecification.Validate(); err != nil {
			invalidParams.AddNested("CustomizedMetricSpecification", err.(request.ErrInvalidParams))
		}
	}
	if s.PredefinedMetricSpecification != nil {
		if err := s.PredefinedMetricSpecification.Validate(); err != nil {
			invalidParams.AddNested("PredefinedMetricSpecification", err.(request.ErrInvalidParams))
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetCustomizedMetricSpecification sets the CustomizedMetricSpecification field's value.
func (s *TargetTrackingConfiguration) SetCustomizedMetricSpecification(v *CustomizedMetricSpecification) *TargetTrackingConfiguration {
	s.CustomizedMetricSpecification = v
	return s
}

// SetDisableScaleIn sets the DisableScaleIn field's value.
func (s *TargetTrackingConfiguration) SetDisableScaleIn(v bool) *TargetTrackingConfiguration {
	s.DisableScaleIn = &v
	return s
}

// SetPredefinedMetricSpecification sets the PredefinedMetricSpecification field's value.
func (s *TargetTrackingConfiguration) SetPredefinedMetricSpecification(v *PredefinedMetricSpecification) *TargetTrackingConfiguration {
	s.PredefinedMetricSpecification = v
	return s
}

// SetTargetValue sets the TargetValue field's value.
func (s *TargetTrackingConfiguration) SetTargetValue(v float64) *TargetTrackingConfiguration {
	s.TargetValue = &v
	return s
}

type TerminateInstanceInAutoScalingGroupInput struct {
	_ struct{} `type:"structure"`

	// The ID of the instance.
	//
	// InstanceId is a required field
	InstanceId *string `min:"1" type:"string" required:"true"`

	// Indicates whether terminating the instance also decrements the size of the
	// Auto Scaling group.
	//
	// ShouldDecrementDesiredCapacity is a required field
	ShouldDecrementDesiredCapacity *bool `type:"boolean" required:"true"`
}

// String returns the string representation
func (s TerminateInstanceInAutoScalingGroupInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s TerminateInstanceInAutoScalingGroupInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *TerminateInstanceInAutoScalingGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "TerminateInstanceInAutoScalingGroupInput"}
	if s.InstanceId == nil {
		invalidParams.Add(request.NewErrParamRequired("InstanceId"))
	}
	if s.InstanceId != nil && len(*s.InstanceId) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("InstanceId", 1))
	}
	if s.ShouldDecrementDesiredCapacity == nil {
		invalidParams.Add(request.NewErrParamRequired("ShouldDecrementDesiredCapacity"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetInstanceId sets the InstanceId field's value.
func (s *TerminateInstanceInAutoScalingGroupInput) SetInstanceId(v string) *TerminateInstanceInAutoScalingGroupInput {
	s.InstanceId = &v
	return s
}

// SetShouldDecrementDesiredCapacity sets the ShouldDecrementDesiredCapacity field's value.
func (s *TerminateInstanceInAutoScalingGroupInput) SetShouldDecrementDesiredCapacity(v bool) *TerminateInstanceInAutoScalingGroupInput {
	s.ShouldDecrementDesiredCapacity = &v
	return s
}

type TerminateInstanceInAutoScalingGroupOutput struct {
	_ struct{} `type:"structure"`

	// A scaling activity.
	Activity *Activity `type:"structure"`
}

// String returns the string representation
func (s TerminateInstanceInAutoScalingGroupOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s TerminateInstanceInAutoScalingGroupOutput) GoString() string {
	return s.String()
}

// SetActivity sets the Activity field's value.
func (s *TerminateInstanceInAutoScalingGroupOutput) SetActivity(v *Activity) *TerminateInstanceInAutoScalingGroupOutput {
	s.Activity = v
	return s
}

type UpdateAutoScalingGroupInput struct {
	_ struct{} `type:"structure"`

	// The name of the Auto Scaling group.
	//
	// AutoScalingGroupName is a required field
	AutoScalingGroupName *string `min:"1" type:"string" required:"true"`

	// One or more Availability Zones for the group.
	AvailabilityZones []*string `min:"1" type:"list"`

	// The amount of time, in seconds, after a scaling activity completes before
	// another scaling activity can start. The default is 300.
	//
	// For more information, see Scaling Cooldowns (http://docs.aws.amazon.com/autoscaling/ec2/userguide/Cooldown.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	DefaultCooldown *int64 `type:"integer"`

	// The number of EC2 instances that should be running in the Auto Scaling group.
	// This number must be greater than or equal to the minimum size of the group
	// and less than or equal to the maximum size of the group.
	DesiredCapacity *int64 `type:"integer"`

	// The amount of time, in seconds, that Amazon EC2 Auto Scaling waits before
	// checking the health status of an EC2 instance that has come into service.
	// The default is 0.
	//
	// For more information, see Health Checks (http://docs.aws.amazon.com/autoscaling/ec2/userguide/healthcheck.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	HealthCheckGracePeriod *int64 `type:"integer"`

	// The service to use for the health checks. The valid values are EC2 and ELB.
	HealthCheckType *string `min:"1" type:"string"`

	// The name of the launch configuration. If you specify this parameter, you
	// can't specify a launch template or a mixed instances policy.
	LaunchConfigurationName *string `min:"1" type:"string"`

	// The launch template and version to use to specify the updates. If you specify
	// this parameter, you can't specify a launch configuration or a mixed instances
	// policy.
	LaunchTemplate *LaunchTemplateSpecification `type:"structure"`

	// The maximum size of the Auto Scaling group.
	MaxSize *int64 `type:"integer"`

	// The minimum size of the Auto Scaling group.
	MinSize *int64 `type:"integer"`

	// The mixed instances policy to use to specify the updates. If you specify
	// this parameter, you can't specify a launch configuration or a launch template.
	MixedInstancesPolicy *MixedInstancesPolicy `type:"structure"`

	// Indicates whether newly launched instances are protected from termination
	// by Auto Scaling when scaling in.
	NewInstancesProtectedFromScaleIn *bool `type:"boolean"`

	// The name of the placement group into which to launch your instances, if any.
	// For more information, see Placement Groups (http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html)
	// in the Amazon Elastic Compute Cloud User Guide.
	PlacementGroup *string `min:"1" type:"string"`

	// The Amazon Resource Name (ARN) of the service-linked role that the Auto Scaling
	// group uses to call other AWS services on your behalf.
	ServiceLinkedRoleARN *string `min:"1" type:"string"`

	// A standalone termination policy or a list of termination policies used to
	// select the instance to terminate. The policies are executed in the order
	// that they are listed.
	//
	// For more information, see Controlling Which Instances Auto Scaling Terminates
	// During Scale In (http://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html)
	// in the Auto Scaling User Guide.
	TerminationPolicies []*string `type:"list"`

	// The ID of the subnet, if you are launching into a VPC. You can specify several
	// subnets in a comma-separated list.
	//
	// When you specify VPCZoneIdentifier with AvailabilityZones, ensure that the
	// subnets' Availability Zones match the values you specify for AvailabilityZones.
	//
	// For more information, see Launching Auto Scaling Instances in a VPC (http://docs.aws.amazon.com/autoscaling/ec2/userguide/asg-in-vpc.html)
	// in the Amazon EC2 Auto Scaling User Guide.
	VPCZoneIdentifier *string `min:"1" type:"string"`
}

// String returns the string representation
func (s UpdateAutoScalingGroupInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s UpdateAutoScalingGroupInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *UpdateAutoScalingGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "UpdateAutoScalingGroupInput"}
	if s.AutoScalingGroupName == nil {
		invalidParams.Add(request.NewErrParamRequired("AutoScalingGroupName"))
	}
	if s.AutoScalingGroupName != nil && len(*s.AutoScalingGroupName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AutoScalingGroupName", 1))
	}
	if s.AvailabilityZones != nil && len(s.AvailabilityZones) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("AvailabilityZones", 1))
	}
	if s.HealthCheckType != nil && len(*s.HealthCheckType) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("HealthCheckType", 1))
	}
	if s.LaunchConfigurationName != nil && len(*s.LaunchConfigurationName) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LaunchConfigurationName", 1))
	}
	if s.PlacementGroup != nil && len(*s.PlacementGroup) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("PlacementGroup", 1))
	}
	if s.ServiceLinkedRoleARN != nil && len(*s.ServiceLinkedRoleARN) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("ServiceLinkedRoleARN", 1))
	}
	if s.VPCZoneIdentifier != nil && len(*s.VPCZoneIdentifier) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("VPCZoneIdentifier", 1))
	}
	if s.LaunchTemplate != nil {
		if err := s.LaunchTemplate.Validate(); err != nil {
			invalidParams.AddNested("LaunchTemplate", err.(request.ErrInvalidParams))
		}
	}
	if s.MixedInstancesPolicy != nil {
		if err := s.MixedInstancesPolicy.Validate(); err != nil {
			invalidParams.AddNested("MixedInstancesPolicy", err.(request.ErrInvalidParams))
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAutoScalingGroupName sets the AutoScalingGroupName field's value.
func (s *UpdateAutoScalingGroupInput) SetAutoScalingGroupName(v string) *UpdateAutoScalingGroupInput {
	s.AutoScalingGroupName = &v
	return s
}

// SetAvailabilityZones sets the AvailabilityZones field's value.
func (s *UpdateAutoScalingGroupInput) SetAvailabilityZones(v []*string) *UpdateAutoScalingGroupInput {
	s.AvailabilityZones = v
	return s
}

// SetDefaultCooldown sets the DefaultCooldown field's value.
func (s *UpdateAutoScalingGroupInput) SetDefaultCooldown(v int64) *UpdateAutoScalingGroupInput {
	s.DefaultCooldown = &v
	return s
}

// SetDesiredCapacity sets the DesiredCapacity field's value.
func (s *UpdateAutoScalingGroupInput) SetDesiredCapacity(v int64) *UpdateAutoScalingGroupInput {
	s.DesiredCapacity = &v
	return s
}

// SetHealthCheckGracePeriod sets the HealthCheckGracePeriod field's value.
func (s *UpdateAutoScalingGroupInput) SetHealthCheckGracePeriod(v int64) *UpdateAutoScalingGroupInput {
	s.HealthCheckGracePeriod = &v
	return s
}

// SetHealthCheckType sets the HealthCheckType field's value.
func (s *UpdateAutoScalingGroupInput) SetHealthCheckType(v string) *UpdateAutoScalingGroupInput {
	s.HealthCheckType = &v
	return s
}

// SetLaunchConfigurationName sets the LaunchConfigurationName field's value.
func (s *UpdateAutoScalingGroupInput) SetLaunchConfigurationName(v string) *UpdateAutoScalingGroupInput {
	s.LaunchConfigurationName = &v
	return s
}

// SetLaunchTemplate sets the LaunchTemplate field's value.
func (s *UpdateAutoScalingGroupInput) SetLaunchTemplate(v *LaunchTemplateSpecification) *UpdateAutoScalingGroupInput {
	s.LaunchTemplate = v
	return s
}

// SetMaxSize sets the MaxSize field's value.
func (s *UpdateAutoScalingGroupInput) SetMaxSize(v int64) *UpdateAutoScalingGroupInput {
	s.MaxSize = &v
	return s
}

// SetMinSize sets the MinSize field's value.
func (s *UpdateAutoScalingGroupInput) SetMinSize(v int64) *UpdateAutoScalingGroupInput {
	s.MinSize = &v
	return s
}

// SetMixedInstancesPolicy sets the MixedInstancesPolicy field's value.
func (s *UpdateAutoScalingGroupInput) SetMixedInstancesPolicy(v *MixedInstancesPolicy) *UpdateAutoScalingGroupInput {
	s.MixedInstancesPolicy = v
	return s
}

// SetNewInstancesProtectedFromScaleIn sets the NewInstancesProtectedFromScaleIn field's value.
func (s *UpdateAutoScalingGroupInput) SetNewInstancesProtectedFromScaleIn(v bool) *UpdateAutoScalingGroupInput {
	s.NewInstancesProtectedFromScaleIn = &v
	return s
}

// SetPlacementGroup sets the PlacementGroup field's value.
func (s *UpdateAutoScalingGroupInput) SetPlacementGroup(v string) *UpdateAutoScalingGroupInput {
	s.PlacementGroup = &v
	return s
}

// SetServiceLinkedRoleARN sets the ServiceLinkedRoleARN field's value.
func (s *UpdateAutoScalingGroupInput) SetServiceLinkedRoleARN(v string) *UpdateAutoScalingGroupInput {
	s.ServiceLinkedRoleARN = &v
	return s
}

// SetTerminationPolicies sets the TerminationPolicies field's value.
func (s *UpdateAutoScalingGroupInput) SetTerminationPolicies(v []*string) *UpdateAutoScalingGroupInput {
	s.TerminationPolicies = v
	return s
}

// SetVPCZoneIdentifier sets the VPCZoneIdentifier field's value.
func (s *UpdateAutoScalingGroupInput) SetVPCZoneIdentifier(v string) *UpdateAutoScalingGroupInput {
	s.VPCZoneIdentifier = &v
	return s
}

type UpdateAutoScalingGroupOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s UpdateAutoScalingGroupOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s UpdateAutoScalingGroupOutput) GoString() string {
	return s.String()
}

const (
	// LifecycleStatePending is a LifecycleState enum value
	LifecycleStatePending = "Pending"

	// LifecycleStatePendingWait is a LifecycleState enum value
	LifecycleStatePendingWait = "Pending:Wait"

	// LifecycleStatePendingProceed is a LifecycleState enum value
	LifecycleStatePendingProceed = "Pending:Proceed"

	// LifecycleStateQuarantined is a LifecycleState enum value
	LifecycleStateQuarantined = "Quarantined"

	// LifecycleStateInService is a LifecycleState enum value
	LifecycleStateInService = "InService"

	// LifecycleStateTerminating is a LifecycleState enum value
	LifecycleStateTerminating = "Terminating"

	// LifecycleStateTerminatingWait is a LifecycleState enum value
	LifecycleStateTerminatingWait = "Terminating:Wait"

	// LifecycleStateTerminatingProceed is a LifecycleState enum value
	LifecycleStateTerminatingProceed = "Terminating:Proceed"

	// LifecycleStateTerminated is a LifecycleState enum value
	LifecycleStateTerminated = "Terminated"

	// LifecycleStateDetaching is a LifecycleState enum value
	LifecycleStateDetaching = "Detaching"

	// LifecycleStateDetached is a LifecycleState enum value
	LifecycleStateDetached = "Detached"

	// LifecycleStateEnteringStandby is a LifecycleState enum value
	LifecycleStateEnteringStandby = "EnteringStandby"

	// LifecycleStateStandby is a LifecycleState enum value
	LifecycleStateStandby = "Standby"
)

const (
	// MetricStatisticAverage is a MetricStatistic enum value
	MetricStatisticAverage = "Average"

	// MetricStatisticMinimum is a MetricStatistic enum value
	MetricStatisticMinimum = "Minimum"

	// MetricStatisticMaximum is a MetricStatistic enum value
	MetricStatisticMaximum = "Maximum"

	// MetricStatisticSampleCount is a MetricStatistic enum value
	MetricStatisticSampleCount = "SampleCount"

	// MetricStatisticSum is a MetricStatistic enum value
	MetricStatisticSum = "Sum"
)

const (
	// MetricTypeAsgaverageCpuutilization is a MetricType enum value
	MetricTypeAsgaverageCpuutilization = "ASGAverageCPUUtilization"

	// MetricTypeAsgaverageNetworkIn is a MetricType enum value
	MetricTypeAsgaverageNetworkIn = "ASGAverageNetworkIn"

	// MetricTypeAsgaverageNetworkOut is a MetricType enum value
	MetricTypeAsgaverageNetworkOut = "ASGAverageNetworkOut"

	// MetricTypeAlbrequestCountPerTarget is a MetricType enum value
	MetricTypeAlbrequestCountPerTarget = "ALBRequestCountPerTarget"
)

const (
	// ScalingActivityStatusCodePendingSpotBidPlacement is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodePendingSpotBidPlacement = "PendingSpotBidPlacement"

	// ScalingActivityStatusCodeWaitingForSpotInstanceRequestId is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodeWaitingForSpotInstanceRequestId = "WaitingForSpotInstanceRequestId"

	// ScalingActivityStatusCodeWaitingForSpotInstanceId is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodeWaitingForSpotInstanceId = "WaitingForSpotInstanceId"

	// ScalingActivityStatusCodeWaitingForInstanceId is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodeWaitingForInstanceId = "WaitingForInstanceId"

	// ScalingActivityStatusCodePreInService is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodePreInService = "PreInService"

	// ScalingActivityStatusCodeInProgress is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodeInProgress = "InProgress"

	// ScalingActivityStatusCodeWaitingForElbconnectionDraining is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodeWaitingForElbconnectionDraining = "WaitingForELBConnectionDraining"

	// ScalingActivityStatusCodeMidLifecycleAction is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodeMidLifecycleAction = "MidLifecycleAction"

	// ScalingActivityStatusCodeWaitingForInstanceWarmup is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodeWaitingForInstanceWarmup = "WaitingForInstanceWarmup"

	// ScalingActivityStatusCodeSuccessful is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodeSuccessful = "Successful"

	// ScalingActivityStatusCodeFailed is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodeFailed = "Failed"

	// ScalingActivityStatusCodeCancelled is a ScalingActivityStatusCode enum value
	ScalingActivityStatusCodeCancelled = "Cancelled"
)
