Deprecate old policy engine and restrict access

This commit does two different changes: it changes the policy engine to
oslo_policy and restrict access to sysinv API to users of projects
'admin' or 'services'.

The policy engine deprecated is the one present in the file
"sysinv/sysinv/sysinv/sysinv/openstack/common/policy.py" (780 lines).
This file is no longer used by this repository and was not deleted
because it is used by other repositories, like starlingx/update. The
library oslo_policy is used in its place. In fact, the deprecated engine
seems to be an ancient version of oslo_policy. The library oslo_policy
changed the default format of configuration files from JSON to YAML, so
the configuration files named "policy.json" were changed to
"policy.yaml". The file that initializes and wraps oslo_policy
("sysinv/sysinv/sysinv/sysinv/common/policy.py") contains the minimal
implementation to use this library.

The access to sysinv API, before this commit, was restricted to users
with role "admin" or "administrator" from any project. This commit
restricts the access to users with role "admin" of projects "admin" or
"services". This change should not cause problems, because role
"administrator" doesn't exist and because all users from Starlingx are
from projects "admin" or "services". This change is needed to avoid
access from admin users of other projects.

To test custom policy rules set in the file "/etc/sysinv/policy.yaml",
it will be used the Service Parameter API actions create/apply/modify/
delete/get (commands "system service-parameter-[add/apply/modify/delete/
list]". To test default policy for sysinv API commands, it will be used
the command to change the system description (PATCH "/v1/isystems",
command "system modify --description='test'"). On test plan, these
commands will be reffered as "test commands". Any change in the file
"/etc/sysinv/policy.yaml" is detected by policy engine and rules are
updated.

Test Plan:

PASS: Successfully deploy an AIO-SX using an Debian image with this
commit present. Successfully create, through openstack CLI, the users:
'testreader' with role 'reader' in project 'admin',
'adminsvc' with role 'admin' in project 'services' and
'otheradmin' with role 'admin' in project 'notadminproject'.
Create openrc files for all new users. Note: the other user that will be
used is the already existing 'admin' with role 'admin' in project
'admin'.
PASS: In the deployed AIO-SX, check the behavior of test commands
through different users: for "admin" and "adminsvc" users, all commands
are successful; for user "testreader", only "service-parameter-list"
command is successful and for user "otheradmin" no command is
successful.
PASS: In the deployed AIO-SX, add the following lines in file
"/etc/sysinv/policy.yaml":
config_api:service_parameter:add: role:reader
config_api:service_parameter:apply: role:reader
config_api:service_parameter:delete: role:reader
config_api:service_parameter:get: role:reader
config_api:service_parameter:modify: role:reader
and check the behavior of test commands through different users:
for "admin" and "adminsvc" users, all commands are successful; for users
"testreader" and "otheradmin", all commands are successful except the
change in the system description ("system modify --description='test'").
PASS: In the deployed AIO-SX, to assert that public API works without
authentication, execute the commands:
"curl -v http://<MGMT_IP>:6385/v1/" and
"curl -v http://<MGMT_IP>:6385/v1/isystems/mgmtvlan" and
verify that they are accepted and that the HTTP response is 200,
and execute the commands:
"curl -v http://<MGMT_IP>:6385/v1/isystems/" and
"curl -v http://<MGMT_IP>:6385/v1/service_parameter" and
verify that they are rejected and that the HTTP response is 401.
PASS: Repeat all tests above changing the deploy to AIO-DX using an
CentOS image.
PASS: Successfully execute Debian AIO-SX daily regression and sanity
tests using an image containing this change.

Story: 2010149
Task: 45984

Signed-off-by: Joao Victor Portal <Joao.VictorPortal@windriver.com>
Change-Id: Id7aa387e154afb1441a8484b076cdc97f2fc46cb
This commit is contained in:
Joao Victor Portal 2022-08-03 21:05:35 -03:00
parent 986c61d0f8
commit 9aee309999
22 changed files with 166 additions and 218 deletions

View File

@ -108,7 +108,7 @@ function cleanup_sysinv {
pip_uninstall sysinv
sudo rm -f $SYSINV_ETC_GOENABLEDD/sysinv_goenabled_check.sh
sudo rm -f $SYSINV_CONF_DIR/policy.json
sudo rm -f $SYSINV_CONF_DIR/policy.yaml
sudo rm -f $SYSINV_ETC_MOTDD/10-system
sudo rm -f $SYSINV_CONF_DIR/upgrades/delete_load.sh
sudo rm -f $STX_OCF_ROOT/resource.d/platform/sysinv-api
@ -247,7 +247,7 @@ function install_sysinv {
sudo install -d -m 755 $SYSINV_ETC_GOENABLEDD
sudo install -p -D -m 755 $SYSINV_DIR/etc/sysinv/sysinv_goenabled_check.sh $SYSINV_ETC_GOENABLEDD/sysinv_goenabled_check.sh
sudo install -d -m 755 $SYSINV_CONF_DIR
sudo install -p -D -m 755 $SYSINV_DIR/etc/sysinv/policy.json $SYSINV_CONF_DIR/policy.json
sudo install -p -D -m 755 $SYSINV_DIR/etc/sysinv/policy.yaml $SYSINV_CONF_DIR/policy.yaml
sudo install -d -m 755 $SYSINV_ETC_MOTDD
sudo install -p -D -m 755 $SYSINV_DIR/etc/sysinv/motd-system $SYSINV_ETC_MOTDD/10-system
sudo install -d -m 755 $SYSINV_CONF_DIR/upgrades

View File

@ -44,6 +44,7 @@ Requires: python2-oslo-config
Requires: python2-oslo-concurrency
Requires: python2-oslo-db
Requires: python2-oslo-log
Requires: python2-oslo-policy
Requires: python2-oslo-rootwrap
Requires: python2-oslo-serialization
Requires: python2-oslo-service
@ -89,7 +90,7 @@ install -d -m 755 %{buildroot}%{local_etc_goenabledd}
install -p -D -m 755 etc/sysinv/sysinv_goenabled_check.sh %{buildroot}%{local_etc_goenabledd}/sysinv_goenabled_check.sh
install -d -m 755 %{buildroot}%{local_etc_sysinv}
install -p -D -m 755 etc/sysinv/policy.json %{buildroot}%{local_etc_sysinv}/policy.json
install -p -D -m 755 etc/sysinv/policy.yaml %{buildroot}%{local_etc_sysinv}/policy.yaml
install -p -D -m 644 etc/sysinv/crushmap-storage-model.txt %{buildroot}%{local_etc_sysinv}/crushmap-storage-model.txt
install -p -D -m 644 etc/sysinv/crushmap-controller-model.txt %{buildroot}%{local_etc_sysinv}/crushmap-controller-model.txt

View File

@ -31,6 +31,7 @@ Build-Depends-Indep:
python3-oslo.log,
python3-oslo.db,
python3-oslo.messaging,
python3-oslo.policy,
python3-oslo.rootwrap,
python3-oslo.service,
python3-oslo.utils,
@ -105,6 +106,7 @@ Depends: ${python3:Depends}, ${misc:Depends},
python3-oslo.log,
python3-oslo.db,
python3-oslo.messaging,
python3-oslo.policy,
python3-oslo.rootwrap,
python3-oslo.service,
python3-oslo.utils,

View File

@ -1,4 +1,4 @@
etc/sysinv/policy.json etc/sysinv
etc/sysinv/policy.yaml etc/sysinv
etc/sysinv/crushmap-storage-model.txt etc/sysinv
etc/sysinv/crushmap-controller-model.txt etc/sysinv
etc/sysinv/crushmap-aio-sx.txt etc/sysinv

View File

@ -47,6 +47,7 @@ Requires: python2-oslo.config
Requires: python2-oslo.concurrency
Requires: python2-oslo.db
Requires: python2-oslo.log
Requires: python2-oslo.policy
Requires: python2-oslo.rootwrap
Requires: python2-oslo.serialization
Requires: python2-oslo.service
@ -89,7 +90,7 @@ install -d -m 755 %{buildroot}%{local_etc_goenabledd}
install -p -D -m 755 etc/sysinv/sysinv_goenabled_check.sh %{buildroot}%{local_etc_goenabledd}/sysinv_goenabled_check.sh
install -d -m 755 %{buildroot}%{local_etc_sysinv}
install -p -D -m 644 etc/sysinv/policy.json %{buildroot}%{local_etc_sysinv}/policy.json
install -p -D -m 644 etc/sysinv/policy.yaml %{buildroot}%{local_etc_sysinv}/policy.yaml
install -p -D -m 644 etc/sysinv/crushmap-storage-model.txt %{buildroot}%{local_etc_sysinv}/crushmap-storage-model.txt
install -p -D -m 644 etc/sysinv/crushmap-controller-model.txt %{buildroot}%{local_etc_sysinv}/crushmap-controller-model.txt

View File

@ -21,5 +21,5 @@ graft doc
graft etc
include sysinv/db/sqlalchemy/migrate_repo/migrate.cfg
include sysinv/openstack/common/config/generator.py
include sysinv/tests/policy.json
include sysinv/tests/policy.yaml
graft tools

View File

@ -1,5 +0,0 @@
{
"admin": "role:admin or role:administrator",
"admin_api": "is_admin:True",
"default": "rule:admin_api"
}

View File

@ -0,0 +1,11 @@
---
# The commented lines below contains the default values for presented rules.
# admin_in_system_projects: role:admin and (project_name:admin or project_name:services)
# reader_in_system_projects: role:reader and (project_name:admin or project_name:services)
# config_api:service_parameter:add: rule:admin_in_system_projects
# config_api:service_parameter:apply: rule:admin_in_system_projects
# config_api:service_parameter:delete: rule:admin_in_system_projects
# config_api:service_parameter:get: rule:reader_in_system_projects
# config_api:service_parameter:modify: rule:admin_in_system_projects

View File

@ -59,7 +59,7 @@
#
# JSON file representing policy (string value)
#policy_file=policy.json
#policy_file=policy.yaml
# Rule checked when requested rule is not found (string value)
#policy_default_rule=default

View File

@ -52,3 +52,4 @@ python-barbicanclient
rfc3986
importlib-metadata>=3.3.0;python_version=="3.6"
importlib-resources==5.2.2;python_version=="3.6"
oslo.policy # Apache-2.0

View File

@ -27,7 +27,6 @@ from sysinv.api.controllers.v1 import link
from sysinv.api.controllers.v1 import types
from sysinv.api.controllers.v1 import utils
from sysinv.api.controllers.v1.query import Query
from sysinv.api.policies import base as base_policy
from sysinv.api.policies import service_parameter as sp_policy
from sysinv import objects
from sysinv.common import constants
@ -827,21 +826,16 @@ class ServiceParameterController(rest.RestController):
def enforce_policy(self, method_name, request):
"""Check policy rules for each action of this controller."""
context = request.context
context_dict = request.context.to_dict()
if method_name == "apply":
policy.enforce(context, sp_policy.POLICY_ROOT % "apply",
{'project_name': base_policy.ADMIN_PROJECT_NAME})
policy.authorize(sp_policy.POLICY_ROOT % "apply", {}, context_dict)
elif method_name == "delete":
policy.enforce(context, sp_policy.POLICY_ROOT % "delete",
{'project_name': base_policy.ADMIN_PROJECT_NAME})
policy.authorize(sp_policy.POLICY_ROOT % "delete", {}, context_dict)
elif method_name in ["get_all", "get_one"]:
policy.enforce(context, sp_policy.POLICY_ROOT % "get",
{'project_name': base_policy.ADMIN_PROJECT_NAME})
policy.authorize(sp_policy.POLICY_ROOT % "get", {}, context_dict)
elif method_name == "patch":
policy.enforce(context, sp_policy.POLICY_ROOT % "modify",
{'project_name': base_policy.ADMIN_PROJECT_NAME})
policy.authorize(sp_policy.POLICY_ROOT % "modify", {}, context_dict)
elif method_name == "post":
policy.enforce(context, sp_policy.POLICY_ROOT % "add",
{'project_name': base_policy.ADMIN_PROJECT_NAME})
policy.authorize(sp_policy.POLICY_ROOT % "add", {}, context_dict)
else:
raise exception.PolicyNotFound()

View File

@ -31,11 +31,12 @@ from oslo_utils import uuidutils
from pecan import hooks
from sysinv._i18n import _
from sysinv.api.policies import base as base_policy
from sysinv.common import context
from sysinv.common import utils
from sysinv.conductor import rpcapi
from sysinv.db import api as dbapi
from sysinv.openstack.common import policy
from sysinv.common import policy
from webob import exc
LOG = log.getLogger(__name__)
@ -141,7 +142,7 @@ class ContextHook(hooks.PecanHook):
domain_id = state.request.headers.get('X-User-Domain-Id')
domain_name = state.request.headers.get('X-User-Domain-Name')
auth_token = state.request.headers.get('X-Auth-Token', None)
creds = {'roles': state.request.headers.get('X-Roles', '').split(',')}
roles = state.request.headers.get('X-Roles', '').split(',')
catalog_header = state.request.headers.get('X-Service-Catalog')
service_catalog = None
if catalog_header:
@ -151,7 +152,12 @@ class ContextHook(hooks.PecanHook):
raise webob.exc.HTTPInternalServerError(
_('Invalid service catalog json.'))
is_admin = policy.check('admin', state.request.headers, creds)
credentials = {
'project_name': project_name,
'roles': roles
}
is_admin = policy.authorize(base_policy.ADMIN_IN_SYSTEM_PROJECTS, {},
credentials, do_raise=False)
utils.safe_rstrip(state.request.path, '/')
is_public_api = state.request.environ.get('is_public_api', False)
@ -165,7 +171,7 @@ class ContextHook(hooks.PecanHook):
is_admin=is_admin,
is_public_api=is_public_api,
project_name=project_name,
roles=creds['roles'],
roles=roles,
service_catalog=service_catalog
)
@ -182,11 +188,16 @@ class AccessPolicyHook(hooks.PecanHook):
def before(self, state):
controller = state.controller.__self__
if hasattr(controller, 'enforce_policy'):
controller_method = state.controller.__name__
controller.enforce_policy(controller_method, state.request)
try:
controller_method = state.controller.__name__
controller.enforce_policy(controller_method, state.request)
except Exception:
raise exc.HTTPForbidden()
else:
context = state.request.context
is_admin_api = policy.check('admin_api', {}, context.to_dict())
is_admin_api = policy.authorize(
base_policy.ADMIN_IN_SYSTEM_PROJECTS, {},
context.to_dict(), do_raise=False)
if not is_admin_api and not context.is_public_api:
raise exc.HTTPForbidden()

View File

@ -14,49 +14,24 @@
#
# SPDX-License-Identifier: Apache-2.0
ADMIN_PROJECT_NAME = 'admin'
ADMIN_IN_SPECIFIC_PROJECT = 'rule:admin_in_specific_project'
READER_IN_SPECIFIC_PROJECT = 'rule:reader_in_specific_project'
from oslo_policy import policy
class RuleDefault(object):
"""Class used to represent a policy rule.
:param name: The name of the policy.
:param check_str: The string that represents the policy.
:param description: A brief description of the policy.
"""
def __init__(self, name, check_str, description):
self.name = name
self.check_str = check_str
self.description = description
ADMIN_IN_SYSTEM_PROJECTS = 'admin_in_system_projects'
READER_IN_SYSTEM_PROJECTS = 'reader_in_system_projects'
base_rules = [
RuleDefault(
name='admin',
check_str='role:admin or role:administrator',
policy.RuleDefault(
name=ADMIN_IN_SYSTEM_PROJECTS,
check_str='role:admin and (project_name:admin or ' +
'project_name:services)',
description="Base rule.",
),
RuleDefault(
name='admin_api',
check_str='is_admin:True',
description="Base rule.",
),
RuleDefault(
name='default',
check_str='rule:admin_api',
description="Base rule.",
),
RuleDefault(
name='admin_in_specific_project',
check_str='role:admin and project_name:%(project_name)s',
description="Base rule.",
),
RuleDefault(
name='reader_in_specific_project',
check_str='role:reader and project_name:%(project_name)s',
description="Base rule.",
policy.RuleDefault(
name=READER_IN_SYSTEM_PROJECTS,
check_str='role:reader and (project_name:admin or ' +
'project_name:services)',
description="Base rule."
)
]

View File

@ -14,36 +14,71 @@
#
# SPDX-License-Identifier: Apache-2.0
from oslo_policy import policy
from sysinv.api.policies import base
POLICY_ROOT = 'config_api:service_parameter:%s'
service_parameter_rules = [
base.RuleDefault(
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'add',
check_str=base.ADMIN_IN_SPECIFIC_PROJECT,
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Add a Service Parameter.",
operations=[
{
'method': 'POST',
'path': '/v1/service_parameter'
}
]
),
base.RuleDefault(
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'apply',
check_str=base.ADMIN_IN_SPECIFIC_PROJECT,
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Apply Service Parameters.",
operations=[
{
'method': 'POST',
'path': '/v1/service_parameter/apply'
}
]
),
base.RuleDefault(
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'delete',
check_str=base.ADMIN_IN_SPECIFIC_PROJECT,
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Delete a Service Parameter.",
operations=[
{
'method': 'DELETE',
'path': '/v1/service_parameter/{parameter_id}'
}
]
),
base.RuleDefault(
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'get',
check_str=base.READER_IN_SPECIFIC_PROJECT,
check_str='rule:' + base.READER_IN_SYSTEM_PROJECTS,
description="Get Service Parameters.",
operations=[
{
'method': 'GET',
'path': '/v1/service_parameter'
},
{
'method': 'GET',
'path': '/v1/service_parameter/{parameter_id}'
}
]
),
base.RuleDefault(
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'modify',
check_str=base.ADMIN_IN_SPECIFIC_PROJECT,
check_str='rule:' + base.ADMIN_IN_SYSTEM_PROJECTS,
description="Modify Service Parameter value.",
operations=[
{
'method': 'PATCH',
'path': '/v1/service_parameter/{parameter_id}'
}
]
)
]

View File

@ -20,6 +20,7 @@ from pecan import hooks
from oslo_context import context as base_context
from oslo_utils import encodeutils
from sysinv.api.policies import base as base_policy
from sysinv.common import policy
ALLOWED_WITHOUT_AUTH = '/'
@ -75,9 +76,9 @@ class RequestContext(base_context.RequestContext):
# Check user is admin or not
if is_admin is None:
self.is_admin = policy.enforce(self, 'context_is_admin',
target={'project': self.project},
do_raise=False)
self.is_admin = policy.authorize(
base_policy.ADMIN_IN_SYSTEM_PROJECTS, {}, self.to_dict(),
do_raise=False)
else:
self.is_admin = is_admin

View File

@ -1,134 +1,55 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
# Copyright (c) 2022 Wind River Systems, Inc.
#
# 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
# 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.
# 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.
#
# SPDX-License-Identifier: Apache-2.0
"""Policy Engine For Sysinv."""
import os.path
from oslo_config import cfg
from sysinv._i18n import _
from oslo_policy import policy
from sysinv.api import policies as controller_policies
from sysinv.common import exception
from sysinv.common import utils
from sysinv.openstack.common import policy
policy_opts = [
cfg.StrOpt('policy_file',
default='policy.json',
help=_('JSON file representing policy')),
cfg.StrOpt('policy_default_rule',
default='default',
help=_('Rule checked when requested rule is not found')),
]
CONF = cfg.CONF
CONF.register_opts(policy_opts)
_POLICY_PATH = None
_POLICY_CACHE = {}
_ENFORCER = None
def reset():
global _POLICY_PATH
global _POLICY_CACHE
_POLICY_PATH = None
_POLICY_CACHE = {}
policy.reset()
"""Discard current Enforcer object."""
global _ENFORCER
_ENFORCER = None
def init():
global _POLICY_PATH
global _POLICY_CACHE
if not _POLICY_PATH:
_POLICY_PATH = CONF.policy_file
if not os.path.exists(_POLICY_PATH):
_POLICY_PATH = CONF.find_file(_POLICY_PATH)
if not _POLICY_PATH:
raise exception.ConfigNotFound(message=CONF.policy_file)
utils.read_cached_file(_POLICY_PATH, _POLICY_CACHE,
reload_func=_set_rules)
def init(policy_file='policy.yaml'):
"""Init an Enforcer class.
:param policy_file: Custom policy file to be used.
def _set_rules(data):
default_rule = CONF.policy_default_rule
rules = policy.Rules.load_rules(data, default_rule,
controller_policies.list_rules())
policy.set_rules(rules)
def enforce(context, action, target, do_raise=True):
"""Verifies that the action is valid on the target in this context.
:param context: sysinv context
:param action: string representing the action to be checked
this should be colon separated for clarity.
i.e. ``compute:create_instance``,
``compute:attach_volume``,
``volume:attach_volume``
:param target: dictionary representing the object of the action
for object creation this should be a dictionary representing the
location of the object e.g. ``{'project_id': context.project_id}``
:param do_raise: if True (the default), raises PolicyNotAuthorized;
if False, returns False
:raises sysinv.exception.PolicyNotAuthorized: if verification fails
and do_raise is True.
:return: returns a non-False value (not necessarily "True") if
authorized, and the exact value False if not authorized and
do_raise is False.
:return: Returns a Enforcer instance.
"""
global _ENFORCER
if not _ENFORCER:
# https://docs.openstack.org/oslo.policy/latest/user/usage.html
_ENFORCER = policy.Enforcer(CONF,
policy_file=policy_file,
default_rule='default',
use_conf=True,
overwrite=True)
_ENFORCER.register_defaults(controller_policies.list_rules())
return _ENFORCER
def authorize(rule, target, creds, do_raise=True):
"""A wrapper around 'authorize' from 'oslo_policy.policy'."""
init()
credentials = context.to_dict()
# Add the exception arguments if asked to do a raise
extra = {}
if do_raise:
extra.update(exc=exception.PolicyNotAuthorized, action=action)
return policy.check(action, target, credentials, **extra)
def check_is_admin(context):
"""Whether or not role contains 'admin' role according to policy setting.
"""
init()
credentials = context.to_dict()
target = credentials
return policy.check('context_is_admin', target, credentials)
@policy.register('context_is_admin')
class IsAdminCheck(policy.Check):
"""An explicit check for is_admin."""
def __init__(self, kind, match):
"""Initialize the check."""
self.expected = (match.lower() == 'true')
super(IsAdminCheck, self).__init__(kind, str(self.expected))
def __call__(self, target, creds):
"""Determine whether is_admin matches the requested value."""
return creds['is_admin'] == self.expected
return _ENFORCER.authorize(rule, target, creds, do_raise=do_raise)

View File

@ -16,6 +16,10 @@
# under the License.
"""
IMPORTANT: this implementation was deprecated by oslo_policy and it is no longer
used in this repository. This file was not deleted because it is used by other
repositories.
Common Policy Engine Implementation
Policies can be expressed in one of two forms: A list of lists, or a

View File

@ -47,8 +47,6 @@ class FunctionalTest(base.TestCase):
def setUp(self):
super(FunctionalTest, self).setUp()
cfg.CONF.set_override("auth_version", "v2.0", group=acl.OPT_GROUP_NAME)
cfg.CONF.set_override("policy_file",
self.path_get('tests/policy.json'))
self.app = self._make_app()
self.dbapi = dbapi.get_instance()
self.context = sysinv_context.RequestContext(is_admin=True)

View File

@ -16,10 +16,10 @@
policy_data = """
{
"admin_api": "role:admin",
"admin_or_owner": "is_admin:True or project_id:%(project_id)s",
"is_admin": "role:admin or role:administrator",
"default": "rule:admin_or_owner"
}
---
admin_api: "role:admin"
admin_or_owner: "is_admin:True or project_id:%(project_id)s"
is_admin: "role:admin or role:administrator"
default: "rule:admin_or_owner"
"""

View File

@ -1,6 +0,0 @@
{
"admin_api": "is_admin:True",
"admin_or_owner": "is_admin:True or project_id:%(project_id)s",
"is_admin": "role:admin or role:administrator",
"default": "rule:admin_or_owner",
}

View File

@ -0,0 +1,11 @@
---
# The commented lines below contains the default values for presented rules.
# admin_in_system_projects: role:admin and (project_name:admin or project_name:services)
# reader_in_system_projects: role:reader and (project_name:admin or project_name:services)
# config_api:service_parameter:add: rule:admin_in_system_projects
# config_api:service_parameter:apply: rule:admin_in_system_projects
# config_api:service_parameter:delete: rule:admin_in_system_projects
# config_api:service_parameter:get: rule:reader_in_system_projects
# config_api:service_parameter:modify: rule:admin_in_system_projects

View File

@ -18,7 +18,6 @@ import fixtures
from oslo_config import cfg
from sysinv.common import policy as sysinv_policy
from sysinv.openstack.common import policy as common_policy
from sysinv.tests import fake_policy
CONF = cfg.CONF
@ -30,15 +29,9 @@ class PolicyFixture(fixtures.Fixture):
super(PolicyFixture, self).setUp()
self.policy_dir = self.useFixture(fixtures.TempDir())
self.policy_file_name = os.path.join(self.policy_dir.path,
'policy.json')
'policy.yaml')
with open(self.policy_file_name, 'w') as policy_file:
policy_file.write(fake_policy.policy_data)
CONF.set_override('policy_file', self.policy_file_name)
sysinv_policy.reset()
sysinv_policy.init()
sysinv_policy.init(self.policy_file_name)
self.addCleanup(sysinv_policy.reset)
def set_rules(self, rules):
common_policy.set_rules(common_policy.Rules(
dict((k, common_policy.parse_rule(v))
for k, v in rules.items())))