Allow creation of subnets from secondary VPC IPv4 CIDR blocks (#3391)
* allow subnets to be created from secondary vpc cidr block * add additional test case for invalid cidr
This commit is contained in:
parent
28c1690fc2
commit
2fe3aee359
@ -3465,19 +3465,30 @@ class SubnetBackend(object):
|
||||
vpc = self.get_vpc(
|
||||
vpc_id
|
||||
) # Validate VPC exists and the supplied CIDR block is a subnet of the VPC's
|
||||
vpc_cidr_block = ipaddress.IPv4Network(
|
||||
six.text_type(vpc.cidr_block), strict=False
|
||||
)
|
||||
vpc_cidr_blocks = [
|
||||
ipaddress.IPv4Network(
|
||||
six.text_type(cidr_block_association["cidr_block"]), strict=False
|
||||
)
|
||||
for cidr_block_association in vpc.get_cidr_block_association_set()
|
||||
]
|
||||
try:
|
||||
subnet_cidr_block = ipaddress.IPv4Network(
|
||||
six.text_type(cidr_block), strict=False
|
||||
)
|
||||
except ValueError:
|
||||
raise InvalidCIDRBlockParameterError(cidr_block)
|
||||
if not (
|
||||
vpc_cidr_block.network_address <= subnet_cidr_block.network_address
|
||||
and vpc_cidr_block.broadcast_address >= subnet_cidr_block.broadcast_address
|
||||
):
|
||||
|
||||
subnet_in_vpc_cidr_range = False
|
||||
for vpc_cidr_block in vpc_cidr_blocks:
|
||||
if (
|
||||
vpc_cidr_block.network_address <= subnet_cidr_block.network_address
|
||||
and vpc_cidr_block.broadcast_address
|
||||
>= subnet_cidr_block.broadcast_address
|
||||
):
|
||||
subnet_in_vpc_cidr_range = True
|
||||
break
|
||||
|
||||
if not subnet_in_vpc_cidr_range:
|
||||
raise InvalidSubnetRangeError(cidr_block)
|
||||
|
||||
for subnet in self.get_all_subnets(filters={"vpc-id": vpc_id}):
|
||||
|
@ -417,6 +417,24 @@ def test_create_subnet_with_invalid_cidr_range():
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnet_with_invalid_cidr_range_multiple_vpc_cidr_blocks():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
ec2.meta.client.associate_vpc_cidr_block(CidrBlock="10.1.0.0/16", VpcId=vpc.id)
|
||||
vpc.reload()
|
||||
vpc.is_default.shouldnt.be.ok
|
||||
|
||||
subnet_cidr_block = "10.2.0.0/20"
|
||||
with assert_raises(ClientError) as ex:
|
||||
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
|
||||
str(ex.exception).should.equal(
|
||||
"An error occurred (InvalidSubnet.Range) when calling the CreateSubnet "
|
||||
"operation: The CIDR '{}' is invalid.".format(subnet_cidr_block)
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnet_with_invalid_cidr_block_parameter():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
@ -436,6 +454,46 @@ def test_create_subnet_with_invalid_cidr_block_parameter():
|
||||
)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnets_with_multiple_vpc_cidr_blocks():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
client = boto3.client("ec2", region_name="us-west-1")
|
||||
|
||||
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
|
||||
ec2.meta.client.associate_vpc_cidr_block(CidrBlock="10.1.0.0/16", VpcId=vpc.id)
|
||||
vpc.reload()
|
||||
vpc.is_default.shouldnt.be.ok
|
||||
|
||||
subnet_cidr_block_primary = "10.0.0.0/24"
|
||||
subnet_primary = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock=subnet_cidr_block_primary
|
||||
)
|
||||
|
||||
subnet_cidr_block_secondary = "10.1.0.0/24"
|
||||
subnet_secondary = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock=subnet_cidr_block_secondary
|
||||
)
|
||||
|
||||
subnets = client.describe_subnets(
|
||||
SubnetIds=[subnet_primary.id, subnet_secondary.id]
|
||||
)["Subnets"]
|
||||
subnets.should.have.length_of(2)
|
||||
|
||||
for subnet in subnets:
|
||||
subnet.should.have.key("AvailabilityZone")
|
||||
subnet.should.have.key("AvailabilityZoneId")
|
||||
subnet.should.have.key("AvailableIpAddressCount")
|
||||
subnet.should.have.key("CidrBlock")
|
||||
subnet.should.have.key("State")
|
||||
subnet.should.have.key("SubnetId")
|
||||
subnet.should.have.key("VpcId")
|
||||
subnet.shouldnt.have.key("Tags")
|
||||
subnet.should.have.key("DefaultForAz").which.should.equal(False)
|
||||
subnet.should.have.key("MapPublicIpOnLaunch").which.should.equal(False)
|
||||
subnet.should.have.key("OwnerId")
|
||||
subnet.should.have.key("AssignIpv6AddressOnCreation").which.should.equal(False)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnets_with_overlapping_cidr_blocks():
|
||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||
|
Loading…
Reference in New Issue
Block a user