summaryrefslogtreecommitdiff
path: root/ironic
diff options
context:
space:
mode:
authorLance Bragstad <lbragstad@gmail.com>2020-11-18 21:31:24 +0000
committerJulia Kreger <juliaashleykreger@gmail.com>2021-02-22 05:50:23 -0800
commit69b28ca99cd031c87936a414691f34eabbc74f3d (patch)
tree317bbfce19fb4051da471338d83c379c04c3249f /ironic
parentff883486e62e394b03ed7c6e6911ca082e599586 (diff)
downloadironic-69b28ca99cd031c87936a414691f34eabbc74f3d.tar.gz
Implement system scoped RBAC for utility APIs
This commit updates the policies for baremetal utility policies to understand scope checking and account for a read-only role. This is part of a broader series of changes across OpenStack to provide a consistent RBAC experience and improve security. Also adds duplicate Heartbeat and Lookup test classes with the middleware scope enforcement enabled and enforced, to ensure that we do not adversely impact these special API endpoints. Change-Id: I89176b3adf1489e12493c62b908bf135c912e017
Diffstat (limited to 'ironic')
-rw-r--r--ironic/common/policy.py42
-rw-r--r--ironic/tests/unit/api/controllers/v1/test_ramdisk.py29
2 files changed, 63 insertions, 8 deletions
diff --git a/ironic/common/policy.py b/ironic/common/policy.py
index 8c8631bda..465e3b4bc 100644
--- a/ironic/common/policy.py
+++ b/ironic/common/policy.py
@@ -95,6 +95,8 @@ default_policies = [
'role:admin or role:administrator',
description='Legacy rule for cloud admin access'),
# is_public_api is set in the environment from AuthPublicRoutes
+ # TODO(TheJulia): Once legacy policy rules are removed, is_public_api
+ # can be removed from the code base.
policy.RuleDefault('public_api',
'is_public_api:True',
description='Internal flag for public API routes'),
@@ -1023,17 +1025,41 @@ vendor_passthru_policies = [
),
]
+
+deprecated_ipa_heartbeat = policy.DeprecatedRule(
+ name='baremetal:node:ipa_heartbeat',
+ check_str='rule:public_api'
+)
+deprecated_ipa_lookup = policy.DeprecatedRule(
+ name='baremetal:driver:ipa_lookup',
+ check_str='rule:public_api'
+)
+deprecated_utility_reason = """
+The baremetal utility API is now aware of system scope and default
+roles.
+"""
+
+# NOTE(TheJulia): Empty check strings basically mean nothing to apply,
+# and the request is permitted.
utility_policies = [
policy.DocumentedRuleDefault(
- 'baremetal:node:ipa_heartbeat',
- 'rule:public_api',
- 'Send heartbeats from IPA ramdisk',
- [{'path': '/heartbeat/{node_ident}', 'method': 'POST'}]),
+ name='baremetal:node:ipa_heartbeat',
+ check_str='',
+ description='Receive heartbeats from IPA ramdisk',
+ operations=[{'path': '/heartbeat/{node_ident}', 'method': 'POST'}],
+ deprecated_rule=deprecated_ipa_heartbeat,
+ deprecated_reason=deprecated_utility_reason,
+ deprecated_since=versionutils.deprecated.WALLABY
+ ),
policy.DocumentedRuleDefault(
- 'baremetal:driver:ipa_lookup',
- 'rule:public_api',
- 'Access IPA ramdisk functions',
- [{'path': '/lookup', 'method': 'GET'}]),
+ name='baremetal:driver:ipa_lookup',
+ check_str='',
+ description='Access IPA ramdisk functions',
+ operations=[{'path': '/lookup', 'method': 'GET'}],
+ deprecated_rule=deprecated_ipa_lookup,
+ deprecated_reason=deprecated_utility_reason,
+ deprecated_since=versionutils.deprecated.WALLABY
+ ),
]
volume_policies = [
diff --git a/ironic/tests/unit/api/controllers/v1/test_ramdisk.py b/ironic/tests/unit/api/controllers/v1/test_ramdisk.py
index 063965754..51005b772 100644
--- a/ironic/tests/unit/api/controllers/v1/test_ramdisk.py
+++ b/ironic/tests/unit/api/controllers/v1/test_ramdisk.py
@@ -19,6 +19,7 @@ from http import client as http_client
from unittest import mock
import fixtures
+from keystonemiddleware import auth_token
from oslo_config import cfg
from oslo_utils import uuidutils
@@ -338,3 +339,31 @@ class TestHeartbeat(test_api_base.BaseApiTest):
headers={api_base.Version.string: '1.67'},
expect_errors=True)
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
+
+
+@mock.patch.object(auth_token.AuthProtocol, 'process_request',
+ lambda *_: None)
+class TestLookupScopedRBAC(TestLookup):
+
+ """Test class to execute the Lookup tests with RBAC enforcement."""
+ def setUp(self):
+ super(TestLookupScopedRBAC, self).setUp()
+
+ cfg.CONF.set_override('enforce_scope', True, group='oslo_policy')
+ cfg.CONF.set_override('enforce_new_defaults', True,
+ group='oslo_policy')
+ cfg.CONF.set_override('auth_strategy', 'keystone')
+
+
+@mock.patch.object(auth_token.AuthProtocol, 'process_request',
+ lambda *_: None)
+class TestHeartbeatScopedRBAC(TestHeartbeat):
+
+ """Test class to execute the Heartbeat tests with RBAC enforcement."""
+ def setUp(self):
+ super(TestHeartbeatScopedRBAC, self).setUp()
+
+ cfg.CONF.set_override('enforce_scope', True, group='oslo_policy')
+ cfg.CONF.set_override('enforce_new_defaults', True,
+ group='oslo_policy')
+ cfg.CONF.set_override('auth_strategy', 'keystone')