Skip to content

Commit cd86fee

Browse files
authored
Merge pull request #43 from stackhpc/upstream/master-2025-04-21
Synchronise master with upstream
2 parents f79342f + 84f5126 commit cd86fee

File tree

8 files changed

+63
-7
lines changed

8 files changed

+63
-7
lines changed

octavia/common/constants.py

+4
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,10 @@
768768
RULE_API_READ_QUOTA_GLOBAL = 'rule:load-balancer:read-quota-global'
769769
RULE_API_WRITE_QUOTA = 'rule:load-balancer:write-quota'
770770

771+
# The service user for Aodh needs to be able to list all
772+
# members of a pool to determine which are healthy.
773+
RULE_MEMBER_API_READ = f'{RULE_API_READ} or rule:service'
774+
771775
RBAC_LOADBALANCER = f'{LOADBALANCER_API}:loadbalancer:'
772776
RBAC_LISTENER = f'{LOADBALANCER_API}:listener:'
773777
RBAC_POOL = f'{LOADBALANCER_API}:pool:'

octavia/controller/worker/v2/tasks/network_tasks.py

+15-3
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,11 @@ def execute(self, loadbalancer, amphora=None):
728728
db_lb, amphora=db_amp)
729729
provider_dict = {}
730730
for amp_id, amp_conf in db_configs.items():
731-
provider_dict[amp_id] = amp_conf.to_dict(recurse=True)
731+
# Do not serialize loadbalancer class. It's unused later and
732+
# could be ignored for storing in results of task in persistence DB
733+
provider_dict[amp_id] = amp_conf.to_dict(
734+
recurse=True, calling_classes=[data_models.LoadBalancer]
735+
)
732736
return provider_dict
733737

734738

@@ -746,7 +750,11 @@ def execute(self, loadbalancer_id, amphora_id=None):
746750
amphora=amphora)
747751
provider_dict = {}
748752
for amp_id, amp_conf in db_configs.items():
749-
provider_dict[amp_id] = amp_conf.to_dict(recurse=True)
753+
# Do not serialize loadbalancer class. It's unused later and
754+
# could be ignored for storing in results of task in persistence DB
755+
provider_dict[amp_id] = amp_conf.to_dict(
756+
recurse=True, calling_classes=[data_models.LoadBalancer]
757+
)
750758
return provider_dict
751759

752760

@@ -762,7 +770,11 @@ def execute(self, loadbalancer_id):
762770
db_configs = self.network_driver.get_network_configs(db_lb)
763771
provider_dict = {}
764772
for amp_id, amp_conf in db_configs.items():
765-
provider_dict[amp_id] = amp_conf.to_dict(recurse=True)
773+
# Do not serialize loadbalancer class. It's unused later and
774+
# could be ignored for storing in results of task in persistence DB
775+
provider_dict[amp_id] = amp_conf.to_dict(
776+
recurse=True, calling_classes=[data_models.LoadBalancer]
777+
)
766778
return provider_dict
767779

768780

octavia/policies/keystone_default_roles.py

+5
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@
5151
# auth_strategy == noauth configuration setting.
5252
# It is equivalent to 'rule:context_is_admin or {auth_strategy == noauth}'
5353

54+
policy.RuleDefault(
55+
name='service',
56+
check_str='role:service',
57+
scope_types=[constants.RBAC_SCOPE_PROJECT]),
58+
5459
policy.RuleDefault(
5560
name='load-balancer:global_observer',
5661
check_str='role:admin',

octavia/policies/member.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
rules = [
1919
policy.DocumentedRuleDefault(
2020
f'{constants.RBAC_MEMBER}{constants.RBAC_GET_ALL}',
21-
constants.RULE_API_READ,
21+
constants.RULE_MEMBER_API_READ,
2222
"List Members of a Pool",
2323
[{'method': 'GET', 'path': '/v2/lbaas/pools/{pool_id}/members'}]
2424
),

octavia/tests/functional/api/v2/test_member.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def test_get_all_hides_deleted(self):
169169
objects = response.json.get(self.root_tag_list)
170170
self.assertEqual(len(objects), 0)
171171

172-
def test_get_all_authorized(self):
172+
def _test_get_all_authorized(self, roles, project_id):
173173
api_m_1 = self.create_member(
174174
self.pool_id, '192.0.2.1', 80).get(self.root_tag)
175175
self.set_lb_status(self.lb_id)
@@ -195,13 +195,13 @@ def test_get_all_authorized(self):
195195
'is_admin_project': True,
196196
'service_project_domain_id': None,
197197
'service_project_id': None,
198-
'roles': ['load-balancer_member', 'member'],
198+
'roles': roles,
199199
'user_id': None,
200200
'is_admin': False,
201201
'service_user_domain_id': None,
202202
'project_domain_id': None,
203203
'service_roles': [],
204-
'project_id': self.project_id}
204+
'project_id': project_id}
205205
with mock.patch(
206206
"oslo_context.context.RequestContext.to_policy_values",
207207
return_value=override_credentials):
@@ -216,6 +216,15 @@ def test_get_all_authorized(self):
216216
for m in [api_m_1, api_m_2]:
217217
self.assertIn(m, response)
218218

219+
def test_get_all_authorized(self):
220+
self._test_get_all_authorized(
221+
roles=['load-balancer_member', 'member'],
222+
project_id=self.project_id)
223+
224+
def test_get_all_authorized_service(self):
225+
self._test_get_all_authorized(
226+
roles=['service'], project_id='services')
227+
219228
def test_get_all_unscoped_token(self):
220229
api_m_1 = self.create_member(
221230
self.pool_id, '192.0.2.1', 80).get(self.root_tag)

octavia/tests/unit/controller/worker/v2/tasks/test_network_tasks.py

+14
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,10 @@ def test_get_amphora_network_configs_by_id(
13491349
AMP_ID = uuidutils.generate_uuid()
13501350
mock_driver = mock.MagicMock()
13511351
mock_get_net_driver.return_value = mock_driver
1352+
amphora_config_mock = mock.MagicMock()
1353+
mock_driver.get_network_configs.return_value = {
1354+
"amphora_uuid1": amphora_config_mock
1355+
}
13521356
mock_amp_get.return_value = 'mock amphora'
13531357
mock_lb_get.return_value = 'mock load balancer'
13541358

@@ -1360,6 +1364,9 @@ def test_get_amphora_network_configs_by_id(
13601364
'mock load balancer', amphora='mock amphora')
13611365
mock_amp_get.assert_called_once_with(mock_get_session(), id=AMP_ID)
13621366
mock_lb_get.assert_called_once_with(mock_get_session(), id=LB_ID)
1367+
amphora_config_mock.to_dict.assert_called_once_with(
1368+
recurse=True, calling_classes=[o_data_models.LoadBalancer]
1369+
)
13631370

13641371
@mock.patch('octavia.db.repositories.LoadBalancerRepository.get')
13651372
@mock.patch('octavia.db.api.get_session', return_value=_session_mock)
@@ -1368,10 +1375,17 @@ def test_get_amphorae_network_configs(self, mock_session, mock_lb_get,
13681375
mock_driver = mock.MagicMock()
13691376
mock_lb_get.return_value = LB
13701377
mock_get_net_driver.return_value = mock_driver
1378+
amphora_config_mock = mock.MagicMock()
1379+
mock_driver.get_network_configs.return_value = {
1380+
"amphora_uuid1": amphora_config_mock
1381+
}
13711382
lb = o_data_models.LoadBalancer()
13721383
net_task = network_tasks.GetAmphoraeNetworkConfigs()
13731384
net_task.execute(self.load_balancer_mock)
13741385
mock_driver.get_network_configs.assert_called_once_with(lb)
1386+
amphora_config_mock.to_dict.assert_called_once_with(
1387+
recurse=True, calling_classes=[o_data_models.LoadBalancer]
1388+
)
13751389

13761390
def test_retrieve_portids_on_amphora_except_lb_network(
13771391
self, mock_get_net_driver):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
features:
3+
- |
4+
The ``service`` role now has access to list members in
5+
a pool, this is needed by Aodh to evaluate unhealthy
6+
members in a pool when doing evaluations.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
fixes:
3+
- |
4+
Ignore serialization loadbalancer class in GetAmphoraNetworkConfigs tasks.
5+
It allows to avoid storing full graph in jobboard details. It fixes cases
6+
with enabled jobboard for huge LBs with ~2000+ resources in graph.

0 commit comments

Comments
 (0)