mirror of
https://opendev.org/x/pyghmi
synced 2025-08-21 02:20:19 +00:00
Add disk inventory when possible from Lenovo IMM
Agentless data may have information about firmware of disks. This commit adds support for reading it when available. Note that some devices may not appear, depending on the drive controller in use and timing factors. Change-Id: I24033a4fe7ed056018dab2747e71845fdcaa5cf0
This commit is contained in:
@@ -87,27 +87,35 @@ def fetch_grouped_properties(ipmicmd, groupinfo):
|
||||
return retdata
|
||||
|
||||
|
||||
def fetch_adapter_firmware(ipmicmd, certverify):
|
||||
adapterdata = None
|
||||
def get_cached_data(ipmicmd, attribute):
|
||||
try:
|
||||
vintage = ipmicmd.ipmi_session.lenovo_cached_adapters[1]
|
||||
if vintage > _monotonic_time() - 30:
|
||||
adapterdata = ipmicmd.ipmi_session.lenovo_cached_adapters[0]
|
||||
kv = getattr(ipmicmd.ipmi_session, attribute)
|
||||
if kv[1] > _monotonic_time() - 30:
|
||||
return kv[0]
|
||||
except AttributeError:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def get_web_session(ipmicmd, certverify, wc):
|
||||
if wc:
|
||||
return wc
|
||||
wc = get_imm_webclient(ipmicmd.bmc, certverify,
|
||||
ipmicmd.ipmi_session.userid,
|
||||
ipmicmd.ipmi_session.password)
|
||||
return wc
|
||||
|
||||
|
||||
def fetch_agentless_firmware(ipmicmd, certverify):
|
||||
wc = None
|
||||
adapterdata = get_cached_data(ipmicmd, 'lenovo_cached_adapters')
|
||||
if not adapterdata:
|
||||
wc = get_imm_webclient(ipmicmd.bmc, certverify,
|
||||
ipmicmd.ipmi_session.userid,
|
||||
ipmicmd.ipmi_session.password)
|
||||
if not wc:
|
||||
return
|
||||
wc.request('GET', '/designs/imm/dataproviders/imm_adapters.php')
|
||||
rsp = wc.getresponse()
|
||||
if rsp.status == 200:
|
||||
adapterdata = json.loads(rsp.read())
|
||||
ipmicmd.ipmi_session.lenovo_cached_adapters = (adapterdata,
|
||||
_monotonic_time())
|
||||
wc.request('GET', '/data/logout')
|
||||
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']:
|
||||
aname = adata['adapter.adapterName']
|
||||
@@ -115,9 +123,9 @@ def fetch_adapter_firmware(ipmicmd, certverify):
|
||||
for fundata in adata['adapter.functions']:
|
||||
fdata = fundata.get('firmwares', ())
|
||||
for firm in fdata:
|
||||
fname = firm['firmwareName']
|
||||
fname = firm['firmwareName'].rstrip()
|
||||
if '.' in fname:
|
||||
fname = firm['description']
|
||||
fname = firm['description'].rstrip()
|
||||
if fname in donenames:
|
||||
# ignore redundant entry
|
||||
continue
|
||||
@@ -128,9 +136,41 @@ def fetch_adapter_firmware(ipmicmd, certverify):
|
||||
if ('releaseDate' in firm and
|
||||
firm['releaseDate'] and
|
||||
firm['releaseDate'] != 'N/A'):
|
||||
bdata['date'] = datetime.strptime(firm['releaseDate'],
|
||||
'%m/%d/%Y')
|
||||
try:
|
||||
bdata['date'] = datetime.strptime(
|
||||
firm['releaseDate'], '%m/%d/%Y')
|
||||
except ValueError:
|
||||
try:
|
||||
bdata['date'] = datetime.strptime(
|
||||
firm['releaseDate'], '%m %d %Y')
|
||||
except ValueError:
|
||||
pass
|
||||
yield ('{0} {1}'.format(aname, fname), bdata)
|
||||
storagedata = get_cached_data(ipmicmd, 'lenovo_cached_storage')
|
||||
if not storagedata:
|
||||
wc = get_web_session(ipmicmd, certverify, wc)
|
||||
if wc:
|
||||
storagedata = wc.grab_json_response(
|
||||
'/designs/imm/dataproviders/raid_alldevices.php')
|
||||
if storagedata:
|
||||
ipmicmd.ipmi_session.lenovo_cached_storage = (
|
||||
storagedata, _monotonic_time())
|
||||
if storagedata and 'items' in storagedata:
|
||||
for adp in storagedata['items']:
|
||||
adpname = adp['storage.vpd.productName']
|
||||
if 'children' not in adp:
|
||||
adp['children'] = ()
|
||||
for diskent in adp['children']:
|
||||
bdata = {}
|
||||
diskname = '{0} Disk {1}'.format(
|
||||
adpname,
|
||||
diskent['storage.slotNo'])
|
||||
bdata['model'] = diskent['storage.vpd.productName'].rstrip()
|
||||
bdata['version'] = diskent['storage.firmwares'][0][
|
||||
'versionStr']
|
||||
yield (diskname, bdata)
|
||||
if wc:
|
||||
wc.request('GET', '/data/logout')
|
||||
|
||||
|
||||
def get_firmware_inventory(ipmicmd, bmcver, certverify):
|
||||
@@ -169,5 +209,5 @@ def get_firmware_inventory(ipmicmd, bmcver, certverify):
|
||||
'build': '/v2/bios/pending_build_id'})
|
||||
if bdata:
|
||||
yield ('UEFI Pending Update', bdata)
|
||||
for firm in fetch_adapter_firmware(ipmicmd, certverify):
|
||||
for firm in fetch_agentless_firmware(ipmicmd, certverify):
|
||||
yield firm
|
||||
|
@@ -20,6 +20,7 @@ __author__ = 'jjohnson2'
|
||||
|
||||
import Cookie
|
||||
import httplib
|
||||
import json
|
||||
import pyghmi.exceptions as pygexc
|
||||
import socket
|
||||
import ssl
|
||||
@@ -53,6 +54,12 @@ class SecureHTTPConnection(httplib.HTTPConnection, object):
|
||||
self.cookies[k] = c[k].value
|
||||
return rsp
|
||||
|
||||
def grab_json_response(self, url):
|
||||
self.request('GET', url)
|
||||
rsp = self.getresponse()
|
||||
if rsp.status == 200:
|
||||
return json.loads(rsp.read())
|
||||
|
||||
def request(self, method, url, body=None, headers=None):
|
||||
if headers is None:
|
||||
headers = {}
|
||||
|
Reference in New Issue
Block a user