Merge "Dont raise RouterInterfaceNotFound on overlap check router ports"

This commit is contained in:
Zuul 2022-12-06 00:47:17 +00:00 committed by Gerrit Code Review
commit dd6a5f0270
3 changed files with 50 additions and 23 deletions

View File

@ -1033,10 +1033,15 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase,
subnets_id.extend([fixed_ip['subnet_id']
for fixed_ip in port['fixed_ips']])
else:
raise l3_exc.RouterInterfaceNotFound(
router_id=router.id, port_id=rp.port_id)
# due to race conditions maybe the port under analysis is
# deleted, so instead returning a RouterInterfaceNotFound
# we continue the analysis avoiding that port
LOG.debug("Port %s could not be found, it might have been "
"deleted concurrently. Will not be checked for "
"an overlapping router interface.",
rp.port_id)
if subnets_id:
if len(subnets_id) > 1:
id_filter = {'id': subnets_id}
subnets = self._core_plugin.get_subnets(context.elevated(),
filters=id_filter)

View File

@ -492,7 +492,11 @@ class BaseTestCase(DietTestCase):
root_helper_daemon=get_rootwrap_daemon_cmd())
def _simulate_concurrent_requests_process_and_raise(self, calls, args):
self._simulate_concurrent_requests_process(calls, args,
raise_on_exception=True)
def _simulate_concurrent_requests_process(self, calls, args,
raise_on_exception=False):
class SimpleThread(threading.Thread):
def __init__(self, q):
super(SimpleThread, self).__init__()
@ -529,10 +533,16 @@ class BaseTestCase(DietTestCase):
t.start()
q.join()
threads_exceptions = []
for t in threads:
e = t.get_exception()
if e:
raise e
if raise_on_exception:
raise e
else:
threads_exceptions.append(e)
return threads_exceptions
class PluginFixture(fixtures.Fixture):

View File

@ -270,25 +270,37 @@ class TestL3Agent(base.BaseFullStackTestCase):
def _test_concurrent_router_subnet_attachment_overlapping_cidr(self,
ha=False):
tenant_id = uuidutils.generate_uuid()
subnet_cidr = '10.100.0.0/24'
network1 = self.safe_client.create_network(
tenant_id, name='foo-network1')
subnet1 = self.safe_client.create_subnet(
tenant_id, network1['id'], subnet_cidr)
network2 = self.safe_client.create_network(
tenant_id, name='foo-network2')
subnet2 = self.safe_client.create_subnet(
tenant_id, network2['id'], subnet_cidr)
subnet_cidr = '10.200.0.0/24'
# to have many port interactions where race conditions would happen
# deleting ports meanwhile find operations to evaluate the overlapping
subnets = 10
funcs = []
args = []
router = self.safe_client.create_router(tenant_id, ha=ha)
funcs = [self.safe_client.add_router_interface,
self.safe_client.add_router_interface]
args = [(router['id'], subnet1['id']), (router['id'], subnet2['id'])]
self.assertRaises(
exceptions.BadRequest,
self._simulate_concurrent_requests_process_and_raise,
funcs,
args)
for i in range(subnets):
network_tmp = self.safe_client.create_network(
tenant_id, name='foo-network' + str(i))
subnet_tmp = self.safe_client.create_subnet(
tenant_id, network_tmp['id'], subnet_cidr)
funcs.append(self.safe_client.add_router_interface)
args.append((router['id'], subnet_tmp['id']))
exception_requests = self._simulate_concurrent_requests_process(
funcs, args)
if not all(type(e) == exceptions.BadRequest
for e in exception_requests):
self.fail('Unexpected exception adding interfaces to router from '
'different subnets overlapping')
if not len(exception_requests) >= (subnets - 1):
self.fail('If we have tried to associate %s subnets overlapping '
'cidr to the router, we should have received at least '
'%s or %s rejected requests, but we have only received '
'%s', (str(subnets), str(subnets - 1), str(subnets),
str(len(exception_requests))))
class TestLegacyL3Agent(TestL3Agent):
@ -441,7 +453,7 @@ class TestLegacyL3Agent(TestL3Agent):
def test_router_fip_qos_after_admin_state_down_up(self):
self._router_fip_qos_after_admin_state_down_up()
def test_concurrent_router_subnet_attachment_overlapping_cidr_(self):
def test_concurrent_router_subnet_attachment_overlapping_cidr(self):
self._test_concurrent_router_subnet_attachment_overlapping_cidr()
@ -601,6 +613,6 @@ class TestHAL3Agent(TestL3Agent):
def test_router_fip_qos_after_admin_state_down_up(self):
self._router_fip_qos_after_admin_state_down_up(ha=True)
def test_concurrent_router_subnet_attachment_overlapping_cidr_(self):
def test_concurrent_router_subnet_attachment_overlapping_cidr(self):
self._test_concurrent_router_subnet_attachment_overlapping_cidr(
ha=True)