policy-in-code support in neutron-lib
policy-in-code will be supported by the main neutron repo because the neutron API layer uses the policy code in the neutron repo. However, neutron_lib.context refers to its own policy enforcer, so we need a small code to support policy-in-code in neutron-lib side. Part of blueprint get-policy-from-neutron-lib Change-Id: I4923a069f4080dc53a8fb359f5a1518de06feb2f
This commit is contained in:
parent
c436b10e56
commit
bede782630
@ -10,6 +10,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import sys
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_policy import policy
|
||||
|
||||
@ -19,6 +21,18 @@ _ADMIN_CTX_POLICY = 'context_is_admin'
|
||||
_ADVSVC_CTX_POLICY = 'context_is_advsvc'
|
||||
|
||||
|
||||
_BASE_RULES = [
|
||||
policy.RuleDefault(
|
||||
_ADMIN_CTX_POLICY,
|
||||
'role:admin',
|
||||
description='Rule for cloud admin access'),
|
||||
policy.RuleDefault(
|
||||
_ADVSVC_CTX_POLICY,
|
||||
'role:advsvc',
|
||||
description='Rule for advanced service role access'),
|
||||
]
|
||||
|
||||
|
||||
def init(conf=cfg.CONF, policy_file=None):
|
||||
"""Initialize the global enforcer if not already initialized.
|
||||
|
||||
@ -35,6 +49,7 @@ def init(conf=cfg.CONF, policy_file=None):
|
||||
global _ROLE_ENFORCER
|
||||
if not _ROLE_ENFORCER:
|
||||
_ROLE_ENFORCER = policy.Enforcer(conf, policy_file=policy_file)
|
||||
_ROLE_ENFORCER.register_defaults(_BASE_RULES)
|
||||
_ROLE_ENFORCER.load_rules(True)
|
||||
|
||||
|
||||
@ -65,3 +80,30 @@ def check_is_advsvc(context):
|
||||
enforcer) and False otherwise.
|
||||
"""
|
||||
return _check_rule(context, _ADVSVC_CTX_POLICY)
|
||||
|
||||
|
||||
def list_rules():
|
||||
return _BASE_RULES
|
||||
|
||||
|
||||
def get_enforcer():
|
||||
# NOTE(amotoki): This was borrowed from nova/policy.py.
|
||||
# This method is for use by oslo.policy CLI scripts. Those scripts need the
|
||||
# 'output-file' and 'namespace' options, but having those in sys.argv means
|
||||
# loading the neutron config options will fail as those are not expected to
|
||||
# be present. So we pass in an arg list with those stripped out.
|
||||
conf_args = []
|
||||
# Start at 1 because cfg.CONF expects the equivalent of sys.argv[1:]
|
||||
i = 1
|
||||
while i < len(sys.argv):
|
||||
if sys.argv[i].strip('-') in ['namespace', 'output-file']:
|
||||
i += 2
|
||||
continue
|
||||
conf_args.append(sys.argv[i])
|
||||
i += 1
|
||||
|
||||
# 'project' must be 'neutron' so that get_enforcer looks at
|
||||
# /etc/neutron/policy.json by default.
|
||||
cfg.CONF(conf_args, project='neutron')
|
||||
init()
|
||||
return _ROLE_ENFORCER
|
||||
|
4
neutron_lib/tests/etc/dummy_policy.json
Normal file
4
neutron_lib/tests/etc/dummy_policy.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"context_is_admin": "role:dummy",
|
||||
"context_is_advsvc": "role:dummy"
|
||||
}
|
@ -39,11 +39,16 @@ class TestPolicyEnforcer(base.BaseTestCase):
|
||||
self.assertTrue(policy.check_is_admin(ctx))
|
||||
|
||||
def test_check_is_admin_no_roles_no_admin(self):
|
||||
policy.init(policy_file='no_policy.json')
|
||||
policy.init(policy_file='dummy_policy.json')
|
||||
ctx = context.Context('me', 'my_project', roles=['user']).elevated()
|
||||
# With no admin role, elevated() should not work.
|
||||
self.assertFalse(policy.check_is_admin(ctx))
|
||||
|
||||
def test_check_user_elevated_is_admin_with_default_policy(self):
|
||||
policy.init(policy_file='no_policy.json')
|
||||
ctx = context.Context('me', 'my_project', roles=['user']).elevated()
|
||||
self.assertTrue(policy.check_is_admin(ctx))
|
||||
|
||||
def test_check_is_advsvc_role(self):
|
||||
ctx = context.Context('me', 'my_project', roles=['advsvc'])
|
||||
self.assertTrue(policy.check_is_advsvc(ctx))
|
||||
@ -58,7 +63,12 @@ class TestPolicyEnforcer(base.BaseTestCase):
|
||||
self.assertFalse(policy.check_is_advsvc(ctx))
|
||||
|
||||
def test_check_is_advsvc_no_roles_no_advsvc(self):
|
||||
policy.init(policy_file='no_policy.json')
|
||||
policy.init(policy_file='dummy_policy.json')
|
||||
ctx = context.Context('me', 'my_project', roles=['advsvc'])
|
||||
# No advsvc role in the policy file, so cannot assume the role.
|
||||
self.assertFalse(policy.check_is_advsvc(ctx))
|
||||
|
||||
def test_check_is_advsvc_role_with_default_policy(self):
|
||||
policy.init(policy_file='no_policy.json')
|
||||
ctx = context.Context('me', 'my_project', roles=['advsvc'])
|
||||
self.assertTrue(policy.check_is_advsvc(ctx))
|
||||
|
8
releasenotes/notes/policy-in-code-1e73cabebd41d66e.yaml
Normal file
8
releasenotes/notes/policy-in-code-1e73cabebd41d66e.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
policy-in-code support in neutron-lib is added.
|
||||
The default policies for 'context_is_admin' and 'context_is_advsvc' are
|
||||
now implemented as embeded policies.
|
||||
(Note that the main policy-in-code support will be implemented
|
||||
in the main neutron codebase.)
|
Loading…
Reference in New Issue
Block a user