Add new config to enforce the new defaults
When policy change their default check_str and not override by operator then old defaults check_str are added with OrCheck to the new default check_str so that old defaults keep working. If operators want to enforce the new defaults with no old defaults then they have to overwrite the policy rule in poicy file with new default value. This is not expected and very painful for them especially when all policies are switching to new defaults. For example: - https://review.opendev.org/#/q/topic:bp/policy-defaults-refresh+(status:open+OR+status:merged) This commit adds a new config options to control the new defaults enforcement. If True then old defaults will not be supported and also no warning will be logged. New config option is default to False so no change in behaviour for old users. Change-Id: I3c2c889af25b723f1eedbe6167d614c6a4bc6cd2
This commit is contained in:
parent
8ce161986a
commit
99012db14b
@ -34,6 +34,17 @@ _options = [
|
|||||||
'will be raised. If ``False``, a message will be '
|
'will be raised. If ``False``, a message will be '
|
||||||
'logged informing operators that policies are being '
|
'logged informing operators that policies are being '
|
||||||
'invoked with mismatching scope.')),
|
'invoked with mismatching scope.')),
|
||||||
|
cfg.BoolOpt('enforce_new_defaults',
|
||||||
|
default=False,
|
||||||
|
help=_('This option controls whether or not to use old '
|
||||||
|
'deprecated defaults when evaluating policies. If '
|
||||||
|
'``True``, the old deprecated defaults are not going '
|
||||||
|
'to be evaluated which mean if any existing token '
|
||||||
|
'allowed for old defaults but disallowed for new '
|
||||||
|
'defaults will be disallowed. It is encouraged to '
|
||||||
|
'enable this flag along with ``enforce_scope`` flag '
|
||||||
|
'so that you can get benefits of new defaults and '
|
||||||
|
'``scope_type`` together')),
|
||||||
cfg.StrOpt('policy_file',
|
cfg.StrOpt('policy_file',
|
||||||
default='policy.json',
|
default='policy.json',
|
||||||
help=_('The relative or absolute path of a file that maps '
|
help=_('The relative or absolute path of a file that maps '
|
||||||
|
@ -696,7 +696,10 @@ class Enforcer(object):
|
|||||||
# messages telling them stuff is going to change if they don't maintain
|
# messages telling them stuff is going to change if they don't maintain
|
||||||
# the policy manually or add infrastructure to their deployment to
|
# the policy manually or add infrastructure to their deployment to
|
||||||
# support the new policy.
|
# support the new policy.
|
||||||
if (deprecated_rule.check_str != default.check_str
|
# If flag enforce_new_defaults is true then do not add OrCheck
|
||||||
|
# the old check_str and enforce only new defaults.
|
||||||
|
if (not self.conf.oslo_policy.enforce_new_defaults
|
||||||
|
and deprecated_rule.check_str != default.check_str
|
||||||
and default.name not in self.file_rules):
|
and default.name not in self.file_rules):
|
||||||
|
|
||||||
default.check = OrCheck([_parser.parse_rule(cs) for cs in
|
default.check = OrCheck([_parser.parse_rule(cs) for cs in
|
||||||
|
@ -1619,6 +1619,39 @@ class DocumentedRuleDefaultDeprecationTestCase(base.PolicyBaseTestCase):
|
|||||||
# Verify that we didn't overwrite the new rule.
|
# Verify that we didn't overwrite the new rule.
|
||||||
self.assertEqual('bang', self.enforcer.rules['new_rule'].match)
|
self.assertEqual('bang', self.enforcer.rules['new_rule'].match)
|
||||||
|
|
||||||
|
def test_enforce_new_defaults_no_old_check_string(self):
|
||||||
|
self.conf.set_override('enforce_new_defaults', True,
|
||||||
|
group='oslo_policy')
|
||||||
|
deprecated_rule = policy.DeprecatedRule(
|
||||||
|
name='foo:create_bar',
|
||||||
|
check_str='role:fizz'
|
||||||
|
)
|
||||||
|
|
||||||
|
rule_list = [policy.DocumentedRuleDefault(
|
||||||
|
name='foo:create_bar',
|
||||||
|
check_str='role:bang',
|
||||||
|
description='Create a bar.',
|
||||||
|
operations=[{'path': '/v1/bars', 'method': 'POST'}],
|
||||||
|
deprecated_rule=deprecated_rule,
|
||||||
|
deprecated_reason='"role:bang" is a better default',
|
||||||
|
deprecated_since='N'
|
||||||
|
)]
|
||||||
|
enforcer = policy.Enforcer(self.conf)
|
||||||
|
enforcer.register_defaults(rule_list)
|
||||||
|
|
||||||
|
with mock.patch('warnings.warn') as mock_warn:
|
||||||
|
enforcer.load_rules()
|
||||||
|
mock_warn.assert_not_called()
|
||||||
|
self.assertTrue(
|
||||||
|
enforcer.enforce('foo:create_bar', {}, {'roles': ['bang']})
|
||||||
|
)
|
||||||
|
self.assertFalse(
|
||||||
|
enforcer.enforce('foo:create_bar', {}, {'roles': ['fizz']})
|
||||||
|
)
|
||||||
|
self.assertFalse(
|
||||||
|
enforcer.enforce('foo:create_bar', {}, {'roles': ['baz']})
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DocumentedRuleDefaultTestCase(base.PolicyBaseTestCase):
|
class DocumentedRuleDefaultTestCase(base.PolicyBaseTestCase):
|
||||||
|
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
features:
|
||||||
|
- |
|
||||||
|
A new configuration option ``enforce_new_defaults`` has been
|
||||||
|
added to the ``[oslo_policy]`` group to control whether or not to
|
||||||
|
use the old deprecated defaults. If ``True``, the old deprecated
|
||||||
|
defaults are not going to be evaluated which mean if any existing
|
||||||
|
token allowed for old defaults but disallowed for new defaults
|
||||||
|
will be disallowed. It is encouraged to enable this flag along
|
||||||
|
with ``enforce_scope`` flag so that you can get benefits of new
|
||||||
|
defaults and ``scope_type`` together. This way operators can switch
|
||||||
|
to new defaults without overwriting the rule in policy file.
|
Loading…
Reference in New Issue
Block a user