From 75b34b0355a849c9343fa7010e070010a235e634 Mon Sep 17 00:00:00 2001 From: Nisha Agarwal Date: Mon, 10 Jul 2017 03:38:32 +0000 Subject: [PATCH] Redfish: Add the nic_capacity attributes This commit adds the "nic_capacity" attribute to server capabilities. Change-Id: Ia74825fcae03b5a926a79e56528e9b3ee743df9d --- proliantutils/ilo/client.py | 26 +++++++++++------ proliantutils/redfish/redfish.py | 3 +- .../redfish/resources/system/pci_device.py | 29 +++++++++++++++++++ proliantutils/tests/ilo/test_client.py | 13 +++++++++ .../redfish/json_samples/pci_device.json | 2 +- .../resources/system/test_pci_device.py | 18 ++++++++++++ proliantutils/tests/redfish/test_redfish.py | 13 +++++---- 7 files changed, 88 insertions(+), 16 deletions(-) diff --git a/proliantutils/ilo/client.py b/proliantutils/ilo/client.py index 9a8ef3f..9f9a0de 100644 --- a/proliantutils/ilo/client.py +++ b/proliantutils/ilo/client.py @@ -81,7 +81,8 @@ SUPPORTED_REDFISH_METHODS = [ 'get_secure_boot_mode', 'set_secure_boot_mode', 'reset_secure_boot_keys', - 'clear_secure_boot_keys' + 'clear_secure_boot_keys', + 'get_server_capabilities' ] LOG = log.get_logger(__name__) @@ -530,15 +531,22 @@ class IloClient(operations.IloOperations): on the server. """ capabilities = self._call_method('get_server_capabilities') - major_minor = ( - self._call_method('get_ilo_firmware_version_as_major_minor')) + # TODO(nisha): Assumption is that Redfish always see the pci_device + # member name field populated similarly to IPMI. + # If redfish is not able to get nic_capacity, we can fall back to + # IPMI way of retrieving nic_capacity in the future. As of now + # the IPMI is not tested on Gen10, hence assuming that + # Redfish will always be able to give the data. + if ('Gen10' not in self.model): + major_minor = ( + self._call_method('get_ilo_firmware_version_as_major_minor')) - # NOTE(vmud213): Even if it is None, pass it on to get_nic_capacity - # as we still want to try getting nic capacity through ipmitool - # irrespective of what firmware we are using. - nic_capacity = ipmi.get_nic_capacity(self.info, major_minor) - if nic_capacity: - capabilities.update({'nic_capacity': nic_capacity}) + # NOTE(vmud213): Even if it is None, pass it on to get_nic_capacity + # as we still want to try getting nic capacity through ipmitool + # irrespective of what firmware we are using. + nic_capacity = ipmi.get_nic_capacity(self.info, major_minor) + if nic_capacity: + capabilities.update({'nic_capacity': nic_capacity}) if capabilities: return capabilities diff --git a/proliantutils/redfish/redfish.py b/proliantutils/redfish/redfish.py index c6e5a47..2c9d7c9 100644 --- a/proliantutils/redfish/redfish.py +++ b/proliantutils/redfish/redfish.py @@ -615,7 +615,8 @@ class RedfishOperations(operations.IloOperations): {'pci_gpu_devices': count, 'ilo_firmware_version': sushy_manager.firmware_version, 'rom_firmware_version': sushy_system.rom_version, - 'server_model': sushy_system.model}) + 'server_model': sushy_system.model, + 'nic_capacity': sushy_system.pci_devices.max_nic_capacity}) capabilities.update( {key: 'true' diff --git a/proliantutils/redfish/resources/system/pci_device.py b/proliantutils/redfish/resources/system/pci_device.py index 653bc0c..d4e4f80 100644 --- a/proliantutils/redfish/resources/system/pci_device.py +++ b/proliantutils/redfish/resources/system/pci_device.py @@ -32,10 +32,30 @@ class PCIDevice(base.ResourceBase): sub_class_code = base.Field('SubclassCode') + _nic_capacity = None + + def refresh(self): + super(PCIDevice, self).refresh() + self._nic_capacity = None + + @property + def nic_capacity(self): + if self._nic_capacity is None: + for item in self.name.split(): + if 'Gb' in item: + capacity = item.strip('Gb') + self._nic_capacity = ( + int(capacity) if capacity.isdigit() else 0) + break + else: + self._nic_capacity = 0 + return self._nic_capacity + class PCIDeviceCollection(base.ResourceCollectionBase): _gpu_devices = None + _max_nic_capacity = None @property def _resource_type(self): @@ -54,3 +74,12 @@ class PCIDeviceCollection(base.ResourceCollectionBase): def refresh(self): super(PCIDeviceCollection, self).refresh() self._gpu_devices = None + self._max_nic_capacity = None + + @property + def max_nic_capacity(self): + """Gets the maximum NIC capacity""" + if self._max_nic_capacity is None: + self._max_nic_capacity = ( + str(max([m.nic_capacity for m in self.get_members()])) + 'Gb') + return self._max_nic_capacity diff --git a/proliantutils/tests/ilo/test_client.py b/proliantutils/tests/ilo/test_client.py index f2b1192..a13032b 100644 --- a/proliantutils/tests/ilo/test_client.py +++ b/proliantutils/tests/ilo/test_client.py @@ -661,6 +661,19 @@ class IloClientTestCase(testtools.TestCase): 'nic_capacity': '10Gb'} self.assertEqual(expected_capabilities, capabilities) + @mock.patch.object(redfish, 'RedfishOperations') + @mock.patch.object(ribcl.RIBCLOperations, 'get_product_name') + @mock.patch.object(ipmi, 'get_nic_capacity') + def test_get_server_capabilities_Gen10(self, ipmi_mock, + ribcl_product_name_mock, + redfish_mock): + ribcl_product_name_mock.return_value = 'Gen10' + self.client = client.IloClient("1.2.3.4", "admin", "secret") + cap_mock = (redfish_mock.return_value.get_server_capabilities) + self.client.get_server_capabilities() + self.assertFalse(ipmi_mock.called) + self.assertTrue(cap_mock.called) + @mock.patch.object(client.IloClient, '_call_method') def test_activate_license(self, call_mock): self.client.activate_license('fake-key') diff --git a/proliantutils/tests/redfish/json_samples/pci_device.json b/proliantutils/tests/redfish/json_samples/pci_device.json index 71ab557..fdd9565 100644 --- a/proliantutils/tests/redfish/json_samples/pci_device.json +++ b/proliantutils/tests/redfish/json_samples/pci_device.json @@ -14,7 +14,7 @@ "FunctionNumber": 0, "Id": "1", "LocationString": "Embedded LOM 1", - "Name": "Network Controller", + "Name": "HPE Ethernet 1Gb 4-port 331i Adapter - NIC", "SegmentNumber": 0, "StructuredName": "NIC.LOM.1.1", "SubclassCode": 0, diff --git a/proliantutils/tests/redfish/resources/system/test_pci_device.py b/proliantutils/tests/redfish/resources/system/test_pci_device.py index fc8749f..1f5491d 100644 --- a/proliantutils/tests/redfish/resources/system/test_pci_device.py +++ b/proliantutils/tests/redfish/resources/system/test_pci_device.py @@ -39,6 +39,7 @@ class PCIDeviceTestCase(testtools.TestCase): self.sys_pci._parse_attributes() self.assertEqual('1.0.2', self.sys_pci.redfish_version) self.assertEqual('1', self.sys_pci.identity) + self.assertEqual(1, self.sys_pci.nic_capacity) class PCIDeviceCollectionTestCase(testtools.TestCase): @@ -100,3 +101,20 @@ class PCIDeviceCollectionTestCase(testtools.TestCase): self.conn.get.return_value.json.side_effect = val self.sys_pci_col.gpu_devices self.assertEqual(1, len(self.sys_pci_col._gpu_devices)) + + def test_max_nic_capacity(self): + self.assertIsNone(self.sys_pci_col._max_nic_capacity) + self.conn.get.return_value.json.reset_mock() + val = [] + path = ('proliantutils/tests/redfish/json_samples/' + 'pci_device.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + path = ('proliantutils/tests/redfish/json_samples/' + 'pci_device1.json') + with open(path, 'r') as f: + val.append(json.loads(f.read())) + self.conn.get.return_value.json.side_effect = val + actual_capacity = self.sys_pci_col.max_nic_capacity + expected = '1Gb' + self.assertEqual(expected, actual_capacity) diff --git a/proliantutils/tests/redfish/test_redfish.py b/proliantutils/tests/redfish/test_redfish.py index d31462c..5e5b922 100644 --- a/proliantutils/tests/redfish/test_redfish.py +++ b/proliantutils/tests/redfish/test_redfish.py @@ -651,11 +651,6 @@ class RedfishOperationsTestCase(testtools.TestCase): @mock.patch.object(redfish.RedfishOperations, '_get_sushy_system') @mock.patch.object(redfish.RedfishOperations, '_get_sushy_manager') def test_get_server_capabilities(self, get_manager_mock, get_system_mock): - val = [] - path = ('proliantutils/tests/redfish/json_samples/' - 'pci_device.json') - with open(path, 'r') as f: - val.append(json.loads(f.read())) type(get_system_mock.return_value.pci_devices).gpu_devices = ( [mock.MagicMock(spec=pci_device.PCIDevice)]) type(get_system_mock.return_value.bios_settings).sriov = ( @@ -664,10 +659,14 @@ class RedfishOperationsTestCase(testtools.TestCase): 'U31 v1.00 (03/11/2017)') type(get_manager_mock.return_value).firmware_version = 'iLO 5 v1.15' type(get_system_mock.return_value).model = 'ProLiant DL180 Gen10' + nic_mock = mock.PropertyMock(return_value='1Gb') + type(get_system_mock.return_value.pci_devices).max_nic_capacity = ( + nic_mock) actual = self.rf_client.get_server_capabilities() expected = {'pci_gpu_devices': 1, 'sriov_enabled': 'true', 'rom_firmware_version': 'U31 v1.00 (03/11/2017)', 'ilo_firmware_version': 'iLO 5 v1.15', + 'nic_capacity': '1Gb', 'server_model': 'ProLiant DL180 Gen10'} self.assertEqual(expected, actual) @@ -688,10 +687,14 @@ class RedfishOperationsTestCase(testtools.TestCase): 'U31 v1.00 (03/11/2017)') type(get_manager_mock.return_value).firmware_version = 'iLO 5 v1.15' type(get_system_mock.return_value).model = 'ProLiant DL180 Gen10' + nic_mock = mock.PropertyMock(return_value='1Gb') + type(get_system_mock.return_value.pci_devices).max_nic_capacity = ( + nic_mock) actual = self.rf_client.get_server_capabilities() expected = {'pci_gpu_devices': 1, 'rom_firmware_version': 'U31 v1.00 (03/11/2017)', 'ilo_firmware_version': 'iLO 5 v1.15', + 'nic_capacity': '1Gb', 'server_model': 'ProLiant DL180 Gen10'} self.assertEqual(expected, actual)