diff --git a/devstack/lib/magnum b/devstack/lib/magnum index e5dc46f357..0674f31a27 100644 --- a/devstack/lib/magnum +++ b/devstack/lib/magnum @@ -42,6 +42,7 @@ MAGNUM_AUTH_CACHE_DIR=${MAGNUM_AUTH_CACHE_DIR:-/var/cache/magnum} MAGNUM_CONF_DIR=/etc/magnum MAGNUM_CONF=$MAGNUM_CONF_DIR/magnum.conf +MAGNUM_POLICY_JSON=$MAGNUM_CONF_DIR/policy.json if is_ssl_enabled_service "magnum" || is_service_enabled tls-proxy; then MAGNUM_SERVICE_PROTOCOL="https" @@ -83,6 +84,7 @@ function configure_magnum { sudo chown $STACK_USER $MAGNUM_CONF_DIR fi + install_default_policy magnum # Rebuild the config file from scratch create_magnum_conf @@ -125,6 +127,8 @@ function create_magnum_conf { iniset $MAGNUM_CONF api host "$MAGNUM_SERVICE_HOST" iniset $MAGNUM_CONF api port "$MAGNUM_SERVICE_PORT" + iniset $MAGNUM_CONF oslo_policy policy_file $MAGNUM_POLICY_JSON + configure_auth_token_middleware $MAGNUM_CONF magnum $MAGNUM_AUTH_CACHE_DIR if is_fedora || is_suse; then diff --git a/etc/magnum/magnum.conf.sample b/etc/magnum/magnum.conf.sample index f8f4f866b3..2cd8fb0bf9 100644 --- a/etc/magnum/magnum.conf.sample +++ b/etc/magnum/magnum.conf.sample @@ -985,3 +985,27 @@ # (boolean value) # Deprecated group/name - [DEFAULT]/fake_rabbit #fake_rabbit = false + +[oslo_policy] + +# +# From oslo.policy +# + +# The JSON file that defines policies. (string value) +# Deprecated group/name - [DEFAULT]/policy_file +#policy_file = policy.json + +# Default rule. Enforced when a requested rule is not found. (string value) +# Deprecated group/name - [DEFAULT]/policy_default_rule +#policy_default_rule = default + +# Directories where policy configuration files are stored. They can be relative +# to any directory in the search path defined by the config_dir option, or +# absolute paths. The file defined by policy_file must exist for these +# directories to be searched. Missing or empty directories are ignored. (multi +# valued) +# Deprecated group/name - [DEFAULT]/policy_dirs +# This option is deprecated for removal. +# Its value may be silently ignored in the future. +#policy_dirs = policy.d diff --git a/etc/magnum/policy.json b/etc/magnum/policy.json new file mode 100644 index 0000000000..d8f39b4d7f --- /dev/null +++ b/etc/magnum/policy.json @@ -0,0 +1,6 @@ +{ + "context_is_admin": "role:admin", + "admin_or_owner": "is_admin:True or project_id:%(project_id)s", + "default": "rule:admin_or_owner", + "admin_api": "is_admin:True", +} diff --git a/magnum/common/policy.py b/magnum/common/policy.py new file mode 100644 index 0000000000..f19e11e299 --- /dev/null +++ b/magnum/common/policy.py @@ -0,0 +1,90 @@ +# Copyright (c) 2015 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Policy Engine For magnum.""" + +from oslo_config import cfg +from oslo_policy import policy + + +_ENFORCER = None +CONF = cfg.CONF + + +# we can get a policy enforcer by this init. +# oslo policy support change policy rule dynamically. +# at present, policy.enforce will reload the policy rules when it checks +# the policy files have been touched. +def init(policy_file=None, rules=None, + default_rule=None, use_conf=True, overwrite=True): + """Init an Enforcer class. + + :param policy_file: Custom policy file to use, if none is + specified, ``conf.policy_file`` will be + used. + :param rules: Default dictionary / Rules to use. It will be + considered just in the first instantiation. If + :meth:`load_rules` with ``force_reload=True``, + :meth:`clear` or :meth:`set_rules` with + ``overwrite=True`` is called this will be overwritten. + :param default_rule: Default rule to use, conf.default_rule will + be used if none is specified. + :param use_conf: Whether to load rules from cache or config file. + :param overwrite: Whether to overwrite existing rules when reload rules + from config file. + """ + global _ENFORCER + if not _ENFORCER: + # http://docs.openstack.org/developer/oslo.policy/usage.html + _ENFORCER = policy.Enforcer(CONF, + policy_file=policy_file, + rules=rules, + default_rule=default_rule, + use_conf=use_conf, + overwrite=overwrite) + return _ENFORCER + + +def enforce(context, action=None, target=None, + do_raise=True, exc=None, *args, **kwargs): + + """Checks authorization of a rule against the target and credentials. + + :param dict context: As much information about the user performing the + action as possible. + :param action: The rule to evaluate. + :param dict target: As much information about the object being operated + on as possible. + :param do_raise: Whether to raise an exception or not if check + fails. + :param exc: Class of the exception to raise if the check fails. + Any remaining arguments passed to :meth:`enforce` (both + positional and keyword arguments) will be passed to + the exception class. If not specified, + :class:`PolicyNotAuthorized` will be used. + + :return: ``False`` if the policy does not allow the action and `exc` is + not provided; otherwise, returns a value that evaluates to + ``True``. Note: for rules using the "case" expression, this + ``True`` value will be the specified string from the + expression. + """ + enforcer = init() + credentials = context.to_dict() + if target is None: + target = {'project_id': context.project_id, + 'user_id': context.user_id} + return enforcer.enforce(action, target, credentials, + do_raise=do_raise, exc=exc, *args, **kwargs) diff --git a/requirements.txt b/requirements.txt index f9a48103e1..9858aa4df5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,6 +26,7 @@ oslo.db>=1.7.0 # Apache-2.0 oslo.i18n>=1.5.0 # Apache-2.0 oslo.log>=1.0.0 # Apache-2.0 oslo.messaging>=1.8.0 # Apache-2.0 +oslo.policy>=0.3.1 # Apache-2.0 oslo.serialization>=1.4.0 # Apache-2.0 oslo.utils>=1.4.0 # Apache-2.0 oslo.versionedobjects>=0.1.1