From e7c61d3eba89e7b684521468c894568b4f010509 Mon Sep 17 00:00:00 2001 From: Nurmatov Mamatisa Date: Mon, 12 Jul 2021 17:59:06 +0300 Subject: [PATCH] use payloads for PORT and FLOATING_IP This patch switches over to callback payloads for PORT and FLOATING_IP PRECOMMIT_DELETE events. Change-Id: I2b3dd3ac70bcdd51125650f0a997859316ff644a --- neutron/db/l3_db.py | 9 ++-- neutron/plugins/ml2/plugin.py | 37 +++++++++-------- neutron/services/portforwarding/pf_plugin.py | 35 +++++++++------- neutron/tests/unit/plugins/ml2/test_plugin.py | 41 +++++++++++-------- 4 files changed, 71 insertions(+), 51 deletions(-) diff --git a/neutron/db/l3_db.py b/neutron/db/l3_db.py index 3b0f089f858..5f949c0ea5e 100644 --- a/neutron/db/l3_db.py +++ b/neutron/db/l3_db.py @@ -1517,11 +1517,12 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase, @registry.receives(resources.PORT, [events.PRECOMMIT_DELETE]) def _precommit_delete_port_callback( - self, resource, event, trigger, **kwargs): - if (kwargs['port']['device_owner'] == + self, resource, event, trigger, payload): + port = payload.latest_state + if (port['device_owner'] == constants.DEVICE_OWNER_FLOATINGIP): - registry.notify(resources.FLOATING_IP, events.PRECOMMIT_DELETE, - self, **kwargs) + registry.publish(resources.FLOATING_IP, events.PRECOMMIT_DELETE, + self, payload) def _delete_floatingip(self, context, id): floatingip = self._get_floatingip(context, id) diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index 36b4a6d9233..619cc2b4c88 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -1953,34 +1953,39 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, network = self.get_network(context, port['network_id']) bound_mech_contexts = [] - kwargs = { - 'context': context, - 'id': id, - 'network': network, - 'port': port, - 'port_db': port_db, - 'bindings': binding, - } device_owner = port['device_owner'] + metadata = {'network': network, + 'port_db': port_db, + 'bindings': binding} if device_owner == const.DEVICE_OWNER_DVR_INTERFACE: bindings = db.get_distributed_port_bindings(context, id) for bind in bindings: levels = db.get_binding_level_objs(context, id, bind.host) - kwargs['bind'] = bind - kwargs['levels'] = levels - registry.notify(resources.PORT, events.PRECOMMIT_DELETE, - self, **kwargs) + metadata['bind'] = bind + metadata['levels'] = levels + registry.publish(resources.PORT, + events.PRECOMMIT_DELETE, + self, + payload=events.DBEventPayload( + context, + resource_id=id, + metadata=metadata, + states=(port,))) mech_context = driver_context.PortContext( self, context, port, network, bind, levels) self.mechanism_manager.delete_port_precommit(mech_context) bound_mech_contexts.append(mech_context) else: levels = db.get_binding_level_objs(context, id, binding.host) - kwargs['bind'] = None - kwargs['levels'] = levels - registry.notify(resources.PORT, events.PRECOMMIT_DELETE, - self, **kwargs) + metadata['bind'] = None + metadata['levels'] = levels + registry.publish(resources.PORT, events.PRECOMMIT_DELETE, self, + payload=events.DBEventPayload( + context, + resource_id=id, + metadata=metadata, + states=(port,))) mech_context = driver_context.PortContext( self, context, port, network, binding, levels) self.mechanism_manager.delete_port_precommit(mech_context) diff --git a/neutron/services/portforwarding/pf_plugin.py b/neutron/services/portforwarding/pf_plugin.py index 39e2df8f950..b8476a0c170 100644 --- a/neutron/services/portforwarding/pf_plugin.py +++ b/neutron/services/portforwarding/pf_plugin.py @@ -147,8 +147,16 @@ class PortForwardingPlugin(fip_pf.PortForwardingPluginBase): if l3_dvr_db.is_distributed_router(router): raise pf_exc.PortHasPortForwarding(port_id=port_id) - @registry.receives(resources.FLOATING_IP, [events.PRECOMMIT_UPDATE, - events.PRECOMMIT_DELETE]) + @registry.receives(resources.FLOATING_IP, [events.PRECOMMIT_DELETE]) + def _check_floatingip_request_precommit_delete( + self, resource, event, trigger, payload): + # TODO(isabek): refactor back into 1 method when FIP code is moved + # to event payloads + return self._check_floatingip_request(resource, event, trigger, + payload.context, + port=payload.latest_state) + + @registry.receives(resources.FLOATING_IP, [events.PRECOMMIT_UPDATE]) def _check_floatingip_request(self, resource, event, trigger, context, **kwargs): # We only support the "free" floatingip to be associated with @@ -178,23 +186,20 @@ class PortForwardingPlugin(fip_pf.PortForwardingPluginBase): if exist_pf_resources: raise pf_exc.FipInUseByPortForwarding(id=floatingip_id) - @registry.receives(resources.PORT, [events.AFTER_UPDATE]) - def _process_updated_port_request(self, resource, event, trigger, + @registry.receives(resources.PORT, [events.AFTER_UPDATE, + events.PRECOMMIT_DELETE]) + def _process_port_request_handler(self, resource, event, trigger, payload): - # TODO(isabek): refactor back into 1 method when all code is moved - # to event payloads - return self._process_port_request(resource, event, trigger, - payload.context, - port=payload.latest_state) - @registry.receives(resources.PORT, [events.PRECOMMIT_DELETE]) + return self._process_port_request(event, payload.context, + payload.latest_state) + @db_api.retry_if_session_inactive() - def _process_port_request(self, resource, event, trigger, context, - **kwargs): + def _process_port_request(self, event, context, port): # Deleting floatingip will receive port resource with precommit_delete # event, so just return, then check the request in # _check_floatingip_request callback. - if kwargs['port']['device_owner'].startswith( + if port['device_owner'].startswith( lib_consts.DEVICE_OWNER_FLOATINGIP): return @@ -204,8 +209,8 @@ class PortForwardingPlugin(fip_pf.PortForwardingPluginBase): # port forwarding resources need to be deleted for port's AFTER_UPDATE # event. Or get all affected ip addresses for port's PRECOMMIT_DELETE # event. - port_id = kwargs['port']['id'] - update_fixed_ips = kwargs['port']['fixed_ips'] + port_id = port['id'] + update_fixed_ips = port['fixed_ips'] update_ip_set = set() for update_fixed_ip in update_fixed_ips: if (netaddr.IPNetwork(update_fixed_ip.get('ip_address')).version == diff --git a/neutron/tests/unit/plugins/ml2/test_plugin.py b/neutron/tests/unit/plugins/ml2/test_plugin.py index 295545cdb9e..f6112fc24e4 100644 --- a/neutron/tests/unit/plugins/ml2/test_plugin.py +++ b/neutron/tests/unit/plugins/ml2/test_plugin.py @@ -2086,27 +2086,18 @@ class TestMl2DvrPortsV2(TestMl2PortsV2): if floating_ip: router_ids.add(ns_to_delete['router_id']) - with self.port() as port,\ - mock.patch.object(registry, 'notify') as notify, \ + with self.port() as port, \ mock.patch.object(registry, 'publish') as publish, \ mock.patch.object(self.l3plugin, 'disassociate_floatingips', return_value=router_ids): port_id = port['port']['id'] self.plugin.delete_port(self.context, port_id) - self.assertEqual(1, notify.call_count) - self.assertEqual(2, publish.call_count) + self.assertEqual(3, publish.call_count) # needed for a full match in the assertion below port['port']['extra_dhcp_opts'] = [] port['port']['standard_attr_id'] = mock.ANY - expected = [mock.call(resources.PORT, events.PRECOMMIT_DELETE, - mock.ANY, network=mock.ANY, bind=mock.ANY, - port=port['port'], port_db=mock.ANY, - context=self.context, levels=mock.ANY, - id=mock.ANY, bindings=mock.ANY)] - notify.assert_has_calls(expected) - expected = [mock.call(resources.PORT, events.BEFORE_DELETE, mock.ANY, payload=mock.ANY)] publish.assert_has_calls(expected) @@ -2115,12 +2106,23 @@ class TestMl2DvrPortsV2(TestMl2PortsV2): self.assertEqual(port_id, payload.resource_id) self.assertTrue(payload.metadata['port_check']) - expected = [mock.call(resources.PORT, events.AFTER_DELETE, + expected = [mock.call(resources.PORT, events.PRECOMMIT_DELETE, mock.ANY, payload=mock.ANY)] publish.assert_has_calls(expected) payload = publish.call_args_list[1][1]['payload'] self.assertEqual(port_id, payload.resource_id) + self.assertEqual(port['port'], payload.latest_state) + self.assertTrue(payload.metadata['network']) + self.assertTrue(payload.metadata['port_db']) + self.assertTrue(payload.metadata['bindings']) + + expected = [mock.call(resources.PORT, events.AFTER_DELETE, + mock.ANY, payload=mock.ANY)] + publish.assert_has_calls(expected) + + payload = publish.call_args_list[2][1]['payload'] + self.assertEqual(port_id, payload.resource_id) def test_delete_port_with_floatingip_notifies_l3_plugin(self): self.test_delete_port_notifies_l3_plugin(floating_ip=True) @@ -2130,14 +2132,21 @@ class TestMl2DvrPortsV2(TestMl2PortsV2): with self.port(device_owner='network:floatingip') as port: try: registry.subscribe(fake_method, resources.FLOATING_IP, - events.PRECOMMIT_DELETE) + events.PRECOMMIT_DELETE) port_id = port['port']['id'] self.plugin.delete_port(self.context, port_id) fake_method.assert_called_once_with( resources.FLOATING_IP, events.PRECOMMIT_DELETE, mock.ANY, - bind=mock.ANY, bindings=mock.ANY, context=mock.ANY, - id=mock.ANY, levels=mock.ANY, network=mock.ANY, - port=mock.ANY, port_db=mock.ANY) + payload=mock.ANY) + payload = fake_method.call_args_list[0][1]['payload'] + self.assertEqual(port_id, payload.resource_id) + port_dict = payload.latest_state + port_dict.pop('standard_attr_id') + self.assertEqual(port['port'], port_dict) + self.assertTrue(payload.metadata['network']) + self.assertTrue(payload.metadata['port_db']) + self.assertTrue(payload.metadata['bindings']) + finally: registry.unsubscribe(fake_method, resources.FLOATING_IP, events.PRECOMMIT_DELETE)