From 973498106f242849b294acb286a3ac88385820e0 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Tue, 30 Jan 2024 20:48:38 +0900 Subject: [PATCH] Add flag to skip undefined rule check Some components like neutron-lib builds its own sub-enforcer which enforces policy rules partially. However even these enforcer may load the full policy rules in the file and this causes a lot of warnings about "undefined rules". This introduces a new flag so that users can disable undefined check, when they know the undefined rules are "expected". Note that the flag is not formally exposed, because we don't know if this requirement is common. If we find similar problems with different components then we may add an argument to __init__ . Related-Bug: #2048198 Change-Id: Ibb4e8e877640e8488aaffb40560e930b0cbfcbce --- oslo_policy/policy.py | 6 +++++- oslo_policy/tests/test_policy.py | 24 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/oslo_policy/policy.py b/oslo_policy/policy.py index ea2ab537..9ca53768 100644 --- a/oslo_policy/policy.py +++ b/oslo_policy/policy.py @@ -556,6 +556,10 @@ class Enforcer(object): self.suppress_default_change_warnings = False # FOR TESTING ONLY self.suppress_deprecation_warnings = False + # NOTE(tkajinam): Some components(eg. neutron-lib) build their own + # enforcers to check only partial rules with the full policy rules, and + # this sometimes causes a lot of undefined warnings + self.skip_undefined_check = False def set_rules(self, rules, overwrite=True, use_conf=False): """Create a new :class:`Rules` based on the provided dict of rules. @@ -693,7 +697,7 @@ class Enforcer(object): cyclic_checks = [] violation = False for name, check in self.rules.items(): - if self._undefined_check(check): + if not self.skip_undefined_check and self._undefined_check(check): undefined_checks.append(name) violation = True if self._cycle_check(check): diff --git a/oslo_policy/tests/test_policy.py b/oslo_policy/tests/test_policy.py index fdcdbca1..0d8858ea 100644 --- a/oslo_policy/tests/test_policy.py +++ b/oslo_policy/tests/test_policy.py @@ -1948,6 +1948,18 @@ class EnforcerCheckRulesTest(base.PolicyBaseTestCase): self.assertFalse(self.enforcer.check_rules()) mock_log.warning.assert_called() + @mock.patch.object(policy, 'LOG') + def test_undefined_rule_skipped(self, mock_log): + rules = jsonutils.dumps({'foo': 'rule:bar'}) + self.create_config_file('policy.json', rules) + self.enforcer.skip_undefined_check = True + self.enforcer.load_rules(True) + + self.assertTrue(self.enforcer.check_rules()) + # TODO(tkajinam): This fails because of warnings caused by JSON format + # policy file used + # mock_log.warning.assert_not_called() + @mock.patch.object(policy, 'LOG') def test_undefined_rule_raises(self, mock_log): rules = jsonutils.dumps({'foo': 'rule:bar'}) @@ -1958,6 +1970,18 @@ class EnforcerCheckRulesTest(base.PolicyBaseTestCase): self.enforcer.check_rules, raise_on_violation=True) mock_log.warning.assert_called() + @mock.patch.object(policy, 'LOG') + def test_undefined_rule_raises_skipped(self, mock_log): + rules = jsonutils.dumps({'foo': 'rule:bar'}) + self.create_config_file('policy.json', rules) + self.enforcer.skip_undefined_check = True + self.enforcer.load_rules(True) + + self.assertTrue(self.enforcer.check_rules(raise_on_violation=True)) + # TODO(tkajinam): This fails because of warnings caused by JSON format + # policy file used + # mock_log.warning.assert_not_called() + @mock.patch.object(policy, 'LOG') def test_cyclical_rules(self, mock_log): rules = jsonutils.dumps({'foo': 'rule:bar', 'bar': 'rule:foo'})