1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Fixes #1992: Isolate errors when one of multiple NAPALM methods fails

This commit is contained in:
Jeremy Stretch
2018-07-18 14:46:15 -04:00
parent 29d9b32b67
commit d665d4d62a

View File

@ -267,7 +267,7 @@ class DeviceViewSet(CustomFieldModelViewSet):
import napalm import napalm
except ImportError: except ImportError:
raise ServiceUnavailable("NAPALM is not installed. Please see the documentation for instructions.") raise ServiceUnavailable("NAPALM is not installed. Please see the documentation for instructions.")
from napalm.base.exceptions import ConnectAuthError, ModuleImportError from napalm.base.exceptions import ModuleImportError
# Validate the configured driver # Validate the configured driver
try: try:
@ -281,16 +281,8 @@ class DeviceViewSet(CustomFieldModelViewSet):
if not request.user.has_perm('dcim.napalm_read'): if not request.user.has_perm('dcim.napalm_read'):
return HttpResponseForbidden() return HttpResponseForbidden()
# Validate requested NAPALM methods # Connect to the device
napalm_methods = request.GET.getlist('method') napalm_methods = request.GET.getlist('method')
for method in napalm_methods:
if not hasattr(driver, method):
return HttpResponseBadRequest("Unknown NAPALM method: {}".format(method))
elif not method.startswith('get_'):
return HttpResponseBadRequest("Unsupported NAPALM method: {}".format(method))
# Connect to the device and execute the requested methods
# TODO: Improve error handling
response = OrderedDict([(m, None) for m in napalm_methods]) response = OrderedDict([(m, None) for m in napalm_methods])
ip_address = str(device.primary_ip.address.ip) ip_address = str(device.primary_ip.address.ip)
d = driver( d = driver(
@ -302,12 +294,23 @@ class DeviceViewSet(CustomFieldModelViewSet):
) )
try: try:
d.open() d.open()
for method in napalm_methods:
response[method] = getattr(d, method)()
except Exception as e: except Exception as e:
raise ServiceUnavailable("Error connecting to the device at {}: {}".format(ip_address, e)) raise ServiceUnavailable("Error connecting to the device at {}: {}".format(ip_address, e))
# Validate and execute each specified NAPALM method
for method in napalm_methods:
if not hasattr(driver, method):
response[method] = {'error': 'Unknown NAPALM method'}
continue
if not method.startswith('get_'):
response[method] = {'error': 'Only get_* NAPALM methods are supported'}
continue
try:
response[method] = getattr(d, method)()
except NotImplementedError:
response[method] = {'error': 'Method not implemented for NAPALM driver {}'.format(driver)}
d.close() d.close()
return Response(response) return Response(response)