diff --git a/lib/App/Netdisco/DB/Result/Virtual/PortUtilization.pm b/lib/App/Netdisco/DB/Result/Virtual/PortUtilization.pm index f08bac65..f0f0638e 100644 --- a/lib/App/Netdisco/DB/Result/Virtual/PortUtilization.pm +++ b/lib/App/Netdisco/DB/Result/Virtual/PortUtilization.pm @@ -17,11 +17,28 @@ __PACKAGE__->result_source_instance->view_definition(< ?::interval )) THEN 1 - ELSE 0 END) as ports_free - FROM device d LEFT JOIN device_port dp + sum(CASE + WHEN ( dp.type != 'propVirtual' AND dp.up_admin = 'up' AND dp.up != 'up' + AND (age(now(), to_timestamp(extract(epoch from d.last_discover) - (d.uptime/100))) < ?::interval) + AND (last_node.time_last IS NULL OR (age(now(), last_node.time_last)) > ?::interval) ) + THEN 1 + WHEN ( dp.type != 'propVirtual' AND dp.up_admin = 'up' AND dp.up != 'up' + AND (last_node.time_last IS NULL OR + (age(now(), to_timestamp(extract(epoch from d.last_discover) - (d.uptime - dp.lastchange)/100)) > ?::interval)) ) + THEN 1 + ELSE 0 + END) as ports_free + FROM device d + LEFT JOIN device_port dp ON d.ip = dp.ip + LEFT JOIN node last_node + ON last_node.mac = ( + SELECT lastnodesub.mac + FROM node lastnodesub + WHERE port = dp.port AND switch = dp.ip + ORDER BY time_last DESC + LIMIT '1' + ) GROUP BY d.dns, d.ip ORDER BY d.dns, d.ip ENDSQL diff --git a/lib/App/Netdisco/DB/ResultSet/DevicePort.pm b/lib/App/Netdisco/DB/ResultSet/DevicePort.pm index 59bf21b6..bdf26435 100644 --- a/lib/App/Netdisco/DB/ResultSet/DevicePort.pm +++ b/lib/App/Netdisco/DB/ResultSet/DevicePort.pm @@ -96,14 +96,22 @@ sub only_free_ports { ->search_rs($cond, $attrs) ->search( { - 'me.up' => { '!=' => 'up' }, - },{ - where => - \["age(now(), to_timestamp(extract(epoch from device.last_discover) " - ."- (device.uptime - me.lastchange)/100)) " - ."> ?::interval", + 'me.up_admin' => 'up', + 'me.up' => { '!=' => 'up' }, + 'me.type' => { '!=' => 'propVirtual' }, + -or => [ + -and => [ + \["age(now(), to_timestamp(extract(epoch from device.last_discover) - (device.uptime/100))) < ?::interval", + [{} => $interval]], + -or => [ + 'last_node.time_last' => undef, + \["age(now(), last_node.time_last) > ?::interval", [{} => $interval]], + ] + ], + \["age(now(), to_timestamp(extract(epoch from device.last_discover) - (device.uptime - me.lastchange)/100)) > ?::interval", [{} => $interval]], - join => 'device' }, + ], + },{ join => [qw/device last_node/] }, ); } diff --git a/lib/App/Netdisco/Web/Plugin/Report/PortUtilization.pm b/lib/App/Netdisco/Web/Plugin/Report/PortUtilization.pm index 399ee51e..ad06f3e7 100644 --- a/lib/App/Netdisco/Web/Plugin/Report/PortUtilization.pm +++ b/lib/App/Netdisco/Web/Plugin/Report/PortUtilization.pm @@ -20,7 +20,7 @@ get '/ajax/content/report/portutilization' => require_login sub { my $age_num = param('age_num') || 3; my $age_unit = param('age_unit') || 'months'; my @results = schema('netdisco')->resultset('Virtual::PortUtilization') - ->search(undef, { bind => [ "$age_num $age_unit" ] })->hri->all; + ->search(undef, { bind => [ "$age_num $age_unit", "$age_num $age_unit", "$age_num $age_unit" ] })->hri->all; if (request->is_ajax) { my $json = to_json (\@results);