From d0d7fc3a19dba48fa988b995db620e0da066381a Mon Sep 17 00:00:00 2001 From: Ken'ichi Ohmichi Date: Mon, 12 Jun 2017 12:37:20 -0700 Subject: [PATCH] Add bool_from_string for force-down action On force-down action API, its forced_down parameter is defined as parameter_types.boolean which allows string values like 'True', 'False', etc. However the API code didn't contain bool_from_string call which converts string value to boolean value. In addition, the parameter is defined as BooleanField in the service object. So if the string value is passed on forced_down parameter, HTTP 500 error happaned. This patch fixes this problem by adding bool_from_string call. Closes-Bug: #1697497 Change-Id: Ifca579d1bb43ece190c633b3ea1ffa476daf6e34 --- nova/api/openstack/compute/services.py | 3 +- .../api/openstack/compute/test_services.py | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/nova/api/openstack/compute/services.py b/nova/api/openstack/compute/services.py index c4b67cfacd5d..435da2a2c981 100644 --- a/nova/api/openstack/compute/services.py +++ b/nova/api/openstack/compute/services.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo_utils import strutils import webob.exc from nova.api.openstack import api_version_request @@ -133,7 +134,7 @@ class ServiceController(wsgi.Controller): def _forced_down(self, body, context): """Set or unset forced_down flag for the service""" try: - forced_down = body["forced_down"] + forced_down = strutils.bool_from_string(body["forced_down"]) except KeyError: msg = _('Missing forced_down field') raise webob.exc.HTTPBadRequest(explanation=msg) diff --git a/nova/tests/unit/api/openstack/compute/test_services.py b/nova/tests/unit/api/openstack/compute/test_services.py index 41ea739f1c25..38f4ba7f2449 100644 --- a/nova/tests/unit/api/openstack/compute/test_services.py +++ b/nova/tests/unit/api/openstack/compute/test_services.py @@ -117,6 +117,9 @@ class FakeRequest(object): super(FakeRequest, self).__init__() self.api_version_request = api_version.APIVersionRequest(version) + def is_legacy_v2(self): + return False + class FakeRequestWithService(FakeRequest): GET = {"binary": "nova-compute"} @@ -886,6 +889,43 @@ class ServicesTestV211(ServicesTestV21): self._process_output(response, has_id=True) self.assertEqual(res_dict, response) + def test_force_down_service(self): + req = FakeRequest(self.wsgi_api_version) + req_body = {"forced_down": True, + "host": "host1", "binary": "nova-compute"} + res_dict = self.controller.update(req, 'force-down', body=req_body) + + response = { + "service": { + "forced_down": True, + "host": "host1", + "binary": "nova-compute" + } + } + self.assertEqual(response, res_dict) + + def test_force_down_service_with_string_forced_down(self): + req = FakeRequest(self.wsgi_api_version) + req_body = {"forced_down": "True", + "host": "host1", "binary": "nova-compute"} + res_dict = self.controller.update(req, 'force-down', body=req_body) + + response = { + "service": { + "forced_down": True, + "host": "host1", + "binary": "nova-compute" + } + } + self.assertEqual(response, res_dict) + + def test_force_down_service_with_invalid_parameter(self): + req = FakeRequest(self.wsgi_api_version) + req_body = {"forced_down": "Invalid", + "host": "host1", "binary": "nova-compute"} + self.assertRaises(exception.ValidationError, + self.controller.update, req, 'force-down', body=req_body) + class ServicesCellsTestV21(test.TestCase):