diff --git a/nova/api/openstack/compute/plugins/v3/extended_volumes.py b/nova/api/openstack/compute/plugins/v3/extended_volumes.py index d60c7400b199..1026a40d2209 100644 --- a/nova/api/openstack/compute/plugins/v3/extended_volumes.py +++ b/nova/api/openstack/compute/plugins/v3/extended_volumes.py @@ -79,6 +79,7 @@ class ExtendedVolumesController(wsgi.Controller): "not in proper format (%s)") % volume_id raise exc.HTTPBadRequest(explanation=msg) + @extensions.expected_errors((400, 404, 409)) @wsgi.response(202) @wsgi.action('attach') def attach(self, req, id, body): @@ -89,7 +90,12 @@ class ExtendedVolumesController(wsgi.Controller): if not self.is_valid_body(body, 'attach'): raise exc.HTTPBadRequest(_("The request body invalid")) - volume_id = body['attach']['volume_id'] + try: + volume_id = body['attach']['volume_id'] + except KeyError: + raise exc.HTTPBadRequest(_("Could not find volume_id from request" + "parameter")) + device = body['attach'].get('device') self._validate_volume_id(volume_id) @@ -115,6 +121,7 @@ class ExtendedVolumesController(wsgi.Controller): except exception.InvalidDevicePath as e: raise exc.HTTPBadRequest(explanation=e.format_message()) + @extensions.expected_errors((400, 404, 409)) @wsgi.response(202) @wsgi.action('detach') def detach(self, req, id, body): @@ -122,7 +129,14 @@ class ExtendedVolumesController(wsgi.Controller): context = req.environ['nova.context'] authorize_detach(context) - volume_id = body['detach']['volume_id'] + if not self.is_valid_body(body, 'detach'): + raise exc.HTTPBadRequest(_("The request body invalid")) + try: + volume_id = body['detach']['volume_id'] + except KeyError: + raise exc.HTTPBadRequest(_("Could not find volume_id from request" + "parameter")) + self._validate_volume_id(volume_id) LOG.audit(_("Detach volume %(volume_id)s from " "instance %(server_id)s"), {"volume_id": volume_id, diff --git a/nova/tests/api/openstack/compute/plugins/v3/test_extended_volumes.py b/nova/tests/api/openstack/compute/plugins/v3/test_extended_volumes.py index b8f25069da5b..76634c692a74 100644 --- a/nova/tests/api/openstack/compute/plugins/v3/test_extended_volumes.py +++ b/nova/tests/api/openstack/compute/plugins/v3/test_extended_volumes.py @@ -179,6 +179,21 @@ class ExtendedVolumesTest(test.TestCase): res = self._make_request(url, {"detach": {"volume_id": UUID2}}) self.assertEqual(res.status_int, 400) + def test_detach_with_bad_id(self): + url = "/v3/servers/%s/action" % UUID1 + res = self._make_request(url, {"detach": {"volume_id": 'xxx'}}) + self.assertEqual(res.status_int, 400) + + def test_detach_without_id(self): + url = "/v3/servers/%s/action" % UUID1 + res = self._make_request(url, {"detach": {}}) + self.assertEqual(res.status_int, 400) + + def test_detach_volume_with_invalid_request(self): + url = "/v3/servers/%s/action" % UUID1 + res = self._make_request(url, {"detach": None}) + self.assertEqual(res.status_int, 400) + def test_attach_volume(self): url = "/v3/servers/%s/action" % UUID1 res = self._make_request(url, {"attach": {"volume_id": UUID1}}) @@ -189,6 +204,16 @@ class ExtendedVolumesTest(test.TestCase): res = self._make_request(url, {"attach": {"volume_id": 'xxx'}}) self.assertEqual(res.status_int, 400) + def test_attach_volume_without_id(self): + url = "/v3/servers/%s/action" % UUID1 + res = self._make_request(url, {"attach": {}}) + self.assertEqual(res.status_int, 400) + + def test_attach_volume_with_invalid_request(self): + url = "/v3/servers/%s/action" % UUID1 + res = self._make_request(url, {"attach": None}) + self.assertEqual(res.status_int, 400) + def test_attach_volume_with_non_existe_vol(self): url = "/v3/servers/%s/action" % UUID1 self.stubs.Set(compute.api.API, 'attach_volume',