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:
parent
86eb67dfca
commit
17982a7744
@ -3569,10 +3569,17 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
|||||||
context, filters, fields, sorts,
|
context, filters, fields, sorts,
|
||||||
limit, marker, page_reverse))
|
limit, marker, page_reverse))
|
||||||
# Add port extensions
|
# Add port extensions
|
||||||
for port in ports:
|
for port in ports[:]:
|
||||||
if 'id' in port:
|
if 'id' in port:
|
||||||
|
try:
|
||||||
port_model = self._get_port(context, port['id'])
|
port_model = self._get_port(context, port['id'])
|
||||||
resource_extend.apply_funcs('ports', port, port_model)
|
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._extend_get_port_dict_qos_and_binding(context, port)
|
||||||
self._remove_provider_security_groups_from_list(port)
|
self._remove_provider_security_groups_from_list(port)
|
||||||
return (ports if not fields else
|
return (ports if not fields else
|
||||||
|
@ -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, 'mac_address', 4)
|
||||||
self._get_ports_with_fields(tenid, 'network_id', 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):
|
def test_list_ports_filtered_by_security_groups(self):
|
||||||
ctx = context.get_admin_context()
|
ctx = context.get_admin_context()
|
||||||
with self.port() as port1, self.port() as port2:
|
with self.port() as port1, self.port() as port2:
|
||||||
|
Loading…
Reference in New Issue
Block a user