summaryrefslogtreecommitdiff
path: root/oslo_policy/policy.py
diff options
context:
space:
mode:
Diffstat (limited to 'oslo_policy/policy.py')
-rw-r--r--oslo_policy/policy.py105
1 files changed, 69 insertions, 36 deletions
diff --git a/oslo_policy/policy.py b/oslo_policy/policy.py
index 903f65b..892e5d4 100644
--- a/oslo_policy/policy.py
+++ b/oslo_policy/policy.py
@@ -225,6 +225,7 @@ import collections.abc
import copy
import logging
import os
+import typing as ty
import warnings
from oslo_config import cfg
@@ -704,6 +705,10 @@ class Enforcer(object):
return
deprecated_rule = default.deprecated_rule
+ deprecated_reason = (
+ deprecated_rule.deprecated_reason or default.deprecated_reason)
+ deprecated_since = (
+ deprecated_rule.deprecated_since or default.deprecated_since)
deprecated_msg = (
'Policy "%(old_name)s":"%(old_check_str)s" was deprecated in '
@@ -713,10 +718,10 @@ class Enforcer(object):
'file and maintain it manually.' % {
'old_name': deprecated_rule.name,
'old_check_str': deprecated_rule.check_str,
- 'release': default.deprecated_since,
+ 'release': deprecated_since,
'name': default.name,
'check_str': default.check_str,
- 'reason': default.deprecated_reason
+ 'reason': deprecated_reason,
}
)
@@ -1163,21 +1168,20 @@ class RuleDefault(object):
:param scope_types: A list containing the intended scopes of the operation
being done.
- .. versionchanged 1.29
+ .. versionchanged:: 1.29
Added *deprecated_rule* parameter.
- .. versionchanged 1.29
+ .. versionchanged:: 1.29
Added *deprecated_for_removal* parameter.
- .. versionchanged 1.29
+ .. versionchanged:: 1.29
Added *deprecated_reason* parameter.
- .. versionchanged 1.29
+ .. versionchanged:: 1.29
Added *deprecated_since* parameter.
- .. versionchanged 1.31
+ .. versionchanged:: 1.31
Added *scope_types* parameter.
-
"""
def __init__(self, name, check_str, description=None,
deprecated_rule=None, deprecated_for_removal=False,
@@ -1199,13 +1203,23 @@ class RuleDefault(object):
'deprecated_rule must be a DeprecatedRule object.'
)
- if (deprecated_for_removal or deprecated_rule) and (
- deprecated_reason is None or deprecated_since is None):
- raise ValueError(
- '%(name)s deprecated without deprecated_reason or '
- 'deprecated_since. Both must be supplied if deprecating a '
- 'policy' % {'name': self.name}
- )
+ # if this rule is being deprecated, we need to provide a deprecation
+ # reason here, but if this rule is replacing another rule, then the
+ # deprecation reason belongs on that other rule
+ if deprecated_for_removal:
+ if deprecated_reason is None or deprecated_since is None:
+ raise ValueError(
+ '%(name)s deprecated without deprecated_reason or '
+ 'deprecated_since. Both must be supplied if deprecating a '
+ 'policy' % {'name': self.name}
+ )
+ elif deprecated_rule and (deprecated_reason or deprecated_since):
+ warnings.warn(
+ f'{name} should not configure deprecated_reason or '
+ f'deprecated_since as these should be configured on the '
+ f'DeprecatedRule indicated by deprecated_rule. '
+ f'This will be an error in a future release',
+ DeprecationWarning)
if scope_types:
msg = 'scope_types must be a list of strings.'
@@ -1330,6 +1344,8 @@ class DeprecatedRule(object):
deprecated_rule = policy.DeprecatedRule(
name='foo:create_bar',
check_str='role:fizz'
+ deprecated_reason='role:bang is a better default',
+ deprecated_since='N',
)
policy.DocumentedRuleDefault(
@@ -1338,8 +1354,6 @@ class DeprecatedRule(object):
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'
)
DeprecatedRule can be used to change the policy name itself. Assume the
@@ -1361,6 +1375,8 @@ class DeprecatedRule(object):
deprecated_rule = policy.DeprecatedRule(
name='foo:post_bar',
check_str='role:fizz'
+ deprecated_reason='foo:create_bar is more consistent',
+ deprecated_since='N',
)
policy.DocumentedRuleDefault(
@@ -1369,8 +1385,6 @@ class DeprecatedRule(object):
description='Create a bar.',
operations=[{'path': '/v1/bars', 'method': 'POST'}],
deprecated_rule=deprecated_rule,
- deprecated_reason='foo:create_bar is more consistent',
- deprecated_since='N'
)
Finally, let's use DeprecatedRule to break a policy into more granular
@@ -1415,6 +1429,10 @@ class DeprecatedRule(object):
deprecated_rule = policy.DeprecatedRule(
name='foo:bar',
check_str='role:bazz'
+ deprecated_reason=(
+ 'foo:bar has been replaced by more granular policies'
+ ),
+ deprecated_since='N',
)
policy.DocumentedRuleDefault(
@@ -1423,8 +1441,6 @@ class DeprecatedRule(object):
description='Create a bar.',
operations=[{'path': '/v1/bars', 'method': 'POST'}],
deprecated_rule=deprecated_rule,
- deprecated_reason='foo:create_bar is more granular than foo:bar',
- deprecated_since='N'
)
policy.DocumentedRuleDefault(
name='foo:list_bars',
@@ -1432,8 +1448,6 @@ class DeprecatedRule(object):
description='List bars.',
operations=[{'path': '/v1/bars', 'method': 'GET'}],
deprecated_rule=deprecated_rule,
- deprecated_reason='foo:list_bars is more granular than foo:bar',
- deprecated_since='N'
)
policy.DocumentedRuleDefault(
name='foo:get_bar',
@@ -1441,8 +1455,6 @@ class DeprecatedRule(object):
description='Get a bar.',
operations=[{'path': '/v1/bars/{bar_id}', 'method': 'GET'}],
deprecated_rule=deprecated_rule,
- deprecated_reason='foo:get_bar is more granular than foo:bar',
- deprecated_since='N'
)
policy.DocumentedRuleDefault(
name='foo:update_bar',
@@ -1450,8 +1462,6 @@ class DeprecatedRule(object):
description='Update a bar.',
operations=[{'path': '/v1/bars/{bar_id}', 'method': 'PATCH'}],
deprecated_rule=deprecated_rule,
- deprecated_reason='foo:update_bar is more granular than foo:bar',
- deprecated_since='N'
)
policy.DocumentedRuleDefault(
name='foo:delete_bar',
@@ -1459,19 +1469,42 @@ class DeprecatedRule(object):
description='Delete a bar.',
operations=[{'path': '/v1/bars/{bar_id}', 'method': 'DELETE'}],
deprecated_rule=deprecated_rule,
- deprecated_reason='foo:delete_bar is more granular than foo:bar',
- deprecated_since='N'
)
- .. versionchanged 1.29
+ :param name: The name of the policy. This is used when referencing it
+ from another rule or during policy enforcement.
+ :param check_str: The policy. This is a string defining a policy that
+ conforms to the policy language outlined at the top of the file.
+ :param deprecated_reason: indicates why this policy is planned for removal
+ in a future release.
+ :param deprecated_since: indicates which release this policy was deprecated
+ in. Accepts any string, though valid version strings are encouraged.
+
+ .. versionchanged:: 1.29
Added *DeprecatedRule* object.
- """
- def __init__(self, name, check_str):
- """Construct a DeprecatedRule object.
+ .. versionchanged:: 3.4
+ Added *deprecated_reason* parameter.
- :param name: the policy name
- :param check_str: the value of the policy's check string
- """
+ .. versionchanged:: 3.4
+ Added *deprecated_since* parameter.
+ """
+
+ def __init__(
+ self,
+ name: str,
+ check_str: str,
+ *,
+ deprecated_reason: ty.Optional[str] = None,
+ deprecated_since: ty.Optional[str] = None,
+ ):
self.name = name
self.check_str = check_str
+ self.deprecated_reason = deprecated_reason
+ self.deprecated_since = deprecated_since
+
+ if not deprecated_reason or not deprecated_since:
+ warnings.warn(
+ f'{name} deprecated without deprecated_reason or '
+ f'deprecated_since. This will be an error in a future release',
+ DeprecationWarning)