ssh to cisco router with expect CPAN

Discussion in 'Perl Misc' started by erik, Mar 19, 2005.

  1. erik

    erik Guest

    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();
     
    erik, Mar 19, 2005
    #1
    1. Advertising

  2. erik wrote:

    > 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 )

    > {
    > 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();
    >
     
    Brian McCauley, Mar 19, 2005
    #2
    1. Advertising

  3. erik

    erik Guest

    All good suggestions, thanks I will go back and apply it all.
     
    erik, Mar 19, 2005
    #3
  4. 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;

    >> {
    >> push (@failed_tests, $no_logging);
    >> $action = "FAIL";


    [ snip redundant trailing qoute - _bad_ nobull ! ]
     
    Brian McCauley, Mar 19, 2005
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. gvozdikov
    Replies:
    1
    Views:
    638
    gvozdikov
    Apr 30, 2010
  2. Simon Strandgaard

    how to expect eof with expect+pty

    Simon Strandgaard, Dec 20, 2006, in forum: Ruby
    Replies:
    4
    Views:
    391
    Simon Strandgaard
    Dec 20, 2006
  3. jackster the jackle

    Net:Telnet to Cisco Router

    jackster the jackle, Dec 14, 2007, in forum: Ruby
    Replies:
    5
    Views:
    322
    jackster the jackle
    Dec 17, 2007
  4. jackster the jackle

    net/ssh for enable mode on cisco router

    jackster the jackle, Nov 22, 2008, in forum: Ruby
    Replies:
    5
    Views:
    371
    Brian Candler
    Nov 25, 2008
  5. tmo

    Expect and Cisco FWSM-problem

    tmo, Oct 29, 2008, in forum: Perl Misc
    Replies:
    1
    Views:
    288
    Josef Moellers
    Oct 30, 2008
Loading...

Share This Page