%perl>
$m->comp('SELF:pickreport');
if ($report && defined($title{$report})) {
my $self = $m->request_comp;
my $comp = 'report_' . $report;
if ( $self->method_exists( $comp ) ) {
$m->comp( 'SELF:' . $comp );
} else {
$m->comp( 'reports_local.html:' . $comp );
}
%perl>
<%$title{$report}%>
% }
% if ($report && (!defined($results) || @$results == 0)) {
No results returned.
% } else {
% foreach my $column (@$columns) {
<%$column->[0]%> |
% }
% foreach my $row (@$results) {
% foreach my $column (@$columns) {
% $row->{$column->[1]} =~ s/\Q$netdisco::CONFIG{domain}\E// if ($column->[1] eq 'name');
<%$row->{$column->[1]} or '[none]'%>
% }
|
% }
% }
<%args>
$report => undef
%args>
<%shared>
my $results = undef;
my $columns = [];
my %title;
my $odd = 1;
my $arg_report;
%shared>
<%init>
%title = (
device_inventory => "Device Inventory",
radio_power => "Access Point Channels and Power",
dns_mismatch => "Device Name / DNS mismatches",
ap_clients => "Clients per Access Point",
poe_status => "PoE Status",
radio_mac_location => "Radio MAC address and location",
radio_speed_ssid => "Wireless client speeds by SSID",
port_usage => "Ports up / recent down / long down",
undiscovered_neighbors => "Undiscovered neighbors",
radio_channel_histo => "Access Point Channel Distribution",
);
if ( $m->comp_exists( 'reports_local.html' ) ) {
# Allow the reports_local page to add reports, if it exists.
$m->comp( 'reports_local.html:update_title', title => \%title );
}
$arg_report = $report;
%init>
<%method pickreport>
Pick a Report
%method>
<%method report_device_inventory>
<%perl>
$columns = [
[ 'Name', 'name' ],
[ 'Location', 'location' ],
[ 'Serial No', 'serial' ],
[ 'Vendor', 'vendor' ],
[ 'Model', 'model' ],
[ 'OS Rev', 'os_ver' ]
];
$results = sql_rows('device', ['*']);
$results = [ sort { $a->{name} cmp $b->{name} } @$results ];
%perl>
%method>
<%method report_dns_mismatch>
<%perl>
$columns = [
[ 'Device Name', 'name' ],
[ 'DNS Name', 'dns' ],
[ 'IP Address', 'ip' ]
];
my $alldev = sql_rows('device', ['name', 'dns', 'ip']);
$results = [];
foreach my $dev (@$alldev) {
my $name = $dev->{name};
my $dns = $dev->{dns};
$name =~ s/\Q$netdisco::CONFIG{domain}\E//;
$dns =~ s/\Q$netdisco::CONFIG{domain}\E//;
push(@$results, $dev) if (lc($name) ne lc($dns));
}
%perl>
%method>
<%method report_ap_clients>
<%perl>
$columns = [
[ 'Name', 'name' ],
[ 'Location', 'location' ],
[ 'Port', 'port' ],
[ '# Clients', 'count' ]
];
$results = sql_rows('device,node', ['device.name','device.location','node.port','count(node.port) as count'],
{ 'device.ip' => \'node.switch',
'device.name' => '%ap%',
'node.active' => 't',
'node.time_last' => \\'>= device.last_macsuck' },
0,
'group by device.name,device.location,node.port');
$results = [ sort { $b->{count} <=> $a->{count} } @$results ];
%perl>
%method>
<%method report_radio_power>
<%perl>
$columns = [
[ 'Name', 'name' ],
[ 'Model', 'model' ],
[ 'Location', 'location' ],
[ 'Port', 'port' ],
[ 'Channel', 'channel' ],
[ 'Tx Power (mW)', 'power' ],
[ 'Tx Power (dBm)', 'power2' ]
];
$results = sql_rows('device d, device_port_wireless w',
[ 'distinct d.name', 'd.model', 'd.location', 'w.port', 'w.channel', 'w.power' ],
{ 'd.ip' => \'w.ip' });
$results = [ sort sortportname @$results ];
foreach $r (@$results) {
next unless defined($r->{power}) && $r->{power};
$r->{power2} = sprintf("%.1f", 10.0*CORE::log($r->{power})/CORE::log(10));
}
sub sortportname {
sort_port($a,$b) or $a->{name} cmp $b->{name};
}
%perl>
%method>
<%method report_poe_status>
<%perl>
$columns = [
[ 'Name', 'name' ],
[ 'Model', 'model' ],
[ 'Location', 'location' ],
[ 'PoE
Module', 'module' ],
[ 'Power
(W)', 'power' ],
[ 'Supply', 'status' ],
[ 'Capable
Ports', 'ports' ],
[ 'Supplied
Ports', 'on' ],
[ 'Disabled
Ports', 'disabled' ],
[ 'Power
Errors', 'err' ],
[ 'Committed
(W)', 'committed' ],
[ 'Delivering
(W)', 'delivering' ],
];
$results = sql_rows('device d, device_power p',
[ 'd.ip', 'd.name', 'd.model', 'd.location', 'p.module', 'p.status', 'p.power' ],
{ 'd.ip' => \'p.ip' }, 0,
'order by d.name, p.module');
foreach my $poe (@$results) {
$m->comp('device.html:poe_stats', poe => $poe);
foreach my $k (keys %{$poe->{stats}}) {
$poe->{$k} = $poe->{stats}->{$k};
if ($k eq 'delivering') {
$poe->{$k} = sprintf("%.2f", $poe->{$k} / 1000.0);
}
}
}
%perl>
%method>
<%method report_radio_mac_location>
<%perl>
$columns = [
[ 'MAC', 'mac' ],
[ 'Location', 'location' ],
];
$results = sql_rows('device d, device_port p',
[ 'distinct p.mac', 'd.location' ],
{ 'd.ip' => \'p.ip', 'p.port' => '%Dot11Radio%' }, 0,
'order by d.location, p.mac');
%perl>
%method>
<%method report_radio_speed_ssid>
<%perl>
$columns = [
[ 'SSID', 'ssid' ],
[ 'Technology', 'type' ],
[ 'Count', 'count' ],
];
$results = sql_rows('node_wireless nw, node n, device_port_ssid s, device d',
[ 'maxrate', 'count(maxrate) as count', 'n.port', 's.ssid' ],
{ 'n.mac' => \'nw.mac', 's.ip' => \'n.switch', 's.port' => \'n.port',
'n.active' => 't', 'd.ip' => \'n.switch',
'n.time_last' => \\'>= d.last_macsuck', }, 0,
'group by nw.maxrate,n.port,s.ssid order by count desc' );
# Strip the subinterface, if any, from the port; then convert to a
# technology. This continues the assumption that Dot11Radio0 is
# 802.11b/g and Dot11Radio1 is 802.11a.
# N rates are not currently exposed via SNMP so there's no way to
# tell between g and n(2.4), or between a and n(5).
my %map = ( 'Dot11Radio0/11' => '802.11b', 'Dot11Radio0/54' => '802.11g',
'Dot11Radio1/54' => '802.11a' );
foreach my $res (@$results) {
my $port = $res->{port};
$port =~ s/\.[0-9]+$//;
my $info = sprintf("%s/%d", $port, $res->{maxrate});
$res->{type} = $map{ $info } || $info;
}
%perl>
%method>
<%method report_port_usage>
<%perl>
$columns = [
[ 'DNS', 'dns' ],
[ 'IP', 'ip' ],
[ 'Up', 'up' ],
[ 'Down since
< 90 days', 'recently_used' ],
[ 'Down since >
90 days', 'not_recently_used' ],
];
$results = sql_rows('device d join device_port p using (ip)',
[
'dns',
'ip',
'sum(case when up=\'up\' then 1 else 0 end) as up',
'sum(case when (up<>\'up\' and age(to_timestamp(extract(epoch from last_discover)-(uptime-lastchange)/100)) <= interval \'90 days\') then 1 else 0 end) as recently_used',
'sum(case when (up<>\'up\' and age(to_timestamp(extract(epoch from last_discover)-(uptime-lastchange)/100)) > interval \'90 days\') then 1 else 0 end) as not_recently_used',
],
{ }, 0,
'group by dns, ip order by dns');
foreach my $res (@$results) {
my $ip = $res->{ip};
$res->{ip} = sprintf(" %s ", $ip, $ip);
}
%perl>
%method>
<%method report_undiscovered_neighbors>
<%perl>
$columns = [
[ 'Device', 'name' ],
[ 'IP', 'ip' ],
[ 'Port', 'port' ],
[ 'Remote Device', 'remote_id' ],
[ 'Remote IP', 'remote_ip' ],
[ 'Remote Port', 'remote_port' ],
];
$results = sql_rows('device_port p join device d using (ip)',
[
'd.name',
'd.ip',
'p.port',
'p.remote_id',
'p.remote_ip',
'p.remote_port',
],
{ 'p.remote_ip' => \\'NOT IN (SELECT ip AS dev_ips FROM device UNION SELECT alias FROM device_ip)' }, 0,
'order by d.dns');
foreach my $res (@$results) {
my $ip = $res->{ip};
$res->{ip} = sprintf(" %s ", $ip, $ip);
my $port = $res->{port};
$res->{port} = sprintf(" %s ",
$ip, $port, $port);
}
%perl>
%method>
<%method report_radio_channel_histo>
<%perl>
$columns = [
[ 'Channel', 'channel' ],
[ 'Count', 'count' ],
];
$results = sql_rows('device_port_wireless',
[
'channel',
'count(channel)'
],
{}, 0, 'group by channel order by count');
%perl>
%method>
<%method title>
- Reporting \
%method>
%# $Id$
%# vim:syntax=mason