From c77e0c709abe614f24a29330fb3c8578f265872e Mon Sep 17 00:00:00 2001 From: Hieu LE Date: Wed, 4 Oct 2017 15:18:15 +0700 Subject: [PATCH] Register default magnum service and stat policies in code This commit uses the existing policy-in-code module to move all default policies for magnum service and stat into code. This commit also adds helpful documentation about each API those policies protect, which will be generated in sample policy files and completely remove usage of policy.json file. Co-authored-By: Dai Dang-Van Implements: blueprint policy-in-code Change-Id: I01a8ce964bf8bd569d4aa4e899cbcd9855281835 --- devstack/lib/magnum | 6 ++-- etc/magnum/policy.json | 4 --- magnum/common/policies/__init__.py | 6 +++- magnum/common/policies/magnum_service.py | 36 +++++++++++++++++++ magnum/common/policies/stats.py | 36 +++++++++++++++++++ magnum/tests/fake_policy.py | 21 ----------- magnum/tests/policy_fixture.py | 13 ++----- .../api/controllers/v1/test_magnum_service.py | 12 +++++-- setup.cfg | 1 - 9 files changed, 90 insertions(+), 45 deletions(-) delete mode 100644 etc/magnum/policy.json create mode 100644 magnum/common/policies/magnum_service.py create mode 100644 magnum/common/policies/stats.py delete mode 100644 magnum/tests/fake_policy.py diff --git a/devstack/lib/magnum b/devstack/lib/magnum index 2a6e49cd77..82d303abbe 100644 --- a/devstack/lib/magnum +++ b/devstack/lib/magnum @@ -43,8 +43,8 @@ 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 MAGNUM_API_PASTE=$MAGNUM_CONF_DIR/api-paste.ini +MAGNUM_POLICY=$MAGNUM_CONF_DIR/policy.yaml if is_ssl_enabled_service "magnum" || is_service_enabled tls-proxy; then MAGNUM_SERVICE_PROTOCOL="https" @@ -92,7 +92,6 @@ function configure_magnum { sudo chown $STACK_USER $MAGNUM_CONF_DIR fi - install_default_policy magnum # Rebuild the config file from scratch create_magnum_conf @@ -132,8 +131,7 @@ function create_magnum_conf { iniset $MAGNUM_CONF database connection `database_connection_url magnum` 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 + iniset $MAGNUM_CONF oslo_policy policy_file $MAGNUM_POLICY iniset $MAGNUM_CONF keystone_auth auth_type password iniset $MAGNUM_CONF keystone_auth username magnum diff --git a/etc/magnum/policy.json b/etc/magnum/policy.json deleted file mode 100644 index 7ec3c3729f..0000000000 --- a/etc/magnum/policy.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "magnum-service:get_all": "rule:admin_api", - "stats:get_all": "rule:admin_or_owner" -} diff --git a/magnum/common/policies/__init__.py b/magnum/common/policies/__init__.py index 9727a75139..0722800fc5 100644 --- a/magnum/common/policies/__init__.py +++ b/magnum/common/policies/__init__.py @@ -20,7 +20,9 @@ from magnum.common.policies import baymodel from magnum.common.policies import certificate from magnum.common.policies import cluster from magnum.common.policies import cluster_template +from magnum.common.policies import magnum_service from magnum.common.policies import quota +from magnum.common.policies import stats def list_rules(): @@ -31,5 +33,7 @@ def list_rules(): certificate.list_rules(), cluster.list_rules(), cluster_template.list_rules(), - quota.list_rules() + magnum_service.list_rules(), + quota.list_rules(), + stats.list_rules() ) diff --git a/magnum/common/policies/magnum_service.py b/magnum/common/policies/magnum_service.py new file mode 100644 index 0000000000..622f13ec56 --- /dev/null +++ b/magnum/common/policies/magnum_service.py @@ -0,0 +1,36 @@ +# 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. +from oslo_policy import policy + +from magnum.common.policies import base + +SERVICE = 'magnum-service:%s' + +rules = [ + policy.DocumentedRuleDefault( + name=SERVICE % 'get_all', + check_str=base.RULE_ADMIN_API, + description='Retrieve a list of magnum-services.', + operations=[ + { + 'path': '/v1/mservices', + 'method': 'GET' + } + ] + ) +] + + +def list_rules(): + return rules diff --git a/magnum/common/policies/stats.py b/magnum/common/policies/stats.py new file mode 100644 index 0000000000..c37164094b --- /dev/null +++ b/magnum/common/policies/stats.py @@ -0,0 +1,36 @@ +# 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. +from oslo_policy import policy + +from magnum.common.policies import base + +STATS = 'stats:%s' + +rules = [ + policy.DocumentedRuleDefault( + name=STATS % 'get_all', + check_str=base.RULE_ADMIN_OR_OWNER, + description='Retrieve magnum stats.', + operations=[ + { + 'path': '/v1/stats', + 'method': 'GET' + } + ] + ) +] + + +def list_rules(): + return rules diff --git a/magnum/tests/fake_policy.py b/magnum/tests/fake_policy.py deleted file mode 100644 index 61fe26ac4f..0000000000 --- a/magnum/tests/fake_policy.py +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (c) 2012 OpenStack Foundation -# -# 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_data = """ -{ - "magnum-service:get_all": "", - "stats:get_all": "" -} -""" diff --git a/magnum/tests/policy_fixture.py b/magnum/tests/policy_fixture.py index 28e1bb1bad..b2ddc8ed9a 100644 --- a/magnum/tests/policy_fixture.py +++ b/magnum/tests/policy_fixture.py @@ -12,29 +12,20 @@ # License for the specific language governing permissions and limitations # under the License. -import os - import fixtures -from oslo_config import cfg from oslo_policy import _parser from oslo_policy import opts as policy_opts from magnum.common import policy as magnum_policy -from magnum.tests import fake_policy +import magnum.conf -CONF = cfg.CONF +CONF = magnum.conf.CONF class PolicyFixture(fixtures.Fixture): def _setUp(self): - self.policy_dir = self.useFixture(fixtures.TempDir()) - self.policy_file_name = os.path.join(self.policy_dir.path, - 'policy.json') - with open(self.policy_file_name, 'w') as policy_file: - policy_file.write(fake_policy.policy_data) policy_opts.set_defaults(CONF) - CONF.set_override('policy_file', self.policy_file_name, 'oslo_policy') magnum_policy._ENFORCER = None self.addCleanup(magnum_policy.init().clear) diff --git a/magnum/tests/unit/api/controllers/v1/test_magnum_service.py b/magnum/tests/unit/api/controllers/v1/test_magnum_service.py index d6ca6843ec..395ee07f32 100644 --- a/magnum/tests/unit/api/controllers/v1/test_magnum_service.py +++ b/magnum/tests/unit/api/controllers/v1/test_magnum_service.py @@ -44,7 +44,9 @@ class db_rec(object): class TestMagnumServiceController(api_base.FunctionalTest): - def test_empty(self): + @mock.patch("magnum.common.policy.enforce") + def test_empty(self, mock_policy): + mock_policy.return_value = True response = self.get_json('/mservices') self.assertEqual([], response['mservices']) @@ -57,9 +59,11 @@ class TestMagnumServiceController(api_base.FunctionalTest): reclist.append(rec) return reclist + @mock.patch("magnum.common.policy.enforce") @mock.patch.object(objects.MagnumService, 'list') @mock.patch.object(servicegroup.ServiceGroup, 'service_is_up') - def test_get_one(self, svc_up, rpc_patcher): + def test_get_one(self, svc_up, rpc_patcher, mock_policy): + mock_policy.return_value = True rpc_patcher.return_value = self._rpc_api_reply() svc_up.return_value = "up" @@ -67,9 +71,11 @@ class TestMagnumServiceController(api_base.FunctionalTest): self.assertEqual(1, len(response['mservices'])) self.assertEqual(1, response['mservices'][0]['id']) + @mock.patch("magnum.common.policy.enforce") @mock.patch.object(objects.MagnumService, 'list') @mock.patch.object(servicegroup.ServiceGroup, 'service_is_up') - def test_get_many(self, svc_up, rpc_patcher): + def test_get_many(self, svc_up, rpc_patcher, mock_policy): + mock_policy.return_value = True svc_num = 5 rpc_patcher.return_value = self._rpc_api_reply(svc_num) svc_up.return_value = "up" diff --git a/setup.cfg b/setup.cfg index a436a65a83..539bd334fb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -22,7 +22,6 @@ classifier = data_files = etc/magnum = etc/magnum/api-paste.ini - etc/magnum/policy.json packages = magnum