mirror of
https://github.com/xcat2/confluent.git
synced 2025-02-25 23:02:20 +00:00
Merge pull request #96 from weragrzeda/master
i reverted NTP and Eaton, Only Geist PDUs merging
This commit is contained in:
commit
e6f6919ef4
@ -1,13 +1,13 @@
|
||||
# Copyright 2022 Lenovo
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
@ -20,12 +20,15 @@ import eventlet.green.time as time
|
||||
import eventlet
|
||||
import eventlet.greenpool as greenpool
|
||||
|
||||
|
||||
|
||||
def simplify_name(name):
|
||||
return name.lower().replace(' ', '_').replace('/', '-').replace(
|
||||
'_-_', '-')
|
||||
return name.lower().replace(' ', '_').replace('/', '-').replace('_-_', '-')
|
||||
|
||||
|
||||
pdupool = greenpool.GreenPool(128)
|
||||
|
||||
|
||||
def data_by_type(indata):
|
||||
databytype = {}
|
||||
for keyname in indata:
|
||||
@ -34,7 +37,9 @@ def data_by_type(indata):
|
||||
if not objtype:
|
||||
continue
|
||||
if objtype in databytype:
|
||||
raise Exception("Multiple instances of type {} not yet supported".format(objtype))
|
||||
raise Exception(
|
||||
'Multiple instances of type {} not yet supported'.format(objtype)
|
||||
)
|
||||
databytype[objtype] = obj
|
||||
obj['keyname'] = keyname
|
||||
return databytype
|
||||
@ -58,31 +63,30 @@ class GeistClient(object):
|
||||
def wc(self):
|
||||
if self._wc:
|
||||
return self._wc
|
||||
targcfg = self.configmanager.get_node_attributes(self.node,
|
||||
['hardwaremanagement.manager'],
|
||||
decrypt=True)
|
||||
targcfg = self.configmanager.get_node_attributes(
|
||||
self.node, ['hardwaremanagement.manager'], decrypt=True
|
||||
)
|
||||
targcfg = targcfg.get(self.node, {})
|
||||
target = targcfg.get(
|
||||
'hardwaremanagement.manager', {}).get('value', None)
|
||||
target = targcfg.get('hardwaremanagement.manager', {}).get('value', None)
|
||||
if not target:
|
||||
target = self.node
|
||||
target = target.split('/', 1)[0]
|
||||
cv = util.TLSCertVerifier(
|
||||
self.configmanager, self.node,
|
||||
'pubkeys.tls_hardwaremanager').verify_cert
|
||||
self.configmanager, self.node, 'pubkeys.tls_hardwaremanager'
|
||||
).verify_cert
|
||||
self._wc = wc.SecureHTTPConnection(target, port=443, verifycallback=cv)
|
||||
return self._wc
|
||||
|
||||
def login(self, configmanager):
|
||||
credcfg = configmanager.get_node_attributes(self.node,
|
||||
['secret.hardwaremanagementuser',
|
||||
'secret.hardwaremanagementpassword'],
|
||||
decrypt=True)
|
||||
credcfg = configmanager.get_node_attributes(
|
||||
self.node,
|
||||
['secret.hardwaremanagementuser', 'secret.hardwaremanagementpassword'],
|
||||
decrypt=True,
|
||||
)
|
||||
credcfg = credcfg.get(self.node, {})
|
||||
username = credcfg.get(
|
||||
'secret.hardwaremanagementuser', {}).get('value', None)
|
||||
passwd = credcfg.get(
|
||||
'secret.hardwaremanagementpassword', {}).get('value', None)
|
||||
username = credcfg.get('secret.hardwaremanagementuser', {}).get('value', None)
|
||||
passwd = credcfg.get('secret.hardwaremanagementpassword', {}).get('value', None)
|
||||
|
||||
if not isinstance(username, str):
|
||||
username = username.decode('utf8')
|
||||
if not isinstance(passwd, str):
|
||||
@ -92,26 +96,32 @@ class GeistClient(object):
|
||||
self.username = username
|
||||
rsp = self.wc.grab_json_response(
|
||||
'/api/auth/{0}'.format(username),
|
||||
{'cmd': 'login', 'data': {'password': passwd}})
|
||||
{'cmd': 'login', 'data': {'password': passwd}},
|
||||
)
|
||||
|
||||
token = rsp['data']['token']
|
||||
return token
|
||||
|
||||
def logout(self):
|
||||
if self._token:
|
||||
self.wc.grab_json_response('/api/auth/{0}'.format(self.username),
|
||||
{'cmd': 'logout', 'token': self.token})
|
||||
self.wc.grab_json_response(
|
||||
'/api/auth/{0}'.format(self.username),
|
||||
{'cmd': 'logout', 'token': self.token},
|
||||
)
|
||||
self._token = None
|
||||
|
||||
def get_outlet(self, outlet):
|
||||
rsp = self.wc.grab_json_response('/api/dev')
|
||||
rsp = rsp['data']
|
||||
dbt = data_by_type(rsp)
|
||||
|
||||
if 't3hd' in dbt:
|
||||
del dbt['t3hd']
|
||||
if len(dbt) != 1:
|
||||
raise Exception('Multiple PDUs not supported per pdu')
|
||||
pdutype = list(dbt)[0]
|
||||
outlet = dbt[pdutype]['outlet'][str(int(outlet) - 1)]
|
||||
|
||||
state = outlet['state'].split('2')[-1]
|
||||
return state
|
||||
|
||||
@ -125,12 +135,20 @@ class GeistClient(object):
|
||||
raise Exception('Multiple PDUs per endpoint not supported')
|
||||
pdu = dbt[list(dbt)[0]]['keyname']
|
||||
outlet = int(outlet) - 1
|
||||
|
||||
rsp = self.wc.grab_json_response(
|
||||
'/api/dev/{0}/outlet/{1}'.format(pdu, outlet),
|
||||
{'cmd': 'control', 'token': self.token,
|
||||
'data': {'action': state, 'delay': False}})
|
||||
{
|
||||
'cmd': 'control',
|
||||
'token': self.token,
|
||||
'data': {'action': state, 'delay': False},
|
||||
},
|
||||
)
|
||||
|
||||
def process_measurement(keyname, name, enttype, entname, measurement, readings, category):
|
||||
|
||||
def process_measurement(
|
||||
keyname, name, enttype, entname, measurement, readings, category
|
||||
):
|
||||
if measurement['type'] == 'realPower':
|
||||
if category not in ('all', 'power'):
|
||||
return
|
||||
@ -147,6 +165,10 @@ def process_measurement(keyname, name, enttype, entname, measurement, readings,
|
||||
if category not in ('all',):
|
||||
return
|
||||
readtype = 'Voltage'
|
||||
elif measurement['type'] == 'current':
|
||||
if category not in ('all',):
|
||||
return
|
||||
readtype = 'Current'
|
||||
elif measurement['type'] == 'temperature':
|
||||
readtype = 'Temperature'
|
||||
elif measurement['type'] == 'dewpoint':
|
||||
@ -158,23 +180,35 @@ def process_measurement(keyname, name, enttype, entname, measurement, readings,
|
||||
myname = entname + ' ' + readtype
|
||||
if name != 'all' and simplify_name(myname) != name:
|
||||
return
|
||||
readings.append({
|
||||
'name': myname,
|
||||
'value': float(measurement['value']),
|
||||
'units': measurement['units'],
|
||||
'type': readtype.split()[-1]
|
||||
})
|
||||
|
||||
readings.append(
|
||||
{
|
||||
'name': myname,
|
||||
'value': float(measurement['value']),
|
||||
'units': measurement['units'],
|
||||
'type': readtype.split()[-1],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def process_measurements(name, category, measurements, enttype, readings):
|
||||
for measure in util.natural_sort(list(measurements)):
|
||||
measurement = measurements[measure]['measurement']
|
||||
entname = measurements[measure]['name']
|
||||
for measureid in measurement:
|
||||
process_measurement(measure, name, enttype, entname, measurement[measureid], readings, category)
|
||||
|
||||
process_measurement(
|
||||
measure,
|
||||
name,
|
||||
enttype,
|
||||
entname,
|
||||
measurement[measureid],
|
||||
readings,
|
||||
category,
|
||||
)
|
||||
|
||||
|
||||
_sensors_by_node = {}
|
||||
|
||||
|
||||
def read_sensors(element, node, configmanager):
|
||||
category, name = element[-2:]
|
||||
justnames = False
|
||||
@ -192,10 +226,12 @@ def read_sensors(element, node, configmanager):
|
||||
_sensors_by_node[node] = (adev, time.time() + 1)
|
||||
sn = _sensors_by_node.get(node, None)
|
||||
dbt = data_by_type(sn[0]['data'])
|
||||
|
||||
readings = []
|
||||
for datatype in dbt:
|
||||
for datatype in dbt:
|
||||
datum = dbt[datatype]
|
||||
process_measurements(name, category, datum['entity'], 'entity', readings)
|
||||
|
||||
if 'outlet' in datum:
|
||||
process_measurements(name, category, datum['outlet'], 'outlet', readings)
|
||||
if justnames:
|
||||
@ -204,25 +240,78 @@ def read_sensors(element, node, configmanager):
|
||||
else:
|
||||
yield msg.SensorReadings(readings, name=node)
|
||||
|
||||
def get_outlet(node, configmanager, element):
|
||||
|
||||
def get_outlet(element, node, configmanager):
|
||||
gc = GeistClient(node, configmanager)
|
||||
state = gc.get_outlet(element[-1])
|
||||
|
||||
return msg.PowerState(node=node, state=state)
|
||||
|
||||
|
||||
def read_firmware(node, configmanager):
|
||||
gc = GeistClient(node, configmanager)
|
||||
adev = 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):
|
||||
_inventory = {}
|
||||
inventory = {}
|
||||
gc = GeistClient(node, configmanager)
|
||||
adev = gc.wc.grab_json_response('/api/sys')
|
||||
basedata = adev['data']
|
||||
inventory['present'] = True
|
||||
inventory['name'] = 'PDU'
|
||||
for elem in basedata.items():
|
||||
|
||||
if (
|
||||
elem[0] != 'component'
|
||||
and elem[0] != 'locale'
|
||||
and elem[0] != 'state'
|
||||
and elem[0] != 'contact'
|
||||
and elem[0] != 'appVersion'
|
||||
and elem[0] != 'build'
|
||||
and elem[0] != 'version'
|
||||
and elem[0] != 'apiVersion'
|
||||
):
|
||||
temp = elem[0]
|
||||
if elem[0] == 'serialNumber':
|
||||
temp = 'Serial'
|
||||
elif elem[0] == 'partNumber':
|
||||
temp = 'P/N'
|
||||
elif elem[0] == 'modelNumber':
|
||||
temp = 'Lenovo P/N and Serial'
|
||||
_inventory[temp] = elem[1]
|
||||
elif elem[0] == 'component':
|
||||
tempname = ''
|
||||
for component in basedata['component'].items():
|
||||
for item in component:
|
||||
if type(item) == str:
|
||||
|
||||
tempname = item
|
||||
else:
|
||||
for entry in item.items():
|
||||
temp = entry[0]
|
||||
if temp == 'sn':
|
||||
temp = 'Serial'
|
||||
_inventory[tempname + ' ' + temp] = entry[1]
|
||||
|
||||
inventory['information'] = _inventory
|
||||
|
||||
yield msg.KeyValueData({'inventory': [inventory]}, node)
|
||||
|
||||
|
||||
def retrieve(nodes, element, configmanager, inputdata):
|
||||
|
||||
if 'outlets' in element:
|
||||
gp = greenpool.GreenPile(pdupool)
|
||||
for node in nodes:
|
||||
gp.spawn(get_outlet, node, configmanager, element)
|
||||
|
||||
gp.spawn(get_outlet, element, node, configmanager)
|
||||
for res in gp:
|
||||
yield res
|
||||
|
||||
|
||||
return
|
||||
elif element[0] == 'sensors':
|
||||
gp = greenpool.GreenPile(pdupool)
|
||||
@ -239,11 +328,20 @@ def retrieve(nodes, element, configmanager, inputdata):
|
||||
for rsp in gp:
|
||||
for datum in rsp:
|
||||
yield datum
|
||||
|
||||
elif '/'.join(element).startswith('inventory/hardware/all'):
|
||||
gp = greenpool.GreenPile(pdupool)
|
||||
for node in nodes:
|
||||
gp.spawn(read_inventory, element, node, configmanager)
|
||||
for rsp in gp:
|
||||
for datum in rsp:
|
||||
yield datum
|
||||
else:
|
||||
for node in nodes:
|
||||
yield msg.ConfluentResourceUnavailable(node, 'Not implemented')
|
||||
yield msg.ConfluentResourceUnavailable(node, 'Not implemented')
|
||||
return
|
||||
|
||||
|
||||
|
||||
def update(nodes, element, configmanager, inputdata):
|
||||
if 'outlets' not in element:
|
||||
yield msg.ConfluentResourceUnavailable(node, 'Not implemented')
|
||||
|
Loading…
x
Reference in New Issue
Block a user