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

package elbv2

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 opAddListenerCertificates = "AddListenerCertificates"

// AddListenerCertificatesRequest generates a "aws/request.Request" representing the
// client's request for the AddListenerCertificates 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 AddListenerCertificates for more information on using the AddListenerCertificates
// 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 AddListenerCertificatesRequest method.
//    req, resp := client.AddListenerCertificatesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/AddListenerCertificates
func (c *ELBV2) AddListenerCertificatesRequest(input *AddListenerCertificatesInput) (req *request.Request, output *AddListenerCertificatesOutput) {
	op := &request.Operation{
		Name:       opAddListenerCertificates,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AddListenerCertificatesInput{}
	}

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

// AddListenerCertificates API operation for Elastic Load Balancing.
//
// Adds the specified certificate to the specified HTTPS listener.
//
// If the certificate was already added, the call is successful but the certificate
// is not added again.
//
// To list the certificates for your listener, use DescribeListenerCertificates.
// To remove certificates from your listener, use RemoveListenerCertificates.
// To specify the default SSL server certificate, use ModifyListener.
//
// 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 Elastic Load Balancing's
// API operation AddListenerCertificates for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The specified listener does not exist.
//
//   * ErrCodeTooManyCertificatesException "TooManyCertificates"
//   You've reached the limit on the number of certificates per load balancer.
//
//   * ErrCodeCertificateNotFoundException "CertificateNotFound"
//   The specified certificate does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/AddListenerCertificates
func (c *ELBV2) AddListenerCertificates(input *AddListenerCertificatesInput) (*AddListenerCertificatesOutput, error) {
	req, out := c.AddListenerCertificatesRequest(input)
	return out, req.Send()
}

// AddListenerCertificatesWithContext is the same as AddListenerCertificates with the addition of
// the ability to pass a context and additional request options.
//
// See AddListenerCertificates 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 *ELBV2) AddListenerCertificatesWithContext(ctx aws.Context, input *AddListenerCertificatesInput, opts ...request.Option) (*AddListenerCertificatesOutput, error) {
	req, out := c.AddListenerCertificatesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opAddTags = "AddTags"

// AddTagsRequest generates a "aws/request.Request" representing the
// client's request for the AddTags 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 AddTags for more information on using the AddTags
// 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 AddTagsRequest method.
//    req, resp := client.AddTagsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/AddTags
func (c *ELBV2) AddTagsRequest(input *AddTagsInput) (req *request.Request, output *AddTagsOutput) {
	op := &request.Operation{
		Name:       opAddTags,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AddTagsInput{}
	}

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

// AddTags API operation for Elastic Load Balancing.
//
// Adds the specified tags to the specified Elastic Load Balancing resource.
// You can tag your Application Load Balancers, Network Load Balancers, and
// your target groups.
//
// Each tag consists of a key and an optional value. If a resource already has
// a tag with the same key, AddTags updates its value.
//
// To list the current tags for your resources, use DescribeTags. To remove
// tags from your resources, use RemoveTags.
//
// 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 Elastic Load Balancing's
// API operation AddTags for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDuplicateTagKeysException "DuplicateTagKeys"
//   A tag key was specified more than once.
//
//   * ErrCodeTooManyTagsException "TooManyTags"
//   You've reached the limit on the number of tags per load balancer.
//
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/AddTags
func (c *ELBV2) AddTags(input *AddTagsInput) (*AddTagsOutput, error) {
	req, out := c.AddTagsRequest(input)
	return out, req.Send()
}

// AddTagsWithContext is the same as AddTags with the addition of
// the ability to pass a context and additional request options.
//
// See AddTags 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 *ELBV2) AddTagsWithContext(ctx aws.Context, input *AddTagsInput, opts ...request.Option) (*AddTagsOutput, error) {
	req, out := c.AddTagsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateListener = "CreateListener"

// CreateListenerRequest generates a "aws/request.Request" representing the
// client's request for the CreateListener 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 CreateListener for more information on using the CreateListener
// 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 CreateListenerRequest method.
//    req, resp := client.CreateListenerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/CreateListener
func (c *ELBV2) CreateListenerRequest(input *CreateListenerInput) (req *request.Request, output *CreateListenerOutput) {
	op := &request.Operation{
		Name:       opCreateListener,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateListenerInput{}
	}

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

// CreateListener API operation for Elastic Load Balancing.
//
// Creates a listener for the specified Application Load Balancer or Network
// Load Balancer.
//
// To update a listener, use ModifyListener. When you are finished with a listener,
// you can delete it using DeleteListener. If you are finished with both the
// listener and the load balancer, you can delete them both using DeleteLoadBalancer.
//
// This operation is idempotent, which means that it completes at most one time.
// If you attempt to create multiple listeners with the same settings, each
// call succeeds.
//
// For more information, see Listeners for Your Application Load Balancers (http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html)
// in the Application Load Balancers Guide and Listeners for Your Network Load
// Balancers (http://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-listeners.html)
// in the Network Load Balancers 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 Elastic Load Balancing's
// API operation CreateListener for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDuplicateListenerException "DuplicateListener"
//   A listener with the specified port already exists.
//
//   * ErrCodeTooManyListenersException "TooManyListeners"
//   You've reached the limit on the number of listeners per load balancer.
//
//   * ErrCodeTooManyCertificatesException "TooManyCertificates"
//   You've reached the limit on the number of certificates per load balancer.
//
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeTargetGroupAssociationLimitException "TargetGroupAssociationLimit"
//   You've reached the limit on the number of load balancers per target group.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
//   * ErrCodeIncompatibleProtocolsException "IncompatibleProtocols"
//   The specified configuration is not valid with this protocol.
//
//   * ErrCodeSSLPolicyNotFoundException "SSLPolicyNotFound"
//   The specified SSL policy does not exist.
//
//   * ErrCodeCertificateNotFoundException "CertificateNotFound"
//   The specified certificate does not exist.
//
//   * ErrCodeUnsupportedProtocolException "UnsupportedProtocol"
//   The specified protocol is not supported.
//
//   * ErrCodeTooManyRegistrationsForTargetIdException "TooManyRegistrationsForTargetId"
//   You've reached the limit on the number of times a target can be registered
//   with a load balancer.
//
//   * ErrCodeTooManyTargetsException "TooManyTargets"
//   You've reached the limit on the number of targets.
//
//   * ErrCodeTooManyActionsException "TooManyActions"
//   You've reached the limit on the number of actions per rule.
//
//   * ErrCodeInvalidLoadBalancerActionException "InvalidLoadBalancerAction"
//   The requested action is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/CreateListener
func (c *ELBV2) CreateListener(input *CreateListenerInput) (*CreateListenerOutput, error) {
	req, out := c.CreateListenerRequest(input)
	return out, req.Send()
}

// CreateListenerWithContext is the same as CreateListener with the addition of
// the ability to pass a context and additional request options.
//
// See CreateListener 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 *ELBV2) CreateListenerWithContext(ctx aws.Context, input *CreateListenerInput, opts ...request.Option) (*CreateListenerOutput, error) {
	req, out := c.CreateListenerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateLoadBalancer = "CreateLoadBalancer"

// CreateLoadBalancerRequest generates a "aws/request.Request" representing the
// client's request for the CreateLoadBalancer 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 CreateLoadBalancer for more information on using the CreateLoadBalancer
// 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 CreateLoadBalancerRequest method.
//    req, resp := client.CreateLoadBalancerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/CreateLoadBalancer
func (c *ELBV2) CreateLoadBalancerRequest(input *CreateLoadBalancerInput) (req *request.Request, output *CreateLoadBalancerOutput) {
	op := &request.Operation{
		Name:       opCreateLoadBalancer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateLoadBalancerInput{}
	}

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

// CreateLoadBalancer API operation for Elastic Load Balancing.
//
// Creates an Application Load Balancer or a Network Load Balancer.
//
// When you create a load balancer, you can specify security groups, public
// subnets, IP address type, and tags. Otherwise, you could do so later using
// SetSecurityGroups, SetSubnets, SetIpAddressType, and AddTags.
//
// To create listeners for your load balancer, use CreateListener. To describe
// your current load balancers, see DescribeLoadBalancers. When you are finished
// with a load balancer, you can delete it using DeleteLoadBalancer.
//
// For limit information, see Limits for Your Application Load Balancer (http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-limits.html)
// in the Application Load Balancers Guide and Limits for Your Network Load
// Balancer (http://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-limits.html)
// in the Network Load Balancers Guide.
//
// This operation is idempotent, which means that it completes at most one time.
// If you attempt to create multiple load balancers with the same settings,
// each call succeeds.
//
// For more information, see Application Load Balancers (http://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html)
// in the Application Load Balancers Guide and Network Load Balancers (http://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html)
// in the Network Load Balancers 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 Elastic Load Balancing's
// API operation CreateLoadBalancer for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDuplicateLoadBalancerNameException "DuplicateLoadBalancerName"
//   A load balancer with the specified name already exists.
//
//   * ErrCodeTooManyLoadBalancersException "TooManyLoadBalancers"
//   You've reached the limit on the number of load balancers for your AWS account.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
//   * ErrCodeSubnetNotFoundException "SubnetNotFound"
//   The specified subnet does not exist.
//
//   * ErrCodeInvalidSubnetException "InvalidSubnet"
//   The specified subnet is out of available addresses.
//
//   * ErrCodeInvalidSecurityGroupException "InvalidSecurityGroup"
//   The specified security group does not exist.
//
//   * ErrCodeInvalidSchemeException "InvalidScheme"
//   The requested scheme is not valid.
//
//   * ErrCodeTooManyTagsException "TooManyTags"
//   You've reached the limit on the number of tags per load balancer.
//
//   * ErrCodeDuplicateTagKeysException "DuplicateTagKeys"
//   A tag key was specified more than once.
//
//   * ErrCodeResourceInUseException "ResourceInUse"
//   A specified resource is in use.
//
//   * ErrCodeAllocationIdNotFoundException "AllocationIdNotFound"
//   The specified allocation ID does not exist.
//
//   * ErrCodeAvailabilityZoneNotSupportedException "AvailabilityZoneNotSupported"
//   The specified Availability Zone is not supported.
//
//   * ErrCodeOperationNotPermittedException "OperationNotPermitted"
//   This operation is not allowed.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/CreateLoadBalancer
func (c *ELBV2) CreateLoadBalancer(input *CreateLoadBalancerInput) (*CreateLoadBalancerOutput, error) {
	req, out := c.CreateLoadBalancerRequest(input)
	return out, req.Send()
}

// CreateLoadBalancerWithContext is the same as CreateLoadBalancer with the addition of
// the ability to pass a context and additional request options.
//
// See CreateLoadBalancer 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 *ELBV2) CreateLoadBalancerWithContext(ctx aws.Context, input *CreateLoadBalancerInput, opts ...request.Option) (*CreateLoadBalancerOutput, error) {
	req, out := c.CreateLoadBalancerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateRule = "CreateRule"

// CreateRuleRequest generates a "aws/request.Request" representing the
// client's request for the CreateRule 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 CreateRule for more information on using the CreateRule
// 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 CreateRuleRequest method.
//    req, resp := client.CreateRuleRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/CreateRule
func (c *ELBV2) CreateRuleRequest(input *CreateRuleInput) (req *request.Request, output *CreateRuleOutput) {
	op := &request.Operation{
		Name:       opCreateRule,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateRuleInput{}
	}

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

// CreateRule API operation for Elastic Load Balancing.
//
// Creates a rule for the specified listener. The listener must be associated
// with an Application Load Balancer.
//
// Rules are evaluated in priority order, from the lowest value to the highest
// value. When the conditions for a rule are met, its actions are performed.
// If the conditions for no rules are met, the actions for the default rule
// are performed. For more information, see Listener Rules (http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-listeners.html#listener-rules)
// in the Application Load Balancers Guide.
//
// To view your current rules, use DescribeRules. To update a rule, use ModifyRule.
// To set the priorities of your rules, use SetRulePriorities. To delete a rule,
// use DeleteRule.
//
// 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 Elastic Load Balancing's
// API operation CreateRule for usage and error information.
//
// Returned Error Codes:
//   * ErrCodePriorityInUseException "PriorityInUse"
//   The specified priority is in use.
//
//   * ErrCodeTooManyTargetGroupsException "TooManyTargetGroups"
//   You've reached the limit on the number of target groups for your AWS account.
//
//   * ErrCodeTooManyRulesException "TooManyRules"
//   You've reached the limit on the number of rules per load balancer.
//
//   * ErrCodeTargetGroupAssociationLimitException "TargetGroupAssociationLimit"
//   You've reached the limit on the number of load balancers per target group.
//
//   * ErrCodeIncompatibleProtocolsException "IncompatibleProtocols"
//   The specified configuration is not valid with this protocol.
//
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The specified listener does not exist.
//
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
//   * ErrCodeTooManyRegistrationsForTargetIdException "TooManyRegistrationsForTargetId"
//   You've reached the limit on the number of times a target can be registered
//   with a load balancer.
//
//   * ErrCodeTooManyTargetsException "TooManyTargets"
//   You've reached the limit on the number of targets.
//
//   * ErrCodeUnsupportedProtocolException "UnsupportedProtocol"
//   The specified protocol is not supported.
//
//   * ErrCodeTooManyActionsException "TooManyActions"
//   You've reached the limit on the number of actions per rule.
//
//   * ErrCodeInvalidLoadBalancerActionException "InvalidLoadBalancerAction"
//   The requested action is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/CreateRule
func (c *ELBV2) CreateRule(input *CreateRuleInput) (*CreateRuleOutput, error) {
	req, out := c.CreateRuleRequest(input)
	return out, req.Send()
}

// CreateRuleWithContext is the same as CreateRule with the addition of
// the ability to pass a context and additional request options.
//
// See CreateRule 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 *ELBV2) CreateRuleWithContext(ctx aws.Context, input *CreateRuleInput, opts ...request.Option) (*CreateRuleOutput, error) {
	req, out := c.CreateRuleRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateTargetGroup = "CreateTargetGroup"

// CreateTargetGroupRequest generates a "aws/request.Request" representing the
// client's request for the CreateTargetGroup 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 CreateTargetGroup for more information on using the CreateTargetGroup
// 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 CreateTargetGroupRequest method.
//    req, resp := client.CreateTargetGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/CreateTargetGroup
func (c *ELBV2) CreateTargetGroupRequest(input *CreateTargetGroupInput) (req *request.Request, output *CreateTargetGroupOutput) {
	op := &request.Operation{
		Name:       opCreateTargetGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateTargetGroupInput{}
	}

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

// CreateTargetGroup API operation for Elastic Load Balancing.
//
// Creates a target group.
//
// To register targets with the target group, use RegisterTargets. To update
// the health check settings for the target group, use ModifyTargetGroup. To
// monitor the health of targets in the target group, use DescribeTargetHealth.
//
// To route traffic to the targets in a target group, specify the target group
// in an action using CreateListener or CreateRule.
//
// To delete a target group, use DeleteTargetGroup.
//
// This operation is idempotent, which means that it completes at most one time.
// If you attempt to create multiple target groups with the same settings, each
// call succeeds.
//
// For more information, see Target Groups for Your Application Load Balancers
// (http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html)
// in the Application Load Balancers Guide or Target Groups for Your Network
// Load Balancers (http://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html)
// in the Network Load Balancers 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 Elastic Load Balancing's
// API operation CreateTargetGroup for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDuplicateTargetGroupNameException "DuplicateTargetGroupName"
//   A target group with the specified name already exists.
//
//   * ErrCodeTooManyTargetGroupsException "TooManyTargetGroups"
//   You've reached the limit on the number of target groups for your AWS account.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/CreateTargetGroup
func (c *ELBV2) CreateTargetGroup(input *CreateTargetGroupInput) (*CreateTargetGroupOutput, error) {
	req, out := c.CreateTargetGroupRequest(input)
	return out, req.Send()
}

// CreateTargetGroupWithContext is the same as CreateTargetGroup with the addition of
// the ability to pass a context and additional request options.
//
// See CreateTargetGroup 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 *ELBV2) CreateTargetGroupWithContext(ctx aws.Context, input *CreateTargetGroupInput, opts ...request.Option) (*CreateTargetGroupOutput, error) {
	req, out := c.CreateTargetGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteListener = "DeleteListener"

// DeleteListenerRequest generates a "aws/request.Request" representing the
// client's request for the DeleteListener 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 DeleteListener for more information on using the DeleteListener
// 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 DeleteListenerRequest method.
//    req, resp := client.DeleteListenerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DeleteListener
func (c *ELBV2) DeleteListenerRequest(input *DeleteListenerInput) (req *request.Request, output *DeleteListenerOutput) {
	op := &request.Operation{
		Name:       opDeleteListener,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteListenerInput{}
	}

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

// DeleteListener API operation for Elastic Load Balancing.
//
// Deletes the specified listener.
//
// Alternatively, your listener is deleted when you delete the load balancer
// to which it is attached, using DeleteLoadBalancer.
//
// 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 Elastic Load Balancing's
// API operation DeleteListener for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The specified listener does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DeleteListener
func (c *ELBV2) DeleteListener(input *DeleteListenerInput) (*DeleteListenerOutput, error) {
	req, out := c.DeleteListenerRequest(input)
	return out, req.Send()
}

// DeleteListenerWithContext is the same as DeleteListener with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteListener 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 *ELBV2) DeleteListenerWithContext(ctx aws.Context, input *DeleteListenerInput, opts ...request.Option) (*DeleteListenerOutput, error) {
	req, out := c.DeleteListenerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteLoadBalancer = "DeleteLoadBalancer"

// DeleteLoadBalancerRequest generates a "aws/request.Request" representing the
// client's request for the DeleteLoadBalancer 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 DeleteLoadBalancer for more information on using the DeleteLoadBalancer
// 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 DeleteLoadBalancerRequest method.
//    req, resp := client.DeleteLoadBalancerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DeleteLoadBalancer
func (c *ELBV2) DeleteLoadBalancerRequest(input *DeleteLoadBalancerInput) (req *request.Request, output *DeleteLoadBalancerOutput) {
	op := &request.Operation{
		Name:       opDeleteLoadBalancer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteLoadBalancerInput{}
	}

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

// DeleteLoadBalancer API operation for Elastic Load Balancing.
//
// Deletes the specified Application Load Balancer or Network Load Balancer
// and its attached listeners.
//
// You can't delete a load balancer if deletion protection is enabled. If the
// load balancer does not exist or has already been deleted, the call succeeds.
//
// Deleting a load balancer does not affect its registered targets. For example,
// your EC2 instances continue to run and are still registered to their target
// groups. If you no longer need these EC2 instances, you can stop or terminate
// them.
//
// 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 Elastic Load Balancing's
// API operation DeleteLoadBalancer for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeOperationNotPermittedException "OperationNotPermitted"
//   This operation is not allowed.
//
//   * ErrCodeResourceInUseException "ResourceInUse"
//   A specified resource is in use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DeleteLoadBalancer
func (c *ELBV2) DeleteLoadBalancer(input *DeleteLoadBalancerInput) (*DeleteLoadBalancerOutput, error) {
	req, out := c.DeleteLoadBalancerRequest(input)
	return out, req.Send()
}

// DeleteLoadBalancerWithContext is the same as DeleteLoadBalancer with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteLoadBalancer 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 *ELBV2) DeleteLoadBalancerWithContext(ctx aws.Context, input *DeleteLoadBalancerInput, opts ...request.Option) (*DeleteLoadBalancerOutput, error) {
	req, out := c.DeleteLoadBalancerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteRule = "DeleteRule"

// DeleteRuleRequest generates a "aws/request.Request" representing the
// client's request for the DeleteRule 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 DeleteRule for more information on using the DeleteRule
// 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 DeleteRuleRequest method.
//    req, resp := client.DeleteRuleRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DeleteRule
func (c *ELBV2) DeleteRuleRequest(input *DeleteRuleInput) (req *request.Request, output *DeleteRuleOutput) {
	op := &request.Operation{
		Name:       opDeleteRule,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteRuleInput{}
	}

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

// DeleteRule API operation for Elastic Load Balancing.
//
// Deletes the specified rule.
//
// 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 Elastic Load Balancing's
// API operation DeleteRule for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeRuleNotFoundException "RuleNotFound"
//   The specified rule does not exist.
//
//   * ErrCodeOperationNotPermittedException "OperationNotPermitted"
//   This operation is not allowed.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DeleteRule
func (c *ELBV2) DeleteRule(input *DeleteRuleInput) (*DeleteRuleOutput, error) {
	req, out := c.DeleteRuleRequest(input)
	return out, req.Send()
}

// DeleteRuleWithContext is the same as DeleteRule with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteRule 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 *ELBV2) DeleteRuleWithContext(ctx aws.Context, input *DeleteRuleInput, opts ...request.Option) (*DeleteRuleOutput, error) {
	req, out := c.DeleteRuleRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteTargetGroup = "DeleteTargetGroup"

// DeleteTargetGroupRequest generates a "aws/request.Request" representing the
// client's request for the DeleteTargetGroup 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 DeleteTargetGroup for more information on using the DeleteTargetGroup
// 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 DeleteTargetGroupRequest method.
//    req, resp := client.DeleteTargetGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DeleteTargetGroup
func (c *ELBV2) DeleteTargetGroupRequest(input *DeleteTargetGroupInput) (req *request.Request, output *DeleteTargetGroupOutput) {
	op := &request.Operation{
		Name:       opDeleteTargetGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteTargetGroupInput{}
	}

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

// DeleteTargetGroup API operation for Elastic Load Balancing.
//
// Deletes the specified target group.
//
// You can delete a target group if it is not referenced by any actions. Deleting
// a target group also deletes any associated health checks.
//
// 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 Elastic Load Balancing's
// API operation DeleteTargetGroup for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeResourceInUseException "ResourceInUse"
//   A specified resource is in use.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DeleteTargetGroup
func (c *ELBV2) DeleteTargetGroup(input *DeleteTargetGroupInput) (*DeleteTargetGroupOutput, error) {
	req, out := c.DeleteTargetGroupRequest(input)
	return out, req.Send()
}

// DeleteTargetGroupWithContext is the same as DeleteTargetGroup with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteTargetGroup 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 *ELBV2) DeleteTargetGroupWithContext(ctx aws.Context, input *DeleteTargetGroupInput, opts ...request.Option) (*DeleteTargetGroupOutput, error) {
	req, out := c.DeleteTargetGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeregisterTargets = "DeregisterTargets"

// DeregisterTargetsRequest generates a "aws/request.Request" representing the
// client's request for the DeregisterTargets 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 DeregisterTargets for more information on using the DeregisterTargets
// 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 DeregisterTargetsRequest method.
//    req, resp := client.DeregisterTargetsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DeregisterTargets
func (c *ELBV2) DeregisterTargetsRequest(input *DeregisterTargetsInput) (req *request.Request, output *DeregisterTargetsOutput) {
	op := &request.Operation{
		Name:       opDeregisterTargets,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeregisterTargetsInput{}
	}

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

// DeregisterTargets API operation for Elastic Load Balancing.
//
// Deregisters the specified targets from the specified target group. After
// the targets are deregistered, they no longer receive traffic from the load
// balancer.
//
// 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 Elastic Load Balancing's
// API operation DeregisterTargets for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeInvalidTargetException "InvalidTarget"
//   The specified target does not exist, is not in the same VPC as the target
//   group, or has an unsupported instance type.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DeregisterTargets
func (c *ELBV2) DeregisterTargets(input *DeregisterTargetsInput) (*DeregisterTargetsOutput, error) {
	req, out := c.DeregisterTargetsRequest(input)
	return out, req.Send()
}

// DeregisterTargetsWithContext is the same as DeregisterTargets with the addition of
// the ability to pass a context and additional request options.
//
// See DeregisterTargets 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 *ELBV2) DeregisterTargetsWithContext(ctx aws.Context, input *DeregisterTargetsInput, opts ...request.Option) (*DeregisterTargetsOutput, error) {
	req, out := c.DeregisterTargetsRequest(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/elasticloadbalancingv2-2015-12-01/DescribeAccountLimits
func (c *ELBV2) 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 Elastic Load Balancing.
//
// Describes the current Elastic Load Balancing resource limits for your AWS
// account.
//
// For more information, see Limits for Your Application Load Balancers (http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-limits.html)
// in the Application Load Balancer Guide or Limits for Your Network Load Balancers
// (http://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-limits.html)
// in the Network Load Balancers 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 Elastic Load Balancing's
// API operation DescribeAccountLimits for usage and error information.
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeAccountLimits
func (c *ELBV2) 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 *ELBV2) 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 opDescribeListenerCertificates = "DescribeListenerCertificates"

// DescribeListenerCertificatesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeListenerCertificates 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 DescribeListenerCertificates for more information on using the DescribeListenerCertificates
// 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 DescribeListenerCertificatesRequest method.
//    req, resp := client.DescribeListenerCertificatesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeListenerCertificates
func (c *ELBV2) DescribeListenerCertificatesRequest(input *DescribeListenerCertificatesInput) (req *request.Request, output *DescribeListenerCertificatesOutput) {
	op := &request.Operation{
		Name:       opDescribeListenerCertificates,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeListenerCertificatesInput{}
	}

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

// DescribeListenerCertificates API operation for Elastic Load Balancing.
//
// Describes the certificates for the specified HTTPS listener.
//
// 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 Elastic Load Balancing's
// API operation DescribeListenerCertificates for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The specified listener does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeListenerCertificates
func (c *ELBV2) DescribeListenerCertificates(input *DescribeListenerCertificatesInput) (*DescribeListenerCertificatesOutput, error) {
	req, out := c.DescribeListenerCertificatesRequest(input)
	return out, req.Send()
}

// DescribeListenerCertificatesWithContext is the same as DescribeListenerCertificates with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeListenerCertificates 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 *ELBV2) DescribeListenerCertificatesWithContext(ctx aws.Context, input *DescribeListenerCertificatesInput, opts ...request.Option) (*DescribeListenerCertificatesOutput, error) {
	req, out := c.DescribeListenerCertificatesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeListeners = "DescribeListeners"

// DescribeListenersRequest generates a "aws/request.Request" representing the
// client's request for the DescribeListeners 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 DescribeListeners for more information on using the DescribeListeners
// 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 DescribeListenersRequest method.
//    req, resp := client.DescribeListenersRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeListeners
func (c *ELBV2) DescribeListenersRequest(input *DescribeListenersInput) (req *request.Request, output *DescribeListenersOutput) {
	op := &request.Operation{
		Name:       opDescribeListeners,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"Marker"},
			OutputTokens:    []string{"NextMarker"},
			LimitToken:      "",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeListenersInput{}
	}

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

// DescribeListeners API operation for Elastic Load Balancing.
//
// Describes the specified listeners or the listeners for the specified Application
// Load Balancer or Network Load Balancer. You must specify either a load balancer
// or one or more listeners.
//
// 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 Elastic Load Balancing's
// API operation DescribeListeners for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The specified listener does not exist.
//
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeUnsupportedProtocolException "UnsupportedProtocol"
//   The specified protocol is not supported.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeListeners
func (c *ELBV2) DescribeListeners(input *DescribeListenersInput) (*DescribeListenersOutput, error) {
	req, out := c.DescribeListenersRequest(input)
	return out, req.Send()
}

// DescribeListenersWithContext is the same as DescribeListeners with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeListeners 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 *ELBV2) DescribeListenersWithContext(ctx aws.Context, input *DescribeListenersInput, opts ...request.Option) (*DescribeListenersOutput, error) {
	req, out := c.DescribeListenersRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeListenersPages iterates over the pages of a DescribeListeners operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeListeners 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 DescribeListeners operation.
//    pageNum := 0
//    err := client.DescribeListenersPages(params,
//        func(page *DescribeListenersOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *ELBV2) DescribeListenersPages(input *DescribeListenersInput, fn func(*DescribeListenersOutput, bool) bool) error {
	return c.DescribeListenersPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeListenersPagesWithContext same as DescribeListenersPages 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 *ELBV2) DescribeListenersPagesWithContext(ctx aws.Context, input *DescribeListenersInput, fn func(*DescribeListenersOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeListenersInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeListenersRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

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

const opDescribeLoadBalancerAttributes = "DescribeLoadBalancerAttributes"

// DescribeLoadBalancerAttributesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLoadBalancerAttributes 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 DescribeLoadBalancerAttributes for more information on using the DescribeLoadBalancerAttributes
// 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 DescribeLoadBalancerAttributesRequest method.
//    req, resp := client.DescribeLoadBalancerAttributesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeLoadBalancerAttributes
func (c *ELBV2) DescribeLoadBalancerAttributesRequest(input *DescribeLoadBalancerAttributesInput) (req *request.Request, output *DescribeLoadBalancerAttributesOutput) {
	op := &request.Operation{
		Name:       opDescribeLoadBalancerAttributes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeLoadBalancerAttributesInput{}
	}

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

// DescribeLoadBalancerAttributes API operation for Elastic Load Balancing.
//
// Describes the attributes for the specified Application Load Balancer or Network
// Load Balancer.
//
// For more information, see Load Balancer Attributes (http://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html#load-balancer-attributes)
// in the Application Load Balancers Guide or Load Balancer Attributes (http://docs.aws.amazon.com/elasticloadbalancing/latest/network/network-load-balancers.html#load-balancer-attributes)
// in the Network Load Balancers 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 Elastic Load Balancing's
// API operation DescribeLoadBalancerAttributes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeLoadBalancerAttributes
func (c *ELBV2) DescribeLoadBalancerAttributes(input *DescribeLoadBalancerAttributesInput) (*DescribeLoadBalancerAttributesOutput, error) {
	req, out := c.DescribeLoadBalancerAttributesRequest(input)
	return out, req.Send()
}

// DescribeLoadBalancerAttributesWithContext is the same as DescribeLoadBalancerAttributes with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLoadBalancerAttributes 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 *ELBV2) DescribeLoadBalancerAttributesWithContext(ctx aws.Context, input *DescribeLoadBalancerAttributesInput, opts ...request.Option) (*DescribeLoadBalancerAttributesOutput, error) {
	req, out := c.DescribeLoadBalancerAttributesRequest(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/elasticloadbalancingv2-2015-12-01/DescribeLoadBalancers
func (c *ELBV2) DescribeLoadBalancersRequest(input *DescribeLoadBalancersInput) (req *request.Request, output *DescribeLoadBalancersOutput) {
	op := &request.Operation{
		Name:       opDescribeLoadBalancers,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"Marker"},
			OutputTokens:    []string{"NextMarker"},
			LimitToken:      "",
			TruncationToken: "",
		},
	}

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

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

// DescribeLoadBalancers API operation for Elastic Load Balancing.
//
// Describes the specified load balancers or all of your load balancers.
//
// To describe the listeners for a load balancer, use DescribeListeners. To
// describe the attributes for a load balancer, use DescribeLoadBalancerAttributes.
//
// 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 Elastic Load Balancing's
// API operation DescribeLoadBalancers for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeLoadBalancers
func (c *ELBV2) 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 *ELBV2) 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()
}

// DescribeLoadBalancersPages iterates over the pages of a DescribeLoadBalancers operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeLoadBalancers 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 DescribeLoadBalancers operation.
//    pageNum := 0
//    err := client.DescribeLoadBalancersPages(params,
//        func(page *DescribeLoadBalancersOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *ELBV2) DescribeLoadBalancersPages(input *DescribeLoadBalancersInput, fn func(*DescribeLoadBalancersOutput, bool) bool) error {
	return c.DescribeLoadBalancersPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeLoadBalancersPagesWithContext same as DescribeLoadBalancersPages 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 *ELBV2) DescribeLoadBalancersPagesWithContext(ctx aws.Context, input *DescribeLoadBalancersInput, fn func(*DescribeLoadBalancersOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeLoadBalancersInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeLoadBalancersRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

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

const opDescribeRules = "DescribeRules"

// DescribeRulesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeRules 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 DescribeRules for more information on using the DescribeRules
// 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 DescribeRulesRequest method.
//    req, resp := client.DescribeRulesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeRules
func (c *ELBV2) DescribeRulesRequest(input *DescribeRulesInput) (req *request.Request, output *DescribeRulesOutput) {
	op := &request.Operation{
		Name:       opDescribeRules,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeRulesInput{}
	}

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

// DescribeRules API operation for Elastic Load Balancing.
//
// Describes the specified rules or the rules for the specified listener. You
// must specify either a listener or one or more rules.
//
// 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 Elastic Load Balancing's
// API operation DescribeRules for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The specified listener does not exist.
//
//   * ErrCodeRuleNotFoundException "RuleNotFound"
//   The specified rule does not exist.
//
//   * ErrCodeUnsupportedProtocolException "UnsupportedProtocol"
//   The specified protocol is not supported.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeRules
func (c *ELBV2) DescribeRules(input *DescribeRulesInput) (*DescribeRulesOutput, error) {
	req, out := c.DescribeRulesRequest(input)
	return out, req.Send()
}

// DescribeRulesWithContext is the same as DescribeRules with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeRules 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 *ELBV2) DescribeRulesWithContext(ctx aws.Context, input *DescribeRulesInput, opts ...request.Option) (*DescribeRulesOutput, error) {
	req, out := c.DescribeRulesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeSSLPolicies = "DescribeSSLPolicies"

// DescribeSSLPoliciesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeSSLPolicies 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 DescribeSSLPolicies for more information on using the DescribeSSLPolicies
// 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 DescribeSSLPoliciesRequest method.
//    req, resp := client.DescribeSSLPoliciesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeSSLPolicies
func (c *ELBV2) DescribeSSLPoliciesRequest(input *DescribeSSLPoliciesInput) (req *request.Request, output *DescribeSSLPoliciesOutput) {
	op := &request.Operation{
		Name:       opDescribeSSLPolicies,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeSSLPoliciesInput{}
	}

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

// DescribeSSLPolicies API operation for Elastic Load Balancing.
//
// Describes the specified policies or all policies used for SSL negotiation.
//
// For more information, see Security Policies (http://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies)
// in the Application Load Balancers 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 Elastic Load Balancing's
// API operation DescribeSSLPolicies for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeSSLPolicyNotFoundException "SSLPolicyNotFound"
//   The specified SSL policy does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeSSLPolicies
func (c *ELBV2) DescribeSSLPolicies(input *DescribeSSLPoliciesInput) (*DescribeSSLPoliciesOutput, error) {
	req, out := c.DescribeSSLPoliciesRequest(input)
	return out, req.Send()
}

// DescribeSSLPoliciesWithContext is the same as DescribeSSLPolicies with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeSSLPolicies 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 *ELBV2) DescribeSSLPoliciesWithContext(ctx aws.Context, input *DescribeSSLPoliciesInput, opts ...request.Option) (*DescribeSSLPoliciesOutput, error) {
	req, out := c.DescribeSSLPoliciesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

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/elasticloadbalancingv2-2015-12-01/DescribeTags
func (c *ELBV2) DescribeTagsRequest(input *DescribeTagsInput) (req *request.Request, output *DescribeTagsOutput) {
	op := &request.Operation{
		Name:       opDescribeTags,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

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

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

// DescribeTags API operation for Elastic Load Balancing.
//
// Describes the tags for the specified resources. You can describe the tags
// for one or more Application Load Balancers, Network Load Balancers, and target
// 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 Elastic Load Balancing's
// API operation DescribeTags for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The specified listener does not exist.
//
//   * ErrCodeRuleNotFoundException "RuleNotFound"
//   The specified rule does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeTags
func (c *ELBV2) 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 *ELBV2) 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()
}

const opDescribeTargetGroupAttributes = "DescribeTargetGroupAttributes"

// DescribeTargetGroupAttributesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeTargetGroupAttributes 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 DescribeTargetGroupAttributes for more information on using the DescribeTargetGroupAttributes
// 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 DescribeTargetGroupAttributesRequest method.
//    req, resp := client.DescribeTargetGroupAttributesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeTargetGroupAttributes
func (c *ELBV2) DescribeTargetGroupAttributesRequest(input *DescribeTargetGroupAttributesInput) (req *request.Request, output *DescribeTargetGroupAttributesOutput) {
	op := &request.Operation{
		Name:       opDescribeTargetGroupAttributes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeTargetGroupAttributesInput{}
	}

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

// DescribeTargetGroupAttributes API operation for Elastic Load Balancing.
//
// Describes the attributes for the specified target group.
//
// For more information, see Target Group Attributes (http://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html#target-group-attributes)
// in the Application Load Balancers Guide or Target Group Attributes (http://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#target-group-attributes)
// in the Network Load Balancers 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 Elastic Load Balancing's
// API operation DescribeTargetGroupAttributes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeTargetGroupAttributes
func (c *ELBV2) DescribeTargetGroupAttributes(input *DescribeTargetGroupAttributesInput) (*DescribeTargetGroupAttributesOutput, error) {
	req, out := c.DescribeTargetGroupAttributesRequest(input)
	return out, req.Send()
}

// DescribeTargetGroupAttributesWithContext is the same as DescribeTargetGroupAttributes with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeTargetGroupAttributes 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 *ELBV2) DescribeTargetGroupAttributesWithContext(ctx aws.Context, input *DescribeTargetGroupAttributesInput, opts ...request.Option) (*DescribeTargetGroupAttributesOutput, error) {
	req, out := c.DescribeTargetGroupAttributesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeTargetGroups = "DescribeTargetGroups"

// DescribeTargetGroupsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeTargetGroups 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 DescribeTargetGroups for more information on using the DescribeTargetGroups
// 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 DescribeTargetGroupsRequest method.
//    req, resp := client.DescribeTargetGroupsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeTargetGroups
func (c *ELBV2) DescribeTargetGroupsRequest(input *DescribeTargetGroupsInput) (req *request.Request, output *DescribeTargetGroupsOutput) {
	op := &request.Operation{
		Name:       opDescribeTargetGroups,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"Marker"},
			OutputTokens:    []string{"NextMarker"},
			LimitToken:      "",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeTargetGroupsInput{}
	}

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

// DescribeTargetGroups API operation for Elastic Load Balancing.
//
// Describes the specified target groups or all of your target groups. By default,
// all target groups are described. Alternatively, you can specify one of the
// following to filter the results: the ARN of the load balancer, the names
// of one or more target groups, or the ARNs of one or more target groups.
//
// To describe the targets for a target group, use DescribeTargetHealth. To
// describe the attributes of a target group, use DescribeTargetGroupAttributes.
//
// 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 Elastic Load Balancing's
// API operation DescribeTargetGroups for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeTargetGroups
func (c *ELBV2) DescribeTargetGroups(input *DescribeTargetGroupsInput) (*DescribeTargetGroupsOutput, error) {
	req, out := c.DescribeTargetGroupsRequest(input)
	return out, req.Send()
}

// DescribeTargetGroupsWithContext is the same as DescribeTargetGroups with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeTargetGroups 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 *ELBV2) DescribeTargetGroupsWithContext(ctx aws.Context, input *DescribeTargetGroupsInput, opts ...request.Option) (*DescribeTargetGroupsOutput, error) {
	req, out := c.DescribeTargetGroupsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeTargetGroupsPages iterates over the pages of a DescribeTargetGroups operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeTargetGroups 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 DescribeTargetGroups operation.
//    pageNum := 0
//    err := client.DescribeTargetGroupsPages(params,
//        func(page *DescribeTargetGroupsOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *ELBV2) DescribeTargetGroupsPages(input *DescribeTargetGroupsInput, fn func(*DescribeTargetGroupsOutput, bool) bool) error {
	return c.DescribeTargetGroupsPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeTargetGroupsPagesWithContext same as DescribeTargetGroupsPages 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 *ELBV2) DescribeTargetGroupsPagesWithContext(ctx aws.Context, input *DescribeTargetGroupsInput, fn func(*DescribeTargetGroupsOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeTargetGroupsInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeTargetGroupsRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

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

const opDescribeTargetHealth = "DescribeTargetHealth"

// DescribeTargetHealthRequest generates a "aws/request.Request" representing the
// client's request for the DescribeTargetHealth 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 DescribeTargetHealth for more information on using the DescribeTargetHealth
// 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 DescribeTargetHealthRequest method.
//    req, resp := client.DescribeTargetHealthRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeTargetHealth
func (c *ELBV2) DescribeTargetHealthRequest(input *DescribeTargetHealthInput) (req *request.Request, output *DescribeTargetHealthOutput) {
	op := &request.Operation{
		Name:       opDescribeTargetHealth,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeTargetHealthInput{}
	}

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

// DescribeTargetHealth API operation for Elastic Load Balancing.
//
// Describes the health of the specified targets or all of your targets.
//
// 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 Elastic Load Balancing's
// API operation DescribeTargetHealth for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeInvalidTargetException "InvalidTarget"
//   The specified target does not exist, is not in the same VPC as the target
//   group, or has an unsupported instance type.
//
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeHealthUnavailableException "HealthUnavailable"
//   The health of the specified targets could not be retrieved due to an internal
//   error.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/DescribeTargetHealth
func (c *ELBV2) DescribeTargetHealth(input *DescribeTargetHealthInput) (*DescribeTargetHealthOutput, error) {
	req, out := c.DescribeTargetHealthRequest(input)
	return out, req.Send()
}

// DescribeTargetHealthWithContext is the same as DescribeTargetHealth with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeTargetHealth 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 *ELBV2) DescribeTargetHealthWithContext(ctx aws.Context, input *DescribeTargetHealthInput, opts ...request.Option) (*DescribeTargetHealthOutput, error) {
	req, out := c.DescribeTargetHealthRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opModifyListener = "ModifyListener"

// ModifyListenerRequest generates a "aws/request.Request" representing the
// client's request for the ModifyListener 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 ModifyListener for more information on using the ModifyListener
// 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 ModifyListenerRequest method.
//    req, resp := client.ModifyListenerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/ModifyListener
func (c *ELBV2) ModifyListenerRequest(input *ModifyListenerInput) (req *request.Request, output *ModifyListenerOutput) {
	op := &request.Operation{
		Name:       opModifyListener,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ModifyListenerInput{}
	}

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

// ModifyListener API operation for Elastic Load Balancing.
//
// Modifies the specified properties of the specified listener.
//
// Any properties that you do not specify retain their current values. However,
// changing the protocol from HTTPS to HTTP, or from TLS to TCP, removes the
// security policy and server certificate properties. If you change the protocol
// from HTTP to HTTPS, or from TCP to TLS, you must add the security policy
// and server certificate properties.
//
// 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 Elastic Load Balancing's
// API operation ModifyListener for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDuplicateListenerException "DuplicateListener"
//   A listener with the specified port already exists.
//
//   * ErrCodeTooManyListenersException "TooManyListeners"
//   You've reached the limit on the number of listeners per load balancer.
//
//   * ErrCodeTooManyCertificatesException "TooManyCertificates"
//   You've reached the limit on the number of certificates per load balancer.
//
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The specified listener does not exist.
//
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeTargetGroupAssociationLimitException "TargetGroupAssociationLimit"
//   You've reached the limit on the number of load balancers per target group.
//
//   * ErrCodeIncompatibleProtocolsException "IncompatibleProtocols"
//   The specified configuration is not valid with this protocol.
//
//   * ErrCodeSSLPolicyNotFoundException "SSLPolicyNotFound"
//   The specified SSL policy does not exist.
//
//   * ErrCodeCertificateNotFoundException "CertificateNotFound"
//   The specified certificate does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
//   * ErrCodeUnsupportedProtocolException "UnsupportedProtocol"
//   The specified protocol is not supported.
//
//   * ErrCodeTooManyRegistrationsForTargetIdException "TooManyRegistrationsForTargetId"
//   You've reached the limit on the number of times a target can be registered
//   with a load balancer.
//
//   * ErrCodeTooManyTargetsException "TooManyTargets"
//   You've reached the limit on the number of targets.
//
//   * ErrCodeTooManyActionsException "TooManyActions"
//   You've reached the limit on the number of actions per rule.
//
//   * ErrCodeInvalidLoadBalancerActionException "InvalidLoadBalancerAction"
//   The requested action is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/ModifyListener
func (c *ELBV2) ModifyListener(input *ModifyListenerInput) (*ModifyListenerOutput, error) {
	req, out := c.ModifyListenerRequest(input)
	return out, req.Send()
}

// ModifyListenerWithContext is the same as ModifyListener with the addition of
// the ability to pass a context and additional request options.
//
// See ModifyListener 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 *ELBV2) ModifyListenerWithContext(ctx aws.Context, input *ModifyListenerInput, opts ...request.Option) (*ModifyListenerOutput, error) {
	req, out := c.ModifyListenerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opModifyLoadBalancerAttributes = "ModifyLoadBalancerAttributes"

// ModifyLoadBalancerAttributesRequest generates a "aws/request.Request" representing the
// client's request for the ModifyLoadBalancerAttributes 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 ModifyLoadBalancerAttributes for more information on using the ModifyLoadBalancerAttributes
// 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 ModifyLoadBalancerAttributesRequest method.
//    req, resp := client.ModifyLoadBalancerAttributesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/ModifyLoadBalancerAttributes
func (c *ELBV2) ModifyLoadBalancerAttributesRequest(input *ModifyLoadBalancerAttributesInput) (req *request.Request, output *ModifyLoadBalancerAttributesOutput) {
	op := &request.Operation{
		Name:       opModifyLoadBalancerAttributes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ModifyLoadBalancerAttributesInput{}
	}

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

// ModifyLoadBalancerAttributes API operation for Elastic Load Balancing.
//
// Modifies the specified attributes of the specified Application Load Balancer
// or Network Load Balancer.
//
// If any of the specified attributes can't be modified as requested, the call
// fails. Any existing attributes that you do not modify retain their current
// values.
//
// 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 Elastic Load Balancing's
// API operation ModifyLoadBalancerAttributes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/ModifyLoadBalancerAttributes
func (c *ELBV2) ModifyLoadBalancerAttributes(input *ModifyLoadBalancerAttributesInput) (*ModifyLoadBalancerAttributesOutput, error) {
	req, out := c.ModifyLoadBalancerAttributesRequest(input)
	return out, req.Send()
}

// ModifyLoadBalancerAttributesWithContext is the same as ModifyLoadBalancerAttributes with the addition of
// the ability to pass a context and additional request options.
//
// See ModifyLoadBalancerAttributes 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 *ELBV2) ModifyLoadBalancerAttributesWithContext(ctx aws.Context, input *ModifyLoadBalancerAttributesInput, opts ...request.Option) (*ModifyLoadBalancerAttributesOutput, error) {
	req, out := c.ModifyLoadBalancerAttributesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opModifyRule = "ModifyRule"

// ModifyRuleRequest generates a "aws/request.Request" representing the
// client's request for the ModifyRule 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 ModifyRule for more information on using the ModifyRule
// 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 ModifyRuleRequest method.
//    req, resp := client.ModifyRuleRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/ModifyRule
func (c *ELBV2) ModifyRuleRequest(input *ModifyRuleInput) (req *request.Request, output *ModifyRuleOutput) {
	op := &request.Operation{
		Name:       opModifyRule,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ModifyRuleInput{}
	}

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

// ModifyRule API operation for Elastic Load Balancing.
//
// Modifies the specified rule.
//
// Any existing properties that you do not modify retain their current values.
//
// To modify the actions for the default rule, use ModifyListener.
//
// 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 Elastic Load Balancing's
// API operation ModifyRule for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeTargetGroupAssociationLimitException "TargetGroupAssociationLimit"
//   You've reached the limit on the number of load balancers per target group.
//
//   * ErrCodeIncompatibleProtocolsException "IncompatibleProtocols"
//   The specified configuration is not valid with this protocol.
//
//   * ErrCodeRuleNotFoundException "RuleNotFound"
//   The specified rule does not exist.
//
//   * ErrCodeOperationNotPermittedException "OperationNotPermitted"
//   This operation is not allowed.
//
//   * ErrCodeTooManyRegistrationsForTargetIdException "TooManyRegistrationsForTargetId"
//   You've reached the limit on the number of times a target can be registered
//   with a load balancer.
//
//   * ErrCodeTooManyTargetsException "TooManyTargets"
//   You've reached the limit on the number of targets.
//
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeUnsupportedProtocolException "UnsupportedProtocol"
//   The specified protocol is not supported.
//
//   * ErrCodeTooManyActionsException "TooManyActions"
//   You've reached the limit on the number of actions per rule.
//
//   * ErrCodeInvalidLoadBalancerActionException "InvalidLoadBalancerAction"
//   The requested action is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/ModifyRule
func (c *ELBV2) ModifyRule(input *ModifyRuleInput) (*ModifyRuleOutput, error) {
	req, out := c.ModifyRuleRequest(input)
	return out, req.Send()
}

// ModifyRuleWithContext is the same as ModifyRule with the addition of
// the ability to pass a context and additional request options.
//
// See ModifyRule 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 *ELBV2) ModifyRuleWithContext(ctx aws.Context, input *ModifyRuleInput, opts ...request.Option) (*ModifyRuleOutput, error) {
	req, out := c.ModifyRuleRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opModifyTargetGroup = "ModifyTargetGroup"

// ModifyTargetGroupRequest generates a "aws/request.Request" representing the
// client's request for the ModifyTargetGroup 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 ModifyTargetGroup for more information on using the ModifyTargetGroup
// 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 ModifyTargetGroupRequest method.
//    req, resp := client.ModifyTargetGroupRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/ModifyTargetGroup
func (c *ELBV2) ModifyTargetGroupRequest(input *ModifyTargetGroupInput) (req *request.Request, output *ModifyTargetGroupOutput) {
	op := &request.Operation{
		Name:       opModifyTargetGroup,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ModifyTargetGroupInput{}
	}

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

// ModifyTargetGroup API operation for Elastic Load Balancing.
//
// Modifies the health checks used when evaluating the health state of the targets
// in the specified target group.
//
// To monitor the health of the targets, use DescribeTargetHealth.
//
// 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 Elastic Load Balancing's
// API operation ModifyTargetGroup for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/ModifyTargetGroup
func (c *ELBV2) ModifyTargetGroup(input *ModifyTargetGroupInput) (*ModifyTargetGroupOutput, error) {
	req, out := c.ModifyTargetGroupRequest(input)
	return out, req.Send()
}

// ModifyTargetGroupWithContext is the same as ModifyTargetGroup with the addition of
// the ability to pass a context and additional request options.
//
// See ModifyTargetGroup 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 *ELBV2) ModifyTargetGroupWithContext(ctx aws.Context, input *ModifyTargetGroupInput, opts ...request.Option) (*ModifyTargetGroupOutput, error) {
	req, out := c.ModifyTargetGroupRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opModifyTargetGroupAttributes = "ModifyTargetGroupAttributes"

// ModifyTargetGroupAttributesRequest generates a "aws/request.Request" representing the
// client's request for the ModifyTargetGroupAttributes 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 ModifyTargetGroupAttributes for more information on using the ModifyTargetGroupAttributes
// 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 ModifyTargetGroupAttributesRequest method.
//    req, resp := client.ModifyTargetGroupAttributesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/ModifyTargetGroupAttributes
func (c *ELBV2) ModifyTargetGroupAttributesRequest(input *ModifyTargetGroupAttributesInput) (req *request.Request, output *ModifyTargetGroupAttributesOutput) {
	op := &request.Operation{
		Name:       opModifyTargetGroupAttributes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ModifyTargetGroupAttributesInput{}
	}

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

// ModifyTargetGroupAttributes API operation for Elastic Load Balancing.
//
// Modifies the specified attributes of the specified target 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 Elastic Load Balancing's
// API operation ModifyTargetGroupAttributes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/ModifyTargetGroupAttributes
func (c *ELBV2) ModifyTargetGroupAttributes(input *ModifyTargetGroupAttributesInput) (*ModifyTargetGroupAttributesOutput, error) {
	req, out := c.ModifyTargetGroupAttributesRequest(input)
	return out, req.Send()
}

// ModifyTargetGroupAttributesWithContext is the same as ModifyTargetGroupAttributes with the addition of
// the ability to pass a context and additional request options.
//
// See ModifyTargetGroupAttributes 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 *ELBV2) ModifyTargetGroupAttributesWithContext(ctx aws.Context, input *ModifyTargetGroupAttributesInput, opts ...request.Option) (*ModifyTargetGroupAttributesOutput, error) {
	req, out := c.ModifyTargetGroupAttributesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opRegisterTargets = "RegisterTargets"

// RegisterTargetsRequest generates a "aws/request.Request" representing the
// client's request for the RegisterTargets 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 RegisterTargets for more information on using the RegisterTargets
// 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 RegisterTargetsRequest method.
//    req, resp := client.RegisterTargetsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/RegisterTargets
func (c *ELBV2) RegisterTargetsRequest(input *RegisterTargetsInput) (req *request.Request, output *RegisterTargetsOutput) {
	op := &request.Operation{
		Name:       opRegisterTargets,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &RegisterTargetsInput{}
	}

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

// RegisterTargets API operation for Elastic Load Balancing.
//
// Registers the specified targets with the specified target group.
//
// If the target is an EC2 instance, it must be in the running state when you
// register it.
//
// By default, the load balancer routes requests to registered targets using
// the protocol and port for the target group. Alternatively, you can override
// the port for a target when you register it. You can register each EC2 instance
// or IP address with the same target group multiple times using different ports.
//
// With a Network Load Balancer, you cannot register instances by instance ID
// if they have the following instance types: C1, CC1, CC2, CG1, CG2, CR1, CS1,
// G1, G2, HI1, HS1, M1, M2, M3, and T1. You can register instances of these
// types by IP address.
//
// To remove a target from a target group, use DeregisterTargets.
//
// 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 Elastic Load Balancing's
// API operation RegisterTargets for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeTooManyTargetsException "TooManyTargets"
//   You've reached the limit on the number of targets.
//
//   * ErrCodeInvalidTargetException "InvalidTarget"
//   The specified target does not exist, is not in the same VPC as the target
//   group, or has an unsupported instance type.
//
//   * ErrCodeTooManyRegistrationsForTargetIdException "TooManyRegistrationsForTargetId"
//   You've reached the limit on the number of times a target can be registered
//   with a load balancer.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/RegisterTargets
func (c *ELBV2) RegisterTargets(input *RegisterTargetsInput) (*RegisterTargetsOutput, error) {
	req, out := c.RegisterTargetsRequest(input)
	return out, req.Send()
}

// RegisterTargetsWithContext is the same as RegisterTargets with the addition of
// the ability to pass a context and additional request options.
//
// See RegisterTargets 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 *ELBV2) RegisterTargetsWithContext(ctx aws.Context, input *RegisterTargetsInput, opts ...request.Option) (*RegisterTargetsOutput, error) {
	req, out := c.RegisterTargetsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opRemoveListenerCertificates = "RemoveListenerCertificates"

// RemoveListenerCertificatesRequest generates a "aws/request.Request" representing the
// client's request for the RemoveListenerCertificates 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 RemoveListenerCertificates for more information on using the RemoveListenerCertificates
// 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 RemoveListenerCertificatesRequest method.
//    req, resp := client.RemoveListenerCertificatesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/RemoveListenerCertificates
func (c *ELBV2) RemoveListenerCertificatesRequest(input *RemoveListenerCertificatesInput) (req *request.Request, output *RemoveListenerCertificatesOutput) {
	op := &request.Operation{
		Name:       opRemoveListenerCertificates,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &RemoveListenerCertificatesInput{}
	}

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

// RemoveListenerCertificates API operation for Elastic Load Balancing.
//
// Removes the specified certificate from the specified HTTPS listener.
//
// You can't remove the default certificate for a listener. To replace the default
// certificate, call ModifyListener.
//
// To list the certificates for your listener, use DescribeListenerCertificates.
//
// 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 Elastic Load Balancing's
// API operation RemoveListenerCertificates for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The specified listener does not exist.
//
//   * ErrCodeOperationNotPermittedException "OperationNotPermitted"
//   This operation is not allowed.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/RemoveListenerCertificates
func (c *ELBV2) RemoveListenerCertificates(input *RemoveListenerCertificatesInput) (*RemoveListenerCertificatesOutput, error) {
	req, out := c.RemoveListenerCertificatesRequest(input)
	return out, req.Send()
}

// RemoveListenerCertificatesWithContext is the same as RemoveListenerCertificates with the addition of
// the ability to pass a context and additional request options.
//
// See RemoveListenerCertificates 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 *ELBV2) RemoveListenerCertificatesWithContext(ctx aws.Context, input *RemoveListenerCertificatesInput, opts ...request.Option) (*RemoveListenerCertificatesOutput, error) {
	req, out := c.RemoveListenerCertificatesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opRemoveTags = "RemoveTags"

// RemoveTagsRequest generates a "aws/request.Request" representing the
// client's request for the RemoveTags 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 RemoveTags for more information on using the RemoveTags
// 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 RemoveTagsRequest method.
//    req, resp := client.RemoveTagsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/RemoveTags
func (c *ELBV2) RemoveTagsRequest(input *RemoveTagsInput) (req *request.Request, output *RemoveTagsOutput) {
	op := &request.Operation{
		Name:       opRemoveTags,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &RemoveTagsInput{}
	}

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

// RemoveTags API operation for Elastic Load Balancing.
//
// Removes the specified tags from the specified Elastic Load Balancing resource.
//
// To list the current tags for your resources, use DescribeTags.
//
// 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 Elastic Load Balancing's
// API operation RemoveTags for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeTargetGroupNotFoundException "TargetGroupNotFound"
//   The specified target group does not exist.
//
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The specified listener does not exist.
//
//   * ErrCodeRuleNotFoundException "RuleNotFound"
//   The specified rule does not exist.
//
//   * ErrCodeTooManyTagsException "TooManyTags"
//   You've reached the limit on the number of tags per load balancer.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/RemoveTags
func (c *ELBV2) RemoveTags(input *RemoveTagsInput) (*RemoveTagsOutput, error) {
	req, out := c.RemoveTagsRequest(input)
	return out, req.Send()
}

// RemoveTagsWithContext is the same as RemoveTags with the addition of
// the ability to pass a context and additional request options.
//
// See RemoveTags 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 *ELBV2) RemoveTagsWithContext(ctx aws.Context, input *RemoveTagsInput, opts ...request.Option) (*RemoveTagsOutput, error) {
	req, out := c.RemoveTagsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetIpAddressType = "SetIpAddressType"

// SetIpAddressTypeRequest generates a "aws/request.Request" representing the
// client's request for the SetIpAddressType 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 SetIpAddressType for more information on using the SetIpAddressType
// 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 SetIpAddressTypeRequest method.
//    req, resp := client.SetIpAddressTypeRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/SetIpAddressType
func (c *ELBV2) SetIpAddressTypeRequest(input *SetIpAddressTypeInput) (req *request.Request, output *SetIpAddressTypeOutput) {
	op := &request.Operation{
		Name:       opSetIpAddressType,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetIpAddressTypeInput{}
	}

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

// SetIpAddressType API operation for Elastic Load Balancing.
//
// Sets the type of IP addresses used by the subnets of the specified Application
// Load Balancer or Network Load Balancer.
//
// Network Load Balancers must use ipv4.
//
// 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 Elastic Load Balancing's
// API operation SetIpAddressType for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
//   * ErrCodeInvalidSubnetException "InvalidSubnet"
//   The specified subnet is out of available addresses.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/SetIpAddressType
func (c *ELBV2) SetIpAddressType(input *SetIpAddressTypeInput) (*SetIpAddressTypeOutput, error) {
	req, out := c.SetIpAddressTypeRequest(input)
	return out, req.Send()
}

// SetIpAddressTypeWithContext is the same as SetIpAddressType with the addition of
// the ability to pass a context and additional request options.
//
// See SetIpAddressType 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 *ELBV2) SetIpAddressTypeWithContext(ctx aws.Context, input *SetIpAddressTypeInput, opts ...request.Option) (*SetIpAddressTypeOutput, error) {
	req, out := c.SetIpAddressTypeRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetRulePriorities = "SetRulePriorities"

// SetRulePrioritiesRequest generates a "aws/request.Request" representing the
// client's request for the SetRulePriorities 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 SetRulePriorities for more information on using the SetRulePriorities
// 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 SetRulePrioritiesRequest method.
//    req, resp := client.SetRulePrioritiesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/SetRulePriorities
func (c *ELBV2) SetRulePrioritiesRequest(input *SetRulePrioritiesInput) (req *request.Request, output *SetRulePrioritiesOutput) {
	op := &request.Operation{
		Name:       opSetRulePriorities,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetRulePrioritiesInput{}
	}

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

// SetRulePriorities API operation for Elastic Load Balancing.
//
// Sets the priorities of the specified rules.
//
// You can reorder the rules as long as there are no priority conflicts in the
// new order. Any existing rules that you do not specify retain their current
// priority.
//
// 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 Elastic Load Balancing's
// API operation SetRulePriorities for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeRuleNotFoundException "RuleNotFound"
//   The specified rule does not exist.
//
//   * ErrCodePriorityInUseException "PriorityInUse"
//   The specified priority is in use.
//
//   * ErrCodeOperationNotPermittedException "OperationNotPermitted"
//   This operation is not allowed.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/SetRulePriorities
func (c *ELBV2) SetRulePriorities(input *SetRulePrioritiesInput) (*SetRulePrioritiesOutput, error) {
	req, out := c.SetRulePrioritiesRequest(input)
	return out, req.Send()
}

// SetRulePrioritiesWithContext is the same as SetRulePriorities with the addition of
// the ability to pass a context and additional request options.
//
// See SetRulePriorities 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 *ELBV2) SetRulePrioritiesWithContext(ctx aws.Context, input *SetRulePrioritiesInput, opts ...request.Option) (*SetRulePrioritiesOutput, error) {
	req, out := c.SetRulePrioritiesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetSecurityGroups = "SetSecurityGroups"

// SetSecurityGroupsRequest generates a "aws/request.Request" representing the
// client's request for the SetSecurityGroups 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 SetSecurityGroups for more information on using the SetSecurityGroups
// 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 SetSecurityGroupsRequest method.
//    req, resp := client.SetSecurityGroupsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/SetSecurityGroups
func (c *ELBV2) SetSecurityGroupsRequest(input *SetSecurityGroupsInput) (req *request.Request, output *SetSecurityGroupsOutput) {
	op := &request.Operation{
		Name:       opSetSecurityGroups,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetSecurityGroupsInput{}
	}

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

// SetSecurityGroups API operation for Elastic Load Balancing.
//
// Associates the specified security groups with the specified Application Load
// Balancer. The specified security groups override the previously associated
// security groups.
//
// You can't specify a security group for a Network Load Balancer.
//
// 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 Elastic Load Balancing's
// API operation SetSecurityGroups for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
//   * ErrCodeInvalidSecurityGroupException "InvalidSecurityGroup"
//   The specified security group does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/SetSecurityGroups
func (c *ELBV2) SetSecurityGroups(input *SetSecurityGroupsInput) (*SetSecurityGroupsOutput, error) {
	req, out := c.SetSecurityGroupsRequest(input)
	return out, req.Send()
}

// SetSecurityGroupsWithContext is the same as SetSecurityGroups with the addition of
// the ability to pass a context and additional request options.
//
// See SetSecurityGroups 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 *ELBV2) SetSecurityGroupsWithContext(ctx aws.Context, input *SetSecurityGroupsInput, opts ...request.Option) (*SetSecurityGroupsOutput, error) {
	req, out := c.SetSecurityGroupsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetSubnets = "SetSubnets"

// SetSubnetsRequest generates a "aws/request.Request" representing the
// client's request for the SetSubnets 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 SetSubnets for more information on using the SetSubnets
// 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 SetSubnetsRequest method.
//    req, resp := client.SetSubnetsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/SetSubnets
func (c *ELBV2) SetSubnetsRequest(input *SetSubnetsInput) (req *request.Request, output *SetSubnetsOutput) {
	op := &request.Operation{
		Name:       opSetSubnets,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetSubnetsInput{}
	}

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

// SetSubnets API operation for Elastic Load Balancing.
//
// Enables the Availability Zone for the specified public subnets for the specified
// Application Load Balancer. The specified subnets replace the previously enabled
// subnets.
//
// You can't change the subnets for a Network Load Balancer.
//
// 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 Elastic Load Balancing's
// API operation SetSubnets for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeLoadBalancerNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration is not valid.
//
//   * ErrCodeSubnetNotFoundException "SubnetNotFound"
//   The specified subnet does not exist.
//
//   * ErrCodeInvalidSubnetException "InvalidSubnet"
//   The specified subnet is out of available addresses.
//
//   * ErrCodeAllocationIdNotFoundException "AllocationIdNotFound"
//   The specified allocation ID does not exist.
//
//   * ErrCodeAvailabilityZoneNotSupportedException "AvailabilityZoneNotSupported"
//   The specified Availability Zone is not supported.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancingv2-2015-12-01/SetSubnets
func (c *ELBV2) SetSubnets(input *SetSubnetsInput) (*SetSubnetsOutput, error) {
	req, out := c.SetSubnetsRequest(input)
	return out, req.Send()
}

// SetSubnetsWithContext is the same as SetSubnets with the addition of
// the ability to pass a context and additional request options.
//
// See SetSubnets 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 *ELBV2) SetSubnetsWithContext(ctx aws.Context, input *SetSubnetsInput, opts ...request.Option) (*SetSubnetsOutput, error) {
	req, out := c.SetSubnetsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// Information about an action.
type Action struct {
	_ struct{} `type:"structure"`

	// [HTTPS listeners] Information for using Amazon Cognito to authenticate users.
	// Specify only when Type is authenticate-cognito.
	AuthenticateCognitoConfig *AuthenticateCognitoActionConfig `type:"structure"`

	// [HTTPS listeners] Information about an identity provider that is compliant
	// with OpenID Connect (OIDC). Specify only when Type is authenticate-oidc.
	AuthenticateOidcConfig *AuthenticateOidcActionConfig `type:"structure"`

	// [Application Load Balancer] Information for creating an action that returns
	// a custom HTTP response. Specify only when Type is fixed-response.
	FixedResponseConfig *FixedResponseActionConfig `type:"structure"`

	// The order for the action. This value is required for rules with multiple
	// actions. The action with the lowest value for order is performed first. The
	// final action to be performed must be a forward or a fixed-response action.
	Order *int64 `min:"1" type:"integer"`

	// [Application Load Balancer] Information for creating a redirect action. Specify
	// only when Type is redirect.
	RedirectConfig *RedirectActionConfig `type:"structure"`

	// The Amazon Resource Name (ARN) of the target group. Specify only when Type
	// is forward.
	TargetGroupArn *string `type:"string"`

	// The type of action. Each rule must include exactly one of the following types
	// of actions: forward, fixed-response, or redirect.
	//
	// Type is a required field
	Type *string `type:"string" required:"true" enum:"ActionTypeEnum"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *Action) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "Action"}
	if s.Order != nil && *s.Order < 1 {
		invalidParams.Add(request.NewErrParamMinValue("Order", 1))
	}
	if s.Type == nil {
		invalidParams.Add(request.NewErrParamRequired("Type"))
	}
	if s.AuthenticateCognitoConfig != nil {
		if err := s.AuthenticateCognitoConfig.Validate(); err != nil {
			invalidParams.AddNested("AuthenticateCognitoConfig", err.(request.ErrInvalidParams))
		}
	}
	if s.AuthenticateOidcConfig != nil {
		if err := s.AuthenticateOidcConfig.Validate(); err != nil {
			invalidParams.AddNested("AuthenticateOidcConfig", err.(request.ErrInvalidParams))
		}
	}
	if s.FixedResponseConfig != nil {
		if err := s.FixedResponseConfig.Validate(); err != nil {
			invalidParams.AddNested("FixedResponseConfig", err.(request.ErrInvalidParams))
		}
	}
	if s.RedirectConfig != nil {
		if err := s.RedirectConfig.Validate(); err != nil {
			invalidParams.AddNested("RedirectConfig", err.(request.ErrInvalidParams))
		}
	}

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

// SetAuthenticateCognitoConfig sets the AuthenticateCognitoConfig field's value.
func (s *Action) SetAuthenticateCognitoConfig(v *AuthenticateCognitoActionConfig) *Action {
	s.AuthenticateCognitoConfig = v
	return s
}

// SetAuthenticateOidcConfig sets the AuthenticateOidcConfig field's value.
func (s *Action) SetAuthenticateOidcConfig(v *AuthenticateOidcActionConfig) *Action {
	s.AuthenticateOidcConfig = v
	return s
}

// SetFixedResponseConfig sets the FixedResponseConfig field's value.
func (s *Action) SetFixedResponseConfig(v *FixedResponseActionConfig) *Action {
	s.FixedResponseConfig = v
	return s
}

// SetOrder sets the Order field's value.
func (s *Action) SetOrder(v int64) *Action {
	s.Order = &v
	return s
}

// SetRedirectConfig sets the RedirectConfig field's value.
func (s *Action) SetRedirectConfig(v *RedirectActionConfig) *Action {
	s.RedirectConfig = v
	return s
}

// SetTargetGroupArn sets the TargetGroupArn field's value.
func (s *Action) SetTargetGroupArn(v string) *Action {
	s.TargetGroupArn = &v
	return s
}

// SetType sets the Type field's value.
func (s *Action) SetType(v string) *Action {
	s.Type = &v
	return s
}

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

	// The certificate to add. You can specify one certificate per call. Set CertificateArn
	// to the certificate ARN but do not set IsDefault.
	//
	// Certificates is a required field
	Certificates []*Certificate `type:"list" required:"true"`

	// The Amazon Resource Name (ARN) of the listener.
	//
	// ListenerArn is a required field
	ListenerArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *AddListenerCertificatesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AddListenerCertificatesInput"}
	if s.Certificates == nil {
		invalidParams.Add(request.NewErrParamRequired("Certificates"))
	}
	if s.ListenerArn == nil {
		invalidParams.Add(request.NewErrParamRequired("ListenerArn"))
	}

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

// SetCertificates sets the Certificates field's value.
func (s *AddListenerCertificatesInput) SetCertificates(v []*Certificate) *AddListenerCertificatesInput {
	s.Certificates = v
	return s
}

// SetListenerArn sets the ListenerArn field's value.
func (s *AddListenerCertificatesInput) SetListenerArn(v string) *AddListenerCertificatesInput {
	s.ListenerArn = &v
	return s
}

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

	// Information about the certificates.
	Certificates []*Certificate `type:"list"`
}

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

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

// SetCertificates sets the Certificates field's value.
func (s *AddListenerCertificatesOutput) SetCertificates(v []*Certificate) *AddListenerCertificatesOutput {
	s.Certificates = v
	return s
}

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

	// The Amazon Resource Name (ARN) of the resource.
	//
	// ResourceArns is a required field
	ResourceArns []*string `type:"list" required:"true"`

	// The tags. Each resource can have a maximum of 10 tags.
	//
	// Tags is a required field
	Tags []*Tag `min:"1" type:"list" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *AddTagsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AddTagsInput"}
	if s.ResourceArns == nil {
		invalidParams.Add(request.NewErrParamRequired("ResourceArns"))
	}
	if s.Tags == nil {
		invalidParams.Add(request.NewErrParamRequired("Tags"))
	}
	if s.Tags != nil && len(s.Tags) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Tags", 1))
	}
	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
}

// SetResourceArns sets the ResourceArns field's value.
func (s *AddTagsInput) SetResourceArns(v []*string) *AddTagsInput {
	s.ResourceArns = v
	return s
}

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

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

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

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

// Request parameters to use when integrating with Amazon Cognito to authenticate
// users.
type AuthenticateCognitoActionConfig struct {
	_ struct{} `type:"structure"`

	// The query parameters (up to 10) to include in the redirect request to the
	// authorization endpoint.
	AuthenticationRequestExtraParams map[string]*string `type:"map"`

	// The behavior if the user is not authenticated. The following are possible
	// values:
	//
	//    * deny - Return an HTTP 401 Unauthorized error.
	//
	//    * allow - Allow the request to be forwarded to the target.
	//
	// authenticate
	OnUnauthenticatedRequest *string `type:"string" enum:"AuthenticateCognitoActionConditionalBehaviorEnum"`

	// The set of user claims to be requested from the IdP. The default is openid.
	//
	// To verify which scope values your IdP supports and how to separate multiple
	// values, see the documentation for your IdP.
	Scope *string `type:"string"`

	// The name of the cookie used to maintain session information. The default
	// is AWSELBAuthSessionCookie.
	SessionCookieName *string `type:"string"`

	// The maximum duration of the authentication session, in seconds. The default
	// is 604800 seconds (7 days).
	SessionTimeout *int64 `type:"long"`

	// The Amazon Resource Name (ARN) of the Amazon Cognito user pool.
	//
	// UserPoolArn is a required field
	UserPoolArn *string `type:"string" required:"true"`

	// The ID of the Amazon Cognito user pool client.
	//
	// UserPoolClientId is a required field
	UserPoolClientId *string `type:"string" required:"true"`

	// The domain prefix or fully-qualified domain name of the Amazon Cognito user
	// pool.
	//
	// UserPoolDomain is a required field
	UserPoolDomain *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *AuthenticateCognitoActionConfig) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AuthenticateCognitoActionConfig"}
	if s.UserPoolArn == nil {
		invalidParams.Add(request.NewErrParamRequired("UserPoolArn"))
	}
	if s.UserPoolClientId == nil {
		invalidParams.Add(request.NewErrParamRequired("UserPoolClientId"))
	}
	if s.UserPoolDomain == nil {
		invalidParams.Add(request.NewErrParamRequired("UserPoolDomain"))
	}

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

// SetAuthenticationRequestExtraParams sets the AuthenticationRequestExtraParams field's value.
func (s *AuthenticateCognitoActionConfig) SetAuthenticationRequestExtraParams(v map[string]*string) *AuthenticateCognitoActionConfig {
	s.AuthenticationRequestExtraParams = v
	return s
}

// SetOnUnauthenticatedRequest sets the OnUnauthenticatedRequest field's value.
func (s *AuthenticateCognitoActionConfig) SetOnUnauthenticatedRequest(v string) *AuthenticateCognitoActionConfig {
	s.OnUnauthenticatedRequest = &v
	return s
}

// SetScope sets the Scope field's value.
func (s *AuthenticateCognitoActionConfig) SetScope(v string) *AuthenticateCognitoActionConfig {
	s.Scope = &v
	return s
}

// SetSessionCookieName sets the SessionCookieName field's value.
func (s *AuthenticateCognitoActionConfig) SetSessionCookieName(v string) *AuthenticateCognitoActionConfig {
	s.SessionCookieName = &v
	return s
}

// SetSessionTimeout sets the SessionTimeout field's value.
func (s *AuthenticateCognitoActionConfig) SetSessionTimeout(v int64) *AuthenticateCognitoActionConfig {
	s.SessionTimeout = &v
	return s
}

// SetUserPoolArn sets the UserPoolArn field's value.
func (s *AuthenticateCognitoActionConfig) SetUserPoolArn(v string) *AuthenticateCognitoActionConfig {
	s.UserPoolArn = &v
	return s
}

// SetUserPoolClientId sets the UserPoolClientId field's value.
func (s *AuthenticateCognitoActionConfig) SetUserPoolClientId(v string) *AuthenticateCognitoActionConfig {
	s.UserPoolClientId = &v
	return s
}

// SetUserPoolDomain sets the UserPoolDomain field's value.
func (s *AuthenticateCognitoActionConfig) SetUserPoolDomain(v string) *AuthenticateCognitoActionConfig {
	s.UserPoolDomain = &v
	return s
}

// Request parameters when using an identity provider (IdP) that is compliant
// with OpenID Connect (OIDC) to authenticate users.
type AuthenticateOidcActionConfig struct {
	_ struct{} `type:"structure"`

	// The query parameters (up to 10) to include in the redirect request to the
	// authorization endpoint.
	AuthenticationRequestExtraParams map[string]*string `type:"map"`

	// The authorization endpoint of the IdP. This must be a full URL, including
	// the HTTPS protocol, the domain, and the path.
	//
	// AuthorizationEndpoint is a required field
	AuthorizationEndpoint *string `type:"string" required:"true"`

	// The OAuth 2.0 client identifier.
	//
	// ClientId is a required field
	ClientId *string `type:"string" required:"true"`

	// The OAuth 2.0 client secret.
	//
	// ClientSecret is a required field
	ClientSecret *string `type:"string" required:"true"`

	// The OIDC issuer identifier of the IdP. This must be a full URL, including
	// the HTTPS protocol, the domain, and the path.
	//
	// Issuer is a required field
	Issuer *string `type:"string" required:"true"`

	// The behavior if the user is not authenticated. The following are possible
	// values:
	//
	//    * deny - Return an HTTP 401 Unauthorized error.
	//
	//    * allow - Allow the request to be forwarded to the target.
	//
	// authenticate
	OnUnauthenticatedRequest *string `type:"string" enum:"AuthenticateOidcActionConditionalBehaviorEnum"`

	// The set of user claims to be requested from the IdP. The default is openid.
	//
	// To verify which scope values your IdP supports and how to separate multiple
	// values, see the documentation for your IdP.
	Scope *string `type:"string"`

	// The name of the cookie used to maintain session information. The default
	// is AWSELBAuthSessionCookie.
	SessionCookieName *string `type:"string"`

	// The maximum duration of the authentication session, in seconds. The default
	// is 604800 seconds (7 days).
	SessionTimeout *int64 `type:"long"`

	// The token endpoint of the IdP. This must be a full URL, including the HTTPS
	// protocol, the domain, and the path.
	//
	// TokenEndpoint is a required field
	TokenEndpoint *string `type:"string" required:"true"`

	// The user info endpoint of the IdP. This must be a full URL, including the
	// HTTPS protocol, the domain, and the path.
	//
	// UserInfoEndpoint is a required field
	UserInfoEndpoint *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *AuthenticateOidcActionConfig) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AuthenticateOidcActionConfig"}
	if s.AuthorizationEndpoint == nil {
		invalidParams.Add(request.NewErrParamRequired("AuthorizationEndpoint"))
	}
	if s.ClientId == nil {
		invalidParams.Add(request.NewErrParamRequired("ClientId"))
	}
	if s.ClientSecret == nil {
		invalidParams.Add(request.NewErrParamRequired("ClientSecret"))
	}
	if s.Issuer == nil {
		invalidParams.Add(request.NewErrParamRequired("Issuer"))
	}
	if s.TokenEndpoint == nil {
		invalidParams.Add(request.NewErrParamRequired("TokenEndpoint"))
	}
	if s.UserInfoEndpoint == nil {
		invalidParams.Add(request.NewErrParamRequired("UserInfoEndpoint"))
	}

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

// SetAuthenticationRequestExtraParams sets the AuthenticationRequestExtraParams field's value.
func (s *AuthenticateOidcActionConfig) SetAuthenticationRequestExtraParams(v map[string]*string) *AuthenticateOidcActionConfig {
	s.AuthenticationRequestExtraParams = v
	return s
}

// SetAuthorizationEndpoint sets the AuthorizationEndpoint field's value.
func (s *AuthenticateOidcActionConfig) SetAuthorizationEndpoint(v string) *AuthenticateOidcActionConfig {
	s.AuthorizationEndpoint = &v
	return s
}

// SetClientId sets the ClientId field's value.
func (s *AuthenticateOidcActionConfig) SetClientId(v string) *AuthenticateOidcActionConfig {
	s.ClientId = &v
	return s
}

// SetClientSecret sets the ClientSecret field's value.
func (s *AuthenticateOidcActionConfig) SetClientSecret(v string) *AuthenticateOidcActionConfig {
	s.ClientSecret = &v
	return s
}

// SetIssuer sets the Issuer field's value.
func (s *AuthenticateOidcActionConfig) SetIssuer(v string) *AuthenticateOidcActionConfig {
	s.Issuer = &v
	return s
}

// SetOnUnauthenticatedRequest sets the OnUnauthenticatedRequest field's value.
func (s *AuthenticateOidcActionConfig) SetOnUnauthenticatedRequest(v string) *AuthenticateOidcActionConfig {
	s.OnUnauthenticatedRequest = &v
	return s
}

// SetScope sets the Scope field's value.
func (s *AuthenticateOidcActionConfig) SetScope(v string) *AuthenticateOidcActionConfig {
	s.Scope = &v
	return s
}

// SetSessionCookieName sets the SessionCookieName field's value.
func (s *AuthenticateOidcActionConfig) SetSessionCookieName(v string) *AuthenticateOidcActionConfig {
	s.SessionCookieName = &v
	return s
}

// SetSessionTimeout sets the SessionTimeout field's value.
func (s *AuthenticateOidcActionConfig) SetSessionTimeout(v int64) *AuthenticateOidcActionConfig {
	s.SessionTimeout = &v
	return s
}

// SetTokenEndpoint sets the TokenEndpoint field's value.
func (s *AuthenticateOidcActionConfig) SetTokenEndpoint(v string) *AuthenticateOidcActionConfig {
	s.TokenEndpoint = &v
	return s
}

// SetUserInfoEndpoint sets the UserInfoEndpoint field's value.
func (s *AuthenticateOidcActionConfig) SetUserInfoEndpoint(v string) *AuthenticateOidcActionConfig {
	s.UserInfoEndpoint = &v
	return s
}

// Information about an Availability Zone.
type AvailabilityZone struct {
	_ struct{} `type:"structure"`

	// [Network Load Balancers] The static IP address.
	LoadBalancerAddresses []*LoadBalancerAddress `type:"list"`

	// The ID of the subnet.
	SubnetId *string `type:"string"`

	// The name of the Availability Zone.
	ZoneName *string `type:"string"`
}

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

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

// SetLoadBalancerAddresses sets the LoadBalancerAddresses field's value.
func (s *AvailabilityZone) SetLoadBalancerAddresses(v []*LoadBalancerAddress) *AvailabilityZone {
	s.LoadBalancerAddresses = v
	return s
}

// SetSubnetId sets the SubnetId field's value.
func (s *AvailabilityZone) SetSubnetId(v string) *AvailabilityZone {
	s.SubnetId = &v
	return s
}

// SetZoneName sets the ZoneName field's value.
func (s *AvailabilityZone) SetZoneName(v string) *AvailabilityZone {
	s.ZoneName = &v
	return s
}

// Information about an SSL server certificate.
type Certificate struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) of the certificate.
	CertificateArn *string `type:"string"`

	// Indicates whether the certificate is the default certificate. Do not set
	// IsDefault when specifying a certificate as an input parameter.
	IsDefault *bool `type:"boolean"`
}

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

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

// SetCertificateArn sets the CertificateArn field's value.
func (s *Certificate) SetCertificateArn(v string) *Certificate {
	s.CertificateArn = &v
	return s
}

// SetIsDefault sets the IsDefault field's value.
func (s *Certificate) SetIsDefault(v bool) *Certificate {
	s.IsDefault = &v
	return s
}

// Information about a cipher used in a policy.
type Cipher struct {
	_ struct{} `type:"structure"`

	// The name of the cipher.
	Name *string `type:"string"`

	// The priority of the cipher.
	Priority *int64 `type:"integer"`
}

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

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

// SetName sets the Name field's value.
func (s *Cipher) SetName(v string) *Cipher {
	s.Name = &v
	return s
}

// SetPriority sets the Priority field's value.
func (s *Cipher) SetPriority(v int64) *Cipher {
	s.Priority = &v
	return s
}

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

	// [HTTPS and TLS listeners] The default SSL server certificate. You must provide
	// exactly one certificate. Set CertificateArn to the certificate ARN but do
	// not set IsDefault.
	//
	// To create a certificate list, use AddListenerCertificates.
	Certificates []*Certificate `type:"list"`

	// The actions for the default rule. The rule must include one forward action
	// or one or more fixed-response actions.
	//
	// If the action type is forward, you specify a target group. The protocol of
	// the target group must be HTTP or HTTPS for an Application Load Balancer.
	// The protocol of the target group must be TCP or TLS for a Network Load Balancer.
	//
	// [HTTPS listeners] If the action type is authenticate-oidc, you authenticate
	// users through an identity provider that is OpenID Connect (OIDC) compliant.
	//
	// [HTTPS listeners] If the action type is authenticate-cognito, you authenticate
	// users through the user pools supported by Amazon Cognito.
	//
	// [Application Load Balancer] If the action type is redirect, you redirect
	// specified client requests from one URL to another.
	//
	// [Application Load Balancer] If the action type is fixed-response, you drop
	// specified client requests and return a custom HTTP response.
	//
	// DefaultActions is a required field
	DefaultActions []*Action `type:"list" required:"true"`

	// The Amazon Resource Name (ARN) of the load balancer.
	//
	// LoadBalancerArn is a required field
	LoadBalancerArn *string `type:"string" required:"true"`

	// The port on which the load balancer is listening.
	//
	// Port is a required field
	Port *int64 `min:"1" type:"integer" required:"true"`

	// The protocol for connections from clients to the load balancer. For Application
	// Load Balancers, the supported protocols are HTTP and HTTPS. For Network Load
	// Balancers, the supported protocols are TCP and TLS.
	//
	// Protocol is a required field
	Protocol *string `type:"string" required:"true" enum:"ProtocolEnum"`

	// [HTTPS and TLS listeners] The security policy that defines which ciphers
	// and protocols are supported. The default is the current predefined security
	// policy.
	SslPolicy *string `type:"string"`
}

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

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

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

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

// SetCertificates sets the Certificates field's value.
func (s *CreateListenerInput) SetCertificates(v []*Certificate) *CreateListenerInput {
	s.Certificates = v
	return s
}

// SetDefaultActions sets the DefaultActions field's value.
func (s *CreateListenerInput) SetDefaultActions(v []*Action) *CreateListenerInput {
	s.DefaultActions = v
	return s
}

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *CreateListenerInput) SetLoadBalancerArn(v string) *CreateListenerInput {
	s.LoadBalancerArn = &v
	return s
}

// SetPort sets the Port field's value.
func (s *CreateListenerInput) SetPort(v int64) *CreateListenerInput {
	s.Port = &v
	return s
}

// SetProtocol sets the Protocol field's value.
func (s *CreateListenerInput) SetProtocol(v string) *CreateListenerInput {
	s.Protocol = &v
	return s
}

// SetSslPolicy sets the SslPolicy field's value.
func (s *CreateListenerInput) SetSslPolicy(v string) *CreateListenerInput {
	s.SslPolicy = &v
	return s
}

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

	// Information about the listener.
	Listeners []*Listener `type:"list"`
}

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

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

// SetListeners sets the Listeners field's value.
func (s *CreateListenerOutput) SetListeners(v []*Listener) *CreateListenerOutput {
	s.Listeners = v
	return s
}

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

	// [Application Load Balancers] The type of IP addresses used by the subnets
	// for your load balancer. The possible values are ipv4 (for IPv4 addresses)
	// and dualstack (for IPv4 and IPv6 addresses). Internal load balancers must
	// use ipv4.
	IpAddressType *string `type:"string" enum:"IpAddressType"`

	// The name of the load balancer.
	//
	// This name must be unique per region per account, can have a maximum of 32
	// characters, must contain only alphanumeric characters or hyphens, must not
	// begin or end with a hyphen, and must not begin with "internal-".
	//
	// Name is a required field
	Name *string `type:"string" required:"true"`

	// The nodes of an Internet-facing load balancer have public IP addresses. The
	// DNS name of an Internet-facing load balancer is publicly resolvable to the
	// public IP addresses of the nodes. Therefore, Internet-facing load balancers
	// can route requests from clients over the internet.
	//
	// The nodes of an internal load balancer have only private IP addresses. The
	// DNS name of an internal load balancer is publicly resolvable to the private
	// IP addresses of the nodes. Therefore, internal load balancers can only route
	// requests from clients with access to the VPC for the load balancer.
	//
	// The default is an Internet-facing load balancer.
	Scheme *string `type:"string" enum:"LoadBalancerSchemeEnum"`

	// [Application Load Balancers] The IDs of the security groups for the load
	// balancer.
	SecurityGroups []*string `type:"list"`

	// The IDs of the public subnets. You can specify only one subnet per Availability
	// Zone. You must specify either subnets or subnet mappings.
	//
	// [Application Load Balancers] You must specify subnets from at least two Availability
	// Zones. You cannot specify Elastic IP addresses for your subnets.
	//
	// [Network Load Balancers] You can specify subnets from one or more Availability
	// Zones. You can specify one Elastic IP address per subnet.
	SubnetMappings []*SubnetMapping `type:"list"`

	// The IDs of the public subnets. You can specify only one subnet per Availability
	// Zone. You must specify either subnets or subnet mappings.
	//
	// [Application Load Balancers] You must specify subnets from at least two Availability
	// Zones.
	//
	// [Network Load Balancers] You can specify subnets from one or more Availability
	// Zones.
	Subnets []*string `type:"list"`

	// One or more tags to assign to the load balancer.
	Tags []*Tag `min:"1" type:"list"`

	// The type of load balancer. The default is application.
	Type *string `type:"string" enum:"LoadBalancerTypeEnum"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateLoadBalancerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateLoadBalancerInput"}
	if s.Name == nil {
		invalidParams.Add(request.NewErrParamRequired("Name"))
	}
	if s.Tags != nil && len(s.Tags) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Tags", 1))
	}
	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
}

// SetIpAddressType sets the IpAddressType field's value.
func (s *CreateLoadBalancerInput) SetIpAddressType(v string) *CreateLoadBalancerInput {
	s.IpAddressType = &v
	return s
}

// SetName sets the Name field's value.
func (s *CreateLoadBalancerInput) SetName(v string) *CreateLoadBalancerInput {
	s.Name = &v
	return s
}

// SetScheme sets the Scheme field's value.
func (s *CreateLoadBalancerInput) SetScheme(v string) *CreateLoadBalancerInput {
	s.Scheme = &v
	return s
}

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

// SetSubnetMappings sets the SubnetMappings field's value.
func (s *CreateLoadBalancerInput) SetSubnetMappings(v []*SubnetMapping) *CreateLoadBalancerInput {
	s.SubnetMappings = v
	return s
}

// SetSubnets sets the Subnets field's value.
func (s *CreateLoadBalancerInput) SetSubnets(v []*string) *CreateLoadBalancerInput {
	s.Subnets = v
	return s
}

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

// SetType sets the Type field's value.
func (s *CreateLoadBalancerInput) SetType(v string) *CreateLoadBalancerInput {
	s.Type = &v
	return s
}

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

	// Information about the load balancer.
	LoadBalancers []*LoadBalancer `type:"list"`
}

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

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

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

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

	// The actions. Each rule must include exactly one of the following types of
	// actions: forward, fixed-response, or redirect.
	//
	// If the action type is forward, you specify a target group. The protocol of
	// the target group must be HTTP or HTTPS for an Application Load Balancer.
	// The protocol of the target group must be TCP or TLS for a Network Load Balancer.
	//
	// [HTTPS listeners] If the action type is authenticate-oidc, you authenticate
	// users through an identity provider that is OpenID Connect (OIDC) compliant.
	//
	// [HTTPS listeners] If the action type is authenticate-cognito, you authenticate
	// users through the user pools supported by Amazon Cognito.
	//
	// [Application Load Balancer] If the action type is redirect, you redirect
	// specified client requests from one URL to another.
	//
	// [Application Load Balancer] If the action type is fixed-response, you drop
	// specified client requests and return a custom HTTP response.
	//
	// Actions is a required field
	Actions []*Action `type:"list" required:"true"`

	// The conditions. Each condition specifies a field name and a single value.
	//
	// If the field name is host-header, you can specify a single host name (for
	// example, my.example.com). A host name is case insensitive, can be up to 128
	// characters in length, and can contain any of the following characters. You
	// can include up to three wildcard characters.
	//
	//    * A-Z, a-z, 0-9
	//
	//    * - .
	//
	//    * * (matches 0 or more characters)
	//
	//    * ? (matches exactly 1 character)
	//
	// If the field name is path-pattern, you can specify a single path pattern.
	// A path pattern is case-sensitive, can be up to 128 characters in length,
	// and can contain any of the following characters. You can include up to three
	// wildcard characters.
	//
	//    * A-Z, a-z, 0-9
	//
	//    * _ - . $ / ~ " ' @ : +
	//
	//    * & (using &)
	//
	//    * * (matches 0 or more characters)
	//
	//    * ? (matches exactly 1 character)
	//
	// Conditions is a required field
	Conditions []*RuleCondition `type:"list" required:"true"`

	// The Amazon Resource Name (ARN) of the listener.
	//
	// ListenerArn is a required field
	ListenerArn *string `type:"string" required:"true"`

	// The rule priority. A listener can't have multiple rules with the same priority.
	//
	// Priority is a required field
	Priority *int64 `min:"1" type:"integer" required:"true"`
}

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

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

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

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

// SetActions sets the Actions field's value.
func (s *CreateRuleInput) SetActions(v []*Action) *CreateRuleInput {
	s.Actions = v
	return s
}

// SetConditions sets the Conditions field's value.
func (s *CreateRuleInput) SetConditions(v []*RuleCondition) *CreateRuleInput {
	s.Conditions = v
	return s
}

// SetListenerArn sets the ListenerArn field's value.
func (s *CreateRuleInput) SetListenerArn(v string) *CreateRuleInput {
	s.ListenerArn = &v
	return s
}

// SetPriority sets the Priority field's value.
func (s *CreateRuleInput) SetPriority(v int64) *CreateRuleInput {
	s.Priority = &v
	return s
}

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

	// Information about the rule.
	Rules []*Rule `type:"list"`
}

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

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

// SetRules sets the Rules field's value.
func (s *CreateRuleOutput) SetRules(v []*Rule) *CreateRuleOutput {
	s.Rules = v
	return s
}

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

	// Indicates whether health checks are enabled. If the target type is instance
	// or ip, the default is true. If the target type is lambda, the default is
	// false.
	HealthCheckEnabled *bool `type:"boolean"`

	// The approximate amount of time, in seconds, between health checks of an individual
	// target. For Application Load Balancers, the range is 5–300 seconds. For Network
	// Load Balancers, the supported values are 10 or 30 seconds. If the target
	// type is instance or ip, the default is 30 seconds. If the target type is
	// lambda, the default is 35 seconds.
	HealthCheckIntervalSeconds *int64 `min:"5" type:"integer"`

	// [HTTP/HTTPS health checks] The ping path that is the destination on the targets
	// for health checks. The default is /.
	HealthCheckPath *string `min:"1" type:"string"`

	// The port the load balancer uses when performing health checks on targets.
	// The default is traffic-port, which is the port on which each target receives
	// traffic from the load balancer.
	HealthCheckPort *string `type:"string"`

	// The protocol the load balancer uses when performing health checks on targets.
	// For Application Load Balancers, the default is HTTP. For Network Load Balancers,
	// the default is TCP. The TCP protocol is supported for health checks only
	// if the protocol of the target group is TCP or TLS. The TLS protocol is not
	// supported for health checks.
	HealthCheckProtocol *string `type:"string" enum:"ProtocolEnum"`

	// The amount of time, in seconds, during which no response from a target means
	// a failed health check. For Application Load Balancers, the range is 2–120
	// seconds and the default is 5 seconds if the target type is instance or ip
	// and 30 seconds if the target type is lambda. For Network Load Balancers,
	// this is 10 seconds for TCP and HTTPS health checks and 6 seconds for HTTP
	// health checks.
	HealthCheckTimeoutSeconds *int64 `min:"2" type:"integer"`

	// The number of consecutive health checks successes required before considering
	// an unhealthy target healthy. For Application Load Balancers, the default
	// is 5. For Network Load Balancers, the default is 3.
	HealthyThresholdCount *int64 `min:"2" type:"integer"`

	// [HTTP/HTTPS health checks] The HTTP codes to use when checking for a successful
	// response from a target.
	Matcher *Matcher `type:"structure"`

	// The name of the target group.
	//
	// This name must be unique per region per account, can have a maximum of 32
	// characters, must contain only alphanumeric characters or hyphens, and must
	// not begin or end with a hyphen.
	//
	// Name is a required field
	Name *string `type:"string" required:"true"`

	// The port on which the targets receive traffic. This port is used unless you
	// specify a port override when registering the target. If the target is a Lambda
	// function, this parameter does not apply.
	Port *int64 `min:"1" type:"integer"`

	// The protocol to use for routing traffic to the targets. For Application Load
	// Balancers, the supported protocols are HTTP and HTTPS. For Network Load Balancers,
	// the supported protocols are TCP and TLS. If the target is a Lambda function,
	// this parameter does not apply.
	Protocol *string `type:"string" enum:"ProtocolEnum"`

	// The type of target that you must specify when registering targets with this
	// target group. You can't specify targets for a target group using more than
	// one target type.
	//
	//    * instance - Targets are specified by instance ID. This is the default
	//    value.
	//
	//    * ip - Targets are specified by IP address. You can specify IP addresses
	//    from the subnets of the virtual private cloud (VPC) for the target group,
	//    the RFC 1918 range (10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16), and
	//    the RFC 6598 range (100.64.0.0/10). You can't specify publicly routable
	//    IP addresses.
	//
	//    * lambda - The target groups contains a single Lambda function.
	TargetType *string `type:"string" enum:"TargetTypeEnum"`

	// The number of consecutive health check failures required before considering
	// a target unhealthy. For Application Load Balancers, the default is 2. For
	// Network Load Balancers, this value must be the same as the healthy threshold
	// count.
	UnhealthyThresholdCount *int64 `min:"2" type:"integer"`

	// The identifier of the virtual private cloud (VPC). If the target is a Lambda
	// function, this parameter does not apply.
	VpcId *string `type:"string"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateTargetGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateTargetGroupInput"}
	if s.HealthCheckIntervalSeconds != nil && *s.HealthCheckIntervalSeconds < 5 {
		invalidParams.Add(request.NewErrParamMinValue("HealthCheckIntervalSeconds", 5))
	}
	if s.HealthCheckPath != nil && len(*s.HealthCheckPath) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("HealthCheckPath", 1))
	}
	if s.HealthCheckTimeoutSeconds != nil && *s.HealthCheckTimeoutSeconds < 2 {
		invalidParams.Add(request.NewErrParamMinValue("HealthCheckTimeoutSeconds", 2))
	}
	if s.HealthyThresholdCount != nil && *s.HealthyThresholdCount < 2 {
		invalidParams.Add(request.NewErrParamMinValue("HealthyThresholdCount", 2))
	}
	if s.Name == nil {
		invalidParams.Add(request.NewErrParamRequired("Name"))
	}
	if s.Port != nil && *s.Port < 1 {
		invalidParams.Add(request.NewErrParamMinValue("Port", 1))
	}
	if s.UnhealthyThresholdCount != nil && *s.UnhealthyThresholdCount < 2 {
		invalidParams.Add(request.NewErrParamMinValue("UnhealthyThresholdCount", 2))
	}
	if s.Matcher != nil {
		if err := s.Matcher.Validate(); err != nil {
			invalidParams.AddNested("Matcher", err.(request.ErrInvalidParams))
		}
	}

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

// SetHealthCheckEnabled sets the HealthCheckEnabled field's value.
func (s *CreateTargetGroupInput) SetHealthCheckEnabled(v bool) *CreateTargetGroupInput {
	s.HealthCheckEnabled = &v
	return s
}

// SetHealthCheckIntervalSeconds sets the HealthCheckIntervalSeconds field's value.
func (s *CreateTargetGroupInput) SetHealthCheckIntervalSeconds(v int64) *CreateTargetGroupInput {
	s.HealthCheckIntervalSeconds = &v
	return s
}

// SetHealthCheckPath sets the HealthCheckPath field's value.
func (s *CreateTargetGroupInput) SetHealthCheckPath(v string) *CreateTargetGroupInput {
	s.HealthCheckPath = &v
	return s
}

// SetHealthCheckPort sets the HealthCheckPort field's value.
func (s *CreateTargetGroupInput) SetHealthCheckPort(v string) *CreateTargetGroupInput {
	s.HealthCheckPort = &v
	return s
}

// SetHealthCheckProtocol sets the HealthCheckProtocol field's value.
func (s *CreateTargetGroupInput) SetHealthCheckProtocol(v string) *CreateTargetGroupInput {
	s.HealthCheckProtocol = &v
	return s
}

// SetHealthCheckTimeoutSeconds sets the HealthCheckTimeoutSeconds field's value.
func (s *CreateTargetGroupInput) SetHealthCheckTimeoutSeconds(v int64) *CreateTargetGroupInput {
	s.HealthCheckTimeoutSeconds = &v
	return s
}

// SetHealthyThresholdCount sets the HealthyThresholdCount field's value.
func (s *CreateTargetGroupInput) SetHealthyThresholdCount(v int64) *CreateTargetGroupInput {
	s.HealthyThresholdCount = &v
	return s
}

// SetMatcher sets the Matcher field's value.
func (s *CreateTargetGroupInput) SetMatcher(v *Matcher) *CreateTargetGroupInput {
	s.Matcher = v
	return s
}

// SetName sets the Name field's value.
func (s *CreateTargetGroupInput) SetName(v string) *CreateTargetGroupInput {
	s.Name = &v
	return s
}

// SetPort sets the Port field's value.
func (s *CreateTargetGroupInput) SetPort(v int64) *CreateTargetGroupInput {
	s.Port = &v
	return s
}

// SetProtocol sets the Protocol field's value.
func (s *CreateTargetGroupInput) SetProtocol(v string) *CreateTargetGroupInput {
	s.Protocol = &v
	return s
}

// SetTargetType sets the TargetType field's value.
func (s *CreateTargetGroupInput) SetTargetType(v string) *CreateTargetGroupInput {
	s.TargetType = &v
	return s
}

// SetUnhealthyThresholdCount sets the UnhealthyThresholdCount field's value.
func (s *CreateTargetGroupInput) SetUnhealthyThresholdCount(v int64) *CreateTargetGroupInput {
	s.UnhealthyThresholdCount = &v
	return s
}

// SetVpcId sets the VpcId field's value.
func (s *CreateTargetGroupInput) SetVpcId(v string) *CreateTargetGroupInput {
	s.VpcId = &v
	return s
}

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

	// Information about the target group.
	TargetGroups []*TargetGroup `type:"list"`
}

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

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

// SetTargetGroups sets the TargetGroups field's value.
func (s *CreateTargetGroupOutput) SetTargetGroups(v []*TargetGroup) *CreateTargetGroupOutput {
	s.TargetGroups = v
	return s
}

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

	// The Amazon Resource Name (ARN) of the listener.
	//
	// ListenerArn is a required field
	ListenerArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteListenerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteListenerInput"}
	if s.ListenerArn == nil {
		invalidParams.Add(request.NewErrParamRequired("ListenerArn"))
	}

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

// SetListenerArn sets the ListenerArn field's value.
func (s *DeleteListenerInput) SetListenerArn(v string) *DeleteListenerInput {
	s.ListenerArn = &v
	return s
}

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

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

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

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

	// The Amazon Resource Name (ARN) of the load balancer.
	//
	// LoadBalancerArn is a required field
	LoadBalancerArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteLoadBalancerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteLoadBalancerInput"}
	if s.LoadBalancerArn == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerArn"))
	}

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

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *DeleteLoadBalancerInput) SetLoadBalancerArn(v string) *DeleteLoadBalancerInput {
	s.LoadBalancerArn = &v
	return s
}

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

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

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

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

	// The Amazon Resource Name (ARN) of the rule.
	//
	// RuleArn is a required field
	RuleArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteRuleInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteRuleInput"}
	if s.RuleArn == nil {
		invalidParams.Add(request.NewErrParamRequired("RuleArn"))
	}

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

// SetRuleArn sets the RuleArn field's value.
func (s *DeleteRuleInput) SetRuleArn(v string) *DeleteRuleInput {
	s.RuleArn = &v
	return s
}

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

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

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

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

	// The Amazon Resource Name (ARN) of the target group.
	//
	// TargetGroupArn is a required field
	TargetGroupArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteTargetGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteTargetGroupInput"}
	if s.TargetGroupArn == nil {
		invalidParams.Add(request.NewErrParamRequired("TargetGroupArn"))
	}

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

// SetTargetGroupArn sets the TargetGroupArn field's value.
func (s *DeleteTargetGroupInput) SetTargetGroupArn(v string) *DeleteTargetGroupInput {
	s.TargetGroupArn = &v
	return s
}

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

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

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

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

	// The Amazon Resource Name (ARN) of the target group.
	//
	// TargetGroupArn is a required field
	TargetGroupArn *string `type:"string" required:"true"`

	// The targets. If you specified a port override when you registered a target,
	// you must specify both the target ID and the port when you deregister it.
	//
	// Targets is a required field
	Targets []*TargetDescription `type:"list" required:"true"`
}

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

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

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

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

// SetTargetGroupArn sets the TargetGroupArn field's value.
func (s *DeregisterTargetsInput) SetTargetGroupArn(v string) *DeregisterTargetsInput {
	s.TargetGroupArn = &v
	return s
}

// SetTargets sets the Targets field's value.
func (s *DeregisterTargetsInput) SetTargets(v []*TargetDescription) *DeregisterTargetsInput {
	s.Targets = v
	return s
}

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

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

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

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

	// The marker for the next set of results. (You received this marker from a
	// previous call.)
	Marker *string `type:"string"`

	// The maximum number of results to return with this call.
	PageSize *int64 `min:"1" type:"integer"`
}

// 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()
}

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

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

// SetMarker sets the Marker field's value.
func (s *DescribeAccountLimitsInput) SetMarker(v string) *DescribeAccountLimitsInput {
	s.Marker = &v
	return s
}

// SetPageSize sets the PageSize field's value.
func (s *DescribeAccountLimitsInput) SetPageSize(v int64) *DescribeAccountLimitsInput {
	s.PageSize = &v
	return s
}

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

	// Information about the limits.
	Limits []*Limit `type:"list"`

	// The marker to use when requesting the next set of results. If there are no
	// additional results, the string is empty.
	NextMarker *string `type:"string"`
}

// 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()
}

// SetLimits sets the Limits field's value.
func (s *DescribeAccountLimitsOutput) SetLimits(v []*Limit) *DescribeAccountLimitsOutput {
	s.Limits = v
	return s
}

// SetNextMarker sets the NextMarker field's value.
func (s *DescribeAccountLimitsOutput) SetNextMarker(v string) *DescribeAccountLimitsOutput {
	s.NextMarker = &v
	return s
}

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

	// The Amazon Resource Names (ARN) of the listener.
	//
	// ListenerArn is a required field
	ListenerArn *string `type:"string" required:"true"`

	// The marker for the next set of results. (You received this marker from a
	// previous call.)
	Marker *string `type:"string"`

	// The maximum number of results to return with this call.
	PageSize *int64 `min:"1" type:"integer"`
}

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

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

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

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

// SetListenerArn sets the ListenerArn field's value.
func (s *DescribeListenerCertificatesInput) SetListenerArn(v string) *DescribeListenerCertificatesInput {
	s.ListenerArn = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *DescribeListenerCertificatesInput) SetMarker(v string) *DescribeListenerCertificatesInput {
	s.Marker = &v
	return s
}

// SetPageSize sets the PageSize field's value.
func (s *DescribeListenerCertificatesInput) SetPageSize(v int64) *DescribeListenerCertificatesInput {
	s.PageSize = &v
	return s
}

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

	// Information about the certificates.
	Certificates []*Certificate `type:"list"`

	// The marker to use when requesting the next set of results. If there are no
	// additional results, the string is empty.
	NextMarker *string `type:"string"`
}

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

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

// SetCertificates sets the Certificates field's value.
func (s *DescribeListenerCertificatesOutput) SetCertificates(v []*Certificate) *DescribeListenerCertificatesOutput {
	s.Certificates = v
	return s
}

// SetNextMarker sets the NextMarker field's value.
func (s *DescribeListenerCertificatesOutput) SetNextMarker(v string) *DescribeListenerCertificatesOutput {
	s.NextMarker = &v
	return s
}

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

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

	// The Amazon Resource Name (ARN) of the load balancer.
	LoadBalancerArn *string `type:"string"`

	// The marker for the next set of results. (You received this marker from a
	// previous call.)
	Marker *string `type:"string"`

	// The maximum number of results to return with this call.
	PageSize *int64 `min:"1" type:"integer"`
}

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

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

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

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

// SetListenerArns sets the ListenerArns field's value.
func (s *DescribeListenersInput) SetListenerArns(v []*string) *DescribeListenersInput {
	s.ListenerArns = v
	return s
}

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *DescribeListenersInput) SetLoadBalancerArn(v string) *DescribeListenersInput {
	s.LoadBalancerArn = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *DescribeListenersInput) SetMarker(v string) *DescribeListenersInput {
	s.Marker = &v
	return s
}

// SetPageSize sets the PageSize field's value.
func (s *DescribeListenersInput) SetPageSize(v int64) *DescribeListenersInput {
	s.PageSize = &v
	return s
}

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

	// Information about the listeners.
	Listeners []*Listener `type:"list"`

	// The marker to use when requesting the next set of results. If there are no
	// additional results, the string is empty.
	NextMarker *string `type:"string"`
}

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

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

// SetListeners sets the Listeners field's value.
func (s *DescribeListenersOutput) SetListeners(v []*Listener) *DescribeListenersOutput {
	s.Listeners = v
	return s
}

// SetNextMarker sets the NextMarker field's value.
func (s *DescribeListenersOutput) SetNextMarker(v string) *DescribeListenersOutput {
	s.NextMarker = &v
	return s
}

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

	// The Amazon Resource Name (ARN) of the load balancer.
	//
	// LoadBalancerArn is a required field
	LoadBalancerArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeLoadBalancerAttributesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeLoadBalancerAttributesInput"}
	if s.LoadBalancerArn == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerArn"))
	}

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

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *DescribeLoadBalancerAttributesInput) SetLoadBalancerArn(v string) *DescribeLoadBalancerAttributesInput {
	s.LoadBalancerArn = &v
	return s
}

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

	// Information about the load balancer attributes.
	Attributes []*LoadBalancerAttribute `type:"list"`
}

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

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

// SetAttributes sets the Attributes field's value.
func (s *DescribeLoadBalancerAttributesOutput) SetAttributes(v []*LoadBalancerAttribute) *DescribeLoadBalancerAttributesOutput {
	s.Attributes = v
	return s
}

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

	// The Amazon Resource Names (ARN) of the load balancers. You can specify up
	// to 20 load balancers in a single call.
	LoadBalancerArns []*string `type:"list"`

	// The marker for the next set of results. (You received this marker from a
	// previous call.)
	Marker *string `type:"string"`

	// The names of the load balancers.
	Names []*string `type:"list"`

	// The maximum number of results to return with this call.
	PageSize *int64 `min:"1" type:"integer"`
}

// 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.PageSize != nil && *s.PageSize < 1 {
		invalidParams.Add(request.NewErrParamMinValue("PageSize", 1))
	}

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

// SetLoadBalancerArns sets the LoadBalancerArns field's value.
func (s *DescribeLoadBalancersInput) SetLoadBalancerArns(v []*string) *DescribeLoadBalancersInput {
	s.LoadBalancerArns = v
	return s
}

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

// SetNames sets the Names field's value.
func (s *DescribeLoadBalancersInput) SetNames(v []*string) *DescribeLoadBalancersInput {
	s.Names = v
	return s
}

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

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

	// Information about the load balancers.
	LoadBalancers []*LoadBalancer `type:"list"`

	// The marker to use when requesting the next set of results. If there are no
	// additional results, the string is empty.
	NextMarker *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 []*LoadBalancer) *DescribeLoadBalancersOutput {
	s.LoadBalancers = v
	return s
}

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

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

	// The Amazon Resource Name (ARN) of the listener.
	ListenerArn *string `type:"string"`

	// The marker for the next set of results. (You received this marker from a
	// previous call.)
	Marker *string `type:"string"`

	// The maximum number of results to return with this call.
	PageSize *int64 `min:"1" type:"integer"`

	// The Amazon Resource Names (ARN) of the rules.
	RuleArns []*string `type:"list"`
}

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

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

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

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

// SetListenerArn sets the ListenerArn field's value.
func (s *DescribeRulesInput) SetListenerArn(v string) *DescribeRulesInput {
	s.ListenerArn = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *DescribeRulesInput) SetMarker(v string) *DescribeRulesInput {
	s.Marker = &v
	return s
}

// SetPageSize sets the PageSize field's value.
func (s *DescribeRulesInput) SetPageSize(v int64) *DescribeRulesInput {
	s.PageSize = &v
	return s
}

// SetRuleArns sets the RuleArns field's value.
func (s *DescribeRulesInput) SetRuleArns(v []*string) *DescribeRulesInput {
	s.RuleArns = v
	return s
}

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

	// The marker to use when requesting the next set of results. If there are no
	// additional results, the string is empty.
	NextMarker *string `type:"string"`

	// Information about the rules.
	Rules []*Rule `type:"list"`
}

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

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

// SetNextMarker sets the NextMarker field's value.
func (s *DescribeRulesOutput) SetNextMarker(v string) *DescribeRulesOutput {
	s.NextMarker = &v
	return s
}

// SetRules sets the Rules field's value.
func (s *DescribeRulesOutput) SetRules(v []*Rule) *DescribeRulesOutput {
	s.Rules = v
	return s
}

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

	// The marker for the next set of results. (You received this marker from a
	// previous call.)
	Marker *string `type:"string"`

	// The names of the policies.
	Names []*string `type:"list"`

	// The maximum number of results to return with this call.
	PageSize *int64 `min:"1" type:"integer"`
}

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

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

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

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

// SetMarker sets the Marker field's value.
func (s *DescribeSSLPoliciesInput) SetMarker(v string) *DescribeSSLPoliciesInput {
	s.Marker = &v
	return s
}

// SetNames sets the Names field's value.
func (s *DescribeSSLPoliciesInput) SetNames(v []*string) *DescribeSSLPoliciesInput {
	s.Names = v
	return s
}

// SetPageSize sets the PageSize field's value.
func (s *DescribeSSLPoliciesInput) SetPageSize(v int64) *DescribeSSLPoliciesInput {
	s.PageSize = &v
	return s
}

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

	// The marker to use when requesting the next set of results. If there are no
	// additional results, the string is empty.
	NextMarker *string `type:"string"`

	// Information about the policies.
	SslPolicies []*SslPolicy `type:"list"`
}

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

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

// SetNextMarker sets the NextMarker field's value.
func (s *DescribeSSLPoliciesOutput) SetNextMarker(v string) *DescribeSSLPoliciesOutput {
	s.NextMarker = &v
	return s
}

// SetSslPolicies sets the SslPolicies field's value.
func (s *DescribeSSLPoliciesOutput) SetSslPolicies(v []*SslPolicy) *DescribeSSLPoliciesOutput {
	s.SslPolicies = v
	return s
}

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

	// The Amazon Resource Names (ARN) of the resources.
	//
	// ResourceArns is a required field
	ResourceArns []*string `type:"list" required:"true"`
}

// 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()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeTagsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeTagsInput"}
	if s.ResourceArns == nil {
		invalidParams.Add(request.NewErrParamRequired("ResourceArns"))
	}

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

// SetResourceArns sets the ResourceArns field's value.
func (s *DescribeTagsInput) SetResourceArns(v []*string) *DescribeTagsInput {
	s.ResourceArns = v
	return s
}

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

	// Information about the tags.
	TagDescriptions []*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()
}

// SetTagDescriptions sets the TagDescriptions field's value.
func (s *DescribeTagsOutput) SetTagDescriptions(v []*TagDescription) *DescribeTagsOutput {
	s.TagDescriptions = v
	return s
}

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

	// The Amazon Resource Name (ARN) of the target group.
	//
	// TargetGroupArn is a required field
	TargetGroupArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeTargetGroupAttributesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeTargetGroupAttributesInput"}
	if s.TargetGroupArn == nil {
		invalidParams.Add(request.NewErrParamRequired("TargetGroupArn"))
	}

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

// SetTargetGroupArn sets the TargetGroupArn field's value.
func (s *DescribeTargetGroupAttributesInput) SetTargetGroupArn(v string) *DescribeTargetGroupAttributesInput {
	s.TargetGroupArn = &v
	return s
}

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

	// Information about the target group attributes
	Attributes []*TargetGroupAttribute `type:"list"`
}

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

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

// SetAttributes sets the Attributes field's value.
func (s *DescribeTargetGroupAttributesOutput) SetAttributes(v []*TargetGroupAttribute) *DescribeTargetGroupAttributesOutput {
	s.Attributes = v
	return s
}

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

	// The Amazon Resource Name (ARN) of the load balancer.
	LoadBalancerArn *string `type:"string"`

	// The marker for the next set of results. (You received this marker from a
	// previous call.)
	Marker *string `type:"string"`

	// The names of the target groups.
	Names []*string `type:"list"`

	// The maximum number of results to return with this call.
	PageSize *int64 `min:"1" type:"integer"`

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

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

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

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

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

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *DescribeTargetGroupsInput) SetLoadBalancerArn(v string) *DescribeTargetGroupsInput {
	s.LoadBalancerArn = &v
	return s
}

// SetMarker sets the Marker field's value.
func (s *DescribeTargetGroupsInput) SetMarker(v string) *DescribeTargetGroupsInput {
	s.Marker = &v
	return s
}

// SetNames sets the Names field's value.
func (s *DescribeTargetGroupsInput) SetNames(v []*string) *DescribeTargetGroupsInput {
	s.Names = v
	return s
}

// SetPageSize sets the PageSize field's value.
func (s *DescribeTargetGroupsInput) SetPageSize(v int64) *DescribeTargetGroupsInput {
	s.PageSize = &v
	return s
}

// SetTargetGroupArns sets the TargetGroupArns field's value.
func (s *DescribeTargetGroupsInput) SetTargetGroupArns(v []*string) *DescribeTargetGroupsInput {
	s.TargetGroupArns = v
	return s
}

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

	// The marker to use when requesting the next set of results. If there are no
	// additional results, the string is empty.
	NextMarker *string `type:"string"`

	// Information about the target groups.
	TargetGroups []*TargetGroup `type:"list"`
}

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

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

// SetNextMarker sets the NextMarker field's value.
func (s *DescribeTargetGroupsOutput) SetNextMarker(v string) *DescribeTargetGroupsOutput {
	s.NextMarker = &v
	return s
}

// SetTargetGroups sets the TargetGroups field's value.
func (s *DescribeTargetGroupsOutput) SetTargetGroups(v []*TargetGroup) *DescribeTargetGroupsOutput {
	s.TargetGroups = v
	return s
}

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

	// The Amazon Resource Name (ARN) of the target group.
	//
	// TargetGroupArn is a required field
	TargetGroupArn *string `type:"string" required:"true"`

	// The targets.
	Targets []*TargetDescription `type:"list"`
}

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

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

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

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

// SetTargetGroupArn sets the TargetGroupArn field's value.
func (s *DescribeTargetHealthInput) SetTargetGroupArn(v string) *DescribeTargetHealthInput {
	s.TargetGroupArn = &v
	return s
}

// SetTargets sets the Targets field's value.
func (s *DescribeTargetHealthInput) SetTargets(v []*TargetDescription) *DescribeTargetHealthInput {
	s.Targets = v
	return s
}

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

	// Information about the health of the targets.
	TargetHealthDescriptions []*TargetHealthDescription `type:"list"`
}

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

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

// SetTargetHealthDescriptions sets the TargetHealthDescriptions field's value.
func (s *DescribeTargetHealthOutput) SetTargetHealthDescriptions(v []*TargetHealthDescription) *DescribeTargetHealthOutput {
	s.TargetHealthDescriptions = v
	return s
}

// Information about an action that returns a custom HTTP response.
type FixedResponseActionConfig struct {
	_ struct{} `type:"structure"`

	// The content type.
	//
	// Valid Values: text/plain | text/css | text/html | application/javascript
	// | application/json
	ContentType *string `type:"string"`

	// The message.
	MessageBody *string `type:"string"`

	// The HTTP response code (2XX, 4XX, or 5XX).
	//
	// StatusCode is a required field
	StatusCode *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *FixedResponseActionConfig) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "FixedResponseActionConfig"}
	if s.StatusCode == nil {
		invalidParams.Add(request.NewErrParamRequired("StatusCode"))
	}

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

// SetContentType sets the ContentType field's value.
func (s *FixedResponseActionConfig) SetContentType(v string) *FixedResponseActionConfig {
	s.ContentType = &v
	return s
}

// SetMessageBody sets the MessageBody field's value.
func (s *FixedResponseActionConfig) SetMessageBody(v string) *FixedResponseActionConfig {
	s.MessageBody = &v
	return s
}

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

// Information about an Elastic Load Balancing resource limit for your AWS account.
type Limit struct {
	_ struct{} `type:"structure"`

	// The maximum value of the limit.
	Max *string `type:"string"`

	// The name of the limit. The possible values are:
	//
	//    * application-load-balancers
	//
	//    * listeners-per-application-load-balancer
	//
	//    * listeners-per-network-load-balancer
	//
	//    * network-load-balancers
	//
	//    * rules-per-application-load-balancer
	//
	//    * target-groups
	//
	//    * targets-per-application-load-balancer
	//
	//    * targets-per-availability-zone-per-network-load-balancer
	//
	//    * targets-per-network-load-balancer
	Name *string `type:"string"`
}

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

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

// SetMax sets the Max field's value.
func (s *Limit) SetMax(v string) *Limit {
	s.Max = &v
	return s
}

// SetName sets the Name field's value.
func (s *Limit) SetName(v string) *Limit {
	s.Name = &v
	return s
}

// Information about a listener.
type Listener struct {
	_ struct{} `type:"structure"`

	// The SSL server certificate. You must provide a certificate if the protocol
	// is HTTPS or TLS.
	Certificates []*Certificate `type:"list"`

	// The default actions for the listener.
	DefaultActions []*Action `type:"list"`

	// The Amazon Resource Name (ARN) of the listener.
	ListenerArn *string `type:"string"`

	// The Amazon Resource Name (ARN) of the load balancer.
	LoadBalancerArn *string `type:"string"`

	// The port on which the load balancer is listening.
	Port *int64 `min:"1" type:"integer"`

	// The protocol for connections from clients to the load balancer.
	Protocol *string `type:"string" enum:"ProtocolEnum"`

	// The security policy that defines which ciphers and protocols are supported.
	// The default is the current predefined security policy.
	SslPolicy *string `type:"string"`
}

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

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

// SetCertificates sets the Certificates field's value.
func (s *Listener) SetCertificates(v []*Certificate) *Listener {
	s.Certificates = v
	return s
}

// SetDefaultActions sets the DefaultActions field's value.
func (s *Listener) SetDefaultActions(v []*Action) *Listener {
	s.DefaultActions = v
	return s
}

// SetListenerArn sets the ListenerArn field's value.
func (s *Listener) SetListenerArn(v string) *Listener {
	s.ListenerArn = &v
	return s
}

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *Listener) SetLoadBalancerArn(v string) *Listener {
	s.LoadBalancerArn = &v
	return s
}

// SetPort sets the Port field's value.
func (s *Listener) SetPort(v int64) *Listener {
	s.Port = &v
	return s
}

// SetProtocol sets the Protocol field's value.
func (s *Listener) SetProtocol(v string) *Listener {
	s.Protocol = &v
	return s
}

// SetSslPolicy sets the SslPolicy field's value.
func (s *Listener) SetSslPolicy(v string) *Listener {
	s.SslPolicy = &v
	return s
}

// Information about a load balancer.
type LoadBalancer struct {
	_ struct{} `type:"structure"`

	// The Availability Zones for the load balancer.
	AvailabilityZones []*AvailabilityZone `type:"list"`

	// The ID of the Amazon Route 53 hosted zone associated with the load balancer.
	CanonicalHostedZoneId *string `type:"string"`

	// The date and time the load balancer was created.
	CreatedTime *time.Time `type:"timestamp"`

	// The public DNS name of the load balancer.
	DNSName *string `type:"string"`

	// The type of IP addresses used by the subnets for your load balancer. The
	// possible values are ipv4 (for IPv4 addresses) and dualstack (for IPv4 and
	// IPv6 addresses).
	IpAddressType *string `type:"string" enum:"IpAddressType"`

	// The Amazon Resource Name (ARN) of the load balancer.
	LoadBalancerArn *string `type:"string"`

	// The name of the load balancer.
	LoadBalancerName *string `type:"string"`

	// The nodes of an Internet-facing load balancer have public IP addresses. The
	// DNS name of an Internet-facing load balancer is publicly resolvable to the
	// public IP addresses of the nodes. Therefore, Internet-facing load balancers
	// can route requests from clients over the internet.
	//
	// The nodes of an internal load balancer have only private IP addresses. The
	// DNS name of an internal load balancer is publicly resolvable to the private
	// IP addresses of the nodes. Therefore, internal load balancers can only route
	// requests from clients with access to the VPC for the load balancer.
	Scheme *string `type:"string" enum:"LoadBalancerSchemeEnum"`

	// The IDs of the security groups for the load balancer.
	SecurityGroups []*string `type:"list"`

	// The state of the load balancer.
	State *LoadBalancerState `type:"structure"`

	// The type of load balancer.
	Type *string `type:"string" enum:"LoadBalancerTypeEnum"`

	// The ID of the VPC for the load balancer.
	VpcId *string `type:"string"`
}

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

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

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

// SetCanonicalHostedZoneId sets the CanonicalHostedZoneId field's value.
func (s *LoadBalancer) SetCanonicalHostedZoneId(v string) *LoadBalancer {
	s.CanonicalHostedZoneId = &v
	return s
}

// SetCreatedTime sets the CreatedTime field's value.
func (s *LoadBalancer) SetCreatedTime(v time.Time) *LoadBalancer {
	s.CreatedTime = &v
	return s
}

// SetDNSName sets the DNSName field's value.
func (s *LoadBalancer) SetDNSName(v string) *LoadBalancer {
	s.DNSName = &v
	return s
}

// SetIpAddressType sets the IpAddressType field's value.
func (s *LoadBalancer) SetIpAddressType(v string) *LoadBalancer {
	s.IpAddressType = &v
	return s
}

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *LoadBalancer) SetLoadBalancerArn(v string) *LoadBalancer {
	s.LoadBalancerArn = &v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *LoadBalancer) SetLoadBalancerName(v string) *LoadBalancer {
	s.LoadBalancerName = &v
	return s
}

// SetScheme sets the Scheme field's value.
func (s *LoadBalancer) SetScheme(v string) *LoadBalancer {
	s.Scheme = &v
	return s
}

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

// SetState sets the State field's value.
func (s *LoadBalancer) SetState(v *LoadBalancerState) *LoadBalancer {
	s.State = v
	return s
}

// SetType sets the Type field's value.
func (s *LoadBalancer) SetType(v string) *LoadBalancer {
	s.Type = &v
	return s
}

// SetVpcId sets the VpcId field's value.
func (s *LoadBalancer) SetVpcId(v string) *LoadBalancer {
	s.VpcId = &v
	return s
}

// Information about a static IP address for a load balancer.
type LoadBalancerAddress struct {
	_ struct{} `type:"structure"`

	// [Network Load Balancers] The allocation ID of the Elastic IP address.
	AllocationId *string `type:"string"`

	// The static IP address.
	IpAddress *string `type:"string"`
}

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

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

// SetAllocationId sets the AllocationId field's value.
func (s *LoadBalancerAddress) SetAllocationId(v string) *LoadBalancerAddress {
	s.AllocationId = &v
	return s
}

// SetIpAddress sets the IpAddress field's value.
func (s *LoadBalancerAddress) SetIpAddress(v string) *LoadBalancerAddress {
	s.IpAddress = &v
	return s
}

// Information about a load balancer attribute.
type LoadBalancerAttribute struct {
	_ struct{} `type:"structure"`

	// The name of the attribute.
	//
	// The following attributes are supported by both Application Load Balancers
	// and Network Load Balancers:
	//
	//    * deletion_protection.enabled - Indicates whether deletion protection
	//    is enabled. The value is true or false. The default is false.
	//
	// The following attributes are supported by only Application Load Balancers:
	//
	//    * access_logs.s3.enabled - Indicates whether access logs are enabled.
	//    The value is true or false. The default is false.
	//
	//    * access_logs.s3.bucket - The name of the S3 bucket for the access logs.
	//    This attribute is required if access logs are enabled. The bucket must
	//    exist in the same region as the load balancer and have a bucket policy
	//    that grants Elastic Load Balancing permissions to write to the bucket.
	//
	//    * access_logs.s3.prefix - The prefix for the location in the S3 bucket
	//    for the access logs.
	//
	//    * idle_timeout.timeout_seconds - The idle timeout value, in seconds. The
	//    valid range is 1-4000 seconds. The default is 60 seconds.
	//
	//    * routing.http2.enabled - Indicates whether HTTP/2 is enabled. The value
	//    is true or false. The default is true.
	//
	// The following attributes are supported by only Network Load Balancers:
	//
	//    * load_balancing.cross_zone.enabled - Indicates whether cross-zone load
	//    balancing is enabled. The value is true or false. The default is false.
	Key *string `type:"string"`

	// The value of the attribute.
	Value *string `type:"string"`
}

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

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

// SetKey sets the Key field's value.
func (s *LoadBalancerAttribute) SetKey(v string) *LoadBalancerAttribute {
	s.Key = &v
	return s
}

// SetValue sets the Value field's value.
func (s *LoadBalancerAttribute) SetValue(v string) *LoadBalancerAttribute {
	s.Value = &v
	return s
}

// Information about the state of the load balancer.
type LoadBalancerState struct {
	_ struct{} `type:"structure"`

	// The state code. The initial state of the load balancer is provisioning. After
	// the load balancer is fully set up and ready to route traffic, its state is
	// active. If the load balancer could not be set up, its state is failed.
	Code *string `type:"string" enum:"LoadBalancerStateEnum"`

	// A description of the state.
	Reason *string `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()
}

// SetCode sets the Code field's value.
func (s *LoadBalancerState) SetCode(v string) *LoadBalancerState {
	s.Code = &v
	return s
}

// SetReason sets the Reason field's value.
func (s *LoadBalancerState) SetReason(v string) *LoadBalancerState {
	s.Reason = &v
	return s
}

// Information to use when checking for a successful response from a target.
type Matcher struct {
	_ struct{} `type:"structure"`

	// The HTTP codes.
	//
	// For Application Load Balancers, you can specify values between 200 and 499,
	// and the default value is 200. You can specify multiple values (for example,
	// "200,202") or a range of values (for example, "200-299").
	//
	// For Network Load Balancers, this is 200–399.
	//
	// HttpCode is a required field
	HttpCode *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *Matcher) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "Matcher"}
	if s.HttpCode == nil {
		invalidParams.Add(request.NewErrParamRequired("HttpCode"))
	}

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

// SetHttpCode sets the HttpCode field's value.
func (s *Matcher) SetHttpCode(v string) *Matcher {
	s.HttpCode = &v
	return s
}

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

	// [HTTPS and TLS listeners] The default SSL server certificate. You must provide
	// exactly one certificate. Set CertificateArn to the certificate ARN but do
	// not set IsDefault.
	//
	// To create a certificate list, use AddListenerCertificates.
	Certificates []*Certificate `type:"list"`

	// The actions for the default rule. The rule must include one forward action
	// or one or more fixed-response actions.
	//
	// If the action type is forward, you specify a target group. The protocol of
	// the target group must be HTTP or HTTPS for an Application Load Balancer.
	// The protocol of the target group must be TCP or TLS for a Network Load Balancer.
	//
	// [HTTPS listeners] If the action type is authenticate-oidc, you authenticate
	// users through an identity provider that is OpenID Connect (OIDC) compliant.
	//
	// [HTTPS listeners] If the action type is authenticate-cognito, you authenticate
	// users through the user pools supported by Amazon Cognito.
	//
	// [Application Load Balancer] If the action type is redirect, you redirect
	// specified client requests from one URL to another.
	//
	// [Application Load Balancer] If the action type is fixed-response, you drop
	// specified client requests and return a custom HTTP response.
	DefaultActions []*Action `type:"list"`

	// The Amazon Resource Name (ARN) of the listener.
	//
	// ListenerArn is a required field
	ListenerArn *string `type:"string" required:"true"`

	// The port for connections from clients to the load balancer.
	Port *int64 `min:"1" type:"integer"`

	// The protocol for connections from clients to the load balancer. Application
	// Load Balancers support the HTTP and HTTPS protocols. Network Load Balancers
	// support the TCP and TLS protocols.
	Protocol *string `type:"string" enum:"ProtocolEnum"`

	// [HTTPS and TLS listeners] The security policy that defines which protocols
	// and ciphers are supported. For more information, see Security Policies (http://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies)
	// in the Application Load Balancers Guide.
	SslPolicy *string `type:"string"`
}

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

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

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

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

// SetCertificates sets the Certificates field's value.
func (s *ModifyListenerInput) SetCertificates(v []*Certificate) *ModifyListenerInput {
	s.Certificates = v
	return s
}

// SetDefaultActions sets the DefaultActions field's value.
func (s *ModifyListenerInput) SetDefaultActions(v []*Action) *ModifyListenerInput {
	s.DefaultActions = v
	return s
}

// SetListenerArn sets the ListenerArn field's value.
func (s *ModifyListenerInput) SetListenerArn(v string) *ModifyListenerInput {
	s.ListenerArn = &v
	return s
}

// SetPort sets the Port field's value.
func (s *ModifyListenerInput) SetPort(v int64) *ModifyListenerInput {
	s.Port = &v
	return s
}

// SetProtocol sets the Protocol field's value.
func (s *ModifyListenerInput) SetProtocol(v string) *ModifyListenerInput {
	s.Protocol = &v
	return s
}

// SetSslPolicy sets the SslPolicy field's value.
func (s *ModifyListenerInput) SetSslPolicy(v string) *ModifyListenerInput {
	s.SslPolicy = &v
	return s
}

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

	// Information about the modified listener.
	Listeners []*Listener `type:"list"`
}

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

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

// SetListeners sets the Listeners field's value.
func (s *ModifyListenerOutput) SetListeners(v []*Listener) *ModifyListenerOutput {
	s.Listeners = v
	return s
}

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

	// The load balancer attributes.
	//
	// Attributes is a required field
	Attributes []*LoadBalancerAttribute `type:"list" required:"true"`

	// The Amazon Resource Name (ARN) of the load balancer.
	//
	// LoadBalancerArn is a required field
	LoadBalancerArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *ModifyLoadBalancerAttributesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ModifyLoadBalancerAttributesInput"}
	if s.Attributes == nil {
		invalidParams.Add(request.NewErrParamRequired("Attributes"))
	}
	if s.LoadBalancerArn == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerArn"))
	}

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

// SetAttributes sets the Attributes field's value.
func (s *ModifyLoadBalancerAttributesInput) SetAttributes(v []*LoadBalancerAttribute) *ModifyLoadBalancerAttributesInput {
	s.Attributes = v
	return s
}

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *ModifyLoadBalancerAttributesInput) SetLoadBalancerArn(v string) *ModifyLoadBalancerAttributesInput {
	s.LoadBalancerArn = &v
	return s
}

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

	// Information about the load balancer attributes.
	Attributes []*LoadBalancerAttribute `type:"list"`
}

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

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

// SetAttributes sets the Attributes field's value.
func (s *ModifyLoadBalancerAttributesOutput) SetAttributes(v []*LoadBalancerAttribute) *ModifyLoadBalancerAttributesOutput {
	s.Attributes = v
	return s
}

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

	// The actions.
	//
	// If the action type is forward, you specify a target group. The protocol of
	// the target group must be HTTP or HTTPS for an Application Load Balancer.
	// The protocol of the target group must be TCP or TLS for a Network Load Balancer.
	//
	// [HTTPS listeners] If the action type is authenticate-oidc, you authenticate
	// users through an identity provider that is OpenID Connect (OIDC) compliant.
	//
	// [HTTPS listeners] If the action type is authenticate-cognito, you authenticate
	// users through the user pools supported by Amazon Cognito.
	//
	// [Application Load Balancer] If the action type is redirect, you redirect
	// specified client requests from one URL to another.
	//
	// [Application Load Balancer] If the action type is fixed-response, you drop
	// specified client requests and return a custom HTTP response.
	Actions []*Action `type:"list"`

	// The conditions. Each condition specifies a field name and a single value.
	//
	// If the field name is host-header, you can specify a single host name (for
	// example, my.example.com). A host name is case insensitive, can be up to 128
	// characters in length, and can contain any of the following characters. You
	// can include up to three wildcard characters.
	//
	//    * A-Z, a-z, 0-9
	//
	//    * - .
	//
	//    * * (matches 0 or more characters)
	//
	//    * ? (matches exactly 1 character)
	//
	// If the field name is path-pattern, you can specify a single path pattern.
	// A path pattern is case-sensitive, can be up to 128 characters in length,
	// and can contain any of the following characters. You can include up to three
	// wildcard characters.
	//
	//    * A-Z, a-z, 0-9
	//
	//    * _ - . $ / ~ " ' @ : +
	//
	//    * & (using &)
	//
	//    * * (matches 0 or more characters)
	//
	//    * ? (matches exactly 1 character)
	Conditions []*RuleCondition `type:"list"`

	// The Amazon Resource Name (ARN) of the rule.
	//
	// RuleArn is a required field
	RuleArn *string `type:"string" required:"true"`
}

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

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

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

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

// SetActions sets the Actions field's value.
func (s *ModifyRuleInput) SetActions(v []*Action) *ModifyRuleInput {
	s.Actions = v
	return s
}

// SetConditions sets the Conditions field's value.
func (s *ModifyRuleInput) SetConditions(v []*RuleCondition) *ModifyRuleInput {
	s.Conditions = v
	return s
}

// SetRuleArn sets the RuleArn field's value.
func (s *ModifyRuleInput) SetRuleArn(v string) *ModifyRuleInput {
	s.RuleArn = &v
	return s
}

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

	// Information about the modified rule.
	Rules []*Rule `type:"list"`
}

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

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

// SetRules sets the Rules field's value.
func (s *ModifyRuleOutput) SetRules(v []*Rule) *ModifyRuleOutput {
	s.Rules = v
	return s
}

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

	// The attributes.
	//
	// Attributes is a required field
	Attributes []*TargetGroupAttribute `type:"list" required:"true"`

	// The Amazon Resource Name (ARN) of the target group.
	//
	// TargetGroupArn is a required field
	TargetGroupArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *ModifyTargetGroupAttributesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ModifyTargetGroupAttributesInput"}
	if s.Attributes == nil {
		invalidParams.Add(request.NewErrParamRequired("Attributes"))
	}
	if s.TargetGroupArn == nil {
		invalidParams.Add(request.NewErrParamRequired("TargetGroupArn"))
	}

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

// SetAttributes sets the Attributes field's value.
func (s *ModifyTargetGroupAttributesInput) SetAttributes(v []*TargetGroupAttribute) *ModifyTargetGroupAttributesInput {
	s.Attributes = v
	return s
}

// SetTargetGroupArn sets the TargetGroupArn field's value.
func (s *ModifyTargetGroupAttributesInput) SetTargetGroupArn(v string) *ModifyTargetGroupAttributesInput {
	s.TargetGroupArn = &v
	return s
}

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

	// Information about the attributes.
	Attributes []*TargetGroupAttribute `type:"list"`
}

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

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

// SetAttributes sets the Attributes field's value.
func (s *ModifyTargetGroupAttributesOutput) SetAttributes(v []*TargetGroupAttribute) *ModifyTargetGroupAttributesOutput {
	s.Attributes = v
	return s
}

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

	// Indicates whether health checks are enabled.
	HealthCheckEnabled *bool `type:"boolean"`

	// The approximate amount of time, in seconds, between health checks of an individual
	// target. For Application Load Balancers, the range is 5–300 seconds. For Network
	// Load Balancers, the supported values are 10 or 30 seconds.
	//
	// If the protocol of the target group is TCP, you can't modify this setting.
	HealthCheckIntervalSeconds *int64 `min:"5" type:"integer"`

	// [HTTP/HTTPS health checks] The ping path that is the destination for the
	// health check request.
	HealthCheckPath *string `min:"1" type:"string"`

	// The port the load balancer uses when performing health checks on targets.
	HealthCheckPort *string `type:"string"`

	// The protocol the load balancer uses when performing health checks on targets.
	// The TCP protocol is supported for health checks only if the protocol of the
	// target group is TCP or TLS. The TLS protocol is not supported for health
	// checks.
	//
	// If the protocol of the target group is TCP, you can't modify this setting.
	HealthCheckProtocol *string `type:"string" enum:"ProtocolEnum"`

	// [HTTP/HTTPS health checks] The amount of time, in seconds, during which no
	// response means a failed health check.
	//
	// If the protocol of the target group is TCP, you can't modify this setting.
	HealthCheckTimeoutSeconds *int64 `min:"2" type:"integer"`

	// The number of consecutive health checks successes required before considering
	// an unhealthy target healthy.
	HealthyThresholdCount *int64 `min:"2" type:"integer"`

	// [HTTP/HTTPS health checks] The HTTP codes to use when checking for a successful
	// response from a target.
	//
	// If the protocol of the target group is TCP, you can't modify this setting.
	Matcher *Matcher `type:"structure"`

	// The Amazon Resource Name (ARN) of the target group.
	//
	// TargetGroupArn is a required field
	TargetGroupArn *string `type:"string" required:"true"`

	// The number of consecutive health check failures required before considering
	// the target unhealthy. For Network Load Balancers, this value must be the
	// same as the healthy threshold count.
	UnhealthyThresholdCount *int64 `min:"2" type:"integer"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *ModifyTargetGroupInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ModifyTargetGroupInput"}
	if s.HealthCheckIntervalSeconds != nil && *s.HealthCheckIntervalSeconds < 5 {
		invalidParams.Add(request.NewErrParamMinValue("HealthCheckIntervalSeconds", 5))
	}
	if s.HealthCheckPath != nil && len(*s.HealthCheckPath) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("HealthCheckPath", 1))
	}
	if s.HealthCheckTimeoutSeconds != nil && *s.HealthCheckTimeoutSeconds < 2 {
		invalidParams.Add(request.NewErrParamMinValue("HealthCheckTimeoutSeconds", 2))
	}
	if s.HealthyThresholdCount != nil && *s.HealthyThresholdCount < 2 {
		invalidParams.Add(request.NewErrParamMinValue("HealthyThresholdCount", 2))
	}
	if s.TargetGroupArn == nil {
		invalidParams.Add(request.NewErrParamRequired("TargetGroupArn"))
	}
	if s.UnhealthyThresholdCount != nil && *s.UnhealthyThresholdCount < 2 {
		invalidParams.Add(request.NewErrParamMinValue("UnhealthyThresholdCount", 2))
	}
	if s.Matcher != nil {
		if err := s.Matcher.Validate(); err != nil {
			invalidParams.AddNested("Matcher", err.(request.ErrInvalidParams))
		}
	}

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

// SetHealthCheckEnabled sets the HealthCheckEnabled field's value.
func (s *ModifyTargetGroupInput) SetHealthCheckEnabled(v bool) *ModifyTargetGroupInput {
	s.HealthCheckEnabled = &v
	return s
}

// SetHealthCheckIntervalSeconds sets the HealthCheckIntervalSeconds field's value.
func (s *ModifyTargetGroupInput) SetHealthCheckIntervalSeconds(v int64) *ModifyTargetGroupInput {
	s.HealthCheckIntervalSeconds = &v
	return s
}

// SetHealthCheckPath sets the HealthCheckPath field's value.
func (s *ModifyTargetGroupInput) SetHealthCheckPath(v string) *ModifyTargetGroupInput {
	s.HealthCheckPath = &v
	return s
}

// SetHealthCheckPort sets the HealthCheckPort field's value.
func (s *ModifyTargetGroupInput) SetHealthCheckPort(v string) *ModifyTargetGroupInput {
	s.HealthCheckPort = &v
	return s
}

// SetHealthCheckProtocol sets the HealthCheckProtocol field's value.
func (s *ModifyTargetGroupInput) SetHealthCheckProtocol(v string) *ModifyTargetGroupInput {
	s.HealthCheckProtocol = &v
	return s
}

// SetHealthCheckTimeoutSeconds sets the HealthCheckTimeoutSeconds field's value.
func (s *ModifyTargetGroupInput) SetHealthCheckTimeoutSeconds(v int64) *ModifyTargetGroupInput {
	s.HealthCheckTimeoutSeconds = &v
	return s
}

// SetHealthyThresholdCount sets the HealthyThresholdCount field's value.
func (s *ModifyTargetGroupInput) SetHealthyThresholdCount(v int64) *ModifyTargetGroupInput {
	s.HealthyThresholdCount = &v
	return s
}

// SetMatcher sets the Matcher field's value.
func (s *ModifyTargetGroupInput) SetMatcher(v *Matcher) *ModifyTargetGroupInput {
	s.Matcher = v
	return s
}

// SetTargetGroupArn sets the TargetGroupArn field's value.
func (s *ModifyTargetGroupInput) SetTargetGroupArn(v string) *ModifyTargetGroupInput {
	s.TargetGroupArn = &v
	return s
}

// SetUnhealthyThresholdCount sets the UnhealthyThresholdCount field's value.
func (s *ModifyTargetGroupInput) SetUnhealthyThresholdCount(v int64) *ModifyTargetGroupInput {
	s.UnhealthyThresholdCount = &v
	return s
}

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

	// Information about the modified target group.
	TargetGroups []*TargetGroup `type:"list"`
}

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

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

// SetTargetGroups sets the TargetGroups field's value.
func (s *ModifyTargetGroupOutput) SetTargetGroups(v []*TargetGroup) *ModifyTargetGroupOutput {
	s.TargetGroups = v
	return s
}

// Information about a redirect action.
//
// A URI consists of the following components: protocol://hostname:port/path?query.
// You must modify at least one of the following components to avoid a redirect
// loop: protocol, hostname, port, or path. Any components that you do not modify
// retain their original values.
//
// You can reuse URI components using the following reserved keywords:
//
//    * #{protocol}
//
//    * #{host}
//
//    * #{port}
//
//    * #{path} (the leading "/" is removed)
//
//    * #{query}
//
// For example, you can change the path to "/new/#{path}", the hostname to "example.#{host}",
// or the query to "#{query}&value=xyz".
type RedirectActionConfig struct {
	_ struct{} `type:"structure"`

	// The hostname. This component is not percent-encoded. The hostname can contain
	// #{host}.
	Host *string `min:"1" type:"string"`

	// The absolute path, starting with the leading "/". This component is not percent-encoded.
	// The path can contain #{host}, #{path}, and #{port}.
	Path *string `min:"1" type:"string"`

	// The port. You can specify a value from 1 to 65535 or #{port}.
	Port *string `type:"string"`

	// The protocol. You can specify HTTP, HTTPS, or #{protocol}. You can redirect
	// HTTP to HTTP, HTTP to HTTPS, and HTTPS to HTTPS. You cannot redirect HTTPS
	// to HTTP.
	Protocol *string `type:"string"`

	// The query parameters, URL-encoded when necessary, but not percent-encoded.
	// Do not include the leading "?", as it is automatically added. You can specify
	// any of the reserved keywords.
	Query *string `type:"string"`

	// The HTTP redirect code. The redirect is either permanent (HTTP 301) or temporary
	// (HTTP 302).
	//
	// StatusCode is a required field
	StatusCode *string `type:"string" required:"true" enum:"RedirectActionStatusCodeEnum"`
}

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

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

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

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

// SetHost sets the Host field's value.
func (s *RedirectActionConfig) SetHost(v string) *RedirectActionConfig {
	s.Host = &v
	return s
}

// SetPath sets the Path field's value.
func (s *RedirectActionConfig) SetPath(v string) *RedirectActionConfig {
	s.Path = &v
	return s
}

// SetPort sets the Port field's value.
func (s *RedirectActionConfig) SetPort(v string) *RedirectActionConfig {
	s.Port = &v
	return s
}

// SetProtocol sets the Protocol field's value.
func (s *RedirectActionConfig) SetProtocol(v string) *RedirectActionConfig {
	s.Protocol = &v
	return s
}

// SetQuery sets the Query field's value.
func (s *RedirectActionConfig) SetQuery(v string) *RedirectActionConfig {
	s.Query = &v
	return s
}

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

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

	// The Amazon Resource Name (ARN) of the target group.
	//
	// TargetGroupArn is a required field
	TargetGroupArn *string `type:"string" required:"true"`

	// The targets.
	//
	// To register a target by instance ID, specify the instance ID. To register
	// a target by IP address, specify the IP address. To register a Lambda function,
	// specify the ARN of the Lambda function.
	//
	// Targets is a required field
	Targets []*TargetDescription `type:"list" required:"true"`
}

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

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

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

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

// SetTargetGroupArn sets the TargetGroupArn field's value.
func (s *RegisterTargetsInput) SetTargetGroupArn(v string) *RegisterTargetsInput {
	s.TargetGroupArn = &v
	return s
}

// SetTargets sets the Targets field's value.
func (s *RegisterTargetsInput) SetTargets(v []*TargetDescription) *RegisterTargetsInput {
	s.Targets = v
	return s
}

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

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

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

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

	// The certificate to remove. You can specify one certificate per call. Set
	// CertificateArn to the certificate ARN but do not set IsDefault.
	//
	// Certificates is a required field
	Certificates []*Certificate `type:"list" required:"true"`

	// The Amazon Resource Name (ARN) of the listener.
	//
	// ListenerArn is a required field
	ListenerArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *RemoveListenerCertificatesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "RemoveListenerCertificatesInput"}
	if s.Certificates == nil {
		invalidParams.Add(request.NewErrParamRequired("Certificates"))
	}
	if s.ListenerArn == nil {
		invalidParams.Add(request.NewErrParamRequired("ListenerArn"))
	}

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

// SetCertificates sets the Certificates field's value.
func (s *RemoveListenerCertificatesInput) SetCertificates(v []*Certificate) *RemoveListenerCertificatesInput {
	s.Certificates = v
	return s
}

// SetListenerArn sets the ListenerArn field's value.
func (s *RemoveListenerCertificatesInput) SetListenerArn(v string) *RemoveListenerCertificatesInput {
	s.ListenerArn = &v
	return s
}

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

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

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

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

	// The Amazon Resource Name (ARN) of the resource.
	//
	// ResourceArns is a required field
	ResourceArns []*string `type:"list" required:"true"`

	// The tag keys for the tags to remove.
	//
	// TagKeys is a required field
	TagKeys []*string `type:"list" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *RemoveTagsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "RemoveTagsInput"}
	if s.ResourceArns == nil {
		invalidParams.Add(request.NewErrParamRequired("ResourceArns"))
	}
	if s.TagKeys == nil {
		invalidParams.Add(request.NewErrParamRequired("TagKeys"))
	}

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

// SetResourceArns sets the ResourceArns field's value.
func (s *RemoveTagsInput) SetResourceArns(v []*string) *RemoveTagsInput {
	s.ResourceArns = v
	return s
}

// SetTagKeys sets the TagKeys field's value.
func (s *RemoveTagsInput) SetTagKeys(v []*string) *RemoveTagsInput {
	s.TagKeys = v
	return s
}

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

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

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

// Information about a rule.
type Rule struct {
	_ struct{} `type:"structure"`

	// The actions.
	Actions []*Action `type:"list"`

	// The conditions.
	Conditions []*RuleCondition `type:"list"`

	// Indicates whether this is the default rule.
	IsDefault *bool `type:"boolean"`

	// The priority.
	Priority *string `type:"string"`

	// The Amazon Resource Name (ARN) of the rule.
	RuleArn *string `type:"string"`
}

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

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

// SetActions sets the Actions field's value.
func (s *Rule) SetActions(v []*Action) *Rule {
	s.Actions = v
	return s
}

// SetConditions sets the Conditions field's value.
func (s *Rule) SetConditions(v []*RuleCondition) *Rule {
	s.Conditions = v
	return s
}

// SetIsDefault sets the IsDefault field's value.
func (s *Rule) SetIsDefault(v bool) *Rule {
	s.IsDefault = &v
	return s
}

// SetPriority sets the Priority field's value.
func (s *Rule) SetPriority(v string) *Rule {
	s.Priority = &v
	return s
}

// SetRuleArn sets the RuleArn field's value.
func (s *Rule) SetRuleArn(v string) *Rule {
	s.RuleArn = &v
	return s
}

// Information about a condition for a rule.
type RuleCondition struct {
	_ struct{} `type:"structure"`

	// The name of the field. The possible values are host-header and path-pattern.
	Field *string `type:"string"`

	// The condition value.
	//
	// If the field name is host-header, you can specify a single host name (for
	// example, my.example.com). A host name is case insensitive, can be up to 128
	// characters in length, and can contain any of the following characters. You
	// can include up to three wildcard characters.
	//
	//    * A-Z, a-z, 0-9
	//
	//    * - .
	//
	//    * * (matches 0 or more characters)
	//
	//    * ? (matches exactly 1 character)
	//
	// If the field name is path-pattern, you can specify a single path pattern
	// (for example, /img/*). A path pattern is case-sensitive, can be up to 128
	// characters in length, and can contain any of the following characters. You
	// can include up to three wildcard characters.
	//
	//    * A-Z, a-z, 0-9
	//
	//    * _ - . $ / ~ " ' @ : +
	//
	//    * & (using &)
	//
	//    * * (matches 0 or more characters)
	//
	//    * ? (matches exactly 1 character)
	Values []*string `type:"list"`
}

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

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

// SetField sets the Field field's value.
func (s *RuleCondition) SetField(v string) *RuleCondition {
	s.Field = &v
	return s
}

// SetValues sets the Values field's value.
func (s *RuleCondition) SetValues(v []*string) *RuleCondition {
	s.Values = v
	return s
}

// Information about the priorities for the rules for a listener.
type RulePriorityPair struct {
	_ struct{} `type:"structure"`

	// The rule priority.
	Priority *int64 `min:"1" type:"integer"`

	// The Amazon Resource Name (ARN) of the rule.
	RuleArn *string `type:"string"`
}

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

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

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

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

// SetPriority sets the Priority field's value.
func (s *RulePriorityPair) SetPriority(v int64) *RulePriorityPair {
	s.Priority = &v
	return s
}

// SetRuleArn sets the RuleArn field's value.
func (s *RulePriorityPair) SetRuleArn(v string) *RulePriorityPair {
	s.RuleArn = &v
	return s
}

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

	// The IP address type. The possible values are ipv4 (for IPv4 addresses) and
	// dualstack (for IPv4 and IPv6 addresses). Internal load balancers must use
	// ipv4.
	//
	// IpAddressType is a required field
	IpAddressType *string `type:"string" required:"true" enum:"IpAddressType"`

	// The Amazon Resource Name (ARN) of the load balancer.
	//
	// LoadBalancerArn is a required field
	LoadBalancerArn *string `type:"string" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *SetIpAddressTypeInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "SetIpAddressTypeInput"}
	if s.IpAddressType == nil {
		invalidParams.Add(request.NewErrParamRequired("IpAddressType"))
	}
	if s.LoadBalancerArn == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerArn"))
	}

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

// SetIpAddressType sets the IpAddressType field's value.
func (s *SetIpAddressTypeInput) SetIpAddressType(v string) *SetIpAddressTypeInput {
	s.IpAddressType = &v
	return s
}

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *SetIpAddressTypeInput) SetLoadBalancerArn(v string) *SetIpAddressTypeInput {
	s.LoadBalancerArn = &v
	return s
}

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

	// The IP address type.
	IpAddressType *string `type:"string" enum:"IpAddressType"`
}

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

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

// SetIpAddressType sets the IpAddressType field's value.
func (s *SetIpAddressTypeOutput) SetIpAddressType(v string) *SetIpAddressTypeOutput {
	s.IpAddressType = &v
	return s
}

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

	// The rule priorities.
	//
	// RulePriorities is a required field
	RulePriorities []*RulePriorityPair `type:"list" required:"true"`
}

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

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

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

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

// SetRulePriorities sets the RulePriorities field's value.
func (s *SetRulePrioritiesInput) SetRulePriorities(v []*RulePriorityPair) *SetRulePrioritiesInput {
	s.RulePriorities = v
	return s
}

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

	// Information about the rules.
	Rules []*Rule `type:"list"`
}

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

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

// SetRules sets the Rules field's value.
func (s *SetRulePrioritiesOutput) SetRules(v []*Rule) *SetRulePrioritiesOutput {
	s.Rules = v
	return s
}

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

	// The Amazon Resource Name (ARN) of the load balancer.
	//
	// LoadBalancerArn is a required field
	LoadBalancerArn *string `type:"string" required:"true"`

	// The IDs of the security groups.
	//
	// SecurityGroups is a required field
	SecurityGroups []*string `type:"list" required:"true"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *SetSecurityGroupsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "SetSecurityGroupsInput"}
	if s.LoadBalancerArn == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerArn"))
	}
	if s.SecurityGroups == nil {
		invalidParams.Add(request.NewErrParamRequired("SecurityGroups"))
	}

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

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *SetSecurityGroupsInput) SetLoadBalancerArn(v string) *SetSecurityGroupsInput {
	s.LoadBalancerArn = &v
	return s
}

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

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

	// The IDs of the security groups associated with the load balancer.
	SecurityGroupIds []*string `type:"list"`
}

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

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

// SetSecurityGroupIds sets the SecurityGroupIds field's value.
func (s *SetSecurityGroupsOutput) SetSecurityGroupIds(v []*string) *SetSecurityGroupsOutput {
	s.SecurityGroupIds = v
	return s
}

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

	// The Amazon Resource Name (ARN) of the load balancer.
	//
	// LoadBalancerArn is a required field
	LoadBalancerArn *string `type:"string" required:"true"`

	// The IDs of the public subnets. You must specify subnets from at least two
	// Availability Zones. You can specify only one subnet per Availability Zone.
	// You must specify either subnets or subnet mappings.
	//
	// You cannot specify Elastic IP addresses for your subnets.
	SubnetMappings []*SubnetMapping `type:"list"`

	// The IDs of the public subnets. You must specify subnets from at least two
	// Availability Zones. You can specify only one subnet per Availability Zone.
	// You must specify either subnets or subnet mappings.
	Subnets []*string `type:"list"`
}

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

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

// Validate inspects the fields of the type to determine if they are valid.
func (s *SetSubnetsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "SetSubnetsInput"}
	if s.LoadBalancerArn == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerArn"))
	}

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

// SetLoadBalancerArn sets the LoadBalancerArn field's value.
func (s *SetSubnetsInput) SetLoadBalancerArn(v string) *SetSubnetsInput {
	s.LoadBalancerArn = &v
	return s
}

// SetSubnetMappings sets the SubnetMappings field's value.
func (s *SetSubnetsInput) SetSubnetMappings(v []*SubnetMapping) *SetSubnetsInput {
	s.SubnetMappings = v
	return s
}

// SetSubnets sets the Subnets field's value.
func (s *SetSubnetsInput) SetSubnets(v []*string) *SetSubnetsInput {
	s.Subnets = v
	return s
}

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

	// Information about the subnet and Availability Zone.
	AvailabilityZones []*AvailabilityZone `type:"list"`
}

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

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

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

// Information about a policy used for SSL negotiation.
type SslPolicy struct {
	_ struct{} `type:"structure"`

	// The ciphers.
	Ciphers []*Cipher `type:"list"`

	// The name of the policy.
	Name *string `type:"string"`

	// The protocols.
	SslProtocols []*string `type:"list"`
}

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

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

// SetCiphers sets the Ciphers field's value.
func (s *SslPolicy) SetCiphers(v []*Cipher) *SslPolicy {
	s.Ciphers = v
	return s
}

// SetName sets the Name field's value.
func (s *SslPolicy) SetName(v string) *SslPolicy {
	s.Name = &v
	return s
}

// SetSslProtocols sets the SslProtocols field's value.
func (s *SslPolicy) SetSslProtocols(v []*string) *SslPolicy {
	s.SslProtocols = v
	return s
}

// Information about a subnet mapping.
type SubnetMapping struct {
	_ struct{} `type:"structure"`

	// [Network Load Balancers] The allocation ID of the Elastic IP address.
	AllocationId *string `type:"string"`

	// The ID of the subnet.
	SubnetId *string `type:"string"`
}

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

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

// SetAllocationId sets the AllocationId field's value.
func (s *SubnetMapping) SetAllocationId(v string) *SubnetMapping {
	s.AllocationId = &v
	return s
}

// SetSubnetId sets the SubnetId field's value.
func (s *SubnetMapping) SetSubnetId(v string) *SubnetMapping {
	s.SubnetId = &v
	return s
}

// Information about a tag.
type Tag struct {
	_ struct{} `type:"structure"`

	// The key of the tag.
	//
	// Key is a required field
	Key *string `min:"1" type:"string" required:"true"`

	// The value of the tag.
	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
}

// SetValue sets the Value field's value.
func (s *Tag) SetValue(v string) *Tag {
	s.Value = &v
	return s
}

// The tags associated with a resource.
type TagDescription struct {
	_ struct{} `type:"structure"`

	// The Amazon Resource Name (ARN) of the resource.
	ResourceArn *string `type:"string"`

	// Information about the tags.
	Tags []*Tag `min:"1" type:"list"`
}

// 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()
}

// SetResourceArn sets the ResourceArn field's value.
func (s *TagDescription) SetResourceArn(v string) *TagDescription {
	s.ResourceArn = &v
	return s
}

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

// Information about a target.
type TargetDescription struct {
	_ struct{} `type:"structure"`

	// An Availability Zone or all. This determines whether the target receives
	// traffic from the load balancer nodes in the specified Availability Zone or
	// from all enabled Availability Zones for the load balancer.
	//
	// This parameter is not supported if the target type of the target group is
	// instance.
	//
	// If the target type is ip and the IP address is in a subnet of the VPC for
	// the target group, the Availability Zone is automatically detected and this
	// parameter is optional. If the IP address is outside the VPC, this parameter
	// is required.
	//
	// With an Application Load Balancer, if the target type is ip and the IP address
	// is outside the VPC for the target group, the only supported value is all.
	//
	// If the target type is lambda, this parameter is optional and the only supported
	// value is all.
	AvailabilityZone *string `type:"string"`

	// The ID of the target. If the target type of the target group is instance,
	// specify an instance ID. If the target type is ip, specify an IP address.
	// If the target type is lambda, specify the ARN of the Lambda function.
	//
	// Id is a required field
	Id *string `type:"string" required:"true"`

	// The port on which the target is listening.
	Port *int64 `min:"1" type:"integer"`
}

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

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

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

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

// SetAvailabilityZone sets the AvailabilityZone field's value.
func (s *TargetDescription) SetAvailabilityZone(v string) *TargetDescription {
	s.AvailabilityZone = &v
	return s
}

// SetId sets the Id field's value.
func (s *TargetDescription) SetId(v string) *TargetDescription {
	s.Id = &v
	return s
}

// SetPort sets the Port field's value.
func (s *TargetDescription) SetPort(v int64) *TargetDescription {
	s.Port = &v
	return s
}

// Information about a target group.
type TargetGroup struct {
	_ struct{} `type:"structure"`

	// Indicates whether health checks are enabled.
	HealthCheckEnabled *bool `type:"boolean"`

	// The approximate amount of time, in seconds, between health checks of an individual
	// target.
	HealthCheckIntervalSeconds *int64 `min:"5" type:"integer"`

	// The destination for the health check request.
	HealthCheckPath *string `min:"1" type:"string"`

	// The port to use to connect with the target.
	HealthCheckPort *string `type:"string"`

	// The protocol to use to connect with the target.
	HealthCheckProtocol *string `type:"string" enum:"ProtocolEnum"`

	// The amount of time, in seconds, during which no response means a failed health
	// check.
	HealthCheckTimeoutSeconds *int64 `min:"2" type:"integer"`

	// The number of consecutive health checks successes required before considering
	// an unhealthy target healthy.
	HealthyThresholdCount *int64 `min:"2" type:"integer"`

	// The Amazon Resource Names (ARN) of the load balancers that route traffic
	// to this target group.
	LoadBalancerArns []*string `type:"list"`

	// The HTTP codes to use when checking for a successful response from a target.
	Matcher *Matcher `type:"structure"`

	// The port on which the targets are listening.
	Port *int64 `min:"1" type:"integer"`

	// The protocol to use for routing traffic to the targets.
	Protocol *string `type:"string" enum:"ProtocolEnum"`

	// The Amazon Resource Name (ARN) of the target group.
	TargetGroupArn *string `type:"string"`

	// The name of the target group.
	TargetGroupName *string `type:"string"`

	// The type of target that you must specify when registering targets with this
	// target group. The possible values are instance (targets are specified by
	// instance ID) or ip (targets are specified by IP address).
	TargetType *string `type:"string" enum:"TargetTypeEnum"`

	// The number of consecutive health check failures required before considering
	// the target unhealthy.
	UnhealthyThresholdCount *int64 `min:"2" type:"integer"`

	// The ID of the VPC for the targets.
	VpcId *string `type:"string"`
}

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

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

// SetHealthCheckEnabled sets the HealthCheckEnabled field's value.
func (s *TargetGroup) SetHealthCheckEnabled(v bool) *TargetGroup {
	s.HealthCheckEnabled = &v
	return s
}

// SetHealthCheckIntervalSeconds sets the HealthCheckIntervalSeconds field's value.
func (s *TargetGroup) SetHealthCheckIntervalSeconds(v int64) *TargetGroup {
	s.HealthCheckIntervalSeconds = &v
	return s
}

// SetHealthCheckPath sets the HealthCheckPath field's value.
func (s *TargetGroup) SetHealthCheckPath(v string) *TargetGroup {
	s.HealthCheckPath = &v
	return s
}

// SetHealthCheckPort sets the HealthCheckPort field's value.
func (s *TargetGroup) SetHealthCheckPort(v string) *TargetGroup {
	s.HealthCheckPort = &v
	return s
}

// SetHealthCheckProtocol sets the HealthCheckProtocol field's value.
func (s *TargetGroup) SetHealthCheckProtocol(v string) *TargetGroup {
	s.HealthCheckProtocol = &v
	return s
}

// SetHealthCheckTimeoutSeconds sets the HealthCheckTimeoutSeconds field's value.
func (s *TargetGroup) SetHealthCheckTimeoutSeconds(v int64) *TargetGroup {
	s.HealthCheckTimeoutSeconds = &v
	return s
}

// SetHealthyThresholdCount sets the HealthyThresholdCount field's value.
func (s *TargetGroup) SetHealthyThresholdCount(v int64) *TargetGroup {
	s.HealthyThresholdCount = &v
	return s
}

// SetLoadBalancerArns sets the LoadBalancerArns field's value.
func (s *TargetGroup) SetLoadBalancerArns(v []*string) *TargetGroup {
	s.LoadBalancerArns = v
	return s
}

// SetMatcher sets the Matcher field's value.
func (s *TargetGroup) SetMatcher(v *Matcher) *TargetGroup {
	s.Matcher = v
	return s
}

// SetPort sets the Port field's value.
func (s *TargetGroup) SetPort(v int64) *TargetGroup {
	s.Port = &v
	return s
}

// SetProtocol sets the Protocol field's value.
func (s *TargetGroup) SetProtocol(v string) *TargetGroup {
	s.Protocol = &v
	return s
}

// SetTargetGroupArn sets the TargetGroupArn field's value.
func (s *TargetGroup) SetTargetGroupArn(v string) *TargetGroup {
	s.TargetGroupArn = &v
	return s
}

// SetTargetGroupName sets the TargetGroupName field's value.
func (s *TargetGroup) SetTargetGroupName(v string) *TargetGroup {
	s.TargetGroupName = &v
	return s
}

// SetTargetType sets the TargetType field's value.
func (s *TargetGroup) SetTargetType(v string) *TargetGroup {
	s.TargetType = &v
	return s
}

// SetUnhealthyThresholdCount sets the UnhealthyThresholdCount field's value.
func (s *TargetGroup) SetUnhealthyThresholdCount(v int64) *TargetGroup {
	s.UnhealthyThresholdCount = &v
	return s
}

// SetVpcId sets the VpcId field's value.
func (s *TargetGroup) SetVpcId(v string) *TargetGroup {
	s.VpcId = &v
	return s
}

// Information about a target group attribute.
type TargetGroupAttribute struct {
	_ struct{} `type:"structure"`

	// The name of the attribute.
	//
	// The following attribute is supported by both Application Load Balancers and
	// Network Load Balancers:
	//
	//    * deregistration_delay.timeout_seconds - The amount of time, in seconds,
	//    for Elastic Load Balancing to wait before changing the state of a deregistering
	//    target from draining to unused. The range is 0-3600 seconds. The default
	//    value is 300 seconds. If the target is a Lambda function, this attribute
	//    is not supported.
	//
	// The following attributes are supported by Application Load Balancers if the
	// target is not a Lambda function:
	//
	//    * slow_start.duration_seconds - The time period, in seconds, during which
	//    a newly registered target receives a linearly increasing share of the
	//    traffic to the target group. After this time period ends, the target receives
	//    its full share of traffic. The range is 30-900 seconds (15 minutes). Slow
	//    start mode is disabled by default.
	//
	//    * stickiness.enabled - Indicates whether sticky sessions are enabled.
	//    The value is true or false. The default is false.
	//
	//    * stickiness.type - The type of sticky sessions. The possible value is
	//    lb_cookie.
	//
	//    * stickiness.lb_cookie.duration_seconds - The time period, in seconds,
	//    during which requests from a client should be routed to the same target.
	//    After this time period expires, the load balancer-generated cookie is
	//    considered stale. The range is 1 second to 1 week (604800 seconds). The
	//    default value is 1 day (86400 seconds).
	//
	// The following attribute is supported only if the target is a Lambda function.
	//
	//    * lambda.multi_value_headers.enabled - Indicates whether the request and
	//    response headers exchanged between the load balancer and the Lambda function
	//    include arrays of values or strings. The value is true or false. The default
	//    is false. If the value is false and the request contains a duplicate header
	//    field name or query parameter key, the load balancer uses the last value
	//    sent by the client.
	//
	// The following attribute is supported only by Network Load Balancers:
	//
	//    * proxy_protocol_v2.enabled - Indicates whether Proxy Protocol version
	//    2 is enabled. The value is true or false. The default is false.
	Key *string `type:"string"`

	// The value of the attribute.
	Value *string `type:"string"`
}

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

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

// SetKey sets the Key field's value.
func (s *TargetGroupAttribute) SetKey(v string) *TargetGroupAttribute {
	s.Key = &v
	return s
}

// SetValue sets the Value field's value.
func (s *TargetGroupAttribute) SetValue(v string) *TargetGroupAttribute {
	s.Value = &v
	return s
}

// Information about the current health of a target.
type TargetHealth struct {
	_ struct{} `type:"structure"`

	// A description of the target health that provides additional details. If the
	// state is healthy, a description is not provided.
	Description *string `type:"string"`

	// The reason code.
	//
	// If the target state is healthy, a reason code is not provided.
	//
	// If the target state is initial, the reason code can be one of the following
	// values:
	//
	//    * Elb.RegistrationInProgress - The target is in the process of being registered
	//    with the load balancer.
	//
	//    * Elb.InitialHealthChecking - The load balancer is still sending the target
	//    the minimum number of health checks required to determine its health status.
	//
	// If the target state is unhealthy, the reason code can be one of the following
	// values:
	//
	//    * Target.ResponseCodeMismatch - The health checks did not return an expected
	//    HTTP code.
	//
	//    * Target.Timeout - The health check requests timed out.
	//
	//    * Target.FailedHealthChecks - The health checks failed because the connection
	//    to the target timed out, the target response was malformed, or the target
	//    failed the health check for an unknown reason.
	//
	//    * Elb.InternalError - The health checks failed due to an internal error.
	//
	// If the target state is unused, the reason code can be one of the following
	// values:
	//
	//    * Target.NotRegistered - The target is not registered with the target
	//    group.
	//
	//    * Target.NotInUse - The target group is not used by any load balancer
	//    or the target is in an Availability Zone that is not enabled for its load
	//    balancer.
	//
	//    * Target.IpUnusable - The target IP address is reserved for use by a load
	//    balancer.
	//
	//    * Target.InvalidState - The target is in the stopped or terminated state.
	//
	// If the target state is draining, the reason code can be the following value:
	//
	//    * Target.DeregistrationInProgress - The target is in the process of being
	//    deregistered and the deregistration delay period has not expired.
	//
	// If the target state is unavailable, the reason code can be the following
	// value:
	//
	//    * Target.HealthCheckDisabled - Health checks are disabled for the target
	//    group.
	Reason *string `type:"string" enum:"TargetHealthReasonEnum"`

	// The state of the target.
	State *string `type:"string" enum:"TargetHealthStateEnum"`
}

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

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

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

// SetReason sets the Reason field's value.
func (s *TargetHealth) SetReason(v string) *TargetHealth {
	s.Reason = &v
	return s
}

// SetState sets the State field's value.
func (s *TargetHealth) SetState(v string) *TargetHealth {
	s.State = &v
	return s
}

// Information about the health of a target.
type TargetHealthDescription struct {
	_ struct{} `type:"structure"`

	// The port to use to connect with the target.
	HealthCheckPort *string `type:"string"`

	// The description of the target.
	Target *TargetDescription `type:"structure"`

	// The health information for the target.
	TargetHealth *TargetHealth `type:"structure"`
}

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

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

// SetHealthCheckPort sets the HealthCheckPort field's value.
func (s *TargetHealthDescription) SetHealthCheckPort(v string) *TargetHealthDescription {
	s.HealthCheckPort = &v
	return s
}

// SetTarget sets the Target field's value.
func (s *TargetHealthDescription) SetTarget(v *TargetDescription) *TargetHealthDescription {
	s.Target = v
	return s
}

// SetTargetHealth sets the TargetHealth field's value.
func (s *TargetHealthDescription) SetTargetHealth(v *TargetHealth) *TargetHealthDescription {
	s.TargetHealth = v
	return s
}

const (
	// ActionTypeEnumForward is a ActionTypeEnum enum value
	ActionTypeEnumForward = "forward"

	// ActionTypeEnumAuthenticateOidc is a ActionTypeEnum enum value
	ActionTypeEnumAuthenticateOidc = "authenticate-oidc"

	// ActionTypeEnumAuthenticateCognito is a ActionTypeEnum enum value
	ActionTypeEnumAuthenticateCognito = "authenticate-cognito"

	// ActionTypeEnumRedirect is a ActionTypeEnum enum value
	ActionTypeEnumRedirect = "redirect"

	// ActionTypeEnumFixedResponse is a ActionTypeEnum enum value
	ActionTypeEnumFixedResponse = "fixed-response"
)

const (
	// AuthenticateCognitoActionConditionalBehaviorEnumDeny is a AuthenticateCognitoActionConditionalBehaviorEnum enum value
	AuthenticateCognitoActionConditionalBehaviorEnumDeny = "deny"

	// AuthenticateCognitoActionConditionalBehaviorEnumAllow is a AuthenticateCognitoActionConditionalBehaviorEnum enum value
	AuthenticateCognitoActionConditionalBehaviorEnumAllow = "allow"

	// AuthenticateCognitoActionConditionalBehaviorEnumAuthenticate is a AuthenticateCognitoActionConditionalBehaviorEnum enum value
	AuthenticateCognitoActionConditionalBehaviorEnumAuthenticate = "authenticate"
)

const (
	// AuthenticateOidcActionConditionalBehaviorEnumDeny is a AuthenticateOidcActionConditionalBehaviorEnum enum value
	AuthenticateOidcActionConditionalBehaviorEnumDeny = "deny"

	// AuthenticateOidcActionConditionalBehaviorEnumAllow is a AuthenticateOidcActionConditionalBehaviorEnum enum value
	AuthenticateOidcActionConditionalBehaviorEnumAllow = "allow"

	// AuthenticateOidcActionConditionalBehaviorEnumAuthenticate is a AuthenticateOidcActionConditionalBehaviorEnum enum value
	AuthenticateOidcActionConditionalBehaviorEnumAuthenticate = "authenticate"
)

const (
	// IpAddressTypeIpv4 is a IpAddressType enum value
	IpAddressTypeIpv4 = "ipv4"

	// IpAddressTypeDualstack is a IpAddressType enum value
	IpAddressTypeDualstack = "dualstack"
)

const (
	// LoadBalancerSchemeEnumInternetFacing is a LoadBalancerSchemeEnum enum value
	LoadBalancerSchemeEnumInternetFacing = "internet-facing"

	// LoadBalancerSchemeEnumInternal is a LoadBalancerSchemeEnum enum value
	LoadBalancerSchemeEnumInternal = "internal"
)

const (
	// LoadBalancerStateEnumActive is a LoadBalancerStateEnum enum value
	LoadBalancerStateEnumActive = "active"

	// LoadBalancerStateEnumProvisioning is a LoadBalancerStateEnum enum value
	LoadBalancerStateEnumProvisioning = "provisioning"

	// LoadBalancerStateEnumActiveImpaired is a LoadBalancerStateEnum enum value
	LoadBalancerStateEnumActiveImpaired = "active_impaired"

	// LoadBalancerStateEnumFailed is a LoadBalancerStateEnum enum value
	LoadBalancerStateEnumFailed = "failed"
)

const (
	// LoadBalancerTypeEnumApplication is a LoadBalancerTypeEnum enum value
	LoadBalancerTypeEnumApplication = "application"

	// LoadBalancerTypeEnumNetwork is a LoadBalancerTypeEnum enum value
	LoadBalancerTypeEnumNetwork = "network"
)

const (
	// ProtocolEnumHttp is a ProtocolEnum enum value
	ProtocolEnumHttp = "HTTP"

	// ProtocolEnumHttps is a ProtocolEnum enum value
	ProtocolEnumHttps = "HTTPS"

	// ProtocolEnumTcp is a ProtocolEnum enum value
	ProtocolEnumTcp = "TCP"

	// ProtocolEnumTls is a ProtocolEnum enum value
	ProtocolEnumTls = "TLS"
)

const (
	// RedirectActionStatusCodeEnumHttp301 is a RedirectActionStatusCodeEnum enum value
	RedirectActionStatusCodeEnumHttp301 = "HTTP_301"

	// RedirectActionStatusCodeEnumHttp302 is a RedirectActionStatusCodeEnum enum value
	RedirectActionStatusCodeEnumHttp302 = "HTTP_302"
)

const (
	// TargetHealthReasonEnumElbRegistrationInProgress is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumElbRegistrationInProgress = "Elb.RegistrationInProgress"

	// TargetHealthReasonEnumElbInitialHealthChecking is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumElbInitialHealthChecking = "Elb.InitialHealthChecking"

	// TargetHealthReasonEnumTargetResponseCodeMismatch is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumTargetResponseCodeMismatch = "Target.ResponseCodeMismatch"

	// TargetHealthReasonEnumTargetTimeout is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumTargetTimeout = "Target.Timeout"

	// TargetHealthReasonEnumTargetFailedHealthChecks is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumTargetFailedHealthChecks = "Target.FailedHealthChecks"

	// TargetHealthReasonEnumTargetNotRegistered is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumTargetNotRegistered = "Target.NotRegistered"

	// TargetHealthReasonEnumTargetNotInUse is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumTargetNotInUse = "Target.NotInUse"

	// TargetHealthReasonEnumTargetDeregistrationInProgress is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumTargetDeregistrationInProgress = "Target.DeregistrationInProgress"

	// TargetHealthReasonEnumTargetInvalidState is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumTargetInvalidState = "Target.InvalidState"

	// TargetHealthReasonEnumTargetIpUnusable is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumTargetIpUnusable = "Target.IpUnusable"

	// TargetHealthReasonEnumTargetHealthCheckDisabled is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumTargetHealthCheckDisabled = "Target.HealthCheckDisabled"

	// TargetHealthReasonEnumElbInternalError is a TargetHealthReasonEnum enum value
	TargetHealthReasonEnumElbInternalError = "Elb.InternalError"
)

const (
	// TargetHealthStateEnumInitial is a TargetHealthStateEnum enum value
	TargetHealthStateEnumInitial = "initial"

	// TargetHealthStateEnumHealthy is a TargetHealthStateEnum enum value
	TargetHealthStateEnumHealthy = "healthy"

	// TargetHealthStateEnumUnhealthy is a TargetHealthStateEnum enum value
	TargetHealthStateEnumUnhealthy = "unhealthy"

	// TargetHealthStateEnumUnused is a TargetHealthStateEnum enum value
	TargetHealthStateEnumUnused = "unused"

	// TargetHealthStateEnumDraining is a TargetHealthStateEnum enum value
	TargetHealthStateEnumDraining = "draining"

	// TargetHealthStateEnumUnavailable is a TargetHealthStateEnum enum value
	TargetHealthStateEnumUnavailable = "unavailable"
)

const (
	// TargetTypeEnumInstance is a TargetTypeEnum enum value
	TargetTypeEnumInstance = "instance"

	// TargetTypeEnumIp is a TargetTypeEnum enum value
	TargetTypeEnumIp = "ip"

	// TargetTypeEnumLambda is a TargetTypeEnum enum value
	TargetTypeEnumLambda = "lambda"
)
