Support policy file in YAML

YAML provides the advantage of being able to add comments.

bp policy-yaml

Change-Id: Ic6236665f2d55b24a56a99120ac57fc2b18e32eb
This commit is contained in:
Brant Knudson 2016-02-10 10:54:25 -06:00
parent 5fb13edfe6
commit 83d209e9ed
3 changed files with 44 additions and 5 deletions

View File

@ -221,6 +221,7 @@ import os
from oslo_config import cfg
from oslo_serialization import jsonutils
import six
import yaml
from oslo_policy import _cache_handler
from oslo_policy import _checks
@ -299,11 +300,17 @@ class Rules(dict):
@classmethod
def load_json(cls, data, default_rule=None):
"""Allow loading of JSON rule data."""
"""Allow loading of YAML/JSON rule data."""
# Suck in the JSON data and parse the rules
rules = {k: _parser.parse_rule(v)
for k, v in jsonutils.loads(data).items()}
try:
parsed = yaml.safe_load(data)
except yaml.YAMLError as e:
# For backwards-compatibility, convert yaml error to ValueError,
# which is what JSON loader raised.
raise ValueError(six.text_type(e))
# Parse the rules
rules = {k: _parser.parse_rule(v) for k, v in parsed.items()}
return cls(rules, default_rule)

View File

@ -101,7 +101,38 @@ class RulesTestCase(test_base.BaseTestCase):
# Note the trailing , in the exemplar is invalid JSON.
exemplar = """{
"admin_or_owner": [["role:admin"], ["project_id:%(project_id)s"]],
"default": [],
"default": [
}"""
self.assertRaises(ValueError, policy.Rules.load_json, exemplar,
'default')
@mock.patch.object(_parser, 'parse_rule', lambda x: x)
def test_load_yaml(self):
# Test that simplified YAML can be used with load_json.
# Show that YAML allows useful comments.
exemplar = """
# Define a custom rule.
admin_or_owner: role:admin or project_id:%(project_id)s
# The default rule is used when there's no action defined.
default: []
"""
rules = policy.Rules.load_json(exemplar, 'default')
self.assertEqual('default', rules.default_rule)
self.assertEqual(dict(
admin_or_owner='role:admin or project_id:%(project_id)s',
default=[],
), rules)
@mock.patch.object(_parser, 'parse_rule', lambda x: x)
def test_load_yaml_invalid_exc(self):
# When the JSON isn't valid, ValueError is raised on load_json.
# Note the trailing , in the exemplar is invalid JSON.
exemplar = """{
# Define a custom rule.
admin_or_owner: role:admin or project_id:%(project_id)s
# The default rule is used when there's no action defined.
default: [
}"""
self.assertRaises(ValueError, policy.Rules.load_json, exemplar,
'default')

View File

@ -7,4 +7,5 @@ oslo.config>=3.4.0 # Apache-2.0
oslo.i18n>=2.1.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
oslo.utils>=3.5.0 # Apache-2.0
PyYAML>=3.1.0 # MIT
six>=1.9.0 # MIT