<%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>
<h1 class="pagehead"><%$title{$report}%></h1>
% }
% if ($report && (!defined($results) || @$results == 0)) {
No results returned.
% } else {
<TABLE>
<TR>
% foreach my $column (@$columns) {
<TH><%$column->[0]%></TH>
% }
</TR>
% foreach my $row (@$results) {
<TR CLASS="match-<%++$odd%2%>">
%  foreach my $column (@$columns) {
%   $row->{$column->[1]} =~ s/\Q$netdisco::CONFIG{domain}\E// if ($column->[1] eq 'name');
<TD><%$row->{$column->[1]} or '[none]'%>
%  }
</TR>
% }
% }
</TABLE>
<%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>
<h1 class="pagehead">Pick a Report</h1>
<FORM ACTION="<%$r->uri%>" METHOD=GET>
<SELECT NAME="report">
% foreach my $key (sort keys %title) {
<OPTION VALUE="<%$key%>"<%$arg_report eq $key ? ' SELECTED' : ''%>><%$title{$key}%></OPTION>
% }
</SELECT>
<INPUT TYPE="submit" CLASS="navbutton" VALUE="View Report">
</FORM>
</%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<br>Module', 'module' ],
        [ 'Power<br>(W)', 'power' ],
        [ 'Supply', 'status' ],
        [ 'Capable<br>Ports', 'ports' ],
        [ 'Supplied<br>Ports', 'on' ],
        [ 'Disabled<br>Ports', 'disabled' ],
        [ 'Power<br>Errors', 'err' ],
        [ 'Committed<br>(W)', 'committed' ],
        [ 'Delivering<br>(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<br>&lt; 90 days', 'recently_used' ],
        [ 'Down since &gt;<br>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("<A HREF=device.html?ip=%s> %s </A>", $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("<A HREF=device.html?ip=%s> %s </A>", $ip, $ip);
    my $port = $res->{port};
    $res->{port} = sprintf("<A HREF=device.html?ip=%s&amp;port=%s> %s </A>",
                        $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
