Merge branch 'master' into em-device-ports-json
This commit is contained in:
@@ -1,8 +1,47 @@
|
||||
2.029008
|
||||
2.029012 - 2014-10-09
|
||||
|
||||
[BUG FIXES]
|
||||
|
||||
* [#152] HP devices with port names "D##" not sorted by portsort.js
|
||||
|
||||
2.029011 - 2014-10-07
|
||||
|
||||
[BUG FIXES]
|
||||
|
||||
* Fix typo in the Device By Location report template
|
||||
|
||||
2.029010 - 2014-10-07
|
||||
|
||||
[NEW FEATURES]
|
||||
|
||||
* Administration (SSH, Telnet, Web) links for devices
|
||||
* [#143] Pass parameter(s) to custom reports via bind_params config
|
||||
|
||||
[BUG FIXES]
|
||||
|
||||
* Require old DBIC version to fix deploy problem
|
||||
|
||||
2.029009 - 2014-09-27
|
||||
|
||||
[ENHANCEMENTS]
|
||||
|
||||
* Setting for items in number of records per table page menu (table_showrecordsmenu).
|
||||
* Defaults now exist for all expire tasks
|
||||
* Added expire_jobs to remove jobs queue items after 14 days
|
||||
|
||||
[BUG FIXES]
|
||||
|
||||
* Require new DBIC version to fix duplicate DB connection problem
|
||||
|
||||
2.029008 - 2014-09-23
|
||||
|
||||
[ENHANCEMENTS]
|
||||
|
||||
* [#144] Setting for items in number of records per table page menu (table_showrecordsmenu).
|
||||
|
||||
[BUG FIXES]
|
||||
|
||||
* Add Dancer import to SSHCollector Platforms
|
||||
* Add note to docs to workaround current Dancer/YAML::XS issue
|
||||
|
||||
2.029007 - 2014-09-12
|
||||
|
||||
|
||||
@@ -314,6 +314,7 @@ share/views/ajax/admintask/undiscoveredneighbors.tt
|
||||
share/views/ajax/admintask/undiscoveredneighbors_csv.tt
|
||||
share/views/ajax/admintask/userlog.tt
|
||||
share/views/ajax/admintask/users.tt
|
||||
share/views/ajax/datatabledefaults.tt
|
||||
share/views/ajax/device/addresses.tt
|
||||
share/views/ajax/device/addresses_csv.tt
|
||||
share/views/ajax/device/details.tt
|
||||
@@ -391,6 +392,7 @@ share/views/report.tt
|
||||
share/views/search.tt
|
||||
share/views/sidebar/device/netmap.tt
|
||||
share/views/sidebar/device/ports.tt
|
||||
share/views/sidebar/report/generic_report.tt
|
||||
share/views/sidebar/report/ipinventory.tt
|
||||
share/views/sidebar/report/moduleinventory.tt
|
||||
share/views/sidebar/report/netbios.tt
|
||||
|
||||
@@ -10,7 +10,7 @@ configure_requires:
|
||||
ExtUtils::MakeMaker: 6.59
|
||||
distribution_type: module
|
||||
dynamic_config: 1
|
||||
generated_by: 'Module::Install version 1.06'
|
||||
generated_by: 'Module::Install version 1.12'
|
||||
license: bsd
|
||||
meta-spec:
|
||||
url: http://module-build.sourceforge.net/META-spec-v1.4.html
|
||||
@@ -35,7 +35,7 @@ requires:
|
||||
Archive::Extract: 0
|
||||
CGI::Expand: 2.05
|
||||
DBD::Pg: 0
|
||||
DBIx::Class: 0.0825
|
||||
DBIx::Class: 0.0827
|
||||
DBIx::Class::Helpers: 2.018004
|
||||
Daemon::Control: 0.001
|
||||
Dancer: 1.3112
|
||||
@@ -71,7 +71,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
|
||||
@@ -91,4 +90,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.029007
|
||||
version: '2.029012'
|
||||
|
||||
@@ -16,7 +16,7 @@ requires 'Archive::Extract' => 0;
|
||||
requires 'CGI::Expand' => 2.05;
|
||||
requires 'Data::Printer' => 0;
|
||||
requires 'DBD::Pg' => 0;
|
||||
requires 'DBIx::Class' => 0.08250;
|
||||
requires 'DBIx::Class' => 0.08270;
|
||||
requires 'DBIx::Class::Helpers' => 2.018004;
|
||||
requires 'Daemon::Control' => 0.001000;
|
||||
requires 'Dancer' => 1.3112;
|
||||
|
||||
@@ -17,7 +17,7 @@ package Module::Install;
|
||||
# 3. The ./inc/ version of Module::Install loads
|
||||
# }
|
||||
|
||||
use 5.005;
|
||||
use 5.006;
|
||||
use strict 'vars';
|
||||
use Cwd ();
|
||||
use File::Find ();
|
||||
@@ -31,7 +31,7 @@ BEGIN {
|
||||
# This is not enforced yet, but will be some time in the next few
|
||||
# releases once we can make sure it won't clash with custom
|
||||
# Module::Install extensions.
|
||||
$VERSION = '1.06';
|
||||
$VERSION = '1.12';
|
||||
|
||||
# Storage for the pseudo-singleton
|
||||
$MAIN = undef;
|
||||
@@ -156,10 +156,10 @@ END_DIE
|
||||
sub autoload {
|
||||
my $self = shift;
|
||||
my $who = $self->_caller;
|
||||
my $cwd = Cwd::cwd();
|
||||
my $cwd = Cwd::getcwd();
|
||||
my $sym = "${who}::AUTOLOAD";
|
||||
$sym->{$cwd} = sub {
|
||||
my $pwd = Cwd::cwd();
|
||||
my $pwd = Cwd::getcwd();
|
||||
if ( my $code = $sym->{$pwd} ) {
|
||||
# Delegate back to parent dirs
|
||||
goto &$code unless $cwd eq $pwd;
|
||||
@@ -239,7 +239,7 @@ sub new {
|
||||
|
||||
# ignore the prefix on extension modules built from top level.
|
||||
my $base_path = Cwd::abs_path($FindBin::Bin);
|
||||
unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
|
||||
unless ( Cwd::abs_path(Cwd::getcwd()) eq $base_path ) {
|
||||
delete $args{prefix};
|
||||
}
|
||||
return $args{_self} if $args{_self};
|
||||
@@ -338,7 +338,7 @@ sub find_extensions {
|
||||
if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
|
||||
my $content = Module::Install::_read($subpath . '.pm');
|
||||
my $in_pod = 0;
|
||||
foreach ( split //, $content ) {
|
||||
foreach ( split /\n/, $content ) {
|
||||
$in_pod = 1 if /^=\w/;
|
||||
$in_pod = 0 if /^=cut/;
|
||||
next if ($in_pod || /^=cut/); # skip pod text
|
||||
@@ -434,7 +434,7 @@ END_OLD
|
||||
|
||||
# _version is for processing module versions (eg, 1.03_05) not
|
||||
# Perl versions (eg, 5.8.1).
|
||||
sub _version ($) {
|
||||
sub _version {
|
||||
my $s = shift || 0;
|
||||
my $d =()= $s =~ /(\.)/g;
|
||||
if ( $d >= 2 ) {
|
||||
@@ -450,12 +450,12 @@ sub _version ($) {
|
||||
return $l + 0;
|
||||
}
|
||||
|
||||
sub _cmp ($$) {
|
||||
sub _cmp {
|
||||
_version($_[1]) <=> _version($_[2]);
|
||||
}
|
||||
|
||||
# Cloned from Params::Util::_CLASS
|
||||
sub _CLASS ($) {
|
||||
sub _CLASS {
|
||||
(
|
||||
defined $_[0]
|
||||
and
|
||||
|
||||
@@ -4,7 +4,7 @@ package Module::Install::Base;
|
||||
use strict 'vars';
|
||||
use vars qw{$VERSION};
|
||||
BEGIN {
|
||||
$VERSION = '1.06';
|
||||
$VERSION = '1.12';
|
||||
}
|
||||
|
||||
# Suspend handler for "redefined" warnings
|
||||
|
||||
@@ -8,7 +8,7 @@ use Module::Install::Base ();
|
||||
|
||||
use vars qw{$VERSION @ISA $ISCORE};
|
||||
BEGIN {
|
||||
$VERSION = '1.06';
|
||||
$VERSION = '1.12';
|
||||
@ISA = 'Module::Install::Base';
|
||||
$ISCORE = 1;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use Module::Install::Base ();
|
||||
|
||||
use vars qw{$VERSION @ISA $ISCORE};
|
||||
BEGIN {
|
||||
$VERSION = '1.06';
|
||||
$VERSION = '1.12';
|
||||
@ISA = 'Module::Install::Base';
|
||||
$ISCORE = 1;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use Fcntl qw/:flock :seek/;
|
||||
|
||||
use vars qw{$VERSION @ISA $ISCORE};
|
||||
BEGIN {
|
||||
$VERSION = '1.06';
|
||||
$VERSION = '1.12';
|
||||
@ISA = 'Module::Install::Base';
|
||||
$ISCORE = 1;
|
||||
}
|
||||
@@ -133,7 +133,7 @@ sub makemaker_args {
|
||||
return $args;
|
||||
}
|
||||
|
||||
# For mm args that take multiple space-seperated args,
|
||||
# For mm args that take multiple space-separated args,
|
||||
# append an argument to the current list.
|
||||
sub makemaker_append {
|
||||
my $self = shift;
|
||||
|
||||
@@ -6,7 +6,7 @@ use Module::Install::Base ();
|
||||
|
||||
use vars qw{$VERSION @ISA $ISCORE};
|
||||
BEGIN {
|
||||
$VERSION = '1.06';
|
||||
$VERSION = '1.12';
|
||||
@ISA = 'Module::Install::Base';
|
||||
$ISCORE = 1;
|
||||
}
|
||||
@@ -347,7 +347,7 @@ sub name_from {
|
||||
^ \s*
|
||||
package \s*
|
||||
([\w:]+)
|
||||
\s* ;
|
||||
[\s|;]*
|
||||
/ixms
|
||||
) {
|
||||
my ($name, $module_name) = ($1, $1);
|
||||
@@ -705,7 +705,7 @@ sub _write_mymeta_data {
|
||||
my @yaml = Parse::CPAN::Meta::LoadFile('META.yml');
|
||||
my $meta = $yaml[0];
|
||||
|
||||
# Overwrite the non-configure dependency hashs
|
||||
# Overwrite the non-configure dependency hashes
|
||||
delete $meta->{requires};
|
||||
delete $meta->{build_requires};
|
||||
delete $meta->{recommends};
|
||||
|
||||
@@ -6,7 +6,7 @@ use Module::Install::Base ();
|
||||
|
||||
use vars qw{$VERSION @ISA $ISCORE};
|
||||
BEGIN {
|
||||
$VERSION = '1.06';
|
||||
$VERSION = '1.12';
|
||||
@ISA = 'Module::Install::Base';
|
||||
$ISCORE = 1;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use ExtUtils::Manifest ();
|
||||
|
||||
use vars qw{$VERSION @ISA $ISCORE};
|
||||
BEGIN {
|
||||
$VERSION = '1.06';
|
||||
$VERSION = '1.12';
|
||||
@ISA = 'Module::Install::Base';
|
||||
$ISCORE = 1;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use Module::Install::Base ();
|
||||
|
||||
use vars qw{$VERSION @ISA $ISCORE};
|
||||
BEGIN {
|
||||
$VERSION = '1.06';
|
||||
$VERSION = '1.12';
|
||||
@ISA = 'Module::Install::Base';
|
||||
$ISCORE = 1;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use Module::Install::Base ();
|
||||
|
||||
use vars qw{$VERSION @ISA $ISCORE};
|
||||
BEGIN {
|
||||
$VERSION = '1.06';
|
||||
$VERSION = '1.12';
|
||||
@ISA = qw{Module::Install::Base};
|
||||
$ISCORE = 1;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use strict;
|
||||
use warnings;
|
||||
use 5.010_000;
|
||||
|
||||
our $VERSION = '2.029007';
|
||||
our $VERSION = '2.029012';
|
||||
use App::Netdisco::Configuration;
|
||||
|
||||
use Module::Find ();
|
||||
@@ -123,6 +123,7 @@ install Netdisco and its dependencies into the C<netdisco> user's home area
|
||||
|
||||
su - netdisco
|
||||
curl -L http://cpanmin.us/ | perl - --notest --local-lib ~/perl5 App::Netdisco
|
||||
~/bin/localenv cpanm --notest --force Dancer@1.3126 DBIx::Class@0.08270
|
||||
|
||||
Link some of the newly installed apps into a handy location:
|
||||
|
||||
@@ -190,7 +191,11 @@ Netdisco 2, disable your system's cron jobs for the Netdisco 1.x poller.
|
||||
For further documentation on deployment, see
|
||||
L<Deployment|App::Netdisco::Manual::Deployment>.
|
||||
|
||||
=head1 Upgrading
|
||||
=head1 Upgrading from 2.x
|
||||
|
||||
If you're running a version of Netdisco prior to 2.x then you should follow
|
||||
the full installation instructions, above. This process is for upgrading
|
||||
version 2.x only.
|
||||
|
||||
Before upgrading please review the latest L<Release
|
||||
Notes|App::Netdisco::Manual::ReleaseNotes>. Then, the process is as follows:
|
||||
@@ -198,6 +203,9 @@ Notes|App::Netdisco::Manual::ReleaseNotes>. Then, the process is as follows:
|
||||
# upgrade Netdisco
|
||||
~/bin/localenv cpanm --notest App::Netdisco
|
||||
|
||||
# workaround for current upstream bug
|
||||
~/bin/localenv cpanm --notest --force Dancer@1.3126 DBIx::Class@0.08270
|
||||
|
||||
# apply database schema updates
|
||||
~/bin/netdisco-deploy
|
||||
|
||||
|
||||
@@ -40,6 +40,15 @@ sub expire {
|
||||
});
|
||||
}
|
||||
|
||||
if (setting('expire_jobs') and setting('expire_jobs') > 0) {
|
||||
schema('netdisco')->txn_do(sub {
|
||||
schema('netdisco')->resultset('Admin')->search({
|
||||
entered => \[q/< (now() - ?::interval)/,
|
||||
(setting('expire_jobs') * 86400)],
|
||||
})->delete();
|
||||
});
|
||||
}
|
||||
|
||||
return job_done("Checked expiry for all Devices and Nodes");
|
||||
}
|
||||
|
||||
|
||||
@@ -256,16 +256,21 @@ code or HTML templates. For example:
|
||||
FROM device d
|
||||
ORDER BY name
|
||||
|
||||
The C<key> of each item in the C<reports> configuration is an alias for the
|
||||
The C<tag> of each item in the C<reports> configuration is an alias for the
|
||||
report, and becomes part of the web path.
|
||||
|
||||
You can munge the data retrieved from the database by placing a Perl script
|
||||
with the same name as the C<reports> key into the C<site_plugins> directory of
|
||||
Netdisco's home area. The script can access C<$config> for its configuration
|
||||
and C<@data> for the retrieved data. It should return a list of munged data.
|
||||
with the same name as the C<reports> key into the "C<site_plugins>" directory
|
||||
of Netdisco's home area. The script can access C<$config> for its
|
||||
configuration and C<@data> for the retrieved data. It should return a list of
|
||||
munged data.
|
||||
|
||||
Within the tree you can provide each of the keys below:
|
||||
|
||||
=head4 C<tag>
|
||||
|
||||
Alias for the Report, which must be usable in a web path.
|
||||
|
||||
=head4 C<label>
|
||||
|
||||
Title for the Report.
|
||||
@@ -295,6 +300,20 @@ C<query> may not be the same as those in the web report. Set this to a list of
|
||||
the columns in C<query>. The C<columns> setting will then be used for the web
|
||||
report.
|
||||
|
||||
=head4 C<bind_params> (optional)
|
||||
|
||||
You can use placeholders in the SQL C<query> (that is, "C<?>") to bind
|
||||
user-supplied parameters. This setting should be a list of the parameters to
|
||||
pick out of the URL query string and match to the placeholders in the same
|
||||
order. For example:
|
||||
|
||||
query: |
|
||||
SELECT ... FROM ... WHERE device = ? AND port = ?
|
||||
bind-params: ['device', 'port']
|
||||
|
||||
# then
|
||||
http://localhost:5000/report/my_special_report?device=192.0.2.1&port=Vlan142
|
||||
|
||||
=head3 C<jobqueue_refresh>
|
||||
|
||||
Value: Integer Number. Default: 5.
|
||||
@@ -724,14 +743,14 @@ seconds as well as integers.
|
||||
|
||||
=head3 C<expire_devices>
|
||||
|
||||
Value: Number of Days.
|
||||
Value: Number of Days. Default: 60
|
||||
|
||||
Devices that have not been refreshed in this number of days will be removed.
|
||||
All nodes connected to this device will be removed as well.
|
||||
|
||||
=head3 C<expire_nodes>
|
||||
|
||||
Value: Number of Days.
|
||||
Value: Number of Days. Default: 90
|
||||
|
||||
Nodes that have not been refreshed in this number of days will be removed from
|
||||
the database. Archived and non-archived nodes are removed. This includes
|
||||
@@ -739,11 +758,19 @@ SwitchPort/MAC and MAC/IP mappings.
|
||||
|
||||
=head3 C<expire_nodes_archive>
|
||||
|
||||
Value: Number of Days.
|
||||
Value: Number of Days. Default: 60
|
||||
|
||||
Archived data for switch-port/MAC and MAC/IP mappings older than this number
|
||||
of days will be removed.
|
||||
|
||||
=head3 C<expire_jobs>
|
||||
|
||||
Value: Number of Days. Default: 14
|
||||
|
||||
Jobs which entered the job queue more than this many days ago will be removed
|
||||
from the queue during the scheduled expiry process (regardless of whether they
|
||||
were ever run).
|
||||
|
||||
=head3 C<dns>
|
||||
|
||||
Value: Settings Tree. Default:
|
||||
|
||||
@@ -36,6 +36,24 @@ but they are backwards compatible.
|
||||
|
||||
=back
|
||||
|
||||
=head1 2.029010
|
||||
|
||||
=head2 General Notices
|
||||
|
||||
When upgrading you will encounter a current incompatibility between Netdisco
|
||||
and one of its components. To work around this, issue the following command:
|
||||
|
||||
~/bin/localenv cpanm --notest --force Dancer@1.3126 DBIx::Class@0.08270
|
||||
|
||||
=head1 2.029008
|
||||
|
||||
=head2 General Notices
|
||||
|
||||
When upgrading you will encounter a current incompatibility between Netdisco
|
||||
and one of its components. To work around this, issue the following command:
|
||||
|
||||
~/bin/localenv cpanm --notest --force Dancer@1.3126
|
||||
|
||||
=head1 2.029002
|
||||
|
||||
=head2 General Notices
|
||||
|
||||
@@ -23,8 +23,9 @@ the same context.
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Moo;
|
||||
use Dancer ':script';
|
||||
use Expect;
|
||||
use Moo;
|
||||
|
||||
=head1 PUBLIC METHODS
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ can't be executed, falls back to the latter.
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Dancer ':script';
|
||||
use Moo;
|
||||
|
||||
=head1 PUBLIC METHODS
|
||||
|
||||
@@ -16,7 +16,6 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use Dancer ':script';
|
||||
use Data::Printer;
|
||||
use Moo;
|
||||
|
||||
=head1 PUBLIC METHODS
|
||||
|
||||
@@ -16,9 +16,8 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use Dancer ':script';
|
||||
use Data::Printer;
|
||||
use Moo;
|
||||
use Expect;
|
||||
use Moo;
|
||||
|
||||
=head1 PUBLIC METHODS
|
||||
|
||||
|
||||
@@ -16,9 +16,8 @@ use strict;
|
||||
use warnings;
|
||||
|
||||
use Dancer ':script';
|
||||
use Data::Printer;
|
||||
use Moo;
|
||||
use Expect;
|
||||
use Moo;
|
||||
|
||||
=head1 PUBLIC METHODS
|
||||
|
||||
|
||||
@@ -22,11 +22,10 @@ foreach my $report (@{setting('reports')}) {
|
||||
});
|
||||
|
||||
get "/ajax/content/report/$r" => require_login sub {
|
||||
my $rs = schema('netdisco')->resultset('Virtual::GenericReport')->result_source;
|
||||
|
||||
# TODO: this should be done by creating a new Virtual Result class on
|
||||
# the fly (package...) and then calling DBIC register_class on it.
|
||||
|
||||
my $rs = schema('netdisco')->resultset('Virtual::GenericReport')->result_source;
|
||||
$rs->view_definition($report->{query});
|
||||
$rs->remove_columns($rs->columns);
|
||||
$rs->add_columns( exists $report->{query_columns}
|
||||
@@ -35,13 +34,17 @@ foreach my $report (@{setting('reports')}) {
|
||||
);
|
||||
|
||||
my $set = schema('netdisco')->resultset('Virtual::GenericReport')
|
||||
->search(undef, {result_class => 'DBIx::Class::ResultClass::HashRefInflator'});
|
||||
->search(undef, {
|
||||
result_class => 'DBIx::Class::ResultClass::HashRefInflator',
|
||||
( (exists $report->{bind_params})
|
||||
? (bind => [map { param($_) } @{ $report->{bind_params} }]) : () ),
|
||||
});
|
||||
@data = $set->all;
|
||||
|
||||
# Data Munging support...
|
||||
|
||||
my $compartment = Safe->new;
|
||||
$config = $report;
|
||||
$config = $report; # closure for the config of this report
|
||||
$compartment->share(qw/$config @data/);
|
||||
$compartment->permit_only(qw/:default sort/);
|
||||
|
||||
|
||||
@@ -169,15 +169,23 @@ register 'register_report' => sub {
|
||||
return error "bad config to register_report";
|
||||
}
|
||||
|
||||
foreach my $item (@{setting('_reports_menu')->{ $config->{category} }}) {
|
||||
if ($item eq $config->{tag}) {
|
||||
setting('_reports')->{$config->{tag}} = $config;
|
||||
return;
|
||||
}
|
||||
if (0 == scalar grep {$_ eq $config->{tag}}
|
||||
@{setting('_reports_menu')->{ $config->{category} }}) {
|
||||
push @{setting('_reports_menu')->{ $config->{category} }}, $config->{tag};
|
||||
}
|
||||
|
||||
push @{setting('_reports_menu')->{ $config->{category} }}, $config->{tag};
|
||||
setting('_reports')->{$config->{tag}} = $config;
|
||||
foreach my $tag (@{setting('_reports_menu')->{ $config->{category} }}) {
|
||||
if ($config->{tag} eq $tag) {
|
||||
setting('_reports')->{$tag} = $config;
|
||||
|
||||
foreach my $rconfig (@{setting('reports')}) {
|
||||
if ($rconfig->{tag} eq $tag) {
|
||||
setting('_reports')->{$tag}->{'rconfig'} = $rconfig;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
register_plugin;
|
||||
|
||||
@@ -130,9 +130,10 @@ nbtstat_only: []
|
||||
nbtstat_max_age: 7
|
||||
nbtstat_interval: 0.02
|
||||
nbtstat_timeout: 1
|
||||
expire_devices: 0
|
||||
expire_nodes: 0
|
||||
expire_nodes_archive: 0
|
||||
expire_devices: 60
|
||||
expire_nodes: 90
|
||||
expire_nodes_archive: 60
|
||||
expire_jobs: 14
|
||||
store_wireless_clients: true
|
||||
store_modules: true
|
||||
ignore_interfaces:
|
||||
|
||||
@@ -24,45 +24,53 @@
|
||||
* See: http://js-naturalsort.googlecode.com/svn/trunk/naturalSort.js
|
||||
*/
|
||||
function portSort (a, b) {
|
||||
var re = /(^(-?\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,
|
||||
var re = /(^0x[0-9a-f]+$|[0-9]+)/gi,
|
||||
// string regex
|
||||
sre = /(^[ ]*|[ ]*$)/g,
|
||||
sre = /(^[ ]*|[ ]*$)/g,
|
||||
// octal regex
|
||||
ore = /^0/,
|
||||
// convert all to strings and trim()
|
||||
x = a.toString().replace(sre, '') || '',
|
||||
y = b.toString().replace(sre, '') || '';
|
||||
// hack for foundry "10GigabitEthernet" -> cisco-like "TenGigabitEthernet"
|
||||
x = x.replace(/^10GigabitEthernet/, 'GigabitEthernet');
|
||||
y = y.replace(/^10GigabitEthernet/, 'GigabitEthernet');
|
||||
// chunk/tokenize
|
||||
var xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
|
||||
yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0');
|
||||
for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
|
||||
// find floats not starting with '0', string or 0 if not defined (Clint Priest)
|
||||
var oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
|
||||
var oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
|
||||
// handle numeric vs string comparison - number < string - (Kyle Adams)
|
||||
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) return (isNaN(oFxNcL)) ? 1 : -1;
|
||||
// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
|
||||
else if (typeof oFxNcL !== typeof oFyNcL) {
|
||||
oFxNcL += '';
|
||||
oFyNcL += '';
|
||||
}
|
||||
if (oFxNcL < oFyNcL) return -1;
|
||||
if (oFxNcL > oFyNcL) return 1;
|
||||
}
|
||||
return 0;
|
||||
ore = /^0/,
|
||||
// convert all to strings and trim()
|
||||
x = a.toString().replace(sre, '') || '',
|
||||
y = b.toString().replace(sre, '') || '';
|
||||
|
||||
// hack for foundry "10GigabitEthernet" -> cisco-like "TenGigabitEthernet"
|
||||
x = x.replace(/^10GigabitEthernet/, 'GigabitEthernet');
|
||||
y = y.replace(/^10GigabitEthernet/, 'GigabitEthernet');
|
||||
|
||||
// chunk/tokenize
|
||||
var xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
|
||||
yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0');
|
||||
|
||||
for (var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
|
||||
// find floats not starting with '0', string or 0 if not defined (Clint Priest)
|
||||
var oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
|
||||
var oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
|
||||
|
||||
// handle numeric vs string comparison - number < string - (Kyle Adams)
|
||||
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
|
||||
return (isNaN(oFxNcL)) ? 1 : -1;
|
||||
}
|
||||
// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
|
||||
else if (typeof oFxNcL !== typeof oFyNcL) {
|
||||
oFxNcL += '';
|
||||
oFyNcL += '';
|
||||
}
|
||||
|
||||
if (oFxNcL < oFyNcL) { return -1; }
|
||||
if (oFxNcL > oFyNcL) { return 1; }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
|
||||
"portsort-asc": function ( a, b ) {
|
||||
return portSort(a,b);
|
||||
},
|
||||
"portsort-asc": function ( a, b ) {
|
||||
return portSort(a,b);
|
||||
},
|
||||
|
||||
"portsort-desc": function ( a, b ) {
|
||||
return portSort(a,b) * -1;
|
||||
}
|
||||
"portsort-desc": function ( a, b ) {
|
||||
return portSort(a,b) * -1;
|
||||
}
|
||||
} );
|
||||
|
||||
}());
|
||||
|
||||
@@ -80,6 +80,17 @@
|
||||
[% END %]
|
||||
</tr>
|
||||
[% END %]
|
||||
<tr>
|
||||
<td>Administration</td>
|
||||
<td>
|
||||
<a href="ssh://[% d.ip | html_entity %]" target="_blank">
|
||||
<span class="label label-info"><i class="icon-keyboard"></i> SSH</span></a>
|
||||
<a href="telnet://[% d.ip | html_entity %]" target="_blank">
|
||||
<span class="label label-info"><i class="icon-keyboard"></i> Telnet</span></a>
|
||||
<a href="https://[% d.ip | html_entity %]/" target="_blank">
|
||||
<span class="label label-info"><i class="icon-external-link"></i> Web</span></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Uptime</td>
|
||||
<td>[% d.uptime_age | html_entity %]</td>
|
||||
|
||||
@@ -48,7 +48,7 @@ $(document).ready(function() {
|
||||
return '<a href="[% search_device %]&q=' + encodeURIComponent(data) + '&model=' + encodeURIComponent(data) + '">' + he.encode(data || '') + '</a>';
|
||||
}
|
||||
}
|
||||
].
|
||||
],
|
||||
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
|
||||
});
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
[% INCLUDE "sidebar/report/${report.tag}.tt" %]
|
||||
[% CATCH %]
|
||||
<script type="text/javascript">has_sidebar["[% report.tag %]"] = 0;</script>
|
||||
[% INCLUDE "sidebar/report/generic_report.tt" %]
|
||||
[% END %]
|
||||
</form>
|
||||
</div> <!-- /tab-pane -->
|
||||
|
||||
4
Netdisco/share/views/sidebar/report/generic_report.tt
Normal file
4
Netdisco/share/views/sidebar/report/generic_report.tt
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
[% FOREACH k IN report.rconfig.bind_params %]
|
||||
<input name="[% k %]" value="[% params.$k | html_entity %]" type="hidden"/>
|
||||
[% END %]
|
||||
@@ -13,5 +13,6 @@ BEGIN {
|
||||
|
||||
is(sort_port(1,1), 0, 'number - same values');
|
||||
is(sort_port('1:2','1:10'), -1, 'colon number (Extreme) - first lesser');
|
||||
is(sort_port('D1','D10'), -1, 'HP - simple letter and number [#152]');
|
||||
|
||||
done_testing;
|
||||
|
||||
@@ -1,188 +1,200 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>portsort.js test suite</title>
|
||||
<script src="http://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
|
||||
<script src="http://code.jquery.com/qunit/qunit-1.14.0.js" type="text/javascript"></script>
|
||||
<meta charset="utf-8">
|
||||
<title>portsort.js test suite</title>
|
||||
<script src="http://code.jquery.com/jquery-1.11.1.min.js" type="text/javascript"></script>
|
||||
<script src="http://code.jquery.com/qunit/qunit-1.14.0.js" type="text/javascript"></script>
|
||||
<script src="../js/qunit-tap.js" type="text/javascript"></script>
|
||||
<script>
|
||||
qunitTap(QUnit, function() { console.log.apply(console, arguments); });
|
||||
</script>
|
||||
<link href="http://code.jquery.com/qunit/qunit-1.14.0.css" type="text/css" rel="stylesheet"></link>
|
||||
<script src="../../share/public/javascripts/jquery.dataTables.min.js" type="text/javascript"></script>
|
||||
<script src="../../share/public/javascripts/portsort.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
module("portsort.js"),
|
||||
test("different values types", function () {
|
||||
wrapTest(
|
||||
['a',1],
|
||||
[1,'a'],
|
||||
'number always comes first');
|
||||
wrapTest(
|
||||
['1',1],
|
||||
['1',1],
|
||||
'number vs numeric string - should remain unchanged (error in chrome)');
|
||||
wrapTest(
|
||||
['02',3,2,'01'],
|
||||
['01','02',2,3],
|
||||
'padding numeric string vs number');
|
||||
});
|
||||
test("numerics", function () {
|
||||
wrapTest(
|
||||
['10',9,2,'1','4'],
|
||||
['1',2,'4',9,'10'],
|
||||
'string vs number');
|
||||
wrapTest(
|
||||
['0001','002','001'],
|
||||
['0001','001','002'],
|
||||
'0 left-padded numbers');
|
||||
wrapTest(
|
||||
[2,1,'1','0001','002','02','001'],
|
||||
['0001','001','002','02',1,'1',2],
|
||||
'0 left-padded numbers and regular numbers');
|
||||
wrapTest(
|
||||
['10.0401',10.022,10.042,'10.021999'],
|
||||
['10.021999',10.022,'10.0401',10.042],
|
||||
'decimal string vs decimal, different precision');
|
||||
wrapTest(
|
||||
['10.04',10.02,10.03,'10.01'],
|
||||
['10.01',10.02,10.03,'10.04'],
|
||||
'decimal string vs decimal, same precision');
|
||||
wrapTest(
|
||||
['10001','10011','101','10010','10','100','10002',
|
||||
'10112','10111'],
|
||||
['10','100','101','10001','10002','10010','10011',
|
||||
'10111','10112'],
|
||||
'mixed length');
|
||||
});
|
||||
test("IP addresses", function () {
|
||||
wrapTest(
|
||||
[
|
||||
'192.168.0.100',
|
||||
'192.168.0.1',
|
||||
'192.168.1.1',
|
||||
'192.168.0.250',
|
||||
'192.168.1.123',
|
||||
'10.0.0.2',
|
||||
'10.0.0.1'
|
||||
],
|
||||
[
|
||||
'10.0.0.1',
|
||||
'10.0.0.2',
|
||||
'192.168.0.1',
|
||||
'192.168.0.100',
|
||||
'192.168.0.250',
|
||||
'192.168.1.1',
|
||||
'192.168.1.123'
|
||||
]);
|
||||
});
|
||||
test("space(s) as first character(s)", function () {
|
||||
wrapTest(
|
||||
['alpha',' 1',' 3',' 2',0],
|
||||
[0,' 1',' 2',' 3','alpha']);
|
||||
});
|
||||
test("wireless controllers", function () {
|
||||
wrapTest(
|
||||
[
|
||||
'00:14:0e:12:34:56','00:08:30:01:23:45.1',
|
||||
<link href="http://code.jquery.com/qunit/qunit-1.14.0.css" type="text/css" rel="stylesheet"></link>
|
||||
<script src="../../share/public/javascripts/jquery.dataTables.min.js" type="text/javascript"></script>
|
||||
<script src="../../share/public/javascripts/portsort.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
module("portsort.js"),
|
||||
test("different values types", function () {
|
||||
wrapTest(
|
||||
['a',1],
|
||||
[1,'a'],
|
||||
'number always comes first');
|
||||
wrapTest(
|
||||
['1',1],
|
||||
['1',1],
|
||||
'number vs numeric string - should remain unchanged (error in chrome)');
|
||||
wrapTest(
|
||||
['02',3,2,'01'],
|
||||
['01','02',2,3],
|
||||
'padding numeric string vs number');
|
||||
});
|
||||
test("numerics", function () {
|
||||
wrapTest(
|
||||
['10',9,2,'1','4'],
|
||||
['1',2,'4',9,'10'],
|
||||
'string vs number');
|
||||
wrapTest(
|
||||
['0001','002','001'],
|
||||
['0001','001','002'],
|
||||
'0 left-padded numbers');
|
||||
wrapTest(
|
||||
[2,1,'1','0001','002','02','001'],
|
||||
['0001','001','002','02',1,'1',2],
|
||||
'0 left-padded numbers and regular numbers');
|
||||
wrapTest(
|
||||
['10.0401',10.022,10.042,'10.021999'],
|
||||
['10.021999',10.022,'10.0401',10.042],
|
||||
'decimal string vs decimal, different precision');
|
||||
wrapTest(
|
||||
['10.04',10.02,10.03,'10.01'],
|
||||
['10.01',10.02,10.03,'10.04'],
|
||||
'decimal string vs decimal, same precision');
|
||||
wrapTest(
|
||||
['10001','10011','101','10010','10','100','10002',
|
||||
'10112','10111'],
|
||||
['10','100','101','10001','10002','10010','10011',
|
||||
'10111','10112'],
|
||||
'mixed length');
|
||||
});
|
||||
test("IP addresses", function () {
|
||||
wrapTest(
|
||||
[
|
||||
'192.168.0.100',
|
||||
'192.168.0.1',
|
||||
'192.168.1.1',
|
||||
'192.168.0.250',
|
||||
'192.168.1.123',
|
||||
'10.0.0.2',
|
||||
'10.0.0.1'
|
||||
],
|
||||
[
|
||||
'10.0.0.1',
|
||||
'10.0.0.2',
|
||||
'192.168.0.1',
|
||||
'192.168.0.100',
|
||||
'192.168.0.250',
|
||||
'192.168.1.1',
|
||||
'192.168.1.123'
|
||||
]);
|
||||
});
|
||||
test("space(s) as first character(s)", function () {
|
||||
wrapTest(
|
||||
['alpha',' 1',' 3',' 2',0],
|
||||
[0,' 1',' 2',' 3','alpha']);
|
||||
});
|
||||
test("wireless controllers", function () {
|
||||
wrapTest(
|
||||
[
|
||||
'00:14:0e:12:34:56','00:08:30:01:23:45.1',
|
||||
'00:15:c7:ab:23:10.0','00:14:0e:01:23:45',
|
||||
'00:08:30:01:23:45.0','00:15:c7:ab:23:00.1'
|
||||
],
|
||||
[
|
||||
'00:08:30:01:23:45.0','00:08:30:01:23:45.1',
|
||||
],
|
||||
[
|
||||
'00:08:30:01:23:45.0','00:08:30:01:23:45.1',
|
||||
'00:14:0e:01:23:45','00:14:0e:12:34:56',
|
||||
'00:15:c7:ab:23:00.1','00:15:c7:ab:23:10.0'
|
||||
],'ap ports');
|
||||
wrapTest(
|
||||
[
|
||||
'wlan-controller1/0.104','wlan-controller1/0',
|
||||
'wlan-controller1/0.252','wlan-controller1/0.103'
|
||||
],
|
||||
[
|
||||
'wlan-controller1/0','wlan-controller1/0.103',
|
||||
],'ap ports');
|
||||
wrapTest(
|
||||
[
|
||||
'wlan-controller1/0.104','wlan-controller1/0',
|
||||
'wlan-controller1/0.252','wlan-controller1/0.103'
|
||||
],
|
||||
[
|
||||
'wlan-controller1/0','wlan-controller1/0.103',
|
||||
'wlan-controller1/0.104','wlan-controller1/0.252'
|
||||
],'controller ports');
|
||||
});
|
||||
test("ports", function () {
|
||||
wrapTest(
|
||||
[
|
||||
'1.1','1.13','1.14','1.19','1.2','Vlan318','1.25',
|
||||
'1.29','3.12','1.3','1.37','1.38','1.4','1.43',
|
||||
'1.6','8.34'
|
||||
],
|
||||
[
|
||||
'1.1','1.2','1.3','1.4','1.6','1.13','1.14','1.19',
|
||||
'1.25','1.29','1.37','1.38','1.43','3.12','8.34',
|
||||
'Vlan318'
|
||||
],'Avaya');
|
||||
wrapTest(
|
||||
[
|
||||
'GigabitEthernet9/0/12',
|
||||
'GigabitEthernet9/0/11',
|
||||
'GigabitEthernet1/0/14',
|
||||
'GigabitEthernet1/1/12',
|
||||
],
|
||||
[
|
||||
'GigabitEthernet1/0/14',
|
||||
'GigabitEthernet1/1/12',
|
||||
'GigabitEthernet9/0/11',
|
||||
'GigabitEthernet9/0/12',
|
||||
],'Cisco');
|
||||
wrapTest(
|
||||
[
|
||||
],'controller ports');
|
||||
});
|
||||
test("ports", function () {
|
||||
wrapTest(
|
||||
[
|
||||
'1.1','1.13','1.14','1.19','1.2','Vlan318','1.25',
|
||||
'1.29','3.12','1.3','1.37','1.38','1.4','1.43',
|
||||
'1.6','8.34'
|
||||
],
|
||||
[
|
||||
'1.1','1.2','1.3','1.4','1.6','1.13','1.14','1.19',
|
||||
'1.25','1.29','1.37','1.38','1.43','3.12','8.34',
|
||||
'Vlan318'
|
||||
],'Avaya');
|
||||
wrapTest(
|
||||
[
|
||||
'GigabitEthernet9/0/12',
|
||||
'GigabitEthernet9/0/11',
|
||||
'GigabitEthernet1/0/14',
|
||||
'GigabitEthernet1/1/12',
|
||||
],
|
||||
[
|
||||
'GigabitEthernet1/0/14',
|
||||
'GigabitEthernet1/1/12',
|
||||
'GigabitEthernet9/0/11',
|
||||
'GigabitEthernet9/0/12',
|
||||
],'Cisco');
|
||||
wrapTest(
|
||||
[
|
||||
'1/1/1','0/1/1','0/3/20','0/2/1','0/3/1','0/3/2',
|
||||
'0/3/11','0/3/10'
|
||||
'0/3/11','0/3/10'
|
||||
|
||||
],[
|
||||
],[
|
||||
'0/1/1','0/2/1','0/3/1','0/3/2','0/3/10','0/3/11',
|
||||
'0/3/20','1/1/1'
|
||||
],'Dell');
|
||||
wrapTest(
|
||||
[
|
||||
],'Dell');
|
||||
wrapTest(
|
||||
[
|
||||
'1:10','1:2','1:1','1:11'
|
||||
|
||||
],[
|
||||
],[
|
||||
'1:1','1:2','1:10','1:11'
|
||||
],'Extreme');
|
||||
wrapTest(
|
||||
[
|
||||
'10GigabitEthernet1/1/12',
|
||||
'GigabitEthernet1/0/14',
|
||||
'GigabitEthernet9/0/12',
|
||||
'10GigabitEthernet9/0/11',
|
||||
],[
|
||||
'GigabitEthernet1/0/14',
|
||||
'10GigabitEthernet1/1/12',
|
||||
'10GigabitEthernet9/0/11',
|
||||
'GigabitEthernet9/0/12',
|
||||
],'Foundry 10Gb');
|
||||
wrapTest(
|
||||
[
|
||||
'Slot: 1 Port: 2 Gigabit - Level',
|
||||
],'Extreme');
|
||||
wrapTest(
|
||||
[
|
||||
'D10','D11','D2','D1', 'A30', 'A3'
|
||||
],[
|
||||
'A3', 'A30', 'D1','D2','D10','D11'
|
||||
],'HP A & D');
|
||||
wrapTest(
|
||||
[
|
||||
'B10','B11','B2','B1', 'A30', 'A3'
|
||||
],[
|
||||
'A3', 'A30', 'B1','B2','B10','B11'
|
||||
],'HP A & B');
|
||||
wrapTest(
|
||||
[
|
||||
'10GigabitEthernet1/1/12',
|
||||
'GigabitEthernet1/0/14',
|
||||
'GigabitEthernet9/0/12',
|
||||
'10GigabitEthernet9/0/11',
|
||||
],[
|
||||
'GigabitEthernet1/0/14',
|
||||
'10GigabitEthernet1/1/12',
|
||||
'10GigabitEthernet9/0/11',
|
||||
'GigabitEthernet9/0/12',
|
||||
],'Foundry 10Gb');
|
||||
wrapTest(
|
||||
[
|
||||
'Slot: 1 Port: 2 Gigabit - Level',
|
||||
'Slot: 1 Port: 1 Gigabit - Level',
|
||||
'Slot: 0 Port: 15 Gigabit - Level',
|
||||
'Slot: 1 Port: 10 Gigabit - Level',
|
||||
'Slot: 0 Port: 15 Gigabit - Level',
|
||||
'Slot: 1 Port: 10 Gigabit - Level',
|
||||
'Slot: 0 Port: 1 Gigabit - Level'
|
||||
],[
|
||||
],[
|
||||
'Slot: 0 Port: 1 Gigabit - Level',
|
||||
'Slot: 0 Port: 15 Gigabit - Level',
|
||||
'Slot: 0 Port: 15 Gigabit - Level',
|
||||
'Slot: 1 Port: 1 Gigabit - Level',
|
||||
'Slot: 1 Port: 2 Gigabit - Level',
|
||||
'Slot: 1 Port: 10 Gigabit - Level'
|
||||
],'Netgear');
|
||||
wrapTest(
|
||||
[
|
||||
'Slot: 1 Port: 2 Gigabit - Level',
|
||||
'Slot: 1 Port: 10 Gigabit - Level'
|
||||
],'Netgear');
|
||||
wrapTest(
|
||||
[
|
||||
'port-channel190','port-channel19',
|
||||
'port-channel1044','port-channel2','port-channel104'
|
||||
'port-channel1044','port-channel2','port-channel104'
|
||||
|
||||
],[
|
||||
],[
|
||||
'port-channel2','port-channel19','port-channel104',
|
||||
'port-channel190','port-channel1044'
|
||||
],'port-channel');
|
||||
wrapTest(
|
||||
[
|
||||
'port-channel190','port-channel1044'
|
||||
],'port-channel');
|
||||
wrapTest(
|
||||
[
|
||||
'Serial1/1:5',
|
||||
'Serial2/0:5-Bearer Channel',
|
||||
'Serial2/0:20',
|
||||
@@ -191,7 +203,7 @@
|
||||
'Serial2/0:21',
|
||||
'Serial2/0:5',
|
||||
'Serial2/0:20-Bearer Channel'
|
||||
],[
|
||||
],[
|
||||
'Serial1/1:0',
|
||||
'Serial1/1:5',
|
||||
'Serial1/1:5-Bearer Channel',
|
||||
@@ -200,41 +212,41 @@
|
||||
'Serial2/0:20',
|
||||
'Serial2/0:20-Bearer Channel',
|
||||
'Serial2/0:21'
|
||||
],'serial');
|
||||
wrapTest(
|
||||
[
|
||||
],'serial');
|
||||
wrapTest(
|
||||
[
|
||||
'unrouted VLAN 990','unrouted VLAN 95',
|
||||
'unrouted VLAN 985','unrouted VLAN 99',
|
||||
'unrouted VLAN 950'
|
||||
'unrouted VLAN 985','unrouted VLAN 99',
|
||||
'unrouted VLAN 950'
|
||||
|
||||
],[
|
||||
],[
|
||||
'unrouted VLAN 95','unrouted VLAN 99',
|
||||
'unrouted VLAN 950','unrouted VLAN 985',
|
||||
'unrouted VLAN 990'
|
||||
],'unrouted vlans');
|
||||
wrapTest(
|
||||
[
|
||||
'unrouted VLAN 950','unrouted VLAN 985',
|
||||
'unrouted VLAN 990'
|
||||
],'unrouted vlans');
|
||||
wrapTest(
|
||||
[
|
||||
'Vlan10','Vlan910','Vlan1','Vlan91'
|
||||
],[
|
||||
],[
|
||||
'Vlan1','Vlan10','Vlan91','Vlan910'
|
||||
],'vlans');
|
||||
wrapTest(
|
||||
[
|
||||
],'vlans');
|
||||
wrapTest(
|
||||
[
|
||||
'voice-port 2/10','voice-port 2/1','voice-port 2/2',
|
||||
'voice-port 2/11'
|
||||
],[
|
||||
'voice-port 2/11'
|
||||
],[
|
||||
'voice-port 2/1','voice-port 2/2','voice-port 2/10',
|
||||
'voice-port 2/11',
|
||||
'voice-port 2/11',
|
||||
|
||||
],'voice-port');
|
||||
});
|
||||
],'voice-port');
|
||||
});
|
||||
|
||||
});
|
||||
var sortFn = jQuery.fn.dataTableExt.oSort["portsort-asc"];
|
||||
function wrapTest(origArray, sortArray, message) {
|
||||
deepEqual($.extend([], origArray).sort(sortFn), sortArray, (message ? message + ' - ' : '') + QUnit.jsDump.parse(origArray));
|
||||
};
|
||||
</script>
|
||||
});
|
||||
var sortFn = jQuery.fn.dataTableExt.oSort["portsort-asc"];
|
||||
function wrapTest(origArray, sortArray, message) {
|
||||
deepEqual($.extend([], origArray).sort(sortFn), sortArray, (message ? message + ' - ' : '') + QUnit.jsDump.parse(origArray));
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="qunit"></div>
|
||||
|
||||
Reference in New Issue
Block a user