App-Netdisco
view release on metacpan or search on metacpan
lib/App/Netdisco/Worker/Plugin/Discover/Neighbors.pm view on Meta::CPAN
package App::Netdisco::Worker::Plugin::Discover::Neighbors;
use Dancer ':syntax';
use App::Netdisco::Worker::Plugin;
use aliased 'App::Netdisco::Worker::Status';
use App::Netdisco::Transport::SNMP ();
use App::Netdisco::Util::Device qw/get_device is_discoverable match_to_setting/;
use App::Netdisco::Util::Permission 'acl_matches';
use App::Netdisco::JobQueue 'jq_insert';
use Dancer::Plugin::DBIC 'schema';
use List::Util 'pairs';
use NetAddr::IP::Lite ();
use NetAddr::MAC;
use Encode;
use Try::Tiny;
=head2 discover_new_neighbors( )
Given a Device database object, and a working SNMP connection, discover and
store the device's port neighbors information.
Entries in the Topology database table will override any discovered device
port relationships.
The Device database object can be a fresh L<DBIx::Class::Row> object which is
not yet stored to the database.
Any discovered neighbor unknown to Netdisco will have a C<discover> job
immediately queued (subject to the filtering by the C<discover_*> settings).
=cut
register_worker({ phase => 'main', driver => 'snmp' }, sub {
my ($job, $workerconf) = @_;
my $device = $job->device;
return unless $device->in_storage;
if (acl_matches($device, 'skip_neighbors') or not setting('discover_neighbors')) {
return Status->info(
sprintf ' [%s] neigh - neighbor discovery is disabled on this device',
$device->ip);
}
my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
or return Status->defer("discover failed: could not SNMP connect to $device");
my @to_discover = store_neighbors($device);
my (%seen_id, %seen_ip) = ((), ());
# only enqueue if device is not already discovered,
# discover_* config permits the discovery
foreach my $neighbor (@to_discover) {
my ($ip, $remote_id) = @$neighbor;
if ($seen_ip{ $ip }++) {
debug sprintf
' queue - skip: IP %s is already queued from %s',
$ip, $device->ip;
next;
}
if ($remote_id and $seen_id{ $remote_id }++) {
debug sprintf
' queue - skip: %s with ID [%s] already queued from %s',
$ip, $remote_id, $device->ip;
next;
}
my $newdev = get_device($ip);
next if $newdev->in_storage;
# risk of things going wrong...?
# https://quickview.cloudapps.cisco.com/quickview/bug/CSCur12254
jq_insert({
( run in 0.763 second using v1.01-cache-2.11-cpan-39bf76dae61 )