=pod

=head1 NAME

Net::Appliance::Session::Cookbook::Recipe01 - Get Running Config with Telnet

=head1 NOTE

This Cookbook was contributed to the L<Net::Appliance::Session> project by
Nigel Bowden. Source code from the Cookbook is shipped in the C<examples>
folder of this module's distribution.

=head1 PROBLEM

You want to Telnet to a Cisco IOS device and retrieve its running
configuration.

=head1 SOLUTION

This recipe shows how simple it is to get the running configuration for a
Cisco IOS device using the L<Net::Appliance::Session> module.

For this recipe, we assume that the IOS device requires only a username and
password to login to the device. At that point, it is assumed that the device
is configured to drop a user straight in to enable mode (privilege level 15)
when logged in (see the next recipe for details of how to explicitly drop in
to enable mode).

The retrieved configuration will be printed to C<STDOUT> in this script.
Later recipes will show how to dump the configuration text out to a file.

 use strict;
 use warnings;
 
 use Net::Appliance::Session;
 
 my $ios_device_ip = '10.250.249.215';
 
 my $ios_username  = 'cisco';
 my $ios_password  = 'cisco';
 
 my $session_obj = Net::Appliance::Session->new(
     Host      => $ios_device_ip,
     Transport => 'Telnet',
 );
 
 # give verbose output whilst we run this script - comment out if not required
 $session_obj->input_log(*STDOUT);
 
 # try to login to the ios device
 $session_obj->connect(Name => $ios_username, Password => $ios_password);
 
 # get our running config
 my @running_config = $session_obj->cmd('show running');
 
 # chop out the extra info top and bottom of the config
 @running_config = @running_config[ 2 .. (@running_config -1)];
 
 print @running_config;
 
 # close down our session
 $session_obj->close;

=head1 DISCUSSION

This recipe shows the simplicity and power provided by the
Net::Appliance::Session module for those of us who wish to script solutions
that interact with Cisco IOS devices.

We start with a few commands that will be common to most recipes that we will
look at, so we'll discuss them here (for the final time).

The first couple of lines specify a couple of pragmas that will enforce some
good-practice programming methods and give us some useful warnings messages
that may help us debug our code later. It is good practice to include these in
every perl script to make sure that we don't fall into any of the most common
traps that haunt Perl programmers.

 use strict;
 use warnings;

After we have switched on these useful pragmas, we come to the first line of
business which tells our script to pull in the Net::Appliance::Session module
to use in our script.

 use Net::Appliance::Session;

Next, we define a few variables to for use later in the script. We need to be
able to tell our script the IP address of the device we wish to Telnet to, and
the username and password to use when we get to it.

 my $ios_device_ip = '10.250.249.215';
 
 my $ios_username  = 'cisco';
 my $ios_password  = 'cisco';

Now we really get down to business by creating an object using the
Net::Appliance::Session module. Once we have our very own instance of this
object, we can access all of the features provided by Net::Appliance::Session.

The first thing that we need to do is to tell our new object instance which
IOS device we would like to Telnet to, and which Transport type we would like
to use. In this case, we use the C<Host> parameter to pass it the IP address
of our IOS device, and specify that we would like to use Telnet using the
C<Transport> parameter.

We haven't actually started a Telnet session to pur device yet, but we're
almost there. One other thing we might like to do before we get the ball
rolling is to make sure we can see what is going on behind the scenes when our
actual Telnet session is taking place (this may help with debugging later).
So, we tell our object that we'd like to send the session interactions to
C<STDOUT> so that we can see the session progress. In a production script, you
would probably comment this line out.

 my $session_obj = Net::Appliance::Session->new(
     Host      => $ios_device_ip,
     Transport => 'Telnet',
 );
 
 # give verbose output whilst we run this script - comment out if not required
 $session_obj->input_log(*STDOUT);

Well, here we go. We now try to make our Telnet connection to the IOS device.
Using the variables we created earlier, we pass the username and password
required for login to our object's connect method.

If the device is unreachable by Telnet, or the login credentials are
incorrect, the script will fail at this point. The script will die giving you
a reason why it couldn't actually login to your IOS device.

 # try to login to the ios device
 $session_obj->connect(Name => $ios_username, Password => $ios_password);

It's worth taking a few moments to consider what is going on in the background
at this point in the backend of the Net::Appliance::Session module. It's doing
a lot of work behind the scenes that aren't immediately obvious.

When we connect to the device, Net::Appliance::Session will send a command to
disable paging. This will enable us to capture screen outputs when we execute
commands on the device, without having to cater for the fact that we need to
hit the space bar after each screen-full of information.

It also does some very clever pattern matching for various prompts so that it
knows when to send our login credentials and when we are ready to send
commands. In general, we shouldn't need to adjust the default pattern matching
for prompts, but if you have any unusual characters in your device hostnames
or prompts, it may be worth looking at the Net::Appliance::Session documents
to find out how to adjust the prompt matching patterns for your environment.

Well, on with the show, and now we're logged in to our device (assuming we
have dropped straight in to enable mode), its time to send a comand to
retrieve our running configuration tidy up the output a little and then
display the configuration on our screen.

The code below shows how we send our C<show running> command to the device we
are connected to using the C<< $session_obj->cmd() >> method.  The output is
saved in an array - one line per array entry.

As the output also contains a couple of unwanted blank lines at the top, and a
single unwanted line at the end, we use an array slice to chop out those lines
and finally display the whole configuration with our 'print' command.

  # get our running config
  my @running_config =  $session_obj->cmd('show running');
  
  # chop out the extra info top and bottom of the config
  @running_config = @running_config[ 2 .. (@running_config -1)];
  
  print @running_config;

We finally tidy things up by sending a close to tidy up our object.

 # close down our session
 $session_obj->close;

Again, behind the scenes, there is more going on than meets the eye, as the
C<close()> method will also back out of our privilege mode, re-enable paging
before finally getting rid of our object.

=head1 SEE ALSO

=over 4

=item L<Net::Appliance::Session>

=back

=head1 AUTHOR

Nigel Bowden, with POD formatting by Oliver Gorwits.

=head1 COPYRIGHT & LICENSE

Copyright (c) Nigel Bowden 2007. All Rights Reserved.

You may distribute and/or modify this documentation under the same terms as
Perl itself.

=cut
