]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Ensure metadata access network does not prevent router deletion
authorSalvatore Orlando <salv.orlando@gmail.com>
Thu, 7 Mar 2013 12:51:15 +0000 (13:51 +0100)
committerSalvatore Orlando <salv.orlando@gmail.com>
Fri, 8 Mar 2013 23:23:29 +0000 (00:23 +0100)
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

quantum/plugins/nicira/nicira_nvp_plugin/QuantumPlugin.py
quantum/plugins/nicira/nicira_nvp_plugin/common/metadata_access.py

index 5c66047a88088cd7b8563c773566258a79e37f82..3e3f4f0bf1307e3fe0119464a33bdf1f55a0af83 100644 (file)
@@ -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'
index 81fdf66e54939da27bf0d0d4440c77c591933b29..2efd0bc74da24e5e5a2808dcabdc84a82259b59d 100644 (file)
@@ -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)