2
0
mirror of https://opendev.org/x/pyghmi synced 2025-01-27 19:37:44 +00:00

Add Hardware inventory from Lenovo Agentless

Lenovo System X systems offer up more inventory over agentless.
Provide this data when the possibility presents itself.

Change-Id: Ic377e951b5a6308157891f98dfdad6311337af48
This commit is contained in:
Jarrod Johnson 2016-05-04 10:25:23 -04:00
parent 6f807ebc42
commit c634450230
2 changed files with 116 additions and 1 deletions

View File

@ -116,6 +116,7 @@ led_status = {
0xFF: "On"
}
led_status_default = "Blink"
mac_format = '{0:02x}:{1:02x}:{2:02x}:{3:02x}:{4:02x}:{5:02x}'
def _megarac_abbrev_image(name):
@ -292,6 +293,8 @@ class OEMHandler(generic.OEMHandler):
if not self.oem_inventory_info:
self._collect_tsm_inventory()
return iter(self.oem_inventory_info)
elif self.has_imm:
return imm.get_hw_descriptions(self.ipmicmd, self._certverify)
return ()
def get_oem_inventory(self):
@ -299,6 +302,9 @@ class OEMHandler(generic.OEMHandler):
self._collect_tsm_inventory()
for compname in self.oem_inventory_info:
yield (compname, self.oem_inventory_info[compname])
elif self.has_imm:
for inv in imm.get_hw_inventory(self.ipmicmd, self._certverify):
yield inv
def get_sensor_data(self):
if self.is_fpc:
@ -319,6 +325,9 @@ class OEMHandler(generic.OEMHandler):
if self.has_tsm:
self._collect_tsm_inventory()
return self.oem_inventory_info.get(component, None)
if self.has_imm:
return imm.get_component_inventory(self.ipmicmd, self._certverify,
component)
def _collect_tsm_inventory(self):
self.oem_inventory_info = {}
@ -415,7 +424,34 @@ class OEMHandler(generic.OEMHandler):
byteguid.extend('\x00' * (16 - len(byteguid)))
if byteguid not in ('\x20' * 16, '\x00' * 16, '\xff' * 16):
fru['UUID'] = util.decode_wireformat_uuid(byteguid)
except (AttributeError, KeyError):
except (AttributeError, KeyError, IndexError):
pass
return fru
elif self.has_imm:
fru['oem_parser'] = 'lenovo'
try:
bextra = fru['board_extra']
fru['FRU Number'] = bextra[0]
fru['Revision'] = bextra[4]
macs = bextra[6]
macprefix = None
idx = 0
endidx = len(macs) - 5
macprefix = None
while idx < endidx:
currmac = macs[idx:idx+6]
if currmac == b'\x00\x00\x00\x00\x00\x00':
break
# VPD may veer off, detect and break off
if macprefix is None:
macprefix = currmac[:3]
elif currmac[:3] != macprefix:
break
ms = mac_format.format(*currmac)
ifidx = idx / 6 + 1
fru['MAC Address {0}'.format(ifidx)] = ms
idx = idx + 6
except (AttributeError, KeyError, IndexError):
pass
return fru
else:

View File

@ -173,6 +173,85 @@ def fetch_agentless_firmware(ipmicmd, certverify):
wc.request('GET', '/data/logout')
def get_hw_inventory(ipmicmd, certverify):
hwmap = hardware_inventory_map(ipmicmd, certverify)
for key in hwmap:
yield (key, hwmap[key])
def get_hw_descriptions(ipmicmd, certverify):
hwmap = hardware_inventory_map(ipmicmd, certverify)
for key in hwmap:
yield key
def get_component_inventory(ipmicmd, certverify, compname):
hwmap = hardware_inventory_map(ipmicmd, certverify)
try:
return hwmap[compname]
except KeyError:
return None
def hardware_inventory_map(ipmicmd, certverify):
hwmap = get_cached_data(ipmicmd, 'lenovo_cached_hwmap')
if hwmap:
return hwmap
hwmap = {}
wc = None
adapterdata = get_cached_data(ipmicmd, 'lenovo_cached_adapters')
if not adapterdata:
wc = get_web_session(ipmicmd, certverify, wc)
if wc:
adapterdata = wc.grab_json_response(
'/designs/imm/dataproviders/imm_adapters.php')
if adapterdata:
ipmicmd.ipmi_session.lenovo_cached_adapters = (
adapterdata, _monotonic_time())
if adapterdata:
for adata in adapterdata['items']:
skipadapter = False
if not adata['adapter.oobSupported']:
continue
aslot = None
aname = adata['adapter.adapterName']
clabel = adata['adapter.connectorLabel']
if clabel == 'Unknown':
continue
if clabel != 'Onboard':
aslot = adata['adapter.slotNo']
if clabel == 'ML2':
clabel = 'ML2 (Slot {0})'.format(aslot)
else:
clabel = 'Slot {0}'.format(aslot)
bdata = {'location': clabel}
for fundata in adata['adapter.functions']:
bdata['pcislot'] = '{0:02x}:{1:02x}'.format(
fundata['generic.busNo'], fundata['generic.devNo'])
serialdata = fundata.get('vpd.serialNo', None)
if (serialdata and serialdata != 'N/A' and
'---' not in serialdata):
bdata['serial'] = serialdata
partnum = fundata.get('vpd.partNo', None)
if partnum and partnum != 'N/A':
bdata['partnumber'] = partnum
if 'network.pPorts' in fundata:
for portinfo in fundata['network.pPorts']:
for lp in portinfo['logicalPorts']:
ma = lp['networkAddr']
ma = ':'.join(
[ma[i:i+2] for i in xrange(
0, len(ma), 2)]).lower()
bdata['MAC Address {0}'.format(
portinfo['portIndex'])] = ma
elif clabel == 'Onboard': # skip the various onboard non-nic
skipadapter = True
if not skipadapter:
hwmap[aname] = bdata
ipmicmd.ipmi_session.lenovo_cached_hwmap = (hwmap, _monotonic_time())
return hwmap
def get_firmware_inventory(ipmicmd, bmcver, certverify):
# First we fetch the system firmware found in imm properties
# then check for agentless, if agentless, get adapter info using