diff --git a/rsdclient/osc/v1/storage.py b/rsdclient/osc/v1/storage_service.py similarity index 51% rename from rsdclient/osc/v1/storage.py rename to rsdclient/osc/v1/storage_service.py index 4a9bca7..10d079f 100644 --- a/rsdclient/osc/v1/storage.py +++ b/rsdclient/osc/v1/storage_service.py @@ -13,14 +13,36 @@ # under the License. # +import json + from rsdclient.common import command -class ListStorage(command.Command): +class ListStorageServices(command.Command): _description = "List all storage services" def take_action(self, parsed_args): self.log.debug("take_action(%s)", parsed_args) rsd_client = self.app.client_manager.rsd - storage_service_list = rsd_client.storage.list() + storage_service_list = rsd_client.storage_service.list() print(storage_service_list) + + +class ShowStorageServices(command.Command): + _description = "Display storage service details" + + def get_parser(self, prog_name): + parser = super(ShowStorageServices, self).get_parser(prog_name) + parser.add_argument( + 'storageservice', + metavar='', + help='ID of the storage service.') + + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)", parsed_args) + rsd_client = self.app.client_manager.rsd + storage_detail = rsd_client.storage_service.show( + parsed_args.storageservice) + print("{0}".format(json.dumps(storage_detail, indent=2))) diff --git a/rsdclient/tests/common/fakes.py b/rsdclient/tests/common/fakes.py index e91775e..75a20b7 100644 --- a/rsdclient/tests/common/fakes.py +++ b/rsdclient/tests/common/fakes.py @@ -13,7 +13,7 @@ # under the License. # -from rsdclient.common import utils +import mock FAKE_NODE_PYTHON_DICT = { @@ -78,6 +78,54 @@ class FakeNode(object): self.memory_summary = FakeMemorySummary() self.uuid = "fd011520-86a2-11e7-b4d4-5d323196a3e4" +FAKE_STORAGE_PYTHON_DICT = { + 'description': 'Storage Service for Testing', + 'identity': '1', + 'name': 'Storage Service', + 'redfish_version': '1.0.0', + 'remote_targets': [{ + 'addresses': [{ + 'iSCSI': { + 'TargetIQN': 'base_logical_volume_target', + 'TargetLUN': [{ + 'LUN': 1, + 'LogicalDrive': { + '@odata.id': '/redfish/v1/Services/1/LogicalDrives/2' + } + }], + 'TargetPortalIP': '10.2.0.4', + 'TargetPortalPort': 3260 + } + }], + 'identity': '1', + 'initiator': [{'iSCSI': {'InitiatorIQN': 'ALL'}}], + 'redfish_version': '1.0.0', + 'target_type': 'iSCSITargets' + }], + 'physical_drives': [{ + 'capacity_gib': 931, + 'drive_type': 'HDD', + 'identity': '1', + 'interface': 'SATA', + 'manufacturer': 'fake manufacture', + 'model': 'ST1000NM0033-9ZM', + 'redfish_version': '1.0.0', + 'rpm': 7200, + 'serial_number': 'Z1W23Q3V' + }], + 'logical_drives': [{ + 'bootable': True, + 'capacity_gib': 5589, + 'drive_type': 'LVM', + 'identity': '2', + 'image': 'fake image', + 'mode': 'LVG', + 'protected': False, + 'redfish_version': '1.0.0', + 'snapshot': False + }] +} + class FakeRemoteTarget(object): @@ -136,9 +184,9 @@ class FakeStorageSerice(object): self.identity = '1' self.name = 'Storage Service' self.redfish_version = '1.0.0' - self.remote_targets = [FakeRemoteTarget()] - self.physical_drives = [FakePhysicalDrive()] - self.logical_drives = [FakeLogicalDrive()] - - -FAKE_STORAGE_PYTHON_DICT = utils.extract_attr(FakeStorageSerice()) + self.remote_targets = mock.Mock() + self.remote_targets.get_members.return_value = [FakeRemoteTarget()] + self.physical_drives = mock.Mock() + self.physical_drives.get_members.return_value = [FakePhysicalDrive()] + self.logical_drives = mock.Mock() + self.logical_drives.get_members.return_value = [FakeLogicalDrive()] diff --git a/rsdclient/tests/v1/test_storage.py b/rsdclient/tests/v1/test_storage_service.py similarity index 83% rename from rsdclient/tests/v1/test_storage.py rename to rsdclient/tests/v1/test_storage_service.py index 4040500..1c1ff51 100644 --- a/rsdclient/tests/v1/test_storage.py +++ b/rsdclient/tests/v1/test_storage_service.py @@ -17,7 +17,7 @@ import mock import testtools from rsdclient.tests.common import fakes -from rsdclient.v1 import storage +from rsdclient.v1 import storage_service class NodeTest(testtools.TestCase): @@ -26,7 +26,7 @@ class NodeTest(testtools.TestCase): super(NodeTest, self).setUp() self.client = mock.Mock() self.client._storage_service_path = '/redfish/v1/Services' - self.mgr = storage.StorageManager(self.client) + self.mgr = storage_service.StorageServiceManager(self.client) def test_list_storage(self): mock_storage_collection = mock.Mock() @@ -49,3 +49,10 @@ class NodeTest(testtools.TestCase): self.mgr.client.get_storage_service.assert_called_once_with( '/redfish/v1/Services/1') self.assertEqual(str(result), expected) + + def test_show_storage(self): + self.client.get_storage_service.return_value = \ + fakes.FakeStorageSerice() + result = self.mgr.show('1') + expected = fakes.FAKE_STORAGE_PYTHON_DICT + self.assertEqual(result, expected) diff --git a/rsdclient/v1/client.py b/rsdclient/v1/client.py index 915d907..f014819 100644 --- a/rsdclient/v1/client.py +++ b/rsdclient/v1/client.py @@ -16,7 +16,7 @@ import rsd_lib from rsdclient.v1 import node -from rsdclient.v1 import storage +from rsdclient.v1 import storage_service class Client(object): @@ -25,4 +25,5 @@ class Client(object): self.client = rsd_lib.RSDLib(base_url, username, password, verify=verify) self.node = node.NodeManager(self.client) - self.storage = storage.StorageManager(self.client) + self.storage_service = \ + storage_service.StorageServiceManager(self.client) diff --git a/rsdclient/v1/storage.py b/rsdclient/v1/storage_service.py similarity index 64% rename from rsdclient/v1/storage.py rename to rsdclient/v1/storage_service.py index 1076a15..b055e84 100644 --- a/rsdclient/v1/storage.py +++ b/rsdclient/v1/storage_service.py @@ -19,11 +19,11 @@ from rsdclient.common import base from rsdclient.common import utils -class StorageManager(base.Manager): +class StorageServiceManager(base.Manager): _resource_name = 'storages' def __init__(self, *args, **kwargs): - super(StorageManager, self).__init__(*args, **kwargs) + super(StorageServiceManager, self).__init__(*args, **kwargs) self.storage_service_path = self.client._storage_service_path def _get_storage_service_uri(self, storage_service_id): @@ -39,3 +39,21 @@ class StorageManager(base.Manager): storage_info_table = utils.print_dict( storages, ["Identity", "Name", "Description"]) return storage_info_table + + def show(self, storage_id): + storage = self.client.get_storage_service( + self._get_storage_service_uri(storage_id)) + storage_dict = utils.extract_attr(storage) + + # Append sub-items attributions + storage_dict['remote_targets'] = [ + utils.extract_attr(item) + for item in storage.remote_targets.get_members()] + storage_dict['physical_drives'] = [ + utils.extract_attr(item) + for item in storage.physical_drives.get_members()] + storage_dict['logical_drives'] = [ + utils.extract_attr(item) + for item in storage.logical_drives.get_members()] + + return storage_dict diff --git a/setup.cfg b/setup.cfg index acd24a0..eb677c0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,7 +33,8 @@ openstack.rsd.v1 = rsd_node_show = rsdclient.osc.v1.node:ShowNode rsd_node_list = rsdclient.osc.v1.node:ListNode - rsd_storage_list = rsdclient.osc.v1.storage:ListStorage + rsd_storage_list = rsdclient.osc.v1.storage_service:ListStorageServices + rsd_storage_show = rsdclient.osc.v1.storage_service:ShowStorageServices [build_sphinx] all-files = 1