use payloads for ROUTER_GATEWAY events

This patch switches the code over to the payload style of callbacks [1]
for PORT ROUTER_GATEWAY events for those that are not using them yet.
The unit tests are also updated where needed to account for the
payload style callbacks and publish() method. Finally the patch
normalizes the passing of gateway IPs which are currently referred to
as 'gw_ips' and 'gateway_ips' depending on the event; now all events use
'gateway_ips'.

NeutronLibImpact

[1] https://docs.openstack.org/neutron-lib/latest/contributor/callbacks.html

Change-Id: Iacd9e2d00838b402c8ab385044a7e294831a1ddc
This commit is contained in:
Boden R 2019-02-20 07:29:00 -07:00 committed by ushen
parent 86feb7916b
commit 42c4b1e087
4 changed files with 61 additions and 45 deletions

View File

@ -432,14 +432,16 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
admin_ctx, gw_port_id, l3_port_check=False)
with context.session.begin(subtransactions=True):
context.session.refresh(router)
registry.notify(resources.ROUTER_GATEWAY,
events.AFTER_DELETE, self,
router_id=router_id,
context=context,
router=router,
network_id=old_network_id,
new_network_id=new_network_id,
gateway_ips=gw_ips)
# TODO(boden): normalize metadata
metadata = {'network_id': old_network_id,
'new_network_id': new_network_id,
'gateway_ips': gw_ips}
registry.publish(resources.ROUTER_GATEWAY,
events.AFTER_DELETE, self,
payload=events.DBEventPayload(
context, states=(router,),
metadata=metadata,
resource_id=router_id))
def _delete_router_gw_port_db(self, context, router):
with context.session.begin(subtransactions=True):
@ -468,11 +470,14 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
subnets = self._core_plugin.get_subnets_by_network(context,
new_network_id)
try:
kwargs = {'context': context, 'router_id': router_id,
'network_id': new_network_id, 'subnets': subnets}
registry.notify(
registry.publish(
resources.ROUTER_GATEWAY, events.BEFORE_CREATE, self,
**kwargs)
payload=events.DBEventPayload(
context, request_body=router,
metadata={
'network_id': new_network_id,
'subnets': subnets},
resource_id=router_id))
except exceptions.CallbackFailure as e:
# raise the underlying exception
raise e.errors[0].error
@ -486,13 +491,14 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
gw_ips = [x['ip_address'] for x in router.gw_port['fixed_ips']]
registry.notify(resources.ROUTER_GATEWAY,
events.AFTER_CREATE,
self._create_gw_port,
context=context,
gw_ips=gw_ips,
network_id=new_network_id,
router_id=router_id)
registry.publish(resources.ROUTER_GATEWAY,
events.AFTER_CREATE,
self._create_gw_port,
payload=events.DBEventPayload(
context, states=(router,),
metadata={'gateway_ips': gw_ips,
'network_id': new_network_id},
resource_id=router_id))
def _update_current_gw_port(self, context, router_id, router, ext_ips):
self._core_plugin.update_port(context, router.gw_port['id'], {'port':

View File

@ -317,8 +317,7 @@ class DVRResourceOperationHandler(object):
@registry.receives(resources.ROUTER_GATEWAY, [events.AFTER_DELETE])
def _delete_dvr_internal_ports(self, event, trigger, resource,
context, router, network_id,
new_network_id, **kwargs):
payload=None):
"""GW port AFTER_DELETE event handler to cleanup DVR ports.
This event is emitted when a router gateway port is being deleted,
@ -326,25 +325,27 @@ class DVRResourceOperationHandler(object):
agent gateway port associated with the dvr router.
"""
if not is_distributed_router(router):
if not is_distributed_router(payload.latest_state):
return
if not new_network_id:
self.delete_csnat_router_interface_ports(context.elevated(),
router)
if not payload.metadata.get('new_network_id'):
self.delete_csnat_router_interface_ports(
payload.context.elevated(), payload.latest_state)
network_id = payload.metadata.get('network_id')
# 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)
payload.context.elevated(), filters)
if not ext_net_gw_ports:
self.delete_floatingip_agent_gateway_port(
context.elevated(), None, network_id)
payload.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.l3plugin.l3_rpc_notifier.delete_fipnamespace_for_ext_net(
context, network_id)
payload.context, network_id)
def delete_floatingip_agent_gateway_port(self, context, host_id,
ext_net_id):

View File

@ -304,7 +304,7 @@ class TestL3_NAT_dbonly_mixin(base.BaseTestCase):
return_value=gw_port), \
mock.patch.object(ctx.session, 'add'), \
mock.patch.object(base_obj.NeutronDbObject, 'create'), \
mock.patch.object(l3_db.registry, 'notify') as mock_notify:
mock.patch.object(l3_db.registry, 'publish') as mock_notify:
self.db._create_gw_port(ctx, router_id=router_id,
router=router,
@ -316,10 +316,14 @@ class TestL3_NAT_dbonly_mixin(base.BaseTestCase):
self.assertTrue(cfdrs.called)
mock_notify.assert_called_with(
resources.ROUTER_GATEWAY, events.AFTER_CREATE,
self.db._create_gw_port, context=ctx,
gw_ips=expected_gw_ips, network_id=new_network_id,
router_id=router_id
)
self.db._create_gw_port, payload=mock.ANY)
cb_payload = mock_notify.mock_calls[1][2]['payload']
self.assertEqual(ctx, cb_payload.context)
self.assertEqual(expected_gw_ips,
cb_payload.metadata.get('gateway_ips'))
self.assertEqual(new_network_id,
cb_payload.metadata.get('network_id'))
self.assertEqual(router_id, cb_payload.resource_id)
class L3_NAT_db_mixin(base.BaseTestCase):

View File

@ -1969,7 +1969,7 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
with self.router() as r:
with self.network() as n:
self._set_net_external(n['network']['id'])
with mock.patch.object(registry, 'notify') as notify:
with mock.patch.object(registry, 'publish') as notify:
errors = [
exceptions.NotificationError(
'foo_callback_id',
@ -1983,20 +1983,21 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
notify.assert_called_once_with(
resources.ROUTER_GATEWAY,
events.BEFORE_CREATE,
mock.ANY,
context=mock.ANY,
router_id=r['router']['id'],
network_id=n['network']['id'],
subnets=[])
mock.ANY, payload=mock.ANY)
payload = notify.mock_calls[0][2]['payload']
self.assertEqual(r['router']['id'], payload.resource_id)
self.assertEqual(n['network']['id'],
payload.metadata.get('network_id'))
self.assertEqual([], payload.metadata.get('subnets'))
def test_router_add_gateway_notifications(self):
call_count_total = 3
call_count_total = 4
with self.router() as r:
with self.network() as n:
with self.subnet(network=n) as s:
self._set_net_external(n['network']['id'])
with mock.patch.object(registry, 'notify') as notify:
with mock.patch.object(registry, 'publish') as notify:
res = self._add_external_gateway_to_router(
r['router']['id'], n['network']['id'],
ext_ips=[{'subnet_id': s['subnet']['id'],
@ -2010,11 +2011,15 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
expected = [mock.call(
resources.ROUTER_GATEWAY,
events.AFTER_CREATE, mock.ANY,
context=mock.ANY,
gw_ips=expected_gw_ips,
network_id=n['network']['id'],
router_id=r['router']['id'])]
payload=mock.ANY)]
notify.assert_has_calls(expected)
payload = notify.mock_calls[1][2]['payload']
self.assertEqual(r['router']['id'],
payload.resource_id)
self.assertEqual(n['network']['id'],
payload.metadata.get('network_id'))
self.assertEqual(expected_gw_ips,
payload.metadata.get('gateway_ips'))
def test_router_remove_interface_inuse_returns_409(self):
with self.router() as r: