Fix Inspection failure in Gen7

Inspection is failing for Gen7 Servers. Failure occurs because
proliantutils is not compatible with Gen7 servers.

This commit adds the Gen7 support in proliantutils.

Change-Id: Ic3eaa57f3d1606751e5da2320bb4dbdd556f27cc
Closes-Bug: #1613794
This commit is contained in:
ankit 2016-08-18 10:58:56 +00:00 committed by Ankit Kumar
parent 04889efae1
commit a83cde9f93
6 changed files with 355 additions and 29 deletions

View File

@ -3,7 +3,6 @@ Aparna Vikraman <aparnavtce@gmail.com>
Debayan Ray <debayan.ray@gmail.com>
Jim Mankovich <jmank@hp.com>
Nisha Agarwal <agarwalnisha1980@gmail.com>
Paresh Sao <paresh.h.sao@gmail.com>
Pratyusha <pratyusha957@gmail.com>
Ramakrishnan G <rameshg87@gmail.com>
Shivanand Tendulker <stendulker@gmail.com>

View File

@ -1,14 +1,6 @@
CHANGES
=======
2.1.10
------
* Fix for 'raid_config' validation error message
* Providing detailed error message for hpssa
* Fix for InvalidInputError exception
* Fix to accommodate very quick firmware update
2.1.9
-----

View File

@ -68,6 +68,7 @@ class IloClient(operations.IloOperations):
self.info = {'address': host, 'username': login, 'password': password}
self.host = host
self.model = self.ribcl.get_product_name()
self.ribcl.init_model_based_tags(self.model)
LOG.debug(self._("IloClient object created. "
"Model: %(model)s"), {'model': self.model})

View File

@ -72,8 +72,12 @@ class RIBCLOperations(operations.IloOperations):
Implements the base class using RIBCL scripting language to talk
to the iLO.
"""
def __init__(self, host, login, password, timeout=60, port=443,
cacert=None):
"""Constructor for RIBCLOperations.
"""
self.host = host
self.login = login
self.password = password
@ -88,6 +92,30 @@ class RIBCLOperations(operations.IloOperations):
if self.cacert is None:
urllib3.disable_warnings(urllib3_exceptions.InsecureRequestWarning)
def init_model_based_tags(self, model):
"""Initializing the model based memory and NIC information tags.
It should be called just after instantiating a RIBCL object.
ribcl = ribcl.RIBCLOperations(host, login, password, timeout,
port, cacert=cacert)
model = ribcl.get_product_name()
ribcl.init_model_based_tags(model)
Again, model attribute is also set here on the RIBCL object.
:param model: the model string
"""
self.model = model
if 'G7' in self.model:
self.MEMORY_SIZE_TAG = "MEMORY_SIZE"
self.MEMORY_SIZE_NOT_PRESENT_TAG = "Not Installed"
self.NIC_INFORMATION_TAG = "NIC_INFOMATION"
else:
self.MEMORY_SIZE_TAG = "TOTAL_MEMORY_SIZE"
self.MEMORY_SIZE_NOT_PRESENT_TAG = "N/A"
self.NIC_INFORMATION_TAG = "NIC_INFORMATION"
def _request_ilo(self, root, extra_headers=None):
"""Send RIBCL XML data to iLO.
@ -752,10 +780,10 @@ class RIBCLOperations(operations.IloOperations):
:raises:IloError if iLO returns an error in command execution.
"""
data = self.get_host_health_data()
properties = {}
properties['memory_mb'] = self._parse_memory_embedded_health(data)
properties = {
'memory_mb': self._parse_memory_embedded_health(data)
}
cpus, cpu_arch = self._parse_processor_embedded_health(data)
properties['cpus'] = cpus
properties['cpu_arch'] = cpu_arch
@ -809,25 +837,23 @@ class RIBCLOperations(operations.IloOperations):
:param data: the output returned by get_host_health_data()
:returns: memory size in MB.
:raises IloError, if unable to get the memory details.
"""
memory_mb = 0
memory = self.get_value_as_list((data['GET_EMBEDDED_HEALTH_DATA']
['MEMORY']), 'MEMORY_DETAILS_SUMMARY')
memory = self._get_memory_details_value_based_on_model(data)
if memory is None:
msg = "Unable to get memory data. Error: Data missing"
raise exception.IloError(msg)
total_memory_size = 0
for item in memory:
for val in item.values():
memsize = val['TOTAL_MEMORY_SIZE']['VALUE']
if memsize != 'N/A':
memory_bytes = (
strutils.string_to_bytes(
memsize.replace(' ', ''), return_int=True))
memory_mb = int(memory_bytes / (1024 * 1024))
total_memory_size = total_memory_size + memory_mb
for memory_item in memory:
memsize = memory_item[self.MEMORY_SIZE_TAG]["VALUE"]
if memsize != self.MEMORY_SIZE_NOT_PRESENT_TAG:
memory_bytes = (
strutils.string_to_bytes(
memsize.replace(' ', ''), return_int=True))
memory_mb = int(memory_bytes / (1024 * 1024))
total_memory_size = total_memory_size + memory_mb
return total_memory_size
def _parse_processor_embedded_health(self, data):
@ -943,7 +969,8 @@ class RIBCLOperations(operations.IloOperations):
"""
nic_data = self.get_value_as_list((data['GET_EMBEDDED_HEALTH_DATA']
['NIC_INFORMATION']), 'NIC')
[self.NIC_INFORMATION_TAG]), 'NIC')
if nic_data is None:
msg = "Unable to get NIC details. Data missing"
raise exception.IloError(msg)
@ -952,12 +979,14 @@ class RIBCLOperations(operations.IloOperations):
try:
port = item['NETWORK_PORT']['VALUE']
mac = item['MAC_ADDRESS']['VALUE']
location = item['LOCATION']['VALUE']
if location == 'Embedded':
nic_dict[port] = mac
self._update_nic_data_from_nic_info_based_on_model(nic_dict,
item, port,
mac)
except KeyError:
msg = "Unable to get NIC details. Data missing"
raise exception.IloError(msg)
return nic_dict
def _get_firmware_embedded_health(self, data):
@ -1126,6 +1155,35 @@ class RIBCLOperations(operations.IloOperations):
})
return root
def _get_memory_details_value_based_on_model(self, data):
"""This method gives memory details based on model.
:param data: the output returned by get_host_health_data()
:returns : a list of memory details.
"""
if 'G7' in self.model:
return (data['GET_EMBEDDED_HEALTH_DATA']['MEMORY']
['MEMORY_COMPONENTS']['MEMORY_COMPONENT'])
else:
return (data['GET_EMBEDDED_HEALTH_DATA']['MEMORY']
['MEMORY_DETAILS_SUMMARY']).values()
def _update_nic_data_from_nic_info_based_on_model(self, nic_dict, item,
port, mac):
"""This method updates with port number and corresponding mac
:param nic_dict: dictionary contains port number and corresponding mac
:param item: dictionary containing nic details
:param port: Port number
:param mac: mac-address
"""
if 'G7' in self.model:
nic_dict[port] = mac
else:
location = item['LOCATION']['VALUE']
if location == 'Embedded':
nic_dict[port] = mac
# The below block of code is there only for backward-compatibility
# reasons (before commit 47608b6 for ris-support).

View File

@ -1231,6 +1231,201 @@ GET_HOST_POWER_READINGS = '''
</RIBCL>
'''
GET_EMBEDDED_HEALTH_OUTPUT_GEN7 = '''
{
"GET_EMBEDDED_HEALTH_DATA": {
"MEMORY": {
"MEMORY_COMPONENTS": {
"MEMORY_COMPONENT": [
{
"MEMORY_SPEED": {
"VALUE": "0 MHz"
},
"MEMORY_SIZE": {
"VALUE": "Not Installed"
},
"MEMORY_LOCATION": {
"VALUE": "PROC 1 DIMM 1G"
}
},
{
"MEMORY_SPEED": {
"VALUE": "1333 MHz"
},
"MEMORY_SIZE": {
"VALUE": "8192 MB"
},
"MEMORY_LOCATION": {
"VALUE": "PROC 1 DIMM 2D"
}
},
{
"MEMORY_SPEED": {
"VALUE": "1333 MHz"
},
"MEMORY_SIZE": {
"VALUE": "8192 MB"
},
"MEMORY_LOCATION": {
"VALUE": "PROC 1 DIMM 3A"
}
},
{
"MEMORY_SPEED": {
"VALUE": "0 MHz"
},
"MEMORY_SIZE": {
"VALUE": "Not Installed"
},
"MEMORY_LOCATION": {
"VALUE": "PROC 1 DIMM 4H"
}
},
{
"MEMORY_SPEED": {
"VALUE": "1333 MHz"
},
"MEMORY_SIZE": {
"VALUE": "8192 MB"
},
"MEMORY_LOCATION": {
"VALUE": "PROC 1 DIMM 5E"
}
},
{
"MEMORY_SPEED": {
"VALUE": "0 MHz"
},
"MEMORY_SIZE": {
"VALUE": "Not Installed"
},
"MEMORY_LOCATION": {
"VALUE": "PROC 1 DIMM 6B"
}
},
{
"MEMORY_SPEED": {
"VALUE": "1333 MHz"
},
"MEMORY_SIZE": {
"VALUE": "8192 MB"
},
"MEMORY_LOCATION": {
"VALUE": "PROC 1 DIMM 7I"
}
},
{
"MEMORY_SPEED": {
"VALUE": "0 MHz"
},
"MEMORY_SIZE": {
"VALUE": "Not Installed"
},
"MEMORY_LOCATION": {
"VALUE": "PROC 1 DIMM 8F"
}
},
{
"MEMORY_SPEED": {
"VALUE": "0 MHz"
},
"MEMORY_SIZE": {
"VALUE": "Not Installed"
},
"MEMORY_LOCATION": {
"VALUE": "PROC 1 DIMM 9C"
}
}
]
}
},
"NIC_INFOMATION": {
"NIC": [
{
"MAC_ADDRESS": {
"VALUE": "78:ac:c0:fe:49:60"
},
"NETWORK_PORT": {
"VALUE": "Port 1"
}
},
{
"MAC_ADDRESS": {
"VALUE": "78:ac:c0:fe:49:62"
},
"NETWORK_PORT": {
"VALUE": "Port 2"
}
},
{
"MAC_ADDRESS": {
"VALUE": "78:ac:c0:fe:49:64"
},
"NETWORK_PORT": {
"VALUE": "Port 3"
}
},
{
"MAC_ADDRESS": {
"VALUE": "78:ac:c0:fe:49:66"
},
"NETWORK_PORT": {
"VALUE": "Port 4"
}
}
],
"iSCSI": [
{
"MAC_ADDRESS": {
"VALUE": "78:ac:c0:fe:49:61"
},
"NETWORK_PORT": {
"VALUE": "Port 1"
}
},
{
"MAC_ADDRESS": {
"VALUE": "78:ac:c0:fe:49:63"
},
"NETWORK_PORT": {
"VALUE": "Port 2"
}
},
{
"MAC_ADDRESS": {
"VALUE": "78:ac:c0:fe:49:65"
},
"NETWORK_PORT": {
"VALUE": "Port 3"
}
},
{
"MAC_ADDRESS": {
"VALUE": "78:ac:c0:fe:49:67"
},
"NETWORK_PORT": {
"VALUE": "Port 4"
}
}
],
"iLO": {
"MAC_ADDRESS": {
"VALUE": "78:ac:c0:fe:49:68"
},
"NETWORK_PORT": {
"VALUE": "iLO Dedicated Network Port"
}
}
}
},
"RESPONSE": {
"MESSAGE": "No error",
"STATUS": "0x0000"
},
"VERSION": "2.23"
}
'''
GET_EMBEDDED_HEALTH_OUTPUT = '''
{
"GET_EMBEDDED_HEALTH_DATA": {

View File

@ -61,6 +61,8 @@ class MaskedRequestDataTestCase(unittest.TestCase):
self.assertIn(xml_data, str(self.maskedRequestData))
@mock.patch.object(ribcl.RIBCLOperations, 'get_product_name',
lambda x: 'ProLiant DL580 Gen8')
class IloRibclTestCaseInitTestCase(unittest.TestCase):
@mock.patch.object(urllib3, 'disable_warnings')
@ -94,7 +96,21 @@ class IloRibclTestCase(unittest.TestCase):
def setUp(self):
super(IloRibclTestCase, self).setUp()
self.ilo = ribcl.RIBCLOperations("x.x.x.x", "admin", "Admin", 60, 443)
self.ilo = ribcl.RIBCLOperations("x.x.x.x", "admin",
"Admin", 60, 443)
self.ilo.init_model_based_tags('ProLiant DL580 Gen8')
def test_init_model_based_tags_gen7(self):
self.ilo.init_model_based_tags('Proliant DL380 G7')
self.assertEqual(self.ilo.MEMORY_SIZE_TAG, "MEMORY_SIZE")
self.assertEqual(self.ilo.MEMORY_SIZE_NOT_PRESENT_TAG, "Not Installed")
self.assertEqual(self.ilo.NIC_INFORMATION_TAG, "NIC_INFOMATION")
def test_init_model_based_tags(self):
self.ilo.init_model_based_tags('ProLiant DL580 Gen8')
self.assertEqual(self.ilo.MEMORY_SIZE_TAG, "TOTAL_MEMORY_SIZE")
self.assertEqual(self.ilo.MEMORY_SIZE_NOT_PRESENT_TAG, "N/A")
self.assertEqual(self.ilo.NIC_INFORMATION_TAG, "NIC_INFORMATION")
@mock.patch.object(ribcl.RIBCLOperations, '_serialize_xml')
@mock.patch.object(requests, 'post')
@ -528,13 +544,39 @@ class IloRibclTestCase(unittest.TestCase):
json_data)
def test__parse_memory_embedded_health(self):
self.ilo.init_model_based_tags('Proliant DL580 Gen8')
data = constants.GET_EMBEDDED_HEALTH_OUTPUT
json_data = json.loads(data)
memory_mb = self.ilo._parse_memory_embedded_health(json_data)
self.assertEqual('32768', str(memory_mb))
self.assertTrue(type(memory_mb), int)
def test__parse_memory_embedded_health_gen7(self):
self.ilo.model = 'Proliant DL380 G7'
self.ilo.init_model_based_tags('Proliant DL380 G7')
data = constants.GET_EMBEDDED_HEALTH_OUTPUT_GEN7
json_data = json.loads(data)
memory_mb = self.ilo._parse_memory_embedded_health(json_data)
self.assertEqual('32768', str(memory_mb))
self.assertTrue(type(memory_mb), int)
def test__parse_nics_embedded_health_gen7(self):
self.ilo.model = 'Proliant DL380 G7'
self.ilo.init_model_based_tags('Proliant DL380 G7')
data = constants.GET_EMBEDDED_HEALTH_OUTPUT_GEN7
json_data = json.loads(data)
expected_output = {u'Port 4': u'78:ac:c0:fe:49:66',
u'Port 3': u'78:ac:c0:fe:49:64',
u'Port 2': u'78:ac:c0:fe:49:62',
u'Port 1': u'78:ac:c0:fe:49:60'}
nic_data = self.ilo._parse_nics_embedded_health(json_data)
self.assertIsInstance(nic_data, dict)
for key, val in nic_data.items():
self.assertIn("Port", key)
self.assertEqual(expected_output, nic_data)
def test__parse_nics_embedded_health(self):
self.ilo.init_model_based_tags('Proliant DL580 Gen8')
data = constants.GET_EMBEDDED_HEALTH_OUTPUT
json_data = json.loads(data)
expected_output = {u'Port 4': u'40:a8:f0:1e:86:77',
@ -827,6 +869,45 @@ class IloRibclTestCase(unittest.TestCase):
'raw_fw_file.bin',
'invalid_component')
def test__get_memory_details_value_based_on_model_gen7(self):
self.ilo.model = 'Proliant DL380 G7'
data = constants.GET_EMBEDDED_HEALTH_OUTPUT_GEN7
self.assertIn('MEMORY_COMPONENTS', data)
self.assertIn('MEMORY_COMPONENT', data)
def test__get_memory_details_value_based_on_model(self):
self.ilo.model = 'ProLiant DL580 Gen8'
data = constants.GET_EMBEDDED_HEALTH_OUTPUT
self.assertIn('MEMORY_DETAILS_SUMMARY', data)
def test__update_nic_data_from_nic_info_based_on_model_gen7(self):
self.ilo.model = 'Proliant DL380 G7'
nic_dict = {}
item = {'NETWORK_PORT': {'VALUE': 'Port 1'},
'MAC_ADDRESS': {'VALUE': '78:ac:c0:fe:49:60'}}
port = 'Port 1'
mac = '78:ac:c0:fe:49:60'
expected_result = {'Port 1': '78:ac:c0:fe:49:60'}
self.ilo._update_nic_data_from_nic_info_based_on_model(
nic_dict, item, port, mac)
self.assertEqual(expected_result, nic_dict)
def test__update_nic_data_from_nic_info_based_on_model(self):
self.ilo.model = 'ProLiant DL580 Gen8'
nic_dict = {}
item = {'NETWORK_PORT': {'VALUE': 'Port 1'},
'STATUS': {'VALUE': 'Unknown'},
'PORT_DESCRIPTION': {'VALUE': 'N/A'},
'LOCATION': {'VALUE': 'Embedded'},
'MAC_ADDRESS': {'VALUE': '40:a8:f0:1e:86:74'},
'IP_ADDRESS': {'VALUE': 'N/A'}}
port = 'Port 1'
mac = '40:a8:f0:1e:86:74'
expected_result = {'Port 1': '40:a8:f0:1e:86:74'}
self.ilo._update_nic_data_from_nic_info_based_on_model(
nic_dict, item, port, mac)
self.assertEqual(expected_result, nic_dict)
class IloRibclTestCaseBeforeRisSupport(unittest.TestCase):