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
This commit is contained in:
parent
0e3b3e8671
commit
f17dd1febf
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
"""Policy Engine For Ironic."""
|
"""Policy Engine For Ironic."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
from oslo_concurrency import lockutils
|
from oslo_concurrency import lockutils
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
@ -227,6 +229,27 @@ def get_enforcer():
|
|||||||
return _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
|
# NOTE(deva): We can't call these methods from within decorators because the
|
||||||
# 'target' and 'creds' parameter must be fetched from the call time
|
# 'target' and 'creds' parameter must be fetched from the call time
|
||||||
# context-local pecan.request magic variable, but decorators are compiled
|
# context-local pecan.request magic variable, but decorators are compiled
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import mock
|
||||||
|
from oslo_config import cfg
|
||||||
from oslo_policy import policy as oslo_policy
|
from oslo_policy import policy as oslo_policy
|
||||||
|
|
||||||
from ironic.common import exception
|
from ironic.common import exception
|
||||||
@ -119,3 +123,34 @@ class PolicyTestCase(base.TestCase):
|
|||||||
exception.IronicException,
|
exception.IronicException,
|
||||||
policy.enforce, 'has_foo_role', creds, creds, True,
|
policy.enforce, 'has_foo_role', creds, creds, True,
|
||||||
exception.IronicException)
|
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)
|
||||||
|
14
releasenotes/notes/oslopolicy-scripts-bdcaeaf7dd9ce2ac.yaml
Normal file
14
releasenotes/notes/oslopolicy-scripts-bdcaeaf7dd9ce2ac.yaml
Normal file
@ -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.
|
@ -25,6 +25,9 @@ packages =
|
|||||||
oslo.config.opts =
|
oslo.config.opts =
|
||||||
ironic = ironic.conf.opts:list_opts
|
ironic = ironic.conf.opts:list_opts
|
||||||
|
|
||||||
|
oslo.policy.enforcer =
|
||||||
|
ironic = ironic.common.policy:get_oslo_policy_enforcer
|
||||||
|
|
||||||
oslo.policy.policies =
|
oslo.policy.policies =
|
||||||
ironic.api = ironic.common.policy:list_policies
|
ironic.api = ironic.common.policy:list_policies
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user