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:
Ghanshyam Mann 2020-04-06 17:17:20 -05:00
parent 8ce161986a
commit 99012db14b
4 changed files with 59 additions and 1 deletions

View File

@ -34,6 +34,17 @@ _options = [
'will be raised. If ``False``, a message will be '
'logged informing operators that policies are being '
'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',
default='policy.json',
help=_('The relative or absolute path of a file that maps '

View File

@ -696,7 +696,10 @@ class Enforcer(object):
# messages telling them stuff is going to change if they don't maintain
# the policy manually or add infrastructure to their deployment to
# 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):
default.check = OrCheck([_parser.parse_rule(cs) for cs in

View File

@ -1619,6 +1619,39 @@ class DocumentedRuleDefaultDeprecationTestCase(base.PolicyBaseTestCase):
# Verify that we didn't overwrite the new rule.
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):

View File

@ -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.