summaryrefslogtreecommitdiff
path: root/oslo_policy
diff options
context:
space:
mode:
authorwangxiyuan <wangxiyuan@huawei.com>2018-10-29 20:00:19 +0800
committerwangxiyuan <wangxiyuan@huawei.com>2018-12-11 10:32:47 +0800
commitab28b32ee9a0b7c08d2f4273dd523670ffbec9a2 (patch)
tree2233318d8da799a1f9461d6adb284846f9698eec /oslo_policy
parentb9fd10e2612f26c93d49c168a0408aba6d20e5bf (diff)
downloadoslo-policy-ab28b32ee9a0b7c08d2f4273dd523670ffbec9a2.tar.gz
Add policy-upgrade tool
Add a new "oslopolicy-policy-upgrade" commnd. Using this command, operator can upgrade their self-defined policy files to follow the new format in the new release when upgrading OpenStack services. Change-Id: Iad9740bd8a5e4fdf1d1e64d61bc93f2483c531f3
Diffstat (limited to 'oslo_policy')
-rw-r--r--oslo_policy/generator.py50
-rw-r--r--oslo_policy/tests/test_generator.py103
2 files changed, 153 insertions, 0 deletions
diff --git a/oslo_policy/generator.py b/oslo_policy/generator.py
index 4e1489c..c6ecd5b 100644
--- a/oslo_policy/generator.py
+++ b/oslo_policy/generator.py
@@ -14,8 +14,10 @@ import logging
import sys
import textwrap
import warnings
+import yaml
from oslo_config import cfg
+from oslo_serialization import jsonutils
import stevedore
from oslo_policy import policy
@@ -45,6 +47,12 @@ ENFORCER_OPTS = [
'which to look for a policy.Enforcer.'),
]
+UPGRADE_OPTS = [
+ cfg.StrOpt('policy',
+ required=True,
+ help='Path to the policy file which need to be updated.')
+]
+
def get_policies_dict(namespaces):
"""Find the options available via the given namespaces.
@@ -330,6 +338,48 @@ def generate_policy(args=None):
_generate_policy(conf.namespace, conf.output_file)
+def _upgrade_policies(policies, default_policies):
+ old_policies_keys = list(policies.keys())
+ for section in sorted(default_policies.keys()):
+ rule_defaults = default_policies[section]
+ for rule_default in rule_defaults:
+ if (rule_default.deprecated_rule and
+ rule_default.deprecated_rule.name in old_policies_keys):
+ policies[rule_default.name] = policies.pop(
+ rule_default.deprecated_rule.name)
+ LOG.info('The name of policy %(old_name)s has been upgraded to'
+ '%(new_name)',
+ {'old_name': rule_default.deprecated_rule.name,
+ 'new_name': rule_default.name})
+
+
+def upgrade_policy(args=None):
+ logging.basicConfig(level=logging.WARN)
+ conf = cfg.ConfigOpts()
+ conf.register_cli_opts(GENERATOR_OPTS + RULE_OPTS + UPGRADE_OPTS)
+ conf.register_opts(GENERATOR_OPTS + RULE_OPTS + UPGRADE_OPTS)
+ conf(args)
+ with open(conf.policy, 'r') as input_data:
+ policies = policy.parse_file_contents(input_data.read())
+ default_policies = get_policies_dict(conf.namespace)
+
+ _upgrade_policies(policies, default_policies)
+
+ if conf.output_file:
+ if conf.format == 'yaml':
+ yaml.safe_dump(policies, open(conf.output_file, 'w'),
+ default_flow_style=False)
+ elif conf.format == 'json':
+ jsonutils.dump(policies, open(conf.output_file, 'w'),
+ indent=4)
+ else:
+ if conf.format == 'yaml':
+ sys.stdout.write(yaml.safe_dump(policies,
+ default_flow_style=False))
+ elif conf.format == 'json':
+ sys.stdout.write(jsonutils.dumps(policies, indent=4))
+
+
def list_redundant(args=None):
logging.basicConfig(level=logging.WARN)
conf = cfg.ConfigOpts()
diff --git a/oslo_policy/tests/test_generator.py b/oslo_policy/tests/test_generator.py
index 06d9de9..98355ff 100644
--- a/oslo_policy/tests/test_generator.py
+++ b/oslo_policy/tests/test_generator.py
@@ -16,10 +16,12 @@ import mock
from oslo_config import cfg
import stevedore
import testtools
+import yaml
from oslo_policy import generator
from oslo_policy import policy
from oslo_policy.tests import base
+from oslo_serialization import jsonutils
OPTS = {'base_rules': [policy.RuleDefault('admin', 'is_admin:True',
@@ -572,3 +574,104 @@ class ListRedundantTestCase(base.PolicyBaseTestCase):
opt1 = matches[1]
self.assertEqual('"owner"', opt1[0])
self.assertEqual('"project_id:%(project_id)s"', opt1[1])
+
+
+class UpgradePolicyTestCase(base.PolicyBaseTestCase):
+ def setUp(self):
+ super(UpgradePolicyTestCase, self).setUp()
+ policy_json_contents = jsonutils.dumps({
+ "deprecated_name": "rule:admin"
+ })
+ self.create_config_file('policy.json', policy_json_contents)
+ deprecated_policy = policy.DeprecatedRule(
+ name='deprecated_name',
+ check_str='rule:admin'
+ )
+ self.new_policy = policy.DocumentedRuleDefault(
+ name='new_policy_name',
+ check_str='rule:admin',
+ description='test_policy',
+ operations=[{'path': '/test', 'method': 'GET'}],
+ deprecated_rule=deprecated_policy,
+ deprecated_reason='test',
+ deprecated_since='Stein'
+ )
+ self.extensions = []
+ ext = stevedore.extension.Extension(name='test_upgrade',
+ entry_point=None,
+ plugin=None,
+ obj=[self.new_policy])
+ self.extensions.append(ext)
+
+ def test_upgrade_policy_json_file(self):
+ test_mgr = stevedore.named.NamedExtensionManager.make_test_instance(
+ extensions=self.extensions, namespace='test_upgrade')
+ with mock.patch('stevedore.named.NamedExtensionManager',
+ return_value=test_mgr):
+ testargs = ['olsopolicy-policy-upgrade',
+ '--policy',
+ self.get_config_file_fullname('policy.json'),
+ '--namespace', 'test_upgrade',
+ '--output-file',
+ self.get_config_file_fullname('new_policy.json'),
+ '--format', 'json']
+ with mock.patch('sys.argv', testargs):
+ generator.upgrade_policy()
+ new_file = self.get_config_file_fullname('new_policy.json')
+ new_policy = jsonutils.loads(open(new_file, 'r').read())
+ self.assertIsNotNone(new_policy.get('new_policy_name'))
+ self.assertIsNone(new_policy.get('deprecated_name'))
+
+ def test_upgrade_policy_yaml_file(self):
+ test_mgr = stevedore.named.NamedExtensionManager.make_test_instance(
+ extensions=self.extensions, namespace='test_upgrade')
+ with mock.patch('stevedore.named.NamedExtensionManager',
+ return_value=test_mgr):
+ testargs = ['olsopolicy-policy-upgrade',
+ '--policy',
+ self.get_config_file_fullname('policy.json'),
+ '--namespace', 'test_upgrade',
+ '--output-file',
+ self.get_config_file_fullname('new_policy.yaml'),
+ '--format', 'yaml']
+ with mock.patch('sys.argv', testargs):
+ generator.upgrade_policy()
+ new_file = self.get_config_file_fullname('new_policy.yaml')
+ new_policy = yaml.safe_load(open(new_file, 'r'))
+ self.assertIsNotNone(new_policy.get('new_policy_name'))
+ self.assertIsNone(new_policy.get('deprecated_name'))
+
+ def test_upgrade_policy_json_stdout(self):
+ test_mgr = stevedore.named.NamedExtensionManager.make_test_instance(
+ extensions=self.extensions, namespace='test_upgrade')
+ stdout = self._capture_stdout()
+ with mock.patch('stevedore.named.NamedExtensionManager',
+ return_value=test_mgr):
+ testargs = ['olsopolicy-policy-upgrade',
+ '--policy',
+ self.get_config_file_fullname('policy.json'),
+ '--namespace', 'test_upgrade',
+ '--format', 'json']
+ with mock.patch('sys.argv', testargs):
+ generator.upgrade_policy()
+ expected = '''{
+ "new_policy_name": "rule:admin"
+}'''
+ self.assertEqual(expected, stdout.getvalue())
+
+ def test_upgrade_policy_yaml_stdout(self):
+ test_mgr = stevedore.named.NamedExtensionManager.make_test_instance(
+ extensions=self.extensions, namespace='test_upgrade')
+ stdout = self._capture_stdout()
+ with mock.patch('stevedore.named.NamedExtensionManager',
+ return_value=test_mgr):
+ testargs = ['olsopolicy-policy-upgrade',
+ '--policy',
+ self.get_config_file_fullname('policy.json'),
+ '--namespace', 'test_upgrade',
+ '--format', 'yaml']
+ with mock.patch('sys.argv', testargs):
+ generator.upgrade_policy()
+ expected = '''new_policy_name: rule:admin
+'''
+ self.assertEqual(expected, stdout.getvalue())