Merge "Revert "Refactoring the exceptions lists""

This commit is contained in:
Jenkins 2015-04-07 02:04:47 +00:00 committed by Gerrit Code Review
commit 0fb9a982e7
9 changed files with 121 additions and 150 deletions

View File

@ -23,6 +23,12 @@ class LazySettings(LazyObject):
HORIZON_CONFIG = copy.copy(DEFAULT_CONFIG)
HORIZON_CONFIG.update(settings.HORIZON_CONFIG)
# Ensure we always have our exception configuration...
for exc_category in ['unauthorized', 'not_found', 'recoverable']:
if exc_category not in HORIZON_CONFIG['exceptions']:
default_exc_config = DEFAULT_CONFIG['exceptions'][exc_category]
HORIZON_CONFIG['exceptions'][exc_category] = default_exc_config
# Ensure our password validator always exists...
if 'regex' not in HORIZON_CONFIG['password_validator']:
default_pw_regex = DEFAULT_CONFIG['password_validator']['regex']

View File

@ -31,6 +31,11 @@ HORIZON_CONFIG = {
# URL for additional help with this site.
'help_url': None,
# Exception configuration.
'exceptions': {'unauthorized': [],
'not_found': [],
'recoverable': []},
# Password configuration.
'password_validator': {'regex': '.*',
'help_text': _("Password is not accepted")},

View File

@ -22,7 +22,6 @@ import sys
import six
from django.conf import settings
from django.core.management import color_style # noqa
from django.http import HttpRequest # noqa
from django.utils import encoding
@ -30,6 +29,7 @@ from django.utils.translation import ugettext_lazy as _
from django.views.debug import CLEANSED_SUBSTITUTE # noqa
from django.views.debug import SafeExceptionReporterFilter # noqa
from horizon.conf import HORIZON_CONFIG # noqa
from horizon import messages
LOG = logging.getLogger(__name__)
@ -202,6 +202,12 @@ class HandledException(HorizonException):
self.wrapped = wrapped
UNAUTHORIZED = tuple(HORIZON_CONFIG['exceptions']['unauthorized'])
NOT_FOUND = tuple(HORIZON_CONFIG['exceptions']['not_found'])
RECOVERABLE = (AlreadyExists, Conflict, NotAvailable, ServiceCatalogException)
RECOVERABLE += tuple(HORIZON_CONFIG['exceptions']['recoverable'])
def error_color(msg):
return color_style().ERROR_OUTPUT(msg)
@ -274,6 +280,13 @@ def handle_recoverable(request, message, redirect, ignore, escalate, handled,
return RecoverableError # return to normal code flow
HANDLE_EXC_METHODS = [
{'exc': UNAUTHORIZED, 'handler': handle_unauthorized, 'set_wrap': False},
{'exc': NOT_FOUND, 'handler': handle_notfound, 'set_wrap': True},
{'exc': RECOVERABLE, 'handler': handle_recoverable, 'set_wrap': True},
]
def handle(request, message=None, redirect=None, ignore=False,
escalate=False, log_level=None, force_log=None):
"""Centralized error handling for Horizon.
@ -303,19 +316,6 @@ def handle(request, message=None, redirect=None, ignore=False,
class indicating the type of exception that was encountered will be
returned.
"""
HORIZON_CONFIG = settings.HORIZON_CONFIG
UNAUTHORIZED = tuple(HORIZON_CONFIG['exceptions']['unauthorized'])
NOT_FOUND = tuple(HORIZON_CONFIG['exceptions']['not_found'])
RECOVERABLE = (AlreadyExists, Conflict, NotAvailable,
ServiceCatalogException)
RECOVERABLE += tuple(HORIZON_CONFIG['exceptions']['recoverable'])
HANDLE_EXC_METHODS = [
{'exc': UNAUTHORIZED, 'handler': handle_unauthorized,
'set_wrap': False},
{'exc': NOT_FOUND, 'handler': handle_notfound, 'set_wrap': True},
{'exc': RECOVERABLE, 'handler': handle_recoverable, 'set_wrap': True}
]
exc_type, exc_value, exc_traceback = sys.exc_info()
log_method = getattr(LOG, log_level or "exception")
force_log = force_log or os.environ.get("HORIZON_TEST_RUN", False)

View File

@ -20,17 +20,6 @@ import os
import socket
import sys
from cinderclient import exceptions as cinderclient
from glanceclient.common import exceptions as glanceclient
from heatclient import exc as heatclient
from keystoneclient import exceptions as keystoneclient
from neutronclient.common import exceptions as neutronclient
from novaclient import exceptions as novaclient
from requests import exceptions as requests
from saharaclient.api import base as saharaclient
from swiftclient import client as swiftclient
from troveclient import exceptions as troveclient
import django
from django.utils import html_parser
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
@ -146,37 +135,6 @@ HORIZON_CONFIG = {
},
'user_home': None,
'help_url': "http://example.com",
'exceptions': {'recoverable': (keystoneclient.ClientException,
keystoneclient.AuthorizationFailure,
keystoneclient.Forbidden,
cinderclient.ClientException,
cinderclient.ConnectionError,
cinderclient.Forbidden,
novaclient.ClientException,
novaclient.Forbidden,
glanceclient.ClientException,
neutronclient.Forbidden,
neutronclient.NeutronClientException,
swiftclient.ClientException,
heatclient.HTTPForbidden,
heatclient.HTTPException,
troveclient.ClientException,
saharaclient.APIException,
requests.RequestException),
'not_found': (keystoneclient.NotFound,
cinderclient.NotFound,
novaclient.NotFound,
glanceclient.NotFound,
neutronclient.NotFound,
heatclient.HTTPNotFound,
troveclient.NotFound),
'unauthorized': (keystoneclient.Unauthorized,
cinderclient.Unauthorized,
novaclient.Unauthorized,
glanceclient.Unauthorized,
neutronclient.Unauthorized,
heatclient.HTTPUnauthorized,
troveclient.Unauthorized)}
}
COMPRESS_ENABLED = True

View File

@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import functools
import itertools
import json
import logging
@ -22,6 +21,7 @@ from django.utils import decorators
from oslo_serialization import jsonutils
from horizon import exceptions
log = logging.getLogger(__name__)
@ -31,6 +31,9 @@ class AjaxError(Exception):
self.http_status = http_status
super(AjaxError, self).__init__(msg)
http_errors = exceptions.UNAUTHORIZED + exceptions.NOT_FOUND + \
exceptions.RECOVERABLE + (AjaxError, )
class CreatedResponse(http.HttpResponse):
def __init__(self, location, data=None):
@ -107,8 +110,6 @@ def ajax(authenticated=True, data_required=False):
return JSONResponse('request requires JSON body', 400)
# invoke the wrapped function, handling exceptions sanely
horizon_exc = settings.HORIZON_CONFIG['exceptions'].values()
api_exc = itertools.chain([AjaxError, ], *horizon_exc)
try:
data = function(self, request, *args, **kw)
if isinstance(data, http.HttpResponse):
@ -116,15 +117,18 @@ def ajax(authenticated=True, data_required=False):
elif data is None:
return JSONResponse('', status=204)
return JSONResponse(data)
except tuple(api_exc) as e:
except http_errors as e:
# exception was raised with a specific HTTP status
if hasattr(e, 'http_status'):
http_status = e.http_status
elif hasattr(e, 'code'):
http_status = e.code
else:
http_status = getattr(e, 'code', 500)
log.exception('API Error: %s', e)
log.exception('HTTP exception with no status/code')
return JSONResponse(str(e), 500)
return JSONResponse(str(e), http_status)
except Exception as e:
log.exception('Internal Error: %s', e)
log.exception('error invoking apiclient')
return JSONResponse(str(e), 500)
return _wrapped

View File

@ -0,0 +1,73 @@
# Copyright 2012 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Copyright 2012 Nebula, Inc.
#
# 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.
from cinderclient import exceptions as cinderclient
from glanceclient.common import exceptions as glanceclient
from heatclient import exc as heatclient
from keystoneclient import exceptions as keystoneclient
from neutronclient.common import exceptions as neutronclient
from novaclient import exceptions as novaclient
from requests import exceptions as requests
from saharaclient.api import base as saharaclient
from swiftclient import client as swiftclient
from troveclient import exceptions as troveclient
UNAUTHORIZED = (
keystoneclient.Unauthorized,
cinderclient.Unauthorized,
novaclient.Unauthorized,
glanceclient.Unauthorized,
neutronclient.Unauthorized,
heatclient.HTTPUnauthorized,
troveclient.Unauthorized,
)
NOT_FOUND = (
keystoneclient.NotFound,
cinderclient.NotFound,
novaclient.NotFound,
glanceclient.NotFound,
neutronclient.NotFound,
heatclient.HTTPNotFound,
troveclient.NotFound,
)
# NOTE(gabriel): This is very broad, and may need to be dialed in.
RECOVERABLE = (
keystoneclient.ClientException,
# AuthorizationFailure is raised when Keystone is "unavailable".
keystoneclient.AuthorizationFailure,
keystoneclient.Forbidden,
cinderclient.ClientException,
cinderclient.ConnectionError,
cinderclient.Forbidden,
novaclient.ClientException,
novaclient.Forbidden,
glanceclient.ClientException,
neutronclient.Forbidden,
neutronclient.NeutronClientException,
swiftclient.ClientException,
heatclient.HTTPForbidden,
heatclient.HTTPException,
troveclient.ClientException,
saharaclient.APIException,
requests.RequestException,
)

View File

@ -2,6 +2,7 @@ import os
from django.utils.translation import ugettext_lazy as _
from openstack_dashboard import exceptions
DEBUG = True
TEMPLATE_DEBUG = DEBUG
@ -73,9 +74,9 @@ HORIZON_CONFIG = {
'types': ['alert-success', 'alert-info']
},
'help_url': "http://docs.openstack.org",
'exceptions': {'recoverable': [],
'not_found': [],
'unauthorized': []},
'exceptions': {'recoverable': exceptions.RECOVERABLE,
'not_found': exceptions.NOT_FOUND,
'unauthorized': exceptions.UNAUTHORIZED},
'modal_backdrop': 'static',
'angular_modules': [],
'js_files': [],

View File

@ -21,20 +21,10 @@ import os
import sys
import warnings
from cinderclient import exceptions as cinderclient
from glanceclient.common import exceptions as glanceclient
from heatclient import exc as heatclient
from keystoneclient import exceptions as keystoneclient
from neutronclient.common import exceptions as neutronclient
from novaclient import exceptions as novaclient
from requests import exceptions as requests
from saharaclient.api import base as saharaclient
from swiftclient import client as swiftclient
from troveclient import exceptions as troveclient
import django
from django.utils.translation import ugettext_lazy as _
from openstack_dashboard import exceptions
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
@ -69,37 +59,9 @@ HORIZON_CONFIG = {
'types': ['alert-success', 'alert-info']
},
'help_url': "http://docs.openstack.org",
'exceptions': {'recoverable': (keystoneclient.ClientException,
keystoneclient.AuthorizationFailure,
keystoneclient.Forbidden,
cinderclient.ClientException,
cinderclient.ConnectionError,
cinderclient.Forbidden,
novaclient.ClientException,
novaclient.Forbidden,
glanceclient.ClientException,
neutronclient.Forbidden,
neutronclient.NeutronClientException,
swiftclient.ClientException,
heatclient.HTTPForbidden,
heatclient.HTTPException,
troveclient.ClientException,
saharaclient.APIException,
requests.RequestException),
'not_found': (keystoneclient.NotFound,
cinderclient.NotFound,
novaclient.NotFound,
glanceclient.NotFound,
neutronclient.NotFound,
heatclient.HTTPNotFound,
troveclient.NotFound),
'unauthorized': (keystoneclient.Unauthorized,
cinderclient.Unauthorized,
novaclient.Unauthorized,
glanceclient.Unauthorized,
neutronclient.Unauthorized,
heatclient.HTTPUnauthorized,
troveclient.Unauthorized)},
'exceptions': {'recoverable': exceptions.RECOVERABLE,
'not_found': exceptions.NOT_FOUND,
'unauthorized': exceptions.UNAUTHORIZED},
'angular_modules': [],
'js_files': [],
'js_spec_files': [],

View File

@ -12,19 +12,9 @@
import os
from cinderclient import exceptions as cinderclient
from glanceclient.common import exceptions as glanceclient
from heatclient import exc as heatclient
from keystoneclient import exceptions as keystoneclient
from neutronclient.common import exceptions as neutronclient
from novaclient import exceptions as novaclient
from requests import exceptions as requests
from saharaclient.api import base as saharaclient
from swiftclient import client as swiftclient
from troveclient import exceptions as troveclient
from horizon.test.settings import * # noqa
from horizon.utils import secret_key
from openstack_dashboard import exceptions
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
STATICFILES_DIRS = get_staticfiles_dirs()
@ -76,39 +66,11 @@ HORIZON_CONFIG = {
},
'user_home': None,
'help_url': "http://docs.openstack.org",
'exceptions': {'recoverable': exceptions.RECOVERABLE,
'not_found': exceptions.NOT_FOUND,
'unauthorized': exceptions.UNAUTHORIZED},
'angular_modules': [],
'js_files': [],
'exceptions': {'recoverable': (keystoneclient.ClientException,
keystoneclient.AuthorizationFailure,
keystoneclient.Forbidden,
cinderclient.ClientException,
cinderclient.ConnectionError,
cinderclient.Forbidden,
novaclient.ClientException,
novaclient.Forbidden,
glanceclient.ClientException,
neutronclient.Forbidden,
neutronclient.NeutronClientException,
swiftclient.ClientException,
heatclient.HTTPForbidden,
heatclient.HTTPException,
troveclient.ClientException,
saharaclient.APIException,
requests.RequestException),
'not_found': (keystoneclient.NotFound,
cinderclient.NotFound,
novaclient.NotFound,
glanceclient.NotFound,
neutronclient.NotFound,
heatclient.HTTPNotFound,
troveclient.NotFound),
'unauthorized': (keystoneclient.Unauthorized,
cinderclient.Unauthorized,
novaclient.Unauthorized,
glanceclient.Unauthorized,
neutronclient.Unauthorized,
heatclient.HTTPUnauthorized,
troveclient.Unauthorized)},
}
# Set to True to allow users to upload images to glance via Horizon server.