From 86bf2276d9adf2365e46a880d7ec4a276780d3ed Mon Sep 17 00:00:00 2001 From: Mark Washenberger Date: Mon, 5 Mar 2012 16:48:18 -0500 Subject: Only pass image uuids to compute api rebuild Addresses bug 881641 Change-Id: I9c0270d5ceb126387a0052c83937ae778d1f49cb --- nova/api/openstack/compute/servers.py | 22 ++++++---- .../api/openstack/compute/test_server_actions.py | 48 +++++++++++++++++++++- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py index 5dc5cff49..2bfbfb745 100644 --- a/nova/api/openstack/compute/servers.py +++ b/nova/api/openstack/compute/servers.py @@ -633,14 +633,7 @@ class Controller(wsgi.Controller): name = name.strip() image_href = self._image_ref_from_req_data(body) - - # If the image href was generated by nova api, strip image_href - # down to an id and use the default glance connection params - image_href = image_href.split('/').pop() - - if not utils.is_uuid_like(str(image_href)): - msg = _("Invalid imageRef provided.") - raise exc.HTTPBadRequest(explanation=msg) + image_href = self._image_uuid_from_href(image_href) personality = server_dict.get('personality') config_drive = server_dict.get('config_drive') @@ -933,6 +926,17 @@ class Controller(wsgi.Controller): msg = _("Missing imageRef attribute") raise exc.HTTPBadRequest(explanation=msg) + def _image_uuid_from_href(self, image_href): + # If the image href was generated by nova api, strip image_href + # down to an id and use the default glance connection params + image_uuid = image_href.split('/').pop() + + if not utils.is_uuid_like(image_uuid): + msg = _("Invalid imageRef provided.") + raise exc.HTTPBadRequest(explanation=msg) + + return image_uuid + def _flavor_id_from_req_data(self, data): try: flavor_ref = data['server']['flavorRef'] @@ -1010,6 +1014,8 @@ class Controller(wsgi.Controller): msg = _("Could not parse imageRef from request.") raise exc.HTTPBadRequest(explanation=msg) + image_href = self._image_uuid_from_href(image_href) + try: password = body['adminPass'] except (KeyError, TypeError): diff --git a/nova/tests/api/openstack/compute/test_server_actions.py b/nova/tests/api/openstack/compute/test_server_actions.py index 30c3d8cff..fd9b5eaef 100644 --- a/nova/tests/api/openstack/compute/test_server_actions.py +++ b/nova/tests/api/openstack/compute/test_server_actions.py @@ -203,6 +203,52 @@ class ServerActionsControllerTest(test.TestCase): self.assertEqual(robj['location'], self_href) + def test_rebuild_instance_with_image_uuid(self): + info = dict(image_href_in_call=None) + + def rebuild(self2, context, instance, image_href, *args, **kwargs): + info['image_href_in_call'] = image_href + + self.stubs.Set(nova.db, 'instance_get', + fakes.fake_instance_get(vm_state=vm_states.ACTIVE)) + self.stubs.Set(nova.compute.API, 'rebuild', rebuild) + + # proper local hrefs must start with 'http://localhost/v2/' + image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' + image_href = 'http://localhost/v2/fake/images/%s' % image_uuid + body = { + 'rebuild': { + 'imageRef': image_uuid, + }, + } + + req = fakes.HTTPRequest.blank('/v2/fake/servers/a/action') + self.controller._action_rebuild(req, FAKE_UUID, body) + self.assertEqual(info['image_href_in_call'], image_uuid) + + def test_rebuild_instance_with_image_href_uses_uuid(self): + info = dict(image_href_in_call=None) + + def rebuild(self2, context, instance, image_href, *args, **kwargs): + info['image_href_in_call'] = image_href + + self.stubs.Set(nova.db, 'instance_get', + fakes.fake_instance_get(vm_state=vm_states.ACTIVE)) + self.stubs.Set(nova.compute.API, 'rebuild', rebuild) + + # proper local hrefs must start with 'http://localhost/v2/' + image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' + image_href = 'http://localhost/v2/fake/images/%s' % image_uuid + body = { + 'rebuild': { + 'imageRef': image_href, + }, + } + + req = fakes.HTTPRequest.blank('/v2/fake/servers/a/action') + self.controller._action_rebuild(req, FAKE_UUID, body) + self.assertEqual(info['image_href_in_call'], image_uuid) + def test_rebuild_accepted_minimum_pass_disabled(self): # run with enable_instance_password disabled to verify adminPass # is missing from response. See lp bug 921814 @@ -231,7 +277,7 @@ class ServerActionsControllerTest(test.TestCase): def test_rebuild_raises_conflict_on_invalid_state(self): body = { "rebuild": { - "imageRef": "http://localhost/images/2", + "imageRef": self._image_href, }, } -- cgit