http://qs321.pair.com?node_id=1009428


in reply to Net::SSH::Expect Connection Refused

Just to clarify:
  1. The cisco_ssh_login() function works fine when the router (or whatever) is setup to use ssh
  2. When the target device can only be accessed by telnet, your script fails as you describe
  3. When you say 'fails in the first line', you mean the first line of cisco_ssh_login(), not the whole script, right?
Assuming all of this, your problem is that most likely, you looked at the example for using login() at the top of the cpan page. login() will croak for any startup problems (like not being able to reach the target device). It tells you this in the documentation for login() a little lower down. To handle this, you need to use eval to run login() and look at $@. Then you can get cisco_ssh_login to return what you want

fnord

  • Comment on Re: Net::SSH::Expect Connection Refused

Replies are listed 'Best First'.
Re^2: Net::SSH::Expect Connection Refused
by netauto (Initiate) on Dec 18, 2012 at 19:01 UTC

    All your assumptions were correct and your advice spot on, Thank You!!!
    In the sub-routine "cisco_ssh_login" I move a couple of declarations up to to make them visible outside of the if statements
    and wrapped the call to "ssh->login()" method with eval,
    added a check on "$@" to force exit and return a value I could use to check the subroutine call and launch the telnet routine.

    sub cisco_ssh_login { my $login_output = ""; my $enable = ""; eval { $login_output = $ssh->login(); if ($login_output !~ /username|password|passcode|#|>/) { die "Login has failed. Login output was $login_output"; } }; if( $@ =~ m/SSHProcessError The ssh process was terminated/ ) { # Login Failed Leave Sub Routine with value "ssh_failed" return "ssh_failed"; } .... } .... $login_result = &cisco_ssh_login(); if ( $login_result eq "ssh_failed") { $login_result = &cisco_telnet_l +ogin(); };


    Thanks for taking the time to help a newbie out.
    For those Struggling Like I was here is the working code I used.
    I will point out it took awhile to get here and the learning is important as is the struggle.

    #!/usr/bin/perl use warnings; use strict; use Net::Telnet(); use Net::SSH::Expect; open(OUTPUT, ">>output.log"); my $host = "10.10.10.10"; my $username = "myuser"; my $passwd = "mypass"; my $enpasswd = "myenpass"; my @output = ""; my @newarray = ""; my $Prompt = ""; my $tempstring = ""; my $msg = ""; my $Chassis = ""; my $access_method = ""; my $login_result = ""; my $ssh = Net::SSH::Expect->new ( host => $host, password => $passwd, user => $username, raw_pty => 1, debug => 1, timeout => 5 ); my $telnet = new Net::Telnet ( Timeout => 20, Errmode => 'die', Prompt => "/#|login:|username:|>/i" ); sub cisco_telnet_login { $telnet->open($host); $telnet->login($username, $passwd); $telnet->print("term length 0"); my @output = $telnet->waitfor('/(.*[#>])/i'); #create an array "out +put" so we can grab the real prompt from it my $device_prompt = $output[$#output]; # now take the array "output +" and grab the last position in the array using "$#" $Prompt = $output[$#output]; $access_method = "cisco_telnet"; $tempstring = shift(@output); if ( $tempstring =~ m/#/ ) { $telnet->print("term length 0"); @output = $telnet->waitfor('/(.*[\$%#>]) $/i'); #create an array + "output" so we can grab the real prompt from it $device_prompt = $output[$#output]; # } if ( $tempstring =~ m/>/ ) { $telnet->print("enable"); @output = $telnet->waitfor('/password:|passcode:/i'); $telnet->print("$enpasswd"); @output = $telnet->waitfor('/(.*[\$%#>]) $/i'); $telnet->print("term length 0"); @output = $telnet->waitfor('/(.*[\$%#>]) $/i'); #create an array + "output" so we can grab the real prompt from it $device_prompt = $output[$#output]; # } print @output; print($Prompt); @output = ""; # Reset array @output - this is not actually empty it + contain on item and it is empty # print("\n"); # $telnet->prompt(/$Prompt/); $telnet->errmode("die"); # print(@output); }; sub cisco_ssh_login { my $login_output = ""; my $enable = ""; eval { $login_output = $ssh->login(); if ($login_output !~ /username|password|passcode|#|>/) { die "Login has failed. Login output was $login_output"; } }; if( $@ =~ m/SSHProcessError The ssh process was terminated/ ) { # Login Failed Leave Sub Routine with value "ssh_failed" return "ssh_failed"; } # my $login_output = $ssh->login(); if( $login_output !~ /\#\s*\z/ ) { #### print "\nInside Not Like Section\n"; # print"\n$@\n\n"; # if you see other failure uncomment and add +if stmt with value, similar to if stmt below $enable = $ssh->exec( "enable" ); #### if we have a password prompt after enable, send the passwor +d if( $enable =~ /[Pp]assword:/ ) { my $enablepass = $ssh->exec( $enpasswd ); # did the enable password fail? if( $enablepass !~ /\#\s*\z/ ) { $msg = "Enable password failed."; $ssh->close( ); return( 249, $msg ); } } # we didn't require a password, but did we get the enable prompt +? elsif( $enable !~ /\#\s*\z/ ) { $msg = "Enable mode prompt not found."; $ssh->close(); return( 249, $msg ); } } $access_method = "cisco_ssh"; if ($login_output =~ /Nexus/) { print"\nFound Device is Nexus During Login\n\n"; } #### Un-Comment next Line to see Login #print "$login_output\n"; @output = $ssh->exec("\n"); $tempstring = shift(@output); @newarray = split(/\r\n/,$tempstring); # $tempstring may only have +new lines "\n", could be why I did not get prompt $Prompt = $newarray[1]; $Prompt =~ s/#//; $Prompt =~ s/\r//; $Prompt =~ s/\n//; print"\nPrompt Value: ",$Prompt,"\n\n"; }; ### Nexus System Info Gathers info from "show version" and sub nexus_sys_info { #### Issue Command it either Telnet or SSH Session, depending on wh +ich was estabished if ( $access_method eq "cisco_telnet" ) { @output = $telnet->cmd("show ver"); @newarray = @output; } if ( $access_method eq "cisco_ssh" ) { $ssh->timeout( 4 ); @output = $ssh->exec("show ver"); $tempstring = shift(@output); @newarray = split(/\r\n/,$tempstring); } #### Issue Command it either Telnet or SSH Session, depending on wh +ich was estabished #### Iterate through output (@newarray) array Line by Line my $counter = 0; $Chassis = ""; foreach my $line(@newarray) { chomp($line); # print "\n$line\n"; $counter++; if($line =~ m/cisco ([^\s]*) Chassis/) { $Chassis = $1; print "\nChassis: ",$Chassis,"\n\n"; print OUTPUT "Chassis:\t$Chassis\n"; } #### adding for testing before IOS version is in place if($line =~ m/cisco\s+([^\s]*)\s+([^\s]*)\s+processor/i) { $Chassis = $1; print "\nChassis: ",$Chassis,"\n\n"; print OUTPUT "Chassis:\t$Chassis\n"; } } $ssh->timeout( 2 ); }; $login_result = &cisco_ssh_login(); if ( $login_result eq "ssh_failed") { $login_result = &cisco_telnet_l +ogin(); }; print "\nReturned from Login\n\n"; if ( $access_method eq "cisco_telnet" ) { # @output = $telnet->cmd("term length 0"); # this is commented out +because it was set in cisco_telnet_login @output = $telnet->cmd("term width 512"); } if ( $access_method eq "cisco_ssh" ) { $ssh->timeout( 2 ); $ssh->exec("terminal width 512"); $ssh->exec("terminal length 0"); } my $system_result = &nexus_sys_info();