Improved keystone error handling in syspanel.
* Added "AuthorizationFailure" to the recoverable errors list since keystoneclient raises it anytime it can't talk to keystone. Fixes bug 971249. * Used proper exception handling for the users index view. Fixed some tests that had been failiing but masked previously. Fixes bug 971250. Change-Id: Iec8c1fc7bf8585a529fa15af55f807abc0f84d42
This commit is contained in:
parent
0bf1e5e953
commit
289fc72168
@ -45,7 +45,8 @@ class IndexView(tables.DataTableView):
|
|||||||
try:
|
try:
|
||||||
tenants = api.keystone.tenant_list(self.request, admin=True)
|
tenants = api.keystone.tenant_list(self.request, admin=True)
|
||||||
except:
|
except:
|
||||||
exceptions.handle(self.request)
|
exceptions.handle(self.request,
|
||||||
|
_("Unable to retrieve project list."))
|
||||||
tenants.sort(key=lambda x: x.id, reverse=True)
|
tenants.sort(key=lambda x: x.id, reverse=True)
|
||||||
return tenants
|
return tenants
|
||||||
|
|
||||||
@ -67,7 +68,7 @@ class UpdateView(forms.ModalFormView):
|
|||||||
except:
|
except:
|
||||||
redirect = reverse("horizon:syspanel:projects:index")
|
redirect = reverse("horizon:syspanel:projects:index")
|
||||||
exceptions.handle(self.request,
|
exceptions.handle(self.request,
|
||||||
_('Unable to retrieve tenant.'),
|
_('Unable to retrieve project.'),
|
||||||
redirect=redirect)
|
redirect=redirect)
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
|
@ -34,8 +34,8 @@ USER_UPDATE_URL = reverse('horizon:syspanel:users:update', args=[1])
|
|||||||
|
|
||||||
class UsersViewTests(test.BaseAdminViewTests):
|
class UsersViewTests(test.BaseAdminViewTests):
|
||||||
def test_index(self):
|
def test_index(self):
|
||||||
self.mox.StubOutWithMock(api, 'user_list')
|
self.mox.StubOutWithMock(api.keystone, 'user_list')
|
||||||
api.user_list(IgnoreArg()).AndReturn(self.users.list())
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
res = self.client.get(USERS_INDEX_URL)
|
res = self.client.get(USERS_INDEX_URL)
|
||||||
@ -176,6 +176,8 @@ class UsersViewTests(test.BaseAdminViewTests):
|
|||||||
def test_enable_user(self):
|
def test_enable_user(self):
|
||||||
user = self.users.get(id="2")
|
user = self.users.get(id="2")
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_update_enabled')
|
self.mox.StubOutWithMock(api.keystone, 'user_update_enabled')
|
||||||
|
self.mox.StubOutWithMock(api.keystone, 'user_list')
|
||||||
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
api.keystone.user_update_enabled(IgnoreArg(),
|
api.keystone.user_update_enabled(IgnoreArg(),
|
||||||
user.id,
|
user.id,
|
||||||
True).AndReturn(user)
|
True).AndReturn(user)
|
||||||
@ -183,11 +185,14 @@ class UsersViewTests(test.BaseAdminViewTests):
|
|||||||
|
|
||||||
formData = {'action': 'users__enable__%s' % user.id}
|
formData = {'action': 'users__enable__%s' % user.id}
|
||||||
res = self.client.post(USERS_INDEX_URL, formData)
|
res = self.client.post(USERS_INDEX_URL, formData)
|
||||||
self.assertRedirects(res, USERS_INDEX_URL)
|
self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
|
||||||
|
|
||||||
def test_disable_user(self):
|
def test_disable_user(self):
|
||||||
user = self.users.get(id="2")
|
user = self.users.get(id="2")
|
||||||
|
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_update_enabled')
|
self.mox.StubOutWithMock(api.keystone, 'user_update_enabled')
|
||||||
|
self.mox.StubOutWithMock(api.keystone, 'user_list')
|
||||||
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
api.keystone.user_update_enabled(IgnoreArg(),
|
api.keystone.user_update_enabled(IgnoreArg(),
|
||||||
user.id,
|
user.id,
|
||||||
False).AndReturn(user)
|
False).AndReturn(user)
|
||||||
@ -195,11 +200,13 @@ class UsersViewTests(test.BaseAdminViewTests):
|
|||||||
|
|
||||||
formData = {'action': 'users__disable__%s' % user.id}
|
formData = {'action': 'users__disable__%s' % user.id}
|
||||||
res = self.client.post(USERS_INDEX_URL, formData)
|
res = self.client.post(USERS_INDEX_URL, formData)
|
||||||
self.assertRedirects(res, USERS_INDEX_URL)
|
self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
|
||||||
|
|
||||||
def test_enable_disable_user_exception(self):
|
def test_enable_disable_user_exception(self):
|
||||||
user = self.users.get(id="2")
|
user = self.users.get(id="2")
|
||||||
self.mox.StubOutWithMock(api.keystone, 'user_update_enabled')
|
self.mox.StubOutWithMock(api.keystone, 'user_update_enabled')
|
||||||
|
self.mox.StubOutWithMock(api.keystone, 'user_list')
|
||||||
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
api_exception = keystone_exceptions.ClientException('apiException',
|
api_exception = keystone_exceptions.ClientException('apiException',
|
||||||
message='apiException')
|
message='apiException')
|
||||||
api.keystone.user_update_enabled(IgnoreArg(),
|
api.keystone.user_update_enabled(IgnoreArg(),
|
||||||
@ -210,15 +217,15 @@ class UsersViewTests(test.BaseAdminViewTests):
|
|||||||
formData = {'action': 'users__enable__%s' % user.id}
|
formData = {'action': 'users__enable__%s' % user.id}
|
||||||
res = self.client.post(USERS_INDEX_URL, formData)
|
res = self.client.post(USERS_INDEX_URL, formData)
|
||||||
|
|
||||||
self.assertRedirects(res, USERS_INDEX_URL)
|
self.assertRedirectsNoFollow(res, USERS_INDEX_URL)
|
||||||
|
|
||||||
def test_shoot_yourself_in_the_foot(self):
|
def test_shoot_yourself_in_the_foot(self):
|
||||||
self.mox.StubOutWithMock(api, 'user_list')
|
self.mox.StubOutWithMock(api.keystone, 'user_list')
|
||||||
# Four times... one for each post and one for each followed redirect
|
# Four times... one for each post and one for each followed redirect
|
||||||
api.user_list(IgnoreArg()).AndReturn(self.users.list())
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
api.user_list(IgnoreArg()).AndReturn(self.users.list())
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
api.user_list(IgnoreArg()).AndReturn(self.users.list())
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
api.user_list(IgnoreArg()).AndReturn(self.users.list())
|
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
|
@ -20,10 +20,8 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.contrib import messages
|
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from keystoneclient import exceptions as api_exceptions
|
|
||||||
|
|
||||||
from horizon import api
|
from horizon import api
|
||||||
from horizon import exceptions
|
from horizon import exceptions
|
||||||
@ -43,17 +41,10 @@ class IndexView(tables.DataTableView):
|
|||||||
def get_data(self):
|
def get_data(self):
|
||||||
users = []
|
users = []
|
||||||
try:
|
try:
|
||||||
users = api.user_list(self.request)
|
users = api.keystone.user_list(self.request)
|
||||||
except api_exceptions.AuthorizationFailure, e:
|
except:
|
||||||
LOG.exception("Unauthorized attempt to list users.")
|
exceptions.handle(self.request,
|
||||||
messages.error(self.request,
|
_('Unable to retrieve user list.'))
|
||||||
_('Unable to get user info: %s') % e.message)
|
|
||||||
except Exception, e:
|
|
||||||
LOG.exception('Exception while getting user list')
|
|
||||||
if not hasattr(e, 'message'):
|
|
||||||
e.message = str(e)
|
|
||||||
messages.error(self.request,
|
|
||||||
_('Unable to get user info: %s') % e.message)
|
|
||||||
return users
|
return users
|
||||||
|
|
||||||
|
|
||||||
|
@ -143,6 +143,8 @@ NOT_FOUND += tuple(EXCEPTION_CONFIG.get('not_found', []))
|
|||||||
|
|
||||||
# NOTE(gabriel): This is very broad, and may need to be dialed in.
|
# NOTE(gabriel): This is very broad, and may need to be dialed in.
|
||||||
RECOVERABLE = (keystoneclient.ClientException,
|
RECOVERABLE = (keystoneclient.ClientException,
|
||||||
|
# AuthorizationFailure is raised when Keystone is "unavailable".
|
||||||
|
keystoneclient.AuthorizationFailure,
|
||||||
novaclient.ClientException,
|
novaclient.ClientException,
|
||||||
glanceclient.GlanceException,
|
glanceclient.GlanceException,
|
||||||
swiftclient.Error,
|
swiftclient.Error,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user