From 4ecd46800b2265a0519fbb4cd3cdb741138ed2c0 Mon Sep 17 00:00:00 2001 From: Yongli He Date: Thu, 18 Jun 2015 13:54:26 +0800 Subject: [PATCH] policy check for node add policy check for node. Change-Id: I4b025cb4f47c4683d826237318afdf2c2009841a Partial-implements: blueprint policy-enforce --- etc/magnum/policy.json | 9 +++- magnum/api/controllers/v1/node.py | 7 +++ magnum/tests/fake_policy.py | 9 +++- .../unit/api/controllers/v1/test_node.py | 43 +++++++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/etc/magnum/policy.json b/etc/magnum/policy.json index 2f4edb65cf..3e547a4963 100644 --- a/etc/magnum/policy.json +++ b/etc/magnum/policy.json @@ -16,5 +16,12 @@ "baymodel:detail": "rule:default", "baymodel:get": "rule:default", "baymodel:get_all": "rule:default", - "baymodel:update": "rule:default" + "baymodel:update": "rule:default", + + "node:create": "rule:default", + "node:delete": "rule:default", + "node:detail": "rule:default", + "node:get": "rule:default", + "node:get_all": "rule:default", + "node:update": "rule:default" } diff --git a/magnum/api/controllers/v1/node.py b/magnum/api/controllers/v1/node.py index cddda13a6d..1c3fbc8a80 100644 --- a/magnum/api/controllers/v1/node.py +++ b/magnum/api/controllers/v1/node.py @@ -27,6 +27,7 @@ from magnum.api.controllers.v1 import collection from magnum.api.controllers.v1 import types from magnum.api.controllers.v1 import utils as api_utils from magnum.common import exception +from magnum.common import policy from magnum import objects @@ -151,6 +152,7 @@ class NodesController(rest.RestController): sort_key=sort_key, sort_dir=sort_dir) + @policy.enforce_wsgi("node") @wsme_pecan.wsexpose(NodeCollection, types.uuid, types.uuid, int, wtypes.text, wtypes.text) def get_all(self, node_uuid=None, marker=None, limit=None, @@ -165,6 +167,7 @@ class NodesController(rest.RestController): return self._get_nodes_collection(marker, limit, sort_key, sort_dir) + @policy.enforce_wsgi("node") @wsme_pecan.wsexpose(NodeCollection, types.uuid, types.uuid, int, wtypes.text, wtypes.text) def detail(self, node_uuid=None, marker=None, limit=None, @@ -188,6 +191,7 @@ class NodesController(rest.RestController): sort_key, sort_dir, expand, resource_url) + @policy.enforce_wsgi("node", "get") @wsme_pecan.wsexpose(Node, types.uuid) def get_one(self, node_uuid): """Retrieve information about the given node. @@ -200,6 +204,7 @@ class NodesController(rest.RestController): rpc_node = objects.Node.get_by_uuid(pecan.request.context, node_uuid) return Node.convert_with_links(rpc_node) + @policy.enforce_wsgi("node", "create") @wsme_pecan.wsexpose(Node, body=Node, status_code=201) def post(self, node): """Create a new node. @@ -220,6 +225,7 @@ class NodesController(rest.RestController): pecan.response.location = link.build_url('nodes', new_node.uuid) return Node.convert_with_links(new_node) + @policy.enforce_wsgi("node", "update") @wsme.validate(types.uuid, [NodePatchType]) @wsme_pecan.wsexpose(Node, types.uuid, body=[NodePatchType]) def patch(self, node_uuid, patch): @@ -253,6 +259,7 @@ class NodesController(rest.RestController): rpc_node.save() return Node.convert_with_links(rpc_node) + @policy.enforce_wsgi("node", "delete") @wsme_pecan.wsexpose(None, types.uuid, status_code=204) def delete(self, node_uuid): """Delete a node. diff --git a/magnum/tests/fake_policy.py b/magnum/tests/fake_policy.py index b81aab0350..6cfbdae73c 100644 --- a/magnum/tests/fake_policy.py +++ b/magnum/tests/fake_policy.py @@ -32,7 +32,14 @@ policy_data = """ "baymodel:detail": "", "baymodel:get": "", "baymodel:get_all": "", - "baymodel:update": "" + "baymodel:update": "", + + "node:create": "", + "node:delete": "", + "node:detail": "", + "node:get": "", + "node:get_all": "", + "node:update": "" } """ diff --git a/magnum/tests/unit/api/controllers/v1/test_node.py b/magnum/tests/unit/api/controllers/v1/test_node.py index cd4b256f84..26fd73e5a2 100644 --- a/magnum/tests/unit/api/controllers/v1/test_node.py +++ b/magnum/tests/unit/api/controllers/v1/test_node.py @@ -14,6 +14,7 @@ import datetime import mock from oslo_config import cfg +from oslo_policy import policy from oslo_utils import timeutils from six.moves.urllib import parse as urlparse from wsme import types as wtypes @@ -264,3 +265,45 @@ class TestDelete(api_base.FunctionalTest): self.assertEqual(404, response.status_int) self.assertEqual('application/json', response.content_type) self.assertTrue(response.json['error_message']) + + +class TestNodePolicyEnforcement(api_base.FunctionalTest): + + def setUp(self): + super(TestNodePolicyEnforcement, self).setUp() + + 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( + "node:get_all", self.get_json, '/nodes') + + def test_policy_disallow_get_one(self): + self._common_policy_check( + "node:get", self.get_json, '/nodes/111-222-333') + + def test_policy_disallow_update(self): + node = obj_utils.create_test_node(self.context, + type='type_A', + uuid="333-444-5555") + self._common_policy_check( + "node:update", self.patch_json, + '/nodes/%s' % node.uuid, + [{'type': '/type', 'value': "new_type", 'op': 'replace'}]) + + def test_policy_disallow_create(self): + bdict = apiutils.node_post_data(name='node_example_A') + self._common_policy_check( + "node:create", self.post_json, '/nodes', bdict) + + def test_policy_disallow_delete(self): + node = obj_utils.create_test_node(self.context, + uuid='137-246-789') + self._common_policy_check( + "node:delete", self.delete, + '/nodes/%s' % node.uuid)