summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen'ichi Ohmichi <ken-oomichi@wx.jp.nec.com>2016-09-28 17:41:51 -0700
committerKen'ichi Ohmichi <ken1ohmichi@gmail.com>2016-10-17 19:16:07 +0000
commita967cfe37a3bc26ee8a8517d5f5dac33b35e377e (patch)
treee1763956b26f67631b7d892e6dbbadc65df2bd6b
parent090bff767b0b410641dba5adf053e9142d1cdc6d (diff)
downloadnova-stable/liberty.tar.gz
Fix error status code on update-volume APIliberty-eol12.0.6stable/liberty
As the following part of API-WG guidline[1], If a request contains a reference to a nonexistent resource in the body (not URI), the code should be 400 Bad Request. Do not use 404 NotFound because :rfc:`7231#section-6.5.4` (section 6.5.4) mentions the origin server did not find a current representation for the target resource for 404 and representation for the target resource means a URI Nova should return a BadRequest response(400) in this case, because new_volume_id is specified in a request body. old_volume_id is not necessary to be changed because the value is specified with URI. So it is valid to return NotFound response if that is not existent. [1]: https://github.com/openstack/api-wg/blob/master/guidelines/http.rst#failure-code-clarifications Close-Bug: #1629110 Change-Id: Ib781b116f5af713d64b5880858cc4f81c3da3977 (cherry picked from commit edd86d9dac1ea75bc580a7964e7d699ee9644b19) (cherry picked from commit 4e6958551c324635a8720fc9125e9596860637f7)
-rw-r--r--nova/api/openstack/compute/legacy_v2/contrib/volumes.py13
-rw-r--r--nova/api/openstack/compute/volumes.py14
-rw-r--r--nova/tests/unit/api/openstack/compute/test_volumes.py12
3 files changed, 34 insertions, 5 deletions
diff --git a/nova/api/openstack/compute/legacy_v2/contrib/volumes.py b/nova/api/openstack/compute/legacy_v2/contrib/volumes.py
index aae3af8e87..c3c27d9ddb 100644
--- a/nova/api/openstack/compute/legacy_v2/contrib/volumes.py
+++ b/nova/api/openstack/compute/legacy_v2/contrib/volumes.py
@@ -355,8 +355,19 @@ class VolumeAttachmentController(wsgi.Controller):
except KeyError:
msg = _("volumeId must be specified.")
raise exc.HTTPBadRequest(explanation=msg)
+
self._validate_volume_id(new_volume_id)
- new_volume = self.volume_api.get(context, new_volume_id)
+ try:
+ new_volume = self.volume_api.get(context, new_volume_id)
+ except exception.VolumeNotFound as e:
+ # NOTE: This BadRequest is different from the above NotFound even
+ # though the same VolumeNotFound exception. This is intentional
+ # because new_volume_id is specified in a request body and if a
+ # nonexistent resource in the body (not URI) the code should be
+ # 400 Bad Request as API-WG guideline. On the other hand,
+ # old_volume_id is specified with URI. So it is valid to return
+ # NotFound response if that is not existent.
+ raise exc.HTTPBadRequest(explanation=e.format_message())
instance = common.get_instance(self.compute_api, context, server_id)
diff --git a/nova/api/openstack/compute/volumes.py b/nova/api/openstack/compute/volumes.py
index 5c013e8afb..585e1796db 100644
--- a/nova/api/openstack/compute/volumes.py
+++ b/nova/api/openstack/compute/volumes.py
@@ -325,11 +325,21 @@ class VolumeAttachmentController(wsgi.Controller):
old_volume_id = id
try:
old_volume = self.volume_api.get(context, old_volume_id)
+ except exception.VolumeNotFound as e:
+ raise exc.HTTPNotFound(explanation=e.format_message())
- new_volume_id = body['volumeAttachment']['volumeId']
+ new_volume_id = body['volumeAttachment']['volumeId']
+ try:
new_volume = self.volume_api.get(context, new_volume_id)
except exception.VolumeNotFound as e:
- raise exc.HTTPNotFound(explanation=e.format_message())
+ # NOTE: This BadRequest is different from the above NotFound even
+ # though the same VolumeNotFound exception. This is intentional
+ # because new_volume_id is specified in a request body and if a
+ # nonexistent resource in the body (not URI) the code should be
+ # 400 Bad Request as API-WG guideline. On the other hand,
+ # old_volume_id is specified with URI. So it is valid to return
+ # NotFound response if that is not existent.
+ raise exc.HTTPBadRequest(explanation=e.format_message())
instance = common.get_instance(self.compute_api, context, server_id)
diff --git a/nova/tests/unit/api/openstack/compute/test_volumes.py b/nova/tests/unit/api/openstack/compute/test_volumes.py
index f6ca8fcaab..80f6563d2d 100644
--- a/nova/tests/unit/api/openstack/compute/test_volumes.py
+++ b/nova/tests/unit/api/openstack/compute/test_volumes.py
@@ -650,9 +650,17 @@ class VolumeAttachTestsV21(test.NoDBTestCase):
status_int = result.status_int
self.assertEqual(202, status_int)
- def test_swap_volume_no_attachment(self):
+ def test_swap_volume_with_nonexistent_uri(self):
self.assertRaises(exc.HTTPNotFound, self._test_swap,
- self.attachments, FAKE_UUID_C)
+ self.attachments, uuid=FAKE_UUID_C)
+
+ @mock.patch.object(cinder.API, 'get')
+ def test_swap_volume_with_nonexistent_dest_in_body(self, mock_update):
+ mock_update.side_effect = [
+ None, exception.VolumeNotFound(volume_id=FAKE_UUID_C)]
+ body = {'volumeAttachment': {'volumeId': FAKE_UUID_C}}
+ self.assertRaises(exc.HTTPBadRequest, self._test_swap,
+ self.attachments, body=body)
def test_swap_volume_without_volumeId(self):
body = {'volumeAttachment': {'device': '/dev/fake'}}