Skip to content

Commit

Permalink
Improved keystone error handling in syspanel.
Browse files Browse the repository at this point in the history
  * 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
  • Loading branch information
gabrielhurley committed Apr 2, 2012
1 parent 0bf1e5e commit 289fc72
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 25 deletions.
5 changes: 3 additions & 2 deletions horizon/dashboards/syspanel/projects/views.py
Expand Up @@ -45,7 +45,8 @@ def get_data(self):
try:
tenants = api.keystone.tenant_list(self.request, admin=True)
except:
exceptions.handle(self.request)
exceptions.handle(self.request,
_("Unable to retrieve project list."))
tenants.sort(key=lambda x: x.id, reverse=True)
return tenants

Expand All @@ -67,7 +68,7 @@ def get_object(self, *args, **kwargs):
except:
redirect = reverse("horizon:syspanel:projects:index")
exceptions.handle(self.request,
_('Unable to retrieve tenant.'),
_('Unable to retrieve project.'),
redirect=redirect)

def get_initial(self):
Expand Down
27 changes: 17 additions & 10 deletions horizon/dashboards/syspanel/users/tests.py
Expand Up @@ -34,8 +34,8 @@

class UsersViewTests(test.BaseAdminViewTests):
def test_index(self):
self.mox.StubOutWithMock(api, 'user_list')
api.user_list(IgnoreArg()).AndReturn(self.users.list())
self.mox.StubOutWithMock(api.keystone, 'user_list')
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
self.mox.ReplayAll()

res = self.client.get(USERS_INDEX_URL)
Expand Down Expand Up @@ -176,30 +176,37 @@ def test_update_user_field_validation(self):
def test_enable_user(self):
user = self.users.get(id="2")
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(),
user.id,
True).AndReturn(user)
self.mox.ReplayAll()

formData = {'action': 'users__enable__%s' % user.id}
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):
user = self.users.get(id="2")

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(),
user.id,
False).AndReturn(user)
self.mox.ReplayAll()

formData = {'action': 'users__disable__%s' % user.id}
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):
user = self.users.get(id="2")
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',
message='apiException')
api.keystone.user_update_enabled(IgnoreArg(),
Expand All @@ -210,15 +217,15 @@ def test_enable_disable_user_exception(self):
formData = {'action': 'users__enable__%s' % user.id}
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):
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
api.user_list(IgnoreArg()).AndReturn(self.users.list())
api.user_list(IgnoreArg()).AndReturn(self.users.list())
api.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.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())
api.keystone.user_list(IgnoreArg()).AndReturn(self.users.list())

self.mox.ReplayAll()

Expand Down
17 changes: 4 additions & 13 deletions horizon/dashboards/syspanel/users/views.py
Expand Up @@ -20,10 +20,8 @@

import logging

from django.contrib import messages
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from keystoneclient import exceptions as api_exceptions

from horizon import api
from horizon import exceptions
Expand All @@ -43,17 +41,10 @@ class IndexView(tables.DataTableView):
def get_data(self):
users = []
try:
users = api.user_list(self.request)
except api_exceptions.AuthorizationFailure, e:
LOG.exception("Unauthorized attempt to list users.")
messages.error(self.request,
_('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)
users = api.keystone.user_list(self.request)
except:
exceptions.handle(self.request,
_('Unable to retrieve user list.'))
return users


Expand Down
2 changes: 2 additions & 0 deletions horizon/exceptions.py
Expand Up @@ -143,6 +143,8 @@ def __init__(self, wrapped):

# 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,
novaclient.ClientException,
glanceclient.GlanceException,
swiftclient.Error,
Expand Down

0 comments on commit 289fc72

Please sign in to comment.