There are encrypted volume tests in Tempest which are passing
in the ceph job but the encryption providers in nova (luks and
cryptsetup) are not actually being called in nova because the
'encrypted' key isn't being set in connection_info for the Rbd
volume driver, and nova is keying off that value to determine
if it needs to run it's encryption providers.
So the tests are passing in the ceph job but it's a total false
positive and the API should actually fail - either the cinder
API to create the encrypted volumes if the Rbd volume driver in
Cinder doesn't support encryption, or the volume attach call in
nova if it can't encrypt the connected volume, either way the
test should fail until that support is baked into nova.
I'm not aware of any kind of 'supports_encryption' or 'encryptable'
capability flag for cinder volume drivers, but that might be
needed for the volume create API to fail if trying to create a
volume from an encrypted volume type where the volume driver
itself doesn't support encryption - but maybe it's only a nova
problem since nova has the encryption providers.
This is fixed generically in the VolumeManager's
initialize_connection method where we check for the encrypted
flag being set in the volume driver method and if not, the
manager sets it based on the volume.encryption_key_id value.
We do this globally since there are other volume drivers besides
rbd that aren't setting the encrypted key in connection_info,
but we test rbd in the gate via the ceph job so most of the
bug tracking is around validation of the ceph job.
Related Nova change: I8efc2628b09d4e9e59831353daa080b20e17ccde
Depends-On: I8548d41095513b9e669f773e3f35353e9228ead9
DocImpact: Attaching 'encrypted' RBD volumes to a Nova server
instance created from the libvirt virt driver will fail
since RBD volume encryption is not currently supported in
Nova's libvirt driver.
Closes-Bug: #
1440227
Related-Bug: #
1463525
Change-Id: I03f8cae05cc117e14f7482115de685fc9f3fa54a
'name': 'fake_name',
'host': 'fake_host',
'id': 'fake_volume_id',
- 'volume_admin_metadata': fake_admin_meta}
+ 'volume_admin_metadata': fake_admin_meta,
+ 'encryption_key_id': ('d371e7bb-7392-4c27-'
+ 'ac0b-ebd9f5d16078')}
mock_volume_get.return_value = fake_volume
mock_volume_update.return_value = fake_volume
connector = {'ip': 'IP', 'initiator': 'INITIATOR'}
mock_driver_init.return_value = {
'driver_volume_type': 'iscsi',
- 'data': {'access_mode': 'rw'}
+ 'data': {'access_mode': 'rw',
+ 'encrypted': False}
}
mock_data_get.return_value = []
- self.volume.initialize_connection(self.context, 'id', connector)
+ conn_info = self.volume.initialize_connection(self.context, 'id',
+ connector)
+ # Asserts that if the driver sets the encrypted flag then the
+ # VolumeManager doesn't overwrite it regardless of what's in the
+ # volume for the encryption_key_id field.
+ self.assertFalse(conn_info['data']['encrypted'])
mock_driver_init.assert_called_with(fake_volume, connector)
data = [{'key': 'key1', 'value': 'value1'}]
connector['initiator'] = None
mock_data_update.reset_mock()
mock_data_get.reset_mock()
- self.volume.initialize_connection(self.context, 'id', connector)
+ mock_driver_init.return_value['data'].pop('encrypted')
+ conn_info = self.volume.initialize_connection(self.context, 'id',
+ connector)
+ # Asserts that VolumeManager sets the encrypted flag if the driver
+ # doesn't set it.
+ self.assertTrue(conn_info['data']['encrypted'])
mock_driver_init.assert_called_with(fake_volume, connector)
self.assertFalse(mock_data_get.called)
self.assertFalse(mock_data_update.called)
else 'rw')
conn_info['data']['access_mode'] = access_mode
+ # Add encrypted flag to connection_info if not set in the driver.
+ if conn_info['data'].get('encrypted') is None:
+ encrypted = bool(volume.get('encryption_key_id'))
+ conn_info['data']['encrypted'] = encrypted
+
LOG.info(_LI("Initialize volume connection completed successfully."),
resource=volume)
return conn_info