Update validatedesign message

Update validatedesign failure message to return more detailed error
message.

Change-Id: I56f11ecd3030532d90b421dce5d8959b28d40cbb
This commit is contained in:
Samantha Blanco 2018-05-24 16:23:58 -04:00
parent ec912fde36
commit 2cd353da21
4 changed files with 111 additions and 45 deletions

View File

@ -11,44 +11,19 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import logging
import falcon
from promenade.config import Configuration
from promenade.control import base
from promenade import exceptions
from promenade import policy
from promenade.utils.validation_message import ValidationMessage
from promenade import validation
LOG = logging.getLogger(__name__)
class ValidateDesignResource(base.BaseResource):
def _return_msg(self, resp, result):
if result['err_count'] == 0:
message = "Promenade validations succeeded."
status_code = falcon.HTTP_200
status = "Success"
else:
message = "Promenade validations failed."
status_code = falcon.HTTP_400
status = "Failure"
resp.body = json.dumps({
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": status,
"message": message,
"reason": "Validation",
"details": {
"errorCount": result['err_count'],
"messageList": result['msg'],
},
"code": status_code,
})
@policy.ApiEnforcer('kubernetes_provisioner:post_validatedesign')
def on_post(self, req, resp):
@ -58,9 +33,12 @@ class ValidateDesignResource(base.BaseResource):
config = Configuration.from_design_ref(
href, allow_missing_substitutions=False)
result = validation.check_design(config)
except exceptions.InvalidFormatError as e:
msg = "Invalid JSON Format: %s" % str(e)
result = {'msg': [msg], 'err_count': 1}
except exceptions.DeckhandException as e:
result = {'msg': [str(e)], 'err_count': 1}
return self._return_msg(resp, result)
except (exceptions.InvalidFormatError,
exceptions.DeckhandException) as e:
if isinstance(e, exceptions.InvalidFormatError):
msg = "Invalid JSON Format: %s" % str(e)
else:
msg = str(e)
result = ValidationMessage()
result.add_error_message(msg, name=e.title)
return result.get_output()

View File

View File

@ -0,0 +1,89 @@
# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import falcon
import json
class ValidationMessage(object):
""" ValidationMessage per UCP convention:
https://github.com/att-comdev/ucp-integration/blob/master/docs/source/api-conventions.rst#output-structure # noqa
Construction of ValidationMessage message:
:param string message: Validation failure message.
:param boolean error: True or False, if this is an error message.
:param string name: Identifying name of the validation.
:param string level: The severity of validation result, as "Error",
"Warning", or "Info"
:param string schema: The schema of the document being validated.
:param string doc_name: The name of the document being validated.
:param string diagnostic: Information about what lead to the message,
or details for resolution.
"""
def __init__(self):
self.error_count = 0
self.details = {'errorCount': 0, 'messageList': []}
self.output = {
'kind': 'Status',
'apiVersion': 'v1.0',
'metadata': {},
'reason': 'Validation',
'details': self.details,
}
def add_error_message(self,
msg,
name=None,
schema=None,
doc_name=None,
diagnostic=None):
new_error = {
'message': msg,
'error': True,
'name': name,
'documents': [],
'level': "Error",
'diagnostic': diagnostic,
'kind': 'ValidationMessage'
}
if schema and doc_name:
self.output['documents'].append(dict(schema=schema, name=doc_name))
self.details['errorCount'] += 1
self.details['messageList'].append(new_error)
def get_output(self, code=falcon.HTTP_400):
""" Return ValidationMessage message.
:returns: The ValidationMessage for the Validation API response.
:rtype: dict
"""
if self.details['errorCount'] != 0:
self.output['code'] = code
self.output['message'] = 'Promenade validations failed'
self.output['status'] = 'Failure'
else:
self.output['code'] = falcon.HTTP_200
self.output['message'] = 'Promenade validations succeeded'
self.output['status'] = 'Success'
return self.output
def get_output_json(self):
""" Return ValidationMessage message as JSON.
:returns: The ValidationMessage formatted in JSON, for logging.
:rtype: json
"""
return json.dumps(self.output, indent=2)

View File

@ -14,42 +14,41 @@
from promenade import exceptions
from promenade import logging
import copy
from promenade.utils.validation_message import ValidationMessage
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)
validation_msg = ValidationMessage()
for kind in kinds:
count = 0
for doc in config.documents:
schema = doc.get('schema', None)
if not schema:
result['msg'].append(
str(
exceptions.ValidationException(
'"schema" is a required document key.')))
result['err_count'] += 1
return result
msg = '"schema" is a required document key.'
validation_msg.add_error_message(
msg, name=exceptions.ValidationException(msg))
return validation_msg
name = schema.split('/')[1]
if name == kind:
count += 1
if count != 1:
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
validation_msg.add_error_message(
msg,
name=exceptions.ValidationException(msg),
schema=schema,
doc_name=kind)
return validation_msg
def check_schemas(documents, schemas=None):