Prevent creating encrypted volume with image
When creating an encrypted volume with a unencrypted image, cinder just copies the unencrypted data to the volume, which keeps unencrypted data in the volume. But when booting/attaching the volume to Nova, it thinks encrypted data on the volume. As a result, Nova reads the data incorrectly. The fix is to prevent such action. Later, we can implement to write encrypted data in encrypted volumes when creating from unencrypted image. Change-Id: I0af8318222cee023451c38812bf83cdb4086faae Closes-bug: #1482464
This commit is contained in:
parent
690f1b24eb
commit
19d5610f93
|
@ -21,6 +21,8 @@ from cinder import exception
|
|||
from cinder import test
|
||||
from cinder.tests.unit import fake_snapshot
|
||||
from cinder.tests.unit import fake_volume
|
||||
from cinder.tests.unit.image import fake as fake_image
|
||||
from cinder.tests.unit.keymgr import mock_key_mgr
|
||||
from cinder.tests.unit.volume.flows import fake_volume_api
|
||||
from cinder.volume.flows.api import create_volume
|
||||
from cinder.volume.flows.manager import create_volume as create_volume_manager
|
||||
|
@ -77,6 +79,97 @@ class CreateVolumeFlowTestCase(test.TestCase):
|
|||
|
||||
task._cast_create_volume(self.ctxt, spec, props)
|
||||
|
||||
@mock.patch('cinder.volume.volume_types.is_encrypted')
|
||||
@mock.patch('cinder.volume.flows.api.create_volume.'
|
||||
'ExtractVolumeRequestTask.'
|
||||
'_get_volume_type_id')
|
||||
def test_extract_volume_request_from_image_encrypted(
|
||||
self,
|
||||
fake_get_volume_type_id,
|
||||
fake_is_encrypted):
|
||||
|
||||
fake_image_service = fake_image.FakeImageService()
|
||||
image_id = 1
|
||||
image_meta = {}
|
||||
image_meta['id'] = image_id
|
||||
image_meta['status'] = 'active'
|
||||
image_meta['size'] = 1
|
||||
fake_image_service.create(self.ctxt, image_meta)
|
||||
fake_key_manager = mock_key_mgr.MockKeyManager()
|
||||
|
||||
task = create_volume.ExtractVolumeRequestTask(
|
||||
fake_image_service,
|
||||
{'nova'})
|
||||
|
||||
fake_is_encrypted.return_value = True
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
task.execute,
|
||||
self.ctxt,
|
||||
size=1,
|
||||
snapshot=None,
|
||||
image_id=image_id,
|
||||
source_volume=None,
|
||||
availability_zone='nova',
|
||||
volume_type=None,
|
||||
metadata=None,
|
||||
key_manager=fake_key_manager,
|
||||
source_replica=None,
|
||||
consistencygroup=None,
|
||||
cgsnapshot=None)
|
||||
|
||||
@mock.patch('cinder.volume.volume_types.is_encrypted')
|
||||
@mock.patch('cinder.volume.volume_types.get_volume_type_qos_specs')
|
||||
@mock.patch('cinder.volume.flows.api.create_volume.'
|
||||
'ExtractVolumeRequestTask.'
|
||||
'_get_volume_type_id')
|
||||
def test_extract_volume_request_from_image(
|
||||
self,
|
||||
fake_get_type_id,
|
||||
fake_get_qos,
|
||||
fake_is_encrypted):
|
||||
|
||||
fake_image_service = fake_image.FakeImageService()
|
||||
image_id = 2
|
||||
image_meta = {}
|
||||
image_meta['id'] = image_id
|
||||
image_meta['status'] = 'active'
|
||||
image_meta['size'] = 1
|
||||
fake_image_service.create(self.ctxt, image_meta)
|
||||
fake_key_manager = mock_key_mgr.MockKeyManager()
|
||||
volume_type = 'type1'
|
||||
|
||||
task = create_volume.ExtractVolumeRequestTask(
|
||||
fake_image_service,
|
||||
{'nova'})
|
||||
|
||||
fake_is_encrypted.return_value = False
|
||||
fake_get_type_id.return_value = 1
|
||||
fake_get_qos.return_value = {'qos_specs': None}
|
||||
result = task.execute(self.ctxt,
|
||||
size=1,
|
||||
snapshot=None,
|
||||
image_id=image_id,
|
||||
source_volume=None,
|
||||
availability_zone='nova',
|
||||
volume_type=volume_type,
|
||||
metadata=None,
|
||||
key_manager=fake_key_manager,
|
||||
source_replica=None,
|
||||
consistencygroup=None,
|
||||
cgsnapshot=None)
|
||||
expected_result = {'size': 1,
|
||||
'snapshot_id': None,
|
||||
'source_volid': None,
|
||||
'availability_zone': 'nova',
|
||||
'volume_type': volume_type,
|
||||
'volume_type_id': 1,
|
||||
'encryption_key_id': None,
|
||||
'qos_specs': None,
|
||||
'source_replicaid': None,
|
||||
'consistencygroup_id': None,
|
||||
'cgsnapshot_id': None, }
|
||||
self.assertEqual(expected_result, result)
|
||||
|
||||
|
||||
class CreateVolumeFlowManagerTestCase(test.TestCase):
|
||||
|
||||
|
|
|
@ -382,6 +382,13 @@ class ExtractVolumeRequestTask(flow_utils.CinderTask):
|
|||
volume_type_id = self._get_volume_type_id(volume_type,
|
||||
source_volume, snapshot)
|
||||
|
||||
if image_id and volume_types.is_encrypted(context, volume_type_id):
|
||||
msg = _('Create encrypted volumes with type %(type)s '
|
||||
'from image %(image)s is not supported.')
|
||||
msg = msg % {'type': volume_type_id,
|
||||
'image': image_id, }
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
|
||||
encryption_key_id = self._get_encryption_key_id(key_manager,
|
||||
context,
|
||||
volume_type_id,
|
||||
|
|
Loading…
Reference in New Issue