Add hw_ephemeral_encryption_secret_uuid image property

If an image is encrypted, we will need to retrieve the passphrase from
the key manager service in order to create an instance from it.

This adds an image property to store the secret UUID that belongs to
the image. It will only be used to decrypt the image and will not be
used to encrypt or decrypt any other image. Nova will create a new
secret for each disk image it creates, including snapshots.

Related to blueprint ephemeral-storage-encryption

Change-Id: I01eef6adc2c8feb64e86b33392b8b4b483041e27
This commit is contained in:
melanie witt 2022-12-09 22:57:43 +00:00
parent 9f7a6732f9
commit 740d5bb531
4 changed files with 33 additions and 6 deletions

View File

@ -133,9 +133,6 @@ class ImageMetaPropsPayload(base.NotificationPayloadBase):
# Version 1.13: Added 'hw_virtio_packed_ring' field # Version 1.13: Added 'hw_virtio_packed_ring' field
VERSION = '1.13' VERSION = '1.13'
SCHEMA = {
k: ('image_meta_props', k) for k in image_meta.ImageMetaProps.fields}
# NOTE(efried): This logic currently relies on all of the fields of # NOTE(efried): This logic currently relies on all of the fields of
# ImageMetaProps being initialized with no arguments. See the docstring. # ImageMetaProps being initialized with no arguments. See the docstring.
# NOTE(efried): It's possible this could just be: # NOTE(efried): It's possible this could just be:
@ -143,7 +140,11 @@ class ImageMetaPropsPayload(base.NotificationPayloadBase):
# But it is not clear that OVO can tolerate the same *instance* of a type # But it is not clear that OVO can tolerate the same *instance* of a type
# class being used in more than one place. # class being used in more than one place.
fields = { fields = {
k: v.__class__() for k, v in image_meta.ImageMetaProps.fields.items()} k: v.__class__() for k, v in image_meta.ImageMetaProps.fields.items()
if k not in ('hw_ephemeral_encryption_secret_uuid',)}
SCHEMA = {
k: ('image_meta_props', k) for k in fields}
def __init__(self, image_meta_props): def __init__(self, image_meta_props):
super(ImageMetaPropsPayload, self).__init__() super(ImageMetaPropsPayload, self).__init__()

View File

@ -195,14 +195,17 @@ class ImageMetaProps(base.NovaObject):
# Version 1.35: Added 'hw_virtio_packed_ring' field # Version 1.35: Added 'hw_virtio_packed_ring' field
# Version 1.36: Added 'hw_maxphysaddr_mode' and # Version 1.36: Added 'hw_maxphysaddr_mode' and
# 'hw_maxphysaddr_bits' field # 'hw_maxphysaddr_bits' field
# Version 1.37: Added 'hw_ephemeral_encryption_secret_uuid' field
# NOTE(efried): When bumping this version, the version of # NOTE(efried): When bumping this version, the version of
# ImageMetaPropsPayload must also be bumped. See its docstring for details. # ImageMetaPropsPayload must also be bumped. See its docstring for details.
VERSION = '1.36' VERSION = '1.37'
def obj_make_compatible(self, primitive, target_version): def obj_make_compatible(self, primitive, target_version):
super(ImageMetaProps, self).obj_make_compatible(primitive, super(ImageMetaProps, self).obj_make_compatible(primitive,
target_version) target_version)
target_version = versionutils.convert_version_to_tuple(target_version) target_version = versionutils.convert_version_to_tuple(target_version)
if target_version < (1, 37):
primitive.pop('hw_ephemeral_encryption_secret_uuid', None)
if target_version < (1, 36): if target_version < (1, 36):
primitive.pop('hw_maxphysaddr_mode', None) primitive.pop('hw_maxphysaddr_mode', None)
primitive.pop('hw_maxphysaddr_bits', None) primitive.pop('hw_maxphysaddr_bits', None)
@ -480,6 +483,8 @@ class ImageMetaProps(base.NovaObject):
# encryption format to be used when ephemeral encryption is enabled # encryption format to be used when ephemeral encryption is enabled
'hw_ephemeral_encryption_format': 'hw_ephemeral_encryption_format':
fields.BlockDeviceEncryptionFormatTypeField(), fields.BlockDeviceEncryptionFormatTypeField(),
# encryption secret uuid string for passphrase in the image
'hw_ephemeral_encryption_secret_uuid': fields.UUIDField(),
# boolean - If true, this will enable the virtio packed ring feature # boolean - If true, this will enable the virtio packed ring feature
'hw_virtio_packed_ring': fields.FlexibleBooleanField(), 'hw_virtio_packed_ring': fields.FlexibleBooleanField(),

View File

@ -14,6 +14,8 @@
import datetime import datetime
from oslo_utils.fixture import uuidsentinel as uuids
from nova import exception from nova import exception
from nova import objects from nova import objects
from nova.objects import fields from nova.objects import fields
@ -570,3 +572,22 @@ class TestImageMetaProps(test.NoDBTestCase):
# and is absent on older versions # and is absent on older versions
primitive = obj.obj_to_primitive('1.33') primitive = obj.obj_to_primitive('1.33')
self.assertNotIn('hw_viommu_model', primitive['nova_object.data']) self.assertNotIn('hw_viommu_model', primitive['nova_object.data'])
def test_obj_make_compatible_ephemeral_encryption_secret_uuid(self):
"""Check 'hw_ephemeral_encryption_secret_uuid' compatibility."""
obj = objects.ImageMetaProps(
hw_ephemeral_encryption_secret_uuid=uuids.secret)
primitive = obj.obj_to_primitive('1.37')
self.assertIn(
'hw_ephemeral_encryption_secret_uuid',
primitive['nova_object.data'])
self.assertEqual(
uuids.secret,
primitive[
'nova_object.data']['hw_ephemeral_encryption_secret_uuid'])
primitive = obj.obj_to_primitive('1.36')
self.assertNotIn(
'hw_ephemeral_encryption_secret_uuid',
primitive['nova_object.data'])

View File

@ -1105,7 +1105,7 @@ object_data = {
'HyperVLiveMigrateData': '1.4-e265780e6acfa631476c8170e8d6fce0', 'HyperVLiveMigrateData': '1.4-e265780e6acfa631476c8170e8d6fce0',
'IDEDeviceBus': '1.0-29d4c9f27ac44197f01b6ac1b7e16502', 'IDEDeviceBus': '1.0-29d4c9f27ac44197f01b6ac1b7e16502',
'ImageMeta': '1.8-642d1b2eb3e880a367f37d72dd76162d', 'ImageMeta': '1.8-642d1b2eb3e880a367f37d72dd76162d',
'ImageMetaProps': '1.36-5d06cd527d8d32e6e2b457ce3b9369e0', 'ImageMetaProps': '1.37-1e0d70fb51041c0446b00695c5ef0e21',
'Instance': '2.8-2727dba5e4a078e6cc848c1f94f7eb24', 'Instance': '2.8-2727dba5e4a078e6cc848c1f94f7eb24',
'InstanceAction': '1.2-9a5abc87fdd3af46f45731960651efb5', 'InstanceAction': '1.2-9a5abc87fdd3af46f45731960651efb5',
'InstanceActionEvent': '1.4-5b1f361bd81989f8bb2c20bb7e8a4cb4', 'InstanceActionEvent': '1.4-5b1f361bd81989f8bb2c20bb7e8a4cb4',