Add NIC inspection for Gen9
This commit adds NIC inspection for Gen9 and just gets the MACs which are physically connected through a cable. Closes-Bug: 1812623 Change-Id: Ica624aae8f956a2da061801def6ddc43152a5b09
This commit is contained in:
@@ -169,6 +169,9 @@ RESPONSE_BODY_FOR_REST_OP = """
|
||||
"MEMORY": {
|
||||
"href": "/rest/v1/Systems/1/Memory"
|
||||
},
|
||||
"NetworkAdapters": {
|
||||
"href": "/rest/v1/Systems/1/NetworkAdapters"
|
||||
},
|
||||
"PCIDevices": {
|
||||
"href": "/rest/v1/Systems/1/PCIDevices"
|
||||
},
|
||||
@@ -4843,3 +4846,177 @@ ArrayControllers"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
NO_MACS_CONNECTED = """
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#Systems/Members/1/\
|
||||
NetworkAdapters/Members/$entity",
|
||||
"@odata.id": "/redfish/v1/Systems/1/NetworkAdapters/1/",
|
||||
"@odata.type": "#BaseNetworkAdapter.1.1.0.BaseNetworkAdapter",
|
||||
"Firmware": {
|
||||
"Current": {
|
||||
"VersionString": null
|
||||
}
|
||||
},
|
||||
"Id": "1",
|
||||
"Name": "HP Ethernet 1Gb 2-port 361i Adapter - NIC",
|
||||
"PartNumber": null,
|
||||
"PhysicalPorts": [{
|
||||
"FullDuplex": false,
|
||||
"IPv4Addresses": [{
|
||||
"Address": null
|
||||
}],
|
||||
"IPv6Addresses": [{
|
||||
"Address": null
|
||||
}],
|
||||
"MacAddress": "50:65:F3:6C:47:F8",
|
||||
"Name": null,
|
||||
"Oem": {
|
||||
"Hp": {
|
||||
"@odata.type": "#HpBaseNetworkAdapterExt.1.0.0.\
|
||||
HpBaseNetworkAdapterExt",
|
||||
"BadReceives": null,
|
||||
"BadTransmits": null,
|
||||
"GoodReceives": null,
|
||||
"GoodTransmits": null,
|
||||
"StructuredName": "NIC.LOM.1.1",
|
||||
"Team": null,
|
||||
"Type": "HpBaseNetworkAdapterExt.1.0.0"
|
||||
}
|
||||
},
|
||||
"SpeedMbps": 0,
|
||||
"Status": {
|
||||
"Health": "Warning",
|
||||
"State": "Disabled"
|
||||
},
|
||||
"UEFIDevicePath": "PciRoot(0x0)/Pci(0x2,0x3)/Pci(0x0,0x0)"
|
||||
}],
|
||||
"SerialNumber": null,
|
||||
"Status": {
|
||||
"Health": "Warning",
|
||||
"State": "Disabled"
|
||||
},
|
||||
"StructuredName": "NIC.LOM.1.1",
|
||||
"Type": "BaseNetworkAdapter.1.1.0",
|
||||
"UEFIDevicePath": "PciRoot(0x0)/Pci(0x2,0x3)/Pci(0x0,0x0)",
|
||||
"links": {
|
||||
"self": {
|
||||
"href": "/rest/v1/Systems/1/NetworkAdapters/1"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
ONE_MAC_CONNECTED = """
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#Systems/Members/1/\
|
||||
NetworkAdapters/Members/$entity",
|
||||
"@odata.id": "/redfish/v1/Systems/1/NetworkAdapters/1/",
|
||||
"@odata.type": "#BaseNetworkAdapter.1.1.0.BaseNetworkAdapter",
|
||||
"Firmware": {
|
||||
"Current": {
|
||||
"VersionString": null
|
||||
}
|
||||
},
|
||||
"Id": "1",
|
||||
"Name": "HP Ethernet 1Gb 2-port 361i Adapter - NIC",
|
||||
"PartNumber": null,
|
||||
"PhysicalPorts": [{
|
||||
"FullDuplex": false,
|
||||
"IPv4Addresses": [{
|
||||
"Address": null
|
||||
}],
|
||||
"IPv6Addresses": [{
|
||||
"Address": null
|
||||
}],
|
||||
"MacAddress": "50:65:F3:6C:47:F8",
|
||||
"Name": null,
|
||||
"Oem": {
|
||||
"Hp": {
|
||||
"@odata.type": "#HpBaseNetworkAdapterExt.1.0.0.\
|
||||
HpBaseNetworkAdapterExt",
|
||||
"BadReceives": null,
|
||||
"BadTransmits": null,
|
||||
"GoodReceives": null,
|
||||
"GoodTransmits": null,
|
||||
"StructuredName": "NIC.LOM.1.1",
|
||||
"Team": null,
|
||||
"Type": "HpBaseNetworkAdapterExt.1.0.0"
|
||||
}
|
||||
},
|
||||
"SpeedMbps": 0,
|
||||
"Status": {
|
||||
"Health": "OK",
|
||||
"State": "Enabled"
|
||||
},
|
||||
"UEFIDevicePath": "PciRoot(0x0)/Pci(0x2,0x3)/Pci(0x0,0x0)"
|
||||
}, {
|
||||
"FullDuplex": false,
|
||||
"IPv4Addresses": [{
|
||||
"Address": null
|
||||
}],
|
||||
"IPv6Addresses": [{
|
||||
"Address": null
|
||||
}],
|
||||
"MacAddress": "50:65:F3:6C:47:F9",
|
||||
"Name": null,
|
||||
"Oem": {
|
||||
"Hp": {
|
||||
"@odata.type": "#HpBaseNetworkAdapterExt.1.0.0.\
|
||||
HpBaseNetworkAdapterExt",
|
||||
"BadReceives": null,
|
||||
"BadTransmits": null,
|
||||
"GoodReceives": null,
|
||||
"GoodTransmits": null,
|
||||
"StructuredName": "NIC.LOM.1.2",
|
||||
"Team": null,
|
||||
"Type": "HpBaseNetworkAdapterExt.1.0.0"
|
||||
}
|
||||
},
|
||||
"SpeedMbps": 0,
|
||||
"Status": {
|
||||
"Health": "Warning",
|
||||
"State": "Disabled"
|
||||
},
|
||||
"UEFIDevicePath": "PciRoot(0x0)/Pci(0x2,0x3)/Pci(0x0,0x1)"
|
||||
}],
|
||||
"SerialNumber": null,
|
||||
"Status": {
|
||||
"Health": "OK",
|
||||
"State": "Enabled"
|
||||
},
|
||||
"StructuredName": "NIC.LOM.1.1",
|
||||
"Type": "BaseNetworkAdapter.1.1.0",
|
||||
"UEFIDevicePath": "PciRoot(0x0)/Pci(0x2,0x3)/Pci(0x0,0x0)",
|
||||
"links": {
|
||||
"self": {
|
||||
"href": "/rest/v1/Systems/1/NetworkAdapters/1"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
NETWORK_ADAPTER_LIST = """
|
||||
{
|
||||
"@odata.context": "/redfish/v1/$metadata#Systems/Members/1/NetworkAdapters",
|
||||
"@odata.id": "/redfish/v1/Systems/1/NetworkAdapters/",
|
||||
"@odata.type": "#BaseNetworkAdapterCollection.BaseNetworkAdapterCollection",
|
||||
"Description": "NetworkAdapters view",
|
||||
"MemberType": "BaseNetworkAdapter.1",
|
||||
"Members": [{
|
||||
"@odata.id": "/redfish/v1/Systems/1/NetworkAdapters/1/"
|
||||
}],
|
||||
"Members@odata.count": 1,
|
||||
"Name": "NetworkAdapters Collection",
|
||||
"Total": 1,
|
||||
"Type": "Collection.1.0.0",
|
||||
"links": {
|
||||
"Member": [{
|
||||
"href": "/rest/v1/Systems/1/NetworkAdapters/1"
|
||||
}],
|
||||
"self": {
|
||||
"href": "/rest/v1/Systems/1/NetworkAdapters"
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
@@ -1036,11 +1036,12 @@ class IloClientTestCase(testtools.TestCase):
|
||||
self.client.set_bios_settings(d, apply_filter)
|
||||
bios_settings_mock.assert_called_once_with(d, False)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_active_macs')
|
||||
@mock.patch.object(client.IloClient, '_call_method')
|
||||
@mock.patch.object(snmp_cpqdisk_sizes, 'get_local_gb')
|
||||
def test_get_essential_prop_no_snmp_ris(self,
|
||||
snmp_mock,
|
||||
call_mock):
|
||||
call_mock, mac_mock):
|
||||
self.client.model = 'Gen9'
|
||||
properties = {'local_gb': 250}
|
||||
data = {'properties': properties}
|
||||
@@ -1048,12 +1049,15 @@ class IloClientTestCase(testtools.TestCase):
|
||||
self.client.get_essential_properties()
|
||||
call_mock.assert_called_once_with('get_essential_properties')
|
||||
self.assertFalse(snmp_mock.called)
|
||||
self.assertTrue(mac_mock.called)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_active_macs')
|
||||
@mock.patch.object(client.IloClient, '_call_method')
|
||||
@mock.patch.object(snmp_cpqdisk_sizes, 'get_local_gb')
|
||||
def test_get_essential_prop_no_snmp_local_gb_0(self,
|
||||
snmp_mock,
|
||||
call_mock):
|
||||
call_mock,
|
||||
mac_mock):
|
||||
self.client.model = 'Gen9'
|
||||
properties = {'local_gb': 0}
|
||||
data = {'properties': properties}
|
||||
@@ -1061,12 +1065,14 @@ class IloClientTestCase(testtools.TestCase):
|
||||
self.client.get_essential_properties()
|
||||
call_mock.assert_called_once_with('get_essential_properties')
|
||||
self.assertFalse(snmp_mock.called)
|
||||
self.assertTrue(mac_mock.called)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_active_macs')
|
||||
@mock.patch.object(client.IloClient, '_call_method')
|
||||
@mock.patch.object(snmp_cpqdisk_sizes, 'get_local_gb')
|
||||
def test_get_essential_prop_snmp_true(self,
|
||||
snmp_mock,
|
||||
call_mock):
|
||||
call_mock, mac_mock):
|
||||
self.client.model = 'Gen9'
|
||||
snmp_credentials = {'auth_user': 'user',
|
||||
'auth_prot_pp': '1234',
|
||||
@@ -1083,12 +1089,15 @@ class IloClientTestCase(testtools.TestCase):
|
||||
call_mock.assert_called_once_with('get_essential_properties')
|
||||
snmp_mock.assert_called_once_with(self.client.info['address'],
|
||||
snmp_credentials)
|
||||
self.assertTrue(mac_mock.called)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_active_macs')
|
||||
@mock.patch.object(client.IloClient, '_call_method')
|
||||
@mock.patch.object(snmp_cpqdisk_sizes, 'get_local_gb')
|
||||
def test_get_essential_prop_snmp_true_local_gb_0(self,
|
||||
snmp_mock,
|
||||
call_mock):
|
||||
call_mock,
|
||||
mac_mock):
|
||||
self.client.model = 'Gen9'
|
||||
snmp_credentials = {'auth_user': 'user',
|
||||
'auth_prot_pp': '1234',
|
||||
@@ -1105,11 +1114,14 @@ class IloClientTestCase(testtools.TestCase):
|
||||
call_mock.assert_called_once_with('get_essential_properties')
|
||||
snmp_mock.assert_called_once_with(self.client.info['address'],
|
||||
snmp_credentials)
|
||||
self.assertTrue(mac_mock.called)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_active_macs')
|
||||
@mock.patch.object(snmp_cpqdisk_sizes, 'get_local_gb')
|
||||
@mock.patch.object(client.IloClient, '_call_method')
|
||||
def test_get_essential_prop_snmp_false_local_gb_0(self, call_mock,
|
||||
snmp_mock):
|
||||
snmp_mock,
|
||||
mac_mock):
|
||||
|
||||
self.client.model = 'Gen9'
|
||||
snmp_credentials = {'auth_user': 'user',
|
||||
@@ -1126,6 +1138,44 @@ class IloClientTestCase(testtools.TestCase):
|
||||
self.client.get_essential_properties()
|
||||
call_mock.assert_called_once_with('get_essential_properties')
|
||||
self.assertFalse(snmp_mock.called)
|
||||
self.assertTrue(mac_mock.called)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_active_macs')
|
||||
@mock.patch.object(client.IloClient, '_call_method')
|
||||
def test_get_essential_prop_macs_gen9(self, call_mock,
|
||||
mac_mock):
|
||||
|
||||
self.client.model = 'Gen9'
|
||||
properties = {'local_gb': 123456789}
|
||||
mac_mock.return_value = {'NIC.LOM.1.1': '50:65:F3:6C:47:F8'}
|
||||
mac_dict = {'Port 1': '50:65:F3:6C:47:F8',
|
||||
'Port 2': '50:65:F3:6C:47:F9'}
|
||||
data = {'properties': properties, 'macs': mac_dict}
|
||||
expected_data = {'properties': properties,
|
||||
'macs': {'NIC.LOM.1.1': '50:65:F3:6C:47:F8'}}
|
||||
call_mock.return_value = data
|
||||
actual_data = self.client.get_essential_properties()
|
||||
self.assertEqual(actual_data, expected_data)
|
||||
call_mock.assert_called_once_with('get_essential_properties')
|
||||
self.assertTrue(mac_mock.called)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, 'get_active_macs')
|
||||
@mock.patch.object(client.IloClient, '_call_method')
|
||||
def test_get_essential_prop_macs_gen8(self, call_mock,
|
||||
mac_mock):
|
||||
|
||||
self.client.model = 'Gen8'
|
||||
properties = {'local_gb': 123456789}
|
||||
mac_dict = {'Port 1': '50:65:F3:6C:47:F8',
|
||||
'Port 2': '50:65:F3:6C:47:F9'}
|
||||
data = {'properties': properties, 'macs': mac_dict}
|
||||
expected_data = {'properties': properties,
|
||||
'macs': mac_dict}
|
||||
call_mock.return_value = data
|
||||
actual_data = self.client.get_essential_properties()
|
||||
self.assertEqual(actual_data, expected_data)
|
||||
call_mock.assert_called_once_with('get_essential_properties')
|
||||
self.assertFalse(mac_mock.called)
|
||||
|
||||
@mock.patch.object(client.IloClient, '_call_method')
|
||||
def test_inject_nmi(self, call_mock):
|
||||
|
||||
@@ -712,11 +712,13 @@ class IloRibclTestCase(unittest.TestCase):
|
||||
self.assertIsInstance(gpu_cnt, dict)
|
||||
self.assertIn('pci_gpu_devices', gpu_cnt)
|
||||
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'get_product_name')
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'get_host_health_data')
|
||||
def test_get_essential_properties(self, health_data_mock):
|
||||
def test_get_essential_properties(self, health_data_mock, prod_mock):
|
||||
data = constants.GET_EMBEDDED_HEALTH_OUTPUT
|
||||
json_data = json.loads(data)
|
||||
health_data_mock.return_value = json_data
|
||||
prod_mock.return_value = "Gen8"
|
||||
expected_properties = {'macs': {
|
||||
u'Port 4': u'40:a8:f0:1e:86:77',
|
||||
u'Port 3': u'40:a8:f0:1e:86:76',
|
||||
@@ -735,6 +737,26 @@ class IloRibclTestCase(unittest.TestCase):
|
||||
self.assertIn('properties', properties)
|
||||
self.assertEqual(expected_properties, properties)
|
||||
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'get_product_name')
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'get_host_health_data')
|
||||
def test_get_essential_properties_Gen9(self, health_data_mock, prod_mock):
|
||||
data = constants.GET_EMBEDDED_HEALTH_OUTPUT
|
||||
json_data = json.loads(data)
|
||||
health_data_mock.return_value = json_data
|
||||
prod_mock.return_value = "Gen9"
|
||||
expected_properties = {'macs': {},
|
||||
'properties': {
|
||||
'memory_mb': 32768,
|
||||
'cpu_arch': 'x86_64',
|
||||
'local_gb': 98,
|
||||
'cpus': 32}
|
||||
}
|
||||
properties = self.ilo.get_essential_properties()
|
||||
self.assertIsInstance(properties, dict)
|
||||
self.assertIn('macs', properties)
|
||||
self.assertIn('properties', properties)
|
||||
self.assertEqual(expected_properties, properties)
|
||||
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'get_product_name')
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'get_host_health_data')
|
||||
@mock.patch.object(ribcl.RIBCLOperations, 'get_supported_boot_mode')
|
||||
|
||||
@@ -2641,3 +2641,94 @@ class TestRISOperationsPrivateMethods(testtools.TestCase):
|
||||
'ProLiant BL460c Gen9',
|
||||
self.client.create_raid_configuration,
|
||||
raid_config)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||
@mock.patch.object(ris.RISOperations, '_get_host_details')
|
||||
def test__get_network_adapters(self, get_host_details_mock, get_mock):
|
||||
system_data = json.loads(ris_outputs.RESPONSE_BODY_FOR_REST_OP)
|
||||
get_host_details_mock.return_value = system_data
|
||||
net_uri = '/rest/v1/Systems/1/NetworkAdapters'
|
||||
net_list = json.loads(ris_outputs.NETWORK_ADAPTER_LIST)
|
||||
|
||||
get_mock.return_value = (200, ris_outputs.GET_HEADERS,
|
||||
net_list)
|
||||
self.client._get_network_adapters()
|
||||
get_mock.assert_called_once_with(net_uri)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||
@mock.patch.object(ris.RISOperations, '_get_host_details')
|
||||
def test__get_network_adapters_fail(self, get_host_details_mock,
|
||||
get_mock):
|
||||
system_data = json.loads(ris_outputs.RESPONSE_BODY_FOR_REST_OP)
|
||||
get_host_details_mock.return_value = system_data
|
||||
net_uri = '/rest/v1/Systems/1/NetworkAdapters'
|
||||
net_list = json.loads(ris_outputs.NETWORK_ADAPTER_LIST)
|
||||
get_mock.return_value = (301, ris_outputs.GET_HEADERS,
|
||||
net_list)
|
||||
self.assertRaises(exception.IloError,
|
||||
self.client._get_network_adapters)
|
||||
get_mock.assert_called_once_with(net_uri)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_get_host_details')
|
||||
def test__get_network_adapters_not_supported(self, get_details_mock):
|
||||
host_response = json.loads(ris_outputs.RESPONSE_BODY_FOR_REST_OP)
|
||||
del host_response['Oem']['Hp']['links']['NetworkAdapters']
|
||||
get_details_mock.return_value = host_response
|
||||
self.assertRaises(exception.IloCommandNotSupportedError,
|
||||
self.client._get_network_adapters)
|
||||
get_details_mock.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||
@mock.patch.object(ris.RISOperations, '_get_network_adapters')
|
||||
def test_get_active_macs_one_mac(self, network_mock, rest_mock):
|
||||
net_details = json.loads(ris_outputs.NETWORK_ADAPTER_LIST)
|
||||
mac_details = json.loads(ris_outputs.ONE_MAC_CONNECTED)
|
||||
network_mock.return_value = net_details
|
||||
uri = '/rest/v1/Systems/1/NetworkAdapters/1'
|
||||
rest_mock.return_value = (200, ris_outputs.GET_HEADERS,
|
||||
mac_details)
|
||||
expected_macs = {'NIC.LOM.1.1': '50:65:F3:6C:47:F8'}
|
||||
actual_macs = self.client.get_active_macs()
|
||||
self.assertEqual(expected_macs, actual_macs)
|
||||
network_mock.assert_called_once_with()
|
||||
rest_mock.assert_called_once_with(uri)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||
@mock.patch.object(ris.RISOperations, '_get_network_adapters')
|
||||
def test_get_active_macs_no_connected_mac(self, network_mock, rest_mock):
|
||||
net_details = json.loads(ris_outputs.NETWORK_ADAPTER_LIST)
|
||||
mac_details = json.loads(ris_outputs.NO_MACS_CONNECTED)
|
||||
network_mock.return_value = net_details
|
||||
rest_mock.return_value = (200, ris_outputs.GET_HEADERS,
|
||||
mac_details)
|
||||
expected_macs = {}
|
||||
actual_macs = self.client.get_active_macs()
|
||||
self.assertEqual(expected_macs, actual_macs)
|
||||
network_mock.assert_called_once_with()
|
||||
self.assertTrue(rest_mock.called)
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_rest_get')
|
||||
@mock.patch.object(ris.RISOperations, '_get_network_adapters')
|
||||
def test_get_active_macs_error(self, network_mock, rest_mock):
|
||||
net_details = json.loads(ris_outputs.NETWORK_ADAPTER_LIST)
|
||||
network_mock.return_value = net_details
|
||||
uri = "/rest/v1/Systems/1/NetworkAdapters/1"
|
||||
rest_mock.return_value = (301, ris_outputs.GET_HEADERS,
|
||||
ris_outputs.REST_FAILURE_OUTPUT)
|
||||
exc = self.assertRaises(exception.IloError,
|
||||
self.client.get_active_macs)
|
||||
network_mock.assert_called_once_with()
|
||||
rest_mock.assert_called_once_with(uri)
|
||||
self.assertIn('FakeFailureMessage', str(exc))
|
||||
|
||||
@mock.patch.object(ris.RISOperations, '_get_network_adapters')
|
||||
def test_get_active_macs_not_supported(self, network_mock):
|
||||
net_details = json.loads(ris_outputs.NETWORK_ADAPTER_LIST)
|
||||
network_mock.return_value = net_details
|
||||
del net_details['links']['Member']
|
||||
exc = self.assertRaises(exception.IloCommandNotSupportedError,
|
||||
self.client.get_active_macs)
|
||||
msg = ('"links" or "links/Member" section in NetworkAdapters'
|
||||
' does not exist')
|
||||
network_mock.assert_called_once_with()
|
||||
self.assertIn(msg, str(exc))
|
||||
|
||||
Reference in New Issue
Block a user