Merge "Add encryption_key_id to volume and backup details"
This commit is contained in:
commit
45217bfd9e
@ -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
|
||||
----------------
|
||||
|
@ -1130,6 +1130,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