From 22c9c4df877b5fabcdf74bb80e61d24d06700dcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Fran=C3=A7oise?= Date: Thu, 18 Feb 2016 14:48:49 +0100 Subject: [PATCH] Disabled PATCH, POST and DELETE for /actions I removed the POST, PATCH and DELETE verbs from the actions controller as they should only be modified internally. Change-Id: Ia72484249240f829423056f66c5c0f9632d02106 Closes-Bug: #1533281 --- watcher/api/controllers/v1/action.py | 11 +++ watcher/locale/watcher.pot | 35 +++++++- watcher/tests/api/v1/test_actions.py | 123 ++------------------------- 3 files changed, 51 insertions(+), 118 deletions(-) diff --git a/watcher/api/controllers/v1/action.py b/watcher/api/controllers/v1/action.py index cd0c44363..f8baa3984 100644 --- a/watcher/api/controllers/v1/action.py +++ b/watcher/api/controllers/v1/action.py @@ -359,6 +359,10 @@ class ActionsController(rest.RestController): :param action: a action within the request body. """ + # FIXME: blueprint edit-action-plan-flow + raise exception.OperationNotPermitted( + _("Cannot create an action directly")) + if self.from_actions: raise exception.OperationNotPermitted @@ -379,6 +383,10 @@ class ActionsController(rest.RestController): :param action_uuid: UUID of a action. :param patch: a json PATCH document to apply to this action. """ + # FIXME: blueprint edit-action-plan-flow + raise exception.OperationNotPermitted( + _("Cannot modify an action directly")) + if self.from_actions: raise exception.OperationNotPermitted @@ -411,6 +419,9 @@ class ActionsController(rest.RestController): :param action_uuid: UUID of a action. """ + # FIXME: blueprint edit-action-plan-flow + raise exception.OperationNotPermitted( + _("Cannot delete an action directly")) action_to_delete = objects.Action.get_by_uuid( pecan.request.context, diff --git a/watcher/locale/watcher.pot b/watcher/locale/watcher.pot index cf3cfcfcd..9074548f9 100644 --- a/watcher/locale/watcher.pot +++ b/watcher/locale/watcher.pot @@ -7,9 +7,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: python-watcher 0.24.1.dev12\n" +"Project-Id-Version: python-watcher 0.25.1.dev3\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2016-03-16 18:18-0500\n" +"POT-Creation-Date: 2016-03-30 10:10+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,6 +18,18 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.2.0\n" +#: watcher/api/controllers/v1/action.py:364 +msgid "Cannot create an action directly" +msgstr "" + +#: watcher/api/controllers/v1/action.py:388 +msgid "Cannot modify an action directly" +msgstr "" + +#: watcher/api/controllers/v1/action.py:424 +msgid "Cannot delete an action directly" +msgstr "" + #: watcher/api/controllers/v1/action_plan.py:102 #, python-format msgid "Invalid state: %(state)s" @@ -551,6 +563,25 @@ msgstr "" msgid "No proper target host could be found" msgstr "" +#: watcher/decision_engine/strategy/strategies/vm_workload_consolidation.py:104 +#, python-format +msgid "Unexpexted resource state type, state=%(state)s, state_type=%(st)s." +msgstr "" + +#: watcher/decision_engine/strategy/strategies/vm_workload_consolidation.py:156 +#, python-format +msgid "Cannot live migrate: vm_uuid=%(vm_uuid)s, state=%(vm_state)s." +msgstr "" + +#: watcher/decision_engine/strategy/strategies/vm_workload_consolidation.py:240 +#, python-format +msgid "No values returned by %(resource_id)s for memory.usage or disk.root.size" +msgstr "" + +#: watcher/decision_engine/strategy/strategies/vm_workload_consolidation.py:489 +msgid "Executing Smart Strategy" +msgstr "" + #: watcher/objects/base.py:70 #, python-format msgid "Error setting %(attr)s" diff --git a/watcher/tests/api/v1/test_actions.py b/watcher/tests/api/v1/test_actions.py index 8e88b39ed..6fc93c988 100644 --- a/watcher/tests/api/v1/test_actions.py +++ b/watcher/tests/api/v1/test_actions.py @@ -14,13 +14,11 @@ import datetime import mock from oslo_config import cfg -from oslo_utils import timeutils from wsme import types as wtypes from watcher.api.controllers.v1 import action as api_action from watcher.common import utils from watcher.db import api as db_api -from watcher import objects from watcher.tests.api import base as api_base from watcher.tests.api import utils as api_utils from watcher.tests import base @@ -442,7 +440,7 @@ class TestPatch(api_base.FunctionalTest): return action @mock.patch('oslo_utils.timeutils.utcnow') - def test_replace_ok(self, mock_utcnow): + def test_patch_not_allowed(self, mock_utcnow): test_time = datetime.datetime(2000, 1, 1, 0, 0) mock_utcnow.return_value = test_time @@ -453,104 +451,12 @@ class TestPatch(api_base.FunctionalTest): response = self.patch_json( '/actions/%s' % self.action.uuid, [{'path': '/state', 'value': new_state, - 'op': 'replace'}]) - self.assertEqual('application/json', response.content_type) - self.assertEqual(200, response.status_code) - - response = self.get_json('/actions/%s' % self.action.uuid) - self.assertEqual(new_state, response['state']) - return_updated_at = timeutils.parse_isotime( - response['updated_at']).replace(tzinfo=None) - self.assertEqual(test_time, return_updated_at) - - def test_replace_non_existent_action(self): - response = self.patch_json('/actions/%s' % utils.generate_uuid(), - [{'path': '/state', 'value': 'SUBMITTED', - 'op': 'replace'}], - expect_errors=True) - self.assertEqual(404, response.status_int) - self.assertEqual('application/json', response.content_type) - self.assertTrue(response.json['error_message']) - - def test_add_ok(self): - new_state = 'SUCCEEDED' - response = self.patch_json( - '/actions/%s' % self.action.uuid, - [{'path': '/state', 'value': new_state, 'op': 'add'}]) - self.assertEqual('application/json', response.content_type) - self.assertEqual(200, response.status_int) - - response = self.get_json('/actions/%s' % self.action.uuid) - self.assertEqual(new_state, response['state']) - - def test_add_non_existent_property(self): - response = self.patch_json( - '/actions/%s' % self.action.uuid, - [{'path': '/foo', 'value': 'bar', 'op': 'add'}], + 'op': 'replace'}], expect_errors=True) self.assertEqual('application/json', response.content_type) - self.assertEqual(400, response.status_int) + self.assertEqual(403, response.status_int) self.assertTrue(response.json['error_message']) - def test_remove_ok(self): - response = self.get_json('/actions/%s' % self.action.uuid) - self.assertIsNotNone(response['state']) - - response = self.patch_json('/actions/%s' % self.action.uuid, - [{'path': '/state', 'op': 'remove'}]) - self.assertEqual('application/json', response.content_type) - self.assertEqual(200, response.status_code) - - response = self.get_json('/actions/%s' % self.action.uuid) - self.assertIsNone(response['state']) - - def test_remove_uuid(self): - response = self.patch_json('/actions/%s' % self.action.uuid, - [{'path': '/uuid', 'op': 'remove'}], - expect_errors=True) - self.assertEqual(400, response.status_int) - self.assertEqual('application/json', response.content_type) - self.assertTrue(response.json['error_message']) - - def test_remove_non_existent_property(self): - response = self.patch_json( - '/actions/%s' % self.action.uuid, - [{'path': '/non-existent', 'op': 'remove'}], - expect_errors=True) - self.assertEqual(400, response.status_code) - self.assertEqual('application/json', response.content_type) - self.assertTrue(response.json['error_message']) - - -# class TestDelete(api_base.FunctionalTest): - -# def setUp(self): -# super(TestDelete, self).setUp() -# self.action = obj_utils.create_test_action(self.context, next=None) -# p = mock.patch.object(db_api.Connection, 'destroy_action') -# self.mock_action_delete = p.start() -# self.mock_action_delete.side_effect = -# self._simulate_rpc_action_delete -# self.addCleanup(p.stop) - -# def _simulate_rpc_action_delete(self, action_uuid): -# action = objects.Action.get_by_uuid(self.context, action_uuid) -# action.destroy() - -# def test_delete_action(self): -# self.delete('/actions/%s' % self.action.uuid) -# response = self.get_json('/actions/%s' % self.action.uuid, -# expect_errors=True) -# self.assertEqual(404, response.status_int) -# self.assertEqual('application/json', response.content_type) -# self.assertTrue(response.json['error_message']) - -# def test_delete_action_not_found(self): -# uuid = utils.generate_uuid() -# response = self.delete('/actions/%s' % uuid, expect_errors=True) -# self.assertEqual(404, response.status_int) -# self.assertEqual('application/json', response.content_type) -# self.assertTrue(response.json['error_message']) class TestDelete(api_base.FunctionalTest): @@ -568,26 +474,11 @@ class TestDelete(api_base.FunctionalTest): return action @mock.patch('oslo_utils.timeutils.utcnow') - def test_delete_action(self, mock_utcnow): + def test_delete_action_not_allowed(self, mock_utcnow): test_time = datetime.datetime(2000, 1, 1, 0, 0) mock_utcnow.return_value = test_time - self.delete('/actions/%s' % self.action.uuid) - response = self.get_json('/actions/%s' % self.action.uuid, - expect_errors=True) - self.assertEqual(404, response.status_int) - self.assertEqual('application/json', response.content_type) - self.assertTrue(response.json['error_message']) - - self.context.show_deleted = True - action = objects.Action.get_by_uuid(self.context, self.action.uuid) - - return_deleted_at = timeutils.strtime(action['deleted_at']) - self.assertEqual(timeutils.strtime(test_time), return_deleted_at) - self.assertEqual('DELETED', action['state']) - - def test_delete_action_not_found(self): - uuid = utils.generate_uuid() - response = self.delete('/actions/%s' % uuid, expect_errors=True) - self.assertEqual(404, response.status_int) + response = self.delete('/actions/%s' % self.action.uuid, + expect_errors=True) + self.assertEqual(403, response.status_int) self.assertEqual('application/json', response.content_type) self.assertTrue(response.json['error_message'])