Make policy init more threadsafe
In a high concurrency environment, it is possible for the policy enforcer to be halfway ready, leading to policies not being loaded. See the linked story for more details on how that can happen. This change fixes that in two (redundant) ways: * policy is initialized in the web app at WSGI application creation, once, before the web service starts * The global that contains the _ENFORCER is not changed from None to assigned until policy is fully loaded. Because of the change in when init() happens, the unit test is changed to not assert the initial state of the enforcer. Change-Id: Iae0c5c3ccda7587087606c97c615b9e44e3a68f0 Story: 2005168 Task: 29905
This commit is contained in:
parent
98f722a603
commit
871b15ef93
@ -23,6 +23,7 @@ from placement import handler
|
||||
from placement import microversion
|
||||
from placement.objects import resource_class
|
||||
from placement.objects import resource_provider
|
||||
from placement import policy
|
||||
from placement import requestlog
|
||||
from placement import resource_class_cache as rc_cache
|
||||
from placement import util
|
||||
@ -122,5 +123,6 @@ def loadapp(config, project_name=NAME):
|
||||
backwards compatibility
|
||||
"""
|
||||
application = deploy(config)
|
||||
policy.init(config)
|
||||
update_database(config)
|
||||
return application
|
||||
|
@ -41,10 +41,11 @@ def init(conf):
|
||||
# to read the policy file from config option [oslo_policy]/policy_file
|
||||
# which is used by nova. In other words, to have separate policy files
|
||||
# for placement and nova, we have to use separate policy_file options.
|
||||
_ENFORCER = policy.Enforcer(
|
||||
_enforcer = policy.Enforcer(
|
||||
conf, policy_file=conf.placement.policy_file)
|
||||
_ENFORCER.register_defaults(policies.list_rules())
|
||||
_ENFORCER.load_rules()
|
||||
_enforcer.register_defaults(policies.list_rules())
|
||||
_enforcer.load_rules()
|
||||
_ENFORCER = _enforcer
|
||||
|
||||
|
||||
def get_enforcer():
|
||||
@ -77,7 +78,6 @@ def authorize(context, action, target, do_raise=True):
|
||||
:returns: non-False value (not necessarily "True") if authorized, and the
|
||||
exact value False if not authorized and do_raise is False.
|
||||
"""
|
||||
init(context.config)
|
||||
credentials = context.to_policy_values()
|
||||
try:
|
||||
# NOTE(mriedem): The "action" kwarg is for the PolicyNotAuthorized exc.
|
||||
|
@ -54,9 +54,6 @@ class PlacementPolicyTestCase(testtools.TestCase):
|
||||
group='placement', policy_file=tmpfilename)
|
||||
|
||||
action = 'placement:test'
|
||||
# Expect PolicyNotRegistered since defaults are not yet loaded.
|
||||
self.assertRaises(oslo_policy.PolicyNotRegistered,
|
||||
policy.authorize, self.ctxt, action, self.target)
|
||||
|
||||
# Load the default action and rule (defaults to "any").
|
||||
enforcer = policy._get_enforcer(self.conf_fixture.conf)
|
||||
|
Loading…
Reference in New Issue
Block a user