Ensure port get works when NVP mapping not stored in Quantum DB
Bug 1153616 If the entry for the mapping between a quantum and a NVP port identifier is not found in the Quantum DB, search the port on NVP, and, if found, add the mapping entry. This ensures upgraded folsom databases keep working with Grizzly code. Change-Id: I74943e8271f522dcd21c1c34b0159dd61bb66e76
This commit is contained in:
parent
45d197d7b1
commit
55ebefa0e7
@ -508,17 +508,18 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
"external networks. Port %s will be down."),
|
||||
port_data['network_id'])
|
||||
return
|
||||
|
||||
port = nicira_db.get_nvp_port_id(context.session, port_data['id'])
|
||||
if port is None:
|
||||
raise q_exc.PortNotFound(port_id=port_data['id'])
|
||||
nvp_port_id = self._nvp_get_port_id(context, self.default_cluster,
|
||||
port_data)
|
||||
if not nvp_port_id:
|
||||
LOG.debug(_("Port '%s' was already deleted on NVP platform"), id)
|
||||
return
|
||||
# TODO(bgh): if this is a bridged network and the lswitch we just got
|
||||
# back will have zero ports after the delete we should garbage collect
|
||||
# the lswitch.
|
||||
try:
|
||||
nvplib.delete_port(self.default_cluster,
|
||||
port_data['network_id'],
|
||||
port)
|
||||
nvp_port_id)
|
||||
LOG.debug(_("_nvp_delete_port completed for port %(port_id)s "
|
||||
"on network %(net_id)s"),
|
||||
{'port_id': port_data['id'],
|
||||
@ -530,8 +531,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
def _nvp_delete_router_port(self, context, port_data):
|
||||
# Delete logical router port
|
||||
lrouter_id = port_data['device_id']
|
||||
nvp_port_id = nicira_db.get_nvp_port_id(context.session,
|
||||
port_data['id'])
|
||||
nvp_port_id = self._nvp_get_port_id(context, self.default_cluster,
|
||||
port_data)
|
||||
if not nvp_port_id:
|
||||
raise q_exc.PortNotFound(port_id=port_data['id'])
|
||||
|
||||
@ -738,6 +739,31 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
# this is a no-op driver
|
||||
pass
|
||||
|
||||
def _nvp_get_port_id(self, context, cluster, quantum_port):
|
||||
""" Return the NVP port uuid for a given quantum port.
|
||||
First, look up the Quantum database. If not found, execute
|
||||
a query on NVP platform as the mapping might be missing because
|
||||
the port was created before upgrading to grizzly. """
|
||||
nvp_port_id = nicira_db.get_nvp_port_id(context.session,
|
||||
quantum_port['id'])
|
||||
if nvp_port_id:
|
||||
return nvp_port_id
|
||||
# Perform a query to NVP and then update the DB
|
||||
try:
|
||||
nvp_port = nvplib.get_port_by_quantum_tag(
|
||||
cluster,
|
||||
quantum_port['network_id'],
|
||||
quantum_port['id'])
|
||||
if nvp_port:
|
||||
nicira_db.add_quantum_nvp_port_mapping(
|
||||
context.session,
|
||||
quantum_port['id'],
|
||||
nvp_port['uuid'])
|
||||
return nvp_port['uuid']
|
||||
except:
|
||||
LOG.exception(_("Unable to find NVP uuid for Quantum port %s"),
|
||||
quantum_port['id'])
|
||||
|
||||
def _extend_fault_map(self):
|
||||
""" Extends the Quantum Fault Map
|
||||
|
||||
@ -969,8 +995,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
'device_owner': ['network:router_interface']}
|
||||
router_iface_ports = self.get_ports(context, filters=port_filter)
|
||||
for port in router_iface_ports:
|
||||
nvp_port_id = nicira_db.get_nvp_port_id(context.session,
|
||||
port['id'])
|
||||
nvp_port_id = self._nvp_get_port_id(
|
||||
context, self.default_cluster, port)
|
||||
if nvp_port_id:
|
||||
port['nvp_port_id'] = nvp_port_id
|
||||
else:
|
||||
@ -1408,7 +1434,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
self._extend_port_port_security_dict(context, ret_port)
|
||||
self._extend_port_dict_security_group(context, ret_port)
|
||||
LOG.debug(_("Update port request: %s"), port)
|
||||
nvp_port_id = nicira_db.get_nvp_port_id(context.session, id)
|
||||
nvp_port_id = self._nvp_get_port_id(
|
||||
context, self.default_cluster, ret_port)
|
||||
nvplib.update_port(self.default_cluster,
|
||||
ret_port['network_id'],
|
||||
nvp_port_id, id, tenant_id,
|
||||
@ -1483,20 +1510,26 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2,
|
||||
if self._network_is_external(context,
|
||||
quantum_db_port['network_id']):
|
||||
return quantum_db_port
|
||||
|
||||
nvp_id = nicira_db.get_nvp_port_id(context.session, id)
|
||||
#TODO: pass the appropriate cluster here
|
||||
try:
|
||||
port = nvplib.get_logical_port_status(
|
||||
self.default_cluster, quantum_db_port['network_id'],
|
||||
nvp_id)
|
||||
quantum_db_port["admin_state_up"] = (
|
||||
port["admin_status_enabled"])
|
||||
if port["fabric_status_up"]:
|
||||
quantum_db_port["status"] = constants.PORT_STATUS_ACTIVE
|
||||
else:
|
||||
quantum_db_port["status"] = constants.PORT_STATUS_DOWN
|
||||
except q_exc.NotFound:
|
||||
nvp_id = self._nvp_get_port_id(context, self.default_cluster,
|
||||
quantum_db_port)
|
||||
# If there's no nvp IP do not bother going to NVP and put
|
||||
# the port in error state
|
||||
if nvp_id:
|
||||
#TODO: pass the appropriate cluster here
|
||||
try:
|
||||
port = nvplib.get_logical_port_status(
|
||||
self.default_cluster, quantum_db_port['network_id'],
|
||||
nvp_id)
|
||||
quantum_db_port["admin_state_up"] = (
|
||||
port["admin_status_enabled"])
|
||||
if port["fabric_status_up"]:
|
||||
quantum_db_port["status"] = (
|
||||
constants.PORT_STATUS_ACTIVE)
|
||||
else:
|
||||
quantum_db_port["status"] = constants.PORT_STATUS_DOWN
|
||||
except q_exc.NotFound:
|
||||
quantum_db_port["status"] = constants.PORT_STATUS_ERROR
|
||||
else:
|
||||
quantum_db_port["status"] = constants.PORT_STATUS_ERROR
|
||||
return quantum_db_port
|
||||
|
||||
|
@ -677,6 +677,36 @@ def get_port_by_display_name(clusters, lswitch, display_name):
|
||||
raise exception.PortNotFound(port_id=display_name, net_id=lswitch)
|
||||
|
||||
|
||||
def get_port_by_quantum_tag(cluster, lswitch_uuid, quantum_port_id):
|
||||
"""Return the NVP UUID of the logical port with tag q_port_id
|
||||
equal to quantum_port_id or None if the port is not Found.
|
||||
"""
|
||||
uri = _build_uri_path(LSWITCHPORT_RESOURCE,
|
||||
parent_resource_id=lswitch_uuid,
|
||||
fields='uuid',
|
||||
filters={'tag': quantum_port_id,
|
||||
'tag_scope': 'q_port_id'})
|
||||
LOG.debug(_("Looking for port with q_port_id tag '%(quantum_port_id)s' "
|
||||
"on: '%(lswitch_uuid)s'") %
|
||||
{'quantum_port_id': quantum_port_id,
|
||||
'lswitch_uuid': lswitch_uuid})
|
||||
try:
|
||||
res_obj = do_single_request(HTTP_GET, uri, cluster=cluster)
|
||||
except Exception:
|
||||
LOG.exception(_("An exception occurred while querying NVP ports"))
|
||||
raise
|
||||
res = json.loads(res_obj)
|
||||
num_results = len(res["results"])
|
||||
if num_results >= 1:
|
||||
if num_results > 1:
|
||||
LOG.warn(_("Found '%(num_ports)d' ports with "
|
||||
"q_port_id tag: '%(quantum_port_id)s'. "
|
||||
"Only 1 was expected.") %
|
||||
{'num_ports': num_results,
|
||||
'quantum_port_id': quantum_port_id})
|
||||
return res["results"][0]
|
||||
|
||||
|
||||
def get_port(cluster, network, port, relations=None):
|
||||
LOG.info(_("get_port() %(network)s %(port)s"), locals())
|
||||
uri = "/ws.v1/lswitch/" + network + "/lport/" + port + "?"
|
||||
|
@ -177,3 +177,30 @@ class NvplibL2GatewayTestCase(NvplibTestCase):
|
||||
self.assertIn('LogicalPortAttachment', resp_obj)
|
||||
self.assertEqual(resp_obj['LogicalPortAttachment']['type'],
|
||||
'L2GatewayAttachment')
|
||||
|
||||
|
||||
class TestNvpLibLogicalPorts(NvplibTestCase):
|
||||
|
||||
def test_get_port_by_tag(self):
|
||||
tenant_id = 'pippo'
|
||||
quantum_port_id = 'whatever'
|
||||
lswitch = nvplib.create_lswitch(self.fake_cluster, tenant_id,
|
||||
'fake-switch')
|
||||
lport = nvplib.create_lport(self.fake_cluster, lswitch['uuid'],
|
||||
tenant_id, quantum_port_id,
|
||||
'name', 'device_id', True)
|
||||
lport2 = nvplib.get_port_by_quantum_tag(self.fake_cluster,
|
||||
lswitch['uuid'],
|
||||
quantum_port_id)
|
||||
self.assertIsNotNone(lport2)
|
||||
self.assertEqual(lport['uuid'], lport2['uuid'])
|
||||
|
||||
def test_get_port_by_tag_not_found_returns_None(self):
|
||||
tenant_id = 'pippo'
|
||||
quantum_port_id = 'whatever'
|
||||
lswitch = nvplib.create_lswitch(self.fake_cluster, tenant_id,
|
||||
'fake-switch')
|
||||
lport = nvplib.get_port_by_quantum_tag(self.fake_cluster,
|
||||
lswitch['uuid'],
|
||||
quantum_port_id)
|
||||
self.assertIsNone(lport)
|
||||
|
Loading…
x
Reference in New Issue
Block a user