Merge "Revert "Refactoring the exceptions lists""
This commit is contained in:
@@ -23,6 +23,12 @@ class LazySettings(LazyObject):
|
|||||||
HORIZON_CONFIG = copy.copy(DEFAULT_CONFIG)
|
HORIZON_CONFIG = copy.copy(DEFAULT_CONFIG)
|
||||||
HORIZON_CONFIG.update(settings.HORIZON_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...
|
# Ensure our password validator always exists...
|
||||||
if 'regex' not in HORIZON_CONFIG['password_validator']:
|
if 'regex' not in HORIZON_CONFIG['password_validator']:
|
||||||
default_pw_regex = DEFAULT_CONFIG['password_validator']['regex']
|
default_pw_regex = DEFAULT_CONFIG['password_validator']['regex']
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ HORIZON_CONFIG = {
|
|||||||
# URL for additional help with this site.
|
# URL for additional help with this site.
|
||||||
'help_url': None,
|
'help_url': None,
|
||||||
|
|
||||||
|
# Exception configuration.
|
||||||
|
'exceptions': {'unauthorized': [],
|
||||||
|
'not_found': [],
|
||||||
|
'recoverable': []},
|
||||||
|
|
||||||
# Password configuration.
|
# Password configuration.
|
||||||
'password_validator': {'regex': '.*',
|
'password_validator': {'regex': '.*',
|
||||||
'help_text': _("Password is not accepted")},
|
'help_text': _("Password is not accepted")},
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import sys
|
|||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core.management import color_style # noqa
|
from django.core.management import color_style # noqa
|
||||||
from django.http import HttpRequest # noqa
|
from django.http import HttpRequest # noqa
|
||||||
from django.utils import encoding
|
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 CLEANSED_SUBSTITUTE # noqa
|
||||||
from django.views.debug import SafeExceptionReporterFilter # noqa
|
from django.views.debug import SafeExceptionReporterFilter # noqa
|
||||||
|
|
||||||
|
from horizon.conf import HORIZON_CONFIG # noqa
|
||||||
from horizon import messages
|
from horizon import messages
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@@ -202,6 +202,12 @@ class HandledException(HorizonException):
|
|||||||
self.wrapped = wrapped
|
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):
|
def error_color(msg):
|
||||||
return color_style().ERROR_OUTPUT(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
|
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,
|
def handle(request, message=None, redirect=None, ignore=False,
|
||||||
escalate=False, log_level=None, force_log=None):
|
escalate=False, log_level=None, force_log=None):
|
||||||
"""Centralized error handling for Horizon.
|
"""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
|
class indicating the type of exception that was encountered will be
|
||||||
returned.
|
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()
|
exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||||
log_method = getattr(LOG, log_level or "exception")
|
log_method = getattr(LOG, log_level or "exception")
|
||||||
force_log = force_log or os.environ.get("HORIZON_TEST_RUN", False)
|
force_log = force_log or os.environ.get("HORIZON_TEST_RUN", False)
|
||||||
|
|||||||
@@ -20,17 +20,6 @@ import os
|
|||||||
import socket
|
import socket
|
||||||
import sys
|
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
|
import django
|
||||||
from django.utils import html_parser
|
from django.utils import html_parser
|
||||||
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
|
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
|
||||||
@@ -146,37 +135,6 @@ HORIZON_CONFIG = {
|
|||||||
},
|
},
|
||||||
'user_home': None,
|
'user_home': None,
|
||||||
'help_url': "http://example.com",
|
'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
|
COMPRESS_ENABLED = True
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
import functools
|
import functools
|
||||||
import itertools
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -22,6 +21,7 @@ from django.utils import decorators
|
|||||||
|
|
||||||
from oslo_serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
|
|
||||||
|
from horizon import exceptions
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -31,6 +31,9 @@ class AjaxError(Exception):
|
|||||||
self.http_status = http_status
|
self.http_status = http_status
|
||||||
super(AjaxError, self).__init__(msg)
|
super(AjaxError, self).__init__(msg)
|
||||||
|
|
||||||
|
http_errors = exceptions.UNAUTHORIZED + exceptions.NOT_FOUND + \
|
||||||
|
exceptions.RECOVERABLE + (AjaxError, )
|
||||||
|
|
||||||
|
|
||||||
class CreatedResponse(http.HttpResponse):
|
class CreatedResponse(http.HttpResponse):
|
||||||
def __init__(self, location, data=None):
|
def __init__(self, location, data=None):
|
||||||
@@ -107,8 +110,6 @@ def ajax(authenticated=True, data_required=False):
|
|||||||
return JSONResponse('request requires JSON body', 400)
|
return JSONResponse('request requires JSON body', 400)
|
||||||
|
|
||||||
# invoke the wrapped function, handling exceptions sanely
|
# invoke the wrapped function, handling exceptions sanely
|
||||||
horizon_exc = settings.HORIZON_CONFIG['exceptions'].values()
|
|
||||||
api_exc = itertools.chain([AjaxError, ], *horizon_exc)
|
|
||||||
try:
|
try:
|
||||||
data = function(self, request, *args, **kw)
|
data = function(self, request, *args, **kw)
|
||||||
if isinstance(data, http.HttpResponse):
|
if isinstance(data, http.HttpResponse):
|
||||||
@@ -116,15 +117,18 @@ def ajax(authenticated=True, data_required=False):
|
|||||||
elif data is None:
|
elif data is None:
|
||||||
return JSONResponse('', status=204)
|
return JSONResponse('', status=204)
|
||||||
return JSONResponse(data)
|
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'):
|
if hasattr(e, 'http_status'):
|
||||||
http_status = e.http_status
|
http_status = e.http_status
|
||||||
|
elif hasattr(e, 'code'):
|
||||||
|
http_status = e.code
|
||||||
else:
|
else:
|
||||||
http_status = getattr(e, 'code', 500)
|
log.exception('HTTP exception with no status/code')
|
||||||
log.exception('API Error: %s', e)
|
return JSONResponse(str(e), 500)
|
||||||
return JSONResponse(str(e), http_status)
|
return JSONResponse(str(e), http_status)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log.exception('Internal Error: %s', e)
|
log.exception('error invoking apiclient')
|
||||||
return JSONResponse(str(e), 500)
|
return JSONResponse(str(e), 500)
|
||||||
|
|
||||||
return _wrapped
|
return _wrapped
|
||||||
|
|||||||
73
openstack_dashboard/exceptions.py
Normal file
73
openstack_dashboard/exceptions.py
Normal 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,
|
||||||
|
)
|
||||||
@@ -2,6 +2,7 @@ import os
|
|||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from openstack_dashboard import exceptions
|
||||||
|
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
TEMPLATE_DEBUG = DEBUG
|
TEMPLATE_DEBUG = DEBUG
|
||||||
@@ -73,9 +74,9 @@ HORIZON_CONFIG = {
|
|||||||
'types': ['alert-success', 'alert-info']
|
'types': ['alert-success', 'alert-info']
|
||||||
},
|
},
|
||||||
'help_url': "http://docs.openstack.org",
|
'help_url': "http://docs.openstack.org",
|
||||||
'exceptions': {'recoverable': [],
|
'exceptions': {'recoverable': exceptions.RECOVERABLE,
|
||||||
'not_found': [],
|
'not_found': exceptions.NOT_FOUND,
|
||||||
'unauthorized': []},
|
'unauthorized': exceptions.UNAUTHORIZED},
|
||||||
'modal_backdrop': 'static',
|
'modal_backdrop': 'static',
|
||||||
'angular_modules': [],
|
'angular_modules': [],
|
||||||
'js_files': [],
|
'js_files': [],
|
||||||
|
|||||||
@@ -21,20 +21,10 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import warnings
|
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
|
import django
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from openstack_dashboard import exceptions
|
||||||
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
|
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
|
||||||
|
|
||||||
|
|
||||||
@@ -69,37 +59,9 @@ HORIZON_CONFIG = {
|
|||||||
'types': ['alert-success', 'alert-info']
|
'types': ['alert-success', 'alert-info']
|
||||||
},
|
},
|
||||||
'help_url': "http://docs.openstack.org",
|
'help_url': "http://docs.openstack.org",
|
||||||
'exceptions': {'recoverable': (keystoneclient.ClientException,
|
'exceptions': {'recoverable': exceptions.RECOVERABLE,
|
||||||
keystoneclient.AuthorizationFailure,
|
'not_found': exceptions.NOT_FOUND,
|
||||||
keystoneclient.Forbidden,
|
'unauthorized': exceptions.UNAUTHORIZED},
|
||||||
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)},
|
|
||||||
'angular_modules': [],
|
'angular_modules': [],
|
||||||
'js_files': [],
|
'js_files': [],
|
||||||
'js_spec_files': [],
|
'js_spec_files': [],
|
||||||
|
|||||||
@@ -12,19 +12,9 @@
|
|||||||
|
|
||||||
import os
|
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.test.settings import * # noqa
|
||||||
from horizon.utils import secret_key
|
from horizon.utils import secret_key
|
||||||
|
from openstack_dashboard import exceptions
|
||||||
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
|
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
|
||||||
|
|
||||||
STATICFILES_DIRS = get_staticfiles_dirs()
|
STATICFILES_DIRS = get_staticfiles_dirs()
|
||||||
@@ -76,39 +66,11 @@ HORIZON_CONFIG = {
|
|||||||
},
|
},
|
||||||
'user_home': None,
|
'user_home': None,
|
||||||
'help_url': "http://docs.openstack.org",
|
'help_url': "http://docs.openstack.org",
|
||||||
|
'exceptions': {'recoverable': exceptions.RECOVERABLE,
|
||||||
|
'not_found': exceptions.NOT_FOUND,
|
||||||
|
'unauthorized': exceptions.UNAUTHORIZED},
|
||||||
'angular_modules': [],
|
'angular_modules': [],
|
||||||
'js_files': [],
|
'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.
|
# Set to True to allow users to upload images to glance via Horizon server.
|
||||||
|
|||||||
Reference in New Issue
Block a user