From 764860a0296bc47cd24d8f62ba745cd1bfdf7eb6 Mon Sep 17 00:00:00 2001 From: He Jie Xu Date: Mon, 2 Sep 2013 16:25:14 +0800 Subject: [PATCH] Fix v3 swap volume with wrong signature Fix bug 1219672 Fix the signature and add related integrated test. And fix test_servers missing subs 'glance_host'. Change-Id: I040dafe2c1bcfc014fdeba3f735b322908af96c0 --- .../os-extended-volumes/server-post-req.json | 16 ++++ .../os-extended-volumes/server-post-req.xml | 19 +++++ .../os-extended-volumes/server-post-resp.json | 16 ++++ .../os-extended-volumes/server-post-resp.xml | 6 ++ .../os-extended-volumes/swap-volume-req.json | 6 ++ .../os-extended-volumes/swap-volume-req.xml | 2 + .../compute/plugins/v3/extended_volumes.py | 4 +- .../server-post-req.json.tpl | 16 ++++ .../server-post-req.xml.tpl | 19 +++++ .../server-post-resp.json.tpl | 16 ++++ .../server-post-resp.xml.tpl | 6 ++ .../swap-volume-req.json.tpl | 6 ++ .../swap-volume-req.xml.tpl | 2 + .../integrated/v3/test_extended_volumes.py | 74 +++++++++++++++++++ nova/tests/integrated/v3/test_servers.py | 1 + 15 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 doc/v3/api_samples/os-extended-volumes/server-post-req.json create mode 100644 doc/v3/api_samples/os-extended-volumes/server-post-req.xml create mode 100644 doc/v3/api_samples/os-extended-volumes/server-post-resp.json create mode 100644 doc/v3/api_samples/os-extended-volumes/server-post-resp.xml create mode 100644 doc/v3/api_samples/os-extended-volumes/swap-volume-req.json create mode 100644 doc/v3/api_samples/os-extended-volumes/swap-volume-req.xml create mode 100644 nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-req.json.tpl create mode 100644 nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-req.xml.tpl create mode 100644 nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-resp.json.tpl create mode 100644 nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-resp.xml.tpl create mode 100644 nova/tests/integrated/v3/api_samples/os-extended-volumes/swap-volume-req.json.tpl create mode 100644 nova/tests/integrated/v3/api_samples/os-extended-volumes/swap-volume-req.xml.tpl create mode 100644 nova/tests/integrated/v3/test_extended_volumes.py diff --git a/doc/v3/api_samples/os-extended-volumes/server-post-req.json b/doc/v3/api_samples/os-extended-volumes/server-post-req.json new file mode 100644 index 000000000000..30851df41a56 --- /dev/null +++ b/doc/v3/api_samples/os-extended-volumes/server-post-req.json @@ -0,0 +1,16 @@ +{ + "server" : { + "name" : "new-server-test", + "image_ref" : "http://glance.openstack.example.com/images/70a599e0-31e7-49b7-b260-868f441e862b", + "flavor_ref" : "http://openstack.example.com/flavors/1", + "metadata" : { + "My Server Name" : "Apache1" + }, + "personality" : [ + { + "path" : "/etc/banner.txt", + "contents" : "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBpdCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5kIGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVsc2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4gQnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRoZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlvdSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vyc2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6b25zLiINCg0KLVJpY2hhcmQgQmFjaA==" + } + ] + } +} \ No newline at end of file diff --git a/doc/v3/api_samples/os-extended-volumes/server-post-req.xml b/doc/v3/api_samples/os-extended-volumes/server-post-req.xml new file mode 100644 index 000000000000..24eabe8533ba --- /dev/null +++ b/doc/v3/api_samples/os-extended-volumes/server-post-req.xml @@ -0,0 +1,19 @@ + + + + Apache1 + + + + ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp + dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k + IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs + c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g + QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo + ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv + dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy + c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6 + b25zLiINCg0KLVJpY2hhcmQgQmFjaA== + + + \ No newline at end of file diff --git a/doc/v3/api_samples/os-extended-volumes/server-post-resp.json b/doc/v3/api_samples/os-extended-volumes/server-post-resp.json new file mode 100644 index 000000000000..1e8d03dadacc --- /dev/null +++ b/doc/v3/api_samples/os-extended-volumes/server-post-resp.json @@ -0,0 +1,16 @@ +{ + "server": { + "admin_pass": "wCGJKvs9RApD", + "id": "c43b584c-86ac-438c-aa9d-70aac14c2b27", + "links": [ + { + "href": "http://openstack.example.com/v3/servers/c43b584c-86ac-438c-aa9d-70aac14c2b27", + "rel": "self" + }, + { + "href": "http://openstack.example.com/servers/c43b584c-86ac-438c-aa9d-70aac14c2b27", + "rel": "bookmark" + } + ] + } +} \ No newline at end of file diff --git a/doc/v3/api_samples/os-extended-volumes/server-post-resp.xml b/doc/v3/api_samples/os-extended-volumes/server-post-resp.xml new file mode 100644 index 000000000000..14559418555f --- /dev/null +++ b/doc/v3/api_samples/os-extended-volumes/server-post-resp.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/doc/v3/api_samples/os-extended-volumes/swap-volume-req.json b/doc/v3/api_samples/os-extended-volumes/swap-volume-req.json new file mode 100644 index 000000000000..32aaf11dfdd2 --- /dev/null +++ b/doc/v3/api_samples/os-extended-volumes/swap-volume-req.json @@ -0,0 +1,6 @@ +{ + "swap": { + "old_volume_id": "a26887c6-c47b-4654-abb5-dfadf7d3f803", + "new_volume_id": "a26887c6-c47b-4654-abb5-dfadf7d3f804" + } +} \ No newline at end of file diff --git a/doc/v3/api_samples/os-extended-volumes/swap-volume-req.xml b/doc/v3/api_samples/os-extended-volumes/swap-volume-req.xml new file mode 100644 index 000000000000..32bc36436f75 --- /dev/null +++ b/doc/v3/api_samples/os-extended-volumes/swap-volume-req.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/nova/api/openstack/compute/plugins/v3/extended_volumes.py b/nova/api/openstack/compute/plugins/v3/extended_volumes.py index 7c2aac7514ad..62ec84eb5702 100644 --- a/nova/api/openstack/compute/plugins/v3/extended_volumes.py +++ b/nova/api/openstack/compute/plugins/v3/extended_volumes.py @@ -54,7 +54,7 @@ class ExtendedVolumesController(wsgi.Controller): @extensions.expected_errors((400, 404, 409)) @wsgi.action('swap_volume_attachment') - def swap(self, req, server_id, body): + def swap(self, req, id, body): context = req.environ['nova.context'] authorize_swap(context) @@ -72,7 +72,7 @@ class ExtendedVolumesController(wsgi.Controller): raise exc.HTTPBadRequest("The request body is invalid") try: - instance = self.compute_api.get(context, server_id, + instance = self.compute_api.get(context, id, want_objects=True) except exception.InstanceNotFound as e: raise exc.HTTPNotFound(explanation=e.format_message()) diff --git a/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-req.json.tpl b/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-req.json.tpl new file mode 100644 index 000000000000..e6c046ceb4e9 --- /dev/null +++ b/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-req.json.tpl @@ -0,0 +1,16 @@ +{ + "server" : { + "name" : "new-server-test", + "image_ref" : "%(glance_host)s/images/%(image_id)s", + "flavor_ref" : "%(host)s/flavors/1", + "metadata" : { + "My Server Name" : "Apache1" + }, + "personality" : [ + { + "path" : "/etc/banner.txt", + "contents" : "ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBpdCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5kIGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVsc2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4gQnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRoZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlvdSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vyc2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6b25zLiINCg0KLVJpY2hhcmQgQmFjaA==" + } + ] + } +} diff --git a/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-req.xml.tpl b/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-req.xml.tpl new file mode 100644 index 000000000000..31892a3c1f4d --- /dev/null +++ b/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-req.xml.tpl @@ -0,0 +1,19 @@ + + + + Apache1 + + + + ICAgICAgDQoiQSBjbG91ZCBkb2VzIG5vdCBrbm93IHdoeSBp + dCBtb3ZlcyBpbiBqdXN0IHN1Y2ggYSBkaXJlY3Rpb24gYW5k + IGF0IHN1Y2ggYSBzcGVlZC4uLkl0IGZlZWxzIGFuIGltcHVs + c2lvbi4uLnRoaXMgaXMgdGhlIHBsYWNlIHRvIGdvIG5vdy4g + QnV0IHRoZSBza3kga25vd3MgdGhlIHJlYXNvbnMgYW5kIHRo + ZSBwYXR0ZXJucyBiZWhpbmQgYWxsIGNsb3VkcywgYW5kIHlv + dSB3aWxsIGtub3csIHRvbywgd2hlbiB5b3UgbGlmdCB5b3Vy + c2VsZiBoaWdoIGVub3VnaCB0byBzZWUgYmV5b25kIGhvcml6 + b25zLiINCg0KLVJpY2hhcmQgQmFjaA== + + + diff --git a/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-resp.json.tpl b/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-resp.json.tpl new file mode 100644 index 000000000000..d061e9cb2e80 --- /dev/null +++ b/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-resp.json.tpl @@ -0,0 +1,16 @@ +{ + "server": { + "admin_pass": "%(password)s", + "id": "%(id)s", + "links": [ + { + "href": "%(host)s/v3/servers/%(uuid)s", + "rel": "self" + }, + { + "href": "%(host)s/servers/%(uuid)s", + "rel": "bookmark" + } + ] + } +} diff --git a/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-resp.xml.tpl b/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-resp.xml.tpl new file mode 100644 index 000000000000..3470373e171f --- /dev/null +++ b/nova/tests/integrated/v3/api_samples/os-extended-volumes/server-post-resp.xml.tpl @@ -0,0 +1,6 @@ + + + + + + diff --git a/nova/tests/integrated/v3/api_samples/os-extended-volumes/swap-volume-req.json.tpl b/nova/tests/integrated/v3/api_samples/os-extended-volumes/swap-volume-req.json.tpl new file mode 100644 index 000000000000..07a32684213b --- /dev/null +++ b/nova/tests/integrated/v3/api_samples/os-extended-volumes/swap-volume-req.json.tpl @@ -0,0 +1,6 @@ +{ + "swap_volume_attachment": { + "old_volume_id": "%(old_volume_id)s", + "new_volume_id": "%(new_volume_id)s" + } +} diff --git a/nova/tests/integrated/v3/api_samples/os-extended-volumes/swap-volume-req.xml.tpl b/nova/tests/integrated/v3/api_samples/os-extended-volumes/swap-volume-req.xml.tpl new file mode 100644 index 000000000000..1d2df75f3e98 --- /dev/null +++ b/nova/tests/integrated/v3/api_samples/os-extended-volumes/swap-volume-req.xml.tpl @@ -0,0 +1,2 @@ + + diff --git a/nova/tests/integrated/v3/test_extended_volumes.py b/nova/tests/integrated/v3/test_extended_volumes.py new file mode 100644 index 000000000000..1163c5a5a1c9 --- /dev/null +++ b/nova/tests/integrated/v3/test_extended_volumes.py @@ -0,0 +1,74 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright 2012 Nebula, Inc. +# Copyright 2013 IBM Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from nova.compute import api as compute_api +from nova.compute import manager as compute_manager +from nova.tests.api.openstack import fakes +from nova.tests.integrated.v3 import test_servers +from nova.volume import cinder + + +class ExtendedVolumesSampleJsonTests(test_servers.ServersSampleBase): + extension_name = "os-extended-volumes" + + def _stub_compute_api_get_instance_bdms(self, server_id): + + def fake_compute_api_get_instance_bdms(self, context, instance): + bdms = [ + {'volume_id': 'a26887c6-c47b-4654-abb5-dfadf7d3f803', + 'instance_uuid': server_id, + 'device_name': '/dev/sdd'}, + {'volume_id': 'a26887c6-c47b-4654-abb5-dfadf7d3f804', + 'instance_uuid': server_id, + 'device_name': '/dev/sdc'} + ] + return bdms + + self.stubs.Set(compute_api.API, "get_instance_bdms", + fake_compute_api_get_instance_bdms) + + def test_swap_volume(self): + server_id = self._post_server() + old_volume_id = "a26887c6-c47b-4654-abb5-dfadf7d3f803" + old_new_volume = 'a26887c6-c47b-4654-abb5-dfadf7d3f805' + self._stub_compute_api_get_instance_bdms(server_id) + + def stub_volume_get(self, context, volume_id): + if volume_id == old_volume_id: + return fakes.stub_volume(volume_id, instance_uuid=server_id) + else: + return fakes.stub_volume(volume_id, instance_uuid=None, + attach_status='detached') + + self.stubs.Set(cinder.API, 'get', stub_volume_get) + self.stubs.Set(cinder.API, 'begin_detaching', lambda *a, **k: None) + self.stubs.Set(cinder.API, 'check_attach', lambda *a, **k: None) + self.stubs.Set(cinder.API, 'check_detach', lambda *a, **k: None) + self.stubs.Set(cinder.API, 'reserve_volume', lambda *a, **k: None) + self.stubs.Set(compute_manager.ComputeManager, 'swap_volume', + lambda *a, **k: None) + subs = { + 'old_volume_id': old_volume_id, + 'new_volume_id': old_new_volume + } + response = self._do_post('servers/%s/action' % server_id, + 'swap-volume-req', subs) + self.assertEqual(response.status, 202) + self.assertEqual(response.read(), '') + + +class ExtendedVolumesSampleXmlTests(ExtendedVolumesSampleJsonTests): + ctype = 'xml' diff --git a/nova/tests/integrated/v3/test_servers.py b/nova/tests/integrated/v3/test_servers.py index fd6bcc8afe20..84e7ab3c5fa9 100644 --- a/nova/tests/integrated/v3/test_servers.py +++ b/nova/tests/integrated/v3/test_servers.py @@ -23,6 +23,7 @@ class ServersSampleBase(api_sample_base.ApiSampleTestBaseV3): subs = { 'image_id': fake.get_valid_image_id(), 'host': self._get_host(), + 'glance_host': self._get_glance_host() } response = self._do_post('servers', 'server-post-req', subs) subs = self._get_regexes()