From 6695f659a12df5e18528717d7fc8f4dd458b76cc Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Sat, 23 Aug 2014 13:35:32 +0100 Subject: [PATCH 01/18] fix get_arp docs --- Netdisco/lib/App/Netdisco/Core/Arpnip.pm | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Netdisco/lib/App/Netdisco/Core/Arpnip.pm b/Netdisco/lib/App/Netdisco/Core/Arpnip.pm index 3480f792..d52d7801 100644 --- a/Netdisco/lib/App/Netdisco/Core/Arpnip.pm +++ b/Netdisco/lib/App/Netdisco/Core/Arpnip.pm @@ -96,14 +96,21 @@ sub _get_arps { return $resolved_ips; } -=head2 store_arp( $mac, $ip, $name, $now? ) +=head2 store_arp( \%host, $now? ) Stores a new entry to the C table with the given MAC, IP (v4 or v6) -and DNS host name. +and DNS host name. Host details are provided in a Hash ref: -Will mark old entries for this IP as no longer C. + { + ip => '192.0.2.1', + node => '00:11:22:33:44:55', + dns => 'myhost.example.com', + } -Optionally a literal string can be passed in the fourth argument for the +The C entry is optional. The update will mark old entries for this IP as +no longer C. + +Optionally a literal string can be passed in the second argument for the C timestamp, otherwise the current timestamp (C) is used. =cut From b59e844d57b786b0b15082c6119a33a8731b7d34 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 25 Aug 2014 10:13:18 +0100 Subject: [PATCH 02/18] netdisco-sshcollector script to get ARP data on devices without SNMP --- Netdisco/Changes | 6 + Netdisco/MANIFEST | 4 + Netdisco/META.yml | 2 +- Netdisco/Makefile.PL | 2 + Netdisco/bin/netdisco-sshcollector | 268 ++++++++++++++++++ .../App/Netdisco/SSHCollector/Platform/ACE.pm | 87 ++++++ .../Netdisco/SSHCollector/Platform/BigIP.pm | 66 +++++ .../App/Netdisco/SSHCollector/Platform/IOS.pm | 55 ++++ 8 files changed, 489 insertions(+), 1 deletion(-) create mode 100644 Netdisco/bin/netdisco-sshcollector create mode 100644 Netdisco/lib/App/Netdisco/SSHCollector/Platform/ACE.pm create mode 100644 Netdisco/lib/App/Netdisco/SSHCollector/Platform/BigIP.pm create mode 100644 Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOS.pm diff --git a/Netdisco/Changes b/Netdisco/Changes index 781e3fff..36004b67 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,3 +1,9 @@ +2.029006 - + + [NEW FEATURES] + + * netdisco-sshcollector script to get ARP data on devices without SNMP (C. Ramseyer) + 2.029005 - 2014-08-13 [ENHANCEMENTS] diff --git a/Netdisco/MANIFEST b/Netdisco/MANIFEST index 8ef8ad38..55ae30c4 100644 --- a/Netdisco/MANIFEST +++ b/Netdisco/MANIFEST @@ -6,6 +6,7 @@ bin/netdisco-db-deploy bin/netdisco-deploy bin/netdisco-do bin/netdisco-rancid-export +bin/netdisco-sshcollector bin/netdisco-web bin/netdisco-web-fg Changes @@ -148,6 +149,9 @@ lib/App/Netdisco/Manual/Deployment.pod lib/App/Netdisco/Manual/Developing.pod lib/App/Netdisco/Manual/ReleaseNotes.pod lib/App/Netdisco/Manual/WritingPlugins.pod +lib/App/Netdisco/SSHCollector/Platform/ACE.pm +lib/App/Netdisco/SSHCollector/Platform/BigIP.pm +lib/App/Netdisco/SSHCollector/Platform/IOS.pm lib/App/Netdisco/Util/Daemon.pm lib/App/Netdisco/Util/Device.pm lib/App/Netdisco/Util/DNS.pm diff --git a/Netdisco/META.yml b/Netdisco/META.yml index 2d7e34e7..1d97f731 100644 --- a/Netdisco/META.yml +++ b/Netdisco/META.yml @@ -24,6 +24,7 @@ no_index: recommends: Graph: 0 GraphViz: 0 + Net::OpenSSH: 0 requires: Algorithm::Cron: 0.07 AnyEvent: 7.05 @@ -69,7 +70,6 @@ requires: Sereal: 0 Socket6: 0.23 Starman: 0.4008 - Sys::Proctitle: 0 Template: 2.24 Template::Plugin::CSV: 0.04 Template::Plugin::Number::Format: 1.02 diff --git a/Netdisco/Makefile.PL b/Netdisco/Makefile.PL index 8e818eb4..1e53763b 100644 --- a/Netdisco/Makefile.PL +++ b/Netdisco/Makefile.PL @@ -70,6 +70,7 @@ if ( $^O eq 'linux' ) { recommends 'Graph' => 0; recommends 'GraphViz' => 0; +recommends 'Net::OpenSSH' => 0; install_share 'share'; @@ -82,6 +83,7 @@ install_script 'bin/netdisco-daemon'; install_script 'bin/netdisco-web-fg'; install_script 'bin/netdisco-web'; install_script 'bin/netdisco-rancid-export'; +install_script 'bin/netdisco-sshcollector'; resources homepage => 'http://netdisco.org/', diff --git a/Netdisco/bin/netdisco-sshcollector b/Netdisco/bin/netdisco-sshcollector new file mode 100644 index 00000000..38747b1b --- /dev/null +++ b/Netdisco/bin/netdisco-sshcollector @@ -0,0 +1,268 @@ +#!/usr/bin/env perl + +# vim: set expandtab tabstop=8 softtabstop=4 shiftwidth=4: + +=head1 NAME + +netdisco-sshcollector - Collect ARP data for Netdisco from devices without +full SNMP support + +=head1 DESCRIPTION + +Collects ARP data for Netdisco from devices without full SNMP support. +Currently, ARP tables can be retrieved from the following device classes: + +=over 4 + +=item * L - Cisco ACE (Application Control Engine) + +=item * L - F5 Networks BigIP + +=item * L - Cisco IOS + +=back + +The collected arp entries are then directly stored in the netdisco database. + +=head1 CONFIGURATION + +The following should go into your Netdisco 2 configuration file, "C<< +~/environments/deployment.yml >>" + +=over 4 + +=item C + +Data is collected from the machines specified in this setting. The format is a +list of dictionaries. The keys C, C, C, and C +are required. Optionally the C key can be used instead of the +C. For example: + + sshcollector: + - ip: '192.0.2.1' + user: oliver + password: letmein + platform: IOS + - hostname: 'core-router.example.com' + user: oliver + password: letmein + platform: IOS + +Platform is the final part of the classname to be instantiated to query the +host, e.g. platform B will be queried using +C. + +If the password is "-", public key authentication will be attempted. + +=back + +=head1 ADDING DEVICES + +Additional device classes can be easily integrated just by adding and +additonal class to the C namespace. +This class must implement an C method which returns +an array of hashrefs in the format + + @result = ({ ip => IPADDR, mac => MACADDR }, ...) + +The parameter C<$ssh> is an active C connection to the host. +Depending on the target system, it can be queried using simple methods like + + my @data = $ssh->capture("show whatever") + +or automated via Expect - this is mostly useful for non-Linux appliances which +don't support command execution via ssh: + + my ($pty, $pid) = $ssh->open2pty or die "unable to run remote command"; + my $expect = Expect->init($pty); + my $prompt = qr/#/; + my ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + $expect->send("terminal length 0\n"); + # etc... + +The returned IP and MAC addresses should be in a format that the respective +B and B datatypes in PostgreSQL can handle. + +=head1 DEPENDENCIES + +=over 4 + +=item L + +=item L + +=back + +=head1 COPYRIGHT AND LICENSE + + Copyright (C) 2013 by the Netdisco Project + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Netdisco Project nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE NETDISCO DEVELOPER TEAM BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Initial Version for Netdisco 1.x + Copyright (C) 2013 by Christian Ramseyer (ramseyer@netnea.com) + I hereby grant full ownership of the code to the Netdisco Project + +=cut + +use warnings; +use strict; + +our $VERSION = 2.001000; +our $home; + +BEGIN { + use FindBin; + FindBin::again(); + + $home = ($ENV{NETDISCO_HOME} || $ENV{HOME}); + + # try to find a localenv if one isn't already in place. + if (!exists $ENV{PERL_LOCAL_LIB_ROOT}) { + use File::Spec; + my $localenv = File::Spec->catfile($FindBin::RealBin, 'localenv'); + exec($localenv, $0, @ARGV) if -f $localenv; + $localenv = File::Spec->catfile($home, 'perl5', 'bin', 'localenv'); + exec($localenv, $0, @ARGV) if -f $localenv; + + die "Sorry, can't find libs required for App::Netdisco.\n" + if !exists $ENV{PERLBREW_PERL}; + } +} + +BEGIN { + use Path::Class; + + # stuff useful locations into @INC and $PATH + unshift @INC, + dir($FindBin::RealBin)->parent->subdir('lib')->stringify, + dir($FindBin::RealBin, 'lib')->stringify; + + unshift @INC, + split m/:/, ($ENV{NETDISCO_INC} || ''); + + use Config; + $ENV{PATH} = $FindBin::RealBin . $Config{path_sep} . $ENV{PATH}; +} + +use App::Netdisco; +use App::Netdisco::Core::Arpnip 'store_arp'; +use App::Netdisco::Util::Node 'check_mac'; +use App::Netdisco::Util::DNS 'hostnames_resolve_async'; +use Dancer ':script'; + +use Data::Printer; +use Module::Load (); +use Net::OpenSSH; +use MCE::Loop Sereal => 1; + +#this may be helpful with SSH issues: +#$Net::OpenSSH::debug = ~0; + +MCE::Loop::init { chunk_size => 1 }; +my %stats; + +exit main(); + +sub main { + my @input = @{ setting('sshcollector') }; + + my @mce_result = mce_loop { + my ($mce, $chunk_ref, $chunk_id) = @_; + my $host = $chunk_ref->[0]; + + my $hostlabel = (!defined $host->{hostname} or $host->{hostname} eq "-") + ? $host->{ip} : $host->{hostname}; + + if ($hostlabel) { + my $ssh = Net::OpenSSH->new( + $hostlabel, + user => $host->{user}, + password => $host->{password}, + timeout => 30, + async => 0, + master_opts => [ + -o => "StrictHostKeyChecking=no", + -o => "BatchMode=no" + ], + ); + + MCE->gather( process($hostlabel, $ssh, $host) ); + } + } \@input; + + return 0 unless scalar @mce_result; + + foreach my $host (@mce_result) { + $stats{host}++; + info sprintf ' [%s] arpnip - retrieved %s entries', + $host->[0], scalar @{$host->[1]}; + store_arpentries($host->[1]); + } + + info sprintf 'arpnip - processed %s ARP Cache entries from %s devices', + $stats{entry}, $stats{host}; + return 0; +} + +sub process { + my ($hostlabel, $ssh, $args) = @_; + + my $class = "App::Netdisco::SSHCollector::Platform::".$args->{platform}; + Module::Load::load $class; + + my $device = $class->new(); + my $arpentries = [ $device->arpnip($hostlabel, $ssh, $args) ]; + + # debug p $arpentries; + if (scalar @$arpentries) { + hostnames_resolve_async($arpentries); + return [$hostlabel, $arpentries]; + } + else { + warning "WARNING: no entries received from <$hostlabel>"; + } +} + +sub store_arpentries { + my ($arpentries) = @_; + + foreach my $arpentry ( @$arpentries ) { + # skip broadcast/vrrp/hsrp and other wierdos + next unless check_mac( undef, $arpentry->{mac} ); + + debug sprintf ' arpnip - stored entry: %s / %s', + $arpentry->{mac}, $arpentry->{ip}; + store_arp({ + node => $arpentry->{mac}, + ip => $arpentry->{ip}, + dns => $arpentry->{dns}, + }); + + $stats{entry}++; + } +} + +__END__ + diff --git a/Netdisco/lib/App/Netdisco/SSHCollector/Platform/ACE.pm b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/ACE.pm new file mode 100644 index 00000000..9cb1b1b8 --- /dev/null +++ b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/ACE.pm @@ -0,0 +1,87 @@ +package App::Netdisco::SSHCollector::Platform::ACE; + +# vim: set expandtab tabstop=8 softtabstop=4 shiftwidth=4: + +=head1 NAME + +App::Netdisco::SSHCollector::Platform::ACE + +=head1 DESCRIPTION + +Collect ARP entries from Cisco ACE load balancers. ACEs have multiple +virtual contexts with individual ARP tables. Contexts are enumerated +with C, afterwards the commands C and +C must be executed for every context. + +The IOS shell does not permit to combine mulitple commands in a single +line, and Net::OpenSSH uses individual connections for individual commands, +so we need to use Expect to execute the changeto and show commands in +the same context. + +=cut + +use strict; +use warnings; + +use Moo; +use Expect; + +=head1 PUBLIC METHODS + +=over 4 + +=item B + +Retrieve ARP entries from device. C<$host> is the hostname or IP address +of the device. C<$ssh> is a Net::OpenSSH connection to the device. + +Returns an array of hashrefs in the format { mac => MACADDR, ip => IPADDR }. + +=cut + +sub arpnip{ + my ($self, $hostlabel, $ssh, @args) = @_; + + debug "$hostlabel $$ arpnip()"; + + my ($pty, $pid) = $ssh->open2pty or die "unable to run remote command"; + my $expect = Expect->init($pty); + + my ($pos, $error, $match, $before, $after); + my $prompt = qr/#/; + + ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + + $expect->send("terminal length 0\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(5, -re, $prompt); + + $expect->send("show context | include Name\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(5, -re, $prompt); + + my @ctx; + my @arpentries; + + for (split(/\n/, $before)){ + if (m/Name: (\S+)/){ + push(@ctx, $1); + $expect->send("changeto $1\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(5, -re, $prompt); + $expect->send("show arp\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(5, -re, $prompt); + for (split(/\n/, $before)){ + my ($ip, $mac) = split(/\s+/); + if ($ip =~ m/(\d{1,3}\.){3}\d{1,3}/ && $mac =~ m/[0-9a-f.]+/i) { + push(@arpentries, { ip => $ip, mac => $mac }); + } + } + + } + } + + $expect->send("exit\n"); + $expect->soft_close(); + + return @arpentries; +} + +1; diff --git a/Netdisco/lib/App/Netdisco/SSHCollector/Platform/BigIP.pm b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/BigIP.pm new file mode 100644 index 00000000..7feb553b --- /dev/null +++ b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/BigIP.pm @@ -0,0 +1,66 @@ +package App::Netdisco::SSHCollector::Platform::BigIP; + +# vim: set expandtab tabstop=8 softtabstop=4 shiftwidth=4: + +=head1 NAME + +NApp::etdisco::SSHCollector::Platform::BigIP + +=head1 DESCRIPTION + +Collect ARP entries from F5 BigIP load balancers. These are Linux boxes, +but feature an additional, proprietary IP stack which does not show +up in the standard SNMP ipNetToMediaTable. + +These devices also feature a CLI interface similar to IOS, which can +either be set as the login shell of the user, or be called from an +ordinary shell. This module assumes the former, and if "show net arp" +can't be executed, falls back to the latter. + +=cut + +use strict; +use warnings; + +use Moo; + +=head1 PUBLIC METHODS + +=over 4 + +=item B + +Retrieve ARP entries from device. C<$host> is the hostname or IP address +of the device. C<$ssh> is a Net::OpenSSH connection to the device. + +Returns an array of hashrefs in the format { mac => MACADDR, ip => IPADDR }. + +=cut +sub arpnip { + my ($self, $hostlabel, $ssh, @args) = @_; + + debug "$hostlabel $$ arpnip()"; + + my @data = $ssh->capture("show net arp"); + unless (@data){ + @data = $ssh->capture('tmsh -c "show net arp"'); + } + + chomp @data; + my @arpentries; + + foreach (@data){ + if (m/\d{1,3}\..*resolved/){ + my (undef, $ip, $mac) = split(/\s+/); + + # ips can look like 172.19.254.143%10, clean + $ip =~ s/%\d+//; + + push(@arpentries, {mac => $mac, ip => $ip}); + } + } + + return @arpentries; +} + +1; diff --git a/Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOS.pm b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOS.pm new file mode 100644 index 00000000..1165e6d5 --- /dev/null +++ b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOS.pm @@ -0,0 +1,55 @@ +package App::Netdisco::SSHCollector::Platform::IOS; + +# vim: set expandtab tabstop=8 softtabstop=4 shiftwidth=4: + +=head1 NAME + +App::Netdisco::SSHCollector::Platform::IOS + +=head1 DESCRIPTION + +Collect ARP entries from Cisco IOS devices. + +=cut + +use strict; +use warnings; + +use Dancer ':script'; +use Data::Printer; +use Moo; + +=head1 PUBLIC METHODS + +=over 4 + +=item B + +Retrieve ARP entries from device. C<$host> is the hostname or IP address +of the device. C<$ssh> is a Net::OpenSSH connection to the device. + +Returns an array of hashrefs in the format { mac => MACADDR, ip => IPADDR }. + +=cut + +sub arpnip { + my ($self, $hostlabel, $ssh, @args) = @_; + + debug "$hostlabel $$ arpnip()"; + my @data = $ssh->capture("show ip arp"); + + chomp @data; + my @arpentries; + + # Internet 172.16.20.15 13 0024.b269.867d ARPA FastEthernet0/0.1 + foreach my $line (@data) { + next unless $line =~ m/^Internet/; + my @fields = split m/\s+/, $line; + + push @arpentries, { mac => $fields[3], ip => $fields[1] }; + } + + return @arpentries; +} + +1; From 7411cf6cdd1880af1c0d60aa7ad364f461f4b556 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 25 Aug 2014 13:38:45 +0100 Subject: [PATCH 03/18] Search device by CDP/LLDP advertised ID or Type --- Netdisco/Changes | 1 + Netdisco/lib/App/Netdisco/DB/Result/Device.pm | 11 +++++++++++ .../lib/App/Netdisco/DB/ResultSet/Device.pm | 17 +++++++++++++++-- .../App/Netdisco/Web/Plugin/Search/Device.pm | 3 ++- Netdisco/share/views/sidebar/search/device.tt | 16 ++++++++++++++++ 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 36004b67..dcde77f2 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -3,6 +3,7 @@ [NEW FEATURES] * netdisco-sshcollector script to get ARP data on devices without SNMP (C. Ramseyer) + * Search device by CDP/LLDP advertised ID or Type 2.029005 - 2014-08-13 diff --git a/Netdisco/lib/App/Netdisco/DB/Result/Device.pm b/Netdisco/lib/App/Netdisco/DB/Result/Device.pm index 19aefbc2..cb602726 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/Device.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/Device.pm @@ -177,6 +177,17 @@ __PACKAGE__->has_many( 'ip', { join_type => 'RIGHT' } ); +=head2 neighbor_ports + +Returns the set of ports on other devices which connect to this device + +=cut + +__PACKAGE__->has_many( + neighbor_ports => 'App::Netdisco::DB::Result::DevicePort', + { 'foreign.remote_ip' => 'self.ip' }, +); + =head2 community Returns the row from the community string table, if one exists. diff --git a/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm b/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm index 79050cff..9feb1768 100644 --- a/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm +++ b/Netdisco/lib/App/Netdisco/DB/ResultSet/Device.pm @@ -176,6 +176,14 @@ Will match exactly the C field, which is the operating sytem software ve Will match exactly the C (manufacturer). +=item neighbor_id + +Will match the device if it has advertised this ID to a CDP/LLDP neighbor. + +=item neighbor_type + +Will match the device if it has advertised this Type to a CDP/LLDP neighbor. + =item dns Can match any of the Device IP address aliases as a substring. @@ -234,6 +242,11 @@ sub search_by_field { ($p->{layers} ? ('me.layers' => { '-ilike' => "\%$layer_string" }) : ()), + ($p->{neighbor_id} ? ('neighbor_ports.remote_id' => + { '-ilike' => "\%$p->{neighbor_id}\%" }) : ()), + ($p->{neighbor_type} ? ('neighbor_ports.remote_type' => + { '-ilike' => "\%$p->{neighbor_type}\%" }) : ()), + ($p->{model} ? ('me.model' => { '-in' => $p->{model} }) : ()), ($p->{os_ver} ? ('me.os_ver' => @@ -256,8 +269,8 @@ sub search_by_field { }, { order_by => [qw/ me.dns me.ip /], - (($p->{dns} or $p->{ip}) ? ( - join => 'device_ips', + (($p->{dns} or $p->{ip} or $p->{neighbor_id} or $p->{neighbor_type}) ? ( + join => [qw/device_ips neighbor_ports/], distinct => 1, ) : ()), } diff --git a/Netdisco/lib/App/Netdisco/Web/Plugin/Search/Device.pm b/Netdisco/lib/App/Netdisco/Web/Plugin/Search/Device.pm index ec78f7ea..8aaae657 100644 --- a/Netdisco/lib/App/Netdisco/Web/Plugin/Search/Device.pm +++ b/Netdisco/lib/App/Netdisco/Web/Plugin/Search/Device.pm @@ -14,7 +14,8 @@ register_search_tab( # device with various properties or a default match-all get '/ajax/content/search/device' => require_login sub { my $has_opt = List::MoreUtils::any { param($_) } - qw/name location dns ip description model os_ver vendor layers/; + qw/name location dns ip description model os_ver vendor layers + neighbor_id neighbor_type/; my $rs; if ($has_opt) { diff --git a/Netdisco/share/views/sidebar/search/device.tt b/Netdisco/share/views/sidebar/search/device.tt index 97722f72..a65b7f48 100644 --- a/Netdisco/share/views/sidebar/search/device.tt +++ b/Netdisco/share/views/sidebar/search/device.tt @@ -41,6 +41,22 @@ type="text" name="description" value="[% params.description | html_entity %]" rel="tooltip" data-placement="left" data-offset="5" data-title="Description"/> +
+ + + +
+
+ + + +
-
-
- - - -
+
+ +
+
+ +
+
+ +
+
+ + +
+
+ + +
+

+
+ + +
+ From fb7bcbf120627740bd2db39a29c24ec6f9752c5c Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 25 Aug 2014 17:13:11 +0100 Subject: [PATCH 07/18] fix undef data error in JS, and when no remote_(ip|port) --- .../lib/App/Netdisco/DB/Result/Virtual/NodesDiscovered.pm | 3 +-- Netdisco/share/views/ajax/report/nodesdiscovered.tt | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodesDiscovered.pm b/Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodesDiscovered.pm index 1000c27d..1b8a39b4 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodesDiscovered.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodesDiscovered.pm @@ -33,8 +33,7 @@ WHERE d.ip = p.ip WHERE a.alias = p.remote_ip AND q.ip = a.ip AND q.port = p.remote_port) - AND p.remote_ip IS NOT NULL - AND p.remote_port IS NOT NULL + AND (p.remote_id IS NOT NULL OR p.remote_type IS NOT NULL) ENDSQL ); diff --git a/Netdisco/share/views/ajax/report/nodesdiscovered.tt b/Netdisco/share/views/ajax/report/nodesdiscovered.tt index 3826f539..f5a28098 100644 --- a/Netdisco/share/views/ajax/report/nodesdiscovered.tt +++ b/Netdisco/share/views/ajax/report/nodesdiscovered.tt @@ -33,7 +33,7 @@ $(document).ready(function() { "type": 'portsort', "render": function(data, type, row, meta) { return type === 'display' ? - '' + he.encode(data) + '' : + '' + he.encode(data) + '' : data; } }, { @@ -44,7 +44,7 @@ $(document).ready(function() { }, { "data": 'remote_ip', "render": function(data, type, row, meta) { - return '' + he.encode(data) + ''; + return '' + he.encode(data || '') + ''; } }, { "data": 'remote_port', From 05493abbb7e825d72846b0b7d3ebe2ec9a0e11f8 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 25 Aug 2014 17:23:14 +0100 Subject: [PATCH 08/18] release 2.029006 --- Netdisco/Changes | 2 +- Netdisco/MANIFEST | 9 +++++---- Netdisco/META.yml | 2 +- Netdisco/lib/App/Netdisco.pm | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index bc91414a..d7d051d8 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,4 +1,4 @@ -2.029006 - +2.029006 - 2014-08-25 [NEW FEATURES] diff --git a/Netdisco/MANIFEST b/Netdisco/MANIFEST index 55ae30c4..df04d959 100644 --- a/Netdisco/MANIFEST +++ b/Netdisco/MANIFEST @@ -80,9 +80,9 @@ lib/App/Netdisco/DB/Result/Virtual/DevicePoeStatus.pm lib/App/Netdisco/DB/Result/Virtual/DuplexMismatch.pm lib/App/Netdisco/DB/Result/Virtual/GenericReport.pm lib/App/Netdisco/DB/Result/Virtual/NodeMonitor.pm +lib/App/Netdisco/DB/Result/Virtual/NodesDiscovered.pm lib/App/Netdisco/DB/Result/Virtual/NodeWithAge.pm lib/App/Netdisco/DB/Result/Virtual/OrphanedDevices.pm -lib/App/Netdisco/DB/Result/Virtual/PhonesDiscovered.pm lib/App/Netdisco/DB/Result/Virtual/PollerPerformance.pm lib/App/Netdisco/DB/Result/Virtual/PortUtilization.pm lib/App/Netdisco/DB/Result/Virtual/SlowDevices.pm @@ -202,8 +202,8 @@ lib/App/Netdisco/Web/Plugin/Report/IpInventory.pm lib/App/Netdisco/Web/Plugin/Report/ModuleInventory.pm lib/App/Netdisco/Web/Plugin/Report/Netbios.pm lib/App/Netdisco/Web/Plugin/Report/NodeMultiIPs.pm +lib/App/Netdisco/Web/Plugin/Report/NodesDiscovered.pm lib/App/Netdisco/Web/Plugin/Report/NodeVendor.pm -lib/App/Netdisco/Web/Plugin/Report/PhonesDiscovered.pm lib/App/Netdisco/Web/Plugin/Report/PortAdminDown.pm lib/App/Netdisco/Web/Plugin/Report/PortBlocking.pm lib/App/Netdisco/Web/Plugin/Report/PortLog.pm @@ -345,10 +345,10 @@ share/views/ajax/report/netbios.tt share/views/ajax/report/netbios_csv.tt share/views/ajax/report/nodemultiips.tt share/views/ajax/report/nodemultiips_csv.tt +share/views/ajax/report/nodesdiscovered.tt +share/views/ajax/report/nodesdiscovered_csv.tt share/views/ajax/report/nodevendor.tt share/views/ajax/report/nodevendor_csv.tt -share/views/ajax/report/phonesdiscovered.tt -share/views/ajax/report/phonesdiscovered_csv.tt share/views/ajax/report/portadmindown.tt share/views/ajax/report/portadmindown_csv.tt share/views/ajax/report/portblocking.tt @@ -392,6 +392,7 @@ share/views/sidebar/device/ports.tt share/views/sidebar/report/ipinventory.tt share/views/sidebar/report/moduleinventory.tt share/views/sidebar/report/netbios.tt +share/views/sidebar/report/nodesdiscovered.tt share/views/sidebar/report/nodevendor.tt share/views/sidebar/report/portlog.tt share/views/sidebar/report/portssid.tt diff --git a/Netdisco/META.yml b/Netdisco/META.yml index 1d97f731..c6e3d6ec 100644 --- a/Netdisco/META.yml +++ b/Netdisco/META.yml @@ -89,4 +89,4 @@ resources: homepage: http://netdisco.org/ license: http://opensource.org/licenses/bsd-license.php repository: git://git.code.sf.net/p/netdisco/netdisco-ng -version: 2.029005 +version: 2.029006 diff --git a/Netdisco/lib/App/Netdisco.pm b/Netdisco/lib/App/Netdisco.pm index c0acaf1c..3eb33805 100644 --- a/Netdisco/lib/App/Netdisco.pm +++ b/Netdisco/lib/App/Netdisco.pm @@ -4,7 +4,7 @@ use strict; use warnings; use 5.010_000; -our $VERSION = '2.029005'; +our $VERSION = '2.029006'; use App::Netdisco::Configuration; use Module::Find (); From 2bc92999b879cc9a7c6fee3e397d7f6e29de18e4 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 25 Aug 2014 18:48:11 +0100 Subject: [PATCH 09/18] [#123] Allow devices with no LLDP/CDP to be found as Nodes --- Netdisco/Changes | 1 + Netdisco/lib/App/Netdisco/Core/Macsuck.pm | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index d7d051d8..16da4037 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -8,6 +8,7 @@ [ENHANCEMENTS] * Port search also searches on the Remote ID and Type + * [#123] Allow devices with no LLDP/CDP to be found as Nodes 2.029005 - 2014-08-13 diff --git a/Netdisco/lib/App/Netdisco/Core/Macsuck.pm b/Netdisco/lib/App/Netdisco/Core/Macsuck.pm index 8f0bdce5..042f28e9 100644 --- a/Netdisco/lib/App/Netdisco/Core/Macsuck.pm +++ b/Netdisco/lib/App/Netdisco/Core/Macsuck.pm @@ -346,6 +346,8 @@ sub _walk_fwtable { next; } + my $vlan = $fw_vlan->{$idx} || $comm_vlan || '0'; + # check to see if the port is connected to another device # and if we have that device in the database. @@ -371,12 +373,13 @@ sub _walk_fwtable { debug sprintf ' [%s] macsuck %s - port %s is detected uplink - skipping.', $device->ip, $mac, $port; + + $skiplist->{$port} = [ $vlan, $mac ] # remember for later + if exists $port_macs->{$mac}; next; } } - my $vlan = $fw_vlan->{$idx} || $comm_vlan || '0'; - if (exists $port_macs->{$mac}) { my $switch_ip = $port_macs->{$mac}; if ($device->ip eq $switch_ip) { @@ -395,7 +398,8 @@ sub _walk_fwtable { if (not setting('macsuck_bleed')) { debug sprintf ' [%s] macsuck %s - adding port %s to skiplist', $device->ip, $mac, $port; - $skiplist->{$port} = delete $cache->{$vlan}->{$port}; + + $skiplist->{$port} = [ $vlan, $mac ]; # remember for later next; } } @@ -410,6 +414,15 @@ sub _walk_fwtable { ++$cache->{$vlan}->{$port}->{$mac}; } + # restore MACs of neighbor devices. + # this is when we have a "possible uplink" detected but we still want to + # record the single MAC of the neighbor device so it works in Node search. + foreach my $port (keys %$skiplist) { + my ($vlan, $mac) = @{ $skiplist->{$port} }; + delete $cache->{$_}->{$port} for keys %$cache; # nuke nodes on all VLANs + ++$cache->{$vlan}->{$port}->{$mac}; + } + return $cache; } From b89988cd697da95b767a21b9ac89fa4a9f487d8a Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Wed, 3 Sep 2014 10:39:05 +0000 Subject: [PATCH 10/18] Skip device aliases which cannot be parsed as IPs --- Netdisco/Changes | 11 ++++++++++- Netdisco/lib/App/Netdisco/Core/Discover.pm | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 16da4037..a553040a 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,3 +1,13 @@ +2.029007 + + [ENHANCEMENTS] + + * [#123] Allow devices with no LLDP/CDP to be found as Nodes + + [BUG FIXES] + + * Skip device aliases which cannot be parsed as IPs + 2.029006 - 2014-08-25 [NEW FEATURES] @@ -8,7 +18,6 @@ [ENHANCEMENTS] * Port search also searches on the Remote ID and Type - * [#123] Allow devices with no LLDP/CDP to be found as Nodes 2.029005 - 2014-08-13 diff --git a/Netdisco/lib/App/Netdisco/Core/Discover.pm b/Netdisco/lib/App/Netdisco/Core/Discover.pm index f4def41d..29acbac6 100644 --- a/Netdisco/lib/App/Netdisco/Core/Discover.pm +++ b/Netdisco/lib/App/Netdisco/Core/Discover.pm @@ -120,7 +120,8 @@ sub store_device { # build device aliases suitable for DBIC my @aliases; foreach my $entry (keys %$ip_index) { - my $ip = NetAddr::IP::Lite->new($entry); + my $ip = NetAddr::IP::Lite->new($entry) + or next; my $addr = $ip->addr; next if $addr eq '0.0.0.0'; From d32024a782bbb9782fb2ddcb43ec665d7447fd12 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Wed, 3 Sep 2014 11:11:15 +0000 Subject: [PATCH 11/18] Accept host names to netdisco-do show --- Netdisco/Changes | 1 + Netdisco/bin/netdisco-do | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index a553040a..5102f44f 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -3,6 +3,7 @@ [ENHANCEMENTS] * [#123] Allow devices with no LLDP/CDP to be found as Nodes + * Accept host names to netdisco-do show [BUG FIXES] diff --git a/Netdisco/bin/netdisco-do b/Netdisco/bin/netdisco-do index 4b2e0d53..724892b6 100755 --- a/Netdisco/bin/netdisco-do +++ b/Netdisco/bin/netdisco-do @@ -113,7 +113,17 @@ unless ($action) { } use App::Netdisco::Util::SNMP (); + use App::Netdisco::Util::Device 'get_device'; + use NetAddr::IP::Lite ':lower'; + use Scalar::Util 'blessed'; sub show { + my $ip = NetAddr::IP::Lite->new($device) + or return ('error', "Bad host or IP: $device"); + my $dev = get_device($ip->addr); + unless (blessed $dev and $dev->in_storage) { + return ('error', "Don't know device: $device"); + } + $extra ||= 'interfaces'; my $class = undef; ($class, $extra) = split(/::([^:]+)$/, $extra); if ($class and $extra) { @@ -123,7 +133,7 @@ unless ($action) { $extra = $class; undef $class; } - my $i = App::Netdisco::Util::SNMP::snmp_connect($device, $class); + my $i = App::Netdisco::Util::SNMP::snmp_connect($dev, $class); Data::Printer::p($i->$extra); return ('done', "Showed $extra response from $device."); } From 1e90fea47a2a6bb522458c9dcf4ed2839025ceb7 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Wed, 3 Sep 2014 12:57:15 +0000 Subject: [PATCH 12/18] do not attempt DNS resolution on bad IPs --- Netdisco/Changes | 1 + Netdisco/lib/App/Netdisco/Util/DNS.pm | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 5102f44f..708aa33b 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -8,6 +8,7 @@ [BUG FIXES] * Skip device aliases which cannot be parsed as IPs + * [#137] do not attempt DNS resolution on bad IPs 2.029006 - 2014-08-25 diff --git a/Netdisco/lib/App/Netdisco/Util/DNS.pm b/Netdisco/lib/App/Netdisco/Util/DNS.pm index d55b2e42..914024eb 100644 --- a/Netdisco/lib/App/Netdisco/Util/DNS.pm +++ b/Netdisco/lib/App/Netdisco/Util/DNS.pm @@ -166,7 +166,8 @@ sub no_resolve { my $config = setting('dns')->{no} || []; return 0 if not scalar @$config; - my $addr = NetAddr::IP::Lite->new($ip); + my $addr = NetAddr::IP::Lite->new($ip) + or return 1; foreach my $item (@$config) { my $c_ip = NetAddr::IP::Lite->new($item) From 9f4be969643d3f9f34b46894b633792ec2fb5c1e Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Wed, 3 Sep 2014 13:22:47 +0000 Subject: [PATCH 13/18] Add PaloAlto and IOS-XR support to netdisco-sshcollector --- Netdisco/Changes | 1 + Netdisco/Makefile.PL | 1 + Netdisco/bin/netdisco-sshcollector | 6 ++ .../Netdisco/SSHCollector/Platform/IOSXR.pm | 68 +++++++++++++++++++ .../SSHCollector/Platform/PaloAlto.pm | 66 ++++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOSXR.pm create mode 100644 Netdisco/lib/App/Netdisco/SSHCollector/Platform/PaloAlto.pm diff --git a/Netdisco/Changes b/Netdisco/Changes index 708aa33b..2c3d3945 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -4,6 +4,7 @@ * [#123] Allow devices with no LLDP/CDP to be found as Nodes * Accept host names to netdisco-do show + * [#139] Add PaloAlto and IOS-XR support to netdisco-sshcollector [BUG FIXES] diff --git a/Netdisco/Makefile.PL b/Netdisco/Makefile.PL index 1e53763b..5f1aa25b 100644 --- a/Netdisco/Makefile.PL +++ b/Netdisco/Makefile.PL @@ -71,6 +71,7 @@ if ( $^O eq 'linux' ) { recommends 'Graph' => 0; recommends 'GraphViz' => 0; recommends 'Net::OpenSSH' => 0; +recommends 'Expect' => 0; install_share 'share'; diff --git a/Netdisco/bin/netdisco-sshcollector b/Netdisco/bin/netdisco-sshcollector index 38747b1b..033fea04 100644 --- a/Netdisco/bin/netdisco-sshcollector +++ b/Netdisco/bin/netdisco-sshcollector @@ -20,6 +20,10 @@ Currently, ARP tables can be retrieved from the following device classes: =item * L - Cisco IOS +=item * L - Cisco IOS XR + +=item * L - PaloAlto devices + =back The collected arp entries are then directly stored in the netdisco database. @@ -91,6 +95,8 @@ B and B datatypes in PostgreSQL can handle. =item L +=item L + =back =head1 COPYRIGHT AND LICENSE diff --git a/Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOSXR.pm b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOSXR.pm new file mode 100644 index 00000000..04404342 --- /dev/null +++ b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOSXR.pm @@ -0,0 +1,68 @@ +package App::Netdisco::SSHCollector::Platform::IOSXR; + +# vim: set expandtab tabstop=8 softtabstop=4 shiftwidth=4: + +=head1 NAME + +App::Netdisco::SSHCollector::Platform::IOSXR + +=head1 DESCRIPTION + +Collect ARP entries from Cisco IOS XR devices. + +=cut + +use strict; +use warnings; + +use Dancer ':script'; +use Data::Printer; +use Moo; +use Expect; + +=head1 PUBLIC METHODS + +=over 4 + +=item B + +Retrieve ARP entries from device. C<$host> is the hostname or IP address +of the device. C<$ssh> is a Net::OpenSSH connection to the device. + +Returns an array of hashrefs in the format { mac => MACADDR, ip => IPADDR }. + +=cut + +sub arpnip { + my ($self, $hostlabel, $ssh, @args) = @_; + + debug "$hostlabel $$ arpnip()"; + + my ($pty, $pid) = $ssh->open2pty or die "unable to run remote command"; + my $expect = Expect->init($pty); + + my ($pos, $error, $match, $before, $after); + my $prompt = qr/#/; + + ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + + $expect->send("terminal length 0\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(5, -re, $prompt); + + my @arpentries; + + $expect->send("show arp vrf all\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(5, -re, $prompt); + + # 0.0.0.0 00:00:00 0000.0000.0000 Dynamic ARPA GigabitEthernet0/0/0/0 + for (split(/\n/, $before)){ + my ($ip, $age, $mac, $state, $t, $iface) = split(/\s+/); + if ($ip =~ m/(\d{1,3}\.){3}\d{1,3}/ && $mac =~ m/[0-9a-f.]+/i) { + push(@arpentries, { ip => $ip, mac => $mac }); + } + } + + return @arpentries; +} + +1; diff --git a/Netdisco/lib/App/Netdisco/SSHCollector/Platform/PaloAlto.pm b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/PaloAlto.pm new file mode 100644 index 00000000..67ba10dc --- /dev/null +++ b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/PaloAlto.pm @@ -0,0 +1,66 @@ +package App::Netdisco::SSHCollector::Platform::PaloAlto; + +# vim: set expandtab tabstop=8 softtabstop=4 shiftwidth=4: + +=head1 NAME + +App::Netdisco::SSHCollector::Platform::PaloAlto + +=head1 DESCRIPTION + +Collect ARP entries from PaloAlto devices. + +=cut + +use strict; +use warnings; + +use Dancer ':script'; +use Data::Printer; +use Moo; +use Expect; + +=head1 PUBLIC METHODS + +=over 4 + +=item B + +Retrieve ARP entries from device. C<$host> is the hostname or IP address +of the device. C<$ssh> is a Net::OpenSSH connection to the device. + +Returns an array of hashrefs in the format { mac => MACADDR, ip => IPADDR }. + +=cut + +sub arpnip{ + my ($self, $hostlabel, $ssh, @args) = @_; + + debug "$hostlabel $$ arpnip()"; + + my ($pty, $pid) = $ssh->open2pty or die "unable to run remote command"; + my $expect = Expect->init($pty); + my ($pos, $error, $match, $before, $after); + my $prompt = qr/> \r?$/; + + ($pos, $error, $match, $before, $after) = $expect->expect(20, -re, $prompt); + $expect->send("set cli pager off\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + $expect->send("show arp all\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + + my @arpentries; + for (split(/\r\n/, $before)){ + next unless $_ =~ m/(\d{1,3}\.){3}\d{1,3}/; + my ($tmp, $ip, $mac) = split(/\s+/); + if ($ip =~ m/(\d{1,3}\.){3}\d{1,3}/ && $mac =~ m/([0-9a-f]{2}:){5}[0-9a-f]{2}/i) { + push(@arpentries, { ip => $ip, mac => $mac }); + } + } + $expect->send("exit\n"); + $expect->soft_close(); + + return @arpentries; +} + +1; From 0c896ab02296dd50cd2e2d8050e66d516c0e763c Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Fri, 12 Sep 2014 14:09:37 +0100 Subject: [PATCH 14/18] release 2.029007 --- Netdisco/Changes | 2 +- Netdisco/MANIFEST | 2 ++ Netdisco/META.yml | 4 +++- Netdisco/lib/App/Netdisco.pm | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 2c3d3945..8170f6c0 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,4 +1,4 @@ -2.029007 +2.029007 - 2014-09-12 [ENHANCEMENTS] diff --git a/Netdisco/MANIFEST b/Netdisco/MANIFEST index df04d959..e1080c3c 100644 --- a/Netdisco/MANIFEST +++ b/Netdisco/MANIFEST @@ -152,6 +152,8 @@ lib/App/Netdisco/Manual/WritingPlugins.pod lib/App/Netdisco/SSHCollector/Platform/ACE.pm lib/App/Netdisco/SSHCollector/Platform/BigIP.pm lib/App/Netdisco/SSHCollector/Platform/IOS.pm +lib/App/Netdisco/SSHCollector/Platform/IOSXR.pm +lib/App/Netdisco/SSHCollector/Platform/PaloAlto.pm lib/App/Netdisco/Util/Daemon.pm lib/App/Netdisco/Util/Device.pm lib/App/Netdisco/Util/DNS.pm diff --git a/Netdisco/META.yml b/Netdisco/META.yml index c6e3d6ec..f593b944 100644 --- a/Netdisco/META.yml +++ b/Netdisco/META.yml @@ -22,6 +22,7 @@ no_index: - share - t recommends: + Expect: 0 Graph: 0 GraphViz: 0 Net::OpenSSH: 0 @@ -70,6 +71,7 @@ requires: Sereal: 0 Socket6: 0.23 Starman: 0.4008 + Sys::Proctitle: 0 Template: 2.24 Template::Plugin::CSV: 0.04 Template::Plugin::Number::Format: 1.02 @@ -89,4 +91,4 @@ resources: homepage: http://netdisco.org/ license: http://opensource.org/licenses/bsd-license.php repository: git://git.code.sf.net/p/netdisco/netdisco-ng -version: 2.029006 +version: 2.029007 diff --git a/Netdisco/lib/App/Netdisco.pm b/Netdisco/lib/App/Netdisco.pm index 3eb33805..18b750fa 100644 --- a/Netdisco/lib/App/Netdisco.pm +++ b/Netdisco/lib/App/Netdisco.pm @@ -4,7 +4,7 @@ use strict; use warnings; use 5.010_000; -our $VERSION = '2.029006'; +our $VERSION = '2.029007'; use App::Netdisco::Configuration; use Module::Find (); From 374a668d38e6ff3164df78ad8b232381639649f4 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 15 Sep 2014 21:29:45 +0100 Subject: [PATCH 15/18] fix header level in docs --- Netdisco/lib/App/Netdisco/Manual/Deployment.pod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Netdisco/lib/App/Netdisco/Manual/Deployment.pod b/Netdisco/lib/App/Netdisco/Manual/Deployment.pod index e6906029..2917750a 100644 --- a/Netdisco/lib/App/Netdisco/Manual/Deployment.pod +++ b/Netdisco/lib/App/Netdisco/Manual/Deployment.pod @@ -164,7 +164,7 @@ Then run the web daemon with the environment variable to enable the feature: DANCER_DEBUG=1 ~/bin/netdisco-web restart -=head2 Database Backups +=head1 Database Backups We recommend you backup the Netdisco database regularly. You could put the following commands into a shell script and call it nightly from C: From b63cd0b6431e60ca0f020cb498455b050f8f0471 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 15 Sep 2014 22:01:41 +0100 Subject: [PATCH 16/18] extract common DT options to template --- Netdisco/share/public/css/netdisco.css | 7 +++++++ Netdisco/share/views/ajax/admintask/nodemonitor.tt | 8 ++------ Netdisco/share/views/ajax/admintask/pseudodevice.tt | 9 ++------- Netdisco/share/views/ajax/admintask/slowdevices.tt | 4 ++-- Netdisco/share/views/ajax/admintask/topology.tt | 9 ++------- .../views/ajax/admintask/undiscoveredneighbors.tt | 7 +------ Netdisco/share/views/ajax/admintask/userlog.tt | 9 ++------- Netdisco/share/views/ajax/admintask/users.tt | 9 ++------- Netdisco/share/views/ajax/datatabledefaults.tt | 11 +++++++++++ Netdisco/share/views/ajax/device/addresses.tt | 9 ++------- Netdisco/share/views/ajax/device/ports.tt | 7 +------ Netdisco/share/views/ajax/report/apchanneldist.tt | 9 ++------- .../share/views/ajax/report/apradiochannelpower.tt | 9 ++------- Netdisco/share/views/ajax/report/deviceaddrnodns.tt | 9 ++------- Netdisco/share/views/ajax/report/devicebylocation.tt | 9 ++------- Netdisco/share/views/ajax/report/devicednsmismatch.tt | 9 ++------- Netdisco/share/views/ajax/report/devicepoestatus.tt | 9 ++------- Netdisco/share/views/ajax/report/duplexmismatch.tt | 9 ++------- Netdisco/share/views/ajax/report/generic_report.tt | 7 +------ Netdisco/share/views/ajax/report/halfduplex.tt | 9 ++------- Netdisco/share/views/ajax/report/ipinventory.tt | 9 ++------- Netdisco/share/views/ajax/report/moduleinventory.tt | 11 +++-------- Netdisco/share/views/ajax/report/netbios.tt | 11 +++-------- Netdisco/share/views/ajax/report/nodemultiips.tt | 9 ++------- Netdisco/share/views/ajax/report/nodesdiscovered.tt | 9 ++------- Netdisco/share/views/ajax/report/nodevendor.tt | 11 +++-------- Netdisco/share/views/ajax/report/portadmindown.tt | 9 ++------- Netdisco/share/views/ajax/report/portblocking.tt | 9 ++------- Netdisco/share/views/ajax/report/portlog.tt | 7 +------ Netdisco/share/views/ajax/report/portmultinodes.tt | 9 ++------- Netdisco/share/views/ajax/report/portssid.tt | 9 ++------- Netdisco/share/views/ajax/report/portutilization.tt | 9 ++------- Netdisco/share/views/ajax/report/subnets.tt | 7 +------ Netdisco/share/views/ajax/report/vlaninventory.tt | 9 ++------- Netdisco/share/views/ajax/search/device.tt | 9 ++------- Netdisco/share/views/ajax/search/node_by_ip.tt | 9 ++------- Netdisco/share/views/ajax/search/node_by_mac.tt | 9 ++------- Netdisco/share/views/ajax/search/port.tt | 9 ++------- Netdisco/share/views/ajax/search/vlan.tt | 9 ++------- 39 files changed, 90 insertions(+), 251 deletions(-) create mode 100644 Netdisco/share/views/ajax/datatabledefaults.tt diff --git a/Netdisco/share/public/css/netdisco.css b/Netdisco/share/public/css/netdisco.css index 8c6edcc1..d6010d59 100644 --- a/Netdisco/share/public/css/netdisco.css +++ b/Netdisco/share/public/css/netdisco.css @@ -653,3 +653,10 @@ form .clearfix.success input { } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* dataTables */ + +div.nd_datatables-pager { + float: left; + margin-left: 50px; +} + diff --git a/Netdisco/share/views/ajax/admintask/nodemonitor.tt b/Netdisco/share/views/ajax/admintask/nodemonitor.tt index c80419f5..dcd47e3e 100644 --- a/Netdisco/share/views/ajax/admintask/nodemonitor.tt +++ b/Netdisco/share/views/ajax/admintask/nodemonitor.tt @@ -71,11 +71,6 @@ diff --git a/Netdisco/share/views/ajax/admintask/pseudodevice.tt b/Netdisco/share/views/ajax/admintask/pseudodevice.tt index 2184f163..51e6ee56 100644 --- a/Netdisco/share/views/ajax/admintask/pseudodevice.tt +++ b/Netdisco/share/views/ajax/admintask/pseudodevice.tt @@ -63,17 +63,12 @@ diff --git a/Netdisco/share/views/ajax/admintask/slowdevices.tt b/Netdisco/share/views/ajax/admintask/slowdevices.tt index 256cb412..f2c5ebe8 100644 --- a/Netdisco/share/views/ajax/admintask/slowdevices.tt +++ b/Netdisco/share/views/ajax/admintask/slowdevices.tt @@ -33,7 +33,7 @@ $(document).ready(function() { "searching": false, "info": false, "order": [[ 4, 'desc' ], [ 0, 'asc' ], [ 1, 'asc' ] ], - "pageLength": [% settings.table_pagesize %], - } ); + "pageLength": 12 + }); } ); diff --git a/Netdisco/share/views/ajax/admintask/topology.tt b/Netdisco/share/views/ajax/admintask/topology.tt index 50f57731..0dcec0aa 100644 --- a/Netdisco/share/views/ajax/admintask/topology.tt +++ b/Netdisco/share/views/ajax/admintask/topology.tt @@ -89,17 +89,12 @@ diff --git a/Netdisco/share/views/ajax/admintask/undiscoveredneighbors.tt b/Netdisco/share/views/ajax/admintask/undiscoveredneighbors.tt index f1071460..204b04f8 100644 --- a/Netdisco/share/views/ajax/admintask/undiscoveredneighbors.tt +++ b/Netdisco/share/views/ajax/admintask/undiscoveredneighbors.tt @@ -27,13 +27,8 @@ diff --git a/Netdisco/share/views/ajax/admintask/userlog.tt b/Netdisco/share/views/ajax/admintask/userlog.tt index d4f04c65..65bc50e4 100644 --- a/Netdisco/share/views/ajax/admintask/userlog.tt +++ b/Netdisco/share/views/ajax/admintask/userlog.tt @@ -17,12 +17,6 @@ diff --git a/Netdisco/share/views/ajax/admintask/users.tt b/Netdisco/share/views/ajax/admintask/users.tt index 89db1e5c..a17bd45a 100644 --- a/Netdisco/share/views/ajax/admintask/users.tt +++ b/Netdisco/share/views/ajax/admintask/users.tt @@ -78,12 +78,6 @@ diff --git a/Netdisco/share/views/ajax/datatabledefaults.tt b/Netdisco/share/views/ajax/datatabledefaults.tt new file mode 100644 index 00000000..1c463211 --- /dev/null +++ b/Netdisco/share/views/ajax/datatabledefaults.tt @@ -0,0 +1,11 @@ + + "processing": true, + "stateSave": true, + "pageLength": [% settings.table_pagesize %], + "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ], + "dom": '<"top"l<"nd_datatables-pager"p>f>rt<"bottom"><"clear">', + "language": { + "search": '_INPUT_', + "searchPlaceholder": 'Filter records...', + "lengthMenu": "Show _MENU_ records." + } diff --git a/Netdisco/share/views/ajax/device/addresses.tt b/Netdisco/share/views/ajax/device/addresses.tt index d392ae17..448bc385 100644 --- a/Netdisco/share/views/ajax/device/addresses.tt +++ b/Netdisco/share/views/ajax/device/addresses.tt @@ -13,12 +13,6 @@ diff --git a/Netdisco/share/views/ajax/device/ports.tt b/Netdisco/share/views/ajax/device/ports.tt index f696052f..4e23349c 100644 --- a/Netdisco/share/views/ajax/device/ports.tt +++ b/Netdisco/share/views/ajax/device/ports.tt @@ -399,12 +399,7 @@ $(document).ready(function() { { "type": 'portsort', "targets": [ 'portsort' ] } ], "order": [[ 1, 'asc' ]], - "processing": true, - "stateSave": true, - "pageLength": [% settings.table_pagesize %], - "language": { - "search": 'Filter records: ' - }, +[% INCLUDE 'ajax/datatabledefaults.tt' -%] } ); } ); diff --git a/Netdisco/share/views/ajax/report/apchanneldist.tt b/Netdisco/share/views/ajax/report/apchanneldist.tt index 4abc7f3c..22f16d74 100644 --- a/Netdisco/share/views/ajax/report/apchanneldist.tt +++ b/Netdisco/share/views/ajax/report/apchanneldist.tt @@ -10,12 +10,6 @@ diff --git a/Netdisco/share/views/ajax/report/apradiochannelpower.tt b/Netdisco/share/views/ajax/report/apradiochannelpower.tt index aab21a89..3a283562 100644 --- a/Netdisco/share/views/ajax/report/apradiochannelpower.tt +++ b/Netdisco/share/views/ajax/report/apradiochannelpower.tt @@ -38,12 +38,6 @@ function groupString(d) { $(document).ready(function() { var table = $('#data-table').DataTable({ - "processing": true, - "stateSave": true, - "pageLength": [% settings.table_pagesize %], - "language": { - "search": 'Filter records: ' - }, "serverSide": true, "ajax": "[% uri_for('/ajax/content/report/apradiochannelpower/data') %]", "order": [[ 0, 'asc' ]], @@ -103,7 +97,8 @@ $(document).ready(function() { last = group; } } ); - } + }, +[% INCLUDE 'ajax/datatabledefaults.tt' -%] } ); // Order by the grouping diff --git a/Netdisco/share/views/ajax/report/deviceaddrnodns.tt b/Netdisco/share/views/ajax/report/deviceaddrnodns.tt index 94b17416..08b7c4da 100644 --- a/Netdisco/share/views/ajax/report/deviceaddrnodns.tt +++ b/Netdisco/share/views/ajax/report/deviceaddrnodns.tt @@ -12,12 +12,6 @@ diff --git a/Netdisco/share/views/ajax/report/devicebylocation.tt b/Netdisco/share/views/ajax/report/devicebylocation.tt index 07a3c6a6..6c563d5f 100644 --- a/Netdisco/share/views/ajax/report/devicebylocation.tt +++ b/Netdisco/share/views/ajax/report/devicebylocation.tt @@ -13,12 +13,6 @@ diff --git a/Netdisco/share/views/ajax/report/devicepoestatus.tt b/Netdisco/share/views/ajax/report/devicepoestatus.tt index bdcaecdf..76e0ec33 100644 --- a/Netdisco/share/views/ajax/report/devicepoestatus.tt +++ b/Netdisco/share/views/ajax/report/devicepoestatus.tt @@ -64,12 +64,6 @@ function groupString(d) { $(document).ready(function() { var table = $('#data-table').DataTable({ - "processing": true, - "stateSave": true, - "pageLength": [% settings.table_pagesize %], - "language": { - "search": 'Filter records: ' - }, "serverSide": true, "ajax": "[% uri_for('/ajax/content/report/devicepoestatus/data') %]", "order": [[ 0, 'asc' ]], @@ -168,7 +162,8 @@ $(document).ready(function() { last = group; } } ); - } + }, +[% INCLUDE 'ajax/datatabledefaults.tt' -%] } ); // Order by the grouping diff --git a/Netdisco/share/views/ajax/report/duplexmismatch.tt b/Netdisco/share/views/ajax/report/duplexmismatch.tt index 2cda1424..17548fc3 100644 --- a/Netdisco/share/views/ajax/report/duplexmismatch.tt +++ b/Netdisco/share/views/ajax/report/duplexmismatch.tt @@ -14,12 +14,6 @@ diff --git a/Netdisco/share/views/ajax/report/generic_report.tt b/Netdisco/share/views/ajax/report/generic_report.tt index 7d3aac74..d2a27386 100644 --- a/Netdisco/share/views/ajax/report/generic_report.tt +++ b/Netdisco/share/views/ajax/report/generic_report.tt @@ -20,12 +20,7 @@ diff --git a/Netdisco/share/views/ajax/report/halfduplex.tt b/Netdisco/share/views/ajax/report/halfduplex.tt index c0601263..4427ce99 100644 --- a/Netdisco/share/views/ajax/report/halfduplex.tt +++ b/Netdisco/share/views/ajax/report/halfduplex.tt @@ -12,12 +12,6 @@ diff --git a/Netdisco/share/views/ajax/report/ipinventory.tt b/Netdisco/share/views/ajax/report/ipinventory.tt index 5eeadd61..53f859f7 100644 --- a/Netdisco/share/views/ajax/report/ipinventory.tt +++ b/Netdisco/share/views/ajax/report/ipinventory.tt @@ -12,12 +12,6 @@ diff --git a/Netdisco/share/views/ajax/report/moduleinventory.tt b/Netdisco/share/views/ajax/report/moduleinventory.tt index be393121..19c0ab6c 100644 --- a/Netdisco/share/views/ajax/report/moduleinventory.tt +++ b/Netdisco/share/views/ajax/report/moduleinventory.tt @@ -30,12 +30,6 @@ diff --git a/Netdisco/share/views/ajax/report/netbios.tt b/Netdisco/share/views/ajax/report/netbios.tt index 964d949b..6134b412 100644 --- a/Netdisco/share/views/ajax/report/netbios.tt +++ b/Netdisco/share/views/ajax/report/netbios.tt @@ -26,12 +26,6 @@ diff --git a/Netdisco/share/views/ajax/report/nodemultiips.tt b/Netdisco/share/views/ajax/report/nodemultiips.tt index b3a8279d..1d70e853 100644 --- a/Netdisco/share/views/ajax/report/nodemultiips.tt +++ b/Netdisco/share/views/ajax/report/nodemultiips.tt @@ -13,12 +13,6 @@ diff --git a/Netdisco/share/views/ajax/report/nodesdiscovered.tt b/Netdisco/share/views/ajax/report/nodesdiscovered.tt index f5a28098..98db813e 100644 --- a/Netdisco/share/views/ajax/report/nodesdiscovered.tt +++ b/Netdisco/share/views/ajax/report/nodesdiscovered.tt @@ -14,12 +14,6 @@ diff --git a/Netdisco/share/views/ajax/report/nodevendor.tt b/Netdisco/share/views/ajax/report/nodevendor.tt index dade6972..0f6f70b0 100644 --- a/Netdisco/share/views/ajax/report/nodevendor.tt +++ b/Netdisco/share/views/ajax/report/nodevendor.tt @@ -26,12 +26,6 @@ diff --git a/Netdisco/share/views/ajax/report/portadmindown.tt b/Netdisco/share/views/ajax/report/portadmindown.tt index 1eb25fa3..9a8c516c 100644 --- a/Netdisco/share/views/ajax/report/portadmindown.tt +++ b/Netdisco/share/views/ajax/report/portadmindown.tt @@ -12,12 +12,6 @@ diff --git a/Netdisco/share/views/ajax/report/portblocking.tt b/Netdisco/share/views/ajax/report/portblocking.tt index 241545dd..5ff08dc9 100644 --- a/Netdisco/share/views/ajax/report/portblocking.tt +++ b/Netdisco/share/views/ajax/report/portblocking.tt @@ -12,12 +12,6 @@ diff --git a/Netdisco/share/views/ajax/report/portlog.tt b/Netdisco/share/views/ajax/report/portlog.tt index 1616980c..777e32d1 100644 --- a/Netdisco/share/views/ajax/report/portlog.tt +++ b/Netdisco/share/views/ajax/report/portlog.tt @@ -30,12 +30,7 @@ diff --git a/Netdisco/share/views/ajax/report/portmultinodes.tt b/Netdisco/share/views/ajax/report/portmultinodes.tt index d359ffc1..8482edfd 100644 --- a/Netdisco/share/views/ajax/report/portmultinodes.tt +++ b/Netdisco/share/views/ajax/report/portmultinodes.tt @@ -12,12 +12,6 @@ diff --git a/Netdisco/share/views/ajax/report/portssid.tt b/Netdisco/share/views/ajax/report/portssid.tt index ce8270ee..23e5e9e8 100644 --- a/Netdisco/share/views/ajax/report/portssid.tt +++ b/Netdisco/share/views/ajax/report/portssid.tt @@ -26,12 +26,6 @@ diff --git a/Netdisco/share/views/ajax/report/portutilization.tt b/Netdisco/share/views/ajax/report/portutilization.tt index 822f0bee..cb1ec9d7 100644 --- a/Netdisco/share/views/ajax/report/portutilization.tt +++ b/Netdisco/share/views/ajax/report/portutilization.tt @@ -13,12 +13,6 @@ diff --git a/Netdisco/share/views/ajax/report/vlaninventory.tt b/Netdisco/share/views/ajax/report/vlaninventory.tt index a7aee16e..5b27c15d 100644 --- a/Netdisco/share/views/ajax/report/vlaninventory.tt +++ b/Netdisco/share/views/ajax/report/vlaninventory.tt @@ -12,12 +12,6 @@ diff --git a/Netdisco/share/views/ajax/search/device.tt b/Netdisco/share/views/ajax/search/device.tt index b36f61b8..b9f11a2a 100644 --- a/Netdisco/share/views/ajax/search/device.tt +++ b/Netdisco/share/views/ajax/search/device.tt @@ -17,12 +17,6 @@ diff --git a/Netdisco/share/views/ajax/search/node_by_ip.tt b/Netdisco/share/views/ajax/search/node_by_ip.tt index 879c6967..e91df02d 100644 --- a/Netdisco/share/views/ajax/search/node_by_ip.tt +++ b/Netdisco/share/views/ajax/search/node_by_ip.tt @@ -175,12 +175,6 @@ tr.group:hover { diff --git a/Netdisco/share/views/ajax/search/vlan.tt b/Netdisco/share/views/ajax/search/vlan.tt index 010d54b8..aa75ce85 100644 --- a/Netdisco/share/views/ajax/search/vlan.tt +++ b/Netdisco/share/views/ajax/search/vlan.tt @@ -14,12 +14,6 @@ From fb365f1203aa2c4acbceb26ec16bea3415d164b7 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 15 Sep 2014 23:41:44 +0100 Subject: [PATCH 17/18] Setting for items in number of records per table page menu --- Netdisco/Changes | 6 ++++++ .../lib/App/Netdisco/Manual/Configuration.pod | 20 +++++++++++++++++++ Netdisco/lib/App/Netdisco/Web.pm | 4 ++++ Netdisco/share/config.yml | 11 ++++++++++ .../share/views/ajax/datatabledefaults.tt | 2 +- 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 8170f6c0..4a63b7e2 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,3 +1,9 @@ +2.029008 + + [ENHANCEMENTS] + + * Setting for items in number of records per table page menu (table_showrecordsmenu). + 2.029007 - 2014-09-12 [ENHANCEMENTS] diff --git a/Netdisco/lib/App/Netdisco/Manual/Configuration.pod b/Netdisco/lib/App/Netdisco/Manual/Configuration.pod index e82228ec..966f8b68 100644 --- a/Netdisco/lib/App/Netdisco/Manual/Configuration.pod +++ b/Netdisco/lib/App/Netdisco/Manual/Configuration.pod @@ -314,6 +314,26 @@ Value: Number. Default: 10. The number of rows in a table page. +=head3 C + +Value: Number. Default: + + - - 10 + - 25 + - 50 + - 100 + - '-1' + - - 10 + - 25 + - 50 + - 100 + - 'All' + +The choices available to users for selecting the number of rows per page. The +format is two lists: one of the values and one of the labels in the web +interface. You can see in the default that a value of "C<-1>" means Show All +Records. Take care of the YAML formatting and indenting for the double list. + =head2 Netdisco Core =head3 C diff --git a/Netdisco/lib/App/Netdisco/Web.pm b/Netdisco/lib/App/Netdisco/Web.pm index 711b10d1..07c403c2 100644 --- a/Netdisco/lib/App/Netdisco/Web.pm +++ b/Netdisco/lib/App/Netdisco/Web.pm @@ -76,6 +76,10 @@ hook 'before_template' => sub { # create date ranges from within templates $tokens->{to_daterange} = sub { interval_to_daterange(@_) }; + # data structure for DataTables records per page menu + $tokens->{table_showrecordsmenu} = + to_json( setting('table_showrecordsmenu') ); + # fix Plugin Template Variables to be only path+query $tokens->{$_} = $tokens->{$_}->path_query for qw/search_node search_device device_ports/; diff --git a/Netdisco/share/config.yml b/Netdisco/share/config.yml index 7710acc0..94d71dec 100644 --- a/Netdisco/share/config.yml +++ b/Netdisco/share/config.yml @@ -82,6 +82,17 @@ jobqueue_refresh: 10 safe_password_store: true reports: [] table_pagesize: 10 +table_showrecordsmenu: + - - 10 + - 25 + - 50 + - 100 + - '-1' + - - 10 + - 25 + - 50 + - 100 + - 'All' # ------------- # NETDISCO CORE diff --git a/Netdisco/share/views/ajax/datatabledefaults.tt b/Netdisco/share/views/ajax/datatabledefaults.tt index 1c463211..55b3ed82 100644 --- a/Netdisco/share/views/ajax/datatabledefaults.tt +++ b/Netdisco/share/views/ajax/datatabledefaults.tt @@ -2,7 +2,7 @@ "processing": true, "stateSave": true, "pageLength": [% settings.table_pagesize %], - "lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ], + "lengthMenu": [% table_showrecordsmenu %], "dom": '<"top"l<"nd_datatables-pager"p>f>rt<"bottom"><"clear">', "language": { "search": '_INPUT_', From c70dcf60d52ddbb86fe665c4d1da053c047b6e13 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Tue, 16 Sep 2014 18:42:46 +0100 Subject: [PATCH 18/18] better format for table page sizes --- .../lib/App/Netdisco/Manual/Configuration.pod | 17 +++++------------ Netdisco/share/config.yml | 12 ++---------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/Netdisco/lib/App/Netdisco/Manual/Configuration.pod b/Netdisco/lib/App/Netdisco/Manual/Configuration.pod index 966f8b68..b9578d99 100644 --- a/Netdisco/lib/App/Netdisco/Manual/Configuration.pod +++ b/Netdisco/lib/App/Netdisco/Manual/Configuration.pod @@ -312,27 +312,20 @@ Set to "C" if you MUST maintain backwards compatibility with the Netdisco Value: Number. Default: 10. -The number of rows in a table page. +The default number of rows in a table page. =head3 C Value: Number. Default: - - - 10 - - 25 - - 50 - - 100 - - '-1' - - - 10 - - 25 - - 50 - - 100 - - 'All' + table_showrecordsmenu: + - [10, 25, 50, 100, '-1'] + - [10, 25, 50, 100, 'All'] The choices available to users for selecting the number of rows per page. The format is two lists: one of the values and one of the labels in the web interface. You can see in the default that a value of "C<-1>" means Show All -Records. Take care of the YAML formatting and indenting for the double list. +Records. =head2 Netdisco Core diff --git a/Netdisco/share/config.yml b/Netdisco/share/config.yml index 94d71dec..019caae8 100644 --- a/Netdisco/share/config.yml +++ b/Netdisco/share/config.yml @@ -83,16 +83,8 @@ safe_password_store: true reports: [] table_pagesize: 10 table_showrecordsmenu: - - - 10 - - 25 - - 50 - - 100 - - '-1' - - - 10 - - 25 - - 50 - - 100 - - 'All' + - [10, 25, 50, 100, '-1'] + - [10, 25, 50, 100, 'All'] # ------------- # NETDISCO CORE