include free ports calculation in SQL
This commit is contained in:
@@ -202,44 +202,6 @@ sub neighbor {
|
|||||||
return eval { $row->neighbor_alias->device || undef };
|
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
|
=head1 ADDITIONAL COLUMNS
|
||||||
|
|
||||||
=head2 tagged_vlans_count
|
=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') }
|
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;
|
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
|
=head2 with_vlan_count
|
||||||
|
|
||||||
This is a modifier for any C<search()> (including the helpers below) which
|
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
|
# make sure query asks for formatted timestamps when needed
|
||||||
$set = $set->with_times if param('c_lastchange');
|
$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'}],
|
prefetch => [{$nodes_name => 'ips'}, {neighbor_alias => 'device'}],
|
||||||
}) if param('c_connected');
|
}) if param('c_connected');
|
||||||
|
|
||||||
# sort, and filter by free ports
|
# sort ports (empty set would be a 'no records' msg)
|
||||||
# the filter could be in the template but here allows a 'no records' msg
|
my $results = [ sort { &netdisco::sort_port($a->port, $b->port) } $set->all ];
|
||||||
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 ];
|
|
||||||
|
|
||||||
return unless scalar @$results;
|
return unless scalar @$results;
|
||||||
|
|
||||||
content_type('text/html');
|
content_type('text/html');
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
<span class="label">s</span>
|
<span class="label">s</span>
|
||||||
[% ELSIF row.stp == 'blocking' %]
|
[% ELSIF row.stp == 'blocking' %]
|
||||||
<span class="label notice">b</span>
|
<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>
|
<span class="label success">f</span>
|
||||||
[% ELSIF row.up_admin == 'up' AND row.up == 'down' %]
|
[% ELSIF row.up_admin == 'up' AND row.up == 'down' %]
|
||||||
<span class="label warning">d</span>
|
<span class="label warning">d</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user