Use openstack-common's policy module
Reworks nova to use the new policy module in openstack-common. Change-Id: Iea8651bad85f26804285616330107d9d5f23e6cb
This commit is contained in:
@@ -18,12 +18,12 @@
|
|||||||
"""Common Policy Engine Implementation"""
|
"""Common Policy Engine Implementation"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
import urllib
|
import urllib
|
||||||
import urllib2
|
import urllib2
|
||||||
|
|
||||||
|
|
||||||
class NotAuthorized(Exception):
|
LOG = logging.getLogger(__name__)
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
_BRAIN = None
|
_BRAIN = None
|
||||||
@@ -45,7 +45,8 @@ def reset():
|
|||||||
_BRAIN = None
|
_BRAIN = None
|
||||||
|
|
||||||
|
|
||||||
def enforce(match_list, target_dict, credentials_dict):
|
def enforce(match_list, target_dict, credentials_dict, exc=None,
|
||||||
|
*args, **kwargs):
|
||||||
"""Enforces authorization of some rules against credentials.
|
"""Enforces authorization of some rules against credentials.
|
||||||
|
|
||||||
:param match_list: nested tuples of data to match against
|
:param match_list: nested tuples of data to match against
|
||||||
@@ -106,14 +107,24 @@ def enforce(match_list, target_dict, credentials_dict):
|
|||||||
Credentials dicts contain as much information as we can about the user
|
Credentials dicts contain as much information as we can about the user
|
||||||
performing the action.
|
performing the action.
|
||||||
|
|
||||||
:raises NotAuthorized: if the check fails
|
:param exc: exception to raise
|
||||||
|
|
||||||
|
Class of the exception to raise if the check fails. Any remaining
|
||||||
|
arguments passed to enforce() (both positional and keyword arguments)
|
||||||
|
will be passed to the exception class. If exc is not provided, returns
|
||||||
|
False.
|
||||||
|
|
||||||
|
:return: True if the policy allows the action
|
||||||
|
:return: False if the policy does not allow the action and exc is not set
|
||||||
"""
|
"""
|
||||||
global _BRAIN
|
global _BRAIN
|
||||||
if not _BRAIN:
|
if not _BRAIN:
|
||||||
_BRAIN = Brain()
|
_BRAIN = Brain()
|
||||||
if not _BRAIN.check(match_list, target_dict, credentials_dict):
|
if not _BRAIN.check(match_list, target_dict, credentials_dict):
|
||||||
raise NotAuthorized()
|
if exc:
|
||||||
|
raise exc(*args, **kwargs)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Brain(object):
|
class Brain(object):
|
||||||
@@ -132,7 +143,12 @@ class Brain(object):
|
|||||||
self.rules[key] = match
|
self.rules[key] = match
|
||||||
|
|
||||||
def _check(self, match, target_dict, cred_dict):
|
def _check(self, match, target_dict, cred_dict):
|
||||||
match_kind, match_value = match.split(':', 1)
|
try:
|
||||||
|
match_kind, match_value = match.split(':', 1)
|
||||||
|
except Exception:
|
||||||
|
LOG.exception(_("Failed to understand rule %(match)r") % locals())
|
||||||
|
# If the rule is invalid, fail closed
|
||||||
|
return False
|
||||||
try:
|
try:
|
||||||
f = getattr(self, '_check_%s' % match_kind)
|
f = getattr(self, '_check_%s' % match_kind)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
@@ -19,10 +19,10 @@
|
|||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
from nova.common import policy
|
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import flags
|
from nova import flags
|
||||||
from nova.openstack.common import cfg
|
from nova.openstack.common import cfg
|
||||||
|
from nova.openstack.common import policy
|
||||||
from nova import utils
|
from nova import utils
|
||||||
|
|
||||||
|
|
||||||
@@ -90,7 +90,5 @@ def enforce(context, action, target):
|
|||||||
match_list = ('rule:%s' % action,)
|
match_list = ('rule:%s' % action,)
|
||||||
credentials = context.to_dict()
|
credentials = context.to_dict()
|
||||||
|
|
||||||
try:
|
policy.enforce(match_list, target, credentials,
|
||||||
policy.enforce(match_list, target, credentials)
|
exception.PolicyNotAuthorized, action=action)
|
||||||
except policy.NotAuthorized:
|
|
||||||
raise exception.PolicyNotAuthorized(action=action)
|
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ from lxml import etree
|
|||||||
import webob
|
import webob
|
||||||
|
|
||||||
from nova.api.openstack.compute.contrib import simple_tenant_usage
|
from nova.api.openstack.compute.contrib import simple_tenant_usage
|
||||||
from nova.common import policy as common_policy
|
|
||||||
from nova.compute import api
|
from nova.compute import api
|
||||||
from nova import context
|
from nova import context
|
||||||
from nova import flags
|
from nova import flags
|
||||||
|
from nova.openstack.common import policy as common_policy
|
||||||
from nova import policy
|
from nova import policy
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova.tests.api.openstack import fakes
|
from nova.tests.api.openstack import fakes
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import time
|
|||||||
import mox
|
import mox
|
||||||
|
|
||||||
import nova
|
import nova
|
||||||
import nova.common.policy
|
|
||||||
from nova import compute
|
from nova import compute
|
||||||
from nova.compute import aggregate_states
|
from nova.compute import aggregate_states
|
||||||
from nova.compute import api as compute_api
|
from nova.compute import api as compute_api
|
||||||
@@ -44,6 +43,7 @@ from nova.image import fake as fake_image
|
|||||||
from nova import log as logging
|
from nova import log as logging
|
||||||
from nova.notifier import test_notifier
|
from nova.notifier import test_notifier
|
||||||
from nova.openstack.common import importutils
|
from nova.openstack.common import importutils
|
||||||
|
from nova.openstack.common import policy as common_policy
|
||||||
import nova.policy
|
import nova.policy
|
||||||
from nova import quota
|
from nova import quota
|
||||||
from nova import rpc
|
from nova import rpc
|
||||||
@@ -3945,7 +3945,7 @@ class ComputePolicyTestCase(BaseTestCase):
|
|||||||
nova.policy.reset()
|
nova.policy.reset()
|
||||||
|
|
||||||
def _set_rules(self, rules):
|
def _set_rules(self, rules):
|
||||||
nova.common.policy.set_brain(nova.common.policy.HttpBrain(rules))
|
common_policy.set_brain(common_policy.HttpBrain(rules))
|
||||||
|
|
||||||
def test_actions_are_prefixed(self):
|
def test_actions_are_prefixed(self):
|
||||||
self.mox.StubOutWithMock(nova.policy, 'enforce')
|
self.mox.StubOutWithMock(nova.policy, 'enforce')
|
||||||
|
|||||||
@@ -21,11 +21,10 @@ import os.path
|
|||||||
import StringIO
|
import StringIO
|
||||||
import urllib2
|
import urllib2
|
||||||
|
|
||||||
from nova.common import policy as common_policy
|
|
||||||
import nova.common.policy
|
|
||||||
from nova import context
|
from nova import context
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import flags
|
from nova import flags
|
||||||
|
from nova.openstack.common import policy as common_policy
|
||||||
from nova import policy
|
from nova import policy
|
||||||
from nova import test
|
from nova import test
|
||||||
from nova import utils
|
from nova import utils
|
||||||
@@ -169,8 +168,8 @@ class DefaultPolicyTestCase(test.TestCase):
|
|||||||
self.context = context.RequestContext('fake', 'fake')
|
self.context = context.RequestContext('fake', 'fake')
|
||||||
|
|
||||||
def _set_brain(self, default_rule):
|
def _set_brain(self, default_rule):
|
||||||
brain = nova.common.policy.HttpBrain(self.rules, default_rule)
|
brain = common_policy.HttpBrain(self.rules, default_rule)
|
||||||
nova.common.policy.set_brain(brain)
|
common_policy.set_brain(brain)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super(DefaultPolicyTestCase, self).tearDown()
|
super(DefaultPolicyTestCase, self).tearDown()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
|
|
||||||
# The list of modules to copy from openstack-common
|
# The list of modules to copy from openstack-common
|
||||||
modules=cfg,excutils,local,importutils,iniparser,jsonutils,setup
|
modules=cfg,excutils,local,importutils,iniparser,jsonutils,setup,policy
|
||||||
|
|
||||||
# The base module to hold the copy of openstack.common
|
# The base module to hold the copy of openstack.common
|
||||||
base=nova
|
base=nova
|
||||||
|
|||||||
Reference in New Issue
Block a user