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:
parent
b8347e16d1
commit
f6df76cc82
|
@ -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):
|
||||
|
|
|
@ -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."""
|
||||
|
|
|
@ -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,\
|
||||
|
|
Loading…
Reference in New Issue