NAME
Devel::REPL::Plugin::NAS - Add Perl to your network devices' command line interfaces
VERSION
This document refers to version 0.0701 of Devel::REPL::Plugin::NAS
WARNING
This is an ALPHA RELEASE. I'd really appreciate any bug reports; you can use the CPAN RT bug tracking system, or email me directly at the address at the bottom of this page.
You probably also want to download the latest "Devel::REPL" code from its subversion repository, as it contains many updates to the version on CPAN.
PURPOSE
Whilst running an automated interactive session on a network device (e.g. a router) using Net::Appliance::Session, the device may throw an error. You can then be dropped into a 'shell' on the device, for manual debugging, but the shell also has Perl bells and whistles.
Alternatively, if used standalone, this module makes it seem like your network device manufacturer embedded Perl in their device's CLI. That's pretty cool.
SYNOPSIS
my $repl = Devel::REPL->new;
$repl->load_plugin('NAS');
$repl->run;
Or,
$> /usr/bin/nsh hostname.example.com
Username [oliver]:
Password:
Net::Appliance::Session=GLOB(0x8e7db7c)
TEST_3750 dir flash:
Directory of flash:/
4 -rwx 7874 May 22 2008 11:43:53 +01:00 config.text
459 drwx 192 Jan 31 2007 15:53:38 +00:00 c3750-ipbasek9-mz.122-25.SEE2
15998976 bytes total (6618624 bytes free)
TEST_3750 #nas_perl
Switched into Perl mode.
re.pl:003:0> write_file ('config.text', qc{more flash:config.text});
1
re.pl:004:0> ^D
Closing Net::Appliance::Session connection.
$>
DESCRIPTION
There is a module, Net::Appliance::Session (NAS), which allows you to automate interactive sessions with a network device CLI (e.g. a router or switch). It's like a smarter and more Perlish version of Expect. A couple of users asked me whether NAS could provide better handling of errors received from the remote device, rather than simply die'ing.
Around the same time, I was reading about Cisco having included the tcl scripting language in their IOS software, and thinking about an IOS with an embedded Perl. Time passed, and then I started playing with the Devel::REPL interactive shell for Perl, and realised there was the potential to create a Perl/NAS shell.
This module is a plugin for "Devel::REPL" which allows the one shell to be used for both Perl commands as well as sending commands to a device connected via "Net::Appliance::Session". There is special support for managing the connection to your device, and easily issueing commands either to Perl or the device, in succession, or combining the two to grab NAS output into Perl variables.
USAGE
Load up the plugin either by including it in your "repl.rc" file, or running the following small Perl program:
my $repl = Devel::REPL->new;
$repl->load_plugin('NAS');
$repl->run;
At this point you'll be at the REPL shell, which has a funny-looking prompt telling you the line number and script name. You can issue any Perl syntax here to be executed, including multi-line statements (e.g. "for" loops), loading of modules, and so on. Lexical variables (created using "my") will persist as long as the shell is running.
re.pl:001:0> print "Hello, World";
Hello World
Once you're done with seeing how cool that is, you can make a connection to your network device using a "Devel::REPL" macro (stricty, known as a turtle). REPL macros begin with the "#" character, and sometimes take command arguments; in this case the hostname, username and
re.pl:002:0> #nas_connect hostname.example username password
$Net_Appliance_Session1 = Net::Appliance::Session=GLOB(0x92165ac);
You are shown the return value of the statement, which happens in this case to be a "Net::Appliance::Session" object, if the connection was successful. You'll get an error message if the connection wasn't
re.pl:002:0> #nas_connect hostname.example username notmypassword
Error returned from Net::Appliance::Session!
Last command sent:
Last response : Permission denied, please try again.
Fault Description: Login failed to remote host at (eval 230) line 8
Net::Telnet error: pattern match timed-out
At this point, the REPL switches from Perl mode into NAS CLI mode. It's the same REPL process, but your commands are sent straight to the network device, rather than being interpreted as Perl. The prompt also
TEST_3750 show int status | incl 15
Fa1/0/15 OWL visitor notconnect 97 auto auto 10/100BaseTX
TEST_3750 conf t
Enter configuration commands, one per line. End with CNTL/Z.
TEST_3750(config)#
To disconnect from the device and quit the REPL in one go, hit "Control+d". To just disconnect from the device but remain at the REPL shell in Perl mode, use the following macro (from either NAS CLI or Perl mode):
TEST_3750(config)# #nas_disconnect
Closing Net::Appliance::Session connection.
FEATURES AND AVAILABLE COMMANDS
If that were all there was to it, you may as well be using SSH directly. But no, as mentioned above, you can issue Perl from within NAS CLI mode, issue network device commands from within Perl mode, and more.
Switching between Perl and NAS CLI mode There are two macros for moving between Perl and NAS CLI mode. To clarify, the mode is only setting the default action for commands received by the REPL shell - whether they are interpreted as Perl, or sent to the network device. You can still perform the other kind of command from either mode, as we'll see in the next section.
To switch from Perl mode to NAS CLI mode:
re.pl:008:0> nas_cli
Switched into NAS CLI mode.
TEST_3750 show int status
To switch from NAS CLI mode to Perl mode:
TEST_3750# #nas_perl
Switched into Perl mode.
re.pl:011:0> print "Hello, world"
The Quoted (interpolated) Command operator Let's say you want to run a command on your network device, and store the results of that in an array. So far we've only seen how to use either Perl mode or NAS CLI mode. The Quoted (interpolated) Command operator is a convenience feature to help you out in this situation.
This operator is just like the other interpolated Perl quote-like operators such as "qx{}" and "qq{}", except that it is "qc{}" (for Quoted Command). The same rules apply for substituting the curly brace characters as do for the other Perl quote-like operators. Here is an
re.pl:015:0> my @output = qc{ show int status }
I've found this to be one of the most useful features - being able to grab command output and munge it in Perl, whilst keeping the remote session open.
One-off commands in an alternate mode If you're in NAS CLI mode, and you want to run a quick bit of Perl (remember, all lexical variables persist, which is handy), then use the "#perl" macro:
TEST_3750# #perl print "Hello again, World";
Hello again, World
Likewise, to send a command to the network device when you're in Perl mode, use the "#nas" macro:
re.pl:012:0> #nas show int status | incl 14
Fa1/0/14 OWL VPN notconnect 98 auto auto 10/100BaseTX
As you can see, by default the output from the command is printed out to the shell. There's an option to suppress this, if you want, which is enabled by adding a flag "-noout" to the macro, like so:
re.pl:013:0> #nas -noout show int status | incl 14
re.pl:014:0>
Command results cache
This module will store the output from all Perl and network device
commands in a cache. This is very useful should you want to post-process
any of the data output by a command.
By default all output is stored in array context, which means that if there are many lines returned each one goes into an element of an array, and a reference to that array gets stored in the cache.
If you'd prefer to have the output from a network device command stored as one big scalar (all the lines joined together), then this is possible via the "#nas" macro, by adding the "-scalar" flag, like so:
re.pl:016:0> #nas -scalar show int status
The output cache itself, including all Perl and NAS CLI mode output, is available via the "$REPL->outputcache" array reference. The most recent command's output is available via the "_" REPL magic variable (no sigil!).
Accessing the "Net::Appliance::Session" object Simply, this is available as $s in your REPL shell. That means it's a good idea not to create a lexical scalar variable of the same name. Note that $s will not exist when there isn't an instantiated object to store, for example before issueing the "nas_connect" macro or after issueing the "disconnect" macro.
One handy thing to do if you're really stuck is drop to lower level
re.pl:017:0> $s->input_log ( *STDOUT )
*main::STDOUT
re.pl:018:0> $s->cmd('show int status | incl 15');
show int status | incl 15
Fa1/0/15 OWL visitor notconnect 97 auto auto 10/100BaseTX
TEST_3750#Fa1/0/15 OWL visitor notconnect 97 auto auto 10/100BaseTX
re.pl:019:0>
Additionally loaded modules
Currently the File::Slurp module is loaded by this plugin, if available.
It provides the "read_file" and "write_file" functions which are
extremely useful for dumping data from a network device (such as files
on flash memory). For further details pleae see the manual page for that
module.
TODO
Currently no way to specify the "Net::Appliance::Session" Transport when
using the connect macro.
There's also no way to specify the NAS Phrasebook, which means it
defaults to Cisco IOS.
REQUIREMENTS
Other than the standard contents of the Perl distribution, you will
To run the bundled "/usr/bin/nsh" program, you'll need the IO::Prompt module.
AUTHOR
Oliver Gorwits "<oliver.gorwits@oucs.ox.ac.uk>"
ACKNOWLEDGEMENTS
All the helpful people in "#moose" on IRC.
COPYRIGHT & LICENSE
Copyright (c) Oliver Gorwits 2008.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.