Allow policy file to not exist

Now that policy rules can be registered in code there is a desire to run
projects without a policy file. However oslo.policy assumed a policy
file would exist and would raise an error if it could not be found. This
changes that behavior to not error if a policy file is not found.

Because there are now tools which can generate policy files which list
the defaults, or list the effective policy there is no requirement that
a policy file be used in order to examine the policy that is in use. So
it should be possible to run without one.

Change-Id: Ia82df77f7a65aa1f3e3eaa7ed949103fa73fb603
This commit is contained in:
Andrew Laski 2016-07-13 14:04:22 -04:00
parent 202340cebd
commit 5a651339d6
2 changed files with 54 additions and 3 deletions

View File

@ -449,6 +449,7 @@ class Enforcer(object):
self._loaded_files = []
self._policy_dir_mtimes = {}
self._file_cache = {}
self._informed_no_policy_file = False
def set_rules(self, rules, overwrite=True, use_conf=False):
"""Create a new :class:`Rules` based on the provided dict of rules.
@ -482,6 +483,7 @@ class Enforcer(object):
self._file_cache.clear()
self.registered_rules = {}
self.file_rules = {}
self._informed_no_policy_file = False
def load_rules(self, force_reload=False):
"""Loads policy_path's rules.
@ -496,10 +498,17 @@ class Enforcer(object):
if self.use_conf:
if not self.policy_path:
self.policy_path = self._get_policy_path(self.policy_file)
try:
self.policy_path = self._get_policy_path(self.policy_file)
except cfg.ConfigFilesNotFoundError:
if not self._informed_no_policy_file:
LOG.debug('The policy file %s could not be found.',
self.policy_file)
self._informed_no_policy_file = True
self._load_policy_file(self.policy_path, force_reload,
overwrite=self.overwrite)
if self.policy_path:
self._load_policy_file(self.policy_path, force_reload,
overwrite=self.overwrite)
for path in self.conf.oslo_policy.policy_dirs:
try:
path = self._get_policy_path(path)

View File

@ -625,6 +625,48 @@ class EnforcerTest(base.PolicyBaseTestCase):
{'roles': ['test']})
class EnforcerNoPolicyFileTest(base.PolicyBaseTestCase):
def setUp(self):
super(EnforcerNoPolicyFileTest, self).setUp()
def check_loaded_files(self, filenames):
self.assertEqual(
[self.get_config_file_fullname(n)
for n in filenames],
self.enforcer._loaded_files
)
def test_load_rules(self):
# Check that loading rules with no policy file does not error
self.enforcer.load_rules(True)
self.assertIsNotNone(self.enforcer.rules)
self.assertEqual(0, len(self.enforcer.rules))
def test_opts_registered(self):
self.enforcer.register_default(policy.RuleDefault(name='admin',
check_str='is_admin:False'))
self.enforcer.register_default(policy.RuleDefault(name='owner',
check_str='role:owner'))
self.enforcer.load_rules(True)
self.assertEqual({}, self.enforcer.file_rules)
self.assertEqual('role:owner', str(self.enforcer.rules['owner']))
self.assertEqual('is_admin:False', str(self.enforcer.rules['admin']))
def test_load_directory(self):
self.create_config_file('policy.d/a.conf', POLICY_JSON_CONTENTS)
self.create_config_file('policy.d/b.conf', POLICY_B_CONTENTS)
self.enforcer.load_rules(True)
self.assertIsNotNone(self.enforcer.rules)
loaded_rules = jsonutils.loads(str(self.enforcer.rules))
self.assertEqual('role:fakeB', loaded_rules['default'])
self.assertEqual('is_admin:True', loaded_rules['admin'])
self.check_loaded_files([
'policy.d/a.conf',
'policy.d/b.conf',
])
class CheckFunctionTestCase(base.PolicyBaseTestCase):
def setUp(self):