Add service role allowed to list members in pool

The Aodh project has an evaluator for Octavia
where it lists the members of a pool to determine
which members is unhealthy [1].

Today this requires the service user used
for Aodh to have the admin role globally
in the cloud, with this change we could
narrow this down to the service user for
Aodh only needing the service role and
not be admin.

[1] https://github.com/openstack/aodh/blob/master/aodh/evaluator/loadbalancer.py#L72

Change-Id: Ieeed0ffd96ad908b43d5e9eed8c53d626e415f5e
This commit is contained in:
Tobias Urdin
2025-03-18 16:14:47 +01:00
parent 1b6d6de448
commit 32eca8ae06
5 changed files with 28 additions and 4 deletions

View File

@@ -768,6 +768,10 @@ RULE_API_READ_QUOTA = 'rule:load-balancer:read-quota'
RULE_API_READ_QUOTA_GLOBAL = 'rule:load-balancer:read-quota-global'
RULE_API_WRITE_QUOTA = 'rule:load-balancer:write-quota'
# The service user for Aodh needs to be able to list all
# members of a pool to determine which are healthy.
RULE_MEMBER_API_READ = f'{RULE_API_READ} or rule:service'
RBAC_LOADBALANCER = f'{LOADBALANCER_API}:loadbalancer:'
RBAC_LISTENER = f'{LOADBALANCER_API}:listener:'
RBAC_POOL = f'{LOADBALANCER_API}:pool:'

View File

@@ -51,6 +51,11 @@ rules = [
# auth_strategy == noauth configuration setting.
# It is equivalent to 'rule:context_is_admin or {auth_strategy == noauth}'
policy.RuleDefault(
name='service',
check_str='role:service',
scope_types=[constants.RBAC_SCOPE_PROJECT]),
policy.RuleDefault(
name='load-balancer:global_observer',
check_str='role:admin',

View File

@@ -18,7 +18,7 @@ from octavia.common import constants
rules = [
policy.DocumentedRuleDefault(
f'{constants.RBAC_MEMBER}{constants.RBAC_GET_ALL}',
constants.RULE_API_READ,
constants.RULE_MEMBER_API_READ,
"List Members of a Pool",
[{'method': 'GET', 'path': '/v2/lbaas/pools/{pool_id}/members'}]
),

View File

@@ -169,7 +169,7 @@ class TestMember(base.BaseAPITest):
objects = response.json.get(self.root_tag_list)
self.assertEqual(len(objects), 0)
def test_get_all_authorized(self):
def _test_get_all_authorized(self, roles, project_id):
api_m_1 = self.create_member(
self.pool_id, '192.0.2.1', 80).get(self.root_tag)
self.set_lb_status(self.lb_id)
@@ -195,13 +195,13 @@ class TestMember(base.BaseAPITest):
'is_admin_project': True,
'service_project_domain_id': None,
'service_project_id': None,
'roles': ['load-balancer_member', 'member'],
'roles': roles,
'user_id': None,
'is_admin': False,
'service_user_domain_id': None,
'project_domain_id': None,
'service_roles': [],
'project_id': self.project_id}
'project_id': project_id}
with mock.patch(
"oslo_context.context.RequestContext.to_policy_values",
return_value=override_credentials):
@@ -216,6 +216,15 @@ class TestMember(base.BaseAPITest):
for m in [api_m_1, api_m_2]:
self.assertIn(m, response)
def test_get_all_authorized(self):
self._test_get_all_authorized(
roles=['load-balancer_member', 'member'],
project_id=self.project_id)
def test_get_all_authorized_service(self):
self._test_get_all_authorized(
roles=['service'], project_id='services')
def test_get_all_unscoped_token(self):
api_m_1 = self.create_member(
self.pool_id, '192.0.2.1', 80).get(self.root_tag)

View File

@@ -0,0 +1,6 @@
---
features:
- |
The ``service`` role now has access to list members in
a pool, this is needed by Aodh to evaluate unhealthy
members in a pool when doing evaluations.