Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Screen Scraping from Juniper Switch using Expect.pm - Multiple Commands

by julio-johnson (Initiate)
on May 05, 2015 at 02:10 UTC ( [id://1125652]=perlquestion: print w/replies, xml ) Need Help??

julio-johnson has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I'm trying to do some telnet/ssh (start with telnet for simplicity) screen scraping from a Juniper switch (netconf/snmp aren't available) using the Expect.pm perl module.

My goal is to be able to shove the output of a few commands into an array for each command. For example:

"show version" goes to @show_version and "show interfaces" goes to @show_interfaces

I've consulted http://search.cpan.org/~rgiersig/Expect-1.15/Expect.pod#NAME

I am failing utterly at this.

I can login to the switch and do a basic command and then wait for the session to timeout.

I've tried various combinations but I've so far failed at:

1. Understanding the flow control logic of the Expect module. So to figure out I'm logged in, I need to look for a CLI prompt. But how do I tell the difference between the initial login vs. subsequent prompts (after the successful completion of a CLI command)?

2. How do I piggy back several show commands together without logging out each time? I see that as part of the module's FAQ (How to expect on multiple spawned commands) where it mentions the -i parameter but I just don't get it.

#!/usr/bin/perl use strict; use warnings; use Expect; my $cmd1 = "show version | no-more "; my $access_protocol = 'telnet'; my $router = '172.16.2.1'; my $expect_log_file = 'expect-log-file.txt'; my $timeout = 15; my $username = 'username1'; my $password = 'asdfasdfasdf'; #Uncomment to hide stdout: #$Expect::Log_Stdout = 0; my $exp = Expect->spawn("$access_protocol $router") or die "Can't conn +ect to $router: $!\n"; $exp->expect ($timeout, ['(yes/no)',sub{my $fh = shift; $fh->send("yes\n"); exp_continue;}], ['(sername: )|(ogin: )$',sub{my $fh = shift; $fh->send("$username\n" +); exp_continue;}], ['(assword:)$',sub{my $fh = shift; $fh->send("$password\n"); exp_con +tinue;}], ['timeout',sub{&login_error();}], '-re', '> $', #wait for router prompt, then exit expect + ); $exp->log_file($expect_log_file); + $exp->expect ($timeout, ['',sub{my $fh = shift; $fh->send("$cmd1 \n");}] + ); $exp->expect ($timeout, ['More',sub{my $fh = shift; $fh->send(" "); exp_continue}], '-re', '[#>:]$', #wait for router prompt, then exit expect, + ); $exp->expect ($timeout, ['',sub{my $fh = shift; $fh->send("exit \n");}] + ); + sub login_error { print "Unable to login to router $router. Try to login manually wit +h SSH. \n"; exit; }
perl ./exp_1.pl Trying 172.16.2.1... Connected to 172.16.2.1 (172.16.2.1). Escape character is '^]'. EX3200-J (ttyp1) login: username1 Password: --- JUNOS 12.3R6.6 built 2014-03-13 06:58:47 UTC username1@EX3200-J> show version | no-more Hostname: EX3200-J Model: ex3200-24t JUNOS Base OS boot [12.3R6.6] JUNOS Base OS Software Suite [12.3R6.6] JUNOS Kernel Software Suite [12.3R6.6] JUNOS Crypto Software Suite [12.3R6.6] JUNOS Online Documentation [12.3R6.6] JUNOS Enterprise Software Suite [12.3R6.6] JUNOS Packet Forwarding Engine Enterprise Software Suite [12.3R6.6] JUNOS Routing Software Suite [12.3R6.6] JUNOS Web Management [12.3R6.6] JUNOS FIPS mode utilities [12.3R6.6] username1@EX3200-J>

Replies are listed 'Best First'.
Re: Screen Scraping from Juniper Switch using Expect.pm - Multiple Commands
by RonW (Parson) on May 05, 2015 at 22:09 UTC
    I need to look for a CLI prompt. But how do I tell the difference between the initial login vs. subsequent prompts (after the successful completion of a CLI command)?

    Presumably, you have used telnet/ssh to manually log in to the switch to run commands. Is the CLI prompt really identical to the login prompt? What about text that precedes the prompts? Often there is some kind of "welcome" text before the login prompt.

    If there's really no difference in the prompts and no other text you can look for, then just issue the command and look for another prompt. Then assume it is a CLI prompt and issue the next command.

Re: Screen Scraping from Juniper Switch using Expect.pm - Multiple Commands
by mrdavis94 (Initiate) on Jun 17, 2015 at 14:48 UTC
    Julio -

    I've updated your script a little and I believe this is what you're looking to do. Since it's looking for a specific "$match" string, password prompt and "---more" string, this will only work on JunOS. You can modify it for other vendors - or get cute with regex and make it multi-vendor.
    #!/usr/bin/perl use Expect; my $access_protocol = 'ssh'; my $host = 'myhost.mycompany.com'; my $timeout = 15; my $username = 'svc_network_readonly'; my $password = 'sc00byd00byD00'; $Expect::Log_Stdout = 0; my @commands = ("show virtual-chassis", "show version", "show arp no-r +esolve", "show ethernet-switching table", "exit"); my $exp = Expect->spawn("$access_protocol -l $username $host") or die +"Can't connect to $host: $!\n"; my $match="^$username\@$host. "; $exp->expect ($timeout, ['^\-\-\-.more', sub { $x = $exp->before(); print "$x"; $exp->send(" "); exp_continue; }], [ qr /$username\@$host\'s password: /, sub { $exp->send("$password\n"); exp_continue; }], [ $match, sub { my $cmd=shift(@commands); $x = $exp->before(); print "$x"; $exp->send("$cmd\n"); exp_continue; }], ['timeout', sub { print "A timeout has occurred - no match found\n"; }], '-re', '] $');

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1125652]
Approved by kevbot
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2024-03-19 04:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found