Merge "Added ValidationErrorMiddleware"
This commit is contained in:
commit
82fae73bcd
@ -26,6 +26,7 @@ from oslo_utils import strutils
|
||||
from designate import exceptions
|
||||
from designate import notifications
|
||||
from designate import context
|
||||
from designate import objects
|
||||
from designate.i18n import _LI
|
||||
from designate.i18n import _LW
|
||||
from designate.i18n import _LE
|
||||
@ -268,3 +269,66 @@ class FaultWrapperMiddleware(base.Middleware):
|
||||
|
||||
return flask.Response(status=status, headers=headers,
|
||||
response=json.dumps(response))
|
||||
|
||||
|
||||
class ValidationErrorMiddleware(base.Middleware):
|
||||
|
||||
def __init__(self, application):
|
||||
super(ValidationErrorMiddleware, self).__init__(application)
|
||||
|
||||
LOG.info(_LI('Starting designate validation middleware'))
|
||||
|
||||
@webob.dec.wsgify
|
||||
def __call__(self, request):
|
||||
try:
|
||||
return request.get_response(self.application)
|
||||
except exceptions.InvalidObject as e:
|
||||
# Allow current views validation to pass through to FaultWapper
|
||||
if not isinstance(e.errors, objects.ValidationErrorList):
|
||||
raise
|
||||
return self._handle_errors(request, e)
|
||||
|
||||
def _handle_errors(self, request, exception):
|
||||
|
||||
response = {}
|
||||
|
||||
headers = [
|
||||
('Content-Type', 'application/json'),
|
||||
]
|
||||
|
||||
url = getattr(request, 'url', None)
|
||||
|
||||
response['code'] = exception.error_code
|
||||
|
||||
response['type'] = exception.error_type or 'unknown'
|
||||
|
||||
response['errors'] = list()
|
||||
|
||||
for error in exception.errors:
|
||||
response['errors'].append(error.to_dict())
|
||||
|
||||
# Return the new response
|
||||
if 'context' in request.environ:
|
||||
response['request_id'] = request.environ['context'].request_id
|
||||
|
||||
notifications.send_api_fault(request.environ['context'], url,
|
||||
response['code'], exception)
|
||||
else:
|
||||
# TODO(ekarlso): Remove after verifying that there's actually a
|
||||
# context always set
|
||||
LOG.error(_LE('Missing context in request, please check.'))
|
||||
|
||||
return flask.Response(status=exception.error_code, headers=headers,
|
||||
response=json.dumps(response))
|
||||
|
||||
|
||||
class APIv1ValidationErrorMiddleware(ValidationErrorMiddleware):
|
||||
def __init__(self, application):
|
||||
super(APIv1ValidationErrorMiddleware, self).__init__(application)
|
||||
self.api_version = 'API_v1'
|
||||
|
||||
|
||||
class APIv2ValidationErrorMiddleware(ValidationErrorMiddleware):
|
||||
def __init__(self, application):
|
||||
super(APIv2ValidationErrorMiddleware, self).__init__(application)
|
||||
self.api_version = 'API_v2'
|
||||
|
@ -30,8 +30,8 @@ class ValidationError(base.DesignateObject):
|
||||
"""
|
||||
|
||||
e = cls()
|
||||
e.relative_path = ".".join([str(x) for x in js_error.relative_path])
|
||||
e.absolute_path = ".".join([str(x) for x in js_error.absolute_path])
|
||||
e.relative_path = js_error.relative_path
|
||||
e.absolute_path = js_error.absolute_path
|
||||
e.message = js_error.message
|
||||
e.validator = js_error.validator
|
||||
e.validator_value = js_error.validator_value
|
||||
|
@ -42,6 +42,10 @@ class ApiV1Test(ApiTestCase):
|
||||
self.app.wsgi_app = middleware.FaultWrapperMiddleware(
|
||||
self.app.wsgi_app)
|
||||
|
||||
# Inject the ValidationError middleware
|
||||
self.app.wsgi_app = middleware.APIv1ValidationErrorMiddleware(
|
||||
self.app.wsgi_app)
|
||||
|
||||
# Inject the TestAuth middleware
|
||||
self.app.wsgi_app = middleware.TestContextMiddleware(
|
||||
self.app.wsgi_app, self.admin_context.tenant,
|
||||
|
@ -49,6 +49,9 @@ class ApiV2TestCase(ApiTestCase):
|
||||
# Inject the FaultWrapper middleware
|
||||
self.app = middleware.FaultWrapperMiddleware(self.app)
|
||||
|
||||
# Inject the ValidationError middleware
|
||||
self.app = middleware.APIv2ValidationErrorMiddleware(self.app)
|
||||
|
||||
# Inject the TestContext middleware
|
||||
self.app = middleware.TestContextMiddleware(
|
||||
self.app, self.admin_context.tenant,
|
||||
|
@ -381,8 +381,9 @@ class DesignateObjectTest(tests.TestCase):
|
||||
self.assertEqual('format', error.validator)
|
||||
|
||||
# Ensure the nested ID field has triggered the failure.
|
||||
self.assertEqual('nested.id', error.absolute_path)
|
||||
self.assertEqual('nested.id', error.relative_path)
|
||||
# For some reason testtools turns lists into deques :/
|
||||
self.assertEqual(list(error.absolute_path), ['nested', 'id'])
|
||||
self.assertEqual(list(error.relative_path), ['nested', 'id'])
|
||||
|
||||
# Set the Nested ID field to a valid value
|
||||
obj.nested.id = 'ffded5c4-e4f6-4e02-a175-48e13c5c12a0'
|
||||
|
@ -9,16 +9,16 @@ paste.app_factory = designate.api.versions:factory
|
||||
|
||||
[composite:osapi_dns_v1]
|
||||
use = call:designate.api.middleware:auth_pipeline_factory
|
||||
noauth = request_id noauthcontext maintenance faultwrapper normalizeuri osapi_dns_app_v1
|
||||
keystone = request_id authtoken keystonecontext maintenance faultwrapper normalizeuri osapi_dns_app_v1
|
||||
noauth = request_id noauthcontext maintenance validation_API_v1 faultwrapper normalizeuri osapi_dns_app_v1
|
||||
keystone = request_id authtoken keystonecontext maintenance validation_API_v1 faultwrapper normalizeuri osapi_dns_app_v1
|
||||
|
||||
[app:osapi_dns_app_v1]
|
||||
paste.app_factory = designate.api.v1:factory
|
||||
|
||||
[composite:osapi_dns_v2]
|
||||
use = call:designate.api.middleware:auth_pipeline_factory
|
||||
noauth = request_id faultwrapper noauthcontext maintenance normalizeuri osapi_dns_app_v2
|
||||
keystone = request_id faultwrapper authtoken keystonecontext maintenance normalizeuri osapi_dns_app_v2
|
||||
noauth = request_id faultwrapper validation_API_v2 noauthcontext maintenance normalizeuri osapi_dns_app_v2
|
||||
keystone = request_id faultwrapper validation_API_v2 authtoken keystonecontext maintenance normalizeuri osapi_dns_app_v2
|
||||
|
||||
[app:osapi_dns_app_v2]
|
||||
paste.app_factory = designate.api.v2:factory
|
||||
@ -43,3 +43,9 @@ paste.filter_factory = designate.api.middleware:NormalizeURIMiddleware.factory
|
||||
|
||||
[filter:faultwrapper]
|
||||
paste.filter_factory = designate.api.middleware:FaultWrapperMiddleware.factory
|
||||
|
||||
[filter:validation_API_v1]
|
||||
paste.filter_factory = designate.api.middleware:APIv1ValidationErrorMiddleware.factory
|
||||
|
||||
[filter:validation_API_v2]
|
||||
paste.filter_factory = designate.api.middleware:APIv2ValidationErrorMiddleware.factory
|
||||
|
Loading…
Reference in New Issue
Block a user