diff --git a/lib/App/Netdisco/DB/Result/DevicePort.pm b/lib/App/Netdisco/DB/Result/DevicePort.pm index 457ef6a2..216cf869 100644 --- a/lib/App/Netdisco/DB/Result/DevicePort.pm +++ b/lib/App/Netdisco/DB/Result/DevicePort.pm @@ -314,7 +314,44 @@ state, or else `undef` if the port is not in an error state. =cut -sub error_disable_cause { return (shift)->get_column('properties_error_disable_cause') } +sub error_disable_cause { return (shift)->get_column('error_disable_cause') } + +=head2 remote_is_wap + +Returns true if the remote LLDP neighbor has reported Wireless Access Point +capability. + +=cut + +sub remote_is_wap { return (shift)->get_column('remote_is_wap') } + +=head2 remote_is_phone + +Returns true if the remote LLDP neighbor has reported Telephone capability. + +=cut + +sub remote_is_phone { return (shift)->get_column('remote_is_phone') } + +=head2 remote_inventory + +Returns a synthesized description of the remote LLDP device if inventory +information was given, including vendor, model, OS version, and serial number. + +=cut + +sub remote_inventory { + my $port = shift; + my $os_ver = ($port->get_column('remote_os_ver') + ? ('running '. $port->get_column('remote_os_ver')) : ''); + my $serial = ($port->get_column('remote_serial') + ? ('('. $port->get_column('remote_serial') .')') : ''); + + my $retval = join ' ', ($port->get_column('remote_vendor') || ''), + ($port->get_column('remote_model') || ''), $serial, $os_ver; + + return (($retval =~ m/[[:alnum:]]/) ? $retval : ''); +} =head2 vlan_count diff --git a/lib/App/Netdisco/DB/Result/DevicePortProperties.pm b/lib/App/Netdisco/DB/Result/DevicePortProperties.pm index 80d4a3e8..ab43fb21 100644 --- a/lib/App/Netdisco/DB/Result/DevicePortProperties.pm +++ b/lib/App/Netdisco/DB/Result/DevicePortProperties.pm @@ -19,10 +19,10 @@ __PACKAGE__->add_columns( { data_type => "boolean", is_nullable => 1 }, "remote_vendor", { data_type => "text", is_nullable => 1 }, - "remote_os_ver", - { data_type => "text", is_nullable => 1 }, "remote_model", { data_type => "text", is_nullable => 1 }, + "remote_os_ver", + { data_type => "text", is_nullable => 1 }, "remote_serial", { data_type => "text", is_nullable => 1 }, ); diff --git a/lib/App/Netdisco/DB/ResultSet/DevicePort.pm b/lib/App/Netdisco/DB/ResultSet/DevicePort.pm index ff270ba8..cf0c978c 100644 --- a/lib/App/Netdisco/DB/ResultSet/DevicePort.pm +++ b/lib/App/Netdisco/DB/ResultSet/DevicePort.pm @@ -113,6 +113,10 @@ will add the following additional synthesized columns to the result set: =item error_disable_cause +=item remote_is_wap (boolean) + +=item remote_is_phone (boolean) + =back =cut @@ -124,8 +128,54 @@ sub with_properties { ->search_rs($cond, $attrs) ->search({}, { - '+select' => ['properties.error_disable_cause'], - '+as' => ['properties_error_disable_cause'], + '+select' => [qw/ + properties.error_disable_cause + properties.remote_is_wap + properties.remote_is_phone + /], + '+as' => [qw/ + error_disable_cause + remote_is_wap remote_is_phone + /], + join => 'properties', + }); +} + +=head2 with_remote_inventory + +This is a modifier for any C which +will add the following additional synthesized columns to the result set: + +=over 4 + +=item remote_vendor + +=item remote_model + +=item remote_os_ver + +=item remote_serial + +=back + +=cut + +sub with_remote_inventory { + my ($rs, $cond, $attrs) = @_; + + return $rs + ->search_rs($cond, $attrs) + ->search({}, + { + '+select' => [qw/ + properties.remote_vendor + properties.remote_model + properties.remote_os_ver + properties.remote_serial + /], + '+as' => [qw/ + remote_vendor remote_model remote_os_ver remote_serial + /], join => 'properties', }); } diff --git a/lib/App/Netdisco/Web/Plugin/Device/Ports.pm b/lib/App/Netdisco/Web/Plugin/Device/Ports.pm index 2e0619fa..e6e1b4a9 100644 --- a/lib/App/Netdisco/Web/Plugin/Device/Ports.pm +++ b/lib/App/Netdisco/Web/Plugin/Device/Ports.pm @@ -190,6 +190,9 @@ get '/ajax/content/device/ports' => require_login sub { '+as' => ['neighbor_ip', 'neighbor_dns'], }) if param('c_neighbors'); + # also get remote LLDP inventory if asked for + $set = $set->with_remote_inventory if param('n_inventory'); + # sort ports (empty set would be a 'no records' msg) my $results = [ sort { &App::Netdisco::Util::Web::sort_port($a->port, $b->port) } $set->all ]; return unless scalar @$results; diff --git a/share/config.yml b/share/config.yml index bacea941..08b80a24 100644 --- a/share/config.yml +++ b/share/config.yml @@ -122,17 +122,18 @@ sidebar_defaults: c_neighbors: { label: 'Connected Devices', default: checked, idx: 17 } c_stp: { label: 'Spanning Tree', default: null, idx: 18 } c_up: { label: 'Status', default: null, idx: 19 } - n_age: { label: 'Age Stamp', default: null, idx: 0 } - n_ip4: { label: 'IPv4 Addresses', default: checked, idx: 1 } - n_ip6: { label: 'IPv6 Addresses', default: checked, idx: 2 } - n_netbios: { label: 'NetBIOS Name', default: checked, idx: 3 } - n_ssid: { label: 'SSID', default: checked, idx: 4 } - n_vendor: { label: 'Vendor', default: null, idx: 5 } - n_archived: { label: 'Archived Data', default: null, idx: 6 } + mac_format: { default: IEEE } + n_inventory: { label: 'Inventory Data', default: checked, idx: 0 } + n_detailed_inventory: { label: 'Detailed Inventory', default: null, idx: 1 } + n_age: { label: 'Age Stamp', default: null, idx: 2 } + n_ip4: { label: 'IPv4 Addresses', default: checked, idx: 3 } + n_ip6: { label: 'IPv6 Addresses', default: checked, idx: 4 } + n_netbios: { label: 'NetBIOS Name', default: checked, idx: 5 } + n_ssid: { label: 'SSID', default: checked, idx: 6 } + n_vendor: { label: 'Vendor', default: null, idx: 7 } + n_archived: { label: 'Archived Data', default: null, idx: 8 } age_num: { default: 3 } age_unit: { default: months } - mac_format: { default: IEEE } - neigh_id: { default: null } device_netmap: showips: { default: null } showspeed: { default: null } diff --git a/share/views/ajax/device/ports.tt b/share/views/ajax/device/ports.tt index a89358ce..fbfd7456 100644 --- a/share/views/ajax/device/ports.tt +++ b/share/views/ajax/device/ports.tt @@ -267,9 +267,9 @@ [% IF params.c_neighbors AND (row.remote_ip OR row.is_uplink) %] [% IF row.get_column('neighbor_ip') %] - [% IF row.remote_type AND row.remote_type.match('(?i)ip.phone') %] + [% IF row.remote_is_phone %]   - [% ELSIF row.remote_type AND row.remote_type.match('^AP:\s') %] + [% ELSIF row.remote_is_wap %]   [% END %] @@ -280,21 +280,27 @@ [% row.remote_port | html_entity %] [% END %]
- [% IF params.neigh_id and (row.remote_id or row.remote_type) %] + [% IF params.n_inventory and row.remote_inventory %] + [% row.remote_inventory %]
+ [% END %] + [% IF params.n_detailed_inventory and (row.remote_id or row.remote_type) %] ([% 'id: '_ row.remote_id IF row.remote_id %] [% ' type: '_ row.remote_type IF row.remote_type %])
[% END %] [% ELSIF row.remote_ip %]   - [% IF row.remote_type AND row.remote_type.match('(?i)ip.phone') %] + [% IF row.remote_is_phone %]   - [% ELSIF row.remote_type AND row.remote_type.match('^AP:\s') %] + [% ELSIF row.remote_is_wap %]   [% END %] [% row.remote_ip | html_entity %] [% ' - ' IF row.remote_port %][% row.remote_port | html_entity %]
- [% IF params.neigh_id and (row.remote_id or row.remote_type) %] + [% IF params.n_inventory and row.remote_inventory %] + [% row.remote_inventory %]
+ [% END %] + [% IF params.n_detailed_inventory and (row.remote_id or row.remote_type) %] ([% 'id: '_ row.remote_id IF row.remote_id %] [% ' type: '_ row.remote_type IF row.remote_type %])
[% END %] @@ -306,10 +312,9 @@ [% FOREACH node IN row.$nodes %] [% '
' IF (row.remote_ip OR row.is_uplink) OR NOT loop.first %] [% '  ' IF NOT node.active %] - [% IF row.remote_type AND row.remote_type.match('(?i)ip.phone') %] + [% IF row.remote_is_phone %]   - [% ELSIF node.wireless.defined - OR (row.remote_type AND row.remote_type.match('^AP:\s')) %] + [% ELSIF node.wireless.defined OR row.remote_is_wap %]   [% END %] diff --git a/share/views/sidebar/device/ports.tt b/share/views/sidebar/device/ports.tt index fb56d353..5897ffbe 100644 --- a/share/views/sidebar/device/ports.tt +++ b/share/views/sidebar/device/ports.tt @@ -75,6 +75,33 @@ +
+ + +
+
    +
  • + MAC address format:
    + +
  • + [% FOREACH item IN settings.connected_properties %] +
  • + +
  • + [% END %] +
+
+
-
  • - -
  • - - - -
    - - -
    -
      -
    • - MAC address format:
      - -
    • - [% FOREACH item IN settings.connected_properties %] -
    • - -
    • - [% END %]