Auto-remove floating agent gw ports on net/subnet delete
fip agent gw ports may be left in DB after router removal due to
race condition between l3 agent and server: when server processes
"router delete" - l3 agent is still processing "router add" and creates
fip agent gw port after server already removed the router.
The patch also adds handling of external network delete event
to cleanup fip namespaces left on agents due to same race condition.
Change-Id: Ib2f3aca08946e584156d092c37e1ea5ed5ca81a6
Closes-Bug: #1902998
(cherry picked from commit b97a8eb488
)
This commit is contained in:
parent
d44d85b810
commit
74c671ba87
|
@ -75,4 +75,5 @@ IDPOOL_SELECT_SIZE = 100
|
|||
# finds out that all existing IP Allocations are associated with ports
|
||||
# with these owners, it will allow subnet deletion to proceed with the
|
||||
# IP allocations being cleaned up by cascade.
|
||||
AUTO_DELETE_PORT_OWNERS = [constants.DEVICE_OWNER_DHCP]
|
||||
AUTO_DELETE_PORT_OWNERS = [constants.DEVICE_OWNER_DHCP,
|
||||
constants.DEVICE_OWNER_AGENT_GW]
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# under the License.
|
||||
import collections
|
||||
|
||||
from neutron_lib.api.definitions import external_net as extnet_apidef
|
||||
from neutron_lib.api.definitions import l3 as l3_apidef
|
||||
from neutron_lib.api.definitions import portbindings
|
||||
from neutron_lib.api.definitions import portbindings_extended
|
||||
|
@ -387,6 +388,15 @@ class DVRResourceOperationHandler(object):
|
|||
if host_id:
|
||||
return
|
||||
|
||||
@registry.receives(resources.NETWORK, [events.AFTER_DELETE])
|
||||
def delete_fip_namespaces_for_ext_net(self, rtype, event, trigger,
|
||||
context, network, **kwargs):
|
||||
if network.get(extnet_apidef.EXTERNAL):
|
||||
# Send the information to all the L3 Agent hosts
|
||||
# to clean up the fip namespace as it is no longer required.
|
||||
self.l3plugin.l3_rpc_notifier.delete_fipnamespace_for_ext_net(
|
||||
context, network['id'])
|
||||
|
||||
def _get_ports_for_allowed_address_pair_ip(self, context, network_id,
|
||||
fixed_ip):
|
||||
"""Return all active ports associated with the allowed_addr_pair ip."""
|
||||
|
|
|
@ -1612,17 +1612,25 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s
|
|||
res = req.get_response(self.api)
|
||||
self.assertEqual(webob.exc.HTTPConflict.code, res.status_int)
|
||||
|
||||
def test_delete_network_port_exists_owned_by_network(self):
|
||||
def _test_delete_network_port_exists_owned_by_network(self, device_owner):
|
||||
res = self._create_network(fmt=self.fmt, name='net',
|
||||
admin_state_up=True)
|
||||
network = self.deserialize(self.fmt, res)
|
||||
network_id = network['network']['id']
|
||||
self._create_port(self.fmt, network_id,
|
||||
device_owner=constants.DEVICE_OWNER_DHCP)
|
||||
device_owner=device_owner)
|
||||
req = self.new_delete_request('networks', network_id)
|
||||
res = req.get_response(self.api)
|
||||
self.assertEqual(webob.exc.HTTPNoContent.code, res.status_int)
|
||||
|
||||
def test_test_delete_network_port_exists_dhcp(self):
|
||||
self._test_delete_network_port_exists_owned_by_network(
|
||||
constants.DEVICE_OWNER_DHCP)
|
||||
|
||||
def test_test_delete_network_port_exists_fip_gw(self):
|
||||
self._test_delete_network_port_exists_owned_by_network(
|
||||
constants.DEVICE_OWNER_AGENT_GW)
|
||||
|
||||
def test_delete_network_port_exists_owned_by_network_race(self):
|
||||
res = self._create_network(fmt=self.fmt, name='net',
|
||||
admin_state_up=True)
|
||||
|
|
Loading…
Reference in New Issue