ssh to cisco router with expect CPAN

E

erik

I am ultimately trying to make CGI where we can Quality Assure Cisco
routers. My script does log into the router, but I don't think it is
storing in my array. I try to print the array and I get nothing. It
hangs within the check_logging_settings subscript.
(I have the ARGV scalars because I am testing it via command line
rather than the browser. )

But like I said the problem is definitely in teh check_logging_settings
sub script. Any advice would be appreciated.





#!/usr/bin/perl -w
#################################################################
# Global Variables #
#################################################################

use Expect;
use CGI(":standard");
use Term::ANSIColor;
#$device = param("device");
#$username = param("username");

#$password = param("password");

#$enable = "enable";

#$enable_password = param(enable_password");


$device = $ARGV[0];
$username = $ARGV[1] ;

$password = $ARGV[2];

$enable = $ARGV[3];

$enable_password = $ARGV[4];


$LoggingMsg = "Do you have logging back to the NTP server";

#Error Report Array
my @failed_tests;

#################################################################
# Create Session with router #
#################################################################

sub spawn_session
{
#open session with router
$command = Expect->spawn("telnet $device");

#Wait for password prompt or send error.
$command->expect($timeout, -re => "Username:") or do
{
print "\nFailed to get username prompt\n";
exit 2;
};

#Send Tacacs Username to router, exit if Username is incorrect
print $command "$username\r";

$command->expect($timeout, -re => "Password:") or do
{
print "\nFailed to get password prompt\n";
exit 4;
};

#Send password to router, exit if password is incorrect
print $command "$password\r";

$command->expect($timeout, -re => ">") or do
{
print "\nDid not get a \> in prompt\n";
exit 5;
};

#Send enable pass to router, exit if password is incorrect
print $command "$enable\r";


$command->expect($timeout, -re => "assword") or do
{
print "\nDid not get a \> in prompt\n";
exit 5;
};

#Send enable pass to router, exit if password is incorrect
print $command "$enable_password\r";
} #end sub


#################################################################
# Ensures that only one interface has manage ssh set #
#################################################################
sub check_logging_settings

{
my $no_logging = "You are missing logging 199.11.x.xx";

$command->clear_accum();
print $command "show config \| inc logging 199.11.x.xx\r";
unless ($command->expect($timeout, -re, '->')) {
return "Never got ssh prompt".$command->exp_error()."\n";
}
my $read = $command->exp_before();
my @read = split ('\n', $read);

my $x = 0;
my $count = 0;

for ($x=0; $x<$#read; $x++)
{
if ($read[$x] =~ /^logging 199.11.1.22$/)
{ $count += 1; }
}
if ($count < 1)
{
push (@failed_tests, $no_logging);
$action = "FAIL";
}
else
{
$action = "OK";
}#end if
print "$action We got here";
}

#################################################################
# Exits the Telnet Session #
#################################################################
sub exit_session
{
print $command "exit\r";
}#end sub

#################################################################
# Prints the failed test error descriptions #
#################################################################
sub print_error_report
{
print <<html1
Conent-Type: text/html\n\n
<html><head><title>QA REPORT</title></head>
<body bgcolor="#ffffff">
<p>
<h2>QA Results</h2>
<ul>
<body>
<b>$LoggingMsg</b><br>
</body>
print <<EndFooter;
</ul>
<p>
</body>
</html>
html1
}
#################################################################
# Main Program Module #
#################################################################
spawn_session();
check_logging_settings();
exit_session();
print_error_report();
 
B

Brian McCauley

erik said:
I am ultimately trying to make CGI where we can Quality Assure Cisco
routers. My script does log into the router, but I don't think it is
storing in my array. I try to print the array and I get nothing. It
hangs within the check_logging_settings subscript.
(I have the ARGV scalars because I am testing it via command line
rather than the browser. )

Since you are using the CGI module this is not really necessary - it has
a special debugging mode for command line testing.
But like I said the problem is definitely in teh check_logging_settings
sub script.

Well I know nothing about Cisco but is the prompt really '->' ?
Any advice would be appreciated.

If any advice is appreciated then why haven't you followed the standard
advice given to everyone who comes here?

Always declare all variables as lexically scoped in the smallest
applicable scope unless there is a reason to do otherwise. Then "use
strict" and "use warnings".

We say this for both your beniefit and ours - if you do it then you will
find programming easier and we won't be asked to do the work of a machine.
#!/usr/bin/perl -w

-w has largely been superceeded by "use warnings". (That's a slight
simplification for details RTFM).
#################################################################
# Global Variables #
#################################################################

################################################################
# ...should be used as sparingly as possbile #
################################################################
use Expect;
use CGI(":standard");
use Term::ANSIColor;
#$device = param("device");
#$username = param("username");

#$password = param("password");

#$enable = "enable";

#$enable_password = param(enable_password");


$device = $ARGV[0];
$username = $ARGV[1] ;

$password = $ARGV[2];

$enable = $ARGV[3];

$enable_password = $ARGV[4];

Perl has list assignment you know.

my ($device,$username,$password,$enable,$enable_password) = @ARGV;
$LoggingMsg = "Do you have logging back to the NTP server";

#Error Report Array
my @failed_tests;

#################################################################
# Create Session with router #
#################################################################

sub spawn_session
{
#open session with router
$command = Expect->spawn("telnet $device");
#Wait for password prompt or send error.
$command->expect($timeout, -re => "Username:") or do

You have never defined $timeout. If you adopted the habit of (wherever
possible) declaring variables at the same time as initializing them and
used strict then Perl would have picked up this mistake for you.

I suspect this is the problem that prompted you to post to Usenet. So
you see it really would help.
{
print "\nFailed to get username prompt\n";
exit 2;
};

#Send Tacacs Username to router, exit if Username is incorrect
print $command "$username\r";

$command->expect($timeout, -re => "Password:") or do
{
print "\nFailed to get password prompt\n";
exit 4;
};

#Send password to router, exit if password is incorrect
print $command "$password\r";

$command->expect($timeout, -re => ">") or do
{
print "\nDid not get a \> in prompt\n";
exit 5;
};

#Send enable pass to router, exit if password is incorrect
print $command "$enable\r";


$command->expect($timeout, -re => "assword") or do
{
print "\nDid not get a \> in prompt\n";
Err....

exit 5;
};

#Send enable pass to router, exit if password is incorrect
print $command "$enable_password\r";
} #end sub


#################################################################
# Ensures that only one interface has manage ssh set #
#################################################################
sub check_logging_settings

{
my $no_logging = "You are missing logging 199.11.x.xx";

$command->clear_accum();
print $command "show config \| inc logging 199.11.x.xx\r";
unless ($command->expect($timeout, -re, '->')) {
return "Never got ssh prompt".$command->exp_error()."\n";

What does ssh have to do with it?
}
my $read = $command->exp_before();
my @read = split ('\n', $read);

The first argument to split is a regex. You can make it look like a
string but this makes your code less readable.
my $x = 0;

You are suffing from premature declaration. There is no reason to
declare $x until you get to the for()
my $count = 0;

for ($x=0; $x<$#read; $x++)

Don't use C-style for() in Perl unless there is a reson.

Did you really itend to omit the last element of @read? (I shall assume
not).

for my $x ( 0 .. $#read )

But in Perl you should only iterate over the subscripts of an array if
there is a reason to do so. If you really want to interate over the
contents of array then you should do just that.

for ( @read )
{
if ($read[$x] =~ /^logging 199.11.1.22$/)

You probaly wanted \. not . in there.
{ $count += 1; }

Perl has ++ operator, you know.

Anyhow, all in all, you are working _much_ too hard.

my $count = grep /^logging 199\.11\.1\.22$/, split /\n/, $read;

if ($count < 1)

Oh, if you only want to ditinguish there/not there then there was no
need to count at all.

if ( $read !~ /^logging 199\.11\.1\.22$/m )
 
B

Brian McCauley

Brian McCauley wrote:

my $count = grep /^logging 199\.11\.1\.22$/, split /\n/, $read;

Or if you feel really terse...

my $count = () = $read =~ /^logging 199\.11\.1\.22$/mg;

[ snip redundant trailing qoute - _bad_ nobull ! ]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top