make delete_router send delete_port to core_plugin

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
This commit is contained in:
mathieu-rohon 2015-01-15 16:19:08 +01:00
parent eaaad83e92
commit 1e00041b0b
4 changed files with 24 additions and 32 deletions

View 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):
#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()
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):
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)
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)
context.session.delete(router)
def get_router(self, context, id, fields=None):

View 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):

View 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."""

View 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