From f17dd1febf974da47be39641e2f5c1b833e087f7 Mon Sep 17 00:00:00 2001 From: Vasyl Saienko Date: Mon, 3 Oct 2016 10:44:08 +0300 Subject: [PATCH] Add entry_point for oslo policy scripts There are two helper scripts in oslo.policy to help deployers understand their policy configuration better. With the setup.cfg entry these can be called directly from oslo.policy. Change-Id: Icfff952f0742b188968603cd3335a3ef50965337 Closes-Bug: #1625804 --- ironic/common/policy.py | 23 ++++++++++++ ironic/tests/unit/common/test_policy.py | 35 +++++++++++++++++++ .../oslopolicy-scripts-bdcaeaf7dd9ce2ac.yaml | 14 ++++++++ setup.cfg | 3 ++ 4 files changed, 75 insertions(+) create mode 100644 releasenotes/notes/oslopolicy-scripts-bdcaeaf7dd9ce2ac.yaml diff --git a/ironic/common/policy.py b/ironic/common/policy.py index 2ff00fb786..89150845b8 100644 --- a/ironic/common/policy.py +++ b/ironic/common/policy.py @@ -15,6 +15,8 @@ """Policy Engine For Ironic.""" +import sys + from oslo_concurrency import lockutils from oslo_config import cfg from oslo_log import log @@ -227,6 +229,27 @@ def get_enforcer(): return _ENFORCER +def get_oslo_policy_enforcer(): + # This method is for use by oslopolicy CLI scripts. Those scripts need the + # 'output-file' and 'namespace' options, but having those in sys.argv means + # loading the Ironic 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 + + cfg.CONF(conf_args, project='ironic') + + return get_enforcer() + + # NOTE(deva): We can't call these methods from within decorators because the # 'target' and 'creds' parameter must be fetched from the call time # context-local pecan.request magic variable, but decorators are compiled diff --git a/ironic/tests/unit/common/test_policy.py b/ironic/tests/unit/common/test_policy.py index 97d3375580..db0a3e437c 100644 --- a/ironic/tests/unit/common/test_policy.py +++ b/ironic/tests/unit/common/test_policy.py @@ -15,6 +15,10 @@ # License for the specific language governing permissions and limitations # under the License. +import sys + +import mock +from oslo_config import cfg from oslo_policy import policy as oslo_policy from ironic.common import exception @@ -119,3 +123,34 @@ class PolicyTestCase(base.TestCase): exception.IronicException, policy.enforce, 'has_foo_role', creds, creds, True, exception.IronicException) + + @mock.patch.object(cfg, 'CONF', autospec=True) + @mock.patch.object(policy, 'get_enforcer', autospec=True) + def test_get_oslo_policy_enforcer_no_args(self, mock_gpe, mock_cfg): + mock_gpe.return_value = mock.Mock() + args = [] + with mock.patch.object(sys, 'argv', args): + policy.get_oslo_policy_enforcer() + mock_cfg.assert_called_once_with([], project='ironic') + self.assertEqual(1, mock_gpe.call_count) + + @mock.patch.object(cfg, 'CONF', autospec=True) + @mock.patch.object(policy, 'get_enforcer', autospec=True) + def test_get_oslo_policy_enforcer_namespace(self, mock_gpe, mock_cfg): + mock_gpe.return_value = mock.Mock() + args = ['opg', '--namespace', 'ironic'] + with mock.patch.object(sys, 'argv', args): + policy.get_oslo_policy_enforcer() + mock_cfg.assert_called_once_with([], project='ironic') + self.assertEqual(1, mock_gpe.call_count) + + @mock.patch.object(cfg, 'CONF', autospec=True) + @mock.patch.object(policy, 'get_enforcer', autospec=True) + def test_get_oslo_policy_enforcer_config_file(self, mock_gpe, mock_cfg): + mock_gpe.return_value = mock.Mock() + args = ['opg', '--namespace', 'ironic', '--config-file', 'my.cfg'] + with mock.patch.object(sys, 'argv', args): + policy.get_oslo_policy_enforcer() + mock_cfg.assert_called_once_with(['--config-file', 'my.cfg'], + project='ironic') + self.assertEqual(1, mock_gpe.call_count) diff --git a/releasenotes/notes/oslopolicy-scripts-bdcaeaf7dd9ce2ac.yaml b/releasenotes/notes/oslopolicy-scripts-bdcaeaf7dd9ce2ac.yaml new file mode 100644 index 0000000000..d510f0fb7e --- /dev/null +++ b/releasenotes/notes/oslopolicy-scripts-bdcaeaf7dd9ce2ac.yaml @@ -0,0 +1,14 @@ +--- +features: + - Ironic is now configured to work with two oslo.policy CLI scripts that have + been added. + + The first of these can be called like + "oslopolicy-list-redundant --namespace ironic" and will output a list of + policy rules in policy.[json|yaml] that match the project defaults. These + rules can be removed from the policy file as they have no effect there. + + The second script can be called like + "oslopolicy-policy-generator --namespace ironic --output-file policy-merged.yaml" + and will populate the policy-merged.yaml file with the effective policy. + This is the merged results of project defaults and config file overrides. diff --git a/setup.cfg b/setup.cfg index 2d89debf52..1a29d88edc 100644 --- a/setup.cfg +++ b/setup.cfg @@ -25,6 +25,9 @@ packages = oslo.config.opts = ironic = ironic.conf.opts:list_opts +oslo.policy.enforcer = + ironic = ironic.common.policy:get_oslo_policy_enforcer + oslo.policy.policies = ironic.api = ironic.common.policy:list_policies