From db77e99fa2f6e0830ed8127bc3d586e85184f5fc Mon Sep 17 00:00:00 2001 From: Simon Oliver Tveit Date: Thu, 23 Nov 2023 11:14:43 +0100 Subject: [PATCH 1/6] Aadd util for registering poe info --- python/nav/web/portadmin/utils.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/python/nav/web/portadmin/utils.py b/python/nav/web/portadmin/utils.py index 7b3d425cda..221b06e170 100644 --- a/python/nav/web/portadmin/utils.py +++ b/python/nav/web/portadmin/utils.py @@ -243,3 +243,11 @@ def is_cisco(netbox): :type netbox: manage.Netbox """ return netbox.type.get_enterprise_id() == VENDOR_ID_CISCOSYSTEMS + + +def add_poe_info(interfaces, handler): + """Add information about PoE state for interfaces""" + states = handler.get_poe_states(interfaces) + for interface in interfaces: + interface.poe_state = states.get(interface.ifname) + interface.supports_poe = True if interface.poe_state else False From 551a9d45734b9bb26b0732254067588248f2ed35 Mon Sep 17 00:00:00 2001 From: Simon Oliver Tveit Date: Thu, 23 Nov 2023 11:15:40 +0100 Subject: [PATCH 2/6] Register poe data in dict for html render --- python/nav/web/portadmin/views.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/python/nav/web/portadmin/views.py b/python/nav/web/portadmin/views.py index 7069115f04..202669c0fb 100644 --- a/python/nav/web/portadmin/views.py +++ b/python/nav/web/portadmin/views.py @@ -46,6 +46,7 @@ mark_detained_interfaces, is_cisco, add_dot1x_info, + add_poe_info, ) from nav.portadmin.config import CONFIG from nav.portadmin.snmp.base import SNMPHandler @@ -55,6 +56,9 @@ NoResponseError, ProtocolError, ManagementError, + POEIndexNotFoundError, + XMLParseError, + POEStateNotSupportedError, ) from .forms import SearchForm from ...portadmin.handlers import DeviceNotConfigurableError @@ -192,6 +196,8 @@ def populate_infodict(request, netbox, interfaces): voice_vlan = None readonly = False handler = None + supports_poe = False + poe_options = [] try: handler = get_and_populate_livedata(netbox, interfaces) @@ -207,6 +213,17 @@ def populate_infodict(request, netbox, interfaces): mark_detained_interfaces(interfaces) if CONFIG.is_dot1x_enabled(): add_dot1x_info(interfaces, handler) + try: + poe_options = handler.get_poe_state_options() + add_poe_info(interfaces, handler) + # Tag poe as being supported if at least one interface supports poe + for interface in interfaces: + if interface.supports_poe: + supports_poe = True + break + except NotImplementedError: + # Only Cisco and Juniper has PoE support currently + pass except NoResponseError: readonly = True messages.error( @@ -230,6 +247,14 @@ def populate_infodict(request, netbox, interfaces): readonly = True messages.error(request, str(error)) + except ( + POEIndexNotFoundError, + XMLParseError, + POEStateNotSupportedError, + ) as error: + readonly = True + messages.error(request, str(error)) + if handler and not handler.is_configurable(): add_readonly_reason(request, handler) readonly = True @@ -260,6 +285,8 @@ def populate_infodict(request, netbox, interfaces): 'aliastemplate': aliastemplate, 'trunk_edit': CONFIG.get_trunk_edit(), 'auditlog_api_parameters': json.dumps(auditlog_api_parameters), + 'supports_poe': supports_poe, + 'poe_options': poe_options, } ) return info_dict From 85bc754bba88bd7df5e1dc1142469cf502e3205a Mon Sep 17 00:00:00 2001 From: Simon Oliver Tveit Date: Thu, 23 Nov 2023 11:16:32 +0100 Subject: [PATCH 3/6] Add html for showing and selecting poe states --- .../nav/web/templates/portadmin/portlist.html | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/python/nav/web/templates/portadmin/portlist.html b/python/nav/web/templates/portadmin/portlist.html index 7a343cf8b5..fac7c4e344 100644 --- a/python/nav/web/templates/portadmin/portlist.html +++ b/python/nav/web/templates/portadmin/portlist.html @@ -36,6 +36,11 @@ Tel {% endif %} + {% if supports_poe %} +
+ PoE State +
+ {% endif %}
{% if not readonly %} @@ -162,6 +167,24 @@
{% endif %} + {# POE STATE #} + {% if supports_poe %} + {% if interface.supports_poe %} +
+
+ +
+
+ {% endif %} + {% endif %} + {# Button for saving #}
{% if interface.iseditable and not readonly %} From 02a0ea68743c11b037fecd9e3b079797db561760 Mon Sep 17 00:00:00 2001 From: Simon Oliver Tveit Date: Thu, 23 Nov 2023 11:16:54 +0100 Subject: [PATCH 4/6] Add javascript to make Poe html reactive --- python/nav/web/static/js/src/portadmin.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/python/nav/web/static/js/src/portadmin.js b/python/nav/web/static/js/src/portadmin.js index 1e146cf5a9..4b1224d1d7 100644 --- a/python/nav/web/static/js/src/portadmin.js +++ b/python/nav/web/static/js/src/portadmin.js @@ -176,13 +176,16 @@ require(['libs/spin.min', 'libs/jquery-ui.min'], function (Spinner) { $wrapper.on('change', '.ifadminstatus', function (event) { actOnChange($(event.target).parents(parentSelector)); }); + $wrapper.on('change', '.poelist', function (event) { + actOnChange($(event.target).parents(parentSelector)); + }); } /* * Mark card changed or not based on values in card */ function actOnChange(row) { - if (textFieldChanged(row) || dropDownChanged(row) || voiceVlanChanged(row) || adminStatusChanged(row)) { + if (textFieldChanged(row) || dropDownChanged(row) || voiceVlanChanged(row) || adminStatusChanged(row) || poeDropDownChanged(row)) { markAsChanged(row); } else { markAsUnchanged(row); @@ -219,6 +222,13 @@ require(['libs/spin.min', 'libs/jquery-ui.min'], function (Spinner) { return origOption !== selectedOption; } + function poeDropDownChanged(row) { + var dropdown = $(row).find(".poelist"); + var origOption = $('[data-orig]', dropdown)[0]; + var selectedOption = $('option:selected', dropdown)[0]; + return origOption !== selectedOption; + } + function voiceVlanChanged(row) { /* * XOR checkbox checked and original value to see if changed @@ -303,6 +313,9 @@ require(['libs/spin.min', 'libs/jquery-ui.min'], function (Spinner) { data.ifadminstatus = 2; } } + if (poeDropDownChanged($row)) { + data.poe_state = $row.find(".poelist").val(); + } if ($row.find(".voicevlan").prop('checked')) { data.voice_activated = true; } From 194616c993c9ce7e58e93e25a1d1c5d2ee2e0550 Mon Sep 17 00:00:00 2001 From: Simon Oliver Tveit Date: Thu, 23 Nov 2023 11:17:12 +0100 Subject: [PATCH 5/6] Update poe state during save --- python/nav/web/portadmin/views.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/python/nav/web/portadmin/views.py b/python/nav/web/portadmin/views.py index 202669c0fb..23ddb3383a 100644 --- a/python/nav/web/portadmin/views.py +++ b/python/nav/web/portadmin/views.py @@ -390,11 +390,23 @@ def set_interface_values(account, interface, request): set_ifalias(account, handler, interface, request) set_vlan(account, handler, interface, request) set_admin_status(handler, interface, request) + set_poe_state(handler, interface, request) save_to_database([interface]) else: messages.info(request, 'Could not connect to netbox') +def set_poe_state(handler, interface, request): + if 'poe_state' in request.POST: + poe_state_name = request.POST.get('poe_state') + for option in handler.get_poe_state_options(): + if option.name == poe_state_name: + handler.set_poe_state(interface, option) + return + # If there was no match between posted value and known states + raise ValueError(f"Invalid PoE state name: {poe_state_name}") + + def build_ajax_messages(request): """Create a structure suitable for converting to json from messages""" ajax_messages = [] From 6e8ff9f231940704ab9daa217d0b7d2746870ef2 Mon Sep 17 00:00:00 2001 From: Simon Oliver Tveit Date: Fri, 24 Nov 2023 14:06:21 +0100 Subject: [PATCH 6/6] Reduce descr size to make space for poe dropdown --- python/nav/web/templates/portadmin/portlist.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/nav/web/templates/portadmin/portlist.html b/python/nav/web/templates/portadmin/portlist.html index fac7c4e344..e6f40e6a98 100644 --- a/python/nav/web/templates/portadmin/portlist.html +++ b/python/nav/web/templates/portadmin/portlist.html @@ -25,7 +25,7 @@
Linked
-
+
Port description
@@ -37,7 +37,7 @@
{% endif %} {% if supports_poe %} -
+
PoE State
{% endif %} @@ -81,7 +81,7 @@
{# Port Description - input field #} -
+
{% if interface.iseditable and not readonly %} +