From c6bcaf66c59ab1b2debeed302068bf0db44614f6 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Sun, 5 May 2013 14:16:25 +0100 Subject: [PATCH] do not clobber manual topo when discovering neighbors --- Netdisco/lib/App/Netdisco/DB.pm | 2 +- .../lib/App/Netdisco/DB/Result/DevicePort.pm | 2 + .../App-Netdisco-DB-18-19-PostgreSQL.sql | 5 ++ .../lib/App/Netdisco/Util/DiscoverAndStore.pm | 89 +++++++++++-------- 4 files changed, 61 insertions(+), 37 deletions(-) create mode 100644 Netdisco/lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-18-19-PostgreSQL.sql diff --git a/Netdisco/lib/App/Netdisco/DB.pm b/Netdisco/lib/App/Netdisco/DB.pm index b3bb937b..63881db0 100644 --- a/Netdisco/lib/App/Netdisco/DB.pm +++ b/Netdisco/lib/App/Netdisco/DB.pm @@ -8,7 +8,7 @@ use base 'DBIx::Class::Schema'; __PACKAGE__->load_namespaces; -our $VERSION = 18; # schema version used for upgrades, keep as integer +our $VERSION = 19; # schema version used for upgrades, keep as integer use Path::Class; use File::Basename; diff --git a/Netdisco/lib/App/Netdisco/DB/Result/DevicePort.pm b/Netdisco/lib/App/Netdisco/DB/Result/DevicePort.pm index aad723cb..932d37aa 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/DevicePort.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/DevicePort.pm @@ -51,6 +51,8 @@ __PACKAGE__->add_columns( { data_type => "text", is_nullable => 1 }, "remote_id", { data_type => "text", is_nullable => 1 }, + "manual_topo", + { data_type => "bool", is_nullable => 0, default_value => \"false" }, "vlan", { data_type => "text", is_nullable => 1 }, "pvid", diff --git a/Netdisco/lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-18-19-PostgreSQL.sql b/Netdisco/lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-18-19-PostgreSQL.sql new file mode 100644 index 00000000..be8c3c48 --- /dev/null +++ b/Netdisco/lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-18-19-PostgreSQL.sql @@ -0,0 +1,5 @@ +BEGIN; + +ALTER TABLE device_port ADD COLUMN "manual_topo" bool DEFAULT false NOT NULL; + +COMMIT; diff --git a/Netdisco/lib/App/Netdisco/Util/DiscoverAndStore.pm b/Netdisco/lib/App/Netdisco/Util/DiscoverAndStore.pm index 91683158..dd32cb25 100644 --- a/Netdisco/lib/App/Netdisco/Util/DiscoverAndStore.pm +++ b/Netdisco/lib/App/Netdisco/Util/DiscoverAndStore.pm @@ -648,6 +648,12 @@ sub find_neighbors { } } + # IP Phone detection type fixup + if (defined $remote_type and $remote_type =~ m/(mitel.5\d{3})/i) { + $remote_type = 'IP Phone - '. $remote_type + if $remote_type !~ /ip phone/i; + } + # hack for devices seeing multiple neighbors on the port if (ref [] eq ref $remote_ip) { debug sprintf @@ -666,6 +672,12 @@ sub find_neighbors { $remote_port = $port; } else { + # what we came here to do.... discover the neighbor + debug sprintf + ' [%s] neigh - adding neighbor %s, type [%s], on %s to discovery queue', + $device->ip, $remote_ip, $remote_type, $port; + _enqueue_discover($remote_ip, $remote_type); + $remote_port = $c_port->{$entry}; if (defined $remote_port) { @@ -678,12 +690,7 @@ sub find_neighbors { } } - # XXX too custom? IP Phone detection - if (defined $remote_type and $remote_type =~ m/(mitel.5\d{3})/i) { - $remote_type = 'IP Phone - '. $remote_type - if $remote_type !~ /ip phone/i; - } - + # if all the data looks sane, update the port row with neighbor info my $portrow = schema('netdisco')->resultset('DevicePort') ->single({ip => $device->ip, port => $port}); @@ -693,17 +700,18 @@ sub find_neighbors { next; } + if ($portrow->manual_topo) { + info sprintf ' [%s] neigh - %s has manually defined topology', + $device->ip, $port; + next; + } + $portrow->update({ remote_ip => $remote_ip, remote_port => $remote_port, remote_type => $remote_type, remote_id => $remote_id, }); - - debug sprintf - ' [%s] neigh - adding neighbor %s, type [%s], on %s to discovery queue', - $device->ip, $remote_ip, $remote_type, $port; - _enqueue_discover($remote_ip, $remote_type); } } @@ -712,34 +720,43 @@ sub find_neighbors { sub _set_manual_topology { my ($device, $snmp) = @_; - my $topo_links = schema('netdisco')->resultset('Topology'); - debug sprintf ' [%s] neigh - setting manual topology links', $device->ip; + schema('netdisco')->txn_do(sub { + # clear manual topology flags + schema('netdisco')->resultset('DevicePort')->update({manual_topo => \'false'}); - while (my $link = $topo_links->next) { - # could fail for broken topo, but we ignore to try the rest - try { - schema('netdisco')->txn_do(sub { - # only work on root_ips - # skip bad entries - my $left = get_device($link->dev1) or return; - my $right = get_device($link->dev2) or return; + my $topo_links = schema('netdisco')->resultset('Topology'); + debug sprintf ' [%s] neigh - setting manual topology links', $device->ip; - $left->ports - ->single({port => $link->port1}) - ->update({ - remote_ip => $right->ip, - remote_port => $link->port2, - }); + while (my $link = $topo_links->next) { + # could fail for broken topo, but we ignore to try the rest + try { + schema('netdisco')->txn_do(sub { + # only work on root_ips + my $left = get_device($link->dev1); + my $right = get_device($link->dev2); - $right->ports - ->single({port => $link->port2}) - ->update({ - remote_ip => $left->ip, - remote_port => $link->port1, - }); - }); - }; - } + # skip bad entries + return unless ($left->in_storage and $right->in_storage); + + $left->ports + ->single({port => $link->port1}) + ->update({ + remote_ip => $right->ip, + remote_port => $link->port2, + manual_topo => \'true', + }); + + $right->ports + ->single({port => $link->port2}) + ->update({ + remote_ip => $left->ip, + remote_port => $link->port1, + manual_topo => \'true', + }); + }); + }; + } + }); } # only enqueue if device is not already discovered, and