Merge "Use generic wrapper for cinder exceptions"
This commit is contained in:
commit
f4dd117a81
@ -14,6 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from cinderclient import exceptions as cinder_exception
|
from cinderclient import exceptions as cinder_exception
|
||||||
|
from keystoneclient import exceptions as keystone_exception
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from nova import context
|
from nova import context
|
||||||
@ -439,3 +440,43 @@ class CinderApiTestCase(test.NoDBTestCase):
|
|||||||
self.api.get_volume_encryption_metadata(self.ctx,
|
self.api.get_volume_encryption_metadata(self.ctx,
|
||||||
{'encryption_key_id':
|
{'encryption_key_id':
|
||||||
'fake_key'})
|
'fake_key'})
|
||||||
|
|
||||||
|
def test_translate_cinder_exception_no_error(self):
|
||||||
|
my_func = mock.Mock()
|
||||||
|
my_func.__name__ = 'my_func'
|
||||||
|
my_func.return_value = 'foo'
|
||||||
|
|
||||||
|
res = cinder.translate_cinder_exception(my_func)('fizzbuzz',
|
||||||
|
'bar', 'baz')
|
||||||
|
|
||||||
|
self.assertEqual('foo', res)
|
||||||
|
my_func.assert_called_once_with('fizzbuzz', 'bar', 'baz')
|
||||||
|
|
||||||
|
def test_translate_cinder_exception_cinder_connection_error(self):
|
||||||
|
self._do_translate_cinder_exception_test(
|
||||||
|
cinder_exception.ConnectionError,
|
||||||
|
exception.CinderConnectionFailed)
|
||||||
|
|
||||||
|
def test_translate_cinder_exception_keystone_connection_error(self):
|
||||||
|
self._do_translate_cinder_exception_test(
|
||||||
|
keystone_exception.ConnectionError,
|
||||||
|
exception.CinderConnectionFailed)
|
||||||
|
|
||||||
|
def test_translate_cinder_exception_cinder_bad_request(self):
|
||||||
|
self._do_translate_cinder_exception_test(
|
||||||
|
cinder_exception.BadRequest(''),
|
||||||
|
exception.InvalidInput)
|
||||||
|
|
||||||
|
def test_translate_cinder_exception_keystone_bad_request(self):
|
||||||
|
self._do_translate_cinder_exception_test(
|
||||||
|
keystone_exception.BadRequest,
|
||||||
|
exception.InvalidInput)
|
||||||
|
|
||||||
|
def _do_translate_cinder_exception_test(self, raised_exc, expected_exc):
|
||||||
|
my_func = mock.Mock()
|
||||||
|
my_func.__name__ = 'my_func'
|
||||||
|
my_func.side_effect = raised_exc
|
||||||
|
|
||||||
|
self.assertRaises(expected_exc,
|
||||||
|
cinder.translate_cinder_exception(my_func),
|
||||||
|
'foo', 'bar', 'baz')
|
||||||
|
@ -20,6 +20,7 @@ Handles all requests relating to volumes + cinder.
|
|||||||
|
|
||||||
import collections
|
import collections
|
||||||
import copy
|
import copy
|
||||||
|
import functools
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from cinderclient import client as cinder_client
|
from cinderclient import client as cinder_client
|
||||||
@ -223,6 +224,28 @@ def _untranslate_snapshot_summary_view(context, snapshot):
|
|||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
def translate_cinder_exception(method):
|
||||||
|
"""Transforms a cinder exception but keeps its traceback intact."""
|
||||||
|
@functools.wraps(method)
|
||||||
|
def wrapper(self, ctx, *args, **kwargs):
|
||||||
|
try:
|
||||||
|
res = method(self, ctx, *args, **kwargs)
|
||||||
|
except (cinder_exception.ConnectionError,
|
||||||
|
keystone_exception.ConnectionError):
|
||||||
|
exc_type, exc_value, exc_trace = sys.exc_info()
|
||||||
|
exc_value = exception.CinderConnectionFailed(
|
||||||
|
reason=six.text_type(exc_value))
|
||||||
|
six.reraise(exc_value, None, exc_trace)
|
||||||
|
except (keystone_exception.BadRequest,
|
||||||
|
cinder_exception.BadRequest):
|
||||||
|
exc_type, exc_value, exc_trace = sys.exc_info()
|
||||||
|
exc_value = exception.InvalidInput(
|
||||||
|
reason=six.text_type(exc_value))
|
||||||
|
six.reraise(exc_value, None, exc_trace)
|
||||||
|
return res
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def translate_volume_exception(method):
|
def translate_volume_exception(method):
|
||||||
"""Transforms the exception for the volume but keeps its traceback intact.
|
"""Transforms the exception for the volume but keeps its traceback intact.
|
||||||
"""
|
"""
|
||||||
@ -235,19 +258,9 @@ def translate_volume_exception(method):
|
|||||||
if isinstance(exc_value, (keystone_exception.NotFound,
|
if isinstance(exc_value, (keystone_exception.NotFound,
|
||||||
cinder_exception.NotFound)):
|
cinder_exception.NotFound)):
|
||||||
exc_value = exception.VolumeNotFound(volume_id=volume_id)
|
exc_value = exception.VolumeNotFound(volume_id=volume_id)
|
||||||
elif isinstance(exc_value, (keystone_exception.BadRequest,
|
|
||||||
cinder_exception.BadRequest)):
|
|
||||||
exc_value = exception.InvalidInput(
|
|
||||||
reason=six.text_type(exc_value))
|
|
||||||
six.reraise(exc_value, None, exc_trace)
|
|
||||||
except (cinder_exception.ConnectionError,
|
|
||||||
keystone_exception.ConnectionError):
|
|
||||||
exc_type, exc_value, exc_trace = sys.exc_info()
|
|
||||||
exc_value = exception.CinderConnectionFailed(
|
|
||||||
reason=six.text_type(exc_value))
|
|
||||||
six.reraise(exc_value, None, exc_trace)
|
six.reraise(exc_value, None, exc_trace)
|
||||||
return res
|
return res
|
||||||
return wrapper
|
return translate_cinder_exception(wrapper)
|
||||||
|
|
||||||
|
|
||||||
def translate_snapshot_exception(method):
|
def translate_snapshot_exception(method):
|
||||||
@ -264,14 +277,8 @@ def translate_snapshot_exception(method):
|
|||||||
cinder_exception.NotFound)):
|
cinder_exception.NotFound)):
|
||||||
exc_value = exception.SnapshotNotFound(snapshot_id=snapshot_id)
|
exc_value = exception.SnapshotNotFound(snapshot_id=snapshot_id)
|
||||||
six.reraise(exc_value, None, exc_trace)
|
six.reraise(exc_value, None, exc_trace)
|
||||||
except (cinder_exception.ConnectionError,
|
|
||||||
keystone_exception.ConnectionError):
|
|
||||||
exc_type, exc_value, exc_trace = sys.exc_info()
|
|
||||||
reason = six.text_type(exc_value)
|
|
||||||
exc_value = exception.CinderConnectionFailed(reason=reason)
|
|
||||||
six.reraise(exc_value, None, exc_trace)
|
|
||||||
return res
|
return res
|
||||||
return wrapper
|
return translate_cinder_exception(wrapper)
|
||||||
|
|
||||||
|
|
||||||
class API(object):
|
class API(object):
|
||||||
@ -282,6 +289,7 @@ class API(object):
|
|||||||
item = cinderclient(context).volumes.get(volume_id)
|
item = cinderclient(context).volumes.get(volume_id)
|
||||||
return _untranslate_volume_summary_view(context, item)
|
return _untranslate_volume_summary_view(context, item)
|
||||||
|
|
||||||
|
@translate_cinder_exception
|
||||||
def get_all(self, context, search_opts=None):
|
def get_all(self, context, search_opts=None):
|
||||||
search_opts = search_opts or {}
|
search_opts = search_opts or {}
|
||||||
items = cinderclient(context).volumes.list(detailed=True,
|
items = cinderclient(context).volumes.list(detailed=True,
|
||||||
@ -428,11 +436,13 @@ class API(object):
|
|||||||
return cinderclient(context).volumes.terminate_connection(volume_id,
|
return cinderclient(context).volumes.terminate_connection(volume_id,
|
||||||
connector)
|
connector)
|
||||||
|
|
||||||
|
@translate_cinder_exception
|
||||||
def migrate_volume_completion(self, context, old_volume_id, new_volume_id,
|
def migrate_volume_completion(self, context, old_volume_id, new_volume_id,
|
||||||
error=False):
|
error=False):
|
||||||
return cinderclient(context).volumes.migrate_volume_completion(
|
return cinderclient(context).volumes.migrate_volume_completion(
|
||||||
old_volume_id, new_volume_id, error)
|
old_volume_id, new_volume_id, error)
|
||||||
|
|
||||||
|
@translate_cinder_exception
|
||||||
def create(self, context, size, name, description, snapshot=None,
|
def create(self, context, size, name, description, snapshot=None,
|
||||||
image_id=None, volume_type=None, metadata=None,
|
image_id=None, volume_type=None, metadata=None,
|
||||||
availability_zone=None):
|
availability_zone=None):
|
||||||
@ -463,9 +473,6 @@ class API(object):
|
|||||||
return _untranslate_volume_summary_view(context, item)
|
return _untranslate_volume_summary_view(context, item)
|
||||||
except cinder_exception.OverLimit:
|
except cinder_exception.OverLimit:
|
||||||
raise exception.OverQuota(overs='volumes')
|
raise exception.OverQuota(overs='volumes')
|
||||||
except (cinder_exception.BadRequest,
|
|
||||||
keystone_exception.BadRequest) as e:
|
|
||||||
raise exception.InvalidInput(reason=e)
|
|
||||||
|
|
||||||
@translate_volume_exception
|
@translate_volume_exception
|
||||||
def delete(self, context, volume_id):
|
def delete(self, context, volume_id):
|
||||||
@ -480,6 +487,7 @@ class API(object):
|
|||||||
item = cinderclient(context).volume_snapshots.get(snapshot_id)
|
item = cinderclient(context).volume_snapshots.get(snapshot_id)
|
||||||
return _untranslate_snapshot_summary_view(context, item)
|
return _untranslate_snapshot_summary_view(context, item)
|
||||||
|
|
||||||
|
@translate_cinder_exception
|
||||||
def get_all_snapshots(self, context):
|
def get_all_snapshots(self, context):
|
||||||
items = cinderclient(context).volume_snapshots.list(detailed=True)
|
items = cinderclient(context).volume_snapshots.list(detailed=True)
|
||||||
rvals = []
|
rvals = []
|
||||||
@ -510,6 +518,7 @@ class API(object):
|
|||||||
def delete_snapshot(self, context, snapshot_id):
|
def delete_snapshot(self, context, snapshot_id):
|
||||||
cinderclient(context).volume_snapshots.delete(snapshot_id)
|
cinderclient(context).volume_snapshots.delete(snapshot_id)
|
||||||
|
|
||||||
|
@translate_cinder_exception
|
||||||
def get_volume_encryption_metadata(self, context, volume_id):
|
def get_volume_encryption_metadata(self, context, volume_id):
|
||||||
return cinderclient(context).volumes.get_encryption_metadata(volume_id)
|
return cinderclient(context).volumes.get_encryption_metadata(volume_id)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user