create default vpc
check if default vpc exists, create if not, use it in describe_vpcs function, fix unit test add unit tests for default vpc creation Change-Id: I32411c55a9877854ef11e52f082496bb6656291f
This commit is contained in:
parent
4bbd243f47
commit
449f7c741c
|
@ -482,6 +482,18 @@ def get_attached_gateway(context, vpc_id, gateway_kind):
|
|||
if gw['vpc_id'] == vpc_id), None)
|
||||
|
||||
|
||||
_check_and_create_default_vpc = None
|
||||
|
||||
|
||||
def check_and_create_default_vpc(context):
|
||||
return _check_and_create_default_vpc(context)
|
||||
|
||||
|
||||
def set_check_and_create_default_vpc(check_and_create_default_vpc):
|
||||
global _check_and_create_default_vpc
|
||||
_check_and_create_default_vpc = check_and_create_default_vpc
|
||||
|
||||
|
||||
# NOTE(ft): following functions are copied from various parts of Nova
|
||||
|
||||
_ephemeral = re.compile('^ephemeral(\d|[1-9]\d+)$')
|
||||
|
|
|
@ -40,27 +40,11 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
Validator = common.Validator
|
||||
|
||||
DEFAULT_VPC_CIDR_BLOCK = '172.31.0.0/16'
|
||||
|
||||
|
||||
def create_vpc(context, cidr_block, instance_tenancy='default'):
|
||||
neutron = clients.neutron(context)
|
||||
with common.OnCrashCleaner() as cleaner:
|
||||
os_router_body = {'router': {}}
|
||||
try:
|
||||
os_router = neutron.create_router(os_router_body)['router']
|
||||
except neutron_exception.OverQuotaClient:
|
||||
raise exception.VpcLimitExceeded()
|
||||
cleaner.addCleanup(neutron.delete_router, os_router['id'])
|
||||
vpc = db_api.add_item(context, 'vpc',
|
||||
{'os_id': os_router['id'],
|
||||
'cidr_block': cidr_block})
|
||||
cleaner.addCleanup(db_api.delete_item, context, vpc['id'])
|
||||
route_table = route_table_api._create_route_table(context, vpc)
|
||||
cleaner.addCleanup(route_table_api._delete_route_table,
|
||||
context, route_table['id'])
|
||||
vpc['route_table_id'] = route_table['id']
|
||||
db_api.update_item(context, vpc)
|
||||
neutron.update_router(os_router['id'], {'router': {'name': vpc['id']}})
|
||||
security_group_api._create_default_security_group(context, vpc)
|
||||
vpc = _create_vpc(context, cidr_block)
|
||||
return {'vpc': _format_vpc(vpc)}
|
||||
|
||||
|
||||
|
@ -130,15 +114,49 @@ class VpcDescriber(common.TaggableItemsDescriber,
|
|||
|
||||
|
||||
def describe_vpcs(context, vpc_id=None, filter=None):
|
||||
_check_and_create_default_vpc(context)
|
||||
formatted_vpcs = VpcDescriber().describe(
|
||||
context, ids=vpc_id, filter=filter)
|
||||
return {'vpcSet': formatted_vpcs}
|
||||
|
||||
|
||||
def _create_vpc(context, cidr_block, is_default=False):
|
||||
neutron = clients.neutron(context)
|
||||
with common.OnCrashCleaner() as cleaner:
|
||||
os_router_body = {'router': {}}
|
||||
try:
|
||||
os_router = neutron.create_router(os_router_body)['router']
|
||||
except neutron_exception.OverQuotaClient:
|
||||
raise exception.VpcLimitExceeded()
|
||||
cleaner.addCleanup(neutron.delete_router, os_router['id'])
|
||||
vpc = db_api.add_item(context, 'vpc',
|
||||
{'os_id': os_router['id'],
|
||||
'cidr_block': cidr_block,
|
||||
'is_default': is_default})
|
||||
cleaner.addCleanup(db_api.delete_item, context, vpc['id'])
|
||||
route_table = route_table_api._create_route_table(context, vpc)
|
||||
cleaner.addCleanup(route_table_api._delete_route_table,
|
||||
context, route_table['id'])
|
||||
vpc['route_table_id'] = route_table['id']
|
||||
db_api.update_item(context, vpc)
|
||||
neutron.update_router(os_router['id'], {'router': {'name': vpc['id']}})
|
||||
security_group_api._create_default_security_group(context, vpc)
|
||||
return vpc
|
||||
|
||||
|
||||
def _check_and_create_default_vpc(context):
|
||||
if not any(vpc.get('is_default')
|
||||
for vpc in db_api.get_items(context, 'vpc')):
|
||||
_create_vpc(context, DEFAULT_VPC_CIDR_BLOCK, is_default=True)
|
||||
|
||||
|
||||
ec2utils.set_check_and_create_default_vpc(_check_and_create_default_vpc)
|
||||
|
||||
|
||||
def _format_vpc(vpc):
|
||||
return {'vpcId': vpc['id'],
|
||||
'state': "available",
|
||||
'cidrBlock': vpc['cidr_block'],
|
||||
'isDefault': False,
|
||||
'isDefault': vpc.get('is_default', False),
|
||||
'dhcpOptionsId': vpc.get('dhcp_options_id', 'default'),
|
||||
}
|
||||
|
|
|
@ -53,11 +53,14 @@ TIME_ATTACH_NETWORK_INTERFACE = timeutils.isotime(None, True)
|
|||
MAC_ADDRESS = 'fb:10:2e:b2:ba:b7'
|
||||
|
||||
# vpc constants
|
||||
ID_EC2_VPC_DEFAULT = random_ec2_id('vpc')
|
||||
ID_EC2_VPC_1 = random_ec2_id('vpc')
|
||||
ID_EC2_VPC_2 = random_ec2_id('vpc')
|
||||
ID_OS_ROUTER_DEFAULT = random_os_id()
|
||||
ID_OS_ROUTER_1 = random_os_id()
|
||||
ID_OS_ROUTER_2 = random_os_id()
|
||||
|
||||
CIDR_VPC_DEFAULT = '172.31.0.0/16'
|
||||
CIDR_VPC_1 = '10.10.0.0/16'
|
||||
CIDR_VPC_2 = '10.20.0.0/16'
|
||||
ID_OS_PUBLIC_NETWORK = random_os_id()
|
||||
|
@ -156,6 +159,7 @@ NAME_DEFAULT_OS_SECURITY_GROUP = 'default'
|
|||
|
||||
|
||||
# route table constants
|
||||
ID_EC2_ROUTE_TABLE_DEFAULT = random_ec2_id('rtb')
|
||||
ID_EC2_ROUTE_TABLE_1 = random_ec2_id('rtb')
|
||||
ID_EC2_ROUTE_TABLE_2 = random_ec2_id('rtb')
|
||||
ID_EC2_ROUTE_TABLE_3 = random_ec2_id('rtb')
|
||||
|
@ -377,9 +381,16 @@ CUSTOMER_GATEWAY_CONFIGURATION_2 = etree.tostring(
|
|||
|
||||
# vpc objects
|
||||
# 2 vpcs in normal state
|
||||
DB_VPC_DEFAULT = {'id': ID_EC2_VPC_DEFAULT,
|
||||
'os_id': ID_OS_ROUTER_DEFAULT,
|
||||
'vpc_id': None,
|
||||
'is_default': True,
|
||||
'cidr_block': CIDR_VPC_DEFAULT,
|
||||
'route_table_id': ID_EC2_ROUTE_TABLE_DEFAULT}
|
||||
DB_VPC_1 = {'id': ID_EC2_VPC_1,
|
||||
'os_id': ID_OS_ROUTER_1,
|
||||
'vpc_id': None,
|
||||
'is_default': False,
|
||||
'cidr_block': CIDR_VPC_1,
|
||||
'route_table_id': ID_EC2_ROUTE_TABLE_1}
|
||||
DB_VPC_2 = {'id': ID_EC2_VPC_2,
|
||||
|
@ -387,6 +398,11 @@ DB_VPC_2 = {'id': ID_EC2_VPC_2,
|
|||
'vpc_id': None,
|
||||
'cidr_block': CIDR_VPC_2}
|
||||
|
||||
EC2_VPC_DEFAULT = {'vpcId': ID_EC2_VPC_DEFAULT,
|
||||
'cidrBlock': CIDR_VPC_DEFAULT,
|
||||
'isDefault': True,
|
||||
'state': 'available',
|
||||
'dhcpOptionsId': 'default'}
|
||||
EC2_VPC_1 = {'vpcId': ID_EC2_VPC_1,
|
||||
'cidrBlock': CIDR_VPC_1,
|
||||
'isDefault': False,
|
||||
|
@ -398,6 +414,9 @@ EC2_VPC_2 = {'vpcId': ID_EC2_VPC_2,
|
|||
'state': 'available',
|
||||
'dhcpOptionsId': 'default'}
|
||||
|
||||
OS_ROUTER_DEFAULT = {'id': ID_OS_ROUTER_DEFAULT,
|
||||
'name': ID_EC2_VPC_DEFAULT,
|
||||
'external_gateway_info': None}
|
||||
OS_ROUTER_1 = {'id': ID_OS_ROUTER_1,
|
||||
'name': ID_EC2_VPC_1,
|
||||
'external_gateway_info': {
|
||||
|
@ -1159,6 +1178,13 @@ EC2_NOVA_SECURITY_GROUP_2 = {
|
|||
|
||||
|
||||
# route table objects
|
||||
DB_ROUTE_TABLE_DEFAULT = {
|
||||
'id': ID_EC2_ROUTE_TABLE_DEFAULT,
|
||||
'vpc_id': ID_EC2_VPC_DEFAULT,
|
||||
'routes': [{'destination_cidr_block': CIDR_VPC_DEFAULT,
|
||||
'gateway_id': None}],
|
||||
}
|
||||
|
||||
DB_ROUTE_TABLE_1 = {
|
||||
'id': ID_EC2_ROUTE_TABLE_1,
|
||||
'vpc_id': ID_EC2_VPC_1,
|
||||
|
|
|
@ -218,14 +218,16 @@ class VpcTestCase(base.ApiTestCase):
|
|||
|
||||
def test_describe_vpcs(self):
|
||||
self.neutron.list_routers.return_value = (
|
||||
{'routers': [fakes.OS_ROUTER_1, fakes.OS_ROUTER_2]})
|
||||
self.set_mock_db_items(fakes.DB_VPC_1, fakes.DB_VPC_2)
|
||||
{'routers': [fakes.OS_ROUTER_DEFAULT,
|
||||
fakes.OS_ROUTER_1, fakes.OS_ROUTER_2]})
|
||||
self.set_mock_db_items(fakes.DB_VPC_DEFAULT,
|
||||
fakes.DB_VPC_1, fakes.DB_VPC_2)
|
||||
|
||||
resp = self.execute('DescribeVpcs', {})
|
||||
self.assertThat(resp['vpcSet'],
|
||||
matchers.ListMatches([fakes.EC2_VPC_1,
|
||||
matchers.ListMatches([fakes.EC2_VPC_DEFAULT,
|
||||
fakes.EC2_VPC_1,
|
||||
fakes.EC2_VPC_2]))
|
||||
self.db_api.get_items.assert_called_once_with(mock.ANY, 'vpc')
|
||||
|
||||
resp = self.execute('DescribeVpcs',
|
||||
{'VpcId.1': fakes.ID_EC2_VPC_1})
|
||||
|
@ -247,10 +249,29 @@ class VpcTestCase(base.ApiTestCase):
|
|||
|
||||
def test_describe_vpcs_no_router(self):
|
||||
self.neutron.list_routers.return_value = {'routers': []}
|
||||
self.set_mock_db_items(fakes.DB_VPC_1)
|
||||
self.set_mock_db_items(fakes.DB_VPC_DEFAULT, fakes.DB_VPC_1)
|
||||
|
||||
resp = self.execute('DescribeVpcs', {})
|
||||
|
||||
self.assertThat(resp['vpcSet'],
|
||||
matchers.ListMatches([fakes.EC2_VPC_1]))
|
||||
self.db_api.get_items.assert_called_once_with(mock.ANY, 'vpc')
|
||||
matchers.ListMatches([fakes.EC2_VPC_DEFAULT,
|
||||
fakes.EC2_VPC_1]))
|
||||
|
||||
@mock.patch('ec2api.api.vpc._check_and_create_default_vpc')
|
||||
def test_describe_vpcs_no_default_vpc(self, check_and_create):
|
||||
def mock_check_and_create(context):
|
||||
self.set_mock_db_items(fakes.DB_VPC_DEFAULT)
|
||||
check_and_create.side_effect = mock_check_and_create
|
||||
|
||||
resp = self.execute('DescribeVpcs', {})
|
||||
self.assertEqual(resp['vpcSet'], [fakes.EC2_VPC_DEFAULT])
|
||||
|
||||
check_and_create.assert_called_once_with(mock.ANY)
|
||||
|
||||
def test_describe_vpcs_with_default_vpc(self):
|
||||
self.set_mock_db_items(fakes.DB_VPC_DEFAULT)
|
||||
|
||||
resp = self.execute('DescribeVpcs', {})
|
||||
self.assertEqual(resp['vpcSet'], [fakes.EC2_VPC_DEFAULT])
|
||||
|
||||
self.db_api.add_item.assert_not_called()
|
||||
|
|
Loading…
Reference in New Issue