This adjusts the prevent_l3_port_deletion function to handle
the case where the port ID that is passed to it does not have
an entry in the database.
Previously it was raising an exception in this case, which is
inconsistent to how ML2 was handling concurrent port_delete requests
further in the port delete function (log them but don't fail).
Closes-Bug: #
1416554
Change-Id: I6da021bdf0c79f72336416d02ab989407f352904
to /ports, but rather via other API calls that perform the proper
deletion checks.
"""
- port_db = self._core_plugin._get_port(context, port_id)
+ try:
+ port_db = self._core_plugin._get_port(context, port_id)
+ except n_exc.PortNotFound:
+ # non-existent ports don't need to be protected from deletion
+ return
if port_db['device_owner'] in self.router_device_owners:
# Raise port in use only if the port has IP addresses
# Otherwise it's a stale port that can be removed
session.begin(subtransactions=True)):
port_db, binding = db.get_locked_port_and_binding(session, id)
if not port_db:
- # the port existed when l3plugin.prevent_l3_port_deletion
- # was called but now is already gone
LOG.debug("The port '%s' was deleted", id)
return
port = self._make_port_dict(port_db)
class L3NatDBSepTestCase(L3BaseForSepTests, L3NatTestCaseBase):
"""Unit tests for a separate L3 routing service plugin."""
- pass
+
+ def test_port_deletion_prevention_handles_missing_port(self):
+ pl = manager.NeutronManager.get_service_plugins().get(
+ service_constants.L3_ROUTER_NAT)
+ self.assertIsNone(
+ pl.prevent_l3_port_deletion(context.get_admin_context(), 'fakeid')
+ )