Add support for default VPCs and subnets.

The first VPC created will be elected as default.
All subnets of the default VPC are considered default for their availability zone.
This commit is contained in:
Marco Rucci 2015-12-06 20:58:54 +01:00
parent be3291b758
commit 284641e8cf
4 changed files with 17 additions and 5 deletions

View File

@ -1543,12 +1543,13 @@ class EBSBackend(object):
class VPC(TaggedEC2Resource): class VPC(TaggedEC2Resource):
def __init__(self, ec2_backend, vpc_id, cidr_block): def __init__(self, ec2_backend, vpc_id, cidr_block, is_default):
self.ec2_backend = ec2_backend self.ec2_backend = ec2_backend
self.id = vpc_id self.id = vpc_id
self.cidr_block = cidr_block self.cidr_block = cidr_block
self.dhcp_options = None self.dhcp_options = None
self.state = 'available' self.state = 'available'
self.is_default = is_default
@classmethod @classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name): def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
@ -1590,7 +1591,7 @@ class VPCBackend(object):
def create_vpc(self, cidr_block): def create_vpc(self, cidr_block):
vpc_id = random_vpc_id() vpc_id = random_vpc_id()
vpc = VPC(self, vpc_id, cidr_block) vpc = VPC(self, vpc_id, cidr_block, len(self.vpcs) == 0)
self.vpcs[vpc_id] = vpc self.vpcs[vpc_id] = vpc
# AWS creates a default main route table and security group. # AWS creates a default main route table and security group.
@ -1734,12 +1735,13 @@ class VPCPeeringConnectionBackend(object):
class Subnet(TaggedEC2Resource): class Subnet(TaggedEC2Resource):
def __init__(self, ec2_backend, subnet_id, vpc_id, cidr_block, availability_zone): def __init__(self, ec2_backend, subnet_id, vpc_id, cidr_block, availability_zone, defaultForAz):
self.ec2_backend = ec2_backend self.ec2_backend = ec2_backend
self.id = subnet_id self.id = subnet_id
self.vpc_id = vpc_id self.vpc_id = vpc_id
self.cidr_block = cidr_block self.cidr_block = cidr_block
self._availability_zone = availability_zone self._availability_zone = availability_zone
self.defaultForAz = defaultForAz
@classmethod @classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name): def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
@ -1799,6 +1801,8 @@ class Subnet(TaggedEC2Resource):
return self.id return self.id
elif filter_name == 'availabilityZone': elif filter_name == 'availabilityZone':
return self.availability_zone return self.availability_zone
elif filter_name == 'defaultForAz':
return self.defaultForAz
filter_value = super(Subnet, self).get_filter_value(filter_name) filter_value = super(Subnet, self).get_filter_value(filter_name)
@ -1827,8 +1831,9 @@ class SubnetBackend(object):
def create_subnet(self, vpc_id, cidr_block, availability_zone=None): def create_subnet(self, vpc_id, cidr_block, availability_zone=None):
subnet_id = random_subnet_id() subnet_id = random_subnet_id()
subnet = Subnet(self, subnet_id, vpc_id, cidr_block, availability_zone) vpc = self.get_vpc(vpc_id) # Validate VPC exists
self.get_vpc(vpc_id) # Validate VPC exists defaultForAz = "true" if vpc.is_default else "false"
subnet = Subnet(self, subnet_id, vpc_id, cidr_block, availability_zone, defaultForAz)
# AWS associates a new subnet with the default Network ACL # AWS associates a new subnet with the default Network ACL
self.associate_default_network_acl_with_subnet(subnet_id) self.associate_default_network_acl_with_subnet(subnet_id)

View File

@ -73,6 +73,7 @@ DESCRIBE_SUBNETS_RESPONSE = """
<cidrBlock>{{ subnet.cidr_block }}</cidrBlock> <cidrBlock>{{ subnet.cidr_block }}</cidrBlock>
<availableIpAddressCount>251</availableIpAddressCount> <availableIpAddressCount>251</availableIpAddressCount>
<availabilityZone>{{ subnet.availability_zone }}</availabilityZone> <availabilityZone>{{ subnet.availability_zone }}</availabilityZone>
<defaultForAz>{{ subnet.defaultForAz }}</defaultForAz>
<tagSet> <tagSet>
{% for tag in subnet.get_tags() %} {% for tag in subnet.get_tags() %}
<item> <item>

View File

@ -57,6 +57,7 @@ DESCRIBE_VPCS_RESPONSE = """
<cidrBlock>{{ vpc.cidr_block }}</cidrBlock> <cidrBlock>{{ vpc.cidr_block }}</cidrBlock>
<dhcpOptionsId>dopt-7a8b9c2d</dhcpOptionsId> <dhcpOptionsId>dopt-7a8b9c2d</dhcpOptionsId>
<instanceTenancy>default</instanceTenancy> <instanceTenancy>default</instanceTenancy>
<isDefault>{{ vpc.is_default }}</isDefault>
<tagSet> <tagSet>
{% for tag in vpc.get_tags() %} {% for tag in vpc.get_tags() %}
<item> <item>

View File

@ -115,6 +115,11 @@ def test_get_subnets_filtering():
subnets_by_az.should.have.length_of(1) subnets_by_az.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_az]).should.equal(set([subnetB1.id])) set([subnet.id for subnet in subnets_by_az]).should.equal(set([subnetB1.id]))
# Filter by defaultForAz
subnets_by_az = conn.get_all_subnets(filters={'defaultForAz': "true"})
subnets_by_az.should.have.length_of(1)
set([subnet.id for subnet in subnets_by_az]).should.equal(set([subnetA.id]))
# Unsupported filter # Unsupported filter
conn.get_all_subnets.when.called_with(filters={'not-implemented-filter': 'foobar'}).should.throw(NotImplementedError) conn.get_all_subnets.when.called_with(filters={'not-implemented-filter': 'foobar'}).should.throw(NotImplementedError)