diff --git a/lib/App/Netdisco/DB/Result/Virtual/DeviceLinks.pm b/lib/App/Netdisco/DB/Result/Virtual/DeviceLinks.pm index 429e3b05..fe61a2d7 100644 --- a/lib/App/Netdisco/DB/Result/Virtual/DeviceLinks.pm +++ b/lib/App/Netdisco/DB/Result/Virtual/DeviceLinks.pm @@ -7,22 +7,43 @@ use base 'DBIx::Class::Core'; __PACKAGE__->table_class('DBIx::Class::ResultSource::View'); +# notes to future devs: + +# this query does not use the slave_of field in device_port table to group +# ports because what we actually want is total b/w between devices on all +# links, regardless of whether those links are in an aggregate. + +# PG 8.4 does not have sorting within an aggregate so we cannot ensure that +# left and right ports and names correspond within arrays. this is why the +# right ports are the left's remote_ports (and right_descr should be ignored) + __PACKAGE__->table('device_links'); __PACKAGE__->result_source_instance->is_virtual(1); __PACKAGE__->result_source_instance->view_definition(< ARRAY[dp2.port]) WHERE dp.ip <= dp2.ip + GROUP BY left_ip, left_port, left_descr, aggspeed, aggports, right_ip, right_port ORDER BY dp.ip ENDSQL ); @@ -32,29 +53,46 @@ __PACKAGE__->add_columns( data_type => 'inet', }, 'left_port' => { - data_type => 'text', + data_type => '[text]', }, 'left_descr' => { - data_type => 'text', + data_type => '[text]', }, - 'speed' => { - data_type => 'text', + 'aggspeed' => { + data_type => 'integer', + }, + 'aggports' => { + data_type => 'integer', }, 'right_ip' => { data_type => 'inet', }, 'right_port' => { - data_type => 'text', + data_type => '[text]', }, 'right_descr' => { - data_type => 'text', + data_type => '[text]', }, ); __PACKAGE__->has_many('left_vlans', 'App::Netdisco::DB::Result::DevicePortVlan', - { 'foreign.ip' => 'self.left_ip', 'foreign.port' => 'self.left_port' }); + sub { + my $args = shift; + return { + "$args->{foreign_alias}.ip" => { -ident => "$args->{self_alias}.left_ip" }, + "$args->{self_alias}.left_port" => { '@>' => \"ARRAY[$args->{foreign_alias}.port]" }, + }; + } +); __PACKAGE__->has_many('right_vlans', 'App::Netdisco::DB::Result::DevicePortVlan', - { 'foreign.ip' => 'self.right_ip', 'foreign.port' => 'self.right_port' }); + sub { + my $args = shift; + return { + "$args->{foreign_alias}.ip" => { -ident => "$args->{self_alias}.right_ip" }, + "$args->{self_alias}.right_port" => { '@>' => \"ARRAY[$args->{foreign_alias}.port]" }, + }; + } +); 1; diff --git a/lib/App/Netdisco/Web/Plugin/Device/Neighbors.pm b/lib/App/Netdisco/Web/Plugin/Device/Neighbors.pm index 62077891..990eee3e 100644 --- a/lib/App/Netdisco/Web/Plugin/Device/Neighbors.pm +++ b/lib/App/Netdisco/Web/Plugin/Device/Neighbors.pm @@ -5,6 +5,7 @@ use Dancer::Plugin::Ajax; use Dancer::Plugin::DBIC; use Dancer::Plugin::Auth::Extensible; +use SNMP::Info (); use List::Util 'first'; use List::MoreUtils (); use App::Netdisco::Util::Permission 'check_acl_only'; @@ -64,6 +65,13 @@ ajax '/ajax/data/device/netmappositions' => require_login sub { } }; +sub to_speed { + my $speed = shift or return ''; + $speed = SNMP::Info::munge_highspeed($speed); + $speed =~ s/(?:\s|bps)//g; + return $speed; +} + ajax '/ajax/data/device/netmap' => require_login sub { my $q = param('q'); my $qdev = schema('netdisco')->resultset('Device') @@ -96,10 +104,7 @@ ajax '/ajax/data/device/netmap' => require_login sub { { left_ip => $qdev->ip }, { right_ip => $qdev->ip }, ]) : ()) - }, { - columns => [qw/left_ip speed right_ip/], - result_class => 'DBIx::Class::ResultClass::HashRefInflator', - }); + }, { result_class => 'DBIx::Class::ResultClass::HashRefInflator' }); if ($vlan) { $links = $links->search({ @@ -116,7 +121,7 @@ ajax '/ajax/data/device/netmap' => require_login sub { push @{$data{'links'}}, { FROMID => $link->{left_ip}, TOID => $link->{right_ip}, - SPEED => $link->{speed}, + SPEED => to_speed($link->{aggspeed}), }; ++$ok_dev{$link->{left_ip}};