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

package ec2

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

// Creates a subnet in the specified VPC. For an IPv4 only subnet, specify an IPv4
// CIDR block. If the VPC has an IPv6 CIDR block, you can create an IPv6 only
// subnet or a dual stack subnet instead. For an IPv6 only subnet, specify an IPv6
// CIDR block. For a dual stack subnet, specify both an IPv4 CIDR block and an IPv6
// CIDR block.
//
// A subnet CIDR block must not overlap the CIDR block of an existing subnet in
// the VPC. After you create a subnet, you can't change its CIDR block.
//
// The allowed size for an IPv4 subnet is between a /28 netmask (16 IP addresses)
// and a /16 netmask (65,536 IP addresses). Amazon Web Services reserves both the
// first four and the last IPv4 address in each subnet's CIDR block. They're not
// available for your use.
//
// If you've associated an IPv6 CIDR block with your VPC, you can associate an
// IPv6 CIDR block with a subnet when you create it.
//
// If you add more than one subnet to a VPC, they're set up in a star topology
// with a logical router in the middle.
//
// When you stop an instance in a subnet, it retains its private IPv4 address.
// It's therefore possible to have a subnet with no running instances (they're all
// stopped), but no remaining IP addresses available.
//
// For more information, see [Subnets] in the Amazon VPC User Guide.
//
// [Subnets]: https://docs.aws.amazon.com/vpc/latest/userguide/configure-subnets.html
func (c *Client) CreateSubnet(ctx context.Context, params *CreateSubnetInput, optFns ...func(*Options)) (*CreateSubnetOutput, error) {
	if params == nil {
		params = &CreateSubnetInput{}
	}

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

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

type CreateSubnetInput struct {

	// The ID of the VPC.
	//
	// This member is required.
	VpcId *string

	// The Availability Zone or Local Zone for the subnet.
	//
	// Default: Amazon Web Services selects one for you. If you create more than one
	// subnet in your VPC, we do not necessarily select a different zone for each
	// subnet.
	//
	// To create a subnet in a Local Zone, set this value to the Local Zone ID, for
	// example us-west-2-lax-1a . For information about the Regions that support Local
	// Zones, see [Available Local Zones].
	//
	// To create a subnet in an Outpost, set this value to the Availability Zone for
	// the Outpost and specify the Outpost ARN.
	//
	// [Available Local Zones]: https://docs.aws.amazon.com/local-zones/latest/ug/available-local-zones.html
	AvailabilityZone *string

	// The AZ ID or the Local Zone ID of the subnet.
	AvailabilityZoneId *string

	// The IPv4 network range for the subnet, in CIDR notation. For example,
	// 10.0.0.0/24 . We modify the specified CIDR block to its canonical form; for
	// example, if you specify 100.68.0.18/18 , we modify it to 100.68.0.0/18 .
	//
	// This parameter is not supported for an IPv6 only subnet.
	CidrBlock *string

	// Checks whether you have the required permissions for the action, without
	// actually making the request, and provides an error response. If you have the
	// required permissions, the error response is DryRunOperation . Otherwise, it is
	// UnauthorizedOperation .
	DryRun *bool

	// An IPv4 IPAM pool ID for the subnet.
	Ipv4IpamPoolId *string

	// An IPv4 netmask length for the subnet.
	Ipv4NetmaskLength *int32

	// The IPv6 network range for the subnet, in CIDR notation. This parameter is
	// required for an IPv6 only subnet.
	Ipv6CidrBlock *string

	// An IPv6 IPAM pool ID for the subnet.
	Ipv6IpamPoolId *string

	// Indicates whether to create an IPv6 only subnet.
	Ipv6Native *bool

	// An IPv6 netmask length for the subnet.
	Ipv6NetmaskLength *int32

	// The Amazon Resource Name (ARN) of the Outpost. If you specify an Outpost ARN,
	// you must also specify the Availability Zone of the Outpost subnet.
	OutpostArn *string

	// The tags to assign to the subnet.
	TagSpecifications []types.TagSpecification

	noSmithyDocumentSerde
}

type CreateSubnetOutput struct {

	// Information about the subnet.
	Subnet *types.Subnet

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

	noSmithyDocumentSerde
}

func (c *Client) addOperationCreateSubnetMiddlewares(stack *middleware.Stack, options Options) (err error) {
	if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
		return err
	}
	err = stack.Serialize.Add(&awsEc2query_serializeOpCreateSubnet{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsEc2query_deserializeOpCreateSubnet{}, middleware.After)
	if err != nil {
		return err
	}
	if err := addProtocolFinalizerMiddlewares(stack, options, "CreateSubnet"); err != nil {
		return fmt.Errorf("add protocol finalizers: %v", err)
	}

	if err = addlegacyEndpointContextSetter(stack, options); err != nil {
		return err
	}
	if err = addSetLoggerMiddleware(stack, options); err != nil {
		return err
	}
	if err = addClientRequestID(stack); err != nil {
		return err
	}
	if err = addComputeContentLength(stack); err != nil {
		return err
	}
	if err = addResolveEndpointMiddleware(stack, options); err != nil {
		return err
	}
	if err = addComputePayloadSHA256(stack); err != nil {
		return err
	}
	if err = addRetry(stack, options); err != nil {
		return err
	}
	if err = addRawResponseToMetadata(stack); err != nil {
		return err
	}
	if err = addRecordResponseTiming(stack); err != nil {
		return err
	}
	if err = addSpanRetryLoop(stack, options); err != nil {
		return err
	}
	if err = addClientUserAgent(stack, options); err != nil {
		return err
	}
	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil {
		return err
	}
	if err = addTimeOffsetBuild(stack, c); err != nil {
		return err
	}
	if err = addUserAgentRetryMode(stack, options); err != nil {
		return err
	}
	if err = addOpCreateSubnetValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateSubnet(options.Region), middleware.Before); err != nil {
		return err
	}
	if err = addRecursionDetection(stack); err != nil {
		return err
	}
	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
		return err
	}
	if err = addResponseErrorMiddleware(stack); err != nil {
		return err
	}
	if err = addRequestResponseLogging(stack, options); err != nil {
		return err
	}
	if err = addDisableHTTPSMiddleware(stack, options); err != nil {
		return err
	}
	if err = addSpanInitializeStart(stack); err != nil {
		return err
	}
	if err = addSpanInitializeEnd(stack); err != nil {
		return err
	}
	if err = addSpanBuildRequestStart(stack); err != nil {
		return err
	}
	if err = addSpanBuildRequestEnd(stack); err != nil {
		return err
	}
	return nil
}

func newServiceMetadataMiddleware_opCreateSubnet(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		OperationName: "CreateSubnet",
	}
}
