From 2c90bf558825034a998750f8029defcebc4bb45c Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Thu, 7 Mar 2013 13:51:15 +0100 Subject: [PATCH] Ensure metadata access network does not prevent router deletion Bug 1152136 This patch checks if a metadata access network is still present when removing a router in the NVP plugin. If yes, the network is detached from the router and then destroyed, thus ensuring a safe completion of the operation as well as removal of metadata access network resources. Change-Id: Id8be6ec50ab4536f4ae9916dadaed56644597c7c --- .../nicira/nicira_nvp_plugin/QuantumPlugin.py | 13 ++++++++----- .../nicira_nvp_plugin/common/metadata_access.py | 10 +++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/quantum/plugins/nicira/nicira_nvp_plugin/QuantumPlugin.py b/quantum/plugins/nicira/nicira_nvp_plugin/QuantumPlugin.py index 5c66047a8..3e3f4f0bf 100644 --- a/quantum/plugins/nicira/nicira_nvp_plugin/QuantumPlugin.py +++ b/quantum/plugins/nicira/nicira_nvp_plugin/QuantumPlugin.py @@ -1593,6 +1593,11 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2, def delete_router(self, context, id): with context.session.begin(subtransactions=True): + # Ensure metadata access network is detached and destroyed + # This will also destroy relevant objects on NVP platform. + # NOTE(salvatore-orlando): A failure in this operation will + # cause the router delete operation to fail too. + self._handle_metadata_access_network(context, id, do_create=False) super(NvpPluginV2, self).delete_router(context, id) # If removal is successful in Quantum it should be so on # the NVP platform too - otherwise the transaction should @@ -1779,6 +1784,7 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2, results = nvplib.query_lswitch_lports( cluster, '*', relations="LogicalPortAttachment", filters={'tag': port_id, 'tag_scope': 'q_port_id'}) + lrouter_port_id = None if len(results): lport = results[0] attachment_data = lport['_relations'].get('LogicalPortAttachment') @@ -1799,11 +1805,8 @@ class NvpPluginV2(db_base_plugin_v2.QuantumDbPluginV2, # to leverage validation performed in the base class if not lrouter_port_id: LOG.warning(_("Unable to find NVP logical router port for " - "Quantum port id:%(q_port_id)s (NVP id: " - "%(nvp_port_id)s). Was this port " - "ever paired with a logical router?"), - {'q_port_id': port_id, - 'nvp_port_id': lport['uuid']}) + "Quantum port id:%s. Was this port ever paired " + "with a logical router?"), port_id) return # Ensure the connection to the 'metadata access network' diff --git a/quantum/plugins/nicira/nicira_nvp_plugin/common/metadata_access.py b/quantum/plugins/nicira/nicira_nvp_plugin/common/metadata_access.py index 81fdf66e5..2efd0bc74 100644 --- a/quantum/plugins/nicira/nicira_nvp_plugin/common/metadata_access.py +++ b/quantum/plugins/nicira/nicira_nvp_plugin/common/metadata_access.py @@ -113,7 +113,8 @@ class NvpMetadataAccess(object): {'network': {'id': meta_net_id}}, 'network.delete.end') - def _handle_metadata_access_network(self, context, router_id): + def _handle_metadata_access_network(self, context, router_id, + do_create=True): if not cfg.CONF.NVP.enable_metadata_access_network: LOG.debug(_("Metadata access network is disabled")) return @@ -128,13 +129,16 @@ class NvpMetadataAccess(object): 'device_owner': [l3_db.DEVICE_OWNER_ROUTER_INTF]} with ctx_elevated.session.begin(subtransactions=True): ports = self.get_ports(ctx_elevated, filters=device_filter) + # Filter out ports without an IP (those are 'stale' router ports) + ports = [port for port in ports if port['fixed_ips']] try: if ports: - if not self._find_metadata_port(ctx_elevated, ports): + if (do_create and + not self._find_metadata_port(ctx_elevated, ports)): self._create_metadata_access_network(context, router_id) elif len(ports) == 1: - # The only port left if the metadata port + # The only port left is the metadata port self._destroy_metadata_access_network(context, router_id, ports) -- 2.45.2