Skip to content

Commit

Permalink
Reject bad img formats for uploaded encrypted vols
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ostackbrian committed Jul 9, 2021
1 parent 735fc31 commit de8b3b0
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 2 deletions.
14 changes: 14 additions & 0 deletions api-ref/source/v3/parameters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions api-ref/source/v3/volumes-v3-volumes-actions.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
8 changes: 8 additions & 0 deletions cinder/api/contrib/volume_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@ def _volume_upload_image(self, req, id, body):
"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.
Expand Down
32 changes: 32 additions & 0 deletions cinder/tests/unit/api/contrib/test_volume_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,38 @@ def test_copy_volume_to_image_invalid_disk_format(self):
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):
Expand Down
12 changes: 12 additions & 0 deletions releasenotes/notes/bug-193688-bb045badcd5aecad.yaml
Original file line number Diff line number Diff line change
@@ -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.

0 comments on commit de8b3b0

Please sign in to comment.