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

This commit is contained in:
Oliver Gorwits
2014-10-11 12:03:36 +01:00
33 changed files with 434 additions and 284 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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'

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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};

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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:

View File

@@ -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

View File

@@ -23,8 +23,9 @@ the same context.
use strict;
use warnings;
use Moo;
use Dancer ':script';
use Expect;
use Moo;
=head1 PUBLIC METHODS

View File

@@ -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

View File

@@ -16,7 +16,6 @@ use strict;
use warnings;
use Dancer ':script';
use Data::Printer;
use Moo;
=head1 PUBLIC METHODS

View File

@@ -16,9 +16,8 @@ use strict;
use warnings;
use Dancer ':script';
use Data::Printer;
use Moo;
use Expect;
use Moo;
=head1 PUBLIC METHODS

View File

@@ -16,9 +16,8 @@ use strict;
use warnings;
use Dancer ':script';
use Data::Printer;
use Moo;
use Expect;
use Moo;
=head1 PUBLIC METHODS

View File

@@ -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/);

View File

@@ -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;

View File

@@ -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:

View File

@@ -24,7 +24,7 @@
* 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,
// octal regex
@@ -32,26 +32,34 @@ function portSort (a, b) {
// 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++) {
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;
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;
if (oFxNcL < oFyNcL) { return -1; }
if (oFxNcL > oFyNcL) { return 1; }
}
return 0;
}

View File

@@ -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>

View File

@@ -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' -%]
});

View File

@@ -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 -->

View File

@@ -0,0 +1,4 @@
[% FOREACH k IN report.rconfig.bind_params %]
<input name="[% k %]" value="[% params.$k | html_entity %]" type="hidden"/>
[% END %]

View File

@@ -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;

View File

@@ -146,6 +146,18 @@
],[
'1:1','1:2','1:10','1:11'
],'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',