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
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_policy import policy
|
from oslo_policy import policy
|
||||||
|
|
||||||
@ -19,6 +21,18 @@ _ADMIN_CTX_POLICY = 'context_is_admin'
|
|||||||
_ADVSVC_CTX_POLICY = 'context_is_advsvc'
|
_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):
|
def init(conf=cfg.CONF, policy_file=None):
|
||||||
"""Initialize the global enforcer if not already initialized.
|
"""Initialize the global enforcer if not already initialized.
|
||||||
|
|
||||||
@ -35,6 +49,7 @@ def init(conf=cfg.CONF, policy_file=None):
|
|||||||
global _ROLE_ENFORCER
|
global _ROLE_ENFORCER
|
||||||
if not _ROLE_ENFORCER:
|
if not _ROLE_ENFORCER:
|
||||||
_ROLE_ENFORCER = policy.Enforcer(conf, policy_file=policy_file)
|
_ROLE_ENFORCER = policy.Enforcer(conf, policy_file=policy_file)
|
||||||
|
_ROLE_ENFORCER.register_defaults(_BASE_RULES)
|
||||||
_ROLE_ENFORCER.load_rules(True)
|
_ROLE_ENFORCER.load_rules(True)
|
||||||
|
|
||||||
|
|
||||||
@ -65,3 +80,30 @@ def check_is_advsvc(context):
|
|||||||
enforcer) and False otherwise.
|
enforcer) and False otherwise.
|
||||||
"""
|
"""
|
||||||
return _check_rule(context, _ADVSVC_CTX_POLICY)
|
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))
|
self.assertTrue(policy.check_is_admin(ctx))
|
||||||
|
|
||||||
def test_check_is_admin_no_roles_no_admin(self):
|
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()
|
ctx = context.Context('me', 'my_project', roles=['user']).elevated()
|
||||||
# With no admin role, elevated() should not work.
|
# With no admin role, elevated() should not work.
|
||||||
self.assertFalse(policy.check_is_admin(ctx))
|
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):
|
def test_check_is_advsvc_role(self):
|
||||||
ctx = context.Context('me', 'my_project', roles=['advsvc'])
|
ctx = context.Context('me', 'my_project', roles=['advsvc'])
|
||||||
self.assertTrue(policy.check_is_advsvc(ctx))
|
self.assertTrue(policy.check_is_advsvc(ctx))
|
||||||
@ -58,7 +63,12 @@ class TestPolicyEnforcer(base.BaseTestCase):
|
|||||||
self.assertFalse(policy.check_is_advsvc(ctx))
|
self.assertFalse(policy.check_is_advsvc(ctx))
|
||||||
|
|
||||||
def test_check_is_advsvc_no_roles_no_advsvc(self):
|
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'])
|
ctx = context.Context('me', 'my_project', roles=['advsvc'])
|
||||||
# No advsvc role in the policy file, so cannot assume the role.
|
# No advsvc role in the policy file, so cannot assume the role.
|
||||||
self.assertFalse(policy.check_is_advsvc(ctx))
|
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.)
|
@ -22,6 +22,12 @@ classifier =
|
|||||||
packages =
|
packages =
|
||||||
neutron_lib
|
neutron_lib
|
||||||
|
|
||||||
|
[entry_points]
|
||||||
|
oslo.policy.enforcer =
|
||||||
|
neutron_lib = neutron_lib._policy:get_enforcer
|
||||||
|
oslo.policy.policies =
|
||||||
|
neutron_lib = neutron_lib._policy:list_rules
|
||||||
|
|
||||||
[compile_catalog]
|
[compile_catalog]
|
||||||
directory = neutron_lib/locale
|
directory = neutron_lib/locale
|
||||||
domain = neutron_lib
|
domain = neutron_lib
|
||||||
|
Loading…
Reference in New Issue
Block a user