From c49fce3909a1705855ee2b91a82c39830fe17edd Mon Sep 17 00:00:00 2001 From: Ankit Agrawal Date: Sun, 13 Dec 2015 23:48:33 -0800 Subject: [PATCH] Add request_ids attribute to resource objects Added request_ids attribute to resource object for all the volume_backups, volume_encryption_types and volume_transfers APIs by updating following APIs: volume_backups: reset_state, delete, export_record, import_record volume_transfers: delete volume_encryption_types: list Returning list with request_ids as attribute in case of 'list' API for volume_encryption_types. These changes are required to return 'request_id' from client to log request_id mappings of cross projects. For more details on how request_id will be returned to the caller, please refer to the approved blueprint [1] discussed with the cross-project team. [1] http://specs.openstack.org/openstack/openstack-specs/specs/return-request-id.html DocImpact 'request-ids' will be returned as an attribute with response object. User can access it using 'res.request_ids' where 'res' is a response object. Change-Id: I2197ca38f6c9a8b0ced5c82d29676b49c9700b09 Partial-Implements: blueprint return-request-id-to-caller --- .../tests/unit/v2/test_volume_backups.py | 57 ++++++++++++------- .../unit/v2/test_volume_encryption_types.py | 6 ++ .../tests/unit/v2/test_volume_transfers.py | 23 +++++--- cinderclient/v2/volume_backups.py | 12 ++-- cinderclient/v2/volume_encryption_types.py | 7 ++- cinderclient/v2/volume_transfers.py | 2 +- 6 files changed, 72 insertions(+), 35 deletions(-) diff --git a/cinderclient/tests/unit/v2/test_volume_backups.py b/cinderclient/tests/unit/v2/test_volume_backups.py index 7f72c63..4cdd8ae 100644 --- a/cinderclient/tests/unit/v2/test_volume_backups.py +++ b/cinderclient/tests/unit/v2/test_volume_backups.py @@ -24,23 +24,27 @@ cs = fakes.FakeClient() class VolumeBackupsTest(utils.TestCase): def test_create(self): - cs.backups.create('2b695faf-b963-40c8-8464-274008fbcef4') + vol = cs.backups.create('2b695faf-b963-40c8-8464-274008fbcef4') cs.assert_called('POST', '/backups') + self._assert_request_id(vol) def test_create_full(self): - cs.backups.create('2b695faf-b963-40c8-8464-274008fbcef4', - None, None, False) + vol = cs.backups.create('2b695faf-b963-40c8-8464-274008fbcef4', + None, None, False) cs.assert_called('POST', '/backups') + self._assert_request_id(vol) def test_create_incremental(self): - cs.backups.create('2b695faf-b963-40c8-8464-274008fbcef4', - None, None, True) + vol = cs.backups.create('2b695faf-b963-40c8-8464-274008fbcef4', + None, None, True) cs.assert_called('POST', '/backups') + self._assert_request_id(vol) def test_create_force(self): - cs.backups.create('2b695faf-b963-40c8-8464-274008fbcef4', - None, None, False, True) + vol = cs.backups.create('2b695faf-b963-40c8-8464-274008fbcef4', + None, None, False, True) cs.assert_called('POST', '/backups') + self._assert_request_id(vol) def test_create_snapshot(self): cs.backups.create('2b695faf-b963-40c8-8464-274008fbcef4', @@ -50,32 +54,39 @@ class VolumeBackupsTest(utils.TestCase): def test_get(self): backup_id = '76a17945-3c6f-435c-975b-b5685db10b62' - cs.backups.get(backup_id) + back = cs.backups.get(backup_id) cs.assert_called('GET', '/backups/%s' % backup_id) + self._assert_request_id(back) def test_list(self): - cs.backups.list() + lst = cs.backups.list() cs.assert_called('GET', '/backups/detail') + self._assert_request_id(lst) def test_list_with_pagination(self): - cs.backups.list(limit=2, marker=100) + lst = cs.backups.list(limit=2, marker=100) cs.assert_called('GET', '/backups/detail?limit=2&marker=100') + self._assert_request_id(lst) def test_sorted_list(self): - cs.backups.list(sort="id") + lst = cs.backups.list(sort="id") cs.assert_called('GET', '/backups/detail?sort=id') + self._assert_request_id(lst) def test_delete(self): b = cs.backups.list()[0] - b.delete() + del_back = b.delete() cs.assert_called('DELETE', '/backups/76a17945-3c6f-435c-975b-b5685db10b62') - cs.backups.delete('76a17945-3c6f-435c-975b-b5685db10b62') + self._assert_request_id(del_back) + del_back = cs.backups.delete('76a17945-3c6f-435c-975b-b5685db10b62') cs.assert_called('DELETE', '/backups/76a17945-3c6f-435c-975b-b5685db10b62') - cs.backups.delete(b) + self._assert_request_id(del_back) + del_back = cs.backups.delete(b) cs.assert_called('DELETE', '/backups/76a17945-3c6f-435c-975b-b5685db10b62') + self._assert_request_id(del_back) def test_restore(self): backup_id = '76a17945-3c6f-435c-975b-b5685db10b62' @@ -83,28 +94,34 @@ class VolumeBackupsTest(utils.TestCase): cs.assert_called('POST', '/backups/%s/restore' % backup_id) self.assertIsInstance(info, volume_backups_restore.VolumeBackupsRestore) + self._assert_request_id(info) def test_reset_state(self): b = cs.backups.list()[0] api = '/backups/76a17945-3c6f-435c-975b-b5685db10b62/action' - b.reset_state(state='error') + st = b.reset_state(state='error') cs.assert_called('POST', api) - cs.backups.reset_state('76a17945-3c6f-435c-975b-b5685db10b62', - state='error') + self._assert_request_id(st) + st = cs.backups.reset_state('76a17945-3c6f-435c-975b-b5685db10b62', + state='error') cs.assert_called('POST', api) - cs.backups.reset_state(b, state='error') + self._assert_request_id(st) + st = cs.backups.reset_state(b, state='error') cs.assert_called('POST', api) + self._assert_request_id(st) def test_record_export(self): backup_id = '76a17945-3c6f-435c-975b-b5685db10b62' - cs.backups.export_record(backup_id) + export = cs.backups.export_record(backup_id) cs.assert_called('GET', '/backups/%s/export_record' % backup_id) + self._assert_request_id(export) def test_record_import(self): backup_service = 'fake-backup-service' backup_url = 'fake-backup-url' expected_body = {'backup-record': {'backup_service': backup_service, 'backup_url': backup_url}} - cs.backups.import_record(backup_service, backup_url) + impt = cs.backups.import_record(backup_service, backup_url) cs.assert_called('POST', '/backups/import_record', expected_body) + self._assert_request_id(impt) diff --git a/cinderclient/tests/unit/v2/test_volume_encryption_types.py b/cinderclient/tests/unit/v2/test_volume_encryption_types.py index b1baf98..ca6ceda 100644 --- a/cinderclient/tests/unit/v2/test_volume_encryption_types.py +++ b/cinderclient/tests/unit/v2/test_volume_encryption_types.py @@ -41,6 +41,7 @@ class VolumeEncryptionTypesTest(utils.TestCase): cs.assert_called_anytime('GET', '/types/1/encryption') for encryption_type in encryption_types: self.assertIsInstance(encryption_type, VolumeEncryptionType) + self._assert_request_id(encryption_type) def test_get(self): """ @@ -53,6 +54,7 @@ class VolumeEncryptionTypesTest(utils.TestCase): encryption_type = cs.volume_encryption_types.get(1) cs.assert_called('GET', '/types/1/encryption') self.assertIsInstance(encryption_type, VolumeEncryptionType) + self._assert_request_id(encryption_type) def test_get_no_encryption(self): """ @@ -65,6 +67,7 @@ class VolumeEncryptionTypesTest(utils.TestCase): self.assertIsInstance(encryption_type, VolumeEncryptionType) self.assertFalse(hasattr(encryption_type, 'id'), 'encryption type has an id') + self._assert_request_id(encryption_type) def test_create(self): """ @@ -80,6 +83,7 @@ class VolumeEncryptionTypesTest(utils.TestCase): None}) cs.assert_called('POST', '/types/2/encryption') self.assertIsInstance(result, VolumeEncryptionType) + self._assert_request_id(result) def test_update(self): """ @@ -96,6 +100,7 @@ class VolumeEncryptionTypesTest(utils.TestCase): cs.assert_called('PUT', '/types/1/encryption/provider') self.assertEqual(expected, result, "empty update must yield original data") + self._assert_request_id(result) def test_delete(self): """ @@ -108,3 +113,4 @@ class VolumeEncryptionTypesTest(utils.TestCase): cs.assert_called('DELETE', '/types/1/encryption/provider') self.assertIsInstance(result, tuple) self.assertEqual(202, result[0].status_code) + self._assert_request_id(result) diff --git a/cinderclient/tests/unit/v2/test_volume_transfers.py b/cinderclient/tests/unit/v2/test_volume_transfers.py index 4b27cb3..a265cf5 100644 --- a/cinderclient/tests/unit/v2/test_volume_transfers.py +++ b/cinderclient/tests/unit/v2/test_volume_transfers.py @@ -14,7 +14,7 @@ # under the License. from cinderclient.tests.unit import utils -from cinderclient.tests.unit.v1 import fakes +from cinderclient.tests.unit.v2 import fakes cs = fakes.FakeClient() @@ -23,29 +23,36 @@ cs = fakes.FakeClient() class VolumeTransfersTest(utils.TestCase): def test_create(self): - cs.transfers.create('1234') + vol = cs.transfers.create('1234') cs.assert_called('POST', '/os-volume-transfer') + self._assert_request_id(vol) def test_get(self): transfer_id = '5678' - cs.transfers.get(transfer_id) + vol = cs.transfers.get(transfer_id) cs.assert_called('GET', '/os-volume-transfer/%s' % transfer_id) + self._assert_request_id(vol) def test_list(self): - cs.transfers.list() + lst = cs.transfers.list() cs.assert_called('GET', '/os-volume-transfer/detail') + self._assert_request_id(lst) def test_delete(self): b = cs.transfers.list()[0] - b.delete() + vol = b.delete() cs.assert_called('DELETE', '/os-volume-transfer/5678') - cs.transfers.delete('5678') + self._assert_request_id(vol) + vol = cs.transfers.delete('5678') + self._assert_request_id(vol) cs.assert_called('DELETE', '/os-volume-transfer/5678') - cs.transfers.delete(b) + vol = cs.transfers.delete(b) cs.assert_called('DELETE', '/os-volume-transfer/5678') + self._assert_request_id(vol) def test_accept(self): transfer_id = '5678' auth_key = '12345' - cs.transfers.accept(transfer_id, auth_key) + vol = cs.transfers.accept(transfer_id, auth_key) cs.assert_called('POST', '/os-volume-transfer/%s/accept' % transfer_id) + self._assert_request_id(vol) diff --git a/cinderclient/v2/volume_backups.py b/cinderclient/v2/volume_backups.py index fc653c8..784aad7 100644 --- a/cinderclient/v2/volume_backups.py +++ b/cinderclient/v2/volume_backups.py @@ -17,6 +17,7 @@ Volume Backups interface (1.1 extension). """ from cinderclient import base +from cinderclient.openstack.common.apiclient import base as common_base class VolumeBackup(base.Resource): @@ -30,7 +31,7 @@ class VolumeBackup(base.Resource): return self.manager.delete(self) def reset_state(self, state): - self.manager.reset_state(self, state) + return self.manager.reset_state(self, state) class VolumeBackupManager(base.ManagerWithFind): @@ -85,7 +86,7 @@ class VolumeBackupManager(base.ManagerWithFind): :param backup: The :class:`VolumeBackup` to delete. """ - self._delete("/backups/%s" % base.getid(backup)) + return self._delete("/backups/%s" % base.getid(backup)) def reset_state(self, backup, state): """Update the specified volume backup with the provided state.""" @@ -96,7 +97,8 @@ class VolumeBackupManager(base.ManagerWithFind): body = {action: info} self.run_hooks('modify_body_for_action', body, **kwargs) url = '/backups/%s/action' % base.getid(backup) - return self.api.client.post(url, body=body) + resp, body = self.api.client.post(url, body=body) + return common_base.TupleWithMeta((resp, body), resp) def export_record(self, backup_id): """Export volume backup metadata record. @@ -106,7 +108,7 @@ class VolumeBackupManager(base.ManagerWithFind): """ resp, body = \ self.api.client.get("/backups/%s/export_record" % backup_id) - return body['backup-record'] + return common_base.DictWithMeta(body['backup-record'], resp) def import_record(self, backup_service, backup_url): """Export volume backup metadata record. @@ -119,4 +121,4 @@ class VolumeBackupManager(base.ManagerWithFind): 'backup_url': backup_url}} self.run_hooks('modify_body_for_update', body, 'backup-record') resp, body = self.api.client.post("/backups/import_record", body=body) - return body['backup'] + return common_base.DictWithMeta(body['backup'], resp) diff --git a/cinderclient/v2/volume_encryption_types.py b/cinderclient/v2/volume_encryption_types.py index dd8fc76..c4c7a69 100644 --- a/cinderclient/v2/volume_encryption_types.py +++ b/cinderclient/v2/volume_encryption_types.py @@ -19,6 +19,7 @@ Volume Encryption Type interface """ from cinderclient import base +from cinderclient.openstack.common.apiclient import base as common_base class VolumeEncryptionType(base.Resource): @@ -47,12 +48,16 @@ class VolumeEncryptionTypeManager(base.ManagerWithFind): # all encryption types without going through all volume types. volume_types = self.api.volume_types.list() encryption_types = [] + list_of_resp = [] for volume_type in volume_types: encryption_type = self._get("/types/%s/encryption" % base.getid(volume_type)) if hasattr(encryption_type, 'volume_type_id'): encryption_types.append(encryption_type) - return encryption_types + + list_of_resp.extend(encryption_type.request_ids) + + return common_base.ListWithMeta(encryption_types, list_of_resp) def get(self, volume_type): """ diff --git a/cinderclient/v2/volume_transfers.py b/cinderclient/v2/volume_transfers.py index 633f2ac..a2bfe3c 100644 --- a/cinderclient/v2/volume_transfers.py +++ b/cinderclient/v2/volume_transfers.py @@ -98,4 +98,4 @@ class VolumeTransferManager(base.ManagerWithFind): :param transfer_id: The :class:`VolumeTransfer` to delete. """ - self._delete("/os-volume-transfer/%s" % base.getid(transfer_id)) + return self._delete("/os-volume-transfer/%s" % base.getid(transfer_id))