Consolidate policy deprecation warnings

Suppress noisy deprecation warnings in favor of a single blanket
warning. Oslopolicy-policy-generator will still emit the same
deprecation warnings, and oslopolicy-policy-upgrade can be used to
migrate existing custom policies to the upgraded version.

This change requires no modification to oslo.policy and so no new
release or requirements bump will be needed.

Change-Id: I3c27c61cee3527b39f6a167b11198ab066614a1d
Closes-bug: #1836568
This commit is contained in:
Colleen Murphy 2019-09-17 23:03:11 -07:00
parent 18e0080af3
commit 15b416c34c
2 changed files with 60 additions and 1 deletions

View File

@ -53,6 +53,40 @@ class RBACEnforcer(object):
# BORG pattern.
self.__dict__ = self.__shared_state__
def _check_deprecated_rule(self, action):
def _name_is_changing(rule):
deprecated_rule = rule.deprecated_rule
return (deprecated_rule and
deprecated_rule.name != rule.name and
deprecated_rule.name in self._enforcer.file_rules)
def _check_str_is_changing(rule):
deprecated_rule = rule.deprecated_rule
return (deprecated_rule and
deprecated_rule.check_str != rule.check_str and
rule.name not in self._enforcer.file_rules)
def _is_deprecated_for_removal(rule):
return (rule.deprecated_for_removal and
rule.name in self._enforcer.file_rules)
def _emit_warning():
if not self._enforcer._warning_emitted:
LOG.warning("Deprecated policy rules found. Use "
"oslopolicy-policy-generator and "
"oslopolicy-policy-upgrade to detect and resolve "
"deprecated policies in your configuration.")
self._enforcer._warning_emitted = True
registered_rule = self._enforcer.registered_rules.get(action)
if not registered_rule:
return
if (_name_is_changing(registered_rule) or
_check_str_is_changing(registered_rule) or
_is_deprecated_for_removal(registered_rule)):
_emit_warning()
def _enforce(self, credentials, action, target, do_raise=True):
"""Verify that the action is valid on the target in this context.
@ -80,8 +114,10 @@ class RBACEnforcer(object):
do_raise=do_raise)
try:
return self._enforcer.enforce(
result = self._enforcer.enforce(
rule=action, target=target, creds=credentials, **extra)
self._check_deprecated_rule(action)
return result
except common_policy.InvalidScope:
raise exception.ForbiddenAction(action=action)
@ -94,9 +130,22 @@ class RBACEnforcer(object):
# The raw oslo-policy enforcer object
if self.__ENFORCER is None:
self.__ENFORCER = common_policy.Enforcer(CONF)
# NOTE(cmurphy) when running in the keystone server, suppress
# deprecation warnings for individual policy rules. Instead, we log
# a single notification at enforcement time indicating the
# oslo.policy tools the operator can use to detect and resolve
# deprecated policies. If there is no request context here, that
# means external tooling such as the oslo.policy tools are running
# this code, in which case we do want the full deprecation warnings
# emitted for individual polcy rules.
if flask.has_request_context():
self.__ENFORCER.suppress_deprecation_warnings = True
# NOTE(cmurphy) Tests may explicitly disable these warnings to
# prevent an explosion of test logs
if self.suppress_deprecation_warnings:
self.__ENFORCER.suppress_deprecation_warnings = True
self.register_rules(self.__ENFORCER)
self.__ENFORCER._warning_emitted = False
return self.__ENFORCER
@staticmethod

View File

@ -0,0 +1,10 @@
---
fixes:
- |
[`bug 1836568 <https://bugs.launchpad.net/keystone/+bug/1836568>`_
Addresses a side effect of the large series of policy migrations in which
the volume of deprecation warnings that were emitted had become too massive
to be helpful. Instead of emitting warnings for individual policy rules,
the keystone server now emits a single warning indicating problematic rules
were found. Operators can use oslopolicy-policy-generator and
oslopolicy-policy-upgrade to find and resolve deprecated policies.