pyghmi 1.5.70__py3-none-any.whl → 1.5.72__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyghmi/ipmi/command.py +2 -2
- pyghmi/ipmi/oem/lenovo/config.py +3 -1
- pyghmi/ipmi/oem/lenovo/handler.py +2 -2
- pyghmi/ipmi/oem/lenovo/imm.py +2 -2
- pyghmi/redfish/command.py +19 -22
- pyghmi/redfish/oem/generic.py +227 -77
- pyghmi/redfish/oem/lenovo/main.py +14 -1
- pyghmi/redfish/oem/lenovo/xcc.py +14 -7
- pyghmi/redfish/oem/lenovo/xcc3.py +137 -0
- {pyghmi-1.5.70.dist-info → pyghmi-1.5.72.dist-info}/METADATA +1 -1
- {pyghmi-1.5.70.dist-info → pyghmi-1.5.72.dist-info}/RECORD +17 -16
- pyghmi-1.5.72.dist-info/pbr.json +1 -0
- pyghmi-1.5.70.dist-info/pbr.json +0 -1
- {pyghmi-1.5.70.dist-info → pyghmi-1.5.72.dist-info}/AUTHORS +0 -0
- {pyghmi-1.5.70.dist-info → pyghmi-1.5.72.dist-info}/LICENSE +0 -0
- {pyghmi-1.5.70.dist-info → pyghmi-1.5.72.dist-info}/WHEEL +0 -0
- {pyghmi-1.5.70.dist-info → pyghmi-1.5.72.dist-info}/entry_points.txt +0 -0
- {pyghmi-1.5.70.dist-info → pyghmi-1.5.72.dist-info}/top_level.txt +0 -0
pyghmi/ipmi/command.py
CHANGED
@@ -849,9 +849,9 @@ class Command(object):
|
|
849
849
|
else:
|
850
850
|
raise Exception("Unrecognized data format " + repr(fetchdata))
|
851
851
|
|
852
|
-
def get_extended_bmc_configuration(self):
|
852
|
+
def get_extended_bmc_configuration(self, hideadvanced=True):
|
853
853
|
self.oem_init()
|
854
|
-
return self._oem.get_extended_bmc_configuration()
|
854
|
+
return self._oem.get_extended_bmc_configuration(hideadvanced=hideadvanced)
|
855
855
|
|
856
856
|
def get_bmc_configuration(self):
|
857
857
|
self.oem_init()
|
pyghmi/ipmi/oem/lenovo/config.py
CHANGED
@@ -272,7 +272,9 @@ class LenovoFirmwareConfig(object):
|
|
272
272
|
cfgfilename = "config"
|
273
273
|
options = {}
|
274
274
|
data = None
|
275
|
-
if self.
|
275
|
+
if not hasattr(self.xc, 'grab_redfish_response_with_status'):
|
276
|
+
rsp = ({}, 500)
|
277
|
+
elif self.connection:
|
276
278
|
rsp = ({}, 200)
|
277
279
|
else:
|
278
280
|
rsp = self.xc.grab_redfish_response_with_status(
|
@@ -1194,9 +1194,9 @@ class OEMHandler(generic.OEMHandler):
|
|
1194
1194
|
return {'height': self._fpc_variant & 0xf, 'slot': 0}
|
1195
1195
|
return super(OEMHandler, self).get_description()
|
1196
1196
|
|
1197
|
-
def get_extended_bmc_configuration(self):
|
1197
|
+
def get_extended_bmc_configuration(self, hideadvanced=True):
|
1198
1198
|
if self.has_xcc:
|
1199
|
-
return self.immhandler.get_extended_bmc_configuration()
|
1199
|
+
return self.immhandler.get_extended_bmc_configuration(hideadvanced=hideadvanced)
|
1200
1200
|
return super(OEMHandler, self).get_extended_bmc_configuration()
|
1201
1201
|
|
1202
1202
|
def get_bmc_configuration(self):
|
pyghmi/ipmi/oem/lenovo/imm.py
CHANGED
@@ -978,8 +978,8 @@ class XCCClient(IMMClient):
|
|
978
978
|
return {}
|
979
979
|
return {'height': int(dsc['u-height']), 'slot': int(dsc['slot'])}
|
980
980
|
|
981
|
-
def get_extended_bmc_configuration(self):
|
982
|
-
immsettings = self.get_system_configuration(fetchimm=True)
|
981
|
+
def get_extended_bmc_configuration(self, hideadvanced=True):
|
982
|
+
immsettings = self.get_system_configuration(fetchimm=True, hideadvanced=hideadvanced)
|
983
983
|
for setting in list(immsettings):
|
984
984
|
if not setting.startswith('IMM.'):
|
985
985
|
del immsettings[setting]
|
pyghmi/redfish/command.py
CHANGED
@@ -81,20 +81,6 @@ def _mask_to_cidr(mask):
|
|
81
81
|
return cidr
|
82
82
|
|
83
83
|
|
84
|
-
def _to_boolean(attrval):
|
85
|
-
attrval = attrval.lower()
|
86
|
-
if not attrval:
|
87
|
-
return False
|
88
|
-
if ('true'.startswith(attrval) or 'yes'.startswith(attrval)
|
89
|
-
or 'enabled'.startswith(attrval) or attrval == '1'):
|
90
|
-
return True
|
91
|
-
if ('false'.startswith(attrval) or 'no'.startswith(attrval)
|
92
|
-
or 'disabled'.startswith(attrval) or attrval == '0'):
|
93
|
-
return False
|
94
|
-
raise Exception(
|
95
|
-
'Unrecognized candidate for boolean: {0}'.format(attrval))
|
96
|
-
|
97
|
-
|
98
84
|
def _cidr_to_mask(cidr):
|
99
85
|
return socket.inet_ntop(
|
100
86
|
socket.AF_INET, struct.pack(
|
@@ -547,7 +533,7 @@ class Command(object):
|
|
547
533
|
msgid = ','.join(msgid)
|
548
534
|
raise exc.RedfishError(errmsg, msgid=msgid)
|
549
535
|
except (ValueError, KeyError):
|
550
|
-
raise exc.PyghmiException(str(url) + ":" + res[0])
|
536
|
+
raise exc.PyghmiException(str(url) + ":" + str(res[0]))
|
551
537
|
if payload is None and method is None:
|
552
538
|
self._urlcache[url] = {'contents': res[0],
|
553
539
|
'vintage': os.times()[4]}
|
@@ -789,6 +775,9 @@ class Command(object):
|
|
789
775
|
def get_health(self, verbose=True):
|
790
776
|
return self.oem.get_health(self, verbose)
|
791
777
|
|
778
|
+
def get_extended_bmc_configuration(self, hideadvanced=True):
|
779
|
+
return self.oem.get_extended_bmc_configuration(self, hideadvanced=hideadvanced)
|
780
|
+
|
792
781
|
def get_bmc_configuration(self):
|
793
782
|
"""Get miscellaneous BMC configuration
|
794
783
|
|
@@ -823,8 +812,16 @@ class Command(object):
|
|
823
812
|
In many cases, this may render remote network access impracticle or
|
824
813
|
impossible."
|
825
814
|
"""
|
815
|
+
bmcinfo = self._do_web_request(self._bmcurl)
|
816
|
+
rc = bmcinfo.get('Actions', {}).get('#Manager.ResetToDefaults', {})
|
817
|
+
actinf = rc.get('ResetType@Redfish.AllowableValues', [])
|
818
|
+
if 'ResetAll' in actinf:
|
819
|
+
acturl = actinf.get('target', None)
|
820
|
+
if acturl:
|
821
|
+
self._do_web_request(acturl, {'ResetType': 'ResetAll'})
|
822
|
+
return
|
826
823
|
raise exc.UnsupportedFunctionality(
|
827
|
-
'Clear BMC configuration not supported
|
824
|
+
'Clear BMC configuration not supported on this platform')
|
828
825
|
|
829
826
|
def get_system_configuration(self, hideadvanced=True):
|
830
827
|
return self.oem.get_system_configuration(hideadvanced, self)
|
@@ -966,7 +963,7 @@ class Command(object):
|
|
966
963
|
|
967
964
|
def get_firmware(self, components=()):
|
968
965
|
try:
|
969
|
-
for firminfo in self.oem.get_firmware_inventory(components):
|
966
|
+
for firminfo in self.oem.get_firmware_inventory(components, self):
|
970
967
|
yield firminfo
|
971
968
|
except exc.BypassGenericBehavior:
|
972
969
|
return
|
@@ -1081,7 +1078,7 @@ class Command(object):
|
|
1081
1078
|
return self._oem
|
1082
1079
|
|
1083
1080
|
def get_description(self):
|
1084
|
-
return self.oem.get_description()
|
1081
|
+
return self.oem.get_description(self)
|
1085
1082
|
|
1086
1083
|
def get_event_log(self, clear=False):
|
1087
1084
|
bmcinfo = self._do_web_request(self._bmcurl)
|
@@ -1413,20 +1410,20 @@ class Command(object):
|
|
1413
1410
|
return self.oem.get_diagnostic_data(savefile, progress, autosuffix)
|
1414
1411
|
|
1415
1412
|
def get_licenses(self):
|
1416
|
-
return self.oem.get_licenses()
|
1413
|
+
return self.oem.get_licenses(self)
|
1417
1414
|
|
1418
1415
|
def delete_license(self, name):
|
1419
|
-
return self.oem.delete_license(name)
|
1416
|
+
return self.oem.delete_license(name, self)
|
1420
1417
|
|
1421
1418
|
def save_licenses(self, directory):
|
1422
1419
|
if os.path.exists(directory) and not os.path.isdir(directory):
|
1423
1420
|
raise exc.InvalidParameterValue(
|
1424
1421
|
'Not allowed to overwrite existing file: {0}'.format(
|
1425
1422
|
directory))
|
1426
|
-
return self.oem.save_licenses(directory)
|
1423
|
+
return self.oem.save_licenses(directory, self)
|
1427
1424
|
|
1428
1425
|
def apply_license(self, filename, progress=None, data=None):
|
1429
|
-
return self.oem.apply_license(filename, progress, data)
|
1426
|
+
return self.oem.apply_license(filename, self, progress, data)
|
1430
1427
|
|
1431
1428
|
|
1432
1429
|
if __name__ == '__main__':
|
pyghmi/redfish/oem/generic.py
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
+
import base64
|
15
16
|
from fnmatch import fnmatch
|
16
17
|
import json
|
17
18
|
import os
|
@@ -43,6 +44,29 @@ class SensorReading(object):
|
|
43
44
|
self.units = units
|
44
45
|
self.unavailable = unavailable
|
45
46
|
|
47
|
+
|
48
|
+
def _to_boolean(attrval):
|
49
|
+
attrval = attrval.lower()
|
50
|
+
if not attrval:
|
51
|
+
return False
|
52
|
+
if ('true'.startswith(attrval) or 'yes'.startswith(attrval)
|
53
|
+
or 'enabled'.startswith(attrval) or attrval == '1'):
|
54
|
+
return True
|
55
|
+
if ('false'.startswith(attrval) or 'no'.startswith(attrval)
|
56
|
+
or 'disabled'.startswith(attrval) or attrval == '0'):
|
57
|
+
return False
|
58
|
+
raise Exception(
|
59
|
+
'Unrecognized candidate for boolean: {0}'.format(attrval))
|
60
|
+
|
61
|
+
|
62
|
+
def _normalize_mac(mac):
|
63
|
+
if ':' not in mac:
|
64
|
+
mac = ':'.join((
|
65
|
+
mac[:2], mac[2:4], mac[4:6],
|
66
|
+
mac[6:8], mac[8:10], mac[10:12]))
|
67
|
+
return mac.lower()
|
68
|
+
|
69
|
+
|
46
70
|
_healthmap = {
|
47
71
|
'Critical': const.Health.Critical,
|
48
72
|
'Unknown': const.Health.Warning,
|
@@ -339,6 +363,38 @@ class OEMHandler(object):
|
|
339
363
|
def get_system_configuration(self, hideadvanced=True, fishclient=None):
|
340
364
|
return self._getsyscfg(fishclient)[0]
|
341
365
|
|
366
|
+
def _get_attrib_registry(self, fishclient, attribreg):
|
367
|
+
overview = fishclient._do_web_request('/redfish/v1/')
|
368
|
+
reglist = overview['Registries']['@odata.id']
|
369
|
+
reglist = fishclient._do_web_request(reglist)
|
370
|
+
regurl = None
|
371
|
+
for cand in reglist.get('Members', []):
|
372
|
+
cand = cand.get('@odata.id', '')
|
373
|
+
candname = cand.split('/')[-1]
|
374
|
+
if candname == '': # implementation uses trailing slash
|
375
|
+
candname = cand.split('/')[-2]
|
376
|
+
if candname == attribreg:
|
377
|
+
regurl = cand
|
378
|
+
break
|
379
|
+
if not regurl:
|
380
|
+
# Workaround a vendor bug where they link to a
|
381
|
+
# non-existant name
|
382
|
+
for cand in reglist.get('Members', []):
|
383
|
+
cand = cand.get('@odata.id', '')
|
384
|
+
candname = cand.split('/')[-1]
|
385
|
+
candname = candname.split('.')[0]
|
386
|
+
if candname == attribreg.split('.')[0]:
|
387
|
+
regurl = cand
|
388
|
+
break
|
389
|
+
if regurl:
|
390
|
+
reginfo = fishclient._do_web_request(regurl)
|
391
|
+
for reg in reginfo.get('Location', []):
|
392
|
+
if reg.get('Language', 'en').startswith('en'):
|
393
|
+
reguri = reg['Uri']
|
394
|
+
reginfo = self._get_biosreg(reguri, fishclient)
|
395
|
+
return reginfo
|
396
|
+
extrainfo, valtodisplay, _, self.attrdeps = reginfo
|
397
|
+
|
342
398
|
def _getsyscfg(self, fishclient):
|
343
399
|
biosinfo = self._do_web_request(fishclient._biosurl, cache=False)
|
344
400
|
reginfo = ({}, {}, {}, {})
|
@@ -346,36 +402,9 @@ class OEMHandler(object):
|
|
346
402
|
valtodisplay = {}
|
347
403
|
self.attrdeps = {'Dependencies': [], 'Attributes': []}
|
348
404
|
if 'AttributeRegistry' in biosinfo:
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
regurl = None
|
353
|
-
for cand in reglist.get('Members', []):
|
354
|
-
cand = cand.get('@odata.id', '')
|
355
|
-
candname = cand.split('/')[-1]
|
356
|
-
if candname == '': # implementation uses trailing slash
|
357
|
-
candname = cand.split('/')[-2]
|
358
|
-
if candname == biosinfo['AttributeRegistry']:
|
359
|
-
regurl = cand
|
360
|
-
break
|
361
|
-
if not regurl:
|
362
|
-
# Workaround a vendor bug where they link to a
|
363
|
-
# non-existant name
|
364
|
-
for cand in reglist.get('Members', []):
|
365
|
-
cand = cand.get('@odata.id', '')
|
366
|
-
candname = cand.split('/')[-1]
|
367
|
-
candname = candname.split('.')[0]
|
368
|
-
if candname == biosinfo[
|
369
|
-
'AttributeRegistry'].split('.')[0]:
|
370
|
-
regurl = cand
|
371
|
-
break
|
372
|
-
if regurl:
|
373
|
-
reginfo = fishclient._do_web_request(regurl)
|
374
|
-
for reg in reginfo.get('Location', []):
|
375
|
-
if reg.get('Language', 'en').startswith('en'):
|
376
|
-
reguri = reg['Uri']
|
377
|
-
reginfo = self._get_biosreg(reguri, fishclient)
|
378
|
-
extrainfo, valtodisplay, _, self.attrdeps = reginfo
|
405
|
+
reginfo = self._get_attrib_registry(fishclient, biosinfo['AttributeRegistry'])
|
406
|
+
if reginfo:
|
407
|
+
extrainfo, valtodisplay, _, self.attrdeps = reginfo
|
379
408
|
currsettings = {}
|
380
409
|
try:
|
381
410
|
pendingsettings = fishclient._do_web_request(
|
@@ -412,10 +441,19 @@ class OEMHandler(object):
|
|
412
441
|
rawsettings = fishclient._do_web_request(fishclient._biosurl,
|
413
442
|
cache=False)
|
414
443
|
rawsettings = rawsettings.get('Attributes', {})
|
415
|
-
pendingsettings = fishclient._do_web_request(
|
444
|
+
pendingsettings = fishclient._do_web_request(
|
445
|
+
fishclient._setbiosurl)
|
446
|
+
return self._set_redfish_settings(
|
447
|
+
changeset, fishclient, currsettings, rawsettings,
|
448
|
+
pendingsettings, self.attrdeps, reginfo,
|
449
|
+
fishclient._setbiosurl)
|
450
|
+
|
451
|
+
def _set_redfish_settings(self, changeset, fishclient, currsettings,
|
452
|
+
rawsettings, pendingsettings, attrdeps, reginfo,
|
453
|
+
seturl):
|
416
454
|
etag = pendingsettings.get('@odata.etag', None)
|
417
455
|
pendingsettings = pendingsettings.get('Attributes', {})
|
418
|
-
dephandler = AttrDependencyHandler(
|
456
|
+
dephandler = AttrDependencyHandler(attrdeps, rawsettings,
|
419
457
|
pendingsettings)
|
420
458
|
for change in list(changeset):
|
421
459
|
if change not in currsettings:
|
@@ -434,7 +472,7 @@ class OEMHandler(object):
|
|
434
472
|
changeval = changeset[change]
|
435
473
|
overrides, blameattrs = dephandler.get_overrides(change)
|
436
474
|
meta = {}
|
437
|
-
for attr in
|
475
|
+
for attr in attrdeps['Attributes']:
|
438
476
|
if attr['AttributeName'] == change:
|
439
477
|
meta = dict(attr)
|
440
478
|
break
|
@@ -473,7 +511,7 @@ class OEMHandler(object):
|
|
473
511
|
changeset[change] = _to_boolean(changeset[change])
|
474
512
|
redfishsettings = {'Attributes': changeset}
|
475
513
|
fishclient._do_web_request(
|
476
|
-
|
514
|
+
seturl, redfishsettings, 'PATCH', etag=etag)
|
477
515
|
|
478
516
|
def attach_remote_media(self, url, username, password, vmurls):
|
479
517
|
return None
|
@@ -481,10 +519,10 @@ class OEMHandler(object):
|
|
481
519
|
def detach_remote_media(self):
|
482
520
|
return None
|
483
521
|
|
484
|
-
def get_description(self):
|
522
|
+
def get_description(self, fishclient):
|
485
523
|
return {}
|
486
524
|
|
487
|
-
def get_firmware_inventory(self, components):
|
525
|
+
def get_firmware_inventory(self, components, fishclient):
|
488
526
|
return []
|
489
527
|
|
490
528
|
def set_credentials(self, username, password):
|
@@ -533,6 +571,12 @@ class OEMHandler(object):
|
|
533
571
|
'Model': self._varsysinfo.get(
|
534
572
|
'SKU', self._varsysinfo.get('PartNumber', '')),
|
535
573
|
}
|
574
|
+
if sysinfo['UUID'] and '-' not in sysinfo['UUID']:
|
575
|
+
sysinfo['UUID'] = '-'.join((
|
576
|
+
sysinfo['UUID'][:8], sysinfo['UUID'][8:12],
|
577
|
+
sysinfo['UUID'][12:16], sysinfo['UUID'][16:20],
|
578
|
+
sysinfo['UUID'][20:]))
|
579
|
+
sysinfo['UUID'] = sysinfo['UUID'].lower()
|
536
580
|
return sysinfo
|
537
581
|
else:
|
538
582
|
for invpair in self.get_inventory():
|
@@ -548,6 +592,12 @@ class OEMHandler(object):
|
|
548
592
|
'Model': self._varsysinfo.get(
|
549
593
|
'SKU', self._varsysinfo.get('PartNumber', '')),
|
550
594
|
}
|
595
|
+
if sysinfo['UUID'] and '-' not in sysinfo['UUID']:
|
596
|
+
sysinfo['UUID'] = '-'.join((
|
597
|
+
sysinfo['UUID'][:8], sysinfo['UUID'][8:12],
|
598
|
+
sysinfo['UUID'][12:16], sysinfo['UUID'][16:20],
|
599
|
+
sysinfo['UUID'][20:]))
|
600
|
+
sysinfo['UUID'] = sysinfo['UUID'].lower()
|
551
601
|
yield ('System', sysinfo)
|
552
602
|
self._hwnamemap = {}
|
553
603
|
cpumemurls = []
|
@@ -599,22 +649,39 @@ class OEMHandler(object):
|
|
599
649
|
yield (dname, ddata)
|
600
650
|
|
601
651
|
def _get_adp_inventory(self, onlyname=False, withids=False, urls=None):
|
652
|
+
foundmacs = False
|
653
|
+
macinfobyadpname = {}
|
654
|
+
if 'NetworkInterfaces' in self._varsysinfo:
|
655
|
+
nifurls = self._do_web_request(self._varsysinfo['NetworkInterfaces']['@odata.id'])
|
656
|
+
nifurls = nifurls.get('Members', [])
|
657
|
+
nifurls = [x['@odata.id'] for x in nifurls]
|
658
|
+
for nifurl in nifurls:
|
659
|
+
nifinfo = self._do_web_request(nifurl)
|
660
|
+
|
661
|
+
nadurl = nifinfo.get('Links', {}).get('NetworkAdapter', {}).get("@odata.id")
|
662
|
+
if nadurl:
|
663
|
+
nadinfo = self._do_web_request(nadurl)
|
664
|
+
if 'Name' not in nadinfo:
|
665
|
+
continue
|
666
|
+
nicname = nadinfo['Name']
|
667
|
+
yieldinf = {}
|
668
|
+
macidx = 1
|
669
|
+
for ctrlr in nadinfo.get('Controllers', []):
|
670
|
+
porturls = [x['@odata.id'] for x in ctrlr.get(
|
671
|
+
'Links', {}).get('Ports', [])]
|
672
|
+
for porturl in porturls:
|
673
|
+
portinfo = self._do_web_request(porturl)
|
674
|
+
macs = [x for x in portinfo.get(
|
675
|
+
'Ethernet', {}).get(
|
676
|
+
'AssociatedMACAddresses', [])]
|
677
|
+
for mac in macs:
|
678
|
+
label = 'MAC Address {}'.format(macidx)
|
679
|
+
yieldinf[label] = _normalize_mac(mac)
|
680
|
+
macidx += 1
|
681
|
+
foundmacs = True
|
682
|
+
macinfobyadpname[nicname] = yieldinf
|
602
683
|
if not urls:
|
603
684
|
urls = self._get_adp_urls()
|
604
|
-
if not urls:
|
605
|
-
# No PCIe device inventory, but *maybe* ethernet inventory...
|
606
|
-
aidx = 1
|
607
|
-
for nicinfo in self._get_eth_urls():
|
608
|
-
nicinfo = self._do_web_request(nicinfo)
|
609
|
-
nicname = nicinfo.get('Name', None)
|
610
|
-
nicinfo = nicinfo.get('MACAddress', None)
|
611
|
-
if not nicname:
|
612
|
-
nicname = 'NIC'
|
613
|
-
if nicinfo:
|
614
|
-
yield (nicname,
|
615
|
-
{'MAC Address {0}'.format(aidx): nicinfo})
|
616
|
-
aidx += 1
|
617
|
-
return
|
618
685
|
for inf in self._do_bulk_requests(urls):
|
619
686
|
adpinfo, url = inf
|
620
687
|
aname = adpinfo.get('Name', 'Unknown')
|
@@ -636,6 +703,8 @@ class OEMHandler(object):
|
|
636
703
|
yieldinf = {'Id': adpinfo.get('Id', aname)}
|
637
704
|
else:
|
638
705
|
yieldinf = {}
|
706
|
+
if aname in macinfobyadpname:
|
707
|
+
yieldinf.update(macinfobyadpname[aname])
|
639
708
|
funurls = [x['@odata.id'] for x in functions]
|
640
709
|
for fun in self._do_bulk_requests(funurls):
|
641
710
|
funinfo, url = fun
|
@@ -648,14 +717,42 @@ class OEMHandler(object):
|
|
648
717
|
yieldinf['PCI Subsystem Vendor ID'] = funinfo[
|
649
718
|
'SubsystemVendorId'].replace('0x', '')
|
650
719
|
yieldinf['Type'] = funinfo['DeviceClass']
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
720
|
+
if aname not in macinfobyadpname:
|
721
|
+
for nicinfo in funinfo.get('Links', {}).get(
|
722
|
+
'EthernetInterfaces', []):
|
723
|
+
nicinfo = self._do_web_request(nicinfo['@odata.id'])
|
724
|
+
macaddr = nicinfo.get('MACAddress', None)
|
725
|
+
if macaddr:
|
726
|
+
macaddr = _normalize_mac(macaddr)
|
727
|
+
foundmacs = True
|
728
|
+
yieldinf['MAC Address {0}'.format(nicidx)] = macaddr
|
729
|
+
nicidx += 1
|
730
|
+
if aname in macinfobyadpname:
|
731
|
+
del macinfobyadpname[aname]
|
658
732
|
yield aname, yieldinf
|
733
|
+
if macinfobyadpname:
|
734
|
+
for adp in macinfobyadpname:
|
735
|
+
yield adp, macinfobyadpname[adp]
|
736
|
+
if not foundmacs:
|
737
|
+
# No PCIe device inventory, but *maybe* ethernet inventory...
|
738
|
+
idxsbyname = {}
|
739
|
+
for nicinfo in self._get_eth_urls():
|
740
|
+
nicinfo = self._do_web_request(nicinfo)
|
741
|
+
nicname = nicinfo.get('Name', None)
|
742
|
+
nicinfo = nicinfo.get('MACAddress', nicinfo.get('PermanentAddress', None))
|
743
|
+
if nicinfo and ':' not in nicinfo:
|
744
|
+
nicinfo = ':'.join((
|
745
|
+
nicinfo[:2], nicinfo[2:4], nicinfo[4:6], nicinfo[6:8],
|
746
|
+
nicinfo[8:10], nicinfo[10:12]))
|
747
|
+
if not nicname:
|
748
|
+
nicname = 'NIC'
|
749
|
+
if nicinfo:
|
750
|
+
if nicname not in idxsbyname:
|
751
|
+
idxsbyname[nicname] = 0
|
752
|
+
idxsbyname[nicname] += 1
|
753
|
+
nicinfo = nicinfo.lower()
|
754
|
+
yield (nicname,
|
755
|
+
{'MAC Address {}'.format(idxsbyname[nicname]): nicinfo})
|
659
756
|
|
660
757
|
def _get_eth_urls(self):
|
661
758
|
ethurls = self._varsysinfo.get('EthernetInterfaces', {})
|
@@ -780,20 +877,24 @@ class OEMHandler(object):
|
|
780
877
|
|
781
878
|
def update_firmware(self, filename, data=None, progress=None, bank=None):
|
782
879
|
usd = self._do_web_request('/redfish/v1/UpdateService')
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
880
|
+
upurl = usd.get('MultipartHttpPushUri', None)
|
881
|
+
ismultipart = True
|
882
|
+
if not upurl:
|
883
|
+
ismultipart = False
|
884
|
+
if usd.get('HttpPushUriTargetsBusy', False):
|
885
|
+
raise exc.TemporaryError('Cannot run multtiple updates to '
|
886
|
+
'same target concurrently')
|
887
|
+
try:
|
888
|
+
upurl = usd['HttpPushUri']
|
889
|
+
except KeyError:
|
890
|
+
raise exc.UnsupportedFunctionality('Redfish firmware update only supported for implementations with push update support')
|
891
|
+
if 'HttpPushUriTargetsBusy' in usd:
|
892
|
+
self._do_web_request(
|
893
|
+
'/redfish/v1/UpdateService',
|
894
|
+
{'HttpPushUriTargetsBusy': True}, method='PATCH')
|
794
895
|
try:
|
795
896
|
uploadthread = webclient.FileUploader(
|
796
|
-
self.webclient, upurl, filename, data, formwrap=
|
897
|
+
self.webclient, upurl, filename, data, formwrap=ismultipart,
|
797
898
|
excepterror=False)
|
798
899
|
uploadthread.start()
|
799
900
|
wc = self.webclient
|
@@ -823,6 +924,7 @@ class OEMHandler(object):
|
|
823
924
|
# sometimes we get an empty pgress when transitioning from the apply phase to
|
824
925
|
# the validating phase; add a retry here so we don't exit the loop in this case
|
825
926
|
retry = 3
|
927
|
+
pct = 0.0
|
826
928
|
while not complete and retry > 0:
|
827
929
|
pgress = self._do_web_request(monitorurl, cache=False)
|
828
930
|
if not pgress:
|
@@ -837,7 +939,10 @@ class OEMHandler(object):
|
|
837
939
|
'Suspended'):
|
838
940
|
raise Exception(
|
839
941
|
json.dumps(json.dumps(pgress['Messages'])))
|
840
|
-
|
942
|
+
if 'PercentComplete' in pgress:
|
943
|
+
pct = float(pgress['PercentComplete'])
|
944
|
+
else:
|
945
|
+
print(repr(pgress))
|
841
946
|
complete = state == 'Completed'
|
842
947
|
progress({'phase': phase, 'progress': pct})
|
843
948
|
if complete:
|
@@ -910,17 +1015,62 @@ class OEMHandler(object):
|
|
910
1015
|
raise exc.UnsupportedFunctionality(
|
911
1016
|
'Retrieving diagnostic data is not implemented for this platform')
|
912
1017
|
|
913
|
-
def
|
914
|
-
|
1018
|
+
def _get_license_collection_url(self, fishclient):
|
1019
|
+
overview = fishclient._do_web_request('/redfish/v1/')
|
1020
|
+
licsrv = overview.get('LicenseService', {}).get('@odata.id', None)
|
1021
|
+
if not licsrv:
|
1022
|
+
raise exc.UnsupportedFunctionality()
|
1023
|
+
lcs = fishclient._do_web_request(licsrv)
|
1024
|
+
licenses = lcs.get('Licenses', {}).get('@odata.id',None)
|
1025
|
+
if not licenses:
|
1026
|
+
raise exc.UnsupportedFunctionality()
|
1027
|
+
return licenses
|
915
1028
|
|
916
|
-
def
|
1029
|
+
def get_extended_bmc_configuration(self, fishclient, hideadvanced=True):
|
917
1030
|
raise exc.UnsupportedFunctionality()
|
918
1031
|
|
919
|
-
def
|
920
|
-
|
1032
|
+
def _get_licenses(self, fishclient):
|
1033
|
+
licenses = self._get_license_collection_url(fishclient)
|
1034
|
+
collection = fishclient._do_web_request(licenses)
|
1035
|
+
alllic = [x['@odata.id'] for x in collection.get('Members', [])]
|
1036
|
+
for license in alllic:
|
1037
|
+
licdet = fishclient._do_web_request(license)
|
1038
|
+
state = licdet.get('Status', {}).get('State')
|
1039
|
+
if state != 'Enabled':
|
1040
|
+
continue
|
1041
|
+
yield licdet
|
921
1042
|
|
922
|
-
def
|
923
|
-
|
1043
|
+
def get_licenses(self, fishclient):
|
1044
|
+
for licdet in self._get_licenses(fishclient):
|
1045
|
+
name = licdet['Name']
|
1046
|
+
yield {'name': name, 'state': 'Active'}
|
1047
|
+
|
1048
|
+
def delete_license(self, name, fishclient):
|
1049
|
+
for licdet in self._get_licenses(fishclient):
|
1050
|
+
lname = licdet['Name']
|
1051
|
+
if name == lname:
|
1052
|
+
fishclient._do_web_request(licdet['@odata.id'], method='DELETE')
|
1053
|
+
|
1054
|
+
def save_licenses(self, directory, fishclient):
|
1055
|
+
for licdet in self._get_licenses(fishclient):
|
1056
|
+
dload = licdet.get('DownloadURI', None)
|
1057
|
+
if dload:
|
1058
|
+
filename = os.path.basename(dload)
|
1059
|
+
savefile = os.path.join(directory, filename)
|
1060
|
+
fd = webclient.FileDownloader(fishclient.wc, dload, savefile)
|
1061
|
+
fd.start()
|
1062
|
+
while fd.isAlive():
|
1063
|
+
fd.join(1)
|
1064
|
+
yield savefile
|
1065
|
+
|
1066
|
+
def apply_license(self, filename, fishclient, progress=None, data=None):
|
1067
|
+
licenses = self._get_license_collection_url(fishclient)
|
1068
|
+
if data is None:
|
1069
|
+
data = open(filename, 'rb')
|
1070
|
+
licdata = data.read()
|
1071
|
+
lic64 = base64.b64encode(licdata).decode()
|
1072
|
+
licinfo = {"LicenseString": lic64}
|
1073
|
+
fishclient._do_web_request(licenses, licinfo)
|
924
1074
|
|
925
1075
|
def get_user_expiration(self, uid):
|
926
1076
|
return None
|
@@ -15,15 +15,28 @@
|
|
15
15
|
import pyghmi.redfish.oem.generic as generic
|
16
16
|
from pyghmi.redfish.oem.lenovo import tsma
|
17
17
|
from pyghmi.redfish.oem.lenovo import xcc
|
18
|
+
from pyghmi.redfish.oem.lenovo import xcc3
|
18
19
|
|
19
20
|
|
20
21
|
def get_handler(sysinfo, sysurl, webclient, cache, cmd):
|
21
22
|
leninf = sysinfo.get('Oem', {}).get('Lenovo', {})
|
23
|
+
mgrinfo = {}
|
24
|
+
if leninf:
|
25
|
+
mgrinf, status = webclient.grab_json_response_with_status('/redfish/v1/Managers/1')
|
26
|
+
if status != 200:
|
27
|
+
mgrinfo = {}
|
22
28
|
if not leninf:
|
23
29
|
bmcinfo = cmd.bmcinfo
|
24
30
|
if 'Ami' in bmcinfo.get('Oem', {}):
|
25
31
|
return tsma.TsmHandler(sysinfo, sysurl, webclient, cache)
|
26
|
-
|
32
|
+
elif 'xclarity controller' in mgrinf.get('Model', '').lower():
|
33
|
+
if mgrinf['Model'].endswith('3'):
|
34
|
+
return xcc3.OEMHandler(sysinfo, sysurl, webclient, cache,
|
35
|
+
gpool=cmd._gpool)
|
36
|
+
else:
|
37
|
+
return xcc.OEMHandler(sysinfo, sysurl, webclient, cache,
|
38
|
+
gpool=cmd._gpool)
|
39
|
+
elif 'FrontPanelUSB' in leninf or 'USBManagementPortAssignment' in leninf or sysinfo.get('SKU', '').startswith('7X58'):
|
27
40
|
return xcc.OEMHandler(sysinfo, sysurl, webclient, cache,
|
28
41
|
gpool=cmd._gpool)
|
29
42
|
else:
|
pyghmi/redfish/oem/lenovo/xcc.py
CHANGED
@@ -149,6 +149,13 @@ class OEMHandler(generic.OEMHandler):
|
|
149
149
|
self.fwc = None
|
150
150
|
self.fwo = None
|
151
151
|
|
152
|
+
def get_extended_bmc_configuration(self, fishclient, hideadvanced=True):
|
153
|
+
immsettings = self.get_system_configuration(fetchimm=True, hideadvanced=hideadvanced)
|
154
|
+
for setting in list(immsettings):
|
155
|
+
if not setting.startswith('IMM.'):
|
156
|
+
del immsettings[setting]
|
157
|
+
return immsettings
|
158
|
+
|
152
159
|
def get_system_configuration(self, hideadvanced=True, fishclient=None,
|
153
160
|
fetchimm=False):
|
154
161
|
if not self.fwc:
|
@@ -572,7 +579,7 @@ class OEMHandler(generic.OEMHandler):
|
|
572
579
|
summary['badreadings'] = fallbackdata
|
573
580
|
return summary
|
574
581
|
|
575
|
-
def get_description(self):
|
582
|
+
def get_description(self, fishclient):
|
576
583
|
description = self._do_web_request('/DeviceDescription.json')
|
577
584
|
if description:
|
578
585
|
description = description[0]
|
@@ -667,7 +674,7 @@ class OEMHandler(generic.OEMHandler):
|
|
667
674
|
for diskent in adp.get('aimDisks', ()):
|
668
675
|
yield self._get_disk_firmware_single(diskent)
|
669
676
|
|
670
|
-
def get_firmware_inventory(self, components):
|
677
|
+
def get_firmware_inventory(self, components, fishclient):
|
671
678
|
sysinf = self.wc.grab_json_response('/api/dataset/sys_info')
|
672
679
|
for item in sysinf.get('items', {}):
|
673
680
|
for firm in item.get('firmware', []):
|
@@ -1553,7 +1560,7 @@ class OEMHandler(generic.OEMHandler):
|
|
1553
1560
|
progress({'phase': 'complete'})
|
1554
1561
|
return savefile
|
1555
1562
|
|
1556
|
-
def get_licenses(self):
|
1563
|
+
def get_licenses(self, fishclient):
|
1557
1564
|
licdata = self.wc.grab_json_response('/api/providers/imm_fod')
|
1558
1565
|
for lic in licdata.get('items', [{}])[0].get('keys', []):
|
1559
1566
|
if lic['status'] == 0:
|
@@ -1564,7 +1571,7 @@ class OEMHandler(generic.OEMHandler):
|
|
1564
1571
|
'state': 'Missing required license'
|
1565
1572
|
}
|
1566
1573
|
|
1567
|
-
def delete_license(self, name):
|
1574
|
+
def delete_license(self, name, fishclient):
|
1568
1575
|
licdata = self.wc.grab_json_response('/api/providers/imm_fod')
|
1569
1576
|
for lic in licdata.get('items', [{}])[0].get('keys', []):
|
1570
1577
|
if lic.get('feature', None) == name:
|
@@ -1577,7 +1584,7 @@ class OEMHandler(generic.OEMHandler):
|
|
1577
1584
|
)
|
1578
1585
|
break
|
1579
1586
|
|
1580
|
-
def save_licenses(self, directory):
|
1587
|
+
def save_licenses(self, directory, fishclient):
|
1581
1588
|
licdata = self.wc.grab_json_response('/api/providers/imm_fod')
|
1582
1589
|
for lic in licdata.get('items', [{}])[0].get('keys', []):
|
1583
1590
|
licid = ','.join((str(lic['type']), str(lic['id'])))
|
@@ -1594,7 +1601,7 @@ class OEMHandler(generic.OEMHandler):
|
|
1594
1601
|
self._refresh_token()
|
1595
1602
|
yield savefile
|
1596
1603
|
|
1597
|
-
def apply_license(self, filename, progress=None, data=None):
|
1604
|
+
def apply_license(self, filename, fishclient, progress=None, data=None):
|
1598
1605
|
license_errors = {
|
1599
1606
|
310: "License is for a different model of system",
|
1600
1607
|
311: "License is for a different system serial number",
|
@@ -1618,7 +1625,7 @@ class OEMHandler(generic.OEMHandler):
|
|
1618
1625
|
if rsp.get('return', 0) in license_errors:
|
1619
1626
|
raise pygexc.InvalidParameterValue(
|
1620
1627
|
license_errors[rsp['return']])
|
1621
|
-
return self.get_licenses()
|
1628
|
+
return self.get_licenses(fishclient)
|
1622
1629
|
|
1623
1630
|
def user_delete(self, uid):
|
1624
1631
|
userinfo = self.wc.grab_json_response('/api/dataset/imm_users')
|
@@ -0,0 +1,137 @@
|
|
1
|
+
import pyghmi.redfish.oem.generic as generic
|
2
|
+
import pyghmi.exceptions as pygexc
|
3
|
+
|
4
|
+
|
5
|
+
class OEMHandler(generic.OEMHandler):
|
6
|
+
|
7
|
+
def get_description(self, fishclient):
|
8
|
+
bmcstgs = fishclient._do_web_request('/redfish/v1/Managers/1/Oem/Lenovo/BMCSettings')
|
9
|
+
heightu = bmcstgs.get('Attributes', {}).get('ServerConfigHeightU')
|
10
|
+
return {'height': heightu}
|
11
|
+
|
12
|
+
|
13
|
+
def get_system_configuration(self, hideadvanced=True, fishclient=None):
|
14
|
+
stgs = self._getsyscfg(fishclient)[0]
|
15
|
+
outstgs = {}
|
16
|
+
for stg in stgs:
|
17
|
+
outstgs[f'UEFI.{stg}'] = stgs[stg]
|
18
|
+
return outstgs
|
19
|
+
|
20
|
+
def set_system_configuration(self, changeset, fishclient):
|
21
|
+
bmchangeset = {}
|
22
|
+
vpdchangeset = {}
|
23
|
+
for stg in list(changeset):
|
24
|
+
if stg.startswith('BMC.'):
|
25
|
+
bmchangeset[stg.replace('BMC.', '')] = changeset[stg]
|
26
|
+
del changeset[stg]
|
27
|
+
if stg.startswith('UEFI.'):
|
28
|
+
changeset[stg.replace('UEFI.' '')] = changeset[stg]
|
29
|
+
del changeset[stg]
|
30
|
+
if stg.startswith('VPD.'):
|
31
|
+
vpdchangeset[stg.replace('VPD.', '')] = changeset[stg]
|
32
|
+
del changeset[stg]
|
33
|
+
if changeset:
|
34
|
+
super().set_system_configuration(changeset, fishclient)
|
35
|
+
if bmchangeset:
|
36
|
+
self._set_xcc3_settings(bmchangeset, fishclient)
|
37
|
+
if vpdchangeset:
|
38
|
+
self._set_xcc3_vpd(vpdchangeset, fishclient)
|
39
|
+
|
40
|
+
def _set_xcc3_vpd(self, changeset, fishclient):
|
41
|
+
newvpd = {'Attributes': changeset}
|
42
|
+
fishclient._do_web_request(
|
43
|
+
'/redfish/v1/Chassis/1/Oem/Lenovo/SysvpdSettings/Actions/LenovoSysVpdSettings.SetVpdSettings',
|
44
|
+
newvpd)
|
45
|
+
|
46
|
+
|
47
|
+
def _set_xcc3_settings(self, changeset, fishclient):
|
48
|
+
currsettings, reginfo = self._get_lnv_bmcstgs(fishclient)
|
49
|
+
rawsettings = fishclient._do_web_request('/redfish/v1/Managers/1/Oem/Lenovo/BMCSettings',
|
50
|
+
cache=False)
|
51
|
+
rawsettings = rawsettings.get('Attributes', {})
|
52
|
+
pendingsettings = {}
|
53
|
+
ret = self._set_redfish_settings(
|
54
|
+
changeset, fishclient, currsettings, rawsettings,
|
55
|
+
pendingsettings, self.lenovobmcattrdeps, reginfo,
|
56
|
+
'/redfish/v1/Managers/1/Oem/Lenovo/BMCSettings')
|
57
|
+
fishclient._do_web_request('/redfish/v1/Managers/1/Oem/Lenovo/BMCSettings', cache=False)
|
58
|
+
return ret
|
59
|
+
|
60
|
+
def get_extended_bmc_configuration(self, fishclient, hideadvanced=True):
|
61
|
+
cfgin = self._get_lnv_bmcstgs(fishclient)[0]
|
62
|
+
cfgout = {}
|
63
|
+
for stgname in cfgin:
|
64
|
+
cfgout[f'BMC.{stgname}'] = cfgin[stgname]
|
65
|
+
vpdin = self._get_lnv_vpd(fishclient)[0]
|
66
|
+
for stgname in vpdin:
|
67
|
+
cfgout[f'VPD.{stgname}'] = vpdin[stgname]
|
68
|
+
return cfgout
|
69
|
+
|
70
|
+
def _get_lnv_vpd(self, fishclient):
|
71
|
+
currsettings, reginfo = self._get_lnv_stgs(
|
72
|
+
fishclient, '/redfish/v1/Chassis/1/Oem/Lenovo/SysvpdSettings')
|
73
|
+
self.lenovobmcattrdeps = reginfo[3]
|
74
|
+
return currsettings, reginfo
|
75
|
+
|
76
|
+
def _get_lnv_bmcstgs(self, fishclient):
|
77
|
+
currsettings, reginfo = self._get_lnv_stgs(
|
78
|
+
fishclient, '/redfish/v1/Managers/1/Oem/Lenovo/BMCSettings')
|
79
|
+
self.lenovobmcattrdeps = reginfo[3]
|
80
|
+
return currsettings, reginfo
|
81
|
+
|
82
|
+
def _get_lnv_stgs(self, fishclient, url):
|
83
|
+
bmcstgs = fishclient._do_web_request(url)
|
84
|
+
bmcreg = bmcstgs.get('AttributeRegistry', None)
|
85
|
+
extrainfo = {}
|
86
|
+
valtodisplay = {}
|
87
|
+
currsettings = {}
|
88
|
+
reginfo = {}, {}, {}, {}
|
89
|
+
if bmcreg:
|
90
|
+
reginfo = self._get_attrib_registry(fishclient, bmcreg)
|
91
|
+
if reginfo:
|
92
|
+
extrainfo, valtodisplay, _, _ = reginfo
|
93
|
+
for setting in bmcstgs.get('Attributes', {}):
|
94
|
+
val = bmcstgs['Attributes'][setting]
|
95
|
+
currval = val
|
96
|
+
val = valtodisplay.get(setting, {}).get(val, val)
|
97
|
+
val = {'value': val}
|
98
|
+
val.update(**extrainfo.get(setting, {}))
|
99
|
+
currsettings[setting] = val
|
100
|
+
return currsettings, reginfo
|
101
|
+
|
102
|
+
def get_firmware_inventory(self, components, fishclient):
|
103
|
+
fwlist = fishclient._do_web_request(fishclient._fwinventory)
|
104
|
+
rawfwurls = [x['@odata.id'] for x in fwlist.get('Members', [])]
|
105
|
+
fwurls = []
|
106
|
+
for fwurl in rawfwurls:
|
107
|
+
if fwurl.startswith('/redfish/v1/UpdateService/FirmwareInventory/Bundle.'):
|
108
|
+
continue # skip Bundle information for now
|
109
|
+
fwurls.append(fwurl)
|
110
|
+
self._fwnamemap = {}
|
111
|
+
for res in fishclient._do_bulk_requests(fwurls):
|
112
|
+
redres = res[0]
|
113
|
+
if redres.get('Name', '').startswith('Firmware:'):
|
114
|
+
redres['Name'] = redres['Name'].replace('Firmware:', '')
|
115
|
+
if redres['Name'].startswith('Firmware-PSoC') and 'Drive_Backplane' in redres["@odata.id"]:
|
116
|
+
redres['Name'] = 'Drive Backplane'
|
117
|
+
if redres['Name'].startswith('DEVICE-'):
|
118
|
+
redres['Name'] = redres['Name'].replace('DEVICE-', '')
|
119
|
+
if redres['Name'].startswith('POWER-PSU'):
|
120
|
+
redres['Name'] = redres['Name'].replace('POWER-', '')
|
121
|
+
swid = redres.get('SoftwareId', '')
|
122
|
+
buildid = ''
|
123
|
+
version = redres.get('Version', None)
|
124
|
+
if swid.startswith('FPGA-') or swid.startswith('UEFI-') or swid.startswith('BMC-'):
|
125
|
+
buildid = swid.split('-')[1] + version.split('-')[0]
|
126
|
+
version = '-'.join(version.split('-')[1:])
|
127
|
+
if version:
|
128
|
+
redres['Version'] = version
|
129
|
+
cres = fishclient._extract_fwinfo(res)
|
130
|
+
if cres[0] is None:
|
131
|
+
continue
|
132
|
+
if buildid:
|
133
|
+
cres[1]['build'] = buildid
|
134
|
+
yield cres
|
135
|
+
raise pygexc.BypassGenericBehavior()
|
136
|
+
|
137
|
+
|
@@ -11,7 +11,7 @@ pyghmi/cmd/pyghmiutil.py,sha256=hir7FFvwKDNxYGpOPCgIVSgHP4UsVKFIbVBgBWqkBxA,2917
|
|
11
11
|
pyghmi/cmd/virshbmc.py,sha256=rNbRJrVnx5BmQQLVRV8JK3lW9YWUcP7Z8hCWfpfVLCM,5149
|
12
12
|
pyghmi/ipmi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
13
|
pyghmi/ipmi/bmc.py,sha256=LJBF90msq8xFcZSUe3s3jVcW02Ib-0Fc5zWvQNtGmcQ,7283
|
14
|
-
pyghmi/ipmi/command.py,sha256=
|
14
|
+
pyghmi/ipmi/command.py,sha256=DkqKeuicNL02JY2pQzZJwJLRvgH3Uakr5DKm0ElPFkY,90345
|
15
15
|
pyghmi/ipmi/console.py,sha256=Jle7uJI3ZQS6cMwbEisFEvXjmu5MVqMs17BcAlygR_4,23369
|
16
16
|
pyghmi/ipmi/events.py,sha256=zgUidJIARHomwxasgeYAzDO1AEMfEOzb6XVxzry22Us,22569
|
17
17
|
pyghmi/ipmi/fru.py,sha256=sw5ZBMrEVSBDgOUPVU_ksehQMJvrl2v-r7rVyA9xoiE,14430
|
@@ -20,14 +20,14 @@ pyghmi/ipmi/oem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
pyghmi/ipmi/oem/generic.py,sha256=HQ-9qTYIBpZqB1K75jTOTSUsirrKAQcI8BhLx0eAJ1g,18518
|
21
21
|
pyghmi/ipmi/oem/lookup.py,sha256=Ex00OEEolsdWCVhyP0QDGzOxHGEA7sKI8a8fW4kJPD8,3653
|
22
22
|
pyghmi/ipmi/oem/lenovo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
|
-
pyghmi/ipmi/oem/lenovo/config.py,sha256=
|
23
|
+
pyghmi/ipmi/oem/lenovo/config.py,sha256=jSA8_NACwzouLpAhsu591QQFaBYPEU7NHvhpEddLQpg,26105
|
24
24
|
pyghmi/ipmi/oem/lenovo/cpu.py,sha256=POZMP9n2S1v6r8iNStkCOVEiQYs3ut3RqL_9x-kgOFw,1651
|
25
25
|
pyghmi/ipmi/oem/lenovo/dimm.py,sha256=L8k1aBgtvxqyubDBNKdDkz80pDE8Sck1eMLcMz1GhFI,1875
|
26
26
|
pyghmi/ipmi/oem/lenovo/drive.py,sha256=MmVgaosEwJXcwi1kKYGnY-dbrx4Zp55941qWMvprUMA,2055
|
27
27
|
pyghmi/ipmi/oem/lenovo/energy.py,sha256=THttIqlwpnj7ljbBWTHjelDLmDaQiCuMvNqJy9Ec7j8,6355
|
28
28
|
pyghmi/ipmi/oem/lenovo/firmware.py,sha256=KS9uUBjFUzvdMw_e-kpr5sYIvFUaeg0yqyo69T94IVc,3747
|
29
|
-
pyghmi/ipmi/oem/lenovo/handler.py,sha256=
|
30
|
-
pyghmi/ipmi/oem/lenovo/imm.py,sha256=
|
29
|
+
pyghmi/ipmi/oem/lenovo/handler.py,sha256=8OBkpxpPiwRFnBBCbs7RI4HtrdPT9k-cpZTEbAuuiG4,56536
|
30
|
+
pyghmi/ipmi/oem/lenovo/imm.py,sha256=2LFdzkTvgn4VaaXTHVazv6TTAosEAyIs77FMB6_fIBI,111202
|
31
31
|
pyghmi/ipmi/oem/lenovo/inventory.py,sha256=FLJJinw-ibdHtf3KmrTzhWXbQrpxq3TSycVf96Hg7cw,5911
|
32
32
|
pyghmi/ipmi/oem/lenovo/nextscale.py,sha256=ojLh17M87GnKUl-3yCTJcIJca1mpcrhlc7rQmhpby3A,43407
|
33
33
|
pyghmi/ipmi/oem/lenovo/pci.py,sha256=S7p-5Q2qu2YhlffN-LEmIvjfXim6OlfYL7Q6r6VZqJ4,2020
|
@@ -43,17 +43,18 @@ pyghmi/ipmi/private/simplesession.py,sha256=cNGaoT0uWIKDut6gUG9kAOX_b_qTzdB26R6I
|
|
43
43
|
pyghmi/ipmi/private/spd.py,sha256=oEPSXm19X2eNXDiyW_6fVjBFqhuuMAtBI9quRJgclH4,27094
|
44
44
|
pyghmi/ipmi/private/util.py,sha256=ayYodiSydlrrt0_pQppoRB1T6n-KNOiHZSfAlCMcpG0,3847
|
45
45
|
pyghmi/redfish/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
46
|
-
pyghmi/redfish/command.py,sha256=
|
46
|
+
pyghmi/redfish/command.py,sha256=SEiaw74uQQTzGrRkWFRKRcGnVpHXd2Kvgch4Ty_7oks,57340
|
47
47
|
pyghmi/redfish/oem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
|
-
pyghmi/redfish/oem/generic.py,sha256=
|
48
|
+
pyghmi/redfish/oem/generic.py,sha256=lOj8FgJOMC5rLj4IHM0Bfls4NkRNVFHrGw__FHjFjEc,46367
|
49
49
|
pyghmi/redfish/oem/lookup.py,sha256=pfJW5xSkUY61OirMeYy0b1SbjBFz6IDfN5ZOYog_Yq4,1530
|
50
50
|
pyghmi/redfish/oem/dell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
51
51
|
pyghmi/redfish/oem/dell/idrac.py,sha256=pNnmqdV1sOP3ABw0xq0wF1QEO2L8onT7Osc_-sDO8EU,2146
|
52
52
|
pyghmi/redfish/oem/dell/main.py,sha256=g8773SShUpbYxXB9zVx2pD5z1xP04wB_sXAxcAs6_xY,793
|
53
53
|
pyghmi/redfish/oem/lenovo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
|
-
pyghmi/redfish/oem/lenovo/main.py,sha256
|
54
|
+
pyghmi/redfish/oem/lenovo/main.py,sha256=-50u7hTT8urunKTOult2MNMAqLU09sOv_cJZsViwGcU,2249
|
55
55
|
pyghmi/redfish/oem/lenovo/tsma.py,sha256=puSj0fO5Dt5VpDoEMVTRY95CP9q18eXcAqq7TDK350E,34633
|
56
|
-
pyghmi/redfish/oem/lenovo/xcc.py,sha256=
|
56
|
+
pyghmi/redfish/oem/lenovo/xcc.py,sha256=wsAo-69qSV1eamFLBDx-dS3dn67V05xUrWfK7r8f0_g,82705
|
57
|
+
pyghmi/redfish/oem/lenovo/xcc3.py,sha256=p0tDMXVm4Z7oheindI0RInth8xvCLBt8CqwS42T1cMQ,5843
|
57
58
|
pyghmi/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
58
59
|
pyghmi/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
60
|
pyghmi/tests/unit/base.py,sha256=xWImA7zPRgfrEe2xAdRZ6w_dLwExGRBJ5CBybssUQGg,744
|
@@ -62,11 +63,11 @@ pyghmi/tests/unit/ipmi/test_sdr.py,sha256=vb3iLY0cnHJ2K_m4xgYUjEcbPd_ZYhYx-uBowB
|
|
62
63
|
pyghmi/util/__init__.py,sha256=GZLBWJiun2Plb_VE9dDSh4_PQMCha3gA7QLUqx3oSYI,25
|
63
64
|
pyghmi/util/parse.py,sha256=6VlyBCEcE8gy8PJWmEDdtCyWATaKwPaTswCdioPCWOE,2120
|
64
65
|
pyghmi/util/webclient.py,sha256=jV091_s-HWNDVMKfMxB5XljqiwinQkfXJgHt1u6Umms,14526
|
65
|
-
pyghmi-1.5.
|
66
|
-
pyghmi-1.5.
|
67
|
-
pyghmi-1.5.
|
68
|
-
pyghmi-1.5.
|
69
|
-
pyghmi-1.5.
|
70
|
-
pyghmi-1.5.
|
71
|
-
pyghmi-1.5.
|
72
|
-
pyghmi-1.5.
|
66
|
+
pyghmi-1.5.72.dist-info/AUTHORS,sha256=-0iHKtdQwAJfAGKcruCnvcQXrXuE_LgBZ3P15DJI1xY,2044
|
67
|
+
pyghmi-1.5.72.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
68
|
+
pyghmi-1.5.72.dist-info/METADATA,sha256=RHABrdEfRdrxJAbFBYVzLnYMfik-0KQmilz1mbfOq_I,1119
|
69
|
+
pyghmi-1.5.72.dist-info/WHEEL,sha256=g4nMs7d-Xl9-xC9XovUrsDHGXt-FT0E17Yqo92DEfvY,92
|
70
|
+
pyghmi-1.5.72.dist-info/entry_points.txt,sha256=WkbeJkEZzG9MOILxkaEPSEQ109YP9euntH9kcxbysuk,169
|
71
|
+
pyghmi-1.5.72.dist-info/pbr.json,sha256=xzV_2z-mjUTo-ASlE1utsOowAV3Aa33TPNq7HGCInsg,46
|
72
|
+
pyghmi-1.5.72.dist-info/top_level.txt,sha256=aDtt6S9eVu6-tNdaUs4Pz9PbdUd69bziZZMhNvk9Ulc,7
|
73
|
+
pyghmi-1.5.72.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
{"git_version": "b6776ce", "is_release": true}
|
pyghmi-1.5.70.dist-info/pbr.json
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"git_version": "3673666", "is_release": true}
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|