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:
Kevin L. Mitchell 2012-06-04 18:49:19 -05:00
parent bf9fd420ae
commit 18ed0b0940
6 changed files with 32 additions and 19 deletions

View File

@ -18,12 +18,12 @@
"""Common Policy Engine Implementation"""
import json
import logging
import urllib
import urllib2
class NotAuthorized(Exception):
pass
LOG = logging.getLogger(__name__)
_BRAIN = None
@ -45,7 +45,8 @@ def reset():
_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.
: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
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
if not _BRAIN:
_BRAIN = Brain()
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):
@ -132,7 +143,12 @@ class Brain(object):
self.rules[key] = match
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:
f = getattr(self, '_check_%s' % match_kind)
except AttributeError:

View File

@ -19,10 +19,10 @@
import os.path
from nova.common import policy
from nova import exception
from nova import flags
from nova.openstack.common import cfg
from nova.openstack.common import policy
from nova import utils
@ -90,7 +90,5 @@ def enforce(context, action, target):
match_list = ('rule:%s' % action,)
credentials = context.to_dict()
try:
policy.enforce(match_list, target, credentials)
except policy.NotAuthorized:
raise exception.PolicyNotAuthorized(action=action)
policy.enforce(match_list, target, credentials,
exception.PolicyNotAuthorized, action=action)

View File

@ -22,10 +22,10 @@ from lxml import etree
import webob
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 import context
from nova import flags
from nova.openstack.common import policy as common_policy
from nova import policy
from nova import test
from nova.tests.api.openstack import fakes

View File

@ -26,7 +26,6 @@ import time
import mox
import nova
import nova.common.policy
from nova import compute
from nova.compute import aggregate_states
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.notifier import test_notifier
from nova.openstack.common import importutils
from nova.openstack.common import policy as common_policy
import nova.policy
from nova import quota
from nova import rpc
@ -3945,7 +3945,7 @@ class ComputePolicyTestCase(BaseTestCase):
nova.policy.reset()
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):
self.mox.StubOutWithMock(nova.policy, 'enforce')

View File

@ -21,11 +21,10 @@ import os.path
import StringIO
import urllib2
from nova.common import policy as common_policy
import nova.common.policy
from nova import context
from nova import exception
from nova import flags
from nova.openstack.common import policy as common_policy
from nova import policy
from nova import test
from nova import utils
@ -169,8 +168,8 @@ class DefaultPolicyTestCase(test.TestCase):
self.context = context.RequestContext('fake', 'fake')
def _set_brain(self, default_rule):
brain = nova.common.policy.HttpBrain(self.rules, default_rule)
nova.common.policy.set_brain(brain)
brain = common_policy.HttpBrain(self.rules, default_rule)
common_policy.set_brain(brain)
def tearDown(self):
super(DefaultPolicyTestCase, self).tearDown()

View File

@ -1,7 +1,7 @@
[DEFAULT]
# 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
base=nova