Merge "Add default value for the "context_with_global_access" policy"

This commit is contained in:
Zuul
2025-08-04 14:54:03 +00:00
committed by Gerrit Code Review
4 changed files with 64 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
.. _Custom Policy Roles:
===================
Custom Policy Roles
===================
Besides the :ref:`default policy roles <Policy Reference>`, Neutron also
supports using custom roles. Using custom roles with for example read only
access to all of the resources requires to configure the policy rule which
allows ``global access`` to the resources.
To grant the ``auditor`` role access to fetch all of the resources from the
database, following rule should be added to the ``policy.yaml`` file:
.. code-block:: yaml
"context_with_global_access": "role:auditor"
This will make all SQL queries made by neutron with the ``auditor`` role in the
context to not be scoped by the project ID.
This however don't grant the ``auditor`` role to receive all of the resources
from the Neutron API yet. To grant such permissions for example for the
``get_network`` action, following rule should be added to the ``policy.yaml``
file:
.. code-block:: yaml
"get_network": "role:admin_only or (role:reader and project_id:%(project_id)s) or rule:shared or rule:external or rule:context_is_advsvc or role:auditor"
With those 2 rules in place, the ``auditor`` role will be able to fetch all of
the networks from the Neutron API.

View File

@@ -9,3 +9,4 @@ Configuration Guide
config
policy
custom_policy_roles

View File

@@ -102,6 +102,10 @@ rules = [
'context_is_admin',
'role:admin',
description='Rule for cloud admin access'),
policy.RuleDefault(
'context_with_global_access',
'!',
description='Rule for context with global access to the resources'),
policy.RuleDefault(
"service_api",
"role:service",

View File

@@ -1061,6 +1061,32 @@ class TestBasicGet(NeutronDbPluginV2TestCase):
n = plugin._get_network(ctx, net_id)
self.assertEqual(net_id, n.id)
def test_list_with_context_with_global_access(self):
plugin = neutron.db.db_base_plugin_v2.NeutronDbPluginV2()
ctx = context.Context(
user_id="auditor", project_id="auditor project",
is_admin=False, has_global_access=True)
with self.network(project_id='some project') as net1, \
self.network(project_id='other project') as net2, \
self.network(project_id='auditor project') as own_net:
networks = plugin.get_networks(ctx)
net_ids = [n['id'] for n in networks]
self.assertIn(own_net['network']['id'], net_ids)
self.assertIn(net1['network']['id'], net_ids)
self.assertIn(net2['network']['id'], net_ids)
def test_single_get_with_context_with_global_access(self):
plugin = neutron.db.db_base_plugin_v2.NeutronDbPluginV2()
ctx = context.Context(
user_id="auditor", project_id="auditor project",
is_admin=False, has_global_access=True)
with self.network(project_id='some project') as net1, \
self.network(project_id='other project') as net2, \
self.network(project_id='auditor project') as own_net:
for net in [net1, net2, own_net]:
network = plugin._get_network(ctx, net['network']['id'])
self.assertEqual(net['network']['id'], network['id'])
class TestV2HTTPResponse(NeutronDbPluginV2TestCase):
def test_create_returns_201(self):