f408709ef9
* Implemented throwing invalid subnet range error and fixed breaking tests. * Implemented throwing invalid CIDR block parameter error for vpcs and subnets. * Implemented throwing invalid destination CIDR block error. * IPv6 addresses not accepted, strict checking disabled. * Implemented throwing invalid subnet conflict error and fixed breaking tests. * Implemented throwing invalid VPC range error and fixed breaking tests. * Fixed accidentally removed ). * Fixed test case trying to create two subnets with the same CIDR range.
341 lines
12 KiB
Python
341 lines
12 KiB
Python
from __future__ import unicode_literals
|
|
# Ensure 'assert_raises' context manager support for Python 2.6
|
|
import tests.backport_assert_raises # noqa
|
|
from nose.tools import assert_raises
|
|
|
|
import boto3
|
|
import boto
|
|
import boto.vpc
|
|
from boto.exception import EC2ResponseError
|
|
from botocore.exceptions import ParamValidationError, ClientError
|
|
import json
|
|
import sure # noqa
|
|
|
|
from moto import mock_cloudformation_deprecated, mock_ec2, mock_ec2_deprecated
|
|
|
|
|
|
@mock_ec2_deprecated
|
|
def test_subnets():
|
|
ec2 = boto.connect_ec2('the_key', 'the_secret')
|
|
conn = boto.connect_vpc('the_key', 'the_secret')
|
|
vpc = conn.create_vpc("10.0.0.0/16")
|
|
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
|
|
|
all_subnets = conn.get_all_subnets()
|
|
all_subnets.should.have.length_of(1 + len(ec2.get_all_zones()))
|
|
|
|
conn.delete_subnet(subnet.id)
|
|
|
|
all_subnets = conn.get_all_subnets()
|
|
all_subnets.should.have.length_of(0 + len(ec2.get_all_zones()))
|
|
|
|
with assert_raises(EC2ResponseError) as cm:
|
|
conn.delete_subnet(subnet.id)
|
|
cm.exception.code.should.equal('InvalidSubnetID.NotFound')
|
|
cm.exception.status.should.equal(400)
|
|
cm.exception.request_id.should_not.be.none
|
|
|
|
|
|
@mock_ec2_deprecated
|
|
def test_subnet_create_vpc_validation():
|
|
conn = boto.connect_vpc('the_key', 'the_secret')
|
|
|
|
with assert_raises(EC2ResponseError) as cm:
|
|
conn.create_subnet("vpc-abcd1234", "10.0.0.0/18")
|
|
cm.exception.code.should.equal('InvalidVpcID.NotFound')
|
|
cm.exception.status.should.equal(400)
|
|
cm.exception.request_id.should_not.be.none
|
|
|
|
|
|
@mock_ec2_deprecated
|
|
def test_subnet_tagging():
|
|
conn = boto.connect_vpc('the_key', 'the_secret')
|
|
vpc = conn.create_vpc("10.0.0.0/16")
|
|
subnet = conn.create_subnet(vpc.id, "10.0.0.0/18")
|
|
|
|
subnet.add_tag("a key", "some value")
|
|
|
|
tag = conn.get_all_tags()[0]
|
|
tag.name.should.equal("a key")
|
|
tag.value.should.equal("some value")
|
|
|
|
# Refresh the subnet
|
|
subnet = conn.get_all_subnets(subnet_ids=[subnet.id])[0]
|
|
subnet.tags.should.have.length_of(1)
|
|
subnet.tags["a key"].should.equal("some value")
|
|
|
|
|
|
@mock_ec2_deprecated
|
|
def test_subnet_should_have_proper_availability_zone_set():
|
|
conn = boto.vpc.connect_to_region('us-west-1')
|
|
vpcA = conn.create_vpc("10.0.0.0/16")
|
|
subnetA = conn.create_subnet(
|
|
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1b')
|
|
subnetA.availability_zone.should.equal('us-west-1b')
|
|
|
|
|
|
@mock_ec2
|
|
def test_default_subnet():
|
|
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
|
|
|
default_vpc = list(ec2.vpcs.all())[0]
|
|
default_vpc.cidr_block.should.equal('172.31.0.0/16')
|
|
default_vpc.reload()
|
|
default_vpc.is_default.should.be.ok
|
|
|
|
subnet = ec2.create_subnet(
|
|
VpcId=default_vpc.id, CidrBlock='172.31.48.0/20', AvailabilityZone='us-west-1a')
|
|
subnet.reload()
|
|
subnet.map_public_ip_on_launch.shouldnt.be.ok
|
|
|
|
|
|
@mock_ec2_deprecated
|
|
def test_non_default_subnet():
|
|
vpc_cli = boto.vpc.connect_to_region('us-west-1')
|
|
|
|
# Create the non default VPC
|
|
vpc = vpc_cli.create_vpc("10.0.0.0/16")
|
|
vpc.is_default.shouldnt.be.ok
|
|
|
|
subnet = vpc_cli.create_subnet(vpc.id, "10.0.0.0/24")
|
|
subnet = vpc_cli.get_all_subnets(subnet_ids=[subnet.id])[0]
|
|
subnet.mapPublicIpOnLaunch.should.equal('false')
|
|
|
|
|
|
@mock_ec2
|
|
def test_boto3_non_default_subnet():
|
|
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
|
|
|
# Create the non default VPC
|
|
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
|
vpc.reload()
|
|
vpc.is_default.shouldnt.be.ok
|
|
|
|
subnet = ec2.create_subnet(
|
|
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
|
|
subnet.reload()
|
|
subnet.map_public_ip_on_launch.shouldnt.be.ok
|
|
|
|
|
|
@mock_ec2
|
|
def test_modify_subnet_attribute():
|
|
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.48.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.map_public_ip_on_launch.shouldnt.be.ok
|
|
|
|
client.modify_subnet_attribute(
|
|
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': False})
|
|
subnet.reload()
|
|
subnet.map_public_ip_on_launch.shouldnt.be.ok
|
|
|
|
client.modify_subnet_attribute(
|
|
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': True})
|
|
subnet.reload()
|
|
subnet.map_public_ip_on_launch.should.be.ok
|
|
|
|
|
|
@mock_ec2
|
|
def test_modify_subnet_attribute_validation():
|
|
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 = ec2.create_subnet(
|
|
VpcId=vpc.id, CidrBlock='10.0.0.0/24', AvailabilityZone='us-west-1a')
|
|
|
|
with assert_raises(ParamValidationError):
|
|
client.modify_subnet_attribute(
|
|
SubnetId=subnet.id, MapPublicIpOnLaunch={'Value': 'invalid'})
|
|
|
|
|
|
@mock_ec2_deprecated
|
|
def test_subnet_get_by_id():
|
|
ec2 = boto.ec2.connect_to_region('us-west-1')
|
|
conn = boto.vpc.connect_to_region('us-west-1')
|
|
vpcA = conn.create_vpc("10.0.0.0/16")
|
|
subnetA = conn.create_subnet(
|
|
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1a')
|
|
vpcB = conn.create_vpc("10.0.0.0/16")
|
|
subnetB1 = conn.create_subnet(
|
|
vpcB.id, "10.0.0.0/24", availability_zone='us-west-1a')
|
|
subnetB2 = conn.create_subnet(
|
|
vpcB.id, "10.0.1.0/24", availability_zone='us-west-1b')
|
|
|
|
subnets_by_id = conn.get_all_subnets(subnet_ids=[subnetA.id, subnetB1.id])
|
|
subnets_by_id.should.have.length_of(2)
|
|
subnets_by_id = tuple(map(lambda s: s.id, subnets_by_id))
|
|
subnetA.id.should.be.within(subnets_by_id)
|
|
subnetB1.id.should.be.within(subnets_by_id)
|
|
|
|
with assert_raises(EC2ResponseError) as cm:
|
|
conn.get_all_subnets(subnet_ids=['subnet-does_not_exist'])
|
|
cm.exception.code.should.equal('InvalidSubnetID.NotFound')
|
|
cm.exception.status.should.equal(400)
|
|
cm.exception.request_id.should_not.be.none
|
|
|
|
|
|
@mock_ec2_deprecated
|
|
def test_get_subnets_filtering():
|
|
ec2 = boto.ec2.connect_to_region('us-west-1')
|
|
conn = boto.vpc.connect_to_region('us-west-1')
|
|
vpcA = conn.create_vpc("10.0.0.0/16")
|
|
subnetA = conn.create_subnet(
|
|
vpcA.id, "10.0.0.0/24", availability_zone='us-west-1a')
|
|
vpcB = conn.create_vpc("10.0.0.0/16")
|
|
subnetB1 = conn.create_subnet(
|
|
vpcB.id, "10.0.0.0/24", availability_zone='us-west-1a')
|
|
subnetB2 = conn.create_subnet(
|
|
vpcB.id, "10.0.1.0/24", availability_zone='us-west-1b')
|
|
|
|
all_subnets = conn.get_all_subnets()
|
|
all_subnets.should.have.length_of(3 + len(ec2.get_all_zones()))
|
|
|
|
# Filter by VPC ID
|
|
subnets_by_vpc = conn.get_all_subnets(filters={'vpc-id': vpcB.id})
|
|
subnets_by_vpc.should.have.length_of(2)
|
|
set([subnet.id for subnet in subnets_by_vpc]).should.equal(
|
|
set([subnetB1.id, subnetB2.id]))
|
|
|
|
# Filter by CIDR variations
|
|
subnets_by_cidr1 = conn.get_all_subnets(filters={'cidr': "10.0.0.0/24"})
|
|
subnets_by_cidr1.should.have.length_of(2)
|
|
set([subnet.id for subnet in subnets_by_cidr1]
|
|
).should.equal(set([subnetA.id, subnetB1.id]))
|
|
|
|
subnets_by_cidr2 = conn.get_all_subnets(
|
|
filters={'cidr-block': "10.0.0.0/24"})
|
|
subnets_by_cidr2.should.have.length_of(2)
|
|
set([subnet.id for subnet in subnets_by_cidr2]
|
|
).should.equal(set([subnetA.id, subnetB1.id]))
|
|
|
|
subnets_by_cidr3 = conn.get_all_subnets(
|
|
filters={'cidrBlock': "10.0.0.0/24"})
|
|
subnets_by_cidr3.should.have.length_of(2)
|
|
set([subnet.id for subnet in subnets_by_cidr3]
|
|
).should.equal(set([subnetA.id, subnetB1.id]))
|
|
|
|
# Filter by VPC ID and CIDR
|
|
subnets_by_vpc_and_cidr = conn.get_all_subnets(
|
|
filters={'vpc-id': vpcB.id, 'cidr': "10.0.0.0/24"})
|
|
subnets_by_vpc_and_cidr.should.have.length_of(1)
|
|
set([subnet.id for subnet in subnets_by_vpc_and_cidr]
|
|
).should.equal(set([subnetB1.id]))
|
|
|
|
# Filter by subnet ID
|
|
subnets_by_id = conn.get_all_subnets(filters={'subnet-id': subnetA.id})
|
|
subnets_by_id.should.have.length_of(1)
|
|
set([subnet.id for subnet in subnets_by_id]).should.equal(set([subnetA.id]))
|
|
|
|
# Filter by availabilityZone
|
|
subnets_by_az = conn.get_all_subnets(
|
|
filters={'availabilityZone': 'us-west-1a', 'vpc-id': vpcB.id})
|
|
subnets_by_az.should.have.length_of(1)
|
|
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(len(conn.get_all_zones()))
|
|
|
|
# Unsupported filter
|
|
conn.get_all_subnets.when.called_with(
|
|
filters={'not-implemented-filter': 'foobar'}).should.throw(NotImplementedError)
|
|
|
|
|
|
@mock_ec2_deprecated
|
|
@mock_cloudformation_deprecated
|
|
def test_subnet_tags_through_cloudformation():
|
|
vpc_conn = boto.vpc.connect_to_region('us-west-1')
|
|
vpc = vpc_conn.create_vpc("10.0.0.0/16")
|
|
|
|
subnet_template = {
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
"Resources": {
|
|
"testSubnet": {
|
|
"Type": "AWS::EC2::Subnet",
|
|
"Properties": {
|
|
"VpcId": vpc.id,
|
|
"CidrBlock": "10.0.0.0/24",
|
|
"AvailabilityZone": "us-west-1b",
|
|
"Tags": [{
|
|
"Key": "foo",
|
|
"Value": "bar",
|
|
}, {
|
|
"Key": "blah",
|
|
"Value": "baz",
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
cf_conn = boto.cloudformation.connect_to_region("us-west-1")
|
|
template_json = json.dumps(subnet_template)
|
|
cf_conn.create_stack(
|
|
"test_stack",
|
|
template_body=template_json,
|
|
)
|
|
|
|
subnet = vpc_conn.get_all_subnets(filters={'cidrBlock': '10.0.0.0/24'})[0]
|
|
subnet.tags["foo"].should.equal("bar")
|
|
subnet.tags["blah"].should.equal("baz")
|
|
|
|
|
|
@mock_ec2
|
|
def test_create_subnet_with_invalid_cidr_range():
|
|
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
|
|
|
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
|
vpc.reload()
|
|
vpc.is_default.shouldnt.be.ok
|
|
|
|
subnet_cidr_block = '10.1.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')
|
|
|
|
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
|
vpc.reload()
|
|
vpc.is_default.shouldnt.be.ok
|
|
|
|
subnet_cidr_block = '1000.1.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 (InvalidParameterValue) when calling the CreateSubnet "
|
|
"operation: Value ({}) for parameter cidrBlock is invalid. This is not a valid CIDR block.".format(subnet_cidr_block))
|
|
|
|
|
|
@mock_ec2
|
|
def test_create_subnets_with_overlapping_cidr_blocks():
|
|
ec2 = boto3.resource('ec2', region_name='us-west-1')
|
|
|
|
vpc = ec2.create_vpc(CidrBlock='10.0.0.0/16')
|
|
vpc.reload()
|
|
vpc.is_default.shouldnt.be.ok
|
|
|
|
subnet_cidr_block = '10.0.0.0/24'
|
|
with assert_raises(ClientError) as ex:
|
|
subnet1 = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
|
|
subnet2 = ec2.create_subnet(VpcId=vpc.id, CidrBlock=subnet_cidr_block)
|
|
str(ex.exception).should.equal(
|
|
"An error occurred (InvalidSubnet.Conflict) when calling the CreateSubnet "
|
|
"operation: The CIDR '{}' conflicts with another subnet".format(subnet_cidr_block))
|