Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Net::OpenSHH unable to execute multiple commands with Cisco CRS?

by Dranzaz (Sexton)
on Jan 30, 2014 at 16:29 UTC ( [id://1072700]=perlquestion: print w/replies, xml ) Need Help??

Dranzaz has asked for the wisdom of the Perl Monks concerning the following question:

I searched around and have been unable to find any solution to the targeted issue I am having.

Purpose: This code is part of a larger script that polls our routers daily to help keep our DataBase up to date on our network connections and bandwidth availability.

Symptoms: The below stripped down code works fine with juniper routers and Cisco IOS based routers with minor tweaks the the command be passed. Unfortunately with the Cisco XR-IOS based routers, multiple command requests are failing after the first completes.

Other Notes: I have tried Net::SSH:Perl and Expect and they do not seem to be able to handle the manner in which the XR-IOS is passing the "security" banner. If I rework the code so that it starts a new ssh connection on each speed check then it gets through all the Database entries. the problem with that is for security reasons we lock the number of connections in a 5 minute period down, this results in the need for a "sleep" timer in the code which severely delays the completion of the script.

What am i looking for: I am hoping someone else has seen something like this and can offer assistance in getting the script to pass multiple commands in a single ssh connection to each router.

Below is the code and it's output. Any assistance or guidance is greatly appreciated.

#!/usr/bin/perl -w use Net::Ping; use Net::OpenSSH; $username = "user"; $password = "pass"; @interface = (); #Input data to fill above variables get_router_data(); $listfiles = system("ls -al /root/scripts/logs/interfaces/"); $deletefiles = system("rm -rf /root/scripts/logs/interfaces/*"); print "$listfiles\n$deletefiles\n\n"; print "\nAttempting to connect to routers...\n"; $pingtest = Net::Ping->new("icmp"); cisco_test(); print "\n\nThe End....\n\n"; sub get_router_data { $hostname = "router1"; $interface[0] = "Bundle-Ether11"; $interface[1] = "Bundle-Ether12"; $routercount = 2; } sub cisco_test { if ($pingtest->ping($hostname, 2)) { $ssh = Net::OpenSSH->new("$hostname", user => $username, passw +ord => $password, master_stderr_discard => 1) || warn("\$!\n"); $testcount = 0; while ($testcount < $routercount) { $reportedspeed = 0; print "\n\nPolling $hostname $interface[$testcount] ...... +... please wait\n"; open (LOGONE, ">/root/scripts/logs/interfaces/log.$hostnam +e.$interface[$testcount].txt"); $out = $ssh -> capture ("show interfaces $interface[$testc +ount] | include BW"); print "$out\n"; print LOGONE $out; close (LOGONE); open (LOGTWO, "/root/scripts/logs/interfaces/log.$hostname +.$interface[$testcount].txt"); while ( <LOGTWO> ) { @splitset = split (/\s+/, $_); $speedcount = 0; foreach $splittest (@splitset) { if ($splittest =~ /BW/) { $locationcount = $speedcount+1; $reportedspeed = $splitset[$locationcount]; } $speedcount++; } } print "Reported Speed: $reportedspeed ...... \n"; close (LOGTWO); $testcount++; } } }

Output of the above script:
[scripts]# perl cisco_crs_int_check.pl total 24 drwxr-xr-x. 2 root root 16384 Jan 30 10:50 . drwxr-xr-x. 4 root root 4096 Jan 29 10:12 .. -rw-r--r--. 1 root root 92 Jan 30 10:50 log.router1.Bundle-Ether11. +txt -rw-r--r--. 1 root root 0 Jan 30 10:50 log.router1.Bundle-Ether12. +txt 0 0 Attempting to connect to routers... Polling router1 Bundle-Ether11 ......... please wait Thu Jan 30 15:51:37.001 UTC MTU 9192 bytes, BW 240000000 Kbit (Max: 240000000 Kbit) Reported Speed: 240000000 ...... Polling router1 Bundle-Ether12 ......... please wait mux_client_request_session: read from master failed: Broken pipe ssh_exchange_identification: read: Connection reset by peer Reported Speed: 0 ...... The End....

Replies are listed 'Best First'.
Re: Net::OpenSHH unable to execute multiple commands with Cisco CRS?
by salva (Canon) on Jan 30, 2014 at 16:47 UTC
    It is not unusual for network equipment to have crappy SSH implementations and that seems to be the case you are currently facing.

    You have two options

    • Ask Cisco to fix the SSH server software in those routers (it would not be the first time I see that happening).
    • Use Expect on top of Net::OpenSSH to talk to the router shell and run several commands in the same session.
Re: Net::OpenSHH unable to execute multiple commands with Cisco CRS?
by Dranzaz (Sexton) on Jan 30, 2014 at 20:04 UTC
    Update:

    Thanks for the suggestions, they got the old grey matter moving. I tried a few attempts with both suggestions (Expect & CLI). Neither proved fruitful immediately. However, as it so happens all to often for me, something in the examples of the other modules gave me a potential modification to the original approach.

    I'm putting the code and output below for the benefit of others in case they are attempting something simular with the XR-IOS boxes from Cisco.

    What I ended up doing was removing the loop for each command after the ssh connection was established. I instead added a check of the interface description followed by the original command. This was looped to create a single variable containing all the interfaces to be passed after the connection was made. It'may not be the prettiest but it is effective. I just now have to apply it to the larger script I am attempting to update.

    Again, tahnks for the suggestions and making me look at this from a different perspective.
    #!/usr/bin/perl -w use Net::Ping; use Net::OpenSSH; $username = "user"; $password = "password"; @interface = (); #Input data to fill above variables get_router_data(); $listfiles = system("ls -al /root/scripts/logs/interfaces/"); $deletefiles = system("rm -rf /root/scripts/logs/interfaces/*"); print "$listfiles\n$deletefiles\n\n"; print "\nAttempting to connect to routers...\n"; $pingtest = Net::Ping->new("icmp"); cisco_test(); print "\n\nThe End....\n\n"; sub get_router_data { $hostname = "router1"; $interface[0] = "Bundle-Ether11"; $interface[1] = "Bundle-Ether12"; $cmd = ""; foreach $intname (@interface) { $cmd = "$cmd\nshow interfaces $intname | include Bundle\nshow +interfaces $intname | include BW\n"; } } sub cisco_test { if ($pingtest->ping($hostname, 2)) { $ssh = Net::OpenSSH->new("$hostname", user => $username, passw +ord => $password, master_stderr_discard => 1) || warn("\$!\n"); $testcount = 0; print "\n\nPolling $hostname ......... please wait\n"; open (LOGONE, ">/root/scripts/logs/interfaces/log.$hostname.tx +t"); $out = $ssh -> capture ("$cmd"); print "$out\n"; print LOGONE $out; close (LOGONE); open (LOGTWO, "/root/scripts/logs/interfaces/log.$hostname.txt +"); $interfacecount = 0; @interfacenamerecord = (); @interfacespeedrecord = (); while ( <LOGTWO> ) { @splitset = split (/\s+/, $_); $speedcount = 0; foreach $splittest (@splitset) { if ($splittest =~ /Bundle/) { $interfacenamerecord[$interfacecount] = $splitset[ +0]; } if ($splittest =~ /BW/) { $locationcount = $speedcount+1; $interfacespeedrecord[$interfacecount] = $splitset +[$locationcount]; $interfacecount++; } $speedcount++; } } $printcount = 0; $intholder = ""; foreach $intholder (@interfacenamerecord) { print "Interface $interfacenamerecord[$printcount] reporte +d speed is $interfacespeedrecord[$printcount]\n"; $printcount++; } close (LOGTWO); $testcount++; } }
    Evaluation output
    [scripts]# perl cisco_crs_int_check.pl total 24 drwxr-xr-x. 2 root root 16384 Jan 30 14:20 . drwxr-xr-x. 4 root root 4096 Jan 29 10:12 .. -rw-r--r--. 1 root root 326 Jan 30 14:20 log.router1.txt 0 0 Attempting to connect to routers... Polling router1 ......... please wait Thu Jan 30 19:26:37.629 UTC Bundle-Ether11 is up, line protocol is up Thu Jan 30 19:26:37.975 UTC MTU 9192 bytes, BW 240000000 Kbit (Max: 240000000 Kbit) Thu Jan 30 19:26:38.268 UTC Bundle-Ether12 is up, line protocol is up Thu Jan 30 19:26:38.545 UTC MTU 9192 bytes, BW 340000000 Kbit (Max: 340000000 Kbit) Interface Bundle-Ether11 reported speed is 240000000 Interface Bundle-Ether12 reported speed is 340000000 The End....
Re: Net::OpenSHH unable to execute multiple commands with Cisco CRS?
by jellisii2 (Hermit) on Jan 30, 2014 at 16:53 UTC
    Control::CLI may be a bit more tolerant to this stupidity. I can't speak to your problem directly, but I've been successful in getting annoying stuff to automate done with it. It does require keys though. No interactive login, like you appear to be using.
      I believe you are mistaken. Control::CLI does not require keys. Credentials may be passed.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2024-04-24 22:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found