Add encryption_key_id to volume and backup details
Add microversion 3.64 for including the encryption_key_id in the volume and backup details when the associated volume is encrypted. This facilitates associating encryption keys (typically stored in Barbican) with the volume or backup that uses it. The encryption_key_id is included in the details only when the associated volume is encrypted, and it isn't using the all-zeros key ID used by the legacy fixed-key ConfKeyMgr. APIImpact DocImpact Implements: blueprint include-encryption-key-id-in-details Change-Id: I16f54e6722cdbcbad4af1eb0d30264b0039412fd
This commit is contained in:
parent
876ac4e79f
commit
f91aec5869
@ -98,6 +98,7 @@ Response Parameters
|
||||
- count: count
|
||||
- metadata: metadata_backup
|
||||
- user_id: user_id_backup
|
||||
- encryption_key_id: encryption_key_id
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
@ -157,6 +158,7 @@ Response Parameters
|
||||
- os-backup-project-attr:project_id: os-backup-project-attr:project_id
|
||||
- metadata: metadata_backup
|
||||
- user_id: user_id_backup
|
||||
- encryption_key_id: encryption_key_id
|
||||
|
||||
Response Example
|
||||
----------------
|
||||
|
@ -1140,6 +1140,12 @@ encryption_id_body:
|
||||
in: body
|
||||
required: true
|
||||
type: string
|
||||
encryption_key_id:
|
||||
description: |
|
||||
The UUID of the encryption key.
|
||||
in: body
|
||||
required: false
|
||||
type: string
|
||||
event_id:
|
||||
description: |
|
||||
The id of the event to this message, this id could
|
||||
|
@ -21,8 +21,8 @@
|
||||
],
|
||||
"min_version": "3.0",
|
||||
"status": "CURRENT",
|
||||
"updated": "2020-11-19T08:56:00Z",
|
||||
"version": "3.63"
|
||||
"updated": "2021-02-03T00:00:00Z",
|
||||
"version": "3.64"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -45,8 +45,8 @@
|
||||
],
|
||||
"min_version": "3.0",
|
||||
"status": "CURRENT",
|
||||
"updated": "2020-11-19T08:56:00Z",
|
||||
"version": "3.63"
|
||||
"updated": "2021-02-03T00:00:00Z",
|
||||
"version": "3.64"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -109,6 +109,7 @@ Response Parameters
|
||||
- availability_zone: availability_zone
|
||||
- os-vol-host-attr:host: os-vol-host-attr:host
|
||||
- encrypted: encrypted
|
||||
- encryption_key_id: encryption_key_id
|
||||
- updated_at: updated_at
|
||||
- replication_status: replication_status
|
||||
- snapshot_id: snapshot_id
|
||||
@ -355,6 +356,7 @@ Response Parameters
|
||||
- availability_zone: availability_zone
|
||||
- os-vol-host-attr:host: os-vol-host-attr:host
|
||||
- encrypted: encrypted
|
||||
- encryption_key_id: encryption_key_id
|
||||
- updated_at: updated_at
|
||||
- replication_status: replication_status
|
||||
- snapshot_id: snapshot_id
|
||||
|
@ -167,6 +167,8 @@ DEFAULT_TYPE_OVERRIDES = '3.62'
|
||||
|
||||
VOLUME_TYPE_ID_IN_VOLUME_DETAIL = '3.63'
|
||||
|
||||
ENCRYPTION_KEY_ID_IN_DETAILS = '3.64'
|
||||
|
||||
|
||||
def get_mv_header(version):
|
||||
"""Gets a formatted HTTP microversion header.
|
||||
|
@ -147,6 +147,7 @@ REST_API_VERSION_HISTORY = """
|
||||
in the volume details. This MV affects the volume detail list
|
||||
("GET /v3/{project_id}/volumes/detail") and volume-show
|
||||
("GET /v3/{project_id}/volumes/{volume_id}") calls.
|
||||
* 3.64 - Include 'encryption_key_id' in volume and backup details
|
||||
"""
|
||||
|
||||
# The minimum and maximum versions of the API supported
|
||||
@ -154,9 +155,9 @@ REST_API_VERSION_HISTORY = """
|
||||
# minimum version of the API supported.
|
||||
# Explicitly using /v2 endpoints will still work
|
||||
_MIN_API_VERSION = "3.0"
|
||||
_MAX_API_VERSION = "3.63"
|
||||
_MAX_API_VERSION = "3.64"
|
||||
_LEGACY_API_VERSION2 = "2.0"
|
||||
UPDATED = "2020-11-19T08:56:00Z"
|
||||
UPDATED = "2021-02-03T00:00:00Z"
|
||||
|
||||
|
||||
# NOTE(cyeoh): min and max versions declared as functions so we can
|
||||
|
@ -485,3 +485,8 @@ value.
|
||||
Includes volume type ID in the volume-show and volume-detail-list JSON
|
||||
responses. Before this microversion, Cinder returns only the volume type name
|
||||
in the volume details.
|
||||
|
||||
3.64
|
||||
----
|
||||
Include the ``encryption_key_id`` in volume and backup details when the
|
||||
associated volume is encrypted.
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.views import backups as views_v2
|
||||
from cinder.common import constants as cinder_constants
|
||||
|
||||
|
||||
class ViewBuilder(views_v2.ViewBuilder):
|
||||
@ -29,4 +30,11 @@ class ViewBuilder(views_v2.ViewBuilder):
|
||||
req_version = request.api_version_request
|
||||
if req_version.matches(mv.BACKUP_METADATA):
|
||||
backup_ref['backup']['metadata'] = backup.metadata
|
||||
|
||||
if req_version.matches(mv.ENCRYPTION_KEY_ID_IN_DETAILS, None):
|
||||
encryption_key_id = backup.get('encryption_key_id', None)
|
||||
if (encryption_key_id and
|
||||
encryption_key_id != cinder_constants.FIXED_KEY_ID):
|
||||
backup_ref['backup']['encryption_key_id'] = encryption_key_id
|
||||
|
||||
return backup_ref
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v2.views import volumes as views_v2
|
||||
from cinder.common import constants as cinder_constants
|
||||
|
||||
|
||||
class ViewBuilder(views_v2.ViewBuilder):
|
||||
@ -70,6 +71,12 @@ class ViewBuilder(views_v2.ViewBuilder):
|
||||
volume_ref[
|
||||
'volume']["volume_type_id"] = volume['volume_type'].get('id')
|
||||
|
||||
if req_version.matches(mv.ENCRYPTION_KEY_ID_IN_DETAILS, None):
|
||||
encryption_key_id = volume.get('encryption_key_id', None)
|
||||
if (encryption_key_id and
|
||||
encryption_key_id != cinder_constants.FIXED_KEY_ID):
|
||||
volume_ref['volume']['encryption_key_id'] = encryption_key_id
|
||||
|
||||
return volume_ref
|
||||
|
||||
def _list_view(self, func, request, volumes, volume_count,
|
||||
|
@ -26,3 +26,6 @@ SCHEDULER_TOPIC = SCHEDULER_BINARY
|
||||
VOLUME_TOPIC = VOLUME_BINARY
|
||||
BACKUP_TOPIC = BACKUP_BINARY
|
||||
LOG_BINARIES = (SCHEDULER_BINARY, VOLUME_BINARY, BACKUP_BINARY, API_BINARY)
|
||||
|
||||
# The encryption key ID used by the legacy fixed-key ConfKeyMgr
|
||||
FIXED_KEY_ID = '00000000-0000-0000-0000-000000000000'
|
||||
|
@ -32,6 +32,7 @@ from cinder import context
|
||||
from cinder import exception
|
||||
from cinder.objects import fields
|
||||
from cinder.tests.unit.api import fakes
|
||||
from cinder.tests.unit.api.v3.test_volumes import ENCRYPTION_KEY_ID_IN_DETAILS
|
||||
from cinder.tests.unit import fake_constants as fake
|
||||
from cinder.tests.unit import test
|
||||
from cinder.tests.unit import utils as test_utils
|
||||
@ -286,6 +287,25 @@ class BackupsControllerAPITestCase(test.TestCase):
|
||||
else:
|
||||
self.assertIn('metadata', backup_get)
|
||||
|
||||
@ddt.data(*ENCRYPTION_KEY_ID_IN_DETAILS)
|
||||
@ddt.unpack
|
||||
def test_backup_show_with_encryption_key_id(self,
|
||||
expected_in_details,
|
||||
encryption_key_id,
|
||||
version):
|
||||
backup = test_utils.create_backup(self.ctxt,
|
||||
encryption_key_id=encryption_key_id)
|
||||
self.addCleanup(backup.destroy)
|
||||
|
||||
url = '/v3/%s/backups/%s' % (fake.PROJECT_ID, backup.id)
|
||||
req = fakes.HTTPRequest.blank(url, version=version)
|
||||
backup_details = self.controller.show(req, backup.id)['backup']
|
||||
|
||||
if expected_in_details:
|
||||
self.assertIn('encryption_key_id', backup_details)
|
||||
else:
|
||||
self.assertNotIn('encryption_key_id', backup_details)
|
||||
|
||||
def test_backup_update_with_null_validate(self):
|
||||
backup = test_utils.create_backup(
|
||||
self.ctxt,
|
||||
|
@ -31,6 +31,7 @@ from cinder.api import microversions as mv
|
||||
from cinder.api.v2.views.volumes import ViewBuilder
|
||||
from cinder.api.v3 import volumes
|
||||
from cinder.backup import api as backup_api
|
||||
from cinder.common import constants as cinder_constants
|
||||
from cinder import context
|
||||
from cinder import db
|
||||
from cinder import exception
|
||||
@ -50,6 +51,29 @@ from cinder.volume import api as vol_get
|
||||
|
||||
DEFAULT_AZ = "zone1:host1"
|
||||
|
||||
# DDT data for testing whether an 'encryption_key_id' should appear in a
|
||||
# volume's or backup's details (also used by test_backups.py).
|
||||
ENCRYPTION_KEY_ID_IN_DETAILS = {
|
||||
'expected_in_details': True,
|
||||
'encryption_key_id': fake.ENCRYPTION_KEY_ID,
|
||||
'version': mv.ENCRYPTION_KEY_ID_IN_DETAILS,
|
||||
}, {
|
||||
# No encryption ID to display
|
||||
'expected_in_details': False,
|
||||
'encryption_key_id': None,
|
||||
'version': mv.ENCRYPTION_KEY_ID_IN_DETAILS,
|
||||
}, {
|
||||
# Fixed key ID should not be displayed
|
||||
'expected_in_details': False,
|
||||
'encryption_key_id': cinder_constants.FIXED_KEY_ID,
|
||||
'version': mv.ENCRYPTION_KEY_ID_IN_DETAILS,
|
||||
}, {
|
||||
# Unsupported microversion
|
||||
'expected_in_details': False,
|
||||
'encryption_key_id': fake.ENCRYPTION_KEY_ID,
|
||||
'version': mv.get_prior_version(mv.ENCRYPTION_KEY_ID_IN_DETAILS),
|
||||
}
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class VolumeApiTest(test.TestCase):
|
||||
@ -856,6 +880,26 @@ class VolumeApiTest(test.TestCase):
|
||||
else:
|
||||
self.assertNotIn('provider_id', res_dict['volume'])
|
||||
|
||||
@ddt.data(*ENCRYPTION_KEY_ID_IN_DETAILS)
|
||||
@ddt.unpack
|
||||
def test_volume_show_with_encryption_key_id(self,
|
||||
expected_in_details,
|
||||
encryption_key_id,
|
||||
version):
|
||||
volume = test_utils.create_volume(self.ctxt,
|
||||
testcase_instance=self,
|
||||
volume_type_id=None,
|
||||
encryption_key_id=encryption_key_id)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v3/volumes/%s' % volume.id,
|
||||
version=version)
|
||||
volume_details = self.controller.show(req, volume.id)['volume']
|
||||
|
||||
if expected_in_details:
|
||||
self.assertIn('encryption_key_id', volume_details)
|
||||
else:
|
||||
self.assertNotIn('encryption_key_id', volume_details)
|
||||
|
||||
def _fake_create_volume(self, size=1):
|
||||
vol = {
|
||||
'display_name': 'fake_volume1',
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Starting with API microversion 3.64, an ``encryption_key_id`` attribute
|
||||
is included in the response body of volume and backup details when the
|
||||
associated volume is encrypted.
|
Loading…
Reference in New Issue
Block a user