Get rid of DVR inheritance of _delete_current_gw_port

Switch to a callback based approach for cleaning up the
distributed resources for a router gateway. This maintains
the current transactional semantics and gets us closer
to eliminating the use of mixins for DVR.

Change-Id: I1d17706652811383d4bc968812d5cd6526febc4b
This commit is contained in:
Kevin Benton 2016-11-19 22:30:22 -07:00
parent b8347e16d1
commit f6df76cc82
3 changed files with 55 additions and 51 deletions

View File

@ -382,32 +382,36 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
if self.router_gw_port_has_floating_ips(admin_ctx, router_id):
raise l3.RouterExternalGatewayInUseByFloatingIp(
router_id=router_id, net_id=router.gw_port['network_id'])
gw_ips = [x['ip_address'] for x in router.gw_port.fixed_ips]
gw_ips = [x['ip_address'] for x in router.gw_port['fixed_ips']]
gw_port_id = router.gw_port['id']
self._delete_router_gw_port_db(context, router)
self._core_plugin.delete_port(
admin_ctx, gw_port_id, l3_port_check=False)
registry.notify(resources.ROUTER_GATEWAY,
events.AFTER_DELETE, self,
router_id=router_id,
context=context,
router=router,
network_id=old_network_id,
gateway_ips=gw_ips)
def _delete_router_gw_port_db(self, context, router):
with context.session.begin(subtransactions=True):
gw_port = router.gw_port
router.gw_port = None
context.session.add(router)
context.session.expire(gw_port)
self._check_router_gw_port_in_use(context, router_id)
self._core_plugin.delete_port(
admin_ctx, gw_port['id'], l3_port_check=False)
registry.notify(resources.ROUTER_GATEWAY,
events.AFTER_DELETE, self,
router_id=router_id,
network_id=old_network_id,
gateway_ips=gw_ips)
def _check_router_gw_port_in_use(self, context, router_id):
try:
kwargs = {'context': context, 'router_id': router_id}
registry.notify(
resources.ROUTER_GATEWAY, events.BEFORE_DELETE, self, **kwargs)
except exceptions.CallbackFailure as e:
with excutils.save_and_reraise_exception():
# NOTE(armax): preserve old check's behavior
if len(e.errors) == 1:
raise e.errors[0].error
raise l3.RouterInUse(router_id=router_id, reason=e)
try:
kwargs = {'context': context, 'router_id': router.id}
registry.notify(
resources.ROUTER_GATEWAY, events.BEFORE_DELETE, self,
**kwargs)
except exceptions.CallbackFailure as e:
with excutils.save_and_reraise_exception():
# NOTE(armax): preserve old check's behavior
if len(e.errors) == 1:
raise e.errors[0].error
raise l3.RouterInUse(router_id=router.id, reason=e)
def _create_gw_port(self, context, router_id, router, new_network_id,
ext_ips):

View File

@ -77,6 +77,8 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
resources.ROUTER, events.AFTER_UPDATE)
registry.subscribe(n._create_snat_interfaces_after_change,
resources.ROUTER, events.AFTER_CREATE)
registry.subscribe(n._delete_dvr_internal_ports,
resources.ROUTER_GATEWAY, events.AFTER_DELETE)
return n
def _create_router_db(self, context, router, tenant_id):
@ -173,39 +175,33 @@ class L3_NAT_with_dvr_db_mixin(l3_db.L3_NAT_db_mixin,
router_db['id'])
return router_db
def _delete_current_gw_port(self, context, router_id, router, new_network):
def _delete_dvr_internal_ports(self, event, trigger, resource,
context, router, network_id, **kwargs):
"""
Overridden here to handle deletion of dvr internal ports.
GW port AFTER_DELETE event handler to cleanup DVR ports.
If there is a valid router update with gateway port to be deleted,
then go ahead and delete the csnat ports and the floatingip
This event is emitted when a router gateway port is being deleted,
so go ahead and delete the csnat ports and the floatingip
agent gateway port associated with the dvr router.
"""
gw_ext_net_id = (
router.gw_port['network_id'] if router.gw_port else None)
super(L3_NAT_with_dvr_db_mixin,
self)._delete_current_gw_port(context, router_id,
router, new_network)
if (is_distributed_router(router) and
gw_ext_net_id != new_network and gw_ext_net_id is not None):
self.delete_csnat_router_interface_ports(
context.elevated(), router)
# NOTE(Swami): Delete the Floatingip agent gateway port
# on all hosts when it is the last gateway port in the
# given external network.
filters = {'network_id': [gw_ext_net_id],
'device_owner': [const.DEVICE_OWNER_ROUTER_GW]}
ext_net_gw_ports = self._core_plugin.get_ports(
context.elevated(), filters)
if not ext_net_gw_ports:
self.delete_floatingip_agent_gateway_port(
context.elevated(), None, gw_ext_net_id)
# Send the information to all the L3 Agent hosts
# to clean up the fip namespace as it is no longer required.
self.l3_rpc_notifier.delete_fipnamespace_for_ext_net(
context, gw_ext_net_id)
if not is_distributed_router(router):
return
self.delete_csnat_router_interface_ports(context.elevated(), router)
# NOTE(Swami): Delete the Floatingip agent gateway port
# on all hosts when it is the last gateway port in the
# given external network.
filters = {'network_id': [network_id],
'device_owner': [const.DEVICE_OWNER_ROUTER_GW]}
ext_net_gw_ports = self._core_plugin.get_ports(
context.elevated(), filters)
if not ext_net_gw_ports:
self.delete_floatingip_agent_gateway_port(
context.elevated(), None, network_id)
# Send the information to all the L3 Agent hosts
# to clean up the fip namespace as it is no longer required.
self.l3_rpc_notifier.delete_fipnamespace_for_ext_net(
context, network_id)
def _get_device_owner(self, context, router=None):
"""Get device_owner for the specified router."""

View File

@ -303,7 +303,8 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
gw_port_db = {
'id': 'my_gw_id',
'network_id': 'ext_net_id',
'device_owner': const.DEVICE_OWNER_ROUTER_GW
'device_owner': const.DEVICE_OWNER_ROUTER_GW,
'fixed_ips': [{'ip_address': '1.2.3.4'}]
}
router.gw_port = gw_port_db
else:
@ -312,7 +313,10 @@ class L3DvrTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
plugin = mock.Mock()
directory.add_plugin(const.CORE, plugin)
with mock.patch.object(l3_dvr_db.l3_db.L3_NAT_db_mixin,
'_delete_current_gw_port'),\
'router_gw_port_has_floating_ips',
return_value=False),\
mock.patch.object(l3_dvr_db.l3_db.L3_NAT_db_mixin,
'_delete_router_gw_port_db'),\
mock.patch.object(
self.mixin,
'_get_router') as grtr,\