From 51810525acf92c628150a3e5c9c1bb94749a38d3 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Sat, 1 Oct 2016 18:26:44 +0100 Subject: [PATCH] Check Point VSX sshcollector support (M. Kosmach) --- Netdisco/Changes | 1 + Netdisco/bin/netdisco-sshcollector | 10 +- .../Netdisco/SSHCollector/Platform/CPVSX.pm | 142 ++++++++++++++++++ 3 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 Netdisco/lib/App/Netdisco/SSHCollector/Platform/CPVSX.pm diff --git a/Netdisco/Changes b/Netdisco/Changes index ed53c852..3176c05b 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -3,6 +3,7 @@ [NEW FEATURES] * FreeBSD sshcollector support (H. Teulahti) + * Check Point VSX sshcollector support (M. Kosmach) * Allow port name to be changed on pseudo devices [ENHANCEMENTS] diff --git a/Netdisco/bin/netdisco-sshcollector b/Netdisco/bin/netdisco-sshcollector index d57b66fb..6b62e050 100755 --- a/Netdisco/bin/netdisco-sshcollector +++ b/Netdisco/bin/netdisco-sshcollector @@ -178,18 +178,20 @@ Currently, ARP tables can be retrieved from the following device classes: =over 4 +=item * L - Check Point VSX + =item * L - Cisco ACE =item * L - Cisco ASA -=item * L - F5 Networks BigIP - -=item * L - FreeBSD - =item * L - Cisco IOS =item * L - Cisco IOS XR +=item * L - F5 Networks BigIP + +=item * L - FreeBSD + =item * L - Linux =item * L - Palo Alto diff --git a/Netdisco/lib/App/Netdisco/SSHCollector/Platform/CPVSX.pm b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/CPVSX.pm new file mode 100644 index 00000000..c2edd764 --- /dev/null +++ b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/CPVSX.pm @@ -0,0 +1,142 @@ +package App::Netdisco::SSHCollector::Platform::CPVSX; + +=head1 NAME + +App::Netdisco::SSHCollector::Platform::CPVSX + +=head1 DESCRIPTION + +Collect ARP entries from Check Point VSX + +This collector uses "C" as the command for the arp utility on your +system. Clish "C" dows not work correctly in versions prior to R77.30. +Config example: + + sshcollector: + - ip: '192.0.2.1' + user: oliver + password: letmein + expert_password: letmein2 + platform: CPVSX + +=cut + +use strict; +use warnings; + +use Dancer ':script'; +use Expect; +use Moo; + +=head1 PUBLIC METHODS + +=over 4 + +=item B + +Retrieve ARP entries from device. C<$host> is the hostname or IP address +of the device. C<$ssh> is a Net::OpenSSH connection to the device. + +Returns a list of hashrefs in the format C<< { mac => MACADDR, ip => IPADDR } >>. + +=back + +=cut + +sub arpnip { + my ($self, $hostlabel, $ssh, $args) = @_; + + my @arpentries = (); + + debug "$hostlabel $$ arpnip()"; + + my ($pty, $pid) = $ssh->open2pty or die "unable to run remote command"; + my $expect = Expect->init($pty); + + my ($pos, $error, $match, $before, $after); + my $prompt; + + $prompt = qr/>/; + ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + + # TODO: check CP os/version via "cpstat os" and VSX status via "show vsx" + # $expect->send("show vsx\n"); + # ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + # debug "$hostlabel $$ show vsx: $before"; + + # Enumerate virtual systems + # Virtual systems list + # VS ID VS NAME + # 0 0 + # 1 BACKUP-VSX_xxxxxx_Context + # ... + + $expect->send("show virtual-system all\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + + my @vsxentries = (); + my @lines = split(m/\n/, $before); + + my $linereg = qr/(\d+)\s+([A-Za-z0-9_-]+)/; + foreach my $line (@lines) { + if ($line =~ $linereg) { + my ($vsid, $vsname) = ($1, $2); + push @vsxentries, { vsid => $vsid, vsname=> $vsname }; + debug "$hostlabel $$ $vsid, $vsname"; + } + } + + # TODO: + # Expert mode should be used only for pre-R77.30 versions + # For R77.30 and later we can use: + # set virtual-system $vsid + # show arp dynamic all + + $expect->send("expert\n"); + + $prompt = qr/Enter expert password:/; + ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + + $expect->send( $args->{expert_password} ."\n" ); + + $prompt = qr/#/; + ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + + foreach (@vsxentries) { + my $vsid = $_->{vsid}; + debug "$hostlabel $$ arpnip VSID: $vsid"; + + $expect->send("vsenv $vsid\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + + $expect->send("arp -n | tail -n +2\n"); + ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); + + @lines = split(m/\n/, $before); + + # 192.168.1.1 ether 00:b6:aa:f5:bb:6e C eth1 + $linereg = qr/([0-9\.]+)\s+ether\s+([a-fA-F0-9:]+)/; + + foreach my $line (@lines) { + if ($line =~ $linereg) { + my ($ip, $mac) = ($1, $2); + push @arpentries, { mac => $mac, ip => $ip }; + debug "$hostlabel $$ arpnip VSID: $vsid IP: $ip MAC: $mac"; + } + } + + } + + $expect->send("exit\n"); + + $prompt = qr/>/; + ($pos, $error, $match, $before, $after) = $expect->expect(5, -re, $prompt); + + $expect->send("exit\n"); + + $expect->soft_close(); + + return @arpentries; +} + +1;