"Fossies" - the Fresh Open Source Software Archive

Member "cinder-13.0.7/cinder/policy.py" (4 Oct 2019, 6271 Bytes) of package /linux/misc/openstack/cinder-13.0.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "policy.py" see the Fossies "Dox" file reference documentation.

    1 # Copyright (c) 2011 OpenStack Foundation
    2 # All Rights Reserved.
    3 #
    4 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
    5 #    not use this file except in compliance with the License. You may obtain
    6 #    a copy of the License at
    7 #
    8 #         http://www.apache.org/licenses/LICENSE-2.0
    9 #
   10 #    Unless required by applicable law or agreed to in writing, software
   11 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   12 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   13 #    License for the specific language governing permissions and limitations
   14 #    under the License.
   15 
   16 """Policy Engine For Cinder"""
   17 
   18 import sys
   19 
   20 from oslo_config import cfg
   21 from oslo_log import log as logging
   22 from oslo_policy import opts as policy_opts
   23 from oslo_policy import policy
   24 from oslo_utils import excutils
   25 
   26 from cinder import exception
   27 from cinder import policies
   28 
   29 CONF = cfg.CONF
   30 LOG = logging.getLogger(__name__)
   31 policy_opts.set_defaults(cfg.CONF, 'policy.yaml')
   32 
   33 _ENFORCER = None
   34 
   35 
   36 def reset():
   37     global _ENFORCER
   38     if _ENFORCER:
   39         _ENFORCER.clear()
   40         _ENFORCER = None
   41 
   42 
   43 def init(use_conf=True):
   44     """Init an Enforcer class.
   45 
   46     :param use_conf: Whether to load rules from config file.
   47     """
   48 
   49     global _ENFORCER
   50     if not _ENFORCER:
   51         _ENFORCER = policy.Enforcer(
   52             CONF,
   53             use_conf=use_conf)
   54         register_rules(_ENFORCER)
   55         _ENFORCER.load_rules()
   56 
   57 
   58 def enforce(context, action, target):
   59     """Verifies that the action is valid on the target in this context.
   60 
   61     :param context: cinder context
   62     :param action: string representing the action to be checked
   63                    this should be colon separated for clarity.
   64                    i.e. ``compute:create_instance``,
   65                    ``compute:attach_volume``,
   66                    ``volume:attach_volume``
   67 
   68     :param target: dictionary representing the object of the action for object
   69                    creation this should be a dictionary representing the
   70                    location of the object e.g.
   71                    ``{'project_id': context.project_id}``
   72 
   73     :raises PolicyNotAuthorized: if verification fails.
   74     """
   75     init()
   76 
   77     return _ENFORCER.enforce(action,
   78                              target,
   79                              context.to_policy_values(),
   80                              do_raise=True,
   81                              exc=exception.PolicyNotAuthorized,
   82                              action=action)
   83 
   84 
   85 def set_rules(rules, overwrite=True, use_conf=False):
   86     """Set rules based on the provided dict of rules.
   87 
   88     :param rules: New rules to use. It should be an instance of dict.
   89     :param overwrite: Whether to overwrite current rules or update them
   90                       with the new rules.
   91     :param use_conf: Whether to reload rules from config file.
   92     """
   93 
   94     init(use_conf=False)
   95     _ENFORCER.set_rules(rules, overwrite, use_conf)
   96 
   97 
   98 def get_rules():
   99     if _ENFORCER:
  100         return _ENFORCER.rules
  101 
  102 
  103 def register_rules(enforcer):
  104     enforcer.register_defaults(policies.list_rules())
  105 
  106 
  107 def get_enforcer():
  108     # This method is for use by oslopolicy CLI scripts. Those scripts need the
  109     # 'output-file' and 'namespace' options, but having those in sys.argv means
  110     # loading the Cinder config options will fail as those are not expected to
  111     # be present. So we pass in an arg list with those stripped out.
  112     conf_args = []
  113     # Start at 1 because cfg.CONF expects the equivalent of sys.argv[1:]
  114     i = 1
  115     while i < len(sys.argv):
  116         if sys.argv[i].strip('-') in ['namespace', 'output-file']:
  117             i += 2
  118             continue
  119         conf_args.append(sys.argv[i])
  120         i += 1
  121 
  122     cfg.CONF(conf_args, project='cinder')
  123     init()
  124     return _ENFORCER
  125 
  126 
  127 def authorize(context, action, target, do_raise=True, exc=None):
  128     """Verifies that the action is valid on the target in this context.
  129 
  130     :param context: cinder context
  131     :param action: string representing the action to be checked
  132                    this should be colon separated for clarity.
  133                    i.e. ``compute:create_instance``,
  134                    ``compute:attach_volume``,
  135                    ``volume:attach_volume``
  136     :param target: dictionary representing the object of the action for object
  137                    creation this should be a dictionary representing the
  138                    location of the object e.g.
  139                    ``{'project_id': context.project_id}``
  140     :param do_raise: if True (the default), raises PolicyNotAuthorized;
  141                      if False, returns False
  142     :param exc: Class of the exception to raise if the check fails.
  143                 Any remaining arguments passed to :meth:`authorize` (both
  144                 positional and keyword arguments) will be passed to
  145                 the exception class. If not specified,
  146                 :class:`PolicyNotAuthorized` will be used.
  147 
  148     :raises cinder.exception.PolicyNotAuthorized: if verification fails
  149            and do_raise is True. Or if 'exc' is specified it will raise an
  150            exception of that type.
  151 
  152     :return: returns a non-False value (not necessarily "True") if
  153              authorized, and the exact value False if not authorized and
  154              do_raise is False.
  155     """
  156     init()
  157     credentials = context.to_policy_values()
  158     if not exc:
  159         exc = exception.PolicyNotAuthorized
  160     try:
  161         result = _ENFORCER.authorize(action, target, credentials,
  162                                      do_raise=do_raise, exc=exc, action=action)
  163     except policy.PolicyNotRegistered:
  164         with excutils.save_and_reraise_exception():
  165             LOG.exception('Policy not registered')
  166     except Exception:
  167         with excutils.save_and_reraise_exception():
  168             LOG.error('Policy check for %(action)s failed with credentials '
  169                       '%(credentials)s',
  170                       {'action': action, 'credentials': credentials})
  171     return result
  172 
  173 
  174 def check_is_admin(context):
  175     """Whether or not user is admin according to policy setting."""
  176     init()
  177     # the target is user-self
  178     credentials = context.to_policy_values()
  179     target = credentials
  180     return _ENFORCER.authorize('context_is_admin', target, credentials)