18
18
# Based on glance/api/policy.py
19
19
"""Policy Engine For Heat"""
24
21
from oslo.config import cfg
26
23
from heat.common import exception
28
25
import heat.openstack.common.log as logging
29
26
from heat.openstack.common import policy
30
from heat.openstack.common.gettextutils import _
32
28
logger = logging.getLogger(__name__)
35
cfg.StrOpt('policy_file',
36
default='policy.json',
37
help=_("Policy file to use")),
38
cfg.StrOpt('policy_default_rule',
40
help=_("Default Rule of Policy File"))
44
CONF.register_opts(policy_opts)
48
'default': policy.TrueCheck(),
34
'default': policy.FalseCheck(),
52
38
class Enforcer(object):
53
39
"""Responsible for loading and enforcing rules."""
55
def __init__(self, scope='heat', exc=exception.Forbidden):
41
def __init__(self, scope='heat', exc=exception.Forbidden,
42
default_rule=DEFAULT_RULES['default']):
58
self.default_rule = CONF.policy_default_rule
59
self.policy_path = self._find_policy_file()
60
self.policy_file_mtime = None
61
self.policy_file_contents = None
45
self.default_rule = default_rule
46
self.enforcer = policy.Enforcer(default_rule=default_rule)
63
def set_rules(self, rules):
48
def set_rules(self, rules, overwrite=True):
64
49
"""Create a new Rules object based on the provided dict of rules."""
65
50
rules_obj = policy.Rules(rules, self.default_rule)
66
policy.set_rules(rules_obj)
51
self.enforcer.set_rules(rules_obj, overwrite)
53
def load_rules(self, force_reload=False):
69
54
"""Set the rules found in the json file on disk."""
71
rules = self._read_policy_file()
75
rule_type = "default "
77
text_rules = dict((k, str(v)) for k, v in rules.items())
82
def _find_policy_file():
83
"""Locate the policy json data file."""
84
policy_file = CONF.find_file(CONF.policy_file)
88
logger.warn(_('Unable to find policy file'))
91
def _read_policy_file(self):
92
"""Read contents of the policy file
94
This re-caches policy data if the file has been changed.
96
mtime = os.path.getmtime(self.policy_path)
97
if not self.policy_file_contents or mtime != self.policy_file_mtime:
98
logger.debug(_("Loading policy from %s") % self.policy_path)
99
with open(self.policy_path) as fap:
100
raw_contents = fap.read()
101
rules_dict = json.loads(raw_contents)
102
self.policy_file_contents = dict(
103
(k, policy.parse_rule(v))
104
for k, v in rules_dict.items())
105
self.policy_file_mtime = mtime
106
return self.policy_file_contents
108
def _check(self, context, rule, target, *args, **kwargs):
55
self.enforcer.load_rules(force_reload)
57
def _check(self, context, rule, target, exc, *args, **kwargs):
109
58
"""Verifies that the action is valid on the target in this context.
111
60
:param context: Heat request context
114
63
:raises: self.exc (defaults to heat.common.exception.Forbidden)
115
64
:returns: A non-False value if access is allowed.
66
do_raise = False if not exc else True
120
68
'roles': context.roles,
121
69
'user': context.username,
122
70
'tenant': context.tenant,
125
return policy.check(rule, target, credentials, *args, **kwargs)
72
return self.enforcer.enforce(rule, target, credentials,
73
do_raise, exc=exc, *args, **kwargs)
127
75
def enforce(self, context, action, target):
128
76
"""Verifies that the action is valid on the target in this context.