From 0604b0404fb77fda498b2ea0f282c0370292ba68 Mon Sep 17 00:00:00 2001 From: Samantha Blanco Date: Wed, 28 Mar 2018 15:44:12 -0400 Subject: [PATCH] Improve Promenade validatedesign message Improves validatedesign return message by including count and list of validation errors. Change-Id: I7771eafedaa56c748f43fe1212926154933f247f --- docs/source/api.rst | 20 +++++++++---------- promenade/control/validatedesign.py | 30 ++++++++++++++--------------- promenade/validation.py | 21 ++++++++++++++++---- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/docs/source/api.rst b/docs/source/api.rst index ac66ea5d..3d17918f 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -11,8 +11,9 @@ GET /v1.0/health Returns the health status. -Responses -- 204 No Content +Responses: + ++ 204 No Content /v1.0/join-scripts @@ -37,9 +38,10 @@ dynamic.labels static.labels Used to set configuration options in the generated script -Responses -- 200 OK: Script returned as response body -- 400 Bad Request: One or more query parameters is missing or misspelled +Responses: + ++ 200 OK: Script returned as response body ++ 400 Bad Request: One or more query parameters is missing or misspelled /v1.0/validatedesign @@ -55,10 +57,8 @@ Message Body href Location of the document to be validated -type - Type of document to be validated Responses: -- 200 OK: Documents were successfully validated -- 400 Bad Request: Documents were not successfully validated -- 404 Not Found: The document (of that type) was not found at the specified location + ++ 200 OK: Documents were successfully validated ++ 400 Bad Request: Documents were not successfully validated diff --git a/promenade/control/validatedesign.py b/promenade/control/validatedesign.py index b366c98b..3fc39f5e 100644 --- a/promenade/control/validatedesign.py +++ b/promenade/control/validatedesign.py @@ -26,13 +26,15 @@ LOG = logging.getLogger(__name__) class ValidateDesignResource(base.BaseResource): - def _return_msg(self, resp, status_code, status="Valid", message=""): - if status_code is falcon.HTTP_200: - count = 0 - msg_list = [] + def _return_msg(self, resp, result): + if result['err_count'] == 0: + message = "Promenade validations succeeded." + status_code = falcon.HTTP_200 + status = "Valid" else: - count = 1 - msg_list = [message] + message = "Promenade validations failed." + status_code = falcon.HTTP_400 + status = "Invalid" resp.body = json.dumps({ "kind": "Status", "apiVersion": "v1", @@ -41,8 +43,8 @@ class ValidateDesignResource(base.BaseResource): "message": message, "reason": "Validation", "details": { - "errorCount": count, - "messageList": msg_list, + "errorCount": result['err_count'], + "messageList": result['msg'], }, "code": status_code, }) @@ -55,12 +57,10 @@ class ValidateDesignResource(base.BaseResource): href = json_data.get('href', None) config = Configuration.from_design_ref( href, allow_missing_substitutions=False) - validation.check_design(config) - msg = "Promenade validations succeeded" - return self._return_msg(resp, falcon.HTTP_200, message=msg) + result = validation.check_design(config) except exceptions.InvalidFormatError as e: msg = "Invalid JSON Format: %s" % str(e) - except exceptions.ValidationException as e: - msg = "Promenade validations failed: %s" % str(e) - return self._return_msg( - resp, falcon.HTTP_400, status="Invalid", message=msg) + result = {'msg': [msg], 'err_count': 1} + except exceptions.DeckhandException as e: + result = {'msg': [str(e)], 'err_count': 1} + return self._return_msg(resp, result) diff --git a/promenade/validation.py b/promenade/validation.py index b8778a84..d2ad3e33 100644 --- a/promenade/validation.py +++ b/promenade/validation.py @@ -14,30 +14,42 @@ from promenade import exceptions from promenade import logging +import copy import jsonschema import os import pkg_resources import yaml __all__ = ['check_schema', 'check_schemas'] +result_template = {'msg': [], 'err_count': 0} LOG = logging.getLogger(__name__) def check_design(config): kinds = ['Docker', 'HostSystem', 'Kubelet', 'KubernetesNetwork'] + result = copy.deepcopy(result_template) for kind in kinds: count = 0 for doc in config.documents: schema = doc.get('schema', None) if not schema: - raise exceptions.ValidationException( - '"schema" is a required document key.') + result['msg'].append( + str( + exceptions.ValidationException( + '"schema" is a required document key.'))) + result['err_count'] += 1 + return result name = schema.split('/')[1] if name == kind: count += 1 if count != 1: - raise exceptions.ValidationException() + msg = ('There are {0} {1} documents. However, there should be one.' + ).format(count, kind) + result['msg'].append( + str(exceptions.ValidationException(description=msg))) + result['err_count'] += 1 + return result def check_schemas(documents, schemas=None): @@ -49,7 +61,8 @@ def check_schemas(documents, schemas=None): def check_schema(document, schemas=None): if not isinstance(document, dict): - LOG.error('Non-dictionary document passed to schema validation.') + msg = 'Non-dictionary document passed to schema validation.' + LOG.error(msg) return schema_name = document.get('schema', '')