From d0216b0ebbda203ba87ea388bc7e1235c9655d21 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Mon, 11 Mar 2019 18:31:26 +0000 Subject: [PATCH] move ssh code into Transport, part one --- .../Netdisco/Worker/Plugin/Arpnip/Nodes.pm | 94 ++++++------------- 1 file changed, 29 insertions(+), 65 deletions(-) diff --git a/lib/App/Netdisco/Worker/Plugin/Arpnip/Nodes.pm b/lib/App/Netdisco/Worker/Plugin/Arpnip/Nodes.pm index 75f33c57..e0adf4ad 100644 --- a/lib/App/Netdisco/Worker/Plugin/Arpnip/Nodes.pm +++ b/lib/App/Netdisco/Worker/Plugin/Arpnip/Nodes.pm @@ -9,16 +9,13 @@ use App::Netdisco::Util::Node qw/check_mac store_arp/; use App::Netdisco::Util::FastResolver 'hostnames_resolve_async'; use Dancer::Plugin::DBIC 'schema'; use Time::HiRes 'gettimeofday'; -use Module::Load (); -use Net::OpenSSH; -use Try::Tiny; register_worker({ phase => 'main', driver => 'snmp' }, sub { my ($job, $workerconf) = @_; my $device = $job->device; my $snmp = App::Netdisco::Transport::SNMP->reader_for($device) - or return Status->defer("arpnip snmp failed: could not SNMP connect to $device"); + or return Status->defer("arpnip failed: could not SNMP connect to $device"); # get v4 arp table my $v4 = get_arps_snmp($device, $snmp->at_paddr, $snmp->at_netaddr); @@ -32,15 +29,15 @@ register_worker({ phase => 'main', driver => 'snmp' }, sub { # update node_ip with ARP and Neighbor Cache entries store_arp(\%$_, $now) for @$v4; - debug sprintf ' [%s] arpnip snmp - processed %s ARP Cache entries', + debug sprintf ' [%s] arpnip - processed %s ARP Cache entries', $device->ip, scalar @$v4; store_arp(\%$_, $now) for @$v6; - debug sprintf ' [%s] arpnip snmp - processed %s IPv6 Neighbor Cache entries', + debug sprintf ' [%s] arpnip - processed %s IPv6 Neighbor Cache entries', $device->ip, scalar @$v6; $device->update({last_arpnip => \$now}); - return Status->done("Ended arpnip snmp for $device"); + return Status->done("Ended arpnip for $device"); }); # get an arp table (v4 or v6) @@ -70,74 +67,41 @@ register_worker({ phase => 'main', driver => 'cli' }, sub { my ($job, $workerconf) = @_; my $device = $job->device; - my ($ssh, $selected_auth) = App::Netdisco::Transport::CLI->session_for($device->ip, "sshcollector"); + my $cli = App::Netdisco::Transport::CLI->session_for($device) + or return Status->defer("arpnip failed: could not SSH connect to $device"); - if (get_arps_cli($device, $ssh, $selected_auth)){ - my $now = 'to_timestamp('. (join '.', gettimeofday) .')'; - $device->update({last_arpnip => \$now}); - my $endmsg = "Ended arpnip cli for $device"; + # should be both v4 and v6 + my $arps = get_arps_cli($device, $cli->arpnip); - if ($selected_auth->{'snmp_arpnip_also'}){ - $endmsg .= ", now running arpnip due to snmp_arpnip_also"; - info sprintf " [%s] arpnip cli - $endmsg", $device->ip; - return Status->info($endmsg); - }else{ - info sprintf " [%s] arpnip cli - $endmsg", $device->ip; - return Status->done($endmsg); - } - }else{ - Status->defer("arpnip cli failed"); - } + # update node_ip with ARP and Neighbor Cache entries + my $now = 'to_timestamp('. (join '.', gettimeofday) .')'; + store_arp(\%$_, $now) for @$arps; + debug sprintf ' [%s] arpnip - processed %s ARP / IPv6 Neighbor Cache entries', + $device->ip, scalar @$arps; + $device->update({last_arpnip => \$now}); + return Status->done("Ended arpnip for $device"); }); sub get_arps_cli { - my ($device, $ssh, $selected_auth) = @_; + my ($device, $entries) = @_; + my @arps = (); + $entries ||= []; - - unless ($ssh){ - my $msg = "could not connect to $device with SSH, deferring job"; - warning sprintf " [%s] arpnip cli - %s", $device->ip, $msg; - return undef; + foreach my $entry (@$entries) { + next unless check_mac( $entry->{mac} ); + push @arps, { + node => $entry->{mac}, + ip => $entry->{ip}, + dns => $entry->{dns}, + }; } - my $class = "App::Netdisco::SSHCollector::Platform::".$selected_auth->{platform}; - debug sprintf " [%s] arpnip cli - delegating to platform module %s", $device->ip, $class; + debug sprintf ' resolving %d ARP entries with max %d outstanding requests', + scalar @arps, $ENV{'PERL_ANYEVENT_MAX_OUTSTANDING_DNS'}; + my $resolved_ips = hostnames_resolve_async(\@arps); - my $load_failed = 0; - try { - Module::Load::load $class; - } catch { - warning sprintf " [%s] arpnip cli - failed to load %s: %s", $device->ip, $class, substr($_, 0, 50)."..."; - $load_failed = 1; - }; - return undef if $load_failed; - - my $platform_class = $class->new(); - my $arpentries = [ $platform_class->arpnip($device->ip, $ssh, $selected_auth) ]; - - if (not scalar @$arpentries) { - warning sprintf " [%s] WARNING: no entries received from device", $device->ip; - } - - hostnames_resolve_async($arpentries); - - foreach my $arpentry ( @$arpentries ) { - - # skip broadcast/vrrp/hsrp and other weirdos - next unless check_mac( $arpentry->{mac} ); - - debug sprintf ' [%s] arpnip cli - stored entry: %s / %s / %s', - $device->ip, $arpentry->{mac}, $arpentry->{ip}, - $arpentry->{dns} if defined $arpentry->{dns}; - store_arp({ - node => $arpentry->{mac}, - ip => $arpentry->{ip}, - dns => $arpentry->{dns}, - }); - } - - return 1; + return $resolved_ips; } true;