<& SELF:report &>
<%args>
$cmd => ''
$text => ''
$dir => 'disable'
@reason => ()
$type => ''
$timeframe => 'month'
$timelength => 'days'
$timenumber => 1
@user => ()
$sort => 'Date'
%args>
<%doc>
TODO:
- Implement Time frames for reports.
%doc>
<%shared>
my %Reasons = %netdisco::PORT_CONTROL_REASONS;
my $matches = undef;
my $argsort = undef;
my $argtype = undef;
%shared>
<%init>
# Get rid of \n's in the long reasons
foreach my $reason (keys %Reasons){
$Reasons{$reason}->[1] =~ s/\n//g;
}
$argsort = $sort;
$argtype = $type;
# Grab the reasons and people out of the port log
# todo: sql_column has no way of doing a 'group by', so this kludge
my $db_reasons = {};
my $db_temp = sql_rows('device_port_log',
['distinct(reason) as reason','count(reason) as count'],
{'action' => "!vlan"},
0,'group by reason');
foreach my $row (@$db_temp){
$db_reasons->{$row->{reason}}=$row->{count};
}
my $db_users = {};
$db_temp = sql_rows('device_port_log',['distinct(username) as username','count(username) as count'],undef,0,'group by username');
foreach my $row (@$db_temp){
$db_users->{$row->{username}}=$row->{count};
}
# Search for ports
if ($cmd eq 'search'){
#Get current time
my ($second, $minute, $hour, $day, $month, $year, $weekDay, $dayofyear, $isDST) = localtime;
if($day < 10) {
$day = "0" . $day;
}
$month++;
if($month < 10) {
$month = "0" . $month;
}
$year += 1900;
my $yearMonth = $year . "-" . $month;
my $yearMonthDay = $yearMonth . "-" . $day;
$timelength =~ s/[^a-z ]+//g;
$timenumber = 1 unless $timenumber =~ m/^\d+$/;
# Get ports from port device log
my $tables = 'device_port_log l left join device d on d.ip = l.ip';
my $cols = ['d.dns','l.reason','l.port','l.ip','l.log','l.username','l.userip','l.action','extract(epoch from l.creation) as creation'];
my $where = {};
$where->{'l.log'} = '%'.$text.'%' if $text;
$where->{'l.reason'} = [\@reason] if (scalar @reason and grep(/\S+/,@reason));
$where->{'l.action'} = $dir if $dir;
$where->{'l.username'} = [\@user] if (scalar @user and grep(/\S+/,@user));
if ($type eq 'now'){
$tables .= ' left join device_port p on l.ip = p.ip and l.port = p.port';
$where->{'p.up_admin'} = 'down';
}
if ($timeframe eq 'interval'){
if ($timelength eq 'days'){
$where->{'age(l.creation)'} = \\"<= interval \'$timenumber day\'";
} elsif ($timelength eq 'months'){
$where->{'age(l.creation)'} = \\"<= interval \'$timenumber mon\'";
} else {
$where->{'age(l.creation)'} = \\"<= interval \'$timenumber year\'";
}
} elsif ($timeframe eq 'today'){
$where->{'l.creation'} = '%'.$yearMonthDay.'%';
} elsif ($timeframe eq 'week'){
$where->{'age(l.creation)'} = \\"<= interval \'$weekDay day\'";
} elsif ($timeframe eq 'month'){
$where->{'l.creation'} = '%'.$yearMonth.'%';
}
#$netdisco::SQLCARP=1;
$matches = sql_rows($tables,$cols,$where) || [];
#$netdisco::SQLCARP=0;
}
%init>
<%method report>
<%perl>
return unless defined $matches;
# Sort by routines
@$matches = sort { $b->{creation} <=> $a->{creation} } @$matches if $argsort eq 'Date';
if ($argsort eq 'User'){
@$matches = sort {
# Sort by username
if ($a->{username} ne $b->{username}) {
return ($a->{username} cmp $b->{username});
}
# Secondary sort by creation
return $b->{creation} <=> $a->{creation};
} @$matches;
}
if ($argsort eq 'Reason'){
@$matches = sort {
# Sort by Reason
if ($a->{reason} ne $b->{reason}){
return $a->{reason} cmp $b->{reason};
}
# 2nd Sort by Date
return $b->{creation} <=> $a->{creation};
} @$matches;
}
if ($argsort eq 'Port'){
@$matches = sort {
# Sort by IP
if ($a->{ip} ne $b->{ip}) {
# Anyone tell me why this will only work when I cast it to scalar???
return scalar &sort_ip;
}
# 2nd - Sort by Port
if ($a->{port} ne $b->{port}){
return scalar &sort_port;
}
# 3rd - Sort by date
return $b->{creation} <=> $a->{creation};
} @$matches;
}
%perl>
Matching Ports
% unless (scalar @$matches) {
No Ports Matching.
%return;}
<%scalar @$matches%> Ports matching.
% if ($argtype eq 'now'){
Showing log entries for ports that are currently disabled only.
% }
Port
Who
Reason/Action
Log
Date
% my $count = 0;
% foreach my $port (@$matches) {
% my $dev = $port->{dns} || $port->{ip};
% $dev =~ s/\Q$netdisco::CONFIG{domain}\E//;
% $count++;