nav
nav copied to clipboard
[BUG] Juniper switch reporting 'NA' as a vlan tag causes PortAdmin to crash
Describe the bug
When visiting a Juniper EX4300 switch stack interface in PortAdmin, a customer finds PortAdmin to crash. A ValueError traceback is mailed to the site admin.
Apparently, the switch stack's PyEZ response to a query for ElsVlanView
returns a list of VLAN entries where one VLAN has as VLAN tag value of NA
. The Juniper ManagementHandler
implementation in PortAdmin expects all these values to be valid integers, and does not handle the unexpected case of a return value not being an integer.
To Reproduce
Not sure how to reliably reproduce the error unless the switch response can be reproduced first. If a switch with the problem is at hand, just opening the PortAdmin view for this switch should be enough to trigger the crash.
A reproduction through a python shell (export DJANGO_SETTINGS_MODULE=nav.django.settings ; django-admin shell
) could be achieved thus:
>>> from nav.portadmin.management import ManagementFactory
>>> from nav.models.manage import Netbox
>>> n = Netbox.objects.get(sysname='switchstack.example.org')
>>> m = ManagementFactory.get_instance(n)
>>> m.get_netbox_vlans()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/portadmin/napalm/juniper.py", line 224, in get_netbox_vlans
result = {_make_vlan(vlan) for vlan in self.vlans}
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/portadmin/napalm/juniper.py", line 224, in <setcomp>
result = {_make_vlan(vlan) for vlan in self.vlans}
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/portadmin/napalm/juniper.py", line 214, in _make_vlan
tag = int(vlan.tag)
ValueError: invalid literal for int() with base 10: 'NA'
>>>
Expected behavior
PortAdmin should not crash in an uncontrolled manner just because it receives strange data from a switch. PortAdmin mostly cares about VLANs in the form of tags, so the likely best course of action is to just ignore VLANs that have no associated tag.
Tracebacks
Traceback (most recent call last):
File "/opt/venvs/nav/lib/python3.7/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/opt/venvs/nav/lib/python3.7/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/web/portadmin/views.py", line 185, in search_by_interfaceid
populate_infodict(request, netbox, interfaces),
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/web/portadmin/views.py", line 199, in populate_infodict
request.account, netbox, interfaces, handler
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/web/portadmin/utils.py", line 78, in find_and_populate_allowed_vlans
allowed_vlans = find_allowed_vlans_for_user_on_netbox(account, netbox, handler)
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/web/portadmin/utils.py", line 87, in find_allowed_vlans_for_user_on_netbox
netbox_vlans = find_vlans_on_netbox(netbox, handler=handler)
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/web/portadmin/utils.py", line 112, in find_vlans_on_netbox
return handler.get_netbox_vlans()
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/portadmin/napalm/juniper.py", line 224, in get_netbox_vlans
result = {_make_vlan(vlan) for vlan in self.vlans}
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/portadmin/napalm/juniper.py", line 224, in <setcomp>
result = {_make_vlan(vlan) for vlan in self.vlans}
File "/opt/venvs/nav/lib/python3.7/site-packages/nav/portadmin/napalm/juniper.py", line 214, in _make_vlan
tag = int(vlan.tag)
Exception Type: ValueError at /portadmin/interfaceid=86404
Exception Value: invalid literal for int() with base 10: 'NA'
Environment (please complete the following information):
- NAV version installed: 5.4.0
- Method of installation: from Debian package