[#70] SSID Search (port)
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
[NEW FEATURES]
|
[NEW FEATURES]
|
||||||
|
|
||||||
* [#75] Device module inventory report / search
|
* [#75] Device module inventory report / search
|
||||||
|
* [#70] SSID Search (port)
|
||||||
|
|
||||||
[ENHANCEMENTS]
|
[ENHANCEMENTS]
|
||||||
|
|
||||||
|
|||||||
48
Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePortSsid.pm
Normal file
48
Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePortSsid.pm
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package App::Netdisco::DB::ResultSet::DevicePortSsid;
|
||||||
|
use base 'App::Netdisco::DB::ResultSet';
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings FATAL => 'all';
|
||||||
|
|
||||||
|
__PACKAGE__->load_components(
|
||||||
|
qw/
|
||||||
|
+App::Netdisco::DB::ExplicitLocking
|
||||||
|
/
|
||||||
|
);
|
||||||
|
|
||||||
|
=head1 ADDITIONAL METHODS
|
||||||
|
|
||||||
|
=head2 get_ssids
|
||||||
|
|
||||||
|
Returns a sorted list of SSIDs with the following columns only:
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item ssid
|
||||||
|
|
||||||
|
=item broadcast
|
||||||
|
|
||||||
|
=item count
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
Where C<count> is the number of instances of the SSID in the Netdisco
|
||||||
|
database.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub get_ssids {
|
||||||
|
my $rs = shift;
|
||||||
|
|
||||||
|
return $rs->search(
|
||||||
|
{},
|
||||||
|
{ select => [ 'ssid', 'broadcast', { count => 'ssid' } ],
|
||||||
|
as => [qw/ ssid broadcast count /],
|
||||||
|
group_by => [qw/ ssid broadcast /],
|
||||||
|
order_by => { -desc => [qw/count/] },
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
70
Netdisco/lib/App/Netdisco/Web/Plugin/Report/PortSsid.pm
Normal file
70
Netdisco/lib/App/Netdisco/Web/Plugin/Report/PortSsid.pm
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package App::Netdisco::Web::Plugin::Report::PortSsid;
|
||||||
|
|
||||||
|
use Dancer ':syntax';
|
||||||
|
use Dancer::Plugin::DBIC;
|
||||||
|
use Dancer::Plugin::Auth::Extensible;
|
||||||
|
|
||||||
|
use App::Netdisco::Web::Plugin;
|
||||||
|
|
||||||
|
register_report(
|
||||||
|
{ category => 'Port',
|
||||||
|
tag => 'portssid',
|
||||||
|
label => 'Port SSID Inventory',
|
||||||
|
provides_csv => 1,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
hook 'before_template' => sub {
|
||||||
|
my $tokens = shift;
|
||||||
|
|
||||||
|
return
|
||||||
|
unless (
|
||||||
|
request->path eq uri_for('/report/portssid')->path
|
||||||
|
or index(
|
||||||
|
request->path, uri_for('/ajax/content/report/portssid')->path
|
||||||
|
) == 0
|
||||||
|
);
|
||||||
|
|
||||||
|
# used in the search sidebar template to set selected items
|
||||||
|
foreach my $opt (qw/ssid/) {
|
||||||
|
my $p = (
|
||||||
|
ref [] eq ref param($opt)
|
||||||
|
? param($opt)
|
||||||
|
: ( param($opt) ? [ param($opt) ] : [] )
|
||||||
|
);
|
||||||
|
$tokens->{"${opt}_lkp"} = { map { $_ => 1 } @$p };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
get '/ajax/content/report/portssid' => require_login sub {
|
||||||
|
|
||||||
|
my $ssid = param('ssid');
|
||||||
|
|
||||||
|
my $rs = schema('netdisco')->resultset('DevicePortSsid');
|
||||||
|
|
||||||
|
if ( defined $ssid ) {
|
||||||
|
|
||||||
|
$rs
|
||||||
|
= $rs->search( { ssid => $ssid } )
|
||||||
|
->prefetch( [qw/ device port /] )
|
||||||
|
->order_by( [qw/ port.ip port.port /] )->hri;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$rs = $rs->get_ssids->hri;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return unless $rs->has_rows;
|
||||||
|
|
||||||
|
if ( request->is_ajax ) {
|
||||||
|
template 'ajax/report/portssid.tt', { results => $rs, },
|
||||||
|
{ layout => undef };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
header( 'Content-Type' => 'text/comma-separated-values' );
|
||||||
|
template 'ajax/report/portssid_csv.tt', { results => $rs, },
|
||||||
|
{ layout => undef };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
1;
|
||||||
@@ -14,6 +14,8 @@ get '/report/*' => require_login sub {
|
|||||||
];
|
];
|
||||||
my $class_list = [ schema('netdisco')->resultset('DeviceModule')
|
my $class_list = [ schema('netdisco')->resultset('DeviceModule')
|
||||||
->get_distinct_col('class') ];
|
->get_distinct_col('class') ];
|
||||||
|
my $ssid_list = [ schema('netdisco')->resultset('DevicePortSsid')
|
||||||
|
->get_distinct_col('ssid') ];
|
||||||
|
|
||||||
# trick the ajax into working as if this were a tabbed page
|
# trick the ajax into working as if this were a tabbed page
|
||||||
params->{tab} = $tag;
|
params->{tab} = $tag;
|
||||||
@@ -24,6 +26,7 @@ get '/report/*' => require_login sub {
|
|||||||
report => setting('_reports')->{$tag},
|
report => setting('_reports')->{$tag},
|
||||||
domain_list => $domain_list,
|
domain_list => $domain_list,
|
||||||
class_list => $class_list,
|
class_list => $class_list,
|
||||||
|
ssid_list => $ssid_list,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ web_plugins:
|
|||||||
- Report::PortAdminDown
|
- Report::PortAdminDown
|
||||||
- Report::PortBlocking
|
- Report::PortBlocking
|
||||||
- Report::PortMultiNodes
|
- Report::PortMultiNodes
|
||||||
|
- Report::PortSsid
|
||||||
- Report::PortUtilization
|
- Report::PortUtilization
|
||||||
- Report::ApChannelDist
|
- Report::ApChannelDist
|
||||||
- Report::ApClients
|
- Report::ApClients
|
||||||
|
|||||||
54
Netdisco/share/views/ajax/report/portssid.tt
Normal file
54
Netdisco/share/views/ajax/report/portssid.tt
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
[% USE Number.Format %]
|
||||||
|
[% IF results.first.device.ip %]
|
||||||
|
[% row = results.reset %]
|
||||||
|
<table class="table table-bordered table-condensed table-striped nd_floatinghead">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Device (Port)</th>
|
||||||
|
<th>Broadcast</th>
|
||||||
|
<th>Model</th>
|
||||||
|
<th>SSID</th>
|
||||||
|
<th>Vendor</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</tbody>
|
||||||
|
[% WHILE (row = results.next) %]
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a class="nd_linkcell"
|
||||||
|
href="[% device_ports %]&q=[% row.port.ip | uri %]&f=[% row.port.port | uri %]&c_nodes=on&n_ssid=on">
|
||||||
|
[% row.device.dns || row.device.name || row.device.ip | html_entity %] ( [% row.port.port | html_entity %] )</a>
|
||||||
|
</td>
|
||||||
|
<td>[% row.broadcast ? 'Yes' : 'No' %]</td>
|
||||||
|
<td>[% row.device.model | html_entity %]</td>
|
||||||
|
<td>[% row.ssid | html_entity %]</td>
|
||||||
|
<td>[% row.device.vendor | html_entity %]</td>
|
||||||
|
</tr>
|
||||||
|
[% END %]
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
[% ELSE %]
|
||||||
|
[% row = results.reset %]
|
||||||
|
<table class="table table-bordered table-condensed table-striped nd_floatinghead">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="nd_center-cell">SSID</th>
|
||||||
|
<th class="nd_center-cell">Broadcast</th>
|
||||||
|
<th class="nd_center-cell">Count</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</tbody>
|
||||||
|
[% WHILE (row = results.next) %]
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a class="nd_linkcell"
|
||||||
|
href="[% uri_for('/report/portssid') %]?ssid=[% row.ssid | uri %]">
|
||||||
|
[% row.ssid | html %]</a>
|
||||||
|
</td>
|
||||||
|
<td class="nd_center-cell">[% row.broadcast ? 'Yes' : 'No' %]</td>
|
||||||
|
<td class="nd_center-cell">[% row.count | format_number %]</td>
|
||||||
|
</tr>
|
||||||
|
[% END %]
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
[% END %]
|
||||||
28
Netdisco/share/views/ajax/report/portssid_csv.tt
Normal file
28
Netdisco/share/views/ajax/report/portssid_csv.tt
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
[% USE CSV -%]
|
||||||
|
[% IF results.first.ip %]
|
||||||
|
[% row = results.reset %]
|
||||||
|
[% CSV.dump(['Device' 'Port' 'Name' 'Broadcast' 'Model' 'SSID' 'Vendor']) %]
|
||||||
|
|
||||||
|
[% WHILE (row = results.next) %]
|
||||||
|
[% mylist = [] %]
|
||||||
|
[% device = row.device.dns || row.device.name || row.device.ip %]
|
||||||
|
[% broadcast = row.broadcast ? 'Yes' : 'No' %]
|
||||||
|
[% FOREACH col IN [ device row.port.port row.device.name broadcast row.device.model row.ssid row.device.vendor ] %]
|
||||||
|
[% mylist.push(col) %]
|
||||||
|
[% END %]
|
||||||
|
[% CSV.dump(mylist) %]
|
||||||
|
|
||||||
|
[% END %]
|
||||||
|
[% ELSE %]
|
||||||
|
[% row = results.reset %]
|
||||||
|
[% CSV.dump(['SSID' 'Count']) %]
|
||||||
|
|
||||||
|
[% WHILE (row = results.next) %]
|
||||||
|
[% mylist = [] %]
|
||||||
|
[% FOREACH col IN [ row.ssid row.count ] %]
|
||||||
|
[% mylist.push(col) %]
|
||||||
|
[% END %]
|
||||||
|
[% CSV.dump(mylist) %]
|
||||||
|
|
||||||
|
[% END %]
|
||||||
|
[% END %]
|
||||||
15
Netdisco/share/views/sidebar/report/portssid.tt
Normal file
15
Netdisco/share/views/sidebar/report/portssid.tt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
<p class="nd_sidebar-title"><em>SSID Search Options</em></p>
|
||||||
|
<div class="clearfix">
|
||||||
|
<select class="nd_side-select nd_colored-input" size="[% ssid_list.size > 8 ? 8 : ssid_list.size %]"
|
||||||
|
multiple="on" name="ssid"
|
||||||
|
rel="tooltip" data-placement="left" data-offset="5" data-title="SSID"/>
|
||||||
|
[% FOREACH opt IN ssid_list %]
|
||||||
|
<option[% ' selected="selected"' IF ssid_lkp.exists(opt) %]>[% opt | html_entity %]</option>
|
||||||
|
[% END %]
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button id="[% report.tag %]_submit" type="submit" class="btn btn-info">
|
||||||
|
<i class="icon-search icon-large pull-left nd_navbar-icon"></i> Search SSID</button>
|
||||||
|
|
||||||
Reference in New Issue
Block a user