Updates to create_subnet and describe_subnets responses (#2053)
* Removed Tags field from create_subnet response. * Added DefaultForAz to create_subnet response. * Added MapPublicIpOnLaunch to create_subnet response. * Added OwnerId to create_subnet response. * Added AssignIpv6AddressOnCreation field for create_subnet and describe_subnet and implemented setting it in modify_subnet_attribute. * Added SubnetArn to create_subnet response. * Added AvailabilityZoneId to create_subnet and describe_subnet responses, and error for invalid availability zone. * Added Ipv6CidrBlockAssociationSet to create_subnet response. * Added missing fields to describe_subnets response. * Added myself to list of contributors and marked describe_subnet as implemented. * Fixed linting errors. * Fixed blank line containing a tab. * Fixed accidentally deleted ). * Fixed broken tests.
This commit is contained in:
parent
2386d47fe3
commit
8f53b16b9a
@ -54,5 +54,6 @@ Moto is written by Steve Pulec with contributions from:
|
||||
* [William Richard](https://github.com/william-richard)
|
||||
* [Alex Casalboni](https://github.com/alexcasalboni)
|
||||
* [Jon Beilke](https://github.com/jrbeilke)
|
||||
* [Bendeguz Acs](https://github.com/acsbendi)
|
||||
* [Craig Anderson](https://github.com/craiga)
|
||||
* [Robert Lewis](https://github.com/ralewis85)
|
||||
|
@ -1473,7 +1473,7 @@
|
||||
- [X] describe_spot_instance_requests
|
||||
- [ ] describe_spot_price_history
|
||||
- [ ] describe_stale_security_groups
|
||||
- [ ] describe_subnets
|
||||
- [X] describe_subnets
|
||||
- [X] describe_tags
|
||||
- [ ] describe_volume_attribute
|
||||
- [ ] describe_volume_status
|
||||
|
@ -430,6 +430,16 @@ class OperationNotPermitted(EC2ClientError):
|
||||
)
|
||||
|
||||
|
||||
class InvalidAvailabilityZoneError(EC2ClientError):
|
||||
|
||||
def __init__(self, availability_zone_value, valid_availability_zones):
|
||||
super(InvalidAvailabilityZoneError, self).__init__(
|
||||
"InvalidParameterValue",
|
||||
"Value ({0}) for parameter availabilityZone is invalid. "
|
||||
"Subnets can currently only be created in the following availability zones: {1}.".format(availability_zone_value, valid_availability_zones)
|
||||
)
|
||||
|
||||
|
||||
class NetworkAclEntryAlreadyExistsError(EC2ClientError):
|
||||
|
||||
def __init__(self, rule_number):
|
||||
|
@ -36,6 +36,7 @@ from .exceptions import (
|
||||
InvalidAMIIdError,
|
||||
InvalidAMIAttributeItemValueError,
|
||||
InvalidAssociationIdError,
|
||||
InvalidAvailabilityZoneError,
|
||||
InvalidCIDRBlockParameterError,
|
||||
InvalidCIDRSubnetError,
|
||||
InvalidCustomerGatewayIdError,
|
||||
@ -1288,17 +1289,107 @@ class Region(object):
|
||||
|
||||
|
||||
class Zone(object):
|
||||
def __init__(self, name, region_name):
|
||||
def __init__(self, name, region_name, zone_id):
|
||||
self.name = name
|
||||
self.region_name = region_name
|
||||
self.zone_id = zone_id
|
||||
|
||||
|
||||
class RegionsAndZonesBackend(object):
|
||||
regions = [Region(ri.name, ri.endpoint) for ri in boto.ec2.regions()]
|
||||
|
||||
zones = dict(
|
||||
(region, [Zone(region + c, region) for c in 'abc'])
|
||||
for region in [r.name for r in regions])
|
||||
zones = {
|
||||
'ap-south-1': [
|
||||
Zone(region_name="ap-south-1", name="ap-south-1a", zone_id="aps1-az1"),
|
||||
Zone(region_name="ap-south-1", name="ap-south-1b", zone_id="aps1-az3")
|
||||
],
|
||||
'eu-west-3': [
|
||||
Zone(region_name="eu-west-3", name="eu-west-3a", zone_id="euw3-az1"),
|
||||
Zone(region_name="eu-west-3", name="eu-west-3b", zone_id="euw3-az2"),
|
||||
Zone(region_name="eu-west-3", name="eu-west-3c", zone_id="euw3-az3")
|
||||
],
|
||||
'eu-north-1': [
|
||||
Zone(region_name="eu-north-1", name="eu-north-1a", zone_id="eun1-az1"),
|
||||
Zone(region_name="eu-north-1", name="eu-north-1b", zone_id="eun1-az2"),
|
||||
Zone(region_name="eu-north-1", name="eu-north-1c", zone_id="eun1-az3")
|
||||
],
|
||||
'eu-west-2': [
|
||||
Zone(region_name="eu-west-2", name="eu-west-2a", zone_id="euw2-az2"),
|
||||
Zone(region_name="eu-west-2", name="eu-west-2b", zone_id="euw2-az3"),
|
||||
Zone(region_name="eu-west-2", name="eu-west-2c", zone_id="euw2-az1")
|
||||
],
|
||||
'eu-west-1': [
|
||||
Zone(region_name="eu-west-1", name="eu-west-1a", zone_id="euw1-az3"),
|
||||
Zone(region_name="eu-west-1", name="eu-west-1b", zone_id="euw1-az1"),
|
||||
Zone(region_name="eu-west-1", name="eu-west-1c", zone_id="euw1-az2")
|
||||
],
|
||||
'ap-northeast-3': [
|
||||
Zone(region_name="ap-northeast-3", name="ap-northeast-2a", zone_id="apne3-az1")
|
||||
],
|
||||
'ap-northeast-2': [
|
||||
Zone(region_name="ap-northeast-2", name="ap-northeast-2a", zone_id="apne2-az1"),
|
||||
Zone(region_name="ap-northeast-2", name="ap-northeast-2c", zone_id="apne2-az3")
|
||||
],
|
||||
'ap-northeast-1': [
|
||||
Zone(region_name="ap-northeast-1", name="ap-northeast-1a", zone_id="apne1-az4"),
|
||||
Zone(region_name="ap-northeast-1", name="ap-northeast-1c", zone_id="apne1-az1"),
|
||||
Zone(region_name="ap-northeast-1", name="ap-northeast-1d", zone_id="apne1-az2")
|
||||
],
|
||||
'sa-east-1': [
|
||||
Zone(region_name="sa-east-1", name="sa-east-1a", zone_id="sae1-az1"),
|
||||
Zone(region_name="sa-east-1", name="sa-east-1c", zone_id="sae1-az3")
|
||||
],
|
||||
'ca-central-1': [
|
||||
Zone(region_name="ca-central-1", name="ca-central-1a", zone_id="cac1-az1"),
|
||||
Zone(region_name="ca-central-1", name="ca-central-1b", zone_id="cac1-az2")
|
||||
],
|
||||
'ap-southeast-1': [
|
||||
Zone(region_name="ap-southeast-1", name="ap-southeast-1a", zone_id="apse1-az1"),
|
||||
Zone(region_name="ap-southeast-1", name="ap-southeast-1b", zone_id="apse1-az2"),
|
||||
Zone(region_name="ap-southeast-1", name="ap-southeast-1c", zone_id="apse1-az3")
|
||||
],
|
||||
'ap-southeast-2': [
|
||||
Zone(region_name="ap-southeast-2", name="ap-southeast-2a", zone_id="apse2-az1"),
|
||||
Zone(region_name="ap-southeast-2", name="ap-southeast-2b", zone_id="apse2-az3"),
|
||||
Zone(region_name="ap-southeast-2", name="ap-southeast-2c", zone_id="apse2-az2")
|
||||
],
|
||||
'eu-central-1': [
|
||||
Zone(region_name="eu-central-1", name="eu-central-1a", zone_id="euc1-az2"),
|
||||
Zone(region_name="eu-central-1", name="eu-central-1b", zone_id="euc1-az3"),
|
||||
Zone(region_name="eu-central-1", name="eu-central-1c", zone_id="euc1-az1")
|
||||
],
|
||||
'us-east-1': [
|
||||
Zone(region_name="us-east-1", name="us-east-1a", zone_id="use1-az6"),
|
||||
Zone(region_name="us-east-1", name="us-east-1b", zone_id="use1-az1"),
|
||||
Zone(region_name="us-east-1", name="us-east-1c", zone_id="use1-az2"),
|
||||
Zone(region_name="us-east-1", name="us-east-1d", zone_id="use1-az4"),
|
||||
Zone(region_name="us-east-1", name="us-east-1e", zone_id="use1-az3"),
|
||||
Zone(region_name="us-east-1", name="us-east-1f", zone_id="use1-az5")
|
||||
],
|
||||
'us-east-2': [
|
||||
Zone(region_name="us-east-2", name="us-east-2a", zone_id="use2-az1"),
|
||||
Zone(region_name="us-east-2", name="us-east-2b", zone_id="use2-az2"),
|
||||
Zone(region_name="us-east-2", name="us-east-2c", zone_id="use2-az3")
|
||||
],
|
||||
'us-west-1': [
|
||||
Zone(region_name="us-west-1", name="us-west-1a", zone_id="usw1-az3"),
|
||||
Zone(region_name="us-west-1", name="us-west-1b", zone_id="usw1-az1")
|
||||
],
|
||||
'us-west-2': [
|
||||
Zone(region_name="us-west-2", name="us-west-2a", zone_id="usw2-az2"),
|
||||
Zone(region_name="us-west-2", name="us-west-2b", zone_id="usw2-az1"),
|
||||
Zone(region_name="us-west-2", name="us-west-2c", zone_id="usw2-az3")
|
||||
],
|
||||
'cn-north-1': [
|
||||
Zone(region_name="cn-north-1", name="cn-north-1a", zone_id="cnn1-az1"),
|
||||
Zone(region_name="cn-north-1", name="cn-north-1b", zone_id="cnn1-az2")
|
||||
],
|
||||
'us-gov-west-1': [
|
||||
Zone(region_name="us-gov-west-1", name="us-gov-west-1a", zone_id="usgw1-az1"),
|
||||
Zone(region_name="us-gov-west-1", name="us-gov-west-1b", zone_id="usgw1-az2"),
|
||||
Zone(region_name="us-gov-west-1", name="us-gov-west-1c", zone_id="usgw1-az3")
|
||||
]
|
||||
}
|
||||
|
||||
def describe_regions(self, region_names=[]):
|
||||
if len(region_names) == 0:
|
||||
@ -2374,7 +2465,7 @@ class VPCPeeringConnectionBackend(object):
|
||||
|
||||
class Subnet(TaggedEC2Resource):
|
||||
def __init__(self, ec2_backend, subnet_id, vpc_id, cidr_block, availability_zone, default_for_az,
|
||||
map_public_ip_on_launch):
|
||||
map_public_ip_on_launch, owner_id=111122223333, assign_ipv6_address_on_creation=False):
|
||||
self.ec2_backend = ec2_backend
|
||||
self.id = subnet_id
|
||||
self.vpc_id = vpc_id
|
||||
@ -2383,6 +2474,9 @@ class Subnet(TaggedEC2Resource):
|
||||
self._availability_zone = availability_zone
|
||||
self.default_for_az = default_for_az
|
||||
self.map_public_ip_on_launch = map_public_ip_on_launch
|
||||
self.owner_id = owner_id
|
||||
self.assign_ipv6_address_on_creation = assign_ipv6_address_on_creation
|
||||
self.ipv6_cidr_block_associations = []
|
||||
|
||||
# Theory is we assign ip's as we go (as 16,777,214 usable IPs in a /8)
|
||||
self._subnet_ip_generator = self.cidr.hosts()
|
||||
@ -2412,7 +2506,7 @@ class Subnet(TaggedEC2Resource):
|
||||
|
||||
@property
|
||||
def availability_zone(self):
|
||||
return self._availability_zone
|
||||
return self._availability_zone.name
|
||||
|
||||
@property
|
||||
def physical_resource_id(self):
|
||||
@ -2509,7 +2603,7 @@ class SubnetBackend(object):
|
||||
return subnets[subnet_id]
|
||||
raise InvalidSubnetIdError(subnet_id)
|
||||
|
||||
def create_subnet(self, vpc_id, cidr_block, availability_zone):
|
||||
def create_subnet(self, vpc_id, cidr_block, availability_zone, context=None):
|
||||
subnet_id = random_subnet_id()
|
||||
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)
|
||||
@ -2529,8 +2623,15 @@ class SubnetBackend(object):
|
||||
# consider it the default
|
||||
default_for_az = str(availability_zone not in self.subnets).lower()
|
||||
map_public_ip_on_launch = default_for_az
|
||||
subnet = Subnet(self, subnet_id, vpc_id, cidr_block, availability_zone,
|
||||
default_for_az, map_public_ip_on_launch)
|
||||
if availability_zone is None:
|
||||
availability_zone = 'us-east-1a'
|
||||
try:
|
||||
availability_zone_data = next(zone for zones in RegionsAndZonesBackend.zones.values() for zone in zones if zone.name == availability_zone)
|
||||
except StopIteration:
|
||||
raise InvalidAvailabilityZoneError(availability_zone, ", ".join([zone.name for zones in RegionsAndZonesBackend.zones.values() for zone in zones]))
|
||||
subnet = Subnet(self, subnet_id, vpc_id, cidr_block, availability_zone_data,
|
||||
default_for_az, map_public_ip_on_launch,
|
||||
owner_id=context.get_current_user() if context else '111122223333', assign_ipv6_address_on_creation=False)
|
||||
|
||||
# AWS associates a new subnet with the default Network ACL
|
||||
self.associate_default_network_acl_with_subnet(subnet_id, vpc_id)
|
||||
@ -2558,11 +2659,12 @@ class SubnetBackend(object):
|
||||
return subnets.pop(subnet_id, None)
|
||||
raise InvalidSubnetIdError(subnet_id)
|
||||
|
||||
def modify_subnet_attribute(self, subnet_id, map_public_ip):
|
||||
def modify_subnet_attribute(self, subnet_id, attr_name, attr_value):
|
||||
subnet = self.get_subnet(subnet_id)
|
||||
if map_public_ip not in ('true', 'false'):
|
||||
raise InvalidParameterValueError(map_public_ip)
|
||||
subnet.map_public_ip_on_launch = map_public_ip
|
||||
if attr_name in ('map_public_ip_on_launch', 'assign_ipv6_address_on_creation'):
|
||||
setattr(subnet, attr_name, attr_value)
|
||||
else:
|
||||
raise InvalidParameterValueError(attr_name)
|
||||
|
||||
|
||||
class SubnetRouteTableAssociation(object):
|
||||
|
@ -1,6 +1,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import random
|
||||
from moto.core.responses import BaseResponse
|
||||
from moto.core.utils import camelcase_to_underscores
|
||||
from moto.ec2.utils import filters_from_querystring
|
||||
|
||||
|
||||
@ -16,6 +17,7 @@ class Subnets(BaseResponse):
|
||||
vpc_id,
|
||||
cidr_block,
|
||||
availability_zone,
|
||||
context=self,
|
||||
)
|
||||
template = self.response_template(CREATE_SUBNET_RESPONSE)
|
||||
return template.render(subnet=subnet)
|
||||
@ -35,8 +37,13 @@ class Subnets(BaseResponse):
|
||||
|
||||
def modify_subnet_attribute(self):
|
||||
subnet_id = self._get_param('SubnetId')
|
||||
map_public_ip = self._get_param('MapPublicIpOnLaunch.Value')
|
||||
self.ec2_backend.modify_subnet_attribute(subnet_id, map_public_ip)
|
||||
|
||||
for attribute in ('MapPublicIpOnLaunch', 'AssignIpv6AddressOnCreation'):
|
||||
if self.querystring.get('%s.Value' % attribute):
|
||||
attr_name = camelcase_to_underscores(attribute)
|
||||
attr_value = self.querystring.get('%s.Value' % attribute)[0]
|
||||
self.ec2_backend.modify_subnet_attribute(
|
||||
subnet_id, attr_name, attr_value)
|
||||
return MODIFY_SUBNET_ATTRIBUTE_RESPONSE
|
||||
|
||||
|
||||
@ -49,17 +56,14 @@ CREATE_SUBNET_RESPONSE = """
|
||||
<vpcId>{{ subnet.vpc_id }}</vpcId>
|
||||
<cidrBlock>{{ subnet.cidr_block }}</cidrBlock>
|
||||
<availableIpAddressCount>251</availableIpAddressCount>
|
||||
<availabilityZone>{{ subnet.availability_zone }}</availabilityZone>
|
||||
<tagSet>
|
||||
{% for tag in subnet.get_tags() %}
|
||||
<item>
|
||||
<resourceId>{{ tag.resource_id }}</resourceId>
|
||||
<resourceType>{{ tag.resource_type }}</resourceType>
|
||||
<key>{{ tag.key }}</key>
|
||||
<value>{{ tag.value }}</value>
|
||||
</item>
|
||||
{% endfor %}
|
||||
</tagSet>
|
||||
<availabilityZone>{{ subnet._availability_zone.name }}</availabilityZone>
|
||||
<availabilityZoneId>{{ subnet._availability_zone.zone_id }}</availabilityZoneId>
|
||||
<defaultForAz>{{ subnet.default_for_az }}</defaultForAz>
|
||||
<mapPublicIpOnLaunch>{{ subnet.map_public_ip_on_launch }}</mapPublicIpOnLaunch>
|
||||
<ownerId>{{ subnet.owner_id }}</ownerId>
|
||||
<assignIpv6AddressOnCreation>{{ subnet.assign_ipv6_address_on_creation }}</assignIpv6AddressOnCreation>
|
||||
<ipv6CidrBlockAssociationSet>{{ subnet.ipv6_cidr_block_associations }}</ipv6CidrBlockAssociationSet>
|
||||
<subnetArn>arn:aws:ec2:{{ subnet._availability_zone.name[0:-1] }}:{{ subnet.owner_id }}:subnet/{{ subnet.id }}</subnetArn>
|
||||
</subnet>
|
||||
</CreateSubnetResponse>"""
|
||||
|
||||
@ -80,9 +84,15 @@ DESCRIBE_SUBNETS_RESPONSE = """
|
||||
<vpcId>{{ subnet.vpc_id }}</vpcId>
|
||||
<cidrBlock>{{ subnet.cidr_block }}</cidrBlock>
|
||||
<availableIpAddressCount>251</availableIpAddressCount>
|
||||
<availabilityZone>{{ subnet.availability_zone }}</availabilityZone>
|
||||
<availabilityZone>{{ subnet._availability_zone.name }}</availabilityZone>
|
||||
<availabilityZoneId>{{ subnet._availability_zone.zone_id }}</availabilityZoneId>
|
||||
<defaultForAz>{{ subnet.default_for_az }}</defaultForAz>
|
||||
<mapPublicIpOnLaunch>{{ subnet.map_public_ip_on_launch }}</mapPublicIpOnLaunch>
|
||||
<ownerId>{{ subnet.owner_id }}</ownerId>
|
||||
<assignIpv6AddressOnCreation>{{ subnet.assign_ipv6_address_on_creation }}</assignIpv6AddressOnCreation>
|
||||
<ipv6CidrBlockAssociationSet>{{ subnet.ipv6_cidr_block_associations }}</ipv6CidrBlockAssociationSet>
|
||||
<subnetArn>arn:aws:ec2:{{ subnet._availability_zone.name[0:-1] }}:{{ subnet.owner_id }}:subnet/{{ subnet.id }}</subnetArn>
|
||||
{% if subnet.get_tags() %}
|
||||
<tagSet>
|
||||
{% for tag in subnet.get_tags() %}
|
||||
<item>
|
||||
@ -93,6 +103,7 @@ DESCRIBE_SUBNETS_RESPONSE = """
|
||||
</item>
|
||||
{% endfor %}
|
||||
</tagSet>
|
||||
{% endif %}
|
||||
</item>
|
||||
{% endfor %}
|
||||
</subnetSet>
|
||||
|
@ -30,12 +30,12 @@ def test_new_subnet_associates_with_default_network_acl():
|
||||
conn = boto.connect_vpc('the_key', 'the secret')
|
||||
vpc = conn.get_all_vpcs()[0]
|
||||
|
||||
subnet = conn.create_subnet(vpc.id, "172.31.48.0/20")
|
||||
subnet = conn.create_subnet(vpc.id, "172.31.112.0/20")
|
||||
all_network_acls = conn.get_all_network_acls()
|
||||
all_network_acls.should.have.length_of(1)
|
||||
|
||||
acl = all_network_acls[0]
|
||||
acl.associations.should.have.length_of(4)
|
||||
acl.associations.should.have.length_of(7)
|
||||
[a.subnet_id for a in acl.associations].should.contain(subnet.id)
|
||||
|
||||
|
||||
|
@ -118,7 +118,7 @@ def test_boto3_non_default_subnet():
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_subnet_attribute():
|
||||
def test_modify_subnet_attribute_public_ip_on_launch():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
client = boto3.client('ec2', region_name='us-west-1')
|
||||
|
||||
@ -145,6 +145,34 @@ def test_modify_subnet_attribute():
|
||||
subnet.map_public_ip_on_launch.should.be.ok
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_subnet_attribute_assign_ipv6_address_on_creation():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
client = boto3.client('ec2', region_name='us-west-1')
|
||||
|
||||
# Get the default VPC
|
||||
vpc = list(ec2.vpcs.all())[0]
|
||||
|
||||
subnet = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='172.31.112.0/20', AvailabilityZone='us-west-1a')
|
||||
|
||||
# 'map_public_ip_on_launch' is set when calling 'DescribeSubnets' action
|
||||
subnet.reload()
|
||||
|
||||
# For non default subnet, attribute value should be 'False'
|
||||
subnet.assign_ipv6_address_on_creation.shouldnt.be.ok
|
||||
|
||||
client.modify_subnet_attribute(
|
||||
SubnetId=subnet.id, AssignIpv6AddressOnCreation={'Value': False})
|
||||
subnet.reload()
|
||||
subnet.assign_ipv6_address_on_creation.shouldnt.be.ok
|
||||
|
||||
client.modify_subnet_attribute(
|
||||
SubnetId=subnet.id, AssignIpv6AddressOnCreation={'Value': True})
|
||||
subnet.reload()
|
||||
subnet.assign_ipv6_address_on_creation.should.be.ok
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_modify_subnet_attribute_validation():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
@ -291,6 +319,84 @@ def test_subnet_tags_through_cloudformation():
|
||||
subnet.tags["blah"].should.equal("baz")
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnet_response_fields():
|
||||
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')
|
||||
subnet = client.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')['Subnet']
|
||||
|
||||
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)
|
||||
|
||||
subnet_arn = "arn:aws:ec2:{region}:{owner_id}:subnet/{subnet_id}".format(region=subnet['AvailabilityZone'][0:-1],
|
||||
owner_id=subnet['OwnerId'],
|
||||
subnet_id=subnet['SubnetId'])
|
||||
subnet.should.have.key('SubnetArn').which.should.equal(subnet_arn)
|
||||
subnet.should.have.key('Ipv6CidrBlockAssociationSet').which.should.equal([])
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_describe_subnet_response_fields():
|
||||
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')
|
||||
subnet_object = ec2.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
|
||||
|
||||
subnets = client.describe_subnets(SubnetIds=[subnet_object.id])['Subnets']
|
||||
subnets.should.have.length_of(1)
|
||||
subnet = subnets[0]
|
||||
|
||||
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)
|
||||
|
||||
subnet_arn = "arn:aws:ec2:{region}:{owner_id}:subnet/{subnet_id}".format(region=subnet['AvailabilityZone'][0:-1],
|
||||
owner_id=subnet['OwnerId'],
|
||||
subnet_id=subnet['SubnetId'])
|
||||
subnet.should.have.key('SubnetArn').which.should.equal(subnet_arn)
|
||||
subnet.should.have.key('Ipv6CidrBlockAssociationSet').which.should.equal([])
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnet_with_invalid_availability_zone():
|
||||
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')
|
||||
|
||||
subnet_availability_zone = 'asfasfas'
|
||||
with assert_raises(ClientError) as ex:
|
||||
subnet = client.create_subnet(
|
||||
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone=subnet_availability_zone)
|
||||
assert str(ex.exception).startswith(
|
||||
"An error occurred (InvalidParameterValue) when calling the CreateSubnet "
|
||||
"operation: Value ({}) for parameter availabilityZone is invalid. Subnets can currently only be created in the following availability zones: ".format(subnet_availability_zone))
|
||||
|
||||
|
||||
@mock_ec2
|
||||
def test_create_subnet_with_invalid_cidr_range():
|
||||
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
||||
|
Loading…
Reference in New Issue
Block a user