Merge branch 'master' into em-device-ports-json

Conflicts:
	Netdisco/share/public/css/netdisco.css
	Netdisco/share/views/ajax/device/ports.tt
This commit is contained in:
Oliver Gorwits
2014-09-16 19:29:41 +01:00
66 changed files with 936 additions and 320 deletions

View File

@@ -1,3 +1,33 @@
2.029008
[ENHANCEMENTS]
* Setting for items in number of records per table page menu (table_showrecordsmenu).
2.029007 - 2014-09-12
[ENHANCEMENTS]
* [#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]
* Skip device aliases which cannot be parsed as IPs
* [#137] do not attempt DNS resolution on bad IPs
2.029006 - 2014-08-25
[NEW FEATURES]
* netdisco-sshcollector script to get ARP data on devices without SNMP (C. Ramseyer)
* Add Nodes discovered through LLDP/CDP report (replaces IP Phones report)
[ENHANCEMENTS]
* Port search also searches on the Remote ID and Type
2.029005 - 2014-08-13 2.029005 - 2014-08-13
[ENHANCEMENTS] [ENHANCEMENTS]

View File

@@ -6,6 +6,7 @@ bin/netdisco-db-deploy
bin/netdisco-deploy bin/netdisco-deploy
bin/netdisco-do bin/netdisco-do
bin/netdisco-rancid-export bin/netdisco-rancid-export
bin/netdisco-sshcollector
bin/netdisco-web bin/netdisco-web
bin/netdisco-web-fg bin/netdisco-web-fg
Changes Changes
@@ -79,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/DuplexMismatch.pm
lib/App/Netdisco/DB/Result/Virtual/GenericReport.pm lib/App/Netdisco/DB/Result/Virtual/GenericReport.pm
lib/App/Netdisco/DB/Result/Virtual/NodeMonitor.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/NodeWithAge.pm
lib/App/Netdisco/DB/Result/Virtual/OrphanedDevices.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/PollerPerformance.pm
lib/App/Netdisco/DB/Result/Virtual/PortUtilization.pm lib/App/Netdisco/DB/Result/Virtual/PortUtilization.pm
lib/App/Netdisco/DB/Result/Virtual/SlowDevices.pm lib/App/Netdisco/DB/Result/Virtual/SlowDevices.pm
@@ -148,6 +149,11 @@ lib/App/Netdisco/Manual/Deployment.pod
lib/App/Netdisco/Manual/Developing.pod lib/App/Netdisco/Manual/Developing.pod
lib/App/Netdisco/Manual/ReleaseNotes.pod lib/App/Netdisco/Manual/ReleaseNotes.pod
lib/App/Netdisco/Manual/WritingPlugins.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/SSHCollector/Platform/IOSXR.pm
lib/App/Netdisco/SSHCollector/Platform/PaloAlto.pm
lib/App/Netdisco/Util/Daemon.pm lib/App/Netdisco/Util/Daemon.pm
lib/App/Netdisco/Util/Device.pm lib/App/Netdisco/Util/Device.pm
lib/App/Netdisco/Util/DNS.pm lib/App/Netdisco/Util/DNS.pm
@@ -198,8 +204,8 @@ lib/App/Netdisco/Web/Plugin/Report/IpInventory.pm
lib/App/Netdisco/Web/Plugin/Report/ModuleInventory.pm lib/App/Netdisco/Web/Plugin/Report/ModuleInventory.pm
lib/App/Netdisco/Web/Plugin/Report/Netbios.pm lib/App/Netdisco/Web/Plugin/Report/Netbios.pm
lib/App/Netdisco/Web/Plugin/Report/NodeMultiIPs.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/NodeVendor.pm
lib/App/Netdisco/Web/Plugin/Report/PhonesDiscovered.pm
lib/App/Netdisco/Web/Plugin/Report/PortAdminDown.pm lib/App/Netdisco/Web/Plugin/Report/PortAdminDown.pm
lib/App/Netdisco/Web/Plugin/Report/PortBlocking.pm lib/App/Netdisco/Web/Plugin/Report/PortBlocking.pm
lib/App/Netdisco/Web/Plugin/Report/PortLog.pm lib/App/Netdisco/Web/Plugin/Report/PortLog.pm
@@ -341,10 +347,10 @@ share/views/ajax/report/netbios.tt
share/views/ajax/report/netbios_csv.tt share/views/ajax/report/netbios_csv.tt
share/views/ajax/report/nodemultiips.tt share/views/ajax/report/nodemultiips.tt
share/views/ajax/report/nodemultiips_csv.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.tt
share/views/ajax/report/nodevendor_csv.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.tt
share/views/ajax/report/portadmindown_csv.tt share/views/ajax/report/portadmindown_csv.tt
share/views/ajax/report/portblocking.tt share/views/ajax/report/portblocking.tt
@@ -388,6 +394,7 @@ share/views/sidebar/device/ports.tt
share/views/sidebar/report/ipinventory.tt share/views/sidebar/report/ipinventory.tt
share/views/sidebar/report/moduleinventory.tt share/views/sidebar/report/moduleinventory.tt
share/views/sidebar/report/netbios.tt share/views/sidebar/report/netbios.tt
share/views/sidebar/report/nodesdiscovered.tt
share/views/sidebar/report/nodevendor.tt share/views/sidebar/report/nodevendor.tt
share/views/sidebar/report/portlog.tt share/views/sidebar/report/portlog.tt
share/views/sidebar/report/portssid.tt share/views/sidebar/report/portssid.tt

View File

@@ -22,8 +22,10 @@ no_index:
- share - share
- t - t
recommends: recommends:
Expect: 0
Graph: 0 Graph: 0
GraphViz: 0 GraphViz: 0
Net::OpenSSH: 0
requires: requires:
Algorithm::Cron: 0.07 Algorithm::Cron: 0.07
AnyEvent: 7.05 AnyEvent: 7.05
@@ -89,4 +91,4 @@ resources:
homepage: http://netdisco.org/ homepage: http://netdisco.org/
license: http://opensource.org/licenses/bsd-license.php license: http://opensource.org/licenses/bsd-license.php
repository: git://git.code.sf.net/p/netdisco/netdisco-ng repository: git://git.code.sf.net/p/netdisco/netdisco-ng
version: 2.029005 version: 2.029007

View File

@@ -70,6 +70,8 @@ if ( $^O eq 'linux' ) {
recommends 'Graph' => 0; recommends 'Graph' => 0;
recommends 'GraphViz' => 0; recommends 'GraphViz' => 0;
recommends 'Net::OpenSSH' => 0;
recommends 'Expect' => 0;
install_share 'share'; install_share 'share';
@@ -82,6 +84,7 @@ install_script 'bin/netdisco-daemon';
install_script 'bin/netdisco-web-fg'; install_script 'bin/netdisco-web-fg';
install_script 'bin/netdisco-web'; install_script 'bin/netdisco-web';
install_script 'bin/netdisco-rancid-export'; install_script 'bin/netdisco-rancid-export';
install_script 'bin/netdisco-sshcollector';
resources resources
homepage => 'http://netdisco.org/', homepage => 'http://netdisco.org/',

View File

@@ -113,7 +113,17 @@ unless ($action) {
} }
use App::Netdisco::Util::SNMP (); use App::Netdisco::Util::SNMP ();
use App::Netdisco::Util::Device 'get_device';
use NetAddr::IP::Lite ':lower';
use Scalar::Util 'blessed';
sub show { 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; $extra ||= 'interfaces'; my $class = undef;
($class, $extra) = split(/::([^:]+)$/, $extra); ($class, $extra) = split(/::([^:]+)$/, $extra);
if ($class and $extra) { if ($class and $extra) {
@@ -123,7 +133,7 @@ unless ($action) {
$extra = $class; $extra = $class;
undef $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); Data::Printer::p($i->$extra);
return ('done', "Showed $extra response from $device."); return ('done', "Showed $extra response from $device.");
} }

View File

@@ -0,0 +1,274 @@
#!/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<App::Netdisco::SSHCollector::Platform::ACE> - Cisco ACE (Application Control Engine)
=item * L<App::Netdisco::SSHCollector::Platform::BigIP> - F5 Networks BigIP
=item * L<App::Netdisco::SSHCollector::Platform::IOS> - Cisco IOS
=item * L<App::Netdisco::SSHCollector::Platform::IOSXR> - Cisco IOS XR
=item * L<App::Netdisco::SSHCollector::Platform::PaloAlto> - PaloAlto devices
=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<sshcollector>
Data is collected from the machines specified in this setting. The format is a
list of dictionaries. The keys C<ip>, C<user>, C<password>, and C<platform>
are required. Optionally the C<hostname> key can be used instead of the
C<ip>. 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<ACE> will be queried using
C<App::Netdisco::SSHCollector::Platform::ACE>.
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<App::Netdisco::SSHCollector::Platform> namespace.
This class must implement an C<arpnip($hostname, $ssh)> method which returns
an array of hashrefs in the format
@result = ({ ip => IPADDR, mac => MACADDR }, ...)
The parameter C<$ssh> is an active C<Net::OpenSSH> 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<inetaddr> and B<macaddr> datatypes in PostgreSQL can handle.
=head1 DEPENDENCIES
=over 4
=item L<App::Netdisco>
=item L<Net::OpenSSH>
=item L<Expect>
=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__

View File

@@ -4,7 +4,7 @@ use strict;
use warnings; use warnings;
use 5.010_000; use 5.010_000;
our $VERSION = '2.029005'; our $VERSION = '2.029007';
use App::Netdisco::Configuration; use App::Netdisco::Configuration;
use Module::Find (); use Module::Find ();

View File

@@ -96,14 +96,21 @@ sub _get_arps {
return $resolved_ips; return $resolved_ips;
} }
=head2 store_arp( $mac, $ip, $name, $now? ) =head2 store_arp( \%host, $now? )
Stores a new entry to the C<node_ip> table with the given MAC, IP (v4 or v6) Stores a new entry to the C<node_ip> 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<active>. {
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<dns> entry is optional. The update will mark old entries for this IP as
no longer C<active>.
Optionally a literal string can be passed in the second argument for the
C<time_last> timestamp, otherwise the current timestamp (C<now()>) is used. C<time_last> timestamp, otherwise the current timestamp (C<now()>) is used.
=cut =cut

View File

@@ -120,7 +120,8 @@ sub store_device {
# build device aliases suitable for DBIC # build device aliases suitable for DBIC
my @aliases; my @aliases;
foreach my $entry (keys %$ip_index) { 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; my $addr = $ip->addr;
next if $addr eq '0.0.0.0'; next if $addr eq '0.0.0.0';

View File

@@ -346,6 +346,8 @@ sub _walk_fwtable {
next; next;
} }
my $vlan = $fw_vlan->{$idx} || $comm_vlan || '0';
# check to see if the port is connected to another device # check to see if the port is connected to another device
# and if we have that device in the database. # and if we have that device in the database.
@@ -371,12 +373,13 @@ sub _walk_fwtable {
debug sprintf debug sprintf
' [%s] macsuck %s - port %s is detected uplink - skipping.', ' [%s] macsuck %s - port %s is detected uplink - skipping.',
$device->ip, $mac, $port; $device->ip, $mac, $port;
$skiplist->{$port} = [ $vlan, $mac ] # remember for later
if exists $port_macs->{$mac};
next; next;
} }
} }
my $vlan = $fw_vlan->{$idx} || $comm_vlan || '0';
if (exists $port_macs->{$mac}) { if (exists $port_macs->{$mac}) {
my $switch_ip = $port_macs->{$mac}; my $switch_ip = $port_macs->{$mac};
if ($device->ip eq $switch_ip) { if ($device->ip eq $switch_ip) {
@@ -395,7 +398,8 @@ sub _walk_fwtable {
if (not setting('macsuck_bleed')) { if (not setting('macsuck_bleed')) {
debug sprintf ' [%s] macsuck %s - adding port %s to skiplist', debug sprintf ' [%s] macsuck %s - adding port %s to skiplist',
$device->ip, $mac, $port; $device->ip, $mac, $port;
$skiplist->{$port} = delete $cache->{$vlan}->{$port};
$skiplist->{$port} = [ $vlan, $mac ]; # remember for later
next; next;
} }
} }
@@ -410,6 +414,15 @@ sub _walk_fwtable {
++$cache->{$vlan}->{$port}->{$mac}; ++$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; return $cache;
} }

View File

@@ -1,4 +1,4 @@
package App::Netdisco::DB::Result::Virtual::PhonesDiscovered; package App::Netdisco::DB::Result::Virtual::NodesDiscovered;
use strict; use strict;
use warnings; use warnings;
@@ -7,7 +7,7 @@ use base 'DBIx::Class::Core';
__PACKAGE__->table_class('DBIx::Class::ResultSource::View'); __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
__PACKAGE__->table('phones_discovered'); __PACKAGE__->table('nodes_discovered');
__PACKAGE__->result_source_instance->is_virtual(1); __PACKAGE__->result_source_instance->is_virtual(1);
__PACKAGE__->result_source_instance->view_definition(<<ENDSQL __PACKAGE__->result_source_instance->view_definition(<<ENDSQL
SELECT d.ip, SELECT d.ip,
@@ -33,9 +33,7 @@ WHERE d.ip = p.ip
WHERE a.alias = p.remote_ip WHERE a.alias = p.remote_ip
AND q.ip = a.ip AND q.ip = a.ip
AND q.port = p.remote_port) AND q.port = p.remote_port)
AND p.remote_ip IS NOT NULL AND (p.remote_id IS NOT NULL OR p.remote_type IS NOT NULL)
AND p.remote_port IS NOT NULL
AND p.remote_type ILIKE '%ip_phone%'
ENDSQL ENDSQL
); );

View File

@@ -312,7 +312,20 @@ Set to "C<false>" if you MUST maintain backwards compatibility with the Netdisco
Value: Number. Default: 10. Value: Number. Default: 10.
The number of rows in a table page. The default number of rows in a table page.
=head3 C<table_showrecordsmenu>
Value: Number. Default:
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.
=head2 Netdisco Core =head2 Netdisco Core

View File

@@ -164,7 +164,7 @@ Then run the web daemon with the environment variable to enable the feature:
DANCER_DEBUG=1 ~/bin/netdisco-web restart 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 We recommend you backup the Netdisco database regularly. You could put the
following commands into a shell script and call it nightly from C<cron>: following commands into a shell script and call it nightly from C<cron>:

View File

@@ -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<show context>, afterwards the commands C<changeto CONTEXTNAME> and
C<show arp> 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<arpnip($host, $ssh)>
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;

View File

@@ -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<arpnip($host, $ssh)>
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;

View File

@@ -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<arpnip($host, $ssh)>
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;

View File

@@ -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<arpnip($host, $ssh)>
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;

View File

@@ -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<arpnip($host, $ssh)>
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;

View File

@@ -166,7 +166,8 @@ sub no_resolve {
my $config = setting('dns')->{no} || []; my $config = setting('dns')->{no} || [];
return 0 if not scalar @$config; 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) { foreach my $item (@$config) {
my $c_ip = NetAddr::IP::Lite->new($item) my $c_ip = NetAddr::IP::Lite->new($item)

View File

@@ -76,6 +76,10 @@ hook 'before_template' => sub {
# create date ranges from within templates # create date ranges from within templates
$tokens->{to_daterange} = sub { interval_to_daterange(@_) }; $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 # fix Plugin Template Variables to be only path+query
$tokens->{$_} = $tokens->{$_}->path_query $tokens->{$_} = $tokens->{$_}->path_query
for qw/search_node search_device device_ports/; for qw/search_node search_device device_ports/;

View File

@@ -0,0 +1,54 @@
package App::Netdisco::Web::Plugin::Report::NodesDiscovered;
use Dancer ':syntax';
use Dancer::Plugin::DBIC;
use Dancer::Plugin::Auth::Extensible;
use App::Netdisco::Web::Plugin;
use App::Netdisco::Util::Web 'sql_match';
register_report(
{ category => 'Node',
tag => 'nodesdiscovered',
label => 'Nodes discovered through LLDP/CDP',
provides_csv => 1,
}
);
get '/ajax/content/report/nodesdiscovered' => require_login sub {
my $op = param('matchall') ? '-and' : '-or';
my @results = schema('netdisco')->resultset('Virtual::NodesDiscovered')
->search({
$op => [
(param('aps') ?
('me.remote_type' => { -ilike => 'AP:%' }) : ()),
(param('phones') ?
('me.remote_type' => { -ilike => '%ip_phone%' }) : ()),
(param('remote_id') ?
('me.remote_id' => { -ilike => scalar sql_match(param('remote_id')) }) : ()),
(param('remote_type') ? ('-or' => [
map {( 'me.remote_type' => { -ilike => scalar sql_match($_) } )}
grep { $_ }
(ref param('remote_type') ? @{param('remote_type')} : param('remote_type'))
]) : ()),
],
})
->hri->all;
return unless scalar @results;
if ( request->is_ajax ) {
my $json = to_json( \@results );
template 'ajax/report/nodesdiscovered.tt', { results => $json },
{ layout => undef };
}
else {
header( 'Content-Type' => 'text/comma-separated-values' );
template 'ajax/report/nodesdiscovered_csv.tt',
{ results => \@results },
{ layout => undef };
}
};
1;

View File

@@ -1,36 +0,0 @@
package App::Netdisco::Web::Plugin::Report::PhonesDiscovered;
use Dancer ':syntax';
use Dancer::Plugin::DBIC;
use Dancer::Plugin::Auth::Extensible;
use App::Netdisco::Web::Plugin;
register_report(
{ category => 'Node',
tag => 'phonesdiscovered',
label => 'IP Phones discovered through LLDP/CDP',
provides_csv => 1,
}
);
get '/ajax/content/report/phonesdiscovered' => require_login sub {
my @results = schema('netdisco')->resultset('Virtual::PhonesDiscovered')
->hri->all;
return unless scalar @results;
if ( request->is_ajax ) {
my $json = to_json( \@results );
template 'ajax/report/phonesdiscovered.tt', { results => $json },
{ layout => undef };
}
else {
header( 'Content-Type' => 'text/comma-separated-values' );
template 'ajax/report/phonesdiscovered_csv.tt',
{ results => \@results },
{ layout => undef };
}
};
1;

View File

@@ -37,6 +37,8 @@ get '/ajax/content/search/port' => require_login sub {
? { "me.mac" => $q } ? { "me.mac" => $q }
: \[ 'me.mac::text ILIKE ?', $likeval ] : \[ 'me.mac::text ILIKE ?', $likeval ]
), ),
{ "me.remote_id" => $likeclause },
{ "me.remote_type" => $likeclause },
] ]
}, },
{ '+columns' => [qw/ device.dns device.name port_vlans.vlan /], { '+columns' => [qw/ device.dns device.name port_vlans.vlan /],

View File

@@ -8,7 +8,7 @@ get '/report/*' => require_login sub {
my ($tag) = splat; my ($tag) = splat;
# used in the report search sidebar to populate select inputs # used in the report search sidebar to populate select inputs
my ( $domain_list, $class_list, $ssid_list, $vendor_list ); my ( $domain_list, $class_list, $ssid_list, $type_list, $vendor_list );
if ( $tag eq 'netbios' ) { if ( $tag eq 'netbios' ) {
$domain_list = [ schema('netdisco')->resultset('NodeNbt') $domain_list = [ schema('netdisco')->resultset('NodeNbt')
@@ -31,6 +31,10 @@ get '/report/*' => require_login sub {
$ssid_list = [ schema('netdisco')->resultset('DevicePortSsid') $ssid_list = [ schema('netdisco')->resultset('DevicePortSsid')
->get_distinct_col('ssid') ]; ->get_distinct_col('ssid') ];
} }
elsif ( $tag eq 'nodesdiscovered' ) {
$type_list = [ schema('netdisco')->resultset('DevicePort')
->get_distinct_col('remote_type') ];
}
elsif ( $tag eq 'nodevendor' ) { elsif ( $tag eq 'nodevendor' ) {
$vendor_list = [ $vendor_list = [
schema('netdisco')->resultset('Node')->search( schema('netdisco')->resultset('Node')->search(
@@ -54,6 +58,7 @@ get '/report/*' => require_login sub {
domain_list => $domain_list, domain_list => $domain_list,
class_list => $class_list, class_list => $class_list,
ssid_list => $ssid_list, ssid_list => $ssid_list,
type_list => $type_list,
vendor_list => $vendor_list, vendor_list => $vendor_list,
}; };
}; };

View File

@@ -54,7 +54,7 @@ web_plugins:
- Report::Netbios - Report::Netbios
- Report::NodeMultiIPs - Report::NodeMultiIPs
- Report::NodeVendor - Report::NodeVendor
- Report::PhonesDiscovered - Report::NodesDiscovered
- Report::SsidInventory - Report::SsidInventory
- Report::VlanInventory - Report::VlanInventory
- Report::SubnetUtilization - Report::SubnetUtilization
@@ -82,6 +82,9 @@ jobqueue_refresh: 10
safe_password_store: true safe_password_store: true
reports: [] reports: []
table_pagesize: 10 table_pagesize: 10
table_showrecordsmenu:
- [10, 25, 50, 100, '-1']
- [10, 25, 50, 100, 'All']
# ------------- # -------------
# NETDISCO CORE # NETDISCO CORE

View File

@@ -657,6 +657,7 @@ form .clearfix.success input {
} }
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* dataTables */
/* Clear div for DataTables ColVis plugin */ /* Clear div for DataTables ColVis plugin */
div.nd_clear-both { div.nd_clear-both {

View File

@@ -71,11 +71,6 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#data-table').dataTable({ $('#data-table').dataTable({
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"columnDefs": [ "columnDefs": [
{ {
"targets": [ 0, 2, 5 ], "targets": [ 0, 2, 5 ],
@@ -85,7 +80,8 @@ $(document).ready(function() {
"targets": [ 0, 2, 5 ], "targets": [ 0, 2, 5 ],
"orderable": false "orderable": false
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
} ); } );
</script> </script>

View File

@@ -63,17 +63,12 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#data-table').dataTable({ $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"columnDefs": [ { "columnDefs": [ {
"targets": [ 2, 3 ], "targets": [ 2, 3 ],
"orderable": false, "orderable": false,
"searchable": false "searchable": false
} ] } ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
} ); } );
</script> </script>

View File

@@ -33,7 +33,7 @@ $(document).ready(function() {
"searching": false, "searching": false,
"info": false, "info": false,
"order": [[ 4, 'desc' ], [ 0, 'asc' ], [ 1, 'asc' ] ], "order": [[ 4, 'desc' ], [ 0, 'asc' ], [ 1, 'asc' ] ],
"pageLength": [% settings.table_pagesize %], "pageLength": 12
} ); });
} ); } );
</script> </script>

View File

@@ -89,17 +89,12 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#data-table').dataTable({ $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"columnDefs": [ { "columnDefs": [ {
"targets": [ 4 ], "targets": [ 4 ],
"orderable": false, "orderable": false,
"searchable": false "searchable": false
} ] } ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
} ); } );
</script> </script>

View File

@@ -27,13 +27,8 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#data-table').dataTable({ $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"order": [[ 2, 'desc' ], [ 1, 'asc' ] ], "order": [[ 2, 'desc' ], [ 1, 'asc' ] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
} ); } );
</script> </script>

View File

@@ -17,12 +17,6 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#aul-data-table').dataTable( { $('#aul-data-table').dataTable( {
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"serverSide": true, "serverSide": true,
"order": [[ 0, "desc" ]], "order": [[ 0, "desc" ]],
"ajax": "[% uri_for('/ajax/control/admin/userlog/data') %]", "ajax": "[% uri_for('/ajax/control/admin/userlog/data') %]",
@@ -60,7 +54,8 @@ $(document).ready(function() {
'"><button class="btn nd_adminbutton" name="del" type="submit"><i class="icon-trash text-error"></i></button>'; '"><button class="btn nd_adminbutton" name="del" type="submit"><i class="icon-trash text-error"></i></button>';
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
} ); } );
</script> </script>

View File

@@ -78,12 +78,6 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#data-table').dataTable({ $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"columnDefs": [ "columnDefs": [
{ {
"targets": [ 2, 3, 4, 5, 6 ], "targets": [ 2, 3, 4, 5, 6 ],
@@ -93,7 +87,8 @@ $(document).ready(function() {
"targets": [ 0, 1, 2, 3, 4, 5, 6 ], "targets": [ 0, 1, 2, 3, 4, 5, 6 ],
"orderable": false "orderable": false
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
} ); } );
</script> </script>

View File

@@ -0,0 +1,11 @@
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"lengthMenu": [% table_showrecordsmenu %],
"dom": '<"top"l<"nd_datatables-pager"p>f>rt<"bottom"><"clear">',
"language": {
"search": '_INPUT_',
"searchPlaceholder": 'Filter records...',
"lengthMenu": "Show _MENU_ records."
}

View File

@@ -13,12 +13,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#da-data-table').dataTable({ var table = $('#da-data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [ "columns": [
@@ -51,7 +45,8 @@ $(document).ready(function() {
return '<a href="[% search_device %]&q=' + encodeURIComponent(data) + '&ip=' + encodeURIComponent(data) + '">' + he.encode(data || '') + '</a>'; return '<a href="[% search_device %]&q=' + encodeURIComponent(data) + '&ip=' + encodeURIComponent(data) + '">' + he.encode(data || '') + '</a>';
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -31,16 +31,6 @@
$(document).ready(function() { $(document).ready(function() {
var freeDate = moment().subtract( [% params.age_num %], '[% params.age_unit %]' ); var freeDate = moment().subtract( [% params.age_num %], '[% params.age_unit %]' );
var table = $('#dp-data-table').dataTable({ var table = $('#dp-data-table').dataTable({
"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."
},
"deferRender": true, "deferRender": true,
"order": [[ 1, "asc" ]], "order": [[ 1, "asc" ]],
"colVis": { "colVis": {
@@ -601,7 +591,8 @@ $(document).ready(function() {
[% END %] [% END %]
[% END %] [% END %]
], ],
"data": [% results %] "data": [% results %],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
// display the column show/hide buttons in the sidebar // display the column show/hide buttons in the sidebar

View File

@@ -10,12 +10,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"order": [[ 1, "desc" ]], "order": [[ 1, "desc" ]],
"data": [% results %], "data": [% results %],
@@ -29,7 +23,8 @@ $(document).ready(function() {
return data.replace(/\B(?=(\d{3})+(?!\d))/g, ","); return data.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -38,12 +38,6 @@ function groupString(d) {
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').DataTable({ var table = $('#data-table').DataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"serverSide": true, "serverSide": true,
"ajax": "[% uri_for('/ajax/content/report/apradiochannelpower/data') %]", "ajax": "[% uri_for('/ajax/content/report/apradiochannelpower/data') %]",
"order": [[ 0, 'asc' ]], "order": [[ 0, 'asc' ]],
@@ -103,7 +97,8 @@ $(document).ready(function() {
last = group; last = group;
} }
} ); } );
} },
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
// Order by the grouping // Order by the grouping

View File

@@ -12,12 +12,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [{ "columns": [{
@@ -41,6 +35,7 @@ $(document).ready(function() {
return he.encode(data || ''); return he.encode(data || '');
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
});</script> });</script>

View File

@@ -13,12 +13,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"order": [[ 0, "asc" ], [2, "asc"], [ 3, "asc" ], [4, "asc"]], "order": [[ 0, "asc" ], [2, "asc"], [ 3, "asc" ], [4, "asc"]],
"data": [% results %], "data": [% results %],
@@ -54,7 +48,8 @@ $(document).ready(function() {
return '<a href="[% search_device %]&q=' + encodeURIComponent(data) + '&model=' + encodeURIComponent(data) + '">' + he.encode(data || '') + '</a>'; return '<a href="[% search_device %]&q=' + encodeURIComponent(data) + '&model=' + encodeURIComponent(data) + '">' + he.encode(data || '') + '</a>';
} }
} }
] ].
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });

View File

@@ -13,12 +13,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [ "columns": [
@@ -48,7 +42,8 @@ $(document).ready(function() {
return he.encode(data || ''); return he.encode(data || '');
} }
} }
] ].
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -64,12 +64,6 @@ function groupString(d) {
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').DataTable({ var table = $('#data-table').DataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"serverSide": true, "serverSide": true,
"ajax": "[% uri_for('/ajax/content/report/devicepoestatus/data') %]", "ajax": "[% uri_for('/ajax/content/report/devicepoestatus/data') %]",
"order": [[ 0, 'asc' ]], "order": [[ 0, 'asc' ]],
@@ -168,7 +162,8 @@ $(document).ready(function() {
last = group; last = group;
} }
} ); } );
} },
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
// Order by the grouping // Order by the grouping

View File

@@ -14,12 +14,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [ "columns": [
@@ -60,7 +54,8 @@ $(document).ready(function() {
return he.encode(capitalizeFirstLetter(data || '')); return he.encode(capitalizeFirstLetter(data || ''));
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -20,12 +20,7 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#rg-data-table').dataTable({ $('#rg-data-table').dataTable({
"processing": true, [% INCLUDE 'ajax/datatabledefaults.tt' -%]
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
}
} ); } );
} ); } );
</script> </script>

View File

@@ -12,12 +12,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [ "columns": [
@@ -47,7 +41,8 @@ $(document).ready(function() {
return he.encode(capitalizeFirstLetter(data)); return he.encode(capitalizeFirstLetter(data));
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -12,12 +12,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [ "columns": [
@@ -53,7 +47,8 @@ $(document).ready(function() {
return he.encode(data || 'Never'); return he.encode(data || 'Never');
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -30,12 +30,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
[% IF opt %] [% IF opt %]
"serverSide": true, "serverSide": true,
"searching": false, "searching": false,
@@ -93,7 +87,7 @@ $(document).ready(function() {
return he.encode(data || ''); return he.encode(data || '');
} }
} }
] ],
[% ELSE %] [% ELSE %]
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
@@ -109,8 +103,9 @@ $(document).ready(function() {
return data.replace(/\B(?=(\d{3})+(?!\d))/g, ","); return data.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} }
} }
] ],
[% END %] [% END %]
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -26,12 +26,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
[% IF opt %] [% IF opt %]
"serverSide": true, "serverSide": true,
"order": [[ 0, "desc" ]], "order": [[ 0, "desc" ]],
@@ -73,7 +67,7 @@ $(document).ready(function() {
} }
} }
], ],
"order": [[0, "asc"], [5, "desc"]] "order": [[0, "asc"], [5, "desc"]],
[% ELSE %] [% ELSE %]
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
@@ -90,8 +84,9 @@ $(document).ready(function() {
} }
} }
], ],
"order": [[1, "desc"]] "order": [[1, "desc"]],
[% END %] [% END %]
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -13,12 +13,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"order": [[ 3, "desc" ]], "order": [[ 3, "desc" ]],
"data": [% results %], "data": [% results %],
@@ -45,7 +39,8 @@ $(document).ready(function() {
return data.replace(/\B(?=(\d{3})+(?!\d))/g, ","); return data.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -14,12 +14,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [ "columns": [
@@ -33,7 +27,7 @@ $(document).ready(function() {
"type": 'portsort', "type": 'portsort',
"render": function(data, type, row, meta) { "render": function(data, type, row, meta) {
return type === 'display' ? return type === 'display' ?
'<a href="[% device_ports %]&q=' + encodeURIComponent(row.ip) + '&f=' + encodeURIComponent(data) + '">' + he.encode(data) + '</a>' : '<a href="[% device_ports %]&c_nodes=on&q=' + encodeURIComponent(row.ip) + '&f=' + encodeURIComponent(data) + '">' + he.encode(data) + '</a>' :
data; data;
} }
}, { }, {
@@ -44,7 +38,7 @@ $(document).ready(function() {
}, { }, {
"data": 'remote_ip', "data": 'remote_ip',
"render": function(data, type, row, meta) { "render": function(data, type, row, meta) {
return '<a href="[% search_node %]&q=' + encodeURIComponent(data) + '">' + he.encode(data) + '</a>'; return '<a href="[% search_node %]&q=' + encodeURIComponent(data || '') + '">' + he.encode(data || '') + '</a>';
} }
}, { }, {
"data": 'remote_port', "data": 'remote_port',
@@ -57,7 +51,8 @@ $(document).ready(function() {
return he.encode(data || ''); return he.encode(data || '');
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -26,12 +26,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
[% IF opt %] [% IF opt %]
"serverSide": true, "serverSide": true,
"order": [[ 0, "desc" ]], "order": [[ 0, "desc" ]],
@@ -69,7 +63,7 @@ $(document).ready(function() {
"data": 'switch', "data": 'switch',
"visible": false "visible": false
} }
] ],
[% ELSE %] [% ELSE %]
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
@@ -86,8 +80,9 @@ $(document).ready(function() {
} }
} }
], ],
"order": [[1, "desc"]] "order": [[1, "desc"]],
[% END %] [% END %]
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -12,12 +12,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"order": [[ 0, "asc" ], [1, "asc"]], "order": [[ 0, "asc" ], [1, "asc"]],
"columns": [ "columns": [
@@ -48,7 +42,8 @@ $(document).ready(function() {
} }
} }
], ],
"data": [% results %] "data": [% results %],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -12,12 +12,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"order": [[ 0, "asc" ], [1, "asc"]], "order": [[ 0, "asc" ], [1, "asc"]],
"data": [% results %], "data": [% results %],
@@ -48,7 +42,8 @@ $(document).ready(function() {
return he.encode(data || ''); return he.encode(data || '');
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -30,12 +30,7 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#data-table').dataTable({ $('#data-table').dataTable({
"processing": true, [% INCLUDE 'ajax/datatabledefaults.tt' -%]
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
}
} ); } );
} ); } );
</script> </script>

View File

@@ -12,12 +12,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"order": [[ 3, "desc" ]], "order": [[ 3, "desc" ]],
"data": [% results %], "data": [% results %],
@@ -47,7 +41,8 @@ $(document).ready(function() {
return data.replace(/\B(?=(\d{3})+(?!\d))/g, ","); return data.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -26,12 +26,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
[% IF opt %] [% IF opt %]
@@ -64,7 +58,7 @@ $(document).ready(function() {
return he.encode(data || ''); return he.encode(data || '');
} }
} }
] ],
[% ELSE %] [% ELSE %]
"columns": [ "columns": [
{ {
@@ -87,6 +81,7 @@ $(document).ready(function() {
], ],
"order": [[ 2, "desc" ]], "order": [[ 2, "desc" ]],
[% END %] [% END %]
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -13,12 +13,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [ "columns": [
@@ -52,7 +46,8 @@ $(document).ready(function() {
return data.replace(/\B(?=(\d{3})+(?!\d))/g, ","); return data.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });

View File

@@ -24,13 +24,8 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
$('#data-table').dataTable({ $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"order": [[ 3, 'desc' ]], "order": [[ 3, 'desc' ]],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
} ); } );
</script> </script>

View File

@@ -12,12 +12,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#data-table').dataTable({ var table = $('#data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [ "columns": [
@@ -44,7 +38,8 @@ $(document).ready(function() {
return data.replace(/\B(?=(\d{3})+(?!\d))/g, ","); return data.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
}); });
</script> </script>

View File

@@ -17,12 +17,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#ds-data-table').dataTable({ var table = $('#ds-data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [{ "columns": [{
@@ -71,6 +65,7 @@ $(document).ready(function() {
return he.encode(data || ''); return he.encode(data || '');
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
});</script> });</script>

View File

@@ -175,12 +175,6 @@ tr.group:hover {
<script> <script>
$(document).ready(function() { $(document).ready(function() {
var table = $('#nsbi-data-table').DataTable({ var table = $('#nsbi-data-table').DataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"columnDefs": [ "columnDefs": [
{ "visible": false, "targets": 0 } { "visible": false, "targets": 0 }
], ],
@@ -203,7 +197,8 @@ $(document).ready(function() {
last = group; last = group;
} }
} ); } );
} },
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
// Order by the grouping // Order by the grouping

View File

@@ -135,12 +135,6 @@ tr.group:hover {
<script> <script>
$(document).ready(function() { $(document).ready(function() {
var table = $('#nsbm-data-table').DataTable({ var table = $('#nsbm-data-table').DataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"columnDefs": [ "columnDefs": [
{ "visible": false, "targets": 0 } { "visible": false, "targets": 0 }
], ],
@@ -163,7 +157,8 @@ $(document).ready(function() {
last = group; last = group;
} }
} ); } );
} },
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
} ); } );
// Order by the grouping // Order by the grouping

View File

@@ -12,12 +12,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#ps-data-table').dataTable({ var table = $('#ps-data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [{ "columns": [{
@@ -32,7 +26,9 @@ $(document).ready(function() {
if (row.device.dns || row.device.name) { if (row.device.dns || row.device.name) {
ddns = ' (' + he.encode(row.device.dns || row.device.name) + ')'; ddns = ' (' + he.encode(row.device.dns || row.device.name) + ')';
} }
return '<a href="[% device_ports %]&q=' + encodeURIComponent(data) + '&f=' + encodeURIComponent(row.port) + '">' + he.encode(data) + '[' + he.encode(row.port) + ']</a>' + ddns; return '<a href="[% device_ports %]&q=' + encodeURIComponent(data)
+ '&f=' + encodeURIComponent(row.port) + '">' + he.encode(data)
+ ' [' + he.encode(row.port) + ']</a>' + ddns;
} }
}, { }, {
"data": 'descr', "data": 'descr',
@@ -45,7 +41,8 @@ $(document).ready(function() {
return data || ''; return data || '';
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
});</script> });</script>

View File

@@ -14,12 +14,6 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
var table = $('#vs-data-table').dataTable({ var table = $('#vs-data-table').dataTable({
"processing": true,
"stateSave": true,
"pageLength": [% settings.table_pagesize %],
"language": {
"search": 'Filter records: '
},
"deferRender": true, "deferRender": true,
"data": [% results %], "data": [% results %],
"columns": [{ "columns": [{
@@ -53,6 +47,7 @@ $(document).ready(function() {
return '<a class="nd_linkcell nd_stealth-link" href="[% device_ports %]&q=' + encodeURIComponent(row.ip) + '&f=' + encodeURIComponent(row.vlans.vlan) + '">' + he.encode(data || '') + '</a>'; return '<a class="nd_linkcell nd_stealth-link" href="[% device_ports %]&q=' + encodeURIComponent(row.ip) + '&f=' + encodeURIComponent(row.vlans.vlan) + '">' + he.encode(data || '') + '</a>';
} }
} }
] ],
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
}); });
});</script> });</script>

View File

@@ -0,0 +1,52 @@
<p class="nd_sidebar-title"><em>Node Search Options</em></p>
<input name="q" value="[% params.q | html_entity %]" type="hidden"/>
<div class="clearfix">
<input class="nd_side-input" placeholder="Remote ID (host name)"
type="text" name="remote_id" value="[% params.name | html_entity %]"
rel="tooltip" data-placement="left" data-offset="5" data-title="Remote ID"/>
</div>
<div class="clearfix">
<input class="nd_side-input" placeholder="Remote Type (platform)"
type="text" name="remote_type" value="[% params.name | html_entity %]"
rel="tooltip" data-placement="left" data-offset="5" data-title="Remote Type"/>
</div>
<div class="clearfix">
<select class="nd_side-select nd_colored-input" size="[% type_list.size > 8 ? 8 : type_list.size %]"
multiple="on" name="remote_type"
rel="tooltip" data-placement="left" data-offset="5" data-title="Remote Type"/>
[% FOREACH opt IN type_list %]
<option[% ' selected="selected"' IF type_lkp.exists(opt) %]>[% opt | html_entity %]</option>
[% END %]
</select>
</div>
<div class="clearfix input-prepend">
<label class="add-on">
<input type="checkbox" id="phones"
name="phones"[% ' checked="checked"' IF params.phones %]/>
</label>
<label class="nd_checkboxlabel" for="phones">
<span class="nd_searchcheckbox uneditable-input"><i class="icon-li icon-phone"></i>&nbsp; IP Phones</span>
</label>
</div>
<div class="clearfix input-prepend">
<label class="add-on">
<input type="checkbox" id="aps"
name="aps"[% ' checked="checked"' IF params.aps %]/>
</label>
<label class="nd_checkboxlabel" for="aps">
<span class="nd_searchcheckbox uneditable-input"><i class="icon-li icon-signal"></i>&nbsp Wireless APs</span>
</label>
</div>
<div class="clearfix"><p></p></div>
<div class="clearfix input-prepend">
<label class="add-on">
<input type="checkbox" id="matchall"
name="matchall"[% ' checked="checked"' IF params.matchall %]/>
</label>
<label class="nd_checkboxlabel" for="matchall">
<span class="nd_searchcheckbox uneditable-input">Match All Options</span>
</label>
</div>
<button id="[% tab.tag %]_submit" type="submit" class="btn btn-info">
<i class="icon-search icon-large pull-left nd_navbar-icon"></i> Search Nodes</button>