Add Undiscovered Neighbors admin report
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
|
||||
* Add IP Phones discovered through LLDP/CDP report
|
||||
* Add device/node/vlan/port specific search from Navbar
|
||||
* Add Undiscovered Neighbors admin report
|
||||
* [#3] [#47] Device Neighbor Map can have max depth and VLAN filter
|
||||
* [#31] get_community now supported
|
||||
* [#19] Ask for Reason when changing Port up/down Status, or VLAN
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package App::Netdisco::DB::Result::Virtual::UndiscoveredNeighbors;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use utf8;
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
__PACKAGE__->table_class('DBIx::Class::ResultSource::View');
|
||||
|
||||
__PACKAGE__->table('undiscovered_neighbors');
|
||||
__PACKAGE__->result_source_instance->is_virtual(1);
|
||||
__PACKAGE__->result_source_instance->view_definition(<<'ENDSQL');
|
||||
SELECT DISTINCT ON (p.remote_ip) d.ip,
|
||||
d.name,
|
||||
d.dns,
|
||||
p.port,
|
||||
p.remote_ip,
|
||||
p.remote_id,
|
||||
p.remote_type,
|
||||
p.remote_port,
|
||||
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
|
||||
ENDSQL
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
"ip",
|
||||
{ data_type => "inet", is_nullable => 0 },
|
||||
"name",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"dns",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"port",
|
||||
{ data_type => "text", is_nullable => 0 },
|
||||
"remote_ip",
|
||||
{ data_type => "inet", is_nullable => 1 },
|
||||
"remote_port",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"remote_type",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"remote_id",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"log",
|
||||
{ data_type => "text", is_nullable => 1 },
|
||||
"finished",
|
||||
{ data_type => "timestamp", is_nullable => 1 },
|
||||
);
|
||||
|
||||
1;
|
||||
@@ -0,0 +1,47 @@
|
||||
package App::Netdisco::Web::Plugin::AdminTask::UndiscoveredNeighbors;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Dancer ':syntax';
|
||||
use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
use App::Netdisco::Util::Device qw/is_discoverable/;
|
||||
|
||||
use App::Netdisco::Web::Plugin;
|
||||
|
||||
register_admin_task(
|
||||
{ tag => 'undiscoveredneighbors',
|
||||
label => 'Undiscovered Neighbors',
|
||||
provides_csv => 1,
|
||||
}
|
||||
);
|
||||
|
||||
get '/ajax/content/admin/undiscoveredneighbors' => require_role admin => sub {
|
||||
my @devices
|
||||
= schema('netdisco')->resultset('Virtual::UndiscoveredNeighbors')
|
||||
->order_by('ip')->hri->all;
|
||||
|
||||
return unless scalar @devices;
|
||||
|
||||
# Don't include devices excluded from discovery by config
|
||||
my @results = grep {
|
||||
is_discoverable( $_->{'ports'}->{remote_ip},
|
||||
$_->{'ports'}->{'remote_type'} )
|
||||
} @devices;
|
||||
|
||||
return unless scalar @results;
|
||||
|
||||
if ( request->is_ajax ) {
|
||||
template 'ajax/admintask/undiscoveredneighbors.tt',
|
||||
{ results => \@results, },
|
||||
{ layout => undef };
|
||||
}
|
||||
else {
|
||||
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||
template 'ajax/admintask/undiscoveredneighbors_csv.tt',
|
||||
{ results => \@results, },
|
||||
{ layout => undef };
|
||||
}
|
||||
};
|
||||
|
||||
1;
|
||||
@@ -59,6 +59,7 @@ web_plugins:
|
||||
- AdminTask::UserLog
|
||||
- AdminTask::Users
|
||||
- AdminTask::PortLog
|
||||
- AdminTask::UndiscoveredNeighbors
|
||||
- Search::Device
|
||||
- Search::Node
|
||||
- Search::VLAN
|
||||
|
||||
26
Netdisco/share/views/ajax/admintask/undiscoveredneighbors.tt
Normal file
26
Netdisco/share/views/ajax/admintask/undiscoveredneighbors.tt
Normal file
@@ -0,0 +1,26 @@
|
||||
<table class="table table-bordered table-condensed table-striped nd_floatinghead">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Device Location Triggering<br>Last Discovery Attempt</th>
|
||||
<th>Undiscovered Neighbor</th>
|
||||
<th class="nd_center-cell">Last Discovery Attempt</th>
|
||||
<th class="nd_center-cell">Last Discovery Log</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</tbody>
|
||||
[% FOREACH row IN results %]
|
||||
<tr>
|
||||
<td><a href="[% device_ports %]&q=[% row.dns || 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 class="nd_center-cell">[% row.finished | html_entity %]</td>
|
||||
<td class="nd_center-cell">[% row.log | html_entity %]</td>
|
||||
</tr>
|
||||
[% END %]
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
[% USE CSV -%]
|
||||
[% CSV.dump([ 'Device Triggering Last Discovery Attempt' 'Device Port'
|
||||
'Remote IP' 'Remote Port' 'Remote ID' 'Remote Type'
|
||||
'Last Discovery Attempt' 'Discovery Log']) %]
|
||||
|
||||
[% FOREACH row IN results %]
|
||||
[% mylist = [] %]
|
||||
[% mylist.push(row.dns || row.name || row.ip) %]
|
||||
[% mylist.push(row.port) %]
|
||||
[% mylist.push(row.remote_ip) %]
|
||||
[% mylist.push(row.remote_port) %]
|
||||
[% mylist.push(row.remote_id) %]
|
||||
[% mylist.push(row.remote_type) %]
|
||||
[% mylist.push(row.finished) %]
|
||||
[% mylist.push(row.log) %]
|
||||
[% CSV.dump(mylist) %]
|
||||
|
||||
[% END %]
|
||||
Reference in New Issue
Block a user