NAME Devel::REPL::Plugin::NAS - Add Perl to your network devices' command line interfaces VERSION This document refers to version 0.0602 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 password: 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 successful: 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 changes: 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 example: 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->output_cache" 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 testing: 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 need: * Devel::REPL * Net::Appliance::Session >= 1.23 To run the bundled "/usr/bin/nsh" program, you'll need the IO::Prompt module. AUTHOR Oliver Gorwits "" ACKNOWLEDGEMENTS All the helpful people in "#moose" on IRC. COPYRIGHT & LICENSE Copyright (c) Oliver Gorwits 2008. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA