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 = self.get_vpc(
|
||||||
vpc_id
|
vpc_id
|
||||||
) # Validate VPC exists and the supplied CIDR block is a subnet of the VPC's
|
) # Validate VPC exists and the supplied CIDR block is a subnet of the VPC's
|
||||||
vpc_cidr_block = ipaddress.IPv4Network(
|
vpc_cidr_blocks = [
|
||||||
six.text_type(vpc.cidr_block), strict=False
|
ipaddress.IPv4Network(
|
||||||
)
|
six.text_type(cidr_block_association["cidr_block"]), strict=False
|
||||||
|
)
|
||||||
|
for cidr_block_association in vpc.get_cidr_block_association_set()
|
||||||
|
]
|
||||||
try:
|
try:
|
||||||
subnet_cidr_block = ipaddress.IPv4Network(
|
subnet_cidr_block = ipaddress.IPv4Network(
|
||||||
six.text_type(cidr_block), strict=False
|
six.text_type(cidr_block), strict=False
|
||||||
)
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise InvalidCIDRBlockParameterError(cidr_block)
|
raise InvalidCIDRBlockParameterError(cidr_block)
|
||||||
if not (
|
|
||||||
vpc_cidr_block.network_address <= subnet_cidr_block.network_address
|
subnet_in_vpc_cidr_range = False
|
||||||
and vpc_cidr_block.broadcast_address >= subnet_cidr_block.broadcast_address
|
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)
|
raise InvalidSubnetRangeError(cidr_block)
|
||||||
|
|
||||||
for subnet in self.get_all_subnets(filters={"vpc-id": vpc_id}):
|
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
|
@mock_ec2
|
||||||
def test_create_subnet_with_invalid_cidr_block_parameter():
|
def test_create_subnet_with_invalid_cidr_block_parameter():
|
||||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
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
|
@mock_ec2
|
||||||
def test_create_subnets_with_overlapping_cidr_blocks():
|
def test_create_subnets_with_overlapping_cidr_blocks():
|
||||||
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
ec2 = boto3.resource("ec2", region_name="us-west-1")
|
||||||
|
Loading…
Reference in New Issue
Block a user