]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
make delete_router send delete_port to core_plugin
authormathieu-rohon <mathieu.rohon@gmail.com>
Thu, 15 Jan 2015 15:19:08 +0000 (16:19 +0100)
committermathieu-rohon <mathieu.rohon@gmail.com>
Thu, 15 Jan 2015 15:19:08 +0000 (16:19 +0100)
Have delete_router API call also delete the gateway port if needed.
Currently, the db_base_plugin_v2 method is called, bypassing the
core_plugin overload of this method. The consequence is that,
in ML2, mechanism drivers are not aware of the port deletion.

In this patch, tha gateway port is deleted through a common
method. This method checks if floating IP and VPN are attached
to the router, so those checks are removed from the delete_router
method.

Closes-Bug: #1361540

Change-Id: Iae98f3fe89126a76f16ed9c5230ce299a09ce8d8

neutron/db/l3_db.py
neutron/plugins/bigswitch/l3_router_plugin.py
neutron/plugins/vmware/plugins/base.py
neutron/tests/unit/vmware/apiclient/fake.py

index 0ef0b89e5f6de3116df94ebfb1a2a67906772f70..c45df499f42d4bf3359e485c68c55acce24dce94 100644 (file)
@@ -395,11 +395,10 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase):
         return ip_address_change
 
     def _ensure_router_not_in_use(self, context, router_id):
-        admin_ctx = context.elevated()
+        """Ensure that no internal network interface is attached
+        to the router.
+        """
         router = self._get_router(context, router_id)
-        if self.get_floatingips_count(
-            admin_ctx, filters={'router_id': [router_id]}):
-            raise l3.RouterInUse(router_id=router_id)
         device_owner = self._get_device_owner(context, router)
         if any(rp.port_type == device_owner
                for rp in router.attached_ports.all()):
@@ -407,20 +406,17 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase):
         return router
 
     def delete_router(self, context, id):
-        with context.session.begin(subtransactions=True):
-            router = self._ensure_router_not_in_use(context, id)
 
-            #TODO(nati) Refactor here when we have router insertion model
-            vpnservice = manager.NeutronManager.get_service_plugins().get(
-                constants.VPN)
-            if vpnservice:
-                vpnservice.check_router_in_use(context, id)
+        #TODO(nati) Refactor here when we have router insertion model
+        router = self._ensure_router_not_in_use(context, id)
+        self._delete_current_gw_port(context, id, router, None, False)
 
-            router_ports = router.attached_ports.all()
-            # Set the router's gw_port to None to avoid a constraint violation.
-            router.gw_port = None
-            for rp in router_ports:
-                self._core_plugin._delete_port(context.elevated(), rp.port.id)
+        router_ports = router.attached_ports.all()
+        for rp in router_ports:
+            self._core_plugin.delete_port(context.elevated(),
+                                          rp.port.id,
+                                          l3_port_check=False)
+        with context.session.begin(subtransactions=True):
             context.session.delete(router)
 
     def get_router(self, context, id, fields=None):
index ff5193d522c3172396d3a9941e1dca46b179ce74..c96bbe5f2c5ec1c003fee52f08e9461436e1fd60 100644 (file)
@@ -28,7 +28,6 @@ from oslo.utils import excutils
 from neutron.api import extensions as neutron_extensions
 from neutron.common import exceptions
 from neutron.common import log
-from neutron.common import utils
 from neutron.db import l3_db
 from neutron.extensions import l3
 from neutron.i18n import _LE
@@ -108,9 +107,6 @@ class L3RestProxy(cplugin.NeutronRestProxyV2Base,
             # return updated router
             return new_router
 
-    # NOTE(kevinbenton): workaround for eventlet/mysql deadlock.
-    # delete_router ends up calling _delete_port instead of delete_port.
-    @utils.synchronized('bsn-port-barrier')
     @put_context_in_serverpool
     @log.log
     def delete_router(self, context, router_id):
index 4ca8ff11854fcef5120b349cd8b6fe38155aa09c..53a5b46f6b77f0742091e604b57697666a5b108c 100644 (file)
@@ -645,10 +645,10 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
 
     @lockutils.synchronized('vmware', 'neutron-')
     def _nsx_delete_ext_gw_port(self, context, port_data):
-        lr_port = self._find_router_gw_port(context, port_data)
         # TODO(salvatore-orlando): Handle NSX resource
         # rollback when something goes not quite as expected
         try:
+            lr_port = self._find_router_gw_port(context, port_data)
             # Delete is actually never a real delete, otherwise the NSX
             # logical router will stop working
             router_id = port_data['device_id']
@@ -668,19 +668,19 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
                 lr_port['uuid'],
                 "L3GatewayAttachment",
                 self.cluster.default_l3_gw_service_uuid)
-
-        except api_exc.ResourceNotFound:
-            raise nsx_exc.NsxPluginException(
-                err_msg=_("Logical router resource %s not found "
-                          "on NSX platform") % router_id)
+            LOG.debug("_nsx_delete_ext_gw_port completed on external network "
+                      "%(ext_net_id)s, attached to NSX router:%(router_id)s",
+                      {'ext_net_id': port_data['network_id'],
+                       'router_id': nsx_router_id})
+        except n_exc.NotFound:
+            LOG.debug("Logical router resource %s not found "
+                      "on NSX platform : the router may have "
+                      "already been deleted",
+                      port_data['device_id'])
         except api_exc.NsxApiException:
             raise nsx_exc.NsxPluginException(
                 err_msg=_("Unable to update logical router"
                           "on NSX Platform"))
-        LOG.debug("_nsx_delete_ext_gw_port completed on external network "
-                  "%(ext_net_id)s, attached to NSX router:%(router_id)s",
-                  {'ext_net_id': port_data['network_id'],
-                   'router_id': nsx_router_id})
 
     def _nsx_create_l2_gw_port(self, context, port_data):
         """Create a switch port, and attach it to a L2 gateway attachment."""
index dfe48cb9e7cf14e922da50fb70fd03fca81d1b22..0dbb69c6dc5de7bb47468570643dc2f139830e40 100644 (file)
@@ -412,7 +412,7 @@ class FakeClient:
             def _lrouter_match(res_uuid):
                 # verify that the router exist
                 if parent_uuid and parent_uuid not in self._fake_lrouter_dict:
-                    raise Exception(_("lrouter:%s not found") % parent_uuid)
+                    raise api_exc.ResourceNotFound()
                 if (not parent_uuid or
                     res_dict[res_uuid].get('lr_uuid') == parent_uuid):
                     return True