Merge "Add "deletion policy" property to uploaded images"

This commit is contained in:
Zuul 2019-09-25 18:20:01 +00:00 committed by Gerrit Code Review
commit 65799390a7
2 changed files with 70 additions and 3 deletions

View File

@ -221,14 +221,13 @@ class VolumeActionsController(wsgi.Controller):
# Clone volume encryption key: the current key cannot # Clone volume encryption key: the current key cannot
# be reused because it will be deleted when the volume is # be reused because it will be deleted when the volume is
# deleted. # deleted.
# TODO(eharney): Currently, there is no mechanism to remove
# these keys, because Glance will not delete the key from
# Barbican when the image is deleted.
encryption_key_id = self._key_manager.store( encryption_key_id = self._key_manager.store(
context, context,
self._key_manager.get(context, volume.encryption_key_id)) self._key_manager.get(context, volume.encryption_key_id))
image_metadata['cinder_encryption_key_id'] = encryption_key_id image_metadata['cinder_encryption_key_id'] = encryption_key_id
image_metadata['cinder_encryption_key_deletion_policy'] = \
'on_image_deletion'
if req_version >= mv.get_api_version( if req_version >= mv.get_api_version(
mv.UPLOAD_IMAGE_PARAMS): mv.UPLOAD_IMAGE_PARAMS):

View File

@ -44,6 +44,7 @@ from cinder.volume import rpcapi as volume_rpcapi
CONF = cfg.CONF CONF = cfg.CONF
ENCRYPTED_VOLUME_ID = 'f78e8977-6164-4114-a593-358fa6646eff'
@ddt.ddt @ddt.ddt
@ -775,6 +776,9 @@ def fake_volume_get_obj(self, context, volume_id, **kwargs):
else: else:
volume.status = 'available' volume.status = 'available'
if volume_id == ENCRYPTED_VOLUME_ID:
volume['encryption_key_id'] = 'does_not_matter'
volume.volume_type = fake_volume.fake_volume_type_obj( volume.volume_type = fake_volume.fake_volume_type_obj(
context, context,
name=v2_fakes.DEFAULT_VOL_TYPE) name=v2_fakes.DEFAULT_VOL_TYPE)
@ -884,6 +888,70 @@ class VolumeImageActionsTest(test.TestCase):
'image_name': 'image_name'}} 'image_name': 'image_name'}}
self.assertDictEqual(expected, res_dict) self.assertDictEqual(expected, res_dict)
@mock.patch.object(volume_api.API, 'get', fake_volume_get_obj)
@mock.patch.object(volume_api.API, "copy_volume_to_image")
def test_check_image_metadata_copy_encrypted_volume_to_image(
self, mock_copy_vol):
"""Make sure the encryption image properties exit the controller."""
# all we're interested in is that the 'metadata' dict contains the
# correct data, so we do this bad hack to smuggle it out in the
# controller's response to make it easy to access
def really_fake_upload_volume(context, volume, metadata, force):
return metadata
mock_copy_vol.side_effect = really_fake_upload_volume
FAKE_ID = 'fake-encryption-key-id'
# the controller does a lazy init of the key manager, so we
# need a 2-level mock here
self.mock_object(self.controller, '_key_mgr')
self.controller._key_mgr.return_value = not None
self.mock_object(self.controller._key_manager, 'store')
self.controller._key_manager.store.return_value = FAKE_ID
vol_id = ENCRYPTED_VOLUME_ID
img = {"container_format": 'bare',
"disk_format": 'raw',
"image_name": 'image_name',
"force": True}
body = {"os-volume_upload_image": img}
req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' %
(fake.PROJECT_ID, vol_id))
res_dict = self.controller._volume_upload_image(req, vol_id, body=body)
sent_meta = res_dict['os-volume_upload_image']
self.assertIn('cinder_encryption_key_id', sent_meta)
self.assertEqual(FAKE_ID, sent_meta['cinder_encryption_key_id'])
self.assertIn('cinder_encryption_key_deletion_policy', sent_meta)
self.assertEqual('on_image_deletion',
sent_meta['cinder_encryption_key_deletion_policy'])
@mock.patch.object(volume_api.API, 'get', fake_volume_get_obj)
@mock.patch.object(volume_api.API, "copy_volume_to_image")
def test_check_image_metadata_copy_nonencrypted_volume_to_image(
self, mock_copy_vol):
"""Make sure no encryption image properties are sent."""
def really_fake_upload_volume(context, volume, metadata, force):
return metadata
mock_copy_vol.side_effect = really_fake_upload_volume
id = fake.VOLUME_ID
img = {"container_format": 'bare',
"disk_format": 'raw',
"image_name": 'image_name',
"force": True}
body = {"os-volume_upload_image": img}
req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' %
(fake.PROJECT_ID, id))
res_dict = self.controller._volume_upload_image(req, id, body=body)
sent_meta = res_dict['os-volume_upload_image']
self.assertNotIn('cinder_encryption_key_id', sent_meta)
self.assertNotIn('cinder_encryption_key_deletion_policy', sent_meta)
def test_copy_volume_to_image_volumenotfound(self): def test_copy_volume_to_image_volumenotfound(self):
def fake_volume_get_raise_exc(self, context, volume_id): def fake_volume_get_raise_exc(self, context, volume_id):
raise exception.VolumeNotFound(volume_id=volume_id) raise exception.VolumeNotFound(volume_id=volume_id)