pyghmi 1.5.70__py3-none-any.whl → 1.5.72__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|