pyghmi 1.5.72__py3-none-any.whl → 1.5.75__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 +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
|