Merge branch 'master' of ssh://git.code.sf.net/p/netdisco/netdisco-ng
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
2.029015
|
||||
|
||||
[NEW FEATURES]
|
||||
|
||||
* [#4] Allow comment on device port in the log, for any user
|
||||
* [#18] Inventory by Model by OS Report
|
||||
|
||||
[ENHANCEMENTS]
|
||||
|
||||
* Request net-snmp-devel on Fedora/Red-Hat builds
|
||||
@@ -10,6 +15,9 @@
|
||||
|
||||
* Fix for node search on some formats of IPv6 addr being seen as MAC
|
||||
* [#190] Ignore entries in the discover form that don't look like IP/hostname
|
||||
* Delete all job queue entries (regardless of status) when deleting device
|
||||
* [#15] Undiscovered Neighbor report JOIN fixed, and updated to include
|
||||
the ports where Macsuck saw the MAC address of a known Device
|
||||
|
||||
2.029014 - 2014-11-19
|
||||
|
||||
|
||||
@@ -201,6 +201,7 @@ lib/App/Netdisco/Web/Plugin/Report/DeviceDnsMismatch.pm
|
||||
lib/App/Netdisco/Web/Plugin/Report/DevicePoeStatus.pm
|
||||
lib/App/Netdisco/Web/Plugin/Report/DuplexMismatch.pm
|
||||
lib/App/Netdisco/Web/Plugin/Report/HalfDuplex.pm
|
||||
lib/App/Netdisco/Web/Plugin/Report/InventoryByModelByOS.pm
|
||||
lib/App/Netdisco/Web/Plugin/Report/IpInventory.pm
|
||||
lib/App/Netdisco/Web/Plugin/Report/ModuleInventory.pm
|
||||
lib/App/Netdisco/Web/Plugin/Report/Netbios.pm
|
||||
@@ -341,6 +342,7 @@ share/views/ajax/report/generic_report.tt
|
||||
share/views/ajax/report/generic_report_csv.tt
|
||||
share/views/ajax/report/halfduplex.tt
|
||||
share/views/ajax/report/halfduplex_csv.tt
|
||||
share/views/ajax/report/inventorybymodelbyos.tt
|
||||
share/views/ajax/report/ipinventory.tt
|
||||
share/views/ajax/report/ipinventory_csv.tt
|
||||
share/views/ajax/report/moduleinventory.tt
|
||||
|
||||
@@ -7,11 +7,11 @@ build_requires:
|
||||
ExtUtils::MakeMaker: 6.59
|
||||
Test::More: 0.88
|
||||
configure_requires:
|
||||
DBIx::Class: 0.082801
|
||||
DBIx::Class: '0.082801'
|
||||
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
|
||||
@@ -39,7 +39,7 @@ requires:
|
||||
DBIx::Class: 0.08281
|
||||
DBIx::Class::Helpers: 2.024
|
||||
Daemon::Control: 0.001006
|
||||
Dancer: 1.3132
|
||||
Dancer: '1.3132'
|
||||
Dancer::Plugin::Auth::Extensible: 0.3
|
||||
Dancer::Plugin::DBIC: 0.2001
|
||||
Dancer::Plugin::Passphrase: 2.0.1
|
||||
@@ -68,7 +68,7 @@ requires:
|
||||
Plack::Middleware::ReverseProxy: 0.15
|
||||
Role::Tiny: 1.002005
|
||||
SNMP::Info: 3.18
|
||||
SQL::Translator: 0.11018
|
||||
SQL::Translator: '0.11018'
|
||||
Sereal: 0
|
||||
Socket6: 0.23
|
||||
Starman: 0.4008
|
||||
@@ -91,4 +91,4 @@ resources:
|
||||
homepage: http://netdisco.org/
|
||||
license: http://opensource.org/licenses/bsd-license.php
|
||||
repository: git://git.code.sf.net/p/netdisco/netdisco-ng
|
||||
version: 2.029014
|
||||
version: '2.029014'
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -160,6 +160,16 @@ __PACKAGE__->has_many( active_nodes_with_age => 'App::Netdisco::DB::Result::Virt
|
||||
cascade_copy => 0, cascade_update => 0, cascade_delete => 0 },
|
||||
);
|
||||
|
||||
=head2 logs
|
||||
|
||||
Returns the set of C<device_port_log> entries associated with this Port.
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->has_many( logs => 'App::Netdisco::DB::Result::DevicePortLog',
|
||||
{ 'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port' },
|
||||
);
|
||||
|
||||
=head2 power
|
||||
|
||||
Returns a row from the C<device_port_power> table if one refers to this
|
||||
@@ -345,4 +355,16 @@ Returns the C<mac> column instantiated into a L<NetAddr::MAC> object.
|
||||
|
||||
sub net_mac { return NetAddr::MAC->new(mac => (shift)->mac) }
|
||||
|
||||
=head2 last_comment
|
||||
|
||||
Returns the most recent comment from the logs for this device port.
|
||||
|
||||
=cut
|
||||
|
||||
sub last_comment {
|
||||
my $row = (shift)->logs->search(undef,
|
||||
{ order_by => { -desc => 'creation' }, rows => 1 })->first;
|
||||
return ($row ? $row->log : '');
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -22,14 +22,17 @@ __PACKAGE__->result_source_instance->view_definition(<<'ENDSQL');
|
||||
a.log,
|
||||
a.finished
|
||||
FROM device_port p
|
||||
JOIN device d ON d.ip = p.ip
|
||||
JOIN ADMIN a ON p.remote_ip = a.device
|
||||
WHERE p.remote_ip NOT IN
|
||||
(SELECT ALIAS
|
||||
FROM device_ip)
|
||||
AND a.action = 'discover'
|
||||
ORDER BY p.remote_ip,
|
||||
a.finished DESC
|
||||
JOIN device d
|
||||
ON d.ip = p.ip
|
||||
LEFT JOIN admin a
|
||||
ON (p.remote_ip = a.device AND a.action = 'discover')
|
||||
WHERE
|
||||
(p.remote_ip NOT IN (SELECT alias FROM device_ip))
|
||||
OR
|
||||
((p.remote_ip IS NULL) AND p.is_uplink)
|
||||
ORDER BY
|
||||
p.remote_ip ASC,
|
||||
a.finished DESC
|
||||
ENDSQL
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
|
||||
@@ -594,7 +594,6 @@ sub delete {
|
||||
|
||||
$schema->resultset('Admin')->search({
|
||||
device => { '-in' => $devices->as_query },
|
||||
action => { '-like' => 'queued%' },
|
||||
})->delete;
|
||||
|
||||
$schema->resultset('Topology')->search({
|
||||
|
||||
@@ -157,6 +157,7 @@ sub delete {
|
||||
DevicePortVlan
|
||||
DevicePortWireless
|
||||
DevicePortSsid
|
||||
DevicePortLog
|
||||
/) {
|
||||
$schema->resultset($set)->search(
|
||||
{ ip => { '-in' => $ports->as_query }},
|
||||
|
||||
@@ -14,6 +14,7 @@ hook 'before' => sub {
|
||||
|
||||
my @default_port_columns_right = (
|
||||
{ name => 'c_descr', label => 'Description', default => '' },
|
||||
{ name => 'c_comment', label => 'Last Comment', default => '' },
|
||||
{ name => 'c_type', label => 'Type', default => '' },
|
||||
{ name => 'c_duplex', label => 'Duplex', default => '' },
|
||||
{ name => 'c_lastchange', label => 'Last Change', default => '' },
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package App::Netdisco::Web::Plugin::Report::InventoryByModelByOS;
|
||||
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
|
||||
use App::Netdisco::Web::Plugin;
|
||||
|
||||
register_report(
|
||||
{ category => 'Device',
|
||||
tag => 'inventorybymodelbyos',
|
||||
label => 'Inventory by Model by OS',
|
||||
provides_csv => 0,
|
||||
}
|
||||
);
|
||||
|
||||
get '/ajax/content/report/inventorybymodelbyos' => require_login sub {
|
||||
my @results = schema('netdisco')->resultset('Device')->search(undef, {
|
||||
columns => [qw/vendor model os os_ver/],
|
||||
select => [ { count => 'os_ver' } ],
|
||||
as => [qw/ os_ver_count /],
|
||||
group_by => [qw/ vendor model os os_ver /],
|
||||
order_by => ['vendor', 'model', { -desc => 'count' }, 'os_ver'],
|
||||
})->hri->all;
|
||||
|
||||
template 'ajax/report/inventorybymodelbyos.tt', { results => \@results, },
|
||||
{ layout => undef };
|
||||
};
|
||||
|
||||
1;
|
||||
@@ -14,6 +14,32 @@ register_report({
|
||||
hidden => true,
|
||||
});
|
||||
|
||||
sub _sanity_ok {
|
||||
return 0 unless
|
||||
param('ip') =~ m/^[[:print:]]+$/
|
||||
and param('port') =~ m/^[[:print:]]+$/
|
||||
and param('log') =~ m/^[[:print:]]+$/;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
ajax '/ajax/control/report/portlog/add' => require_login sub {
|
||||
send_error('Bad Request', 400) unless _sanity_ok();
|
||||
|
||||
schema('netdisco')->txn_do(sub {
|
||||
my $user = schema('netdisco')->resultset('DevicePortLog')
|
||||
->create({
|
||||
ip => param('ip'),
|
||||
port => param('port'),
|
||||
reason => 'other',
|
||||
log => param('log'),
|
||||
username => session('logged_in_user'),
|
||||
userip => request->remote_address,
|
||||
action => 'comment',
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
ajax '/ajax/content/report/portlog' => require_role port_control => sub {
|
||||
my $device = param('q');
|
||||
my $port = param('f');
|
||||
|
||||
@@ -46,6 +46,7 @@ web_plugins:
|
||||
- Report::HalfDuplex
|
||||
- Report::DeviceAddrNoDNS
|
||||
- Report::DeviceByLocation
|
||||
- Report::InventoryByModelByOS
|
||||
- Report::DeviceDnsMismatch
|
||||
- Report::DevicePoeStatus
|
||||
- Report::DuplexMismatch
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<table id="data-table" class="table table-striped table-bordered" width="100%" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Device Location Triggering<br>Last Discovery Attempt</th>
|
||||
<th>Observing Device</th>
|
||||
<th>Undiscovered Neighbor</th>
|
||||
<th class="nd_center-cell">Last Discovery Attempt</th>
|
||||
<th class="nd_center-cell">Last Discovery Log</th>
|
||||
@@ -12,11 +12,18 @@
|
||||
<tr>
|
||||
<td><a href="[% device_ports %]&q=[% row.ip | uri %]&f=[% row.port | uri %]">
|
||||
[% row.dns || row.name || row.ip | html_entity %] ( [% row.port | html_entity %] ) </a></td>
|
||||
<td><a href="[% search_node %]&q=[% row.remote_ip | uri %]">
|
||||
[% row.remote_ip | html_entity %]</a>
|
||||
([% row.remote_port | html_entity %])
|
||||
[% ' id: '_ row.remote_id IF row.remote_id %]
|
||||
[% ' type: '_ row.remote_type IF row.remote_type %]</td>
|
||||
<td>
|
||||
[% IF row.remote_ip %]
|
||||
<a href="[% search_node %]&q=[% row.remote_ip | uri %]">
|
||||
[% row.remote_ip | html_entity %]
|
||||
</a> ([% row.remote_port | html_entity %])
|
||||
[% '<br />' IF row.remote_id or row.remote_type %]
|
||||
[% ' id: '_ row.remote_id IF row.remote_id %]
|
||||
[% ' type: '_ row.remote_type IF row.remote_type %]
|
||||
[% ELSE %]
|
||||
Known Device's MAC Address seen on this Port during Macsuck
|
||||
[% END %]
|
||||
</td>
|
||||
<td class="nd_center-cell">[% row.finished | html_entity %]</td>
|
||||
<td class="nd_center-cell">[% row.log | html_entity %]</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[% USE CSV -%]
|
||||
[% CSV.dump([ 'Device Triggering Last Discovery Attempt' 'Device Port'
|
||||
[% CSV.dump([ 'Observing Device' 'Device Port'
|
||||
'Remote IP' 'Remote Port' 'Remote ID' 'Remote Type'
|
||||
'Last Discovery Attempt' 'Discovery Log']) %]
|
||||
|
||||
|
||||
@@ -82,6 +82,10 @@
|
||||
rel="tooltip" data-placement="top" data-offset="3"
|
||||
data-animation="" data-title="Enable Port"></i>
|
||||
</span>
|
||||
[% END %]
|
||||
[% ELSE %]
|
||||
<td nowrap class="nd_editable-cell"
|
||||
data-order="[% row.port | html_entity %]" data-filter="[% row.port | html_entity %]">
|
||||
[% END %]
|
||||
<a class="nd_log-icon"
|
||||
href="[% uri_for('/report/portlog') %]?q=[% device.ip | uri %]&f=[% row.port | uri %]">
|
||||
@@ -89,9 +93,6 @@
|
||||
rel="tooltip" data-placement="top" data-offset="3"
|
||||
data-animation="" data-title="View Port Log"></i>
|
||||
</a>
|
||||
[% ELSE %]
|
||||
<td nowrap data-order="[% row.port | html_entity %]" data-filter="[% row.port | html_entity %]">
|
||||
[% END %]
|
||||
<a class="nd_this-port-only nd_port-only-first" href="[% uri_for('/device',
|
||||
self_options) %]&q=[% params.q | uri %]&f=[% row.port | uri %]&prefer=port">
|
||||
[% IF row.is_master %]
|
||||
@@ -121,6 +122,10 @@
|
||||
<td nowrap>[% row.descr | html_entity %]</td>
|
||||
[% END %]
|
||||
|
||||
[% IF params.c_comment %]
|
||||
<td nowrap>[% row.last_comment | html_entity %]</td>
|
||||
[% END %]
|
||||
|
||||
[% IF params.c_type %]
|
||||
<td>[% row.type | html_entity %]</td>
|
||||
[% END %]
|
||||
|
||||
@@ -61,6 +61,10 @@
|
||||
[% myport.push(row.descr) %]
|
||||
[% END %]
|
||||
|
||||
[% IF params.c_comment %]
|
||||
[% myport.push(row.last_comment) %]
|
||||
[% END %]
|
||||
|
||||
[% IF params.c_type %]
|
||||
[% myport.push(row.type) %]
|
||||
[% END %]
|
||||
|
||||
71
Netdisco/share/views/ajax/report/inventorybymodelbyos.tt
Normal file
71
Netdisco/share/views/ajax/report/inventorybymodelbyos.tt
Normal file
@@ -0,0 +1,71 @@
|
||||
<table id="nsbi-data-table" class="table table-bordered table-hover" width="100%" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Model</th>
|
||||
<th>Operating System Version</th>
|
||||
<th>Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</tbody>
|
||||
[% FOREACH row IN results %]
|
||||
<tr>
|
||||
<td>
|
||||
<a href="[% search_device %]&q=[% row.model | uri %]&vendor=[% row.vendor | uri %]&model=[% row.model | uri %]">
|
||||
[% row.vendor.ucfirst | html_entity %] [% row.model | html_entity %]</a>
|
||||
[% IF row.os %] running "[% row.os | html_entity %]"[% END %]
|
||||
</td>
|
||||
<td>
|
||||
<a class="nd_linkcell"
|
||||
href="[% search_device %]&q=[% row.os_ver | uri %]&vendor=[% row.vendor | uri %]&model=[% row.model | uri %]&os=[% row.os | uri %]&os_ver=[% row.os_ver | uri %]&matchall=on">
|
||||
[% row.os_ver | html_entity %]</a>
|
||||
</td>
|
||||
<td>[% row.os_ver_count | html_entity %]</td>
|
||||
</tr>
|
||||
[% END %]
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<style>
|
||||
tr.group,
|
||||
tr.group:hover {
|
||||
background-color: #ddd !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var table = $('#nsbi-data-table').DataTable({
|
||||
"columnDefs": [
|
||||
{ "visible": false, "targets": 0 }
|
||||
],
|
||||
sort: false,
|
||||
"drawCallback": function ( settings ) {
|
||||
var api = this.api();
|
||||
var rows = api.rows( {page:'current'} ).nodes();
|
||||
var last=null;
|
||||
|
||||
api.column(0, {page:'current'} ).data().each( function ( group, i ) {
|
||||
if ( last !== group ) {
|
||||
$(rows).eq( i ).before(
|
||||
'<tr class="group"><td colspan="2">'+group+'</td></tr>'
|
||||
);
|
||||
|
||||
last = group;
|
||||
}
|
||||
} );
|
||||
},
|
||||
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
|
||||
} );
|
||||
|
||||
// Order by the grouping
|
||||
$('#nsbi-data-table tbody').on( 'click', 'tr.group', function () {
|
||||
var currentOrder = table.order()[0];
|
||||
if ( currentOrder[0] === 0 && currentOrder[1] === 'asc' ) {
|
||||
table.order( [ 0, 'desc' ] ).draw();
|
||||
}
|
||||
else {
|
||||
table.order( [ 0, 'asc' ] ).draw();
|
||||
}
|
||||
} );
|
||||
} );
|
||||
</script>
|
||||
@@ -4,8 +4,8 @@
|
||||
[% FOREACH row IN results %]
|
||||
[% mylist = [] %]
|
||||
[% mylist.push(row.ip) %]
|
||||
[% mylist.push(row.mac) %]
|
||||
[% mylist.push(row.dns) %]
|
||||
[% mylist.push(row.time_first) %]
|
||||
[% mylist.push(row.time_last) %]
|
||||
[% CSV.dump(mylist) %]
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
[% IF results.count == 0 %]
|
||||
<div class="span2 alert alert-info">This port's log is empty.</div>
|
||||
[% ELSE %]
|
||||
<table id="data-table" class="table table-bordered table-condensed table-striped" width="100%" cellspacing="0">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -10,9 +7,24 @@
|
||||
<th class="nd_center-cell">Action</th>
|
||||
<th class="nd_center-cell">Reason</th>
|
||||
<th class="nd_center-cell">Log</th>
|
||||
<th class="nd_center-cell">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</tbody>
|
||||
<tr>
|
||||
<td class="nd_center-cell">-</td>
|
||||
<td class="nd_center-cell">[% session.logged_in_user | html_entity %]</td>
|
||||
<td class="nd_center-cell">-</td>
|
||||
<td class="nd_center-cell">comment</td>
|
||||
<td class="nd_center-cell">Other</td>
|
||||
<td class="nd_center-cell"><input data-form="add" class="span4" name="log" type="text" placeholder="Add comment..."></td>
|
||||
<input data-form="add" name="ip" type="hidden" value="[% params.q | html_entity %]">
|
||||
<input data-form="add" name="port" type="hidden" value="[% params.f | html_entity %]">
|
||||
<td class="nd_center-cell">
|
||||
<button class="btn btn-small nd_adminbutton" name="add" type="submit"><i class="icon-plus-sign"></i> Add</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
[% WHILE (row = results.next) %]
|
||||
<tr>
|
||||
<td class="nd_center-cell">[% row.creation_stamp | html_entity %]</td>
|
||||
@@ -21,15 +33,16 @@
|
||||
<td class="nd_center-cell">[% row.action | html_entity %]</td>
|
||||
<td class="nd_center-cell">[% settings.port_control_reasons.item(row.reason) || row.reason | html_entity %]</td>
|
||||
<td class="nd_center-cell">[% row.log || '-' | html_entity %]</td>
|
||||
<td class="nd_center-cell"></td>
|
||||
</tr>
|
||||
[% END %]
|
||||
</tbody>
|
||||
</table>
|
||||
[% END %]
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('#data-table').dataTable({
|
||||
sort: false,
|
||||
[% INCLUDE 'ajax/datatabledefaults.tt' -%]
|
||||
} );
|
||||
} );
|
||||
|
||||
@@ -52,4 +52,35 @@
|
||||
,delay: 150
|
||||
,minLength: 3
|
||||
});
|
||||
|
||||
// dynamically bind to all forms in the table
|
||||
$('.content').on('click', '.nd_adminbutton', function(event) {
|
||||
// stop form from submitting normally
|
||||
event.preventDefault();
|
||||
|
||||
// what purpose - add/update/del
|
||||
var mode = $(this).attr('name');
|
||||
|
||||
// submit the query and put results into the tab pane
|
||||
$.ajax({
|
||||
type: 'POST'
|
||||
,async: true
|
||||
,dataType: 'html'
|
||||
,url: uri_base + '/ajax/control/report/' + tab + '/' + mode
|
||||
,data: $(this).closest('tr').find('input[data-form="' + mode + '"]').serializeArray()
|
||||
,beforeSend: function() {
|
||||
$(target).html(
|
||||
'<div class="span2 alert">Request submitted...</div>'
|
||||
);
|
||||
}
|
||||
,success: function() {
|
||||
$('#' + tab + '_form').trigger('submit');
|
||||
}
|
||||
// skip any error reporting for now
|
||||
// TODO: fix sanity_ok in Netdisco Web
|
||||
,error: function() {
|
||||
$('#' + tab + '_form').trigger('submit');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user