~ubuntu-branches/ubuntu/trusty/quantum/trusty

« back to all changes in this revision

Viewing changes to quantum/policy.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Adam Gandelman, Chuck Short
  • Date: 2012-11-23 09:43:14 UTC
  • mfrom: (2.1.16)
  • Revision ID: package-import@ubuntu.com-20121123094314-e1tqsulrwe21b9aq
Tags: 2013.1~g1-0ubuntu1
[ Adam Gandelman ]
* debian/patches/*: Refreshed for opening of Grizzly.

[ Chuck Short ]
* New upstream release.
* debian/rules: FTFBS if there is missing binaries.
* debian/quantum-server.install: Add quantum-debug.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
"""
19
19
Policy engine for quantum.  Largely copied from nova.
20
20
"""
21
 
import logging
22
21
 
23
22
from quantum.api.v2 import attributes
24
23
from quantum.common import exceptions
 
24
import quantum.common.utils as utils
25
25
from quantum.openstack.common import cfg
26
 
import quantum.common.utils as utils
 
26
from quantum.openstack.common import log as logging
27
27
from quantum.openstack.common import policy
28
28
 
29
29
 
50
50
    # pass _set_brain to read_cached_file so that the policy brain
51
51
    # is reset only if the file has changed
52
52
    utils.read_cached_file(_POLICY_PATH, _POLICY_CACHE,
53
 
                           reload_func=_set_brain)
 
53
                           reload_func=_set_rules)
54
54
 
55
55
 
56
56
def get_resource_and_action(action):
59
59
    return ("%ss" % data[-1], data[0] != 'get')
60
60
 
61
61
 
62
 
def _set_brain(data):
 
62
def _set_rules(data):
63
63
    default_rule = 'default'
64
 
    policy.set_brain(policy.Brain.load_json(data, default_rule))
 
64
    policy.set_rules(policy.Rules.load_json(data, default_rule))
65
65
 
66
66
 
67
67
def _is_attribute_explicitly_set(attribute_name, resource, target):
95
95
    return target
96
96
 
97
97
 
98
 
def _build_match_list(action, target):
99
 
    """Create the list of rules to match for a given action.
 
98
def _build_match_rule(action, target):
 
99
    """Create the rule to match for a given action.
100
100
 
101
 
    The list of policy rules to be matched is built in the following way:
 
101
    The policy rule to be matched is built in the following way:
102
102
    1) add entries for matching permission on objects
103
103
    2) add an entry for the specific action (e.g.: create_network)
104
104
    3) add an entry for attributes of a resource for which the action
106
106
 
107
107
    """
108
108
 
109
 
    match_list = ('rule:%s' % action,)
 
109
    match_rule = policy.RuleCheck('rule', action)
110
110
    resource, is_write = get_resource_and_action(action)
111
111
    if is_write:
112
112
        # assigning to variable with short name for improving readability
118
118
                                                target):
119
119
                    attribute = res_map[resource][attribute_name]
120
120
                    if 'enforce_policy' in attribute and is_write:
121
 
                        match_list += ('rule:%s:%s' % (action,
122
 
                                                       attribute_name),)
123
 
    return [match_list]
 
121
                        attr_rule = policy.RuleCheck('rule', '%s:%s' %
 
122
                                                     (action, attribute_name))
 
123
                        match_rule = policy.AndCheck([match_rule, attr_rule])
 
124
 
 
125
    return match_rule
124
126
 
125
127
 
126
128
@policy.register('field')
127
 
def check_field(brain, match_kind, match, target_dict, cred_dict):
128
 
    # If this method is invoked for the wrong kind of match
129
 
    # which should never happen, just skip the check and don't
130
 
    # fail the policy evaluation
131
 
    if match_kind != 'field':
132
 
        LOG.warning("Field check function invoked with wrong match_kind:%s",
133
 
                    match_kind)
134
 
        return True
135
 
    resource, field_value = match.split(':', 1)
136
 
    field, value = field_value.split('=', 1)
137
 
    target_value = target_dict.get(field)
138
 
    # target_value might be a boolean, explicitly compare with None
139
 
    if target_value is None:
140
 
        LOG.debug("Unable to find requested field: %s in target: %s",
141
 
                  field, target_dict)
142
 
        return False
143
 
    # Value migth need conversion - we need help from the attribute map
144
 
    conv_func = attributes.RESOURCE_ATTRIBUTE_MAP[resource][field].get(
145
 
        'convert_to', lambda x: x)
146
 
    if target_value != conv_func(value):
147
 
        LOG.debug("%s does not match the value in the target object:%s",
148
 
                  conv_func(value), target_value)
149
 
        return False
150
 
    # If we manage to get here, the policy check is successful
151
 
    return True
 
129
class FieldCheck(policy.Check):
 
130
    def __init__(self, kind, match):
 
131
        # Process the match
 
132
        resource, field_value = match.split(':', 1)
 
133
        field, value = field_value.split('=', 1)
 
134
 
 
135
        super(FieldCheck, self).__init__(kind, '%s:%s:%s' %
 
136
                                         (resource, field, value))
 
137
 
 
138
        # Value might need conversion - we need help from the attribute map
 
139
        try:
 
140
            attr = attributes.RESOURCE_ATTRIBUTE_MAP[resource][field]
 
141
            conv_func = attr['convert_to']
 
142
        except KeyError:
 
143
            conv_func = lambda x: x
 
144
 
 
145
        self.field = field
 
146
        self.value = conv_func(value)
 
147
 
 
148
    def __call__(self, target_dict, cred_dict):
 
149
        target_value = target_dict.get(self.field)
 
150
        # target_value might be a boolean, explicitly compare with None
 
151
        if target_value is None:
 
152
            LOG.debug("Unable to find requested field: %s in target: %s",
 
153
                      self.field, target_dict)
 
154
            return False
 
155
 
 
156
        return target_value == self.value
152
157
 
153
158
 
154
159
def check(context, action, target, plugin=None):
167
172
    """
168
173
    init()
169
174
    real_target = _build_target(action, target, plugin, context)
170
 
    match_list = _build_match_list(action, real_target)
 
175
    match_rule = _build_match_rule(action, real_target)
171
176
    credentials = context.to_dict()
172
 
    return policy.enforce(match_list, real_target, credentials)
 
177
    return policy.check(match_rule, real_target, credentials)
173
178
 
174
179
 
175
180
def enforce(context, action, target, plugin=None):
189
194
 
190
195
    init()
191
196
    real_target = _build_target(action, target, plugin, context)
192
 
    match_list = _build_match_list(action, real_target)
 
197
    match_rule = _build_match_rule(action, real_target)
193
198
    credentials = context.to_dict()
194
 
    policy.enforce(match_list, real_target, credentials,
195
 
                   exceptions.PolicyNotAuthorized, action=action)
 
199
    return policy.check(match_rule, real_target, credentials,
 
200
                        exceptions.PolicyNotAuthorized, action=action)