Fix retrieval of shared networks

Bug 1130171

This patch adds a new tag_scope, 'shared', in order to allow
the NVP plugin to retrieve also shared networks from NVP when
listing networks. This way it won't appear as Quantum has a
network without a corresponding lswitch in NVP

Change-Id: I24f950d54c0b9e582c92e8008e75ebd00f6c9fe3
This commit is contained in:
Salvatore Orlando 2013-01-22 08:30:02 -08:00
parent 9d44d51c3a
commit 4e17590090
3 changed files with 53 additions and 6 deletions

View File

@ -819,12 +819,13 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
main_ls = [ls for ls in lswitches if ls['uuid'] == network.id] main_ls = [ls for ls in lswitches if ls['uuid'] == network.id]
tag_dict = dict((x['scope'], x['tag']) for x in main_ls[0]['tags']) tag_dict = dict((x['scope'], x['tag']) for x in main_ls[0]['tags'])
if 'multi_lswitch' not in tag_dict: if 'multi_lswitch' not in tag_dict:
tags = main_ls[0]['tags']
tags.append({'tag': 'True', 'scope': 'multi_lswitch'})
nvplib.update_lswitch(cluster, nvplib.update_lswitch(cluster,
main_ls[0]['uuid'], main_ls[0]['uuid'],
main_ls[0]['display_name'], main_ls[0]['display_name'],
network['tenant_id'], network['tenant_id'],
tags=[{'tag': 'True', tags=tags)
'scope': 'multi_lswitch'}])
selected_lswitch = nvplib.create_lswitch( selected_lswitch = nvplib.create_lswitch(
cluster, network.tenant_id, cluster, network.tenant_id,
"%s-ext-%s" % (network.name, len(lswitches)), "%s-ext-%s" % (network.name, len(lswitches)),
@ -882,7 +883,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
target_cluster, tenant_id, net_data.get('name'), target_cluster, tenant_id, net_data.get('name'),
nvp_binding_type, nvp_binding_type,
net_data.get(pnet.PHYSICAL_NETWORK), net_data.get(pnet.PHYSICAL_NETWORK),
net_data.get(pnet.SEGMENTATION_ID)) net_data.get(pnet.SEGMENTATION_ID),
shared=net_data.get(attr.SHARED))
net_data['id'] = lswitch['uuid'] net_data['id'] = lswitch['uuid']
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
@ -1051,17 +1053,28 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
else: else:
tenant_ids = tenant_ids or [context.tenant_id] tenant_ids = tenant_ids or [context.tenant_id]
tenant_filter = ''.join(filter_fmt % tid for tid in tenant_ids) tenant_filter = ''.join(filter_fmt % tid for tid in tenant_ids)
lswitch_filters = "uuid,display_name,fabric_status,tags" lswitch_filters = "uuid,display_name,fabric_status,tags"
lswitch_url_path = ( lswitch_url_path_1 = (
"/ws.v1/lswitch?fields=%s&relations=LogicalSwitchStatus%s" "/ws.v1/lswitch?fields=%s&relations=LogicalSwitchStatus%s"
% (lswitch_filters, tenant_filter)) % (lswitch_filters, tenant_filter))
lswitch_url_path_2 = nvplib._build_uri_path(
nvplib.LSWITCH_RESOURCE,
fields=lswitch_filters,
relations='LogicalSwitchStatus',
filters={'tag': 'true', 'tag_scope': 'shared'})
try: try:
for c in self.clusters.itervalues(): for c in self.clusters.itervalues():
res = nvplib.get_all_query_pages( res = nvplib.get_all_query_pages(
lswitch_url_path, c) lswitch_url_path_1, c)
nvp_lswitches.update(dict( nvp_lswitches.update(dict(
(ls['uuid'], ls) for ls in res)) (ls['uuid'], ls) for ls in res))
# Issue a second query for fetching shared networks.
# We cannot unfortunately use just a single query because tags
# cannot be or-ed
res_shared = nvplib.get_all_query_pages(
lswitch_url_path_2, c)
nvp_lswitches.update(dict(
(ls['uuid'], ls) for ls in res_shared))
except Exception: except Exception:
err_msg = _("Unable to get logical switches") err_msg = _("Unable to get logical switches")
LOG.exception(err_msg) LOG.exception(err_msg)

View File

@ -277,6 +277,7 @@ def create_lswitch(cluster, tenant_id, display_name,
transport_zone_uuid=None, transport_zone_uuid=None,
vlan_id=None, vlan_id=None,
quantum_net_id=None, quantum_net_id=None,
shared=None,
**kwargs): **kwargs):
nvp_binding_type = transport_type nvp_binding_type = transport_type
if transport_type in ('flat', 'vlan'): if transport_type in ('flat', 'vlan'):
@ -294,6 +295,9 @@ def create_lswitch(cluster, tenant_id, display_name,
if quantum_net_id: if quantum_net_id:
lswitch_obj["tags"].append({"tag": quantum_net_id, lswitch_obj["tags"].append({"tag": quantum_net_id,
"scope": "quantum_net_id"}) "scope": "quantum_net_id"})
if shared:
lswitch_obj["tags"].append({"tag": "true",
"scope": "shared"})
if "tags" in kwargs: if "tags" in kwargs:
lswitch_obj["tags"].extend(kwargs["tags"]) lswitch_obj["tags"].extend(kwargs["tags"])
uri = _build_uri_path(LSWITCH_RESOURCE) uri = _build_uri_path(LSWITCH_RESOURCE)

View File

@ -198,6 +198,36 @@ class TestNiciraNetworksV2(test_plugin.TestNetworksV2,
self._test_list_resources('network', [net1, net2], self._test_list_resources('network', [net1, net2],
query_params=query_params) query_params=query_params)
def test_delete_network_after_removing_subet(self):
gateway_ip = '10.0.0.1'
cidr = '10.0.0.0/24'
fmt = 'json'
# Create new network
res = self._create_network(fmt=fmt, name='net',
admin_state_up=True)
network = self.deserialize(fmt, res)
subnet = self._make_subnet(fmt, network, gateway_ip,
cidr, ip_version=4)
req = self.new_delete_request('subnets', subnet['subnet']['id'])
sub_del_res = req.get_response(self.api)
self.assertEqual(sub_del_res.status_int, 204)
req = self.new_delete_request('networks', network['network']['id'])
net_del_res = req.get_response(self.api)
self.assertEqual(net_del_res.status_int, 204)
def test_list_networks_with_shared(self):
with self.network(name='net1') as net1:
with self.network(name='net2', shared=True) as net2:
req = self.new_list_request('networks')
res = self.deserialize('json', req.get_response(self.api))
self.assertEqual(len(res['networks']), 2)
req_2 = self.new_list_request('networks')
req_2.environ['quantum.context'] = context.Context('',
'somebody')
res = self.deserialize('json', req_2.get_response(self.api))
# tenant must see a single network
self.assertEqual(len(res['networks']), 1)
class NiciraPortSecurityTestCase(psec.PortSecurityDBTestCase): class NiciraPortSecurityTestCase(psec.PortSecurityDBTestCase):