pyghmi 1.5.72__py3-none-any.whl → 1.5.75__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 +6 -2
- pyghmi/ipmi/oem/generic.py +3 -1
- pyghmi/ipmi/oem/lenovo/handler.py +3 -1
- pyghmi/ipmi/oem/lenovo/imm.py +9 -0
- pyghmi/redfish/command.py +209 -146
- pyghmi/redfish/oem/generic.py +256 -80
- pyghmi/redfish/oem/lenovo/main.py +10 -3
- pyghmi/redfish/oem/lenovo/smm3.py +85 -0
- pyghmi/redfish/oem/lenovo/xcc3.py +272 -14
- pyghmi/util/webclient.py +32 -8
- {pyghmi-1.5.72.dist-info → pyghmi-1.5.75.dist-info}/METADATA +6 -7
- {pyghmi-1.5.72.dist-info → pyghmi-1.5.75.dist-info}/RECORD +18 -17
- {pyghmi-1.5.72.dist-info → pyghmi-1.5.75.dist-info}/WHEEL +1 -1
- {pyghmi-1.5.72.dist-info → pyghmi-1.5.75.dist-info}/entry_points.txt +0 -1
- pyghmi-1.5.75.dist-info/pbr.json +1 -0
- pyghmi-1.5.72.dist-info/pbr.json +0 -1
- {pyghmi-1.5.72.dist-info → pyghmi-1.5.75.dist-info}/AUTHORS +0 -0
- {pyghmi-1.5.72.dist-info → pyghmi-1.5.75.dist-info}/LICENSE +0 -0
- {pyghmi-1.5.72.dist-info → pyghmi-1.5.75.dist-info}/top_level.txt +0 -0
@@ -1,14 +1,76 @@
|
|
1
|
+
# Copyright 2025 Lenovo Corporation
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
import copy
|
15
|
+
import json
|
1
16
|
import pyghmi.redfish.oem.generic as generic
|
2
17
|
import pyghmi.exceptions as pygexc
|
3
|
-
|
18
|
+
import pyghmi.util.webclient as webclient
|
19
|
+
import zipfile
|
20
|
+
import time
|
21
|
+
import os.path
|
4
22
|
|
5
23
|
class OEMHandler(generic.OEMHandler):
|
6
24
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
|
25
|
+
def supports_expand(self, url):
|
26
|
+
return True
|
27
|
+
|
28
|
+
def get_diagnostic_data(self, savefile, progress=None, autosuffix=False):
|
29
|
+
tsk = self._do_web_request(
|
30
|
+
'/redfish/v1/Systems/1/LogServices/DiagnosticLog/Actions/LogService.CollectDiagnosticData',
|
31
|
+
{"DiagnosticDataType": "Manager", "SelectDataTypes": []})
|
32
|
+
taskrunning = True
|
33
|
+
taskurl = tsk.get('TaskMonitor', None)
|
34
|
+
pct = 0 if taskurl else 100
|
35
|
+
durl = None
|
36
|
+
while pct < 100 and taskrunning:
|
37
|
+
status = self._do_web_request(taskurl)
|
38
|
+
durl = status.get('AdditionalDataURI', '')
|
39
|
+
pct = status.get('PercentComplete', 0)
|
40
|
+
taskrunning = status.get('TaskState', 'Complete') == 'Running'
|
41
|
+
if progress:
|
42
|
+
progress({'phase': 'initializing', 'progress': float(pct)})
|
43
|
+
if taskrunning:
|
44
|
+
time.sleep(3)
|
45
|
+
if not durl:
|
46
|
+
raise Exception("Failed getting service data url")
|
47
|
+
fname = os.path.basename(durl)
|
48
|
+
if autosuffix and not savefile.endswith('.tar.zst'):
|
49
|
+
savefile += '-{0}'.format(fname)
|
50
|
+
fd = webclient.FileDownloader(self.webclient, durl, savefile)
|
51
|
+
fd.start()
|
52
|
+
while fd.isAlive():
|
53
|
+
fd.join(1)
|
54
|
+
if progress and self.webclient.get_download_progress():
|
55
|
+
progress({'phase': 'download',
|
56
|
+
'progress': 100 * self.webclient.get_download_progress()})
|
57
|
+
if fd.exc:
|
58
|
+
raise fd.exc
|
59
|
+
if progress:
|
60
|
+
progress({'phase': 'complete'})
|
61
|
+
return savefile
|
11
62
|
|
63
|
+
def get_system_power_watts(self, fishclient):
|
64
|
+
powerinfo = fishclient._do_web_request('/redfish/v1/Chassis/1/Sensors/power_Sys_Power')
|
65
|
+
return powerinfo['Reading']
|
66
|
+
|
67
|
+
def _get_cpu_temps(self, fishclient):
|
68
|
+
cputemps = []
|
69
|
+
for reading in super()._get_cpu_temps(fishclient):
|
70
|
+
if 'Margin' in reading['Name']:
|
71
|
+
continue
|
72
|
+
cputemps.append(reading)
|
73
|
+
return cputemps
|
12
74
|
|
13
75
|
def get_system_configuration(self, hideadvanced=True, fishclient=None):
|
14
76
|
stgs = self._getsyscfg(fishclient)[0]
|
@@ -25,7 +87,7 @@ class OEMHandler(generic.OEMHandler):
|
|
25
87
|
bmchangeset[stg.replace('BMC.', '')] = changeset[stg]
|
26
88
|
del changeset[stg]
|
27
89
|
if stg.startswith('UEFI.'):
|
28
|
-
changeset[stg.replace('UEFI.' '')] = changeset[stg]
|
90
|
+
changeset[stg.replace('UEFI.', '')] = changeset[stg]
|
29
91
|
del changeset[stg]
|
30
92
|
if stg.startswith('VPD.'):
|
31
93
|
vpdchangeset[stg.replace('VPD.', '')] = changeset[stg]
|
@@ -57,6 +119,159 @@ class OEMHandler(generic.OEMHandler):
|
|
57
119
|
fishclient._do_web_request('/redfish/v1/Managers/1/Oem/Lenovo/BMCSettings', cache=False)
|
58
120
|
return ret
|
59
121
|
|
122
|
+
oemacctmap = {
|
123
|
+
'password_reuse_count': 'MinimumPasswordReuseCycle',
|
124
|
+
'password_change_interval': 'MinimumPasswordChangeIntervalHours',
|
125
|
+
'password_expiration': 'PasswordExpirationPeriodDays',
|
126
|
+
'password_complexity': 'ComplexPassword',
|
127
|
+
}
|
128
|
+
|
129
|
+
acctmap = {
|
130
|
+
'password_login_failures': 'AccountLockoutThreshold',
|
131
|
+
'password_min_length': 'MinPasswordLength',
|
132
|
+
'password_lockout_period': 'AccountLockoutDuration',
|
133
|
+
}
|
134
|
+
|
135
|
+
def update_firmware(self, filename, data=None, progress=None, bank=None, otherfields=()):
|
136
|
+
if not otherfields and bank == 'backup':
|
137
|
+
uxzcount = 0
|
138
|
+
otherfields = {'UpdateParameters': {"Targets": ["/redfish/v1/UpdateService/FirmwareInventory/BMC-Backup"]}}
|
139
|
+
needseek = False
|
140
|
+
if data and hasattr(data, 'read'):
|
141
|
+
if zipfile.is_zipfile(data):
|
142
|
+
needseek = True
|
143
|
+
z = zipfile.ZipFile(data)
|
144
|
+
else:
|
145
|
+
data.seek(0)
|
146
|
+
elif data is None and zipfile.is_zipfile(filename):
|
147
|
+
z = zipfile.ZipFile(filename)
|
148
|
+
if z:
|
149
|
+
for tmpname in z.namelist():
|
150
|
+
if tmpname.startswith('payloads/'):
|
151
|
+
uxzcount += 1
|
152
|
+
if tmpname.endswith('.uxz'):
|
153
|
+
wrappedfilename = tmpname
|
154
|
+
if uxzcount == 1 and wrappedfilename:
|
155
|
+
filename = os.path.basename(wrappedfilename)
|
156
|
+
data = z.open(wrappedfilename)
|
157
|
+
elif needseek:
|
158
|
+
data.seek(0)
|
159
|
+
super().update_firmware(filename, data=data, progress=progress, bank=bank, otherfields=otherfields)
|
160
|
+
|
161
|
+
def get_bmc_configuration(self):
|
162
|
+
settings = {}
|
163
|
+
acctsrv = self._do_web_request('/redfish/v1/AccountService')
|
164
|
+
for oemstg in self.oemacctmap:
|
165
|
+
settings[oemstg] = {
|
166
|
+
'value': acctsrv['Oem']['Lenovo'][self.oemacctmap[oemstg]]}
|
167
|
+
for stg in self.acctmap:
|
168
|
+
settings[stg] = {
|
169
|
+
'value': acctsrv[self.acctmap[stg]]}
|
170
|
+
bmcstgs = self._do_web_request('/redfish/v1/Managers/1/Oem/Lenovo/BMCSettings')
|
171
|
+
bmcattrs = bmcstgs['Attributes']
|
172
|
+
self.ethoverusb = True if 'EthOverUSBEnabled' in bmcattrs else False
|
173
|
+
usbcfg = bmcattrs.get('NetMgrUsb0Enabled', bmcattrs.get('EthOverUSBEnabled', 'False'))
|
174
|
+
usbeth = 'Enable' if usbcfg == 'True' else 'Disable'
|
175
|
+
settings['usb_ethernet'] = {
|
176
|
+
'value': usbeth
|
177
|
+
}
|
178
|
+
usbcfg = bmcattrs.get('NetMgrUsb0PortForwardingEnabled', bmcattrs.get('EthOverUSBPortForwardingEnabled', 'False'))
|
179
|
+
fwd = 'Enable' if usbcfg == 'True' else 'Disable'
|
180
|
+
settings['usb_ethernet_port_forwarding'] = fwd
|
181
|
+
mappings = []
|
182
|
+
for idx in range(1, 11):
|
183
|
+
keyname = 'NetMgrUsb0PortForwardingPortMapping.{}'.format(idx)
|
184
|
+
keyaltname = 'EthOverUSBPortForwardingPortMapping_{}'.format(idx)
|
185
|
+
currval = bmcattrs.get(keyname, bmcattrs.get(keyaltname, '0,0'))
|
186
|
+
if currval == '0,0':
|
187
|
+
continue
|
188
|
+
src, dst = currval.split(',')
|
189
|
+
mappings.append('{}:{}'.format(src,dst))
|
190
|
+
settings['usb_forwarded_ports'] = {'value': ','.join(mappings)}
|
191
|
+
return settings
|
192
|
+
|
193
|
+
def set_bmc_configuration(self, changeset):
|
194
|
+
acctattribs = {}
|
195
|
+
usbsettings = {}
|
196
|
+
for key in changeset:
|
197
|
+
if isinstance(changeset[key], str):
|
198
|
+
changeset[key] = {'value': changeset[key]}
|
199
|
+
currval = changeset[key].get('value', None)
|
200
|
+
if key == 'password_complexity':
|
201
|
+
if currval.lower() in ("false", 0):
|
202
|
+
currval = False
|
203
|
+
elif currval.lower() in ('true', 1):
|
204
|
+
currval = True
|
205
|
+
elif key.lower().startswith('usb_'):
|
206
|
+
if 'forwarded_ports' not in key.lower():
|
207
|
+
currval = currval.lower()
|
208
|
+
if currval and 'disabled'.startswith(currval):
|
209
|
+
currval = 'False'
|
210
|
+
elif currval and 'enabled'.startswith(currval):
|
211
|
+
currval = 'True'
|
212
|
+
else:
|
213
|
+
currval = int(currval)
|
214
|
+
if key.lower() in self.oemacctmap:
|
215
|
+
if 'Oem' not in acctattribs:
|
216
|
+
acctattribs['Oem'] = {'Lenovo': {}}
|
217
|
+
acctattribs['Oem']['Lenovo'][
|
218
|
+
self.oemacctmap[key.lower()]] = currval
|
219
|
+
if key.lower() == 'password_expiration':
|
220
|
+
warntime = str(int(int(currval) * 0.08))
|
221
|
+
acctattribs['Oem']['Lenovo'][
|
222
|
+
'PasswordExpirationWarningPeriod'] = warntime
|
223
|
+
elif key.lower() in self.acctmap:
|
224
|
+
acctattribs[self.acctmap[key.lower()]] = currval
|
225
|
+
elif key.lower() in (
|
226
|
+
'usb_ethernet', 'usb_ethernet_port_forwarding',
|
227
|
+
'usb_forwarded_ports'):
|
228
|
+
usbsettings[key] = currval
|
229
|
+
else:
|
230
|
+
raise pygexc.InvalidParameterValue(
|
231
|
+
'{0} not a known setting'.format(key))
|
232
|
+
if acctattribs:
|
233
|
+
self._do_web_request(
|
234
|
+
'/redfish/v1/AccountService', acctattribs, method='PATCH')
|
235
|
+
self._do_web_request('/redfish/v1/AccountService', cache=False)
|
236
|
+
if usbsettings:
|
237
|
+
self.apply_usb_configuration(usbsettings)
|
238
|
+
|
239
|
+
def apply_usb_configuration(self, usbsettings):
|
240
|
+
bmcattribs = {}
|
241
|
+
if not hasattr(self, 'ethoverusb'):
|
242
|
+
self.get_bmc_configuration()
|
243
|
+
|
244
|
+
if 'usb_forwarded_ports' in usbsettings:
|
245
|
+
pairs = usbsettings['usb_forwarded_ports'].split(',')
|
246
|
+
idx = 1
|
247
|
+
for pair in pairs:
|
248
|
+
if self.ethoverusb:
|
249
|
+
keyname = 'EthOverUSBPortForwardingPortMapping_{}'.format(idx)
|
250
|
+
else:
|
251
|
+
keyname = 'NetMgrUsb0PortForwardingPortMapping.{}'.format(idx)
|
252
|
+
pair = pair.replace(':', ',')
|
253
|
+
bmcattribs[keyname] = pair
|
254
|
+
idx += 1
|
255
|
+
while idx < 11:
|
256
|
+
if self.ethoverusb:
|
257
|
+
keyname = 'EthOverUSBPortForwardingPortMapping_{}'.format(idx)
|
258
|
+
else:
|
259
|
+
keyname = 'NetMgrUsb0PortForwardingPortMapping.{}'.format(idx)
|
260
|
+
bmcattribs[keyname] = '0,0'
|
261
|
+
idx += 1
|
262
|
+
if 'usb_ethernet' in usbsettings:
|
263
|
+
keyname = 'EthOverUSBEnabled' if self.ethoverusb else 'NetMgrUsb0Enabled'
|
264
|
+
bmcattribs[keyname] = usbsettings['usb_ethernet']
|
265
|
+
if 'usb_ethernet_port_forwarding' in usbsettings:
|
266
|
+
keyname = 'EthOverUSBPortForwardingEnabled' if self.ethoverusb else 'NetMgrUsb0PortForwardingEnabled'
|
267
|
+
bmcattribs[keyname] = usbsettings[
|
268
|
+
'usb_ethernet_port_forwarding']
|
269
|
+
self._do_web_request(
|
270
|
+
'/redfish/v1/Managers/1/Oem/Lenovo/BMCSettings',
|
271
|
+
{'Attributes': bmcattribs}, method='PATCH')
|
272
|
+
self._do_web_request(
|
273
|
+
'/redfish/v1/Managers/1/Oem/Lenovo/BMCSettings', cache=False)
|
274
|
+
|
60
275
|
def get_extended_bmc_configuration(self, fishclient, hideadvanced=True):
|
61
276
|
cfgin = self._get_lnv_bmcstgs(fishclient)[0]
|
62
277
|
cfgout = {}
|
@@ -99,17 +314,60 @@ class OEMHandler(generic.OEMHandler):
|
|
99
314
|
currsettings[setting] = val
|
100
315
|
return currsettings, reginfo
|
101
316
|
|
317
|
+
def get_description(self, fishclient):
|
318
|
+
rsp = self._get_expanded_data('/redfish/v1/Chassis')
|
319
|
+
for chassis in rsp['Members']:
|
320
|
+
if (chassis['@odata.id'] == '/redfish/v1/Chassis/1'
|
321
|
+
and chassis['ChassisType'] != 'Blade'):
|
322
|
+
hmm = chassis.get('HeightMm', None)
|
323
|
+
if hmm:
|
324
|
+
return {'height': hmm/44.45}
|
325
|
+
if (chassis['@odata.id'] == '/redfish/v1/Chassis/Enclosure'
|
326
|
+
and chassis.get('ChassisType', None) == 'Enclosure'):
|
327
|
+
try:
|
328
|
+
slot = chassis['Location']['PartLocation']['LocationOrdinalValue']
|
329
|
+
slotnum = (2 * (slot >> 4) - 1) + ((slot & 15) % 10)
|
330
|
+
slotcoord = [slot >> 4, (slot & 15) - 9]
|
331
|
+
return {'slot': slotnum, 'slotlabel': '{:02x}'.format(slot), 'slotcoord': slotcoord}
|
332
|
+
except KeyError:
|
333
|
+
continue
|
334
|
+
return {}
|
335
|
+
|
336
|
+
def upload_media(self, filename, progress=None, data=None):
|
337
|
+
wc = self.webclient
|
338
|
+
uploadthread = webclient.FileUploader(
|
339
|
+
wc, '/rdoc_upload', filename, data,
|
340
|
+
formname='file',
|
341
|
+
formwrap=True)
|
342
|
+
uploadthread.start()
|
343
|
+
while uploadthread.isAlive():
|
344
|
+
uploadthread.join(3)
|
345
|
+
if progress:
|
346
|
+
progress({'phase': 'upload',
|
347
|
+
'progress': 100 * wc.get_upload_progress()})
|
348
|
+
rsp = json.loads(uploadthread.rsp)
|
349
|
+
if rsp['return'] != 0:
|
350
|
+
raise Exception('Issue uploading file')
|
351
|
+
remfilename = rsp['upload_filename']
|
352
|
+
if progress:
|
353
|
+
progress({'phase': 'upload',
|
354
|
+
'progress': 100.0})
|
355
|
+
self._do_web_request(
|
356
|
+
'/redfish/v1/Systems/1/VirtualMedia/RDOC1',
|
357
|
+
{'Image':'file:///gpx/rdocupload/' + remfilename,
|
358
|
+
'WriteProtected': False}, method='PATCH')
|
359
|
+
if progress:
|
360
|
+
progress({'phase': 'complete'})
|
361
|
+
|
102
362
|
def get_firmware_inventory(self, components, fishclient):
|
103
|
-
fwlist = fishclient._do_web_request(fishclient._fwinventory)
|
104
|
-
|
105
|
-
|
106
|
-
for
|
363
|
+
fwlist = fishclient._do_web_request(fishclient._fwinventory + '?$expand=.')
|
364
|
+
fwlist = copy.deepcopy(fwlist.get('Members', []))
|
365
|
+
self._fwnamemap = {}
|
366
|
+
for redres in fwlist:
|
367
|
+
fwurl = redres['@odata.id']
|
368
|
+
res = (redres, fwurl)
|
107
369
|
if fwurl.startswith('/redfish/v1/UpdateService/FirmwareInventory/Bundle.'):
|
108
370
|
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
371
|
if redres.get('Name', '').startswith('Firmware:'):
|
114
372
|
redres['Name'] = redres['Name'].replace('Firmware:', '')
|
115
373
|
if redres['Name'].startswith('Firmware-PSoC') and 'Drive_Backplane' in redres["@odata.id"]:
|
pyghmi/util/webclient.py
CHANGED
@@ -97,8 +97,9 @@ class FileDownloader(threading.Thread):
|
|
97
97
|
|
98
98
|
|
99
99
|
def get_upload_form(filename, data, formname, otherfields):
|
100
|
+
ffilename = filename.split('/')[-1]
|
100
101
|
if not formname:
|
101
|
-
formname =
|
102
|
+
formname = ffilename
|
102
103
|
try:
|
103
104
|
return uploadforms[filename]
|
104
105
|
except KeyError:
|
@@ -106,16 +107,22 @@ def get_upload_form(filename, data, formname, otherfields):
|
|
106
107
|
data = data.read()
|
107
108
|
except AttributeError:
|
108
109
|
pass
|
109
|
-
form =
|
110
|
+
form = b''
|
111
|
+
for ofield in otherfields:
|
112
|
+
tfield = otherfields[ofield]
|
113
|
+
xtra=''
|
114
|
+
if isinstance(tfield, dict):
|
115
|
+
tfield = json.dumps(tfield)
|
116
|
+
xtra = '\r\nContent-Type: application/json'
|
117
|
+
form += (b'--' + BND
|
118
|
+
+ '\r\nContent-Disposition: form-data; '
|
119
|
+
'name="{0}"{1}\r\n\r\n{2}\r\n'.format(
|
120
|
+
ofield, xtra, tfield).encode('utf-8'))
|
121
|
+
form += (b'--' + BND
|
110
122
|
+ '\r\nContent-Disposition: form-data; '
|
111
123
|
'name="{0}"; filename="{1}"\r\n'.format(
|
112
|
-
formname,
|
124
|
+
formname, ffilename).encode('utf-8'))
|
113
125
|
form += b'Content-Type: application/octet-stream\r\n\r\n' + data
|
114
|
-
for ofield in otherfields:
|
115
|
-
form += (b'\r\n--' + BND
|
116
|
-
+ '\r\nContent-Disposition: form-data; '
|
117
|
-
'name="{0}"\r\n\r\n{1}'.format(
|
118
|
-
ofield, otherfields[ofield]).encode('utf-8'))
|
119
126
|
form += b'\r\n--' + BND + b'--\r\n'
|
120
127
|
uploadforms[filename] = form
|
121
128
|
return form
|
@@ -272,6 +279,22 @@ class SecureHTTPConnection(httplib.HTTPConnection, object):
|
|
272
279
|
return json.loads(body) if body else {}, rsp.status
|
273
280
|
return body, rsp.status
|
274
281
|
|
282
|
+
def grab_rsp(self, url, data=None, referer=None, headers=None, method=None):
|
283
|
+
webclient = self.dupe()
|
284
|
+
if isinstance(data, dict):
|
285
|
+
data = json.dumps(data)
|
286
|
+
if data:
|
287
|
+
if not method:
|
288
|
+
method = 'POST'
|
289
|
+
webclient.request(method, url, data, referer=referer,
|
290
|
+
headers=headers)
|
291
|
+
else:
|
292
|
+
if not method:
|
293
|
+
method = 'GET'
|
294
|
+
webclient.request(method, url, referer=referer, headers=headers)
|
295
|
+
rsp = webclient.getresponse()
|
296
|
+
return rsp
|
297
|
+
|
275
298
|
def download(self, url, file):
|
276
299
|
"""Download a file to filename or file object
|
277
300
|
|
@@ -390,3 +413,4 @@ class SecureHTTPConnection(httplib.HTTPConnection, object):
|
|
390
413
|
except httplib.CannotSendRequest:
|
391
414
|
self.broken = True
|
392
415
|
raise
|
416
|
+
|
@@ -1,12 +1,11 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pyghmi
|
3
|
-
Version: 1.5.
|
3
|
+
Version: 1.5.75
|
4
4
|
Summary: Python General Hardware Management Initiative (IPMI and others)
|
5
5
|
Home-page: http://github.com/openstack/pyghmi/
|
6
6
|
Author: Jarrod Johnson
|
7
7
|
Author-email: jjohnson2@lenovo.com
|
8
8
|
License: Apache License, Version 2.0
|
9
|
-
Platform: UNKNOWN
|
10
9
|
Classifier: Intended Audience :: Information Technology
|
11
10
|
Classifier: Intended Audience :: System Administrators
|
12
11
|
Classifier: License :: OSI Approved :: Apache Software License
|
@@ -18,14 +17,14 @@ Classifier: Programming Language :: Python :: 3
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.6
|
19
18
|
Classifier: Programming Language :: Python :: 3.7
|
20
19
|
Classifier: Programming Language :: Python :: 3.8
|
21
|
-
|
22
|
-
|
23
|
-
Requires-Dist:
|
20
|
+
License-File: LICENSE
|
21
|
+
License-File: AUTHORS
|
22
|
+
Requires-Dist: cryptography >=2.1
|
23
|
+
Requires-Dist: python-dateutil >=2.8.1
|
24
|
+
Requires-Dist: six >=1.10.0
|
24
25
|
|
25
26
|
This is a pure python implementation of IPMI protocol.
|
26
27
|
|
27
28
|
pyghmicons and pyghmiutil are example scripts to show how one may incorporate
|
28
29
|
this library into python code
|
29
30
|
|
30
|
-
|
31
|
-
|
@@ -11,13 +11,13 @@ 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=qfoo_s2zosV7prL7IpuAaFwlBRM6ormXnPWqFj1LFoA,90521
|
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
|
18
18
|
pyghmi/ipmi/sdr.py,sha256=U4NH-ca1zwEmU_dKT2wvXY2vEvXh33dV9rIUlmf_5Xw,32999
|
19
19
|
pyghmi/ipmi/oem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
|
-
pyghmi/ipmi/oem/generic.py,sha256
|
20
|
+
pyghmi/ipmi/oem/generic.py,sha256=-5mIxczwkvOdRy2NSPbSgPerQ5AMez-KhC8AkOrwkL0,18614
|
21
21
|
pyghmi/ipmi/oem/lookup.py,sha256=Ex00OEEolsdWCVhyP0QDGzOxHGEA7sKI8a8fW4kJPD8,3653
|
22
22
|
pyghmi/ipmi/oem/lenovo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
23
|
pyghmi/ipmi/oem/lenovo/config.py,sha256=jSA8_NACwzouLpAhsu591QQFaBYPEU7NHvhpEddLQpg,26105
|
@@ -26,8 +26,8 @@ pyghmi/ipmi/oem/lenovo/dimm.py,sha256=L8k1aBgtvxqyubDBNKdDkz80pDE8Sck1eMLcMz1GhF
|
|
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=Y2c_IZph1VE5rP8d2fZASQulDtxL_yGv7bvJNtDxwL8,56632
|
30
|
+
pyghmi/ipmi/oem/lenovo/imm.py,sha256=Yfrafthw1HU7Blw4JWnkryc2AEeUAoVok06A53hKvZc,111538
|
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,18 +43,19 @@ 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=Z-mvtSIVn1FedEGxo7cpf25Kj6vmHspxh3fHvhyGV24,59995
|
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=fcpY1LOYjQoeQ1vUD0pqz_B5QgXB417BAADqJbq54wc,54957
|
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=bnx8LuC_C4_OluNR8JSHIxtSlM4_jdBb4cUzJM6mazE,2597
|
55
|
+
pyghmi/redfish/oem/lenovo/smm3.py,sha256=FWNCR6eSK6a9ZgZ5G-HyAllYkUD5hZeO7oOVKNNslEE,3152
|
55
56
|
pyghmi/redfish/oem/lenovo/tsma.py,sha256=puSj0fO5Dt5VpDoEMVTRY95CP9q18eXcAqq7TDK350E,34633
|
56
57
|
pyghmi/redfish/oem/lenovo/xcc.py,sha256=wsAo-69qSV1eamFLBDx-dS3dn67V05xUrWfK7r8f0_g,82705
|
57
|
-
pyghmi/redfish/oem/lenovo/xcc3.py,sha256=
|
58
|
+
pyghmi/redfish/oem/lenovo/xcc3.py,sha256=pSwFW1zOoi8udjXByWEPVZaMpxsd9BaDhHDs1hNLe3w,17432
|
58
59
|
pyghmi/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
60
|
pyghmi/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
60
61
|
pyghmi/tests/unit/base.py,sha256=xWImA7zPRgfrEe2xAdRZ6w_dLwExGRBJ5CBybssUQGg,744
|
@@ -62,12 +63,12 @@ pyghmi/tests/unit/ipmi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
62
63
|
pyghmi/tests/unit/ipmi/test_sdr.py,sha256=vb3iLY0cnHJ2K_m4xgYUjEcbPd_ZYhYx-uBowByplXw,824
|
63
64
|
pyghmi/util/__init__.py,sha256=GZLBWJiun2Plb_VE9dDSh4_PQMCha3gA7QLUqx3oSYI,25
|
64
65
|
pyghmi/util/parse.py,sha256=6VlyBCEcE8gy8PJWmEDdtCyWATaKwPaTswCdioPCWOE,2120
|
65
|
-
pyghmi/util/webclient.py,sha256=
|
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.
|
73
|
-
pyghmi-1.5.
|
66
|
+
pyghmi/util/webclient.py,sha256=782_yMuy_LuN9E2vh2EJ-R64X_EyvLLRuurE__jfn20,15371
|
67
|
+
pyghmi-1.5.75.dist-info/AUTHORS,sha256=-0iHKtdQwAJfAGKcruCnvcQXrXuE_LgBZ3P15DJI1xY,2044
|
68
|
+
pyghmi-1.5.75.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
69
|
+
pyghmi-1.5.75.dist-info/METADATA,sha256=76V_6mgbQWPgnupAdMeDA2z4dCXBALX56Vh1Rch1nK4,1137
|
70
|
+
pyghmi-1.5.75.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
71
|
+
pyghmi-1.5.75.dist-info/entry_points.txt,sha256=-OpJliDzATxmuPXK0VR3Ma-Yk_i4ZhfIIB-12A26dSI,168
|
72
|
+
pyghmi-1.5.75.dist-info/pbr.json,sha256=CCJ1OeaUszEm9jxLh5Ke72JHEG5JRuOCVK3B6FrUSMY,46
|
73
|
+
pyghmi-1.5.75.dist-info/top_level.txt,sha256=aDtt6S9eVu6-tNdaUs4Pz9PbdUd69bziZZMhNvk9Ulc,7
|
74
|
+
pyghmi-1.5.75.dist-info/RECORD,,
|
@@ -0,0 +1 @@
|
|
1
|
+
{"git_version": "8666417", "is_release": true}
|
pyghmi-1.5.72.dist-info/pbr.json
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"git_version": "b6776ce", "is_release": true}
|
File without changes
|
File without changes
|
File without changes
|