The v1 and v2 xml deserializers for volume requests are missing
support for the imageRef, snapshot_id and source_volid attributes
resulting in xml format create volume requests which specify any
of those attributes being silently ignored. This fix adds support
to v1 and v2 and extends the volumes unit tests to check for this.
Also includes some minor debug logging enhancements to make this
easier to find in future.
Fixes bug #
1188581
Change-Id: Ib661c4a961c57e682e0e4e6db98d863b3a99cf71
volume_node = self.find_first_child_named(node, 'volume')
attributes = ['display_name', 'display_description', 'size',
- 'volume_type', 'availability_zone']
+ 'volume_type', 'availability_zone', 'imageRef',
+ 'snapshot_id', 'source_volid']
for attr in attributes:
if volume_node.getAttribute(attr):
volume[attr] = volume_node.getAttribute(attr)
if not self.is_valid_body(body, 'volume'):
raise exc.HTTPUnprocessableEntity()
+ LOG.debug('Create volume request body: %s', body)
context = req.environ['cinder.context']
volume = body['volume']
volume_node = self.find_first_child_named(node, 'volume')
attributes = ['name', 'description', 'size',
- 'volume_type', 'availability_zone']
+ 'volume_type', 'availability_zone', 'imageRef',
+ 'snapshot_id', 'source_volid']
for attr in attributes:
if volume_node.getAttribute(attr):
volume[attr] = volume_node.getAttribute(attr)
if not self.is_valid_body(body, 'volume'):
raise exc.HTTPBadRequest()
+ LOG.debug('Create volume request body: %s', body)
context = req.environ['cinder.context']
volume = body['volume']
}
self.assertEquals(request['body'], expected)
+ def test_imageref(self):
+ self_request = """
+<volume xmlns="http://docs.openstack.org/volume/api/v1"
+ size="1"
+ display_name="Volume-xml"
+ display_description="description"
+ imageRef="4a90189d-d702-4c7c-87fc-6608c554d737"></volume>"""
+ request = self.deserializer.deserialize(self_request)
+ expected = {
+ "volume": {
+ "size": "1",
+ "display_name": "Volume-xml",
+ "display_description": "description",
+ "imageRef": "4a90189d-d702-4c7c-87fc-6608c554d737",
+ },
+ }
+ self.assertEquals(expected, request['body'])
+
+ def test_snapshot_id(self):
+ self_request = """
+<volume xmlns="http://docs.openstack.org/volume/api/v1"
+ size="1"
+ display_name="Volume-xml"
+ display_description="description"
+ snapshot_id="4a90189d-d702-4c7c-87fc-6608c554d737"></volume>"""
+ request = self.deserializer.deserialize(self_request)
+ expected = {
+ "volume": {
+ "size": "1",
+ "display_name": "Volume-xml",
+ "display_description": "description",
+ "snapshot_id": "4a90189d-d702-4c7c-87fc-6608c554d737",
+ },
+ }
+ self.assertEquals(expected, request['body'])
+
+ def test_source_volid(self):
+ self_request = """
+<volume xmlns="http://docs.openstack.org/volume/api/v1"
+ size="1"
+ display_name="Volume-xml"
+ display_description="description"
+ source_volid="4a90189d-d702-4c7c-87fc-6608c554d737"></volume>"""
+ request = self.deserializer.deserialize(self_request)
+ expected = {
+ "volume": {
+ "size": "1",
+ "display_name": "Volume-xml",
+ "display_description": "description",
+ "source_volid": "4a90189d-d702-4c7c-87fc-6608c554d737",
+ },
+ }
+ self.assertEquals(expected, request['body'])
+
class VolumesUnprocessableEntityTestCase(test.TestCase):
},
}
self.assertEquals(request['body'], expected)
+
+ def test_imageref(self):
+ self_request = """
+<volume xmlns="http://docs.openstack.org/api/openstack-volume/2.0/content"
+ size="1"
+ name="Volume-xml"
+ description="description"
+ imageRef="4a90189d-d702-4c7c-87fc-6608c554d737"></volume>"""
+ request = self.deserializer.deserialize(self_request)
+ expected = {
+ "volume": {
+ "size": "1",
+ "name": "Volume-xml",
+ "description": "description",
+ "imageRef": "4a90189d-d702-4c7c-87fc-6608c554d737",
+ },
+ }
+ self.assertEquals(expected, request['body'])
+
+ def test_snapshot_id(self):
+ self_request = """
+<volume xmlns="http://docs.openstack.org/api/openstack-volume/2.0/content"
+ size="1"
+ name="Volume-xml"
+ description="description"
+ snapshot_id="4a90189d-d702-4c7c-87fc-6608c554d737"></volume>"""
+ request = self.deserializer.deserialize(self_request)
+ expected = {
+ "volume": {
+ "size": "1",
+ "name": "Volume-xml",
+ "description": "description",
+ "snapshot_id": "4a90189d-d702-4c7c-87fc-6608c554d737",
+ },
+ }
+ self.assertEquals(expected, request['body'])
+
+ def test_source_volid(self):
+ self_request = """
+<volume xmlns="http://docs.openstack.org/api/openstack-volume/2.0/content"
+ size="1"
+ name="Volume-xml"
+ description="description"
+ source_volid="4a90189d-d702-4c7c-87fc-6608c554d737"></volume>"""
+ request = self.deserializer.deserialize(self_request)
+ expected = {
+ "volume": {
+ "size": "1",
+ "name": "Volume-xml",
+ "description": "description",
+ "source_volid": "4a90189d-d702-4c7c-87fc-6608c554d737",
+ },
+ }
+ self.assertEquals(expected, request['body'])