rbacs: filter out model that are already owned by context

Taking example of a network that have multiple rbacs. In a situation
of selecting networks that are shared to a project.

If we could could already match the one that are owned by the context
we can expect les rbacs to scan.

https://bugs.launchpad.net/neutron/+bug/1918145/comments/54

In an environement with about 200 00 rbacs and 200 networks this
reduce time of the request from more than 50s to less than a second.

Related-bug: #1918145
Signed-off-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@industrialdiscipline.com>
Change-Id: I54808cbd4cdccfee97eb59053418f55ba57e11a6

Signed-off-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@industrialdiscipline.com>
Change-Id: Ib155fbb3f6b325d10e3fbea201677dc218111c17
This commit is contained in:
Sahid Orentino Ferdjaoui 2023-01-19 17:40:11 +01:00
parent 1056650237
commit e6de524555
2 changed files with 6 additions and 2 deletions

View File

@ -51,6 +51,8 @@ def _network_filter_hook(context, original_model, conditions):
(rbac_model.target_project == context.tenant_id) |
(rbac_model.target_project == '*'))
conditions = expr.or_(tenant_allowed, *conditions)
conditions = expr.or_(original_model.tenant_id == context.tenant_id,
*conditions)
return conditions

View File

@ -142,7 +142,8 @@ class ExtNetDBTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
def test_network_filter_hook_nonadmin_context(self):
ctx = context.Context('edinson', 'cavani')
model = models_v2.Network
txt = ("networkrbacs.action = :action_1 AND "
txt = ("networks.project_id = :project_id_1 OR "
"networkrbacs.action = :action_1 AND "
"networkrbacs.target_project = :target_project_1 OR "
"networkrbacs.target_project = :target_project_2")
conditions = external_net_db._network_filter_hook(ctx, model, [])
@ -150,7 +151,8 @@ class ExtNetDBTestCase(test_db_base_plugin_v2.NeutronDbPluginV2TestCase):
# Try to concatenate conditions
txt2 = (txt.replace('project_1', 'project_3').
replace('project_2', 'project_4').
replace('action_1', 'action_2'))
replace('action_1', 'action_2').
replace('project_id_1', 'project_id_2'))
conditions = external_net_db._network_filter_hook(ctx, model,
conditions)
self.assertEqual(conditions.__str__(), "%s OR %s" % (txt, txt2))