mirror of
https://github.com/xcat2/confluent.git
synced 2026-08-05 10:17:51 +00:00
Add node operations against Nexus switch
This enables the commands to work that one would expect.
This commit is contained in:
@@ -20,7 +20,10 @@ def add_sensedata(component, sensedata, name=None):
|
||||
if units == 'Celsius':
|
||||
units = '°C'
|
||||
senseinfo['units'] = units
|
||||
senseinfo['health'] = _healthmap.get(attrs['operSt'], attrs['operSt'])
|
||||
senseinfo['health'] = _healthmap.get(attrs['operSt'], 'unknown')
|
||||
if senseinfo['health'] == 'unknown':
|
||||
print(senseinfo['health'] + ' not recognized')
|
||||
senseinfo['health'] = 'critical'
|
||||
elif 'eqptFtSlot' in component:
|
||||
attrs = component['eqptFtSlot']['attributes']
|
||||
name = '{} {}'.format(attrs['descr'], attrs['physId'])
|
||||
@@ -52,6 +55,8 @@ def add_sensedata(component, sensedata, name=None):
|
||||
senseinfo = {}
|
||||
elif 'eqptPsuSlot' in component:
|
||||
attrs = component['eqptPsuSlot']['attributes']
|
||||
senseinfo['value'] = None
|
||||
senseinfo['units'] = None
|
||||
senseinfo['name'] = 'PSU Slot {}'.format(attrs['physId'])
|
||||
senseinfo['health'] = 'ok'
|
||||
senseinfo['states'] = ['Present']
|
||||
@@ -66,10 +71,6 @@ def add_sensedata(component, sensedata, name=None):
|
||||
add_sensedata(child, sensedata, name)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class NxApiClient:
|
||||
def __init__(self, switch, user, password, configmanager):
|
||||
self.cachedurls = {}
|
||||
@@ -104,19 +105,6 @@ class NxApiClient:
|
||||
firmdata['BIOS'] = {'version': attrs['biosVersion'], 'date': attrs['biosCompileTime']}
|
||||
return firmdata
|
||||
|
||||
|
||||
|
||||
def get_serial(self):
|
||||
for imdata in self.grab_imdata('/api/mo/sys/ch.json'):
|
||||
for keyn in imdata:
|
||||
currinfo = imdata[keyn]
|
||||
model = currinfo.get('model', 'Unknown')
|
||||
serial = currinfo.get('ser', 'Unknown')
|
||||
modelname = currinfo.get('descr', 'Uknonwn')
|
||||
|
||||
self.wc.grab_json_response_with_status('/api/mo/sys.json')
|
||||
rsp['imdata'][0]['topSystem']['attributes'][serial]
|
||||
|
||||
def get_sensors(self):
|
||||
sensedata = []
|
||||
for imdata in self.grab_imdata('/api/mo/sys/ch.json?rsp-subtree=full'):
|
||||
@@ -125,6 +113,18 @@ class NxApiClient:
|
||||
add_sensedata(component, sensedata)
|
||||
return sensedata
|
||||
|
||||
def get_health(self):
|
||||
healthdata = {'health': 'ok', 'sensors': []}
|
||||
for sensor in self.get_sensors():
|
||||
currhealth = sensor.get('health', 'ok')
|
||||
if currhealth != 'ok':
|
||||
healthdata['sensors'].append(sensor)
|
||||
if sensor['health'] == 'critical':
|
||||
healthdata['health'] = 'critical'
|
||||
elif sensor['health'] == 'warning' and healthdata['health'] != 'critical':
|
||||
healthdata['health'] = 'warning'
|
||||
return healthdata
|
||||
|
||||
def get_inventory(self):
|
||||
invdata = []
|
||||
for imdata in self.grab_imdata('/api/mo/sys/ch.json?rsp-subtree=full'):
|
||||
@@ -155,11 +155,6 @@ class NxApiClient:
|
||||
invdata.append(invinfo)
|
||||
return invdata
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def grab(self, url, cache=True, retry=True):
|
||||
if cache is True:
|
||||
cache = 1
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
import confluent.networking.nxapi as nxapi
|
||||
import eventlet
|
||||
import eventlet.queue as queue
|
||||
import eventlet.greenpool as greenpool
|
||||
import confluent.messages as msg
|
||||
import traceback
|
||||
|
||||
|
||||
def retrieve_node(node, element, user, pwd, configmanager, inputdata, results):
|
||||
try:
|
||||
retrieve_node_backend(node, element, user, pwd, configmanager, inputdata, results)
|
||||
except Exception as e:
|
||||
print(traceback.format_exc())
|
||||
print(repr(e))
|
||||
|
||||
def simplify_name(name):
|
||||
return name.lower().replace(' ', '_').replace('/', '-').replace(
|
||||
'_-_', '-')
|
||||
|
||||
def retrieve_node_backend(node, element, user, pwd, configmanager, inputdata, results):
|
||||
cli = nxapi.NxApiClient(node, user, pwd, configmanager)
|
||||
if element == ['power', 'state']: # client initted successfully, must be on
|
||||
results.put(msg.PowerState(node, 'on'))
|
||||
elif element == ['health', 'hardware']:
|
||||
hinfo = cli.get_health()
|
||||
results.put(msg.HealthSummary(hinfo.get('health', 'unknown'), name=node))
|
||||
results.put(msg.SensorReadings(hinfo.get('sensors', []), name=node))
|
||||
elif element[:3] == ['inventory', 'hardware', 'all']:
|
||||
if len(element) == 3:
|
||||
results.put(msg.ChildCollection('all'))
|
||||
return
|
||||
invinfo = cli.get_inventory()
|
||||
if invinfo:
|
||||
results.put(msg.KeyValueData({'inventory': invinfo}, node))
|
||||
elif element[:3] == ['inventory', 'firmware', 'all']:
|
||||
if len(element) == 3:
|
||||
results.put(msg.ChildCollection('all'))
|
||||
return
|
||||
fwinfo = []
|
||||
for fwnam, fwdat in cli.get_firmware().items():
|
||||
fwinfo.append({fwnam: fwdat})
|
||||
if fwinfo:
|
||||
results.put(msg.Firmware(fwinfo, node))
|
||||
elif element == ['sensors', 'hardware', 'all']:
|
||||
sensors = cli.get_sensors()
|
||||
for sensor in sensors:
|
||||
results.put(msg.ChildCollection(simplify_name(sensor['name'])))
|
||||
elif element[:3] == ['sensors', 'hardware', 'all']:
|
||||
sensors = cli.get_sensors()
|
||||
for sensor in sensors:
|
||||
if element[-1] == 'all' or simplify_name(sensor['name']) == element[-1]:
|
||||
results.put(msg.SensorReadings([sensor], node))
|
||||
else:
|
||||
print(repr(element))
|
||||
|
||||
|
||||
def retrieve(nodes, element, configmanager, inputdata):
|
||||
results = queue.LightQueue()
|
||||
workers = set([])
|
||||
creds = configmanager.get_node_attributes(
|
||||
nodes, ['secret.hardwaremanagementuser', 'secret.hardwaremanagementpassword'], decrypt=True)
|
||||
for node in nodes:
|
||||
cred = creds.get(node, {})
|
||||
user = cred.get('secret.hardwaremanagementuser', {}).get('value')
|
||||
pwd = cred.get('secret.hardwaremanagementpassword', {}).get('value')
|
||||
try:
|
||||
user = user.decode()
|
||||
pwd = pwd.decode()
|
||||
except Exception:
|
||||
pass
|
||||
if not user or not pwd:
|
||||
yield msg.ConfluentTargetInvalidCredentials(node)
|
||||
continue
|
||||
workers.add(eventlet.spawn(retrieve_node, node, element, user, pwd, configmanager, inputdata, results))
|
||||
while workers:
|
||||
try:
|
||||
datum = results.get(block=True, timeout=10)
|
||||
while datum:
|
||||
if datum:
|
||||
yield datum
|
||||
datum = results.get_nowait()
|
||||
except queue.Empty:
|
||||
pass
|
||||
eventlet.sleep(0.001)
|
||||
for t in list(workers):
|
||||
if t.dead:
|
||||
workers.discard(t)
|
||||
try:
|
||||
while True:
|
||||
datum = results.get_nowait()
|
||||
if datum:
|
||||
yield datum
|
||||
except queue.Empty:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user