From f2751b48182b32fccad3d175e6ddc3d8e53e5867 Mon Sep 17 00:00:00 2001 From: Yumeng_Bao Date: Thu, 8 Jun 2017 17:04:02 +0800 Subject: [PATCH] Replace voluptuous with JSONSchema to validate change_nova_service_state Now in watcher,both JSONSchema and voluptuous are used to validate JSON payloads. We want to remove voluptuous and Use JSONSchema as our only JSON validation tool to keep consistence and also to make it easier to expose the validation schema through our API in future work. In this patch, we replace voluptuous with JSONSchema to validate the change_nova_service_state action in watcher applier. Partially Implements: blueprint jsonschema-validation Change-Id: I09a03fff96d9555024a74ba255c6951affc39de8 --- .../actions/change_nova_service_state.py | 37 +++++++++++++------ .../actions/test_change_nova_service_state.py | 27 ++++---------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/watcher/applier/actions/change_nova_service_state.py b/watcher/applier/actions/change_nova_service_state.py index 201a3c5fe..5082651e7 100644 --- a/watcher/applier/actions/change_nova_service_state.py +++ b/watcher/applier/actions/change_nova_service_state.py @@ -17,8 +17,7 @@ # limitations under the License. # -import six -import voluptuous +import jsonschema from watcher._i18n import _ from watcher.applier.actions import base @@ -51,15 +50,31 @@ class ChangeNovaServiceState(base.BaseAction): @property def schema(self): - return voluptuous.Schema({ - voluptuous.Required(self.RESOURCE_ID): - voluptuous.All( - voluptuous.Any(*six.string_types), - voluptuous.Length(min=1)), - voluptuous.Required(self.STATE): - voluptuous.Any(*[state.value - for state in list(element.ServiceState)]), - }) + return { + 'type': 'object', + 'properties': { + 'resource_id': { + 'type': 'string', + "minlength": 1 + }, + 'state': { + 'type': 'string', + 'enum': [element.ServiceState.ONLINE.value, + element.ServiceState.OFFLINE.value, + element.ServiceState.ENABLED.value, + element.ServiceState.DISABLED.value] + } + }, + 'required': ['resource_id', 'state'], + 'additionalProperties': False, + } + + def validate_parameters(self): + try: + jsonschema.validate(self.input_parameters, self.schema) + return True + except jsonschema.ValidationError as e: + raise e @property def host(self): diff --git a/watcher/tests/applier/actions/test_change_nova_service_state.py b/watcher/tests/applier/actions/test_change_nova_service_state.py index 2495a4b7c..e2f016c56 100644 --- a/watcher/tests/applier/actions/test_change_nova_service_state.py +++ b/watcher/tests/applier/actions/test_change_nova_service_state.py @@ -15,8 +15,8 @@ from __future__ import unicode_literals +import jsonschema import mock -import voluptuous from watcher.applier.actions import base as baction from watcher.applier.actions import change_nova_service_state @@ -73,33 +73,20 @@ class TestChangeNovaServiceState(base.TestCase): self.action.input_parameters = { baction.BaseAction.RESOURCE_ID: "compute-1", self.action.STATE: 'error'} - exc = self.assertRaises( - voluptuous.Invalid, self.action.validate_parameters) - self.assertEqual( - [(['state'], voluptuous.ScalarInvalid)], - [([str(p) for p in e.path], type(e)) for e in exc.errors]) + self.assertRaises(jsonschema.ValidationError, + self.action.validate_parameters) def test_parameters_resource_id_empty(self): self.action.input_parameters = { self.action.STATE: element.ServiceState.ENABLED.value, } - exc = self.assertRaises( - voluptuous.Invalid, self.action.validate_parameters) - self.assertEqual( - [(['resource_id'], voluptuous.RequiredFieldInvalid)], - [([str(p) for p in e.path], type(e)) for e in exc.errors]) + self.assertRaises(jsonschema.ValidationError, + self.action.validate_parameters) def test_parameters_applies_add_extra(self): self.action.input_parameters = {"extra": "failed"} - exc = self.assertRaises( - voluptuous.Invalid, self.action.validate_parameters) - self.assertEqual( - sorted([(['resource_id'], voluptuous.RequiredFieldInvalid), - (['state'], voluptuous.RequiredFieldInvalid), - (['extra'], voluptuous.Invalid)], - key=lambda x: str(x[0])), - sorted([([str(p) for p in e.path], type(e)) for e in exc.errors], - key=lambda x: str(x[0]))) + self.assertRaises(jsonschema.ValidationError, + self.action.validate_parameters) def test_change_service_state_pre_condition(self): try: