Merge "Improve get_subent in local neutron"

This commit is contained in:
Zuul 2017-11-13 02:32:52 +00:00 committed by Gerrit Code Review
commit cb72e9d4de
2 changed files with 129 additions and 22 deletions

View File

@ -249,6 +249,30 @@ class TricirclePlugin(plugin.Ml2Plugin):
{'network': net_body})
return b_network
def _is_valid_network(self, context, network_id):
try:
self.core_plugin.get_network(context, network_id)
except q_exceptions.NotFound:
if self._in_subnet_delete(context):
raise
t_ctx = t_context.get_context_from_neutron_context(context)
t_network = self.neutron_handle.handle_get(
t_ctx, 'network', network_id)
region_name = self._get_neutron_region()
located = self._is_network_located_in_region(t_network,
region_name)
if not located:
LOG.error('network: %(network_id)s not located in current '
'region: %(region_name)s, '
'az_hints: %(az_hints)s',
{'network_id': t_network['id'],
'region_name': region_name,
'az_hints': t_network[az_def.AZ_HINTS]})
return located
self._create_bottom_network(context, network_id)
return True
def _is_network_located_in_region(self, t_network, region_name):
az_hints = t_network.get(az_def.AZ_HINTS)
if not az_hints:
@ -268,12 +292,7 @@ class TricirclePlugin(plugin.Ml2Plugin):
t_ctx = t_context.get_context_from_neutron_context(context)
if self._skip_non_api_query(t_ctx):
raise q_exceptions.NetworkNotFound(net_id=_id)
t_network = self.neutron_handle.handle_get(t_ctx, 'network', _id)
if not t_network:
raise q_exceptions.NetworkNotFound(net_id=_id)
self._adapt_network_body(t_network)
b_network = self.core_plugin.create_network(context,
{'network': t_network})
t_network, b_network = self._create_bottom_network(context, _id)
subnet_ids = self._ensure_subnet(context, t_network)
if subnet_ids:
b_network['subnets'] = subnet_ids
@ -363,10 +382,19 @@ class TricirclePlugin(plugin.Ml2Plugin):
b_gateway_ip)['subnet']
t_subnet['gateway_ip'] = subnet_body['gateway_ip']
t_subnet['allocation_pools'] = subnet_body['allocation_pools']
b_subnet = self.core_plugin.create_subnet(q_ctx, {'subnet': t_subnet})
return b_subnet
def _create_bottom_network(self, context, _id):
t_ctx = t_context.get_context_from_neutron_context(context)
t_network = self.neutron_handle.handle_get(t_ctx, 'network', _id)
if not t_network:
raise q_exceptions.NetworkNotFound(net_id=_id)
self._adapt_network_body(t_network)
b_network = self.core_plugin.create_network(context,
{'network': t_network})
return t_network, b_network
def get_subnet(self, context, _id, fields=None):
t_ctx = t_context.get_context_from_neutron_context(context)
try:
@ -377,6 +405,9 @@ class TricirclePlugin(plugin.Ml2Plugin):
t_subnet = self.neutron_handle.handle_get(t_ctx, 'subnet', _id)
if not t_subnet:
raise q_exceptions.SubnetNotFound(subnet_id=_id)
valid = self._is_valid_network(context, t_subnet['network_id'])
if not valid:
raise q_exceptions.SubnetNotFound(subnet_id=_id)
b_subnet = self._create_bottom_subnet(t_ctx, context, t_subnet)
if b_subnet['enable_dhcp']:
self._ensure_subnet_dhcp_port(t_ctx, context, b_subnet)
@ -417,6 +448,9 @@ class TricirclePlugin(plugin.Ml2Plugin):
missing_subnets = [subnet for subnet in t_subnets if (
subnet['id'] in missing_id_set)]
for subnet in missing_subnets:
valid = self._is_valid_network(context, subnet['network_id'])
if not valid:
continue
b_subnet = self._create_bottom_subnet(t_ctx, context, subnet)
if b_subnet['enable_dhcp']:
self._ensure_subnet_dhcp_port(t_ctx, context, b_subnet)

View File

@ -123,6 +123,10 @@ class FakeCorePlugin(object):
def get_subnet(self, context, _id, fields=None):
return get_resource('subnet', False, _id)
def get_subnets(self, context, filters=None, fields=None, sorts=None,
limit=None, marker=None, page_reverse=False):
return list_resource('subnet', False, filters)
def create_port(self, context, port):
create_resource('port', False, port['port'])
return port['port']
@ -181,6 +185,9 @@ class FakeClient(object):
def list_networks(self, **kwargs):
return {'networks': list_resource('network', True, kwargs)}
def list_subnets(self, **kwargs):
return {'subnets': list_resource('subnet', True, kwargs)}
def create_port(self, port):
if 'id' not in port['port']:
port['port']['id'] = uuidutils.generate_uuid()
@ -313,18 +320,28 @@ class PluginTest(unittest.TestCase):
TOP_SGS.append(t_sg)
return t_net, t_subnet, t_port, t_sg
def _validate(self, net, subnet, port):
b_net = self.plugin.get_network(self.context, net['id'])
net.pop('provider:network_type')
net.pop('availability_zone_hints')
b_net_type = b_net.pop('provider:network_type')
def _get_bottom_resources_with_net(self, net, subnet, port):
b_net = get_resource('network', False, net['id'])
b_subnet = get_resource('subnet', False, subnet['id'])
b_port = get_resource('port', False, port['id'])
b_net.pop('project_id')
return b_net, b_subnet, b_port
def _get_bottom_resources_without_net(self, subnet, port):
b_net = get_resource('network', False, subnet['network_id'])
b_subnet = get_resource('subnet', False, subnet['id'])
b_port = get_resource('port', False, port['id'])
return b_net, b_subnet, b_port
def _validate(self, b_net, b_subnet, b_port, t_net, t_subnet, t_port):
t_net.pop('provider:network_type')
t_net.pop('availability_zone_hints')
b_net_type = b_net.pop('provider:network_type')
b_subnet.pop('project_id')
pool = subnet.pop('allocation_pools')[0]
pool = t_subnet.pop('allocation_pools')[0]
b_pools = b_subnet.pop('allocation_pools')
t_gateway_ip = subnet.pop('gateway_ip')
t_gateway_ip = t_subnet.pop('gateway_ip')
b_gateway_ip = b_subnet.pop('gateway_ip')
def ip_to_digit(ip):
@ -347,13 +364,13 @@ class PluginTest(unittest.TestCase):
ip_to_digit(pool['end'])))
b_pool_range = list(range(ip_to_digit(b_pools[0]['start']),
ip_to_digit(b_pools[0]['end'])))
port.pop('name')
t_port.pop('name')
b_port.pop('name')
self.assertDictEqual(net, b_net)
self.assertDictEqual(subnet, b_subnet)
self.assertDictEqual(t_net, b_net)
self.assertDictEqual(t_subnet, b_subnet)
self.assertSetEqual(set(pool_range), set(b_pool_range))
self.assertEqual('vlan', b_net_type)
self.assertDictEqual(port, b_port)
self.assertDictEqual(t_port, b_port)
def _prepare_vm_port(self, t_net, t_subnet, index, t_sgs=[]):
port_id = uuidutils.generate_uuid()
@ -372,16 +389,39 @@ class PluginTest(unittest.TestCase):
TOP_PORTS.append(t_port)
return t_port
@patch.object(t_context, 'get_context_from_neutron_context', new=mock.Mock)
def test_get_subnet_no_bottom_network(self):
t_net, t_subnet, t_port, _ = self._prepare_resource()
self.plugin.get_subnet(self.context, t_subnet['id'])
b_net, b_subnet, b_port = self._get_bottom_resources_without_net(
t_subnet, t_port)
self._validate(b_net, b_subnet, b_port, t_net, t_subnet, t_port)
@patch.object(t_context, 'get_context_from_neutron_context', new=mock.Mock)
def test_get_subnet(self):
t_net, t_subnet, t_port, _ = self._prepare_resource()
self.plugin.get_network(self.context, t_net['id'])
self.plugin.get_subnet(self.context, t_subnet['id'])
b_net, b_subnet, b_port = self._get_bottom_resources_with_net(
t_net, t_subnet, t_port)
self._validate(b_net, b_subnet, b_port, t_net, t_subnet, t_port)
@patch.object(t_context, 'get_context_from_neutron_context', new=mock.Mock)
def test_get_network(self):
t_net, t_subnet, t_port, _ = self._prepare_resource()
self._validate(t_net, t_subnet, t_port)
self.plugin.get_network(self.context, t_net['id'])
b_net, b_subnet, b_port = self._get_bottom_resources_with_net(
t_net, t_subnet, t_port)
self._validate(b_net, b_subnet, b_port, t_net, t_subnet, t_port)
@patch.object(t_context, 'get_context_from_neutron_context', new=mock.Mock)
def test_get_network_no_gateway(self):
t_net, t_subnet, t_port, _ = self._prepare_resource()
update_resource('subnet', True, t_subnet['id'], {'gateway_ip': None})
self._validate(t_net, t_subnet, t_port)
self.plugin.get_network(self.context, t_net['id'])
b_net, b_subnet, b_port = self._get_bottom_resources_with_net(
t_net, t_subnet, t_port)
self._validate(b_net, b_subnet, b_port, t_net, t_subnet, t_port)
@patch.object(t_context, 'get_context_from_neutron_context', new=mock.Mock)
@patch.object(client.Client, 'get_admin_token', new=mock.Mock)
@ -393,8 +433,12 @@ class PluginTest(unittest.TestCase):
self.plugin.get_networks(self.context,
{'id': [t_net1['id'], t_net2['id'],
'fake_net_id']})
self._validate(t_net1, t_subnet1, t_port1)
self._validate(t_net2, t_subnet2, t_port2)
b_net1, b_subnet1, b_port1 = self._get_bottom_resources_with_net(
t_net1, t_subnet1, t_port1)
b_net2, b_subnet2, b_port2 = self._get_bottom_resources_with_net(
t_net2, t_subnet2, t_port2)
self._validate(b_net1, b_subnet1, b_port1, t_net1, t_subnet1, t_port1)
self._validate(b_net2, b_subnet2, b_port2, t_net2, t_subnet2, t_port2)
@patch.object(t_context, 'get_context_from_neutron_context', new=mock.Mock)
@patch.object(client.Client, 'get_admin_token', new=mock.Mock)
@ -408,6 +452,35 @@ class PluginTest(unittest.TestCase):
nets = self.plugin.get_networks(self.context, net_filter)
six.assertCountEqual(self, nets, [])
@patch.object(t_context, 'get_context_from_neutron_context', new=mock.Mock)
@patch.object(client.Client, 'get_admin_token', new=mock.Mock)
def test_get_subnets(self):
az_hints = ['Pod1', 'Pod2']
t_net1, t_subnet1, t_port1, _ = self._prepare_resource()
t_net2, t_subnet2, t_port2, _ = self._prepare_resource(az_hints)
cfg.CONF.set_override('region_name', 'Pod1', 'nova')
self.plugin.get_subnets(self.context,
{'id': [t_subnet1['id'], t_subnet2['id'],
'fake_net_id']})
b_net1, b_subnet1, b_port1 = self._get_bottom_resources_without_net(
t_subnet1, t_port1)
b_net2, b_subnet2, b_port2 = self._get_bottom_resources_without_net(
t_subnet2, t_port2)
self._validate(b_net1, b_subnet1, b_port1, t_net1, t_subnet1, t_port1)
self._validate(b_net2, b_subnet2, b_port2, t_net2, t_subnet2, t_port2)
@patch.object(t_context, 'get_context_from_neutron_context', new=mock.Mock)
@patch.object(client.Client, 'get_admin_token', new=mock.Mock)
def test_get_invaild_subnets(self):
az_hints = ['Pod2', 'Pod3']
t_net1, t_subnet1, t_port1, _ = self._prepare_resource(az_hints)
cfg.CONF.set_override('region_name', 'Pod1', 'nova')
net_filter = {
'id': [t_subnet1.get('id')]
}
subnets = self.plugin.get_subnets(self.context, net_filter)
six.assertCountEqual(self, subnets, [])
@patch.object(t_context, 'get_context_from_neutron_context', new=mock.Mock)
def test_create_port(self):
t_net, t_subnet, t_port, _ = self._prepare_resource()