diff --git a/vmware_nsx/plugins/nsx_v3/plugin.py b/vmware_nsx/plugins/nsx_v3/plugin.py index ee42b2a716..3e28207038 100644 --- a/vmware_nsx/plugins/nsx_v3/plugin.py +++ b/vmware_nsx/plugins/nsx_v3/plugin.py @@ -3569,10 +3569,17 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin, context, filters, fields, sorts, limit, marker, page_reverse)) # Add port extensions - for port in ports: + for port in ports[:]: if 'id' in port: - port_model = self._get_port(context, port['id']) - resource_extend.apply_funcs('ports', port, port_model) + try: + port_model = self._get_port(context, port['id']) + resource_extend.apply_funcs('ports', port, port_model) + except n_exc.PortNotFound: + # Port might have been deleted by now + LOG.debug("Port %s was deleted during the get_ports " + "process, and is being skipped", port['id']) + ports.remove(port) + continue self._extend_get_port_dict_qos_and_binding(context, port) self._remove_provider_security_groups_from_list(port) return (ports if not fields else diff --git a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py index 66b6fe2720..30f2ab0680 100644 --- a/vmware_nsx/tests/unit/nsx_v3/test_plugin.py +++ b/vmware_nsx/tests/unit/nsx_v3/test_plugin.py @@ -1250,6 +1250,28 @@ class TestPortsV2(test_plugin.TestPortsV2, NsxV3PluginTestCaseMixin, self._get_ports_with_fields(tenid, 'mac_address', 4) self._get_ports_with_fields(tenid, 'network_id', 4) + def test_list_ports_while_deleting(self): + self.plugin = directory.get_plugin() + orig_get_port = self.plugin._get_port + + class local(object): + counter = 0 + + def mock_get_port(*args): + #global counter + local.counter += 1 + if local.counter == 3: + raise n_exc.PortNotFound(port_id=args[1]) + return orig_get_port(*args) + + self.plugin = directory.get_plugin() + with self.port(), self.port(), self.port(), self.port() as p: + tenid = p['port']['tenant_id'] + # get all ports, while "deleting" one of them: + with mock.patch.object(self.plugin, "_get_port", + side_effect=mock_get_port): + self._get_ports_with_fields(tenid, None, 3) + def test_list_ports_filtered_by_security_groups(self): ctx = context.get_admin_context() with self.port() as port1, self.port() as port2: