From d9739584bf2b4a5dc5b0223f41d429edf849d0bc Mon Sep 17 00:00:00 2001 From: yuntongjin Date: Thu, 23 Jul 2015 11:10:49 +0800 Subject: [PATCH] policy check for container add policy check for container Change-Id: I7ff39b37b4a65d882b896dcad65d6ff5dc08c0d1 Partial-implements: blueprint policy-enforce --- etc/magnum/policy.json | 9 +++- magnum/api/controllers/v1/container.py | 7 +++ magnum/tests/fake_policy.py | 9 +++- .../unit/api/controllers/v1/test_container.py | 50 +++++++++++++++++++ 4 files changed, 73 insertions(+), 2 deletions(-) diff --git a/etc/magnum/policy.json b/etc/magnum/policy.json index 1970a32fbb..833d26cd43 100644 --- a/etc/magnum/policy.json +++ b/etc/magnum/policy.json @@ -44,5 +44,12 @@ "service:detail": "rule:default", "service:get": "rule:default", "service:get_all": "rule:default", - "service:update": "rule:default" + "service:update": "rule:default", + + "container:create": "rule:default", + "container:delete": "rule:default", + "container:detail": "rule:default", + "container:get": "rule:default", + "container:get_all": "rule:default", + "container:update": "rule:default" } diff --git a/magnum/api/controllers/v1/container.py b/magnum/api/controllers/v1/container.py index eaa0d7f6d7..70ce31ec96 100644 --- a/magnum/api/controllers/v1/container.py +++ b/magnum/api/controllers/v1/container.py @@ -29,6 +29,7 @@ from magnum.api.controllers.v1 import utils as api_utils from magnum.api import expose from magnum.api import validation from magnum.common import exception +from magnum.common import policy from magnum import objects LOG = logging.getLogger(__name__) @@ -291,6 +292,7 @@ class ContainersController(rest.RestController): sort_key=sort_key, sort_dir=sort_dir) + @policy.enforce_wsgi("container") @expose.expose(ContainerCollection, types.uuid, types.uuid, int, wtypes.text, wtypes.text) def get_all(self, container_uuid=None, marker=None, limit=None, @@ -305,6 +307,7 @@ class ContainersController(rest.RestController): return self._get_containers_collection(marker, limit, sort_key, sort_dir) + @policy.enforce_wsgi("container") @expose.expose(ContainerCollection, types.uuid, types.uuid, int, wtypes.text, wtypes.text) def detail(self, container_uuid=None, marker=None, limit=None, @@ -328,6 +331,7 @@ class ContainersController(rest.RestController): sort_key, sort_dir, expand, resource_url) + @policy.enforce_wsgi("container", "get") @expose.expose(Container, types.uuid_or_name) def get_one(self, container_ident): """Retrieve information about the given container. @@ -339,6 +343,7 @@ class ContainersController(rest.RestController): res_container = pecan.request.rpcapi.container_show(rpc_container.uuid) return Container.convert_with_links(res_container) + @policy.enforce_wsgi("container", "create") @expose.expose(Container, body=Container, status_code=201) @validation.enforce_bay_types('swarm') def post(self, container): @@ -362,6 +367,7 @@ class ContainersController(rest.RestController): res_container.uuid) return Container.convert_with_links(res_container) + @policy.enforce_wsgi("container", "update") @wsme.validate(types.uuid, [ContainerPatchType]) @expose.expose(Container, types.uuid_or_name, body=[ContainerPatchType]) @@ -395,6 +401,7 @@ class ContainersController(rest.RestController): rpc_container.save() return Container.convert_with_links(rpc_container) + @policy.enforce_wsgi("container") @expose.expose(None, types.uuid_or_name, status_code=204) def delete(self, container_ident): """Delete a container. diff --git a/magnum/tests/fake_policy.py b/magnum/tests/fake_policy.py index b4d0410534..172a49c744 100644 --- a/magnum/tests/fake_policy.py +++ b/magnum/tests/fake_policy.py @@ -60,7 +60,14 @@ policy_data = """ "service:detail": "", "service:get": "", "service:get_all": "", - "service:update": "" + "service:update": "", + + "container:create": "", + "container:delete": "", + "container:detail": "", + "container:get": "", + "container:get_all": "", + "container:update": "" } """ diff --git a/magnum/tests/unit/api/controllers/v1/test_container.py b/magnum/tests/unit/api/controllers/v1/test_container.py index e60642f005..a6aa75c51a 100644 --- a/magnum/tests/unit/api/controllers/v1/test_container.py +++ b/magnum/tests/unit/api/controllers/v1/test_container.py @@ -10,10 +10,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +from magnum.common import utils as comm_utils from magnum import objects from magnum.tests.unit.api import base as api_base from magnum.tests.unit.db import utils +from oslo_policy import policy + import mock from mock import patch from webtest.app import AppError @@ -441,3 +444,50 @@ class TestContainerController(api_base.FunctionalTest): self.assertEqual(response.status_int, 204) mock_container_delete.assert_called_once_with(container_uuid) mock_destroy.assert_called_once_with() + + +class TestContainerEnforcement(api_base.FunctionalTest): + + def _common_policy_check(self, rule, func, *arg, **kwarg): + self.policy.set_rules({rule: 'project:non_fake'}) + exc = self.assertRaises(policy.PolicyNotAuthorized, + func, *arg, **kwarg) + self.assertTrue(exc.message.startswith(rule)) + self.assertTrue(exc.message.endswith('disallowed by policy')) + + def test_policy_disallow_get_all(self): + self._common_policy_check( + 'container:get_all', self.get_json, '/containers') + + def test_policy_disallow_get_one(self): + self._common_policy_check( + 'container:get', self.get_json, '/containers/111-222-333') + + def test_policy_disallow_detail(self): + self._common_policy_check( + 'container:detail', + self.get_json, + '/containers/111-222-333/detail') + + def test_policy_disallow_update(self): + test_container = utils.get_test_container() + container_uuid = test_container.get('uuid') + params = [{'path': '/name', + 'value': 'new_name', + 'op': 'replace'}] + self._common_policy_check( + 'container:update', self.app.patch_json, + '/v1/containers/%s' % container_uuid, params) + + def test_policy_disallow_create(self): + params = ('{"name": "' + 'i' * 256 + '", "image": "ubuntu",' + '"command": "env",' + '"bay_uuid": "fff114da-3bfa-4a0f-a123-c0dffad9718e"}') + + self._common_policy_check( + 'container:create', self.app.post, '/v1/containers', params) + + def test_policy_disallow_delete(self): + self._common_policy_check( + 'container:delete', self.app.delete, + '/v1/containers/%s' % comm_utils.generate_uuid())