diff --git a/proliantutils/redfish/redfish.py b/proliantutils/redfish/redfish.py index c18c38a3..8b3f8cbb 100644 --- a/proliantutils/redfish/redfish.py +++ b/proliantutils/redfish/redfish.py @@ -658,36 +658,43 @@ class RedfishOperations(operations.IloOperations): 'boot_mode_uefi': boot_mode.boot_mode_uefi}) tpm_state = sushy_system.bios_settings.tpm_state + all_key_to_value_expression_tuples = [ + ('sriov_enabled', + sushy_system.bios_settings.sriov == sys_cons.SRIOV_ENABLED), + ('cpu_vt', + sushy_system.bios_settings.cpu_vt == ( + sys_cons.CPUVT_ENABLED)), + ('trusted_boot', + (tpm_state == sys_cons.TPM_PRESENT_ENABLED + or tpm_state == sys_cons.TPM_PRESENT_DISABLED)), + ('secure_boot', + GET_SECUREBOOT_CURRENT_BOOT_MAP.get( + sushy_system.secure_boot.current_boot)), + ('iscsi_boot', + (sushy_system.bios_settings.iscsi_settings. + is_iscsi_boot_supported())), + ('hardware_supports_raid', + len(sushy_system.smart_storage.array_controllers. + members_identities) > 0), + ('has_ssd', + common_storage.has_ssd(sushy_system)), + ('has_rotational', + common_storage.has_rotational(sushy_system)), + ('has_nvme_ssd', + common_storage.has_nvme_ssd(sushy_system)) + ] + + all_key_to_value_expression_tuples += ( + [('logical_raid_level_' + x, True) + for x in sushy_system.smart_storage.logical_raid_levels]) + capabilities.update( {key: 'true' - for (key, value) in (( - 'sriov_enabled', - sushy_system.bios_settings.sriov == sys_cons.SRIOV_ENABLED - ), - ('cpu_vt', - sushy_system.bios_settings.cpu_vt == ( - sys_cons.CPUVT_ENABLED)), - ('trusted_boot', - (tpm_state == sys_cons.TPM_PRESENT_ENABLED - or tpm_state == sys_cons.TPM_PRESENT_DISABLED)), - ('secure_boot', - GET_SECUREBOOT_CURRENT_BOOT_MAP.get( - sushy_system.secure_boot.current_boot)), - ('iscsi_boot', - (sushy_system.bios_settings.iscsi_settings. - is_iscsi_boot_supported())), - ('hardware_supports_raid', - len(sushy_system.smart_storage.array_controllers. - members_identities) > 0), - ('has_ssd', - common_storage.has_ssd(sushy_system)), - ('has_rotational', - common_storage.has_rotational(sushy_system)), - ('has_nvme_ssd', - common_storage.has_nvme_ssd(sushy_system)), - ) if value}) + for (key, value) in all_key_to_value_expression_tuples + if value}) memory_data = sushy_system.memory.details() + if memory_data.has_nvdimm_n: capabilities.update( {'persistent_memory': ( diff --git a/proliantutils/redfish/resources/system/storage/array_controller.py b/proliantutils/redfish/resources/system/storage/array_controller.py index c385d4f3..5e208b91 100644 --- a/proliantutils/redfish/resources/system/storage/array_controller.py +++ b/proliantutils/redfish/resources/system/storage/array_controller.py @@ -74,6 +74,7 @@ class HPEArrayControllerCollection(base.ResourceCollectionBase): _physical_drives_maximum_size_mib = None _has_ssd = None _has_rotational = None + _logical_raid_levels = None @property def _resource_type(self): @@ -127,9 +128,23 @@ class HPEArrayControllerCollection(base.ResourceCollectionBase): break return self._has_rotational + @property + def logical_raid_levels(self): + """Gets the raid level for each logical volume + + :returns the set of list of raid levels configured + """ + if self._logical_raid_levels is None: + self._logical_raid_levels = set() + for member in self.get_members(): + self._logical_raid_levels.update( + member.logical_drives.logical_raid_levels) + return self._logical_raid_levels + def refresh(self): super(HPEArrayControllerCollection, self).refresh() self._logical_drives_maximum_size_mib = None self._physical_drives_maximum_size_mib = None self._has_ssd = None self._has_rotational = None + self._logical_raid_levels = None diff --git a/proliantutils/redfish/resources/system/storage/common.py b/proliantutils/redfish/resources/system/storage/common.py index 5aeb308f..49cd6ab9 100644 --- a/proliantutils/redfish/resources/system/storage/common.py +++ b/proliantutils/redfish/resources/system/storage/common.py @@ -163,7 +163,7 @@ def has_rotational(system_obj): def has_nvme_ssd(system_obj): - """Gets if the system has any drive as SSD drive + """Gets if the system has any drive as NVMe SSD drive :param system_obj: The HPESystem object. :returns True if system has SSD drives and protocol is NVMe. diff --git a/proliantutils/redfish/resources/system/storage/logical_drive.py b/proliantutils/redfish/resources/system/storage/logical_drive.py index 1dd206c6..5929a392 100644 --- a/proliantutils/redfish/resources/system/storage/logical_drive.py +++ b/proliantutils/redfish/resources/system/storage/logical_drive.py @@ -37,6 +37,7 @@ class HPELogicalDriveCollection(base.ResourceCollectionBase): """This class represents the collection of LogicalDrives resource""" _maximum_size_mib = None + _logical_raid_levels = None @property def _resource_type(self): @@ -54,6 +55,20 @@ class HPELogicalDriveCollection(base.ResourceCollectionBase): for member in self.get_members()])) return self._maximum_size_mib + @property + def logical_raid_levels(self): + """Gets the raid level for each logical volume + + :returns the set of list of raid levels configured. + """ + if self._logical_raid_levels is None: + self._logical_raid_levels = set() + for member in self.get_members(): + self._logical_raid_levels.add( + mappings.RAID_LEVEL_MAP_REV.get(member.raid)) + return self._logical_raid_levels + def refresh(self): super(HPELogicalDriveCollection, self).refresh() self._maximum_size_mib = None + self._logical_raid_levels = None diff --git a/proliantutils/redfish/resources/system/storage/smart_storage.py b/proliantutils/redfish/resources/system/storage/smart_storage.py index 79e62a88..13f52cd0 100644 --- a/proliantutils/redfish/resources/system/storage/smart_storage.py +++ b/proliantutils/redfish/resources/system/storage/smart_storage.py @@ -35,6 +35,7 @@ class HPESmartStorage(base.ResourceBase): _physical_drives_maximum_size_mib = None _has_ssd = None _has_rotational = None + _logical_raid_levels = None @property def array_controllers(self): @@ -101,6 +102,19 @@ class HPESmartStorage(base.ResourceBase): break return self._has_rotational + @property + def logical_raid_levels(self): + """Gets the raid level for each logical volume + + :returns the set of list of raid levels configured. + """ + if self._logical_raid_levels is None: + self._logical_raid_levels = set() + for member in self.array_controllers.get_members(): + self._logical_raid_levels.update( + member.logical_drives.logical_raid_levels) + return self._logical_raid_levels + def refresh(self): super(HPESmartStorage, self).refresh() self._logical_drives_maximum_size_mib = None @@ -108,3 +122,4 @@ class HPESmartStorage(base.ResourceBase): self._array_controllers = None self._has_ssd = None self._has_rotational = None + self._logical_raid_levels = None diff --git a/proliantutils/redfish/resources/system/storage/storage.py b/proliantutils/redfish/resources/system/storage/storage.py index 2fe5ba41..591407aa 100644 --- a/proliantutils/redfish/resources/system/storage/storage.py +++ b/proliantutils/redfish/resources/system/storage/storage.py @@ -106,7 +106,7 @@ class Storage(base.ResourceBase): @property def has_nvme_ssd(self): - """Return true if the drive is SSD and protocol is NVMe""" + """Return True if the drive is SSD and protocol is NVMe""" if self._has_nvme_ssd is None: self._has_nvme_ssd = False @@ -188,7 +188,7 @@ class StorageCollection(base.ResourceCollectionBase): @property def has_nvme_ssd(self): - """Return true if Storage has SSD drive and protocol is NVMe""" + """Return True if Storage has SSD drive and protocol is NVMe""" if self._has_nvme_ssd is None: self._has_nvme_ssd = False diff --git a/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py b/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py index 48d121f3..c8a0da71 100644 --- a/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py +++ b/proliantutils/tests/redfish/resources/system/storage/test_array_controller.py @@ -138,6 +138,27 @@ class HPEArrayControllerCollectionTestCase(testtools.TestCase): actual = self.sys_stor_col.logical_drives_maximum_size_mib self.assertEqual(expected, actual) + def test_logical_raid_levels(self): + self.assertIsNone(self.sys_stor_col._logical_raid_levels) + self.conn.get.return_value.json.reset_mock() + val = [] + path = ('proliantutils/tests/redfish/json_samples/' + 'array_controller.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + path = ('proliantutils/tests/redfish/json_samples/' + 'logical_drive_collection.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + path = ('proliantutils/tests/redfish/json_samples/' + 'logical_drive.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + self.conn.get.return_value.json.side_effect = val + expected = set(['0']) + actual = self.sys_stor_col.logical_raid_levels + self.assertEqual(expected, actual) + def test_physical_drives_maximum_size_mib(self): self.assertIsNone(self.sys_stor_col._physical_drives_maximum_size_mib) self.conn.get.return_value.json.reset_mock() diff --git a/proliantutils/tests/redfish/resources/system/storage/test_logical_drive.py b/proliantutils/tests/redfish/resources/system/storage/test_logical_drive.py index f67e7a89..5b1a76ed 100644 --- a/proliantutils/tests/redfish/resources/system/storage/test_logical_drive.py +++ b/proliantutils/tests/redfish/resources/system/storage/test_logical_drive.py @@ -96,3 +96,14 @@ class HPELogicalDriveCollectionTestCase(testtools.TestCase): expected = 953837 actual = self.sys_stor_col.maximum_size_mib self.assertEqual(expected, actual) + + def test_logical_raid_levels(self): + self.assertIsNone(self.sys_stor_col._logical_raid_levels) + self.conn.get.return_value.json.reset_mock() + path = ('proliantutils/tests/redfish/json_samples/' + 'logical_drive.json') + with open(path, 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + expected = set(['0']) + actual = self.sys_stor_col.logical_raid_levels + self.assertEqual(expected, actual) diff --git a/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py b/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py index 4ca40249..cd15f12f 100644 --- a/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py +++ b/proliantutils/tests/redfish/resources/system/storage/test_smart_storage.py @@ -81,6 +81,31 @@ class HPESmartStorageTestCase(testtools.TestCase): actual = self.sys_stor.logical_drives_maximum_size_mib self.assertEqual(expected, actual) + def test_logical_raid_levels(self): + self.assertIsNone(self.sys_stor._logical_raid_levels) + self.conn.get.return_value.json.reset_mock() + val = [] + path = ('proliantutils/tests/redfish/json_samples/' + 'array_controller_collection.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + path = ('proliantutils/tests/redfish/json_samples/' + 'array_controller.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + path = ('proliantutils/tests/redfish/json_samples/' + 'logical_drive_collection.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + path = ('proliantutils/tests/redfish/json_samples/' + 'logical_drive.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + self.conn.get.return_value.json.side_effect = val + expected = set(['0']) + actual = self.sys_stor.logical_raid_levels + self.assertEqual(expected, actual) + def test_physical_drives_maximum_size_mib(self): self.assertIsNone(self.sys_stor._physical_drives_maximum_size_mib) self.conn.get.return_value.json.reset_mock() diff --git a/proliantutils/tests/redfish/test_redfish.py b/proliantutils/tests/redfish/test_redfish.py index 1152e555..057b3b63 100644 --- a/proliantutils/tests/redfish/test_redfish.py +++ b/proliantutils/tests/redfish/test_redfish.py @@ -731,6 +731,9 @@ class RedfishOperationsTestCase(testtools.TestCase): ssd_mock.return_value = True rotational_mock.return_value = True nvme_mock.return_value = True + raid_mock = mock.PropertyMock(return_value=set(['0', '1'])) + type(get_system_mock.return_value. + smart_storage).logical_raid_levels = (raid_mock) actual = self.rf_client.get_server_capabilities() expected = {'pci_gpu_devices': 1, 'sriov_enabled': 'true', 'secure_boot': 'true', 'cpu_vt': 'true', @@ -747,7 +750,9 @@ class RedfishOperationsTestCase(testtools.TestCase): 'logical_nvdimm_n': 'false', 'has_ssd': 'true', 'has_rotational': 'true', - 'has_nvme_ssd': 'true'} + 'has_nvme_ssd': 'true', + 'logical_raid_level_0': 'true', + 'logical_raid_level_1': 'true'} self.assertEqual(expected, actual) @mock.patch.object(common_storage, 'has_nvme_ssd') @@ -798,6 +803,9 @@ class RedfishOperationsTestCase(testtools.TestCase): ssd_mock.return_value = False rotational_mock.return_value = False nvme_mock.return_value = False + raid_mock = mock.PropertyMock(return_value=set()) + type(get_system_mock.return_value. + smart_storage).logical_raid_levels = (raid_mock) actual = self.rf_client.get_server_capabilities() expected = {'pci_gpu_devices': 1, 'rom_firmware_version': 'U31 v1.00 (03/11/2017)',