From e0412e8d10c6418c0a3cca3ddb11a434f330ad40 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Fri, 16 Apr 2021 01:51:38 -0700 Subject: [PATCH] [NSX-P] Ensure DHCP binding are always deleted from backend Perform operations to check if network has DHCP enabled in elevated context. In this way info will always be retrieved even if the port delete operation is performed in a context different than the one of the network owner. Also adding unit test to validate the scenario. Change-Id: I25da68d61afbe85687a040d449869b47e61073d4 --- vmware_nsx/plugins/nsx_p/plugin.py | 7 +++++-- vmware_nsx/tests/unit/nsx_p/test_plugin.py | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/vmware_nsx/plugins/nsx_p/plugin.py b/vmware_nsx/plugins/nsx_p/plugin.py index a4859341e4..da216478f8 100644 --- a/vmware_nsx/plugins/nsx_p/plugin.py +++ b/vmware_nsx/plugins/nsx_p/plugin.py @@ -1937,10 +1937,13 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base): def _delete_port_policy_dhcp_binding(self, context, port): # Do not check device_owner here because Nova may have already # deleted that before Neutron's port deletion. + # These operations need to performed in elevated context as it is not + # possible to guarantee port and network belong to the same tenant + ctx_elevated = context.elevated() net_id = port['network_id'] - if not self._is_dhcp_network(context, net_id): + if not self._is_dhcp_network(ctx_elevated, net_id): return - segment_id = self._get_network_nsx_segment_id(context, net_id) + segment_id = self._get_network_nsx_segment_id(ctx_elevated, net_id) v4_dhcp = v6_dhcp = False for fixed_ip in port['fixed_ips']: diff --git a/vmware_nsx/tests/unit/nsx_p/test_plugin.py b/vmware_nsx/tests/unit/nsx_p/test_plugin.py index 3345933c31..43c9ba7e70 100644 --- a/vmware_nsx/tests/unit/nsx_p/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_p/test_plugin.py @@ -1066,6 +1066,24 @@ class NsxPTestPorts(common_v3.NsxV3TestPorts, def test_requested_invalid_fixed_ip_address_v6_slaac(self): self.skipTest("NSX subnet GW validation") + def test_delete_port_shared_network_with_dhcp_sub(self): + with mock.patch.object( + self.plugin.nsxpolicy.segment_dhcp_static_bindings, + 'delete') as mock_delete_binding: + with self.network(shared=True) as network: + with self.subnet(network): + port_res = self._create_port( + self.fmt, network['network']['id'], + exc.HTTPCreated.code, + tenant_id='another_tenant', + set_context=True) + port = self.deserialize(self.fmt, port_res) + self._delete('ports', port['port']['id']) + self._show('ports', port['port']['id'], + expected_code=exc.HTTPNotFound.code) + mock_delete_binding.assert_called_once_with( + network['network']['id'], mock.ANY) + class NsxPTestSubnets(common_v3.NsxV3TestSubnets, NsxPPluginTestCaseMixin):