include free ports calculation in SQL
This commit is contained in:
@@ -202,44 +202,6 @@ sub neighbor {
|
||||
return eval { $row->neighbor_alias->device || undef };
|
||||
}
|
||||
|
||||
=head2 is_free( $quantity, $unit )
|
||||
|
||||
This method can be used to evaluate whether a device port could be considered
|
||||
unused, based on the last time it changed from the "up" state to a "down"
|
||||
state.
|
||||
|
||||
Pass in two parameters, first the C<$quantity> which must be an integer, and
|
||||
second the C<$unit> which must be a string of either C<days>, C<weeks>,
|
||||
C<months> or C<years>.
|
||||
|
||||
A True value is returned if the port is in a "down" state but administratively
|
||||
"up", yet last changed state at or further back than the parameters' time
|
||||
window. If the port is not in the correct state, or last changed state more
|
||||
recently, then a False value is returned.
|
||||
|
||||
=cut
|
||||
|
||||
sub is_free {
|
||||
my ($row, $num, $unit) = @_;
|
||||
return unless $num =~ m/^\d+$/
|
||||
and $unit =~ m/(?:days|weeks|months|years)/;
|
||||
|
||||
return 0 unless
|
||||
($row->up_admin and $row->up_admin eq 'up')
|
||||
and ($row->up and $row->up eq 'down');
|
||||
|
||||
my $quan = {
|
||||
days => (60 * 60 * 24),
|
||||
weeks => (60 * 60 * 24 * 7),
|
||||
months => (60 * 60 * 24 * 31),
|
||||
years => (60 * 60 * 24 * 365),
|
||||
};
|
||||
my $total = $num * $quan->{$unit};
|
||||
|
||||
my $diff_sec = $row->lastchange / 100;
|
||||
return ($diff_sec >= $total ? 1 : 0);
|
||||
}
|
||||
|
||||
=head1 ADDITIONAL COLUMNS
|
||||
|
||||
=head2 tagged_vlans_count
|
||||
@@ -265,4 +227,16 @@ between the date stamp and time stamp. That is:
|
||||
|
||||
sub lastchange_stamp { return (shift)->get_column('lastchange_stamp') }
|
||||
|
||||
=head2 is_free
|
||||
|
||||
This method can be used to evaluate whether a device port could be considered
|
||||
unused, based on the last time it changed from the "up" state to a "down"
|
||||
state.
|
||||
|
||||
See the C<with_is_free> and C<only_free_ports> modifiers to C<search()>.
|
||||
|
||||
=cut
|
||||
|
||||
sub is_free { return (shift)->get_column('is_free') }
|
||||
|
||||
1;
|
||||
|
||||
@@ -35,6 +35,75 @@ sub with_times {
|
||||
});
|
||||
}
|
||||
|
||||
=head2 with_free_ports
|
||||
|
||||
This is a modifier for any C<search()> (including the helpers below) which
|
||||
will add the following additional synthesized columns to the result set:
|
||||
|
||||
=over 4
|
||||
|
||||
=item is_free
|
||||
|
||||
=back
|
||||
|
||||
In the C<$cond> hash (the first parameter) pass in the C<age_num> which must
|
||||
be an integer, and the C<age_unit> which must be a string of either C<days>,
|
||||
C<weeks>, C<months> or C<years>.
|
||||
|
||||
=cut
|
||||
|
||||
sub with_is_free {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
my $interval = (delete $cond->{age_num}) .' '. (delete $cond->{age_unit});
|
||||
|
||||
return $rs
|
||||
->search_rs($cond, $attrs)
|
||||
->search({},
|
||||
{
|
||||
'+select' => [
|
||||
\["up != 'up' and "
|
||||
."age(to_timestamp(extract(epoch from device.last_discover) "
|
||||
."- (device.uptime - lastchange)/100)) "
|
||||
."> ?::interval",
|
||||
[{} => $interval]],
|
||||
],
|
||||
'+as' => [qw/ is_free /],
|
||||
join => 'device',
|
||||
});
|
||||
}
|
||||
|
||||
=head2 only_free_ports
|
||||
|
||||
This is a modifier for any C<search()> (including the helpers below) which
|
||||
will restrict results based on whether the port is considered "free".
|
||||
|
||||
In the C<$cond> hash (the first parameter) pass in the C<age_num> which must
|
||||
be an integer, and the C<age_unit> which must be a string of either C<days>,
|
||||
C<weeks>, C<months> or C<years>.
|
||||
|
||||
=cut
|
||||
|
||||
sub only_free_ports {
|
||||
my ($rs, $cond, $attrs) = @_;
|
||||
|
||||
my $interval = (delete $cond->{age_num}) .' '. (delete $cond->{age_unit});
|
||||
|
||||
return $rs
|
||||
->search_rs($cond, $attrs)
|
||||
->search(
|
||||
{
|
||||
'up' => { '!=' => 'up' },
|
||||
},{
|
||||
where =>
|
||||
\["age(to_timestamp(extract(epoch from device.last_discover) "
|
||||
."- (device.uptime - lastchange)/100)) "
|
||||
."> ?::interval",
|
||||
[{} => $interval]],
|
||||
join => 'device' },
|
||||
);
|
||||
}
|
||||
|
||||
=head2 with_vlan_count
|
||||
|
||||
This is a modifier for any C<search()> (including the helpers below) which
|
||||
|
||||
@@ -93,6 +93,13 @@ ajax '/ajax/content/device/ports' => sub {
|
||||
}
|
||||
}
|
||||
|
||||
# filter for free ports if asked
|
||||
my $free_filter = (param('free') ? 'only_free_ports' : 'with_is_free');
|
||||
$set = $set->$free_filter({
|
||||
age_num => (param('age_num') || 3),
|
||||
age_unit => (param('age_unit') || 'months')
|
||||
});
|
||||
|
||||
# make sure query asks for formatted timestamps when needed
|
||||
$set = $set->with_times if param('c_lastchange');
|
||||
|
||||
@@ -108,12 +115,8 @@ ajax '/ajax/content/device/ports' => sub {
|
||||
prefetch => [{$nodes_name => 'ips'}, {neighbor_alias => 'device'}],
|
||||
}) if param('c_connected');
|
||||
|
||||
# sort, and filter by free ports
|
||||
# the filter could be in the template but here allows a 'no records' msg
|
||||
my $results = [ sort { &netdisco::sort_port($a->port, $b->port) }
|
||||
grep { not param('free')
|
||||
or $_->is_free(param('age_num'), param('age_unit')) } $set->all ];
|
||||
|
||||
# sort ports (empty set would be a 'no records' msg)
|
||||
my $results = [ sort { &netdisco::sort_port($a->port, $b->port) } $set->all ];
|
||||
return unless scalar @$results;
|
||||
|
||||
content_type('text/html');
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<span class="label">s</span>
|
||||
[% ELSIF row.stp == 'blocking' %]
|
||||
<span class="label notice">b</span>
|
||||
[% ELSIF row.is_free(params.age_num, params.age_unit) %]
|
||||
[% ELSIF params.free OR row.is_free %]
|
||||
<span class="label success">f</span>
|
||||
[% ELSIF row.up_admin == 'up' AND row.up == 'down' %]
|
||||
<span class="label warning">d</span>
|
||||
|
||||
Reference in New Issue
Block a user