#1009 neighbour map depth and/or until end of lldp chains

* sidebar and style changes

* switch server code to new params and values

* working algo for cloud and neighbor depth

* store map positions for lldp cloud with depth

* color the root node uniquely

* restrict all devices, depth, cloud map to < 1000 devices
This commit is contained in:
Oliver Gorwits
2023-11-09 19:54:34 +00:00
committed by GitHub
parent b893d71e66
commit e52f789b45
9 changed files with 83 additions and 17 deletions

View File

@@ -11,7 +11,7 @@ __PACKAGE__->load_namespaces(
);
our # try to hide from kwalitee
$VERSION = 83; # schema version used for upgrades, keep as integer
$VERSION = 84; # schema version used for upgrades, keep as integer
use Path::Class;
use File::ShareDir 'dist_dir';

View File

@@ -17,6 +17,8 @@ __PACKAGE__->add_columns(
{ data_type => "text[]", is_nullable => 0 },
"vlan",
{ data_type => "integer", is_nullable => 0, default => 0 },
"depth",
{ data_type => "integer", is_nullable => 0, default => 0 },
"positions",
{ data_type => "text", is_nullable => 0 },
);

View File

@@ -86,6 +86,7 @@ get '/device' => require_login sub {
template 'device', {
netdisco_device => $first,
display_name => ($others ? $first->ip : ($first->dns || $first->ip)),
device_count => schema(vars->{'tenant'})->resultset('Device')->count(),
lgroup_list => [ schema(vars->{'tenant'})->resultset('Device')->get_distinct_col('location') ],
hgroup_list => setting('host_group_displaynames'),
device => params->{'tab'},

View File

@@ -30,7 +30,9 @@ ajax '/ajax/data/device/netmappositions' => require_login sub {
undef $vlan if (defined $vlan and $vlan !~ m/^\d+$/);
my $mapshow = param('mapshow');
return if !defined $mapshow or $mapshow !~ m/^(?:all|neighbors)$/;
return if !defined $mapshow or $mapshow !~ m/^(?:all|cloud|depth)$/;
my $depth = param('depth') || 1;
return if $depth !~ m/^\d+$/;
# list of groups selected by user and passed in param
my $hgroup = (ref [] eq ref param('hgroup') ? param('hgroup') : [param('hgroup')]);
@@ -56,7 +58,8 @@ ajax '/ajax/data/device/netmappositions' => require_login sub {
return unless scalar keys %clean;
my $posrow = schema(vars->{'tenant'})->resultset('NetmapPositions')->find({
device => (($mapshow eq 'neighbors') ? $qdev->ip : undef),
device => ($mapshow ne 'all' ? $qdev->ip : undef),
depth => ($mapshow eq 'depth' ? $depth : 0),
host_groups => \[ '= ?', [host_groups => [sort @hgrplist]] ],
locations => \[ '= ?', [locations => [sort @lgrplist]] ],
vlan => ($vlan || 0),
@@ -67,7 +70,8 @@ ajax '/ajax/data/device/netmappositions' => require_login sub {
}
else {
schema(vars->{'tenant'})->resultset('NetmapPositions')->create({
device => (($mapshow eq 'neighbors') ? $qdev->ip : undef),
device => ($mapshow ne 'all' ? $qdev->ip : undef),
depth => ($mapshow eq 'depth' ? $depth : 0),
host_groups => [sort @hgrplist],
locations => [sort @lgrplist],
vlan => ($vlan || 0),
@@ -143,8 +147,9 @@ ajax '/ajax/data/device/netmap' => require_login sub {
undef $vlan if (defined $vlan and $vlan !~ m/^\d+$/);
my $colorby = (param('colorby') || 'speed');
my $mapshow = (param('mapshow') || 'neighbors');
$mapshow = 'neighbors' if $mapshow !~ m/^(?:all|neighbors)$/;
my $mapshow = (param('mapshow') || 'depth');
my $depth = (param('depth') || 1);
$mapshow = 'depth' if $mapshow !~ m/^(?:all|cloud|depth)$/;
$mapshow = 'all' unless $qdev->in_storage;
# list of groups selected by user and passed in param
@@ -169,7 +174,7 @@ ajax '/ajax/data/device/netmap' => require_login sub {
my %seen_link = ();
my $links = schema(vars->{'tenant'})->resultset('Virtual::DeviceLinks')->search({
($mapshow eq 'neighbors' ? ( -or => [
(($mapshow eq 'depth' and $depth == 1) ? ( -or => [
{ left_ip => $qdev->ip },
{ right_ip => $qdev->ip },
]) : ())
@@ -193,10 +198,41 @@ ajax '/ajax/data/device/netmap' => require_login sub {
++$seen_link{$link->{left_ip} ."\0". $link->{right_ip}};
}
# filter by lldp cloud or depth
# this is O(N^2) or worse
my %cloud = ($qdev->ip => 1);
my $seen_cloud = scalar keys %cloud;
my $passes = ($mapshow eq 'cloud' ? 999 : $depth);
if ($mapshow eq 'cloud' or ($mapshow eq 'depth' and $depth > 1)) {
while ($seen_cloud > 0 and $passes > 0) {
--$passes;
$seen_cloud = 0;
foreach my $cip (keys %cloud) {
foreach my $okip (keys %ok_dev) {
next if exists $cloud{$okip};
if (exists $seen_link{$cip ."\0". $okip}
or exists $seen_link{$okip ."\0". $cip}) {
++$cloud{$okip};
++$seen_cloud;
}
}
}
}
}
elsif ($mapshow eq 'depth' and $depth == 1) {
%cloud = %ok_dev;
}
# DEVICES (NODES)
my $posrow = schema(vars->{'tenant'})->resultset('NetmapPositions')->find({
device => (($mapshow eq 'neighbors') ? $qdev->ip : undef),
device => ($mapshow ne 'all' ? $qdev->ip : undef),
depth => ($mapshow eq 'depth' ? $depth : 0),
host_groups => \[ '= ?', [host_groups => [sort @hgrplist]] ],
locations => \[ '= ?', [locations => [sort @lgrplist]] ],
vlan => ($vlan || 0),
@@ -219,8 +255,8 @@ ajax '/ajax/data/device/netmap' => require_login sub {
DEVICE: while (my $device = $devices->next) {
# if in neighbors mode then use %ok_dev to filter
next DEVICE if ($device->ip ne $qdev->ip)
and ($mapshow eq 'neighbors')
and (not $ok_dev{$device->ip}); # showing only neighbors but no link
and ($mapshow ne 'all')
and (not $cloud{$device->ip}); # showing only neighbors but no link
# if location picked then filter
next DEVICE if ((scalar @lgrplist) and ((!defined $device->location)
@@ -249,6 +285,7 @@ ajax '/ajax/data/device/netmap' => require_login sub {
ID => $device->ip,
SIZEVALUE => (param('dynamicsize') ? $color_lkp{speed} : 3000),
((exists $color_lkp{$colorby}) ? (COLORVALUE => $color_lkp{$colorby}) : ()),
(($device->ip eq $qdev->ip) ? (COLORVALUE => 'ROOTNODE') : ()),
LABEL => (param('showips') ? ($device->ip .' '. $name) : $name),
ORIG_LABEL => $name,
INFOSTRING => make_node_infostring($device),