2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-05-16 19:34:19 +00:00

Remove pyghmi usage across multiple areas

This commit is contained in:
Jarrod Johnson
2026-01-23 13:31:09 -05:00
parent 60c3d5400a
commit c4616745c4
6 changed files with 103 additions and 96 deletions
@@ -18,7 +18,8 @@ import confluent.messages as msg
import confluent.exceptions as exc
import eventlet
import eventlet.green.socket as socket
wc = eventlet.import_patched('pyghmi.util.webclient')
import aiohmi.util.webclient as wc
import confluent.util as util
import re
import hashlib
@@ -18,7 +18,7 @@ import confluent.exceptions as exc
import eventlet.green.time as time
import eventlet
import eventlet.greenpool as greenpool
wc = eventlet.import_patched('pyghmi.util.webclient')
import aiohmi.util.webclient as wc
@@ -62,7 +62,7 @@ class EnlogicClient(object):
cv = util.TLSCertVerifier(
self.configmanager, self.node, 'pubkeys.tls_hardwaremanager'
).verify_cert
self._wc = wc.SecureHTTPConnection(target, port=443, verifycallback=cv)
self._wc = wc.WebConnection(target, port=443, verifycallback=cv)
return self._wc
def grab_json_response(self, url, body=None):
@@ -76,7 +76,7 @@ class EnlogicClient(object):
return rsp
return {}
def login(self, configmanager):
async def login(self, configmanager):
credcfg = configmanager.get_node_attributes(
self.node,
['secret.hardwaremanagementuser', 'secret.hardwaremanagementpassword'],
@@ -93,25 +93,25 @@ class EnlogicClient(object):
if not username or not passwd:
raise Exception('Missing username or password')
self.username = username
rsp = self.wc.grab_json_response(
rsp = await self.wc.grab_json_response(
'/xhrlogin.jsp',
{'username': username, 'password': passwd, 'cookie': 0}
)
print(repr(rsp))
#print(repr(rsp))
self.authtoken = rsp['cookie']
self.wc.set_header('Authorization', self.authtoken)
return self.authtoken
def logout(self):
async def logout(self):
if self._token:
self.wc.grab_json_response(
await self.wc.grab_json_response(
'/xhrlogout.jsp',
{'timeout': 0, 'cookie': self._token},
)
self._token = None
def get_outlet(self, outlet):
rsp = self.grab_json_response(
async def get_outlet(self, outlet):
rsp = await self.grab_json_response(
'/xhroutgetgrid.jsp', {
'cookie': self.token,
'pduid': 1
@@ -122,7 +122,7 @@ class EnlogicClient(object):
state = "on" if olet['powstat'] == 1 else "off"
return state
def set_outlet(self, outlet, state):
async def set_outlet(self, outlet, state):
bitflags = 2**(int(outlet) - 1)
outlet1 = bitflags & (2**24-1)
outlet2 = bitflags >> 24
@@ -139,13 +139,13 @@ class EnlogicClient(object):
'pduid': 1,
'powstat': state
}
rsp = self.grab_json_response('/xhroutpowstatset.jsp', request)
rsp = await self.grab_json_response('/xhroutpowstatset.jsp', request)
_sensors_by_node = {}
def read_sensors(element, node, configmanager):
async def read_sensors(element, node, configmanager):
category, name = element[-2:]
justnames = False
if len(element) == 3:
@@ -163,7 +163,7 @@ def read_sensors(element, node, configmanager):
sn = _sensors_by_node.get(node, None)
if not sn or sn[1] < time.time():
gc = get_client(node, configmanager)
adev = gc.grab_json_response('/energy_get', {'cookie': gc.token, 'end': 1, 'start': 1})
adev = await gc.grab_json_response('/energy_get', {'cookie': gc.token, 'end': 1, 'start': 1})
_sensors_by_node[node] = (adev, time.time() + 1)
sn = _sensors_by_node.get(node, None)
if sn:
@@ -196,24 +196,24 @@ def get_client(node, configmanager):
_pduclients[node] = EnlogicClient(node, configmanager)
return _pduclients[node]
def get_outlet(element, node, configmanager):
async def get_outlet(element, node, configmanager):
gc = get_client(node, configmanager)
state = gc.get_outlet(element[-1])
state = await gc.get_outlet(element[-1])
return msg.PowerState(node=node, state=state)
def read_firmware(node, configmanager):
async def read_firmware(node, configmanager):
gc = get_client(node, configmanager)
adev = gc.grab_json_response('/xhrgetuserlist.jsp')
adev = await gc.grab_json_response('/xhrgetuserlist.jsp')
myversion = adev[0]['fwver']
yield msg.Firmware([{'PDU Firmware': {'version': myversion}}], node)
def read_inventory(element, node, configmanager):
async def read_inventory(element, node, configmanager):
_inventory = {}
inventory = {}
gc = get_client(node, configmanager)
adev = gc.grab_json_response('/sys_info_get', {
adev = await gc.grab_json_response('/sys_info_get', {
'cookie': gc.token, 'pduid': 1
})
inventory['present'] = True
@@ -225,7 +225,7 @@ def read_inventory(element, node, configmanager):
inventory['information'] = info
yield msg.KeyValueData({'inventory': [inventory]}, node)
def retrieve(nodes, element, configmanager, inputdata):
async def retrieve(nodes, element, configmanager, inputdata):
if 'outlets' in element:
gp = greenpool.GreenPile(pdupool)
@@ -265,7 +265,7 @@ def retrieve(nodes, element, configmanager, inputdata):
return
def update(nodes, element, configmanager, inputdata):
async def update(nodes, element, configmanager, inputdata):
if 'outlets' not in element:
for node in nodes:
yield msg.ConfluentResourceUnavailable(node, 'Not implemented')
@@ -273,7 +273,7 @@ def update(nodes, element, configmanager, inputdata):
for node in nodes:
gc = get_client(node, configmanager)
newstate = inputdata.powerstate(node)
gc.set_outlet(element[-1], newstate)
await gc.set_outlet(element[-1], newstate)
eventlet.sleep(1)
for res in retrieve(nodes, element, configmanager, inputdata):
async for res in retrieve(nodes, element, configmanager, inputdata):
yield res
@@ -19,7 +19,7 @@ import confluent.exceptions as exc
import eventlet.green.time as time
import eventlet
import eventlet.greenpool as greenpool
wc = eventlet.import_patched('pyghmi.util.webclient')
import aiohmi.util.webclient as wc
@@ -54,10 +54,9 @@ class GeistClient(object):
self._wc = None
self.username = None
@property
def token(self):
async def token(self):
if not self._token:
self._token = self.login(self.configmanager)
self._token = await self.login(self.configmanager)
return self._token
@property
@@ -75,10 +74,10 @@ class GeistClient(object):
cv = util.TLSCertVerifier(
self.configmanager, self.node, 'pubkeys.tls_hardwaremanager'
).verify_cert
self._wc = wc.SecureHTTPConnection(target, port=443, verifycallback=cv)
self._wc = wc.WebConnection(target, port=443, verifycallback=cv)
return self._wc
def login(self, configmanager):
async def login(self, configmanager):
credcfg = configmanager.get_node_attributes(
self.node,
['secret.hardwaremanagementuser', 'secret.hardwaremanagementpassword'],
@@ -95,7 +94,7 @@ class GeistClient(object):
if not username or not passwd:
raise Exception('Missing username or password')
self.username = username
rsp = self.wc.grab_json_response(
rsp = await self.wc.grab_json_response(
'/api/auth/{0}'.format(username),
{'cmd': 'login', 'data': {'password': passwd}},
)
@@ -103,16 +102,16 @@ class GeistClient(object):
token = rsp['data']['token']
return token
def logout(self):
async def logout(self):
if self._token:
self.wc.grab_json_response(
await self.wc.grab_json_response(
'/api/auth/{0}'.format(self.username),
{'cmd': 'logout', 'token': self.token},
{'cmd': 'logout', 'token': await self.token()},
)
self._token = None
def get_outlet(self, outlet):
rsp = self.wc.grab_json_response('/api/dev')
async def get_outlet(self, outlet):
rsp = await self.wc.grab_json_response('/api/dev')
rsp = rsp['data']
dbt = data_by_type(rsp)
@@ -126,22 +125,22 @@ class GeistClient(object):
state = outlet['state'].split('2')[-1]
return state
def set_outlet(self, outlet, state):
rsp = self.wc.grab_json_response('/api/dev')
async def set_outlet(self, outlet, state):
rsp = await self.wc.grab_json_response('/api/dev')
dbt = data_by_type(rsp['data'])
if 't3hd' in dbt:
del dbt['t3hd']
if len(dbt) != 1:
self.logout()
await self.logout()
raise Exception('Multiple PDUs per endpoint not supported')
pdu = dbt[list(dbt)[0]]['keyname']
outlet = int(outlet) - 1
rsp = self.wc.grab_json_response(
rsp = await self.wc.grab_json_response(
'/api/dev/{0}/outlet/{1}'.format(pdu, outlet),
{
'cmd': 'control',
'token': self.token,
'token': await self.token(),
'data': {'action': state, 'delay': False},
},
)
@@ -210,7 +209,7 @@ def process_measurements(name, category, measurements, enttype, readings):
_sensors_by_node = {}
def read_sensors(element, node, configmanager):
async def read_sensors(element, node, configmanager):
category, name = element[-2:]
justnames = False
if len(element) == 3:
@@ -223,7 +222,7 @@ def read_sensors(element, node, configmanager):
sn = _sensors_by_node.get(node, None)
if not sn or sn[1] < time.time():
gc = GeistClient(node, configmanager)
adev = gc.wc.grab_json_response('/api/dev')
adev = await gc.wc.grab_json_response('/api/dev')
_sensors_by_node[node] = (adev, time.time() + 1)
sn = _sensors_by_node.get(node, None)
dbt = data_by_type(sn[0]['data'])
@@ -242,25 +241,25 @@ def read_sensors(element, node, configmanager):
yield msg.SensorReadings(readings, name=node)
def get_outlet(element, node, configmanager):
async def get_outlet(element, node, configmanager):
gc = GeistClient(node, configmanager)
state = gc.get_outlet(element[-1])
state = await gc.get_outlet(element[-1])
return msg.PowerState(node=node, state=state)
def read_firmware(node, configmanager):
async def read_firmware(node, configmanager):
gc = GeistClient(node, configmanager)
adev = gc.wc.grab_json_response('/api/sys')
adev = await gc.wc.grab_json_response('/api/sys')
myversion = adev['data']['version']
yield msg.Firmware([{'PDU Firmware': {'version': myversion}}], node)
def read_inventory(element, node, configmanager):
async def read_inventory(element, node, configmanager):
_inventory = {}
inventory = {}
gc = GeistClient(node, configmanager)
adev = gc.wc.grab_json_response('/api/sys')
adev = await gc.wc.grab_json_response('/api/sys')
basedata = adev['data']
inventory['present'] = True
inventory['name'] = 'PDU'
@@ -303,7 +302,7 @@ def read_inventory(element, node, configmanager):
yield msg.KeyValueData({'inventory': [inventory]}, node)
def retrieve(nodes, element, configmanager, inputdata):
async def retrieve(nodes, element, configmanager, inputdata):
if 'outlets' in element:
gp = greenpool.GreenPile(pdupool)
@@ -343,7 +342,7 @@ def retrieve(nodes, element, configmanager, inputdata):
return
def update(nodes, element, configmanager, inputdata):
async def update(nodes, element, configmanager, inputdata):
if 'outlets' not in element:
yield msg.ConfluentResourceUnavailable(node, 'Not implemented')
return
@@ -13,7 +13,7 @@
# limitations under the License.
import confluent.core as core
import confluent.messages as msg
import pyghmi.exceptions as pygexc
import aiohmi.exceptions as pygexc
import confluent.exceptions as exc
import eventlet.greenpool as greenpool
import eventlet.queue as queue
@@ -3,9 +3,9 @@ import codecs
import confluent.util as util
import confluent.messages as msg
import eventlet
import json
import struct
webclient = eventlet.import_patched('pyghmi.util.webclient')
import aiohmi.util.webclient as webclient
import eventlet.green.socket as socket
import eventlet.green.ssl as ssl
import eventlet
@@ -124,8 +124,8 @@ class VmwApiClient:
self.password = self.password.decode()
except Exception:
pass
self.wc = webclient.SecureHTTPConnection(vcsa, port=443, verifycallback=cv)
self.login()
self.wc = webclient.Web(vcsa, port=443, verifycallback=cv)
self.logged = False
self.vmlist = {}
self.vmbyid = {}
@@ -136,8 +136,11 @@ class VmwApiClient:
body = rsp.read().decode().replace('"', '')
del self.wc.stdheaders['Authorization']
self.wc.set_header('vmware-api-session-id', body)
self.logged = True
def get_screenshot(self, vm, outfile):
async def get_screenshot(self, vm, outfile):
if not self.logged:
await self.login()
vm = self.index_vm(vm)
url = f'/screen?id={vm}'
wc = self.wc.dupe()
@@ -146,8 +149,10 @@ class VmwApiClient:
fd.start()
fd.join()
def list_vms(self):
rsp = self.wc.grab_json_response('/api/vcenter/vm')
async def list_vms(self):
if not self.logged:
await self.login()
rsp = await self.wc.grab_json_response('/api/vcenter/vm')
self.vmlist = {}
for vm in rsp:
name = vm['name']
@@ -156,25 +161,27 @@ class VmwApiClient:
self.vmbyid[vmid] = name
return self.vmlist
def index_vm(self, vm):
async def index_vm(self, vm):
if not self.logged:
await self.login()
if vm in self.vmlist:
return self.vmlist[vm]
if vm in self.vmbyid:
return vm
self.list_vms()
await self.list_vms()
if vm not in self.vmlist:
if vm in self.vmbyid:
return vm
raise Exception("VM not found")
return self.vmlist[vm]
def get_vm(self, vm):
vm = self.index_vm(vm)
rsp = self.wc.grab_json_response(f'/api/vcenter/vm/{vm}')
async def get_vm(self, vm):
vm = await self.index_vm(vm)
rsp = await self.wc.grab_json_response(f'/api/vcenter/vm/{vm}')
return rsp
def get_vm_inventory(self, vm):
rawinv = self.get_vm(vm)
async def get_vm_inventory(self, vm):
rawinv = await self.get_vm(vm)
hwver = rawinv['hardware']['version']
uuid = fixuuid(rawinv['identity']['bios_uuid'])
serial = rawinv['identity']['instance_uuid']
@@ -206,23 +213,23 @@ class VmwApiClient:
def get_vm_host(self, vm):
async def get_vm_host(self, vm):
# unfortunately, the REST api doesn't manifest this as a simple attribute,
vm = self.index_vm(vm)
rsp = self.wc.grab_json_response(f'/api/vcenter/host')
vm = await self.index_vm(vm)
rsp = await self.wc.grab_json_response(f'/api/vcenter/host')
for hostinfo in rsp:
host = hostinfo['host']
rsp = self.wc.grab_json_response(f'/api/vcenter/vm?hosts={host}')
rsp = await self.wc.grab_json_response(f'/api/vcenter/vm?hosts={host}')
for guest in rsp:
if guest['vm'] == vm:
return hostinfo
def get_vm_serial(self, vm):
vm = self.index_vm(vm)
rsp = self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/serial')
async def get_vm_serial(self, vm):
vm = await self.index_vm(vm)
rsp = await self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/serial')
if rsp[1] == 200 and len(rsp[0]) > 0:
portid = rsp[0][0]['port']
rsp = self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/serial/{portid}')
rsp = await self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/serial/{portid}')
if rsp[1] == 200:
if rsp[0]['backing']['type'] != 'NETWORK_SERVER':
return
@@ -231,7 +238,7 @@ class VmwApiClient:
tlsenabled = False
if netloc.startswith('telnets'):
tlsenabled = True
hostinfo = self.get_vm_host(vm)
hostinfo = await self.get_vm_host(vm)
hostname = hostinfo['name']
rsp[0]
return {
@@ -240,9 +247,9 @@ class VmwApiClient:
'tls': tlsenabled,
}
def get_vm_bootdev(self, vm):
vm = self.index_vm(vm)
rsp = self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/boot')
async def get_vm_bootdev(self, vm):
vm = await self.index_vm(vm)
rsp = await self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/boot')
if rsp[0]['enter_setup_mode']:
return 'setup'
rsp = self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/boot/device')
@@ -253,9 +260,9 @@ class VmwApiClient:
pass
return 'default'
def get_vm_power(self, vm):
vm = self.index_vm(vm)
rsp = self.wc.grab_json_response(f'/api/vcenter/vm/{vm}/power')
async def get_vm_power(self, vm):
vm = await self.index_vm(vm)
rsp = await self.wc.grab_json_response(f'/api/vcenter/vm/{vm}/power')
if rsp['state'] == 'POWERED_ON':
return 'on'
if rsp['state'] == 'POWERED_OFF':
@@ -264,12 +271,12 @@ class VmwApiClient:
return 'suspended'
raise Exception("Unknown response {}".format(repr(rsp)))
def set_vm_power(self, vm, state):
async def set_vm_power(self, vm, state):
current = None
targstate = state
vm = self.index_vm(vm)
vm = await self.index_vm(vm)
if state == 'boot':
current = self.get_vm_power(vm)
current = await self.get_vm_power(vm)
if current == 'on':
state = 'reset'
targstate = state
@@ -280,12 +287,12 @@ class VmwApiClient:
state = 'start'
elif state == 'off':
state = 'stop'
rsp = self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/power?action={state}', method='POST')
rsp = await self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/power?action={state}', method='POST')
return targstate, current
def set_vm_bootdev(self, vm, bootdev):
vm = self.index_vm(vm)
async def set_vm_bootdev(self, vm, bootdev):
vm = await self.index_vm(vm)
self.wc.set_header('Content-Type', 'application/json')
try:
bootdevs = []
@@ -297,18 +304,18 @@ class VmwApiClient:
# However, vmware api counter to documentation seems to just ignore
# such a request. So instead we just go "disk first"
# and rely upon fast fail/retry to take us to a normal place
currdisks, rcode = self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/disk')
currdisks, rcode = await self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/disk')
currdisks = [x['disk'] for x in currdisks]
bootdevs.append({'type': 'DISK', 'disks': currdisks})
elif bootdev in ('net', 'network'):
currnics, rcode = self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/ethernet')
currnics, rcode = await self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/ethernet')
for nic in currnics:
bootdevs.append({'type': 'ETHERNET', 'nic': nic['nic']})
payload = {'devices': bootdevs}
rsp = self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/boot/device',
rsp = await self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/boot/device',
payload,
method='PUT')
rsp = self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/boot',
rsp = await self.wc.grab_json_response_with_status(f'/api/vcenter/vm/{vm}/hardware/boot',
{'enter_setup_mode': entersetup},
method='PATCH')
finally:
@@ -329,16 +336,16 @@ def prep_vcsa_clients(nodes, configmanager):
clientsbynode[node] = clientsbyvcsa[currvcsa]
return clientsbynode
def retrieve(nodes, element, configmanager, inputdata):
async def retrieve(nodes, element, configmanager, inputdata):
clientsbynode = prep_vcsa_clients(nodes, configmanager)
for node in nodes:
currclient = clientsbynode[node]
if element == ['power', 'state']:
yield msg.PowerState(node, currclient.get_vm_power(node))
yield msg.PowerState(node, await currclient.get_vm_power(node))
elif element == ['boot', 'nextdevice']:
yield msg.BootDevice(node, currclient.get_vm_bootdev(node))
yield msg.BootDevice(node, await currclient.get_vm_bootdev(node))
elif element[:2] == ['inventory', 'hardware'] and len(element) == 4:
for rsp in currclient.get_vm_inventory(node):
async for rsp in currclient.get_vm_inventory(node):
yield rsp
elif element == ['console', 'ikvm_methods']:
dsc = {'ikvm_methods': ['screenshot']}
+1 -1
View File
@@ -5,7 +5,7 @@ block_cipher = None
a = Analysis(['c:/Python27/Scripts/confluentsrv.py'],
pathex=[],
hiddenimports=['pyghmi.constants', 'pyghmi.exceptions', 'pyghmi.ipmi.console', 'pyghmi.ipmi.private.constants', 'pyghmi.ipmi.private', 'pyghmi.ipmi.private.session', 'pyghmi.ipmi.command', 'pyghmi.ipmi.events', 'pyghmi.ipmi.fru', 'pyghmi.ipmi.private.spd', 'pyghmi.ipmi.oem.lookup', 'pyghmi.ipmi.oem.generic', 'pyghmi.ipmi.oem.lenovo', 'pyghmi.ipmi.private.util', 'pyghmi.ipmi.sdr'],
hiddenimports=[], # ['pyghmi.constants', 'pyghmi.exceptions', 'pyghmi.ipmi.console', 'pyghmi.ipmi.private.constants', 'pyghmi.ipmi.private', 'pyghmi.ipmi.private.session', 'pyghmi.ipmi.command', 'pyghmi.ipmi.events', 'pyghmi.ipmi.fru', 'pyghmi.ipmi.private.spd', 'pyghmi.ipmi.oem.lookup', 'pyghmi.ipmi.oem.generic', 'pyghmi.ipmi.oem.lenovo', 'pyghmi.ipmi.private.util', 'pyghmi.ipmi.sdr'],
hookspath=None,
runtime_hooks=None,
excludes=None,