Send proper exception info as expected by the neutron client

The python neutron client for the V2 API expects the neutron API
to send information back such as the type and detail of the exception
in the body of the message

Change-Id: I9486d757258c4be72799c41102babe1f7923121c
Closes-bug: #1226400
This commit is contained in:
Oleg Bondarev 2013-09-19 15:07:23 +04:00
parent 289d353d8c
commit 20b97388ef
4 changed files with 28 additions and 9 deletions

View File

@ -86,7 +86,10 @@ def Resource(controller, faults=None, deserializers=None, serializers=None):
netaddr.AddrFormatError) as e:
LOG.exception(_('%s failed'), action)
e = translate(e, language)
body = serializer.serialize({'NeutronError': e})
# following structure is expected by python-neutronclient
err_data = {'type': e.__class__.__name__,
'message': e, 'detail': ''}
body = serializer.serialize({'NeutronError': err_data})
kwargs = {'body': body, 'content_type': content_type}
for fault in faults:
if isinstance(e, fault):

View File

@ -1315,7 +1315,7 @@ class QuotaTest(APIv2TestBase):
instance.get_networks_count.assert_called_with(mock.ANY,
filters=mock.ANY)
self.assertIn("Quota exceeded for resources",
res.json['NeutronError'])
res.json['NeutronError']['message'])
def test_create_network_quota_no_counts(self):
cfg.CONF.set_override('quota_network', 1, group='QUOTAS')
@ -1332,7 +1332,7 @@ class QuotaTest(APIv2TestBase):
instance.get_networks_count.assert_called_with(mock.ANY,
filters=mock.ANY)
self.assertIn("Quota exceeded for resources",
res.json['NeutronError'])
res.json['NeutronError']['message'])
def test_create_network_quota_without_limit(self):
cfg.CONF.set_override('quota_network', -1, group='QUOTAS')

View File

@ -129,7 +129,11 @@ class ResourceTestCase(base.BaseTestCase):
class TestException(q_exc.NeutronException):
message = msg
expected_res = {'body': {'NeutronError': msg}}
expected_res = {'body': {
'NeutronError': {
'type': 'TestException',
'message': msg,
'detail': ''}}}
controller = mock.MagicMock()
controller.test.side_effect = TestException()
@ -147,7 +151,11 @@ class ResourceTestCase(base.BaseTestCase):
class TestException(q_exc.NeutronException):
message = msg
expected_res = {'body': {'NeutronError': msg}}
expected_res = {'body': {
'NeutronError': {
'type': 'TestException',
'message': msg,
'detail': ''}}}
controller = mock.MagicMock()
controller.test.side_effect = TestException()
@ -187,7 +195,11 @@ class ResourceTestCase(base.BaseTestCase):
class TestException(q_exc.NeutronException):
message = msg
expected_res = {'body': {'NeutronError': msg}}
expected_res = {'body': {
'NeutronError': {
'type': 'TestException',
'message': msg,
'detail': ''}}}
controller = mock.MagicMock()
controller.test.side_effect = TestException()
@ -207,7 +219,11 @@ class ResourceTestCase(base.BaseTestCase):
class TestException(q_exc.NeutronException):
message = msg
expected_res = {'body': {'NeutronError': msg}}
expected_res = {'body': {
'NeutronError': {
'type': 'TestException',
'message': msg,
'detail': ''}}}
controller = mock.MagicMock()
controller.test.side_effect = TestException()

View File

@ -1162,7 +1162,7 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s
res = self._create_port(self.fmt, id)
data = self.deserialize(self.fmt, res)
msg = str(q_exc.IpAddressGenerationFailure(net_id=id))
self.assertEqual(data['NeutronError'], msg)
self.assertEqual(data['NeutronError']['message'], msg)
self.assertEqual(res.status_int, webob.exc.HTTPConflict.code)
def test_update_port_update_ip(self):
@ -2477,7 +2477,7 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase):
data = self.deserialize(self.fmt, res)
self.assertEqual(res.status_int, webob.exc.HTTPConflict.code)
msg = str(q_exc.SubnetInUse(subnet_id=id))
self.assertEqual(data['NeutronError'], msg)
self.assertEqual(data['NeutronError']['message'], msg)
def test_delete_network(self):
gateway_ip = '10.0.0.1'