2
0
mirror of https://github.com/xcat2/confluent.git synced 2024-11-22 17:43:14 +00:00

Provide better exceptions and propogate them to client on snmp

When doing snmp, messages would always go to log only, even if the
user was at the confetty cli.  Give user access to knowing the error
impacting the query.
This commit is contained in:
Jarrod Johnson 2018-10-04 14:59:25 -04:00
parent 32602fbba3
commit 8d9a082739
2 changed files with 34 additions and 17 deletions

View File

@ -171,7 +171,7 @@ def _extract_neighbor_data_b(args):
args are carried as a tuple, because of eventlet convenience
"""
switch, password, user, force = args
switch, password, user, force = args[:4]
vintage = _neighdata.get(switch, {}).get('!!vintage', 0)
now = util.monotonic_time()
if vintage > (now - 60) and not force:
@ -220,17 +220,19 @@ def _extract_neighbor_data_b(args):
_neighdata[switch] = lldpdata
def update_switch_data(switch, configmanager, force=False):
def update_switch_data(switch, configmanager, force=False, retexc=False):
switchcreds = netutil.get_switchcreds(configmanager, (switch,))[0]
_extract_neighbor_data(switchcreds + (force,))
ndr = _extract_neighbor_data(switchcreds + (force, retexc))
if retexc and isinstance(ndr, Exception):
raise ndr
return _neighdata.get(switch, {})
def update_neighbors(configmanager, force=False):
return _update_neighbors_backend(configmanager, force)
def update_neighbors(configmanager, force=False, retexc=False):
return _update_neighbors_backend(configmanager, force, retexc)
def _update_neighbors_backend(configmanager, force):
def _update_neighbors_backend(configmanager, force, retexc):
global _neighdata
global _neighbypeerid
vintage = _neighdata.get('!!vintage', 0)
@ -241,7 +243,7 @@ def _update_neighbors_backend(configmanager, force):
_neighbypeerid = {'!!vintage': now}
switches = netutil.list_switches(configmanager)
switchcreds = netutil.get_switchcreds(configmanager, switches)
switchcreds = [ x + (force,) for x in switchcreds]
switchcreds = [ x + (force, retexc) for x in switchcreds]
pool = GreenPool(64)
for ans in pool.imap(_extract_neighbor_data, switchcreds):
yield ans
@ -258,9 +260,15 @@ def _extract_neighbor_data(args):
return
try:
with _updatelocks[switch]:
_extract_neighbor_data_b(args)
except Exception:
log.logtrace()
return _extract_neighbor_data_b(args)
except Exception as e:
yieldexc = False
if len(args) >= 5:
yieldexc = args[4]
if yieldexc:
return e
else:
log.logtrace()
if __name__ == '__main__':
# a quick one-shot test, args are switch and snmpv1 string for now
@ -327,7 +335,9 @@ def _handle_neighbor_query(pathcomponents, configmanager):
# guaranteed
if (parms['by-peerid'] not in _neighbypeerid and
_neighbypeerid.get('!!vintage', 0) < util.monotonic_time() - 60):
list(update_neighbors(configmanager))
for x in update_neighbors(configmanager, retexc=True):
if isinstance(x, Exception):
raise x
if parms['by-peerid'] not in _neighbypeerid:
raise exc.NotFoundException('No matching peer known')
return _dump_neighbordatum(_neighbypeerid[parms['by-peerid']])
@ -336,9 +346,11 @@ def _handle_neighbor_query(pathcomponents, configmanager):
if listrequested not in multi_selectors | single_selectors:
raise exc.NotFoundException('{0} is not found'.format(listrequested))
if 'by-switch' in parms:
update_switch_data(parms['by-switch'], configmanager)
update_switch_data(parms['by-switch'], configmanager, retexc=True)
else:
list(update_neighbors(configmanager))
for x in update_neighbors(configmanager, retexc=True):
if isinstance(x, Exception):
raise x
return list_info(parms, listrequested)

View File

@ -92,12 +92,17 @@ class Session(object):
errstr, errnum, erridx, answers = rsp
if errstr:
errstr = str(errstr)
if errstr in ('unknownUserName', 'wrongDigest'):
raise exc.TargetEndpointBadCredentials(errstr)
finerr = errstr + ' while trying to connect to ' \
'{0}'.format(self.server)
if errstr in ('Unknown USM user', 'unknownUserName',
'wrongDigest', 'Wrong SNMP PDU digest'):
raise exc.TargetEndpointBadCredentials(finerr)
# need to do bad credential versus timeout
raise exc.TargetEndpointUnreachable(errstr)
raise exc.TargetEndpointUnreachable(finerr)
elif errnum:
raise exc.ConfluentException(errnum.prettyPrint())
raise exc.ConfluentException(errnum.prettyPrint() +
' while trying to connect to '
'{0}'.format(self.server))
for ans in answers:
if not obj[0].isPrefixOf(ans[0]):
# PySNMP returns leftovers in a bulk command