Add keystone exceptions wrapper for openstack clients
* Added decorator which wraps keystone exceptions * Added unit tests with no auth_token and with heat client cached Change-Id: If42efe5f6806b12e7aabfd943150917a0b8f7618
This commit is contained in:
@@ -16,6 +16,7 @@ from heatclient import client as heatclient
|
||||
from keystoneclient.v2_0 import client as ksclient
|
||||
from oslo.config import cfg
|
||||
|
||||
from solum.common import exception
|
||||
from solum.openstack.common.gettextutils import _
|
||||
from solum.openstack.common import log as logging
|
||||
|
||||
@@ -77,6 +78,7 @@ class OpenStackClients(object):
|
||||
def _get_client_option(self, client, option):
|
||||
return getattr(getattr(cfg.CONF, '%s_client' % client), option)
|
||||
|
||||
@exception.wrap_keystone_exception
|
||||
def heat(self):
|
||||
if self._heat:
|
||||
return self._heat
|
||||
|
||||
@@ -20,8 +20,10 @@ Includes decorator for re-raising Solum-type exceptions.
|
||||
|
||||
import functools
|
||||
import pecan
|
||||
import sys
|
||||
import wsme
|
||||
|
||||
from keystoneclient import exceptions as keystone_exceptions
|
||||
from oslo.config import cfg
|
||||
import six
|
||||
|
||||
@@ -30,6 +32,7 @@ from solum.openstack.common import excutils
|
||||
from solum.openstack.common.gettextutils import _
|
||||
from solum.openstack.common import log as logging
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
exc_log_opts = [
|
||||
@@ -96,6 +99,25 @@ def wrap_controller_exception(func):
|
||||
return wrapped
|
||||
|
||||
|
||||
def wrap_keystone_exception(func):
|
||||
"""This decorator wraps keystone exception by throwing Solum specific
|
||||
exceptions.
|
||||
"""
|
||||
@functools.wraps(func)
|
||||
def wrapped(*args, **kw):
|
||||
try:
|
||||
return func(*args, **kw)
|
||||
except keystone_exceptions.AuthorizationFailure:
|
||||
raise AuthorizationFailure(
|
||||
client=func.__name__, message="reason: %s" % sys.exc_info()[1])
|
||||
except keystone_exceptions.ClientException:
|
||||
raise AuthorizationFailure(
|
||||
client=func.__name__,
|
||||
message="unexpected keystone client error occurred: %s"
|
||||
% sys.exc_info()[1])
|
||||
return wrapped
|
||||
|
||||
|
||||
class SolumException(Exception):
|
||||
"""Base Solum Exception
|
||||
|
||||
@@ -152,3 +174,7 @@ class ResourceExists(SolumException):
|
||||
class NotImplemented(SolumException):
|
||||
msg_fmt = _("The requested operation is not implemented.")
|
||||
code = 501
|
||||
|
||||
|
||||
class AuthorizationFailure(SolumException):
|
||||
msg_fmt = _("%(client)s connection failed. %(message)s")
|
||||
|
||||
@@ -14,6 +14,7 @@ import mock
|
||||
|
||||
from heatclient import client as heatclient
|
||||
from solum.common import clients
|
||||
from solum.common import exception
|
||||
from solum.tests import base
|
||||
|
||||
|
||||
@@ -37,3 +38,31 @@ class ClientsTest(base.BaseTestCase):
|
||||
cert_file=None, token='3bcc3d3a03f44e3d8377f9247b0ad155',
|
||||
auth_url='keystone_url', ca_file=None, key_file=None,
|
||||
password=None, insecure=False)
|
||||
|
||||
def test_clients_heat_noauth(self):
|
||||
con = mock.MagicMock()
|
||||
con.auth_token = None
|
||||
con.tenant = "b363706f891f48019483f8bd6503c54b"
|
||||
auth_url = mock.PropertyMock(name="auth_url",
|
||||
return_value="keystone_url")
|
||||
type(con).auth_url = auth_url
|
||||
con.get_url_for = mock.Mock(name="get_url_for")
|
||||
con.get_url_for.return_value = "url_from_keystone"
|
||||
obj = clients.OpenStackClients(con)
|
||||
obj._heat = None
|
||||
self.assertRaises(exception.AuthorizationFailure, obj.heat)
|
||||
|
||||
def test_clients_heat_cached(self):
|
||||
con = mock.MagicMock()
|
||||
con.tenant = "b363706f891f48019483f8bd6503c54b"
|
||||
con.auth_token = "3bcc3d3a03f44e3d8377f9247b0ad155"
|
||||
auth_url = mock.PropertyMock(name="auth_url",
|
||||
return_value="keystone_url")
|
||||
type(con).auth_url = auth_url
|
||||
con.get_url_for = mock.Mock(name="get_url_for")
|
||||
con.get_url_for.return_value = "url_from_keystone"
|
||||
obj = clients.OpenStackClients(con)
|
||||
obj._heat = None
|
||||
heat = obj.heat()
|
||||
heat_cached = obj.heat()
|
||||
self.assertEqual(heat, heat_cached)
|
||||
|
||||
Reference in New Issue
Block a user