From 8cc8bdcd19ece58bb4eea6e577145aaf5218e51b Mon Sep 17 00:00:00 2001 From: Christian Ramseyer Date: Tue, 13 Dec 2022 09:16:32 +0100 Subject: [PATCH] Add NAC columns to UI (#941) * Add NAC columns to UI * Compact variant with a "NAC Summary" column * display PAE stuff as very short summary in web and full columbs in csv * add tooltips for actual port status and state detail * minor naming tweaks Co-authored-by: Oliver Gorwits --- lib/App/Netdisco/DB/Result/DevicePort.pm | 56 +++++++++++++++++++++ lib/App/Netdisco/DB/ResultSet/DevicePort.pm | 14 +++++- share/config.yml | 9 ++-- share/views/ajax/device/details.tt | 4 ++ share/views/ajax/device/ports.tt | 14 ++++++ share/views/ajax/device/ports_csv.tt | 16 ++++++ 6 files changed, 108 insertions(+), 5 deletions(-) diff --git a/lib/App/Netdisco/DB/Result/DevicePort.pm b/lib/App/Netdisco/DB/Result/DevicePort.pm index 3d8da347..a99544e9 100644 --- a/lib/App/Netdisco/DB/Result/DevicePort.pm +++ b/lib/App/Netdisco/DB/Result/DevicePort.pm @@ -389,6 +389,62 @@ Returns the interface index (C) of the port. sub ifindex { return (shift)->get_column('ifindex') } +=head2 pae_authsess_user + +Returns the pae_authsess_user of the port. + +=cut + +sub pae_authsess_user { return (shift)->get_column('pae_authsess_user') } + +=head2 pae_authsess_user_net_mac + +Returns the pae_authsess_user of the port as a NetAddr::MAC instance. + +=cut + +sub pae_authsess_user_net_mac { return NetAddr::MAC->new(mac => ((shift)->pae_authsess_user || '')) } + +=head2 pae_authconfig_port_control + +Returns the pae_authconfig_port_control of the port. + +=cut + +sub pae_authconfig_port_control { return (shift)->get_column('pae_authconfig_port_control') } + +=head2 pae_authconfig_state + +Returns the pae_authconfig_state of the port. + +=cut + +sub pae_authconfig_state { return (shift)->get_column('pae_authconfig_state') } + +=head2 pae_authconfig_port_status + +Returns the pae_authconfig_port_status of the port. + +=cut + +sub pae_authconfig_port_status { return (shift)->get_column('pae_authconfig_port_status') } + +=head2 pae_authsess_mab + +Returns the pae_authsess_mab of the port. + +=cut + +sub pae_authsess_mab { return (shift)->get_column('pae_authsess_mab') } + +=head2 pae_last_eapol_frame_source + +Returns the pae_last_eapol_frame_source of the port. + +=cut + +sub pae_last_eapol_frame_source { return (shift)->get_column('pae_last_eapol_frame_source') } + =head2 remote_dns Returns a hostname resolved from C column. diff --git a/lib/App/Netdisco/DB/ResultSet/DevicePort.pm b/lib/App/Netdisco/DB/ResultSet/DevicePort.pm index 253b96a4..d95bf542 100644 --- a/lib/App/Netdisco/DB/ResultSet/DevicePort.pm +++ b/lib/App/Netdisco/DB/ResultSet/DevicePort.pm @@ -158,11 +158,23 @@ sub with_properties { properties.remote_is_phone properties.remote_dns properties.ifindex + properties.pae_authconfig_port_control + properties.pae_authconfig_state + properties.pae_authconfig_port_status + properties.pae_authsess_user + properties.pae_authsess_mab + properties.pae_last_eapol_frame_source /], '+as' => [qw/ error_disable_cause remote_is_discoverable remote_is_wap remote_is_phone remote_dns - ifindex + ifindex + pae_authconfig_port_control + pae_authconfig_state + pae_authconfig_port_status + pae_authsess_user + pae_authsess_mab + pae_last_eapol_frame_source /], join => 'properties', }); diff --git a/share/config.yml b/share/config.yml index 99cb2bc5..96fa76d2 100644 --- a/share/config.yml +++ b/share/config.yml @@ -130,10 +130,11 @@ sidebar_defaults: c_vmember: { label: 'VLAN Membership', default: checked, idx: 15 } c_power: { label: 'PoE', default: null, idx: 16 } c_ssid: { label: 'SSID', default: null, idx: 17 } - c_nodes: { label: 'Connected Nodes', default: null, idx: 18 } - c_neighbors: { label: 'Connected Devices', default: checked, idx: 19 } - c_stp: { label: 'Spanning Tree', default: null, idx: 20 } - c_up: { label: 'Status', default: null, idx: 21 } + c_nac_summary: { label: 'NAC/802.1X Status', default: null, idx: 18 } + c_nodes: { label: 'Connected Nodes', default: null, idx: 19 } + c_neighbors: { label: 'Connected Devices', default: checked, idx: 20 } + c_stp: { label: 'Spanning Tree', default: null, idx: 21 } + c_up: { label: 'Up/Down Status', default: null, idx: 22 } mac_format: { default: IEEE } n_inventory: { label: 'Remote Inventory', default: checked, idx: 0 } n_detailed_inventory: { label: 'Remote Advertisement', default: null, idx: 1 } diff --git a/share/views/ajax/device/details.tt b/share/views/ajax/device/details.tt index 8cfc1675..677180cb 100644 --- a/share/views/ajax/device/details.tt +++ b/share/views/ajax/device/details.tt @@ -144,6 +144,10 @@ Last Macsuck [% d.last_macsuck_stamp | html_entity %] + + NAC / 802.1X + [% IF d.pae_is_enabled %] Enabled [% END %] + Hardware Status Fan: [% d.fan | html_entity %] diff --git a/share/views/ajax/device/ports.tt b/share/views/ajax/device/ports.tt index 80955ca6..d1ff2f8b 100644 --- a/share/views/ajax/device/ports.tt +++ b/share/views/ajax/device/ports.tt @@ -318,6 +318,20 @@ [% row.ssid.ssid | html_entity %] [% END %] + [% IF params.c_nac_summary %] + + [% IF row.up == 'up' AND (row.pae_authconfig_port_status OR row.pae_authconfig_state) %] + + + + [% SET sessuser = (row.pae_authsess_user_net_mac.$mac_format_call || row.pae_authsess_user.remove(settings.domain_suffix)) %] + [% sessuser | html_entity %] + [% END %] + + [% END %] + [% IF params.c_nodes OR params.c_neighbors %] [% IF params.c_neighbors AND (row.remote_ip OR row.is_uplink) %] diff --git a/share/views/ajax/device/ports_csv.tt b/share/views/ajax/device/ports_csv.tt index 7827b0fd..db7c6c1c 100644 --- a/share/views/ajax/device/ports_csv.tt +++ b/share/views/ajax/device/ports_csv.tt @@ -20,6 +20,13 @@ [% ELSIF item.name == 'c_power' %] [% headers.push('PoE Status') %] [% headers.push('PoE Power (mW)') %] + [% ELSIF item.name == 'c_nac_summary' %] + [% headers.push('PAE AuthConfig Port Control') %] + [% headers.push('PAE AuthConfig State') %] + [% headers.push('PAE AuthConfig Port Status') %] + [% headers.push('PAE AuthSession User') %] + [% headers.push('PAE AuthSession MAB') %] + [% headers.push('PAE Last EAPOL Frame Source') %] [% ELSIF item.name == 'c_neighbors' %] [% headers.push('Neighbor IP') %] [% headers.push('Neighbor DNS') %] @@ -137,6 +144,15 @@ [% END %] [% END %] + [% IF params.c_nac_summary %] + [% myport.push( row.pae_authconfig_port_control ) %] + [% myport.push( row.pae_authconfig_state ) %] + [% myport.push( row.pae_authconfig_port_status ) %] + [% myport.push( row.pae_authsess_user ) %] + [% myport.push( row.pae_authsess_mab ) %] + [% myport.push( row.pae_last_eapol_frame_source ) %] + [% END %] + [% IF params.c_nodes %] [% myport.push('') %] [% myport.push('') %]