policy: Don't persist default rule changes in tests

'oslo.policy' expects a list of default rules be provided when
initialising the enforcer. Unfortunately, it demonstrates a nasty habit
of modifying these defaults once it has them [1]. This can result in
configuration from one test bleeding through to the next.

Resolve this by initialising the enforcer with a copy of the default
rules, rather than the originals, allowing 'oslo.policy' to do whatever
it likes to the rules. Ultimately this should probably be fixed in
'oslo.policy', which should be either copying the defaults or creating
new rules based on these defaults, but that needs some thought and can
be done later.

[1] https://github.com/openstack/oslo.policy/blob/3.6.0/oslo_policy/policy.py#L762-L764

Change-Id: Ib864606d4cf4a8ecba95386bcc2b8a4bb68f2d17
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
Story: 2008556
Task: 41687
This commit is contained in:
Stephen Finucane 2021-01-26 11:24:23 +00:00 committed by Lance Bragstad
parent 069583c3cf
commit f9f6599472
3 changed files with 15 additions and 4 deletions

View File

@ -25,7 +25,7 @@ from placement.policies import usage
def list_rules():
return itertools.chain(
rules = itertools.chain(
base.list_rules(),
resource_provider.list_rules(),
resource_class.list_rules(),
@ -37,3 +37,4 @@ def list_rules():
allocation_candidate.list_rules(),
reshaper.list_rules(),
)
return list(rules)

View File

@ -11,6 +11,8 @@
# under the License.
"""Policy Enforcement for placement API."""
import typing as ty
from oslo_config import cfg
from oslo_log import log as logging
from oslo_policy import opts as policy_opts
@ -36,12 +38,14 @@ def reset():
def init(
conf: cfg.ConfigOpts,
suppress_deprecation_warnings: bool = False,
rules: ty.List[policy.RuleDefault] = None,
):
"""Init an Enforcer class. Sets the _ENFORCER global.
:param conf: A ConfigOpts object to load configuration from.
:param suppress_deprecation_warnings: **Test only** Suppress policy
deprecation warnings to avoid polluting logs.
:param rules: **Test only** The default rules to initialise.
"""
global _ENFORCER
if not _ENFORCER:
@ -56,7 +60,7 @@ def init(
_enforcer.suppress_default_change_warnings = True
_enforcer.suppress_deprecation_warnings = suppress_deprecation_warnings
_enforcer.register_defaults(policies.list_rules())
_enforcer.register_defaults(rules or policies.list_rules())
_enforcer.load_rules()
_ENFORCER = _enforcer

View File

@ -12,11 +12,13 @@
# License for the specific language governing permissions and limitations
# under the License.
import fixtures
import copy
import fixtures
from oslo_policy import policy as oslo_policy
from placement.conf import paths
from placement import policies
from placement import policy as placement_policy
@ -32,9 +34,13 @@ class PolicyFixture(fixtures.Fixture):
policy_file = paths.state_path_def('etc/placement/policy.yaml')
self.conf_fixture.config(group='oslo_policy', policy_file=policy_file)
placement_policy.reset()
# because oslo.policy has a nasty habit of modifying the default rules
# we provide, we must pass a copy of the rules rather then the rules
# themselves
placement_policy.init(
self.conf_fixture.conf,
suppress_deprecation_warnings=True)
suppress_deprecation_warnings=True,
rules=copy.deepcopy(policies.list_rules()))
self.addCleanup(placement_policy.reset)
@staticmethod