NSX|V3: Handle port-not-found during get_ports

Under stress, a port might be deleted while geting ports list.
This patch prevent this port from being at the results, or crashing
the api.

Change-Id: Ib6d298a7990556da73277f549580d9c04512518e
This commit is contained in:
Adit Sarfaty 2018-07-24 15:05:09 +03:00
parent 3cffa0dfa9
commit 6258c7fccd
2 changed files with 32 additions and 3 deletions

View File

@ -2876,10 +2876,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

View File

@ -527,6 +527,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_port_failure_rollback_dhcp_exception(self):
cfg.CONF.set_override('native_dhcp_metadata', True, 'nsx_v3')
self.plugin = directory.get_plugin()