Update validatedesign message
Update validatedesign failure message to return more detailed error message. Change-Id: I56f11ecd3030532d90b421dce5d8959b28d40cbb
This commit is contained in:
parent
ec912fde36
commit
2cd353da21
@ -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()
|
||||
|
0
promenade/utils/__init__.py
Normal file
0
promenade/utils/__init__.py
Normal file
89
promenade/utils/validation_message.py
Normal file
89
promenade/utils/validation_message.py
Normal 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)
|
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user