From b65d678f4d475a62f9a83f96bddbeb6f694d1e5b Mon Sep 17 00:00:00 2001
From: Pascal Wehrle
Date: Mon, 17 Nov 2014 23:20:17 +0100
Subject: [PATCH] allow image_id for imageRef in create volume API v2
The create volume request for the V2 API has a property named
"imageRef" with the ID of the image to be used when creating the
volume.
The name of this property is inconsistent as all multi word
properties use snake case and the property in the reponse is named
"image_id".
This adds support for aliasing the imageRef key with image_id when
creating a volume in v2 of the Cinder API in a backward-compatible
way.
Change-Id: I85a5c6734ba05a8a7ea9eff3f849d12fb3d167fb
Closes-Bug: 1375867
---
cinder/api/v2/volumes.py | 7 +-
cinder/tests/api/v2/test_volumes.py | 100 ++++++++++++++++++++++++++--
2 files changed, 101 insertions(+), 6 deletions(-)
diff --git a/cinder/api/v2/volumes.py b/cinder/api/v2/volumes.py
index 8addd0f3d..96ef3150e 100644
--- a/cinder/api/v2/volumes.py
+++ b/cinder/api/v2/volumes.py
@@ -122,7 +122,8 @@ class CommonDeserializer(wsgi.MetadataXMLDeserializer):
attributes = ['name', 'description', 'size',
'volume_type', 'availability_zone', 'imageRef',
- 'snapshot_id', 'source_volid', 'consistencygroup_id']
+ 'image_id', 'snapshot_id', 'source_volid',
+ 'consistencygroup_id']
for attr in attributes:
if volume_node.getAttribute(attr):
volume[attr] = volume_node.getAttribute(attr)
@@ -290,6 +291,10 @@ class VolumeController(wsgi.Controller):
volume['display_description'] = volume.get('description')
del volume['description']
+ if 'image_id' in volume:
+ volume['imageRef'] = volume.get('image_id')
+ del volume['image_id']
+
req_volume_type = volume.get('volume_type', None)
if req_volume_type:
try:
diff --git a/cinder/tests/api/v2/test_volumes.py b/cinder/tests/api/v2/test_volumes.py
index 1fded8937..ded01d812 100644
--- a/cinder/tests/api/v2/test_volumes.py
+++ b/cinder/tests/api/v2/test_volumes.py
@@ -211,7 +211,7 @@ class VolumeApiTest(test.TestCase):
self.controller.create,
req, body)
- def test_volume_create_with_image_id(self):
+ def test_volume_create_with_image_ref(self):
self.stubs.Set(volume_api.API, 'get', stubs.stub_volume_get)
self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create)
@@ -250,9 +250,9 @@ class VolumeApiTest(test.TestCase):
body = {"volume": vol}
req = fakes.HTTPRequest.blank('/v2/volumes')
res_dict = self.controller.create(req, body)
- self.assertEqual(res_dict, ex)
+ self.assertEqual(ex, res_dict)
- def test_volume_create_with_image_id_is_integer(self):
+ def test_volume_create_with_image_ref_is_integer(self):
self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create)
self.ext_mgr.extensions = {'os-image-create': 'fake'}
vol = {
@@ -269,7 +269,7 @@ class VolumeApiTest(test.TestCase):
req,
body)
- def test_volume_create_with_image_id_not_uuid_format(self):
+ def test_volume_create_with_image_ref_not_uuid_format(self):
self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create)
self.ext_mgr.extensions = {'os-image-create': 'fake'}
vol = {
@@ -286,7 +286,7 @@ class VolumeApiTest(test.TestCase):
req,
body)
- def test_volume_create_with_image_id_with_empty_string(self):
+ def test_volume_create_with_image_ref_with_empty_string(self):
self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create)
self.ext_mgr.extensions = {'os-image-create': 'fake'}
vol = {"size": 1,
@@ -301,6 +301,96 @@ class VolumeApiTest(test.TestCase):
req,
body)
+ def test_volume_create_with_image_id(self):
+ self.stubs.Set(volume_api.API, 'get', stubs.stub_volume_get)
+ self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create)
+
+ self.ext_mgr.extensions = {'os-image-create': 'fake'}
+ vol = {"size": '1',
+ "name": "Volume Test Name",
+ "description": "Volume Test Desc",
+ "availability_zone": "nova",
+ "image_id": 'c905cedb-7281-47e4-8a62-f26bc5fc4c77'}
+ ex = {'volume': {'attachments': [{'device': '/',
+ 'host_name': None,
+ 'id': '1',
+ 'server_id': 'fakeuuid',
+ 'volume_id': '1'}],
+ 'availability_zone': 'nova',
+ 'bootable': 'false',
+ 'consistencygroup_id': None,
+ 'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
+ 'description': 'Volume Test Desc',
+ 'encrypted': False,
+ 'id': '1',
+ 'links':
+ [{'href': 'http://localhost/v2/fakeproject/volumes/1',
+ 'rel': 'self'},
+ {'href': 'http://localhost/fakeproject/volumes/1',
+ 'rel': 'bookmark'}],
+ 'metadata': {},
+ 'name': 'Volume Test Name',
+ 'replication_status': 'disabled',
+ 'size': '1',
+ 'snapshot_id': None,
+ 'source_volid': None,
+ 'status': 'fakestatus',
+ 'user_id': 'fakeuser',
+ 'volume_type': 'vol_type_name'}}
+ body = {"volume": vol}
+ req = fakes.HTTPRequest.blank('/v2/volumes')
+ res_dict = self.controller.create(req, body)
+ self.assertEqual(ex, res_dict)
+
+ def test_volume_create_with_image_id_is_integer(self):
+ self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create)
+ self.ext_mgr.extensions = {'os-image-create': 'fake'}
+ vol = {
+ "size": '1',
+ "name": "Volume Test Name",
+ "description": "Volume Test Desc",
+ "availability_zone": "cinder",
+ "image_id": 1234,
+ }
+ body = {"volume": vol}
+ req = fakes.HTTPRequest.blank('/v2/volumes')
+ self.assertRaises(webob.exc.HTTPBadRequest,
+ self.controller.create,
+ req,
+ body)
+
+ def test_volume_create_with_image_id_not_uuid_format(self):
+ self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create)
+ self.ext_mgr.extensions = {'os-image-create': 'fake'}
+ vol = {
+ "size": '1',
+ "name": "Volume Test Name",
+ "description": "Volume Test Desc",
+ "availability_zone": "cinder",
+ "image_id": '12345'
+ }
+ body = {"volume": vol}
+ req = fakes.HTTPRequest.blank('/v2/volumes')
+ self.assertRaises(webob.exc.HTTPBadRequest,
+ self.controller.create,
+ req,
+ body)
+
+ def test_volume_create_with_image_id_with_empty_string(self):
+ self.stubs.Set(volume_api.API, "create", stubs.stub_volume_create)
+ self.ext_mgr.extensions = {'os-image-create': 'fake'}
+ vol = {"size": 1,
+ "display_name": "Volume Test Name",
+ "display_description": "Volume Test Desc",
+ "availability_zone": "cinder",
+ "image_id": ''}
+ body = {"volume": vol}
+ req = fakes.HTTPRequest.blank('/v2/volumes')
+ self.assertRaises(webob.exc.HTTPBadRequest,
+ self.controller.create,
+ req,
+ body)
+
def test_volume_update(self):
self.stubs.Set(volume_api.API, 'get', stubs.stub_volume_get)
self.stubs.Set(volume_api.API, "update", stubs.stub_volume_update)
--
2.45.2