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
except ImportError:
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
try:
@ -281,16 +281,8 @@ class DeviceViewSet(CustomFieldModelViewSet):
if not request.user.has_perm('dcim.napalm_read'):
return HttpResponseForbidden()
# Validate requested NAPALM methods
# Connect to the device
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])
ip_address = str(device.primary_ip.address.ip)
d = driver(
@ -302,12 +294,23 @@ class DeviceViewSet(CustomFieldModelViewSet):
)
try:
d.open()
for method in napalm_methods:
response[method] = getattr(d, method)()
except Exception as 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()
return Response(response)