Reject bad img formats for uploaded encrypted vols

Cinder only supports uploading volumes of encrypted volume types as
images with disk format 'raw' and container format 'bare'.  Screen
for this at the REST API layer when the request is made.

Change-Id: Ibb77b8b1be6c35c5db3b07fdc4056afd51d48782
Closes-bug: #1935688
This commit is contained in:
Brian Rosmaita 2021-07-09 11:08:34 -04:00
parent 735fc313a1
commit de8b3b0b00
5 changed files with 68 additions and 2 deletions

View File

@ -853,6 +853,13 @@ container_format:
in: body
required: false
type: string
container_format_upload:
description: |
Container format for the new image. Default is bare. (Note: Volumes
of an encrypted volume type must use a bare container format.)
in: body
required: false
type: string
control_location:
description: |
Notional service where encryption is performed. Valid values are
@ -1100,6 +1107,13 @@ disk_format:
in: body
required: false
type: string
disk_format_upload:
description: |
Disk format for the new image. Default is raw. (Note: volumes of an
encrypted volume type can only be uploaded in raw format.)
in: body
required: false
type: string
display_name:
description: |
The name of volume backend capabilities.

View File

@ -699,8 +699,8 @@ Request
- os-volume_upload_image: os-volume_upload_image
- image_name: image_name
- force: force_upload_vol
- disk_format: disk_format
- container_format: container_format
- disk_format: disk_format_upload
- container_format: container_format_upload
- visibility: visibility_min
- protected: protected

View File

@ -217,6 +217,14 @@ class VolumeActionsController(wsgi.Controller):
"name": params["image_name"]}
if volume.encryption_key_id:
# encrypted volumes cannot be converted on upload
if (image_metadata['disk_format'] != 'raw'
or image_metadata['container_format'] != 'bare'):
msg = _("An encrypted volume uploaded as an image must use "
"'raw' disk_format and 'bare' container_format, "
"which are the defaults for these options.")
raise webob.exc.HTTPBadRequest(explanation=msg)
# Clone volume encryption key: the current key cannot
# be reused because it will be deleted when the volume is
# deleted.

View File

@ -1003,6 +1003,38 @@ class VolumeImageActionsTest(test.TestCase):
id,
body=body)
@mock.patch.object(volume_api.API, 'get', fake_volume_get_obj)
def test_copy_volume_to_image_bad_disk_format_for_encrypted_vol(self):
id = ENCRYPTED_VOLUME_ID
vol = {"container_format": 'bare',
"disk_format": 'qcow2',
"image_name": 'image_name',
"force": True}
body = {"os-volume_upload_image": vol}
req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action'
% (fake.PROJECT_ID, id))
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller._volume_upload_image,
req,
id,
body=body)
@mock.patch.object(volume_api.API, 'get', fake_volume_get_obj)
def test_copy_volume_to_image_bad_container_format_for_encrypted_vol(self):
id = ENCRYPTED_VOLUME_ID
vol = {"container_format": 'ovf',
"disk_format": 'raw',
"image_name": 'image_name',
"force": True}
body = {"os-volume_upload_image": vol}
req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action'
% (fake.PROJECT_ID, id))
self.assertRaises(webob.exc.HTTPBadRequest,
self.controller._volume_upload_image,
req,
id,
body=body)
@mock.patch.object(volume_api.API, "copy_volume_to_image")
def test_copy_volume_to_image_disk_format_ploop(self,
mock_copy_to_image):

View File

@ -0,0 +1,12 @@
---
fixes:
- |
`Bug #1935688 <https://bugs.launchpad.net/cinder/+bug/1935688>`_:
Cinder only supports uploading a volume of an encrypted volume type as an
image to the Image service in ``raw`` format using a ``bare`` container
type. Previously, ``os-volume_upload_image`` action requests to the Block
Storage API specifying different format option values were accepted, but
would result in a later failure. This condition is now checked at the API
layer, and ``os-volume_upload_image`` action requests on a volume of an
encrypted type that specify unsupported values for ``disk_format`` or
``container_format`` now result in a 400 (Bad Request) response.