NAME
    Net::Appliance::Session - Run command-line sessions to network
    appliances

VERSION
    This document refers to version 0.05 of Net::Appliance::Session.

SYNOPSIS
     use Net::Appliance::Session;
     my $s = Net::Appliance::Session->new('hostname.example');

     eval {
         $s->connect(Name => 'username', Password => 'loginpass');
         $s->begin_privileged('privilegedpass');
         print $s->cmd('show access-list');
         $s->end_privileged;
     };
     if ($@) {
         $e = Exception::Class->caught();
         ref $e ? $e->rethrow : die $e;
     }

     $s->close;

DESCRIPTION
    Use this module to establish an interactive command-line session with a
    network appliance. There is special support for moving into "privileged"
    mode and "configure" mode, with all other commands being sent through a
    generic call to your session object.

    There are other CPAN modules that cover similar ground, including
    Net::SSH and Net::Telnet::Cisco, but they are quite buggy or do not
    handle SSH properly. Objects created by this module are based upon
    Net::Telnet so the majority of your interaction will be with methods in
    that module. It is recommended that you read the Net::Telnet manual page
    for further details.

    In this early release of "Net::Appliance::Session", only SSH connections
    to Cisco devices are supported, but it is hoped that further trasports
    (for example serial line access) and target device engines (e.g.
    Juniper) will be developed.

METHODS
    Objects created by this module are based upon Net::Telnet so the
    majority of your interaction will be with methods in that module. The
    following Net::Telnet method is documented here for completeness :

    "Net::Appliance::Session->new"
        Like Net::Telnet you can supply either a single parameter to this
        method which is used for the target device hostname, or a list of
        named parameters as listed in the Net::Telnet documentation. Do not
        use "Net::Telnet"'s "Errmode" parameter, because it will be
        overridden by this module.

        The significant difference with this module is that the actual
        connection to the remote device is delayed until you "connect()".

        Further named arguments to those in Net::Telnet are accepted, to
        control behaviour specific to this module. This is discussed
        further, below.

        This method returns a new "Net::Appliance::Session" object.

    The following methods are provided in addition to those in Net::Telnet
    and all return the current "Net::Appliance::Session" object:

    "$s->connect"
        When you instantiate a new Net::Appliance::Session object the module
        does not actually establish a connection with the target device.
        This behaviour is slightly different to Net::Telnet and is because
        the module also needs to have login credentials. Use this method to
        establish that interactive session.

        This method requires two arguments: the login username and password.
        Either provide them as a pair of parameters to "connect" in that
        order, or as a list of named parameters using the key names "Name"
        and "Password" respectively. For example:

         $s->connect('username', 'password');
         # or
         $s->connect(Name => 'username', Password => 'password');

        In addition to logging in, "connect" will also disable paging in the
        output for its interactive session. This means that unlike
        Net::Telnet::Cisco no special page scraping logic is required in
        this module's code.

    "$s->begin_privileged"
        To enter privileged mode on the device use this method. Of course
        you must be connected to the device using the "connect" method,
        first.

        All parameters are optional, and if none are given then the login
        password will be used as the privileged password.

        If one parameter is given then it is assumed to be the privileged
        password.

        If two parameters are given then they are assumed to be the
        privileged username and password, respectively.

        If more than two parameters are given then they are interepreted as
        a list of named parameters using the key names "Name" and "Password"
        for the privileged username and password, respectively.

    "$s->end_privileged"
        To leave privileged mode and return to the unpriviledged shell then
        use this method.

    "$s->in_privileged_mode"
        This method will return True if your interactive session is
        currently in privileged (or configure) mode, and False if it is not.

    "$s->begin_configure"
        In order to enter configure mode, you must first have entered
        privileged mode, using the "begin_privileged" method described
        above.

        To enter configure mode on the device use this method.

    "$s->end_configure"
        To leave configure mode and return to privileged mode the use this
        method.

    "$s->in_configure_mode"
        This method will return True if your interactive session is
        currently in configure mode, and False if it is not.

    "$s->cmd"
        Ordinarily, you might use this "Net::Telnet" method in scalar
        context to observe whether the command was successful on the target
        appliance. However, this module's version "die"s if it doesn't think
        everything went well. See "DIAGNOSTICS" for tips on managing this
        using an "eval{}" construct.

        The following error conditions are checked on your behalf:

        *   Incomplete command output, it was cut short for some reason

        *   Timeout waiting for command response

        *   EOF or other anomaly received in the command response

        *   Error message from your appliance in the response

        If any of these occurs then you will get an exception with
        apropriately populated fields. Otherwise, in array context this
        method returns the command response, just as "Net::Telnet" would. In
        scalar context the object itself returned.

        Being overridden in this way means you should have no need for the
        "print()" and "waitfor()" methods of "Net::Telnet", although they
        are of course still available should you want them. The only usable
        method arguments are "String", "Output" and "Timeout".

    "$s->close"
        This "Net::Telnet" method has been overridden to automatically back
        out of configure and/or privilege mode, as well as re-enable paging
        mode on your behalf, as necessary.

    "$s->error"
        Rather than following the "Net::Telnet" documentation, this method
        now creates and throws an exception, setting the field values for
        you. See "DIAGNOSTICS" below for more information, however undor
        most circumstances it will be called automatically for you by the
        overridden "cmd()" method.

CONFIGURATION
    Occasionally there is a configuration setting that is implemented
    through different commands on different models of device. To cope with
    this, Net::Appliance::Session makes use of a phrasebook in which it
    stores alternative syntax for various operating system platforms.

    The default operation of Net::Appliance::Session is to assume that the
    target is running a form of Cisco's IOS. Support is also available, via
    the "Net::Appliance::Phrasebook" module, for the following operating
    systems:

     IOS     # the default
     Aironet # currently the same as the default

     PIXOS   # for PIX OS-based devices (including FWSM Release 2.x)
     FWSM    # currently the same as 'PIXOS'
     FWSM3   # for FWSM Release 3.x devices (slightly different to FWSM 2.x)

    To select a phrasebook, pass an optional parameter to the "new" method
    like so:

     my $s = Net::Appliance::Session->new(
         Host     => 'hostname.example',
         Platform => 'FWSM3',
     );

    If you want to add a new phrasebook, or edit an exiting one, there are
    two options. Either submit a patch to the maintaner of the
    "Net::Appliance::Phrasebook" module, or read the manual page for that
    module to find out how to use a local phrasebook rather than the builtin
    one.

DIAGNOSTICS
    Firstly, if you want to see a copy of everything sent to and received
    from the appliance, then something like the following will probably do
    what you want:

     $s->input_log(*STDOUT);

    All errors returned from Net::Appliance::Session methods are Perl
    exceptions, meaning that in effect "die()" is called and you will need
    to use "eval {}". The rationale behind this is that you should have
    taken care to script interactive sessions robustly, and tested them
    thoroughly, so if a prompt is not returned or you supply incorrect
    parameters then it's an exceptional error.

    Recommended practice is to wrap your interactive session in an eval
    block like so:

     eval {
         $s->begin_privileged('password');
         print $s->cmd('show version');
         # and so on...
     };
     if ( UNIVERSAL::isa($@,'Net::Appliance::Session::Exception') ) {
         print $@->message, "\n";  # fault description from Net::Appliance::Session
         print $@->errmsg, "\n";   # message from Net::Telnet
         print $@->lastline, "\n"; # last line of output from your appliance
         # perform any other cleanup as necessary
     }
     $s->close;

    Exceptions belong to the "Net::Appliance::Session::Exception" class if
    they result from errors internal to Net::Telnet such as lack of returned
    prompts, command timeouts, and so on.

    Alternatively exceptions will belong to "Net::Appliance::Session::Error"
    if you have been silly (for example missed a method parameter or tried
    to enter configure mode without having first entered privileged mode).

    All exception objects are created from "Exception::Class" and so
    stringify correctly and support methods as described in the manual page
    for that module.

    "Net::Appliance::Session::Exception" exception objects have two
    additional methods (a.k.a. fields), "errmsg" and "lastline" which
    contain output from Net::Telnet diagnostics.

INTERNALS
    The guts of this module are pretty tricky, although I would also hope
    elegant, in parts ;-) In particular, the following "Net::Telnet" method
    has been overridden to modify behaviour:

    "Net::Appliance::Session::fhopen"
        The killer feature in "Net::Telnet" is that it allows you to swap
        out the builtin I/O target from a standard TELNET connection, to
        another filehandle of your choice. However, it does so in a rather
        intrusive way to the poor object, so this method is overridden to
        safeguard the instance's private data.

DEPENDENCIES
    Other than the contents of the standard Perl distribution, you will need
    the following:

    *   Exception::Class

    *   Net::Telnet

    *   IO::Pty

    *   UNIVERSAL::require

    *   Class::Accessor >= 0.25

    *   Class::Accessor::Fast::Contained

    *   Net::Appliance::Phrasebook

AUTHOR
    Oliver Gorwits "<oliver.gorwits@oucs.ox.ac.uk>"

ACKNOWLEDGEMENTS
    Parts of this module are based on the work of Robin Stevens and Roger
    Treweek. The SSH command spawning code was based on that in "Expect.pm"
    and is copyright Roland Giersig and/or Austin Schutz.

COPYRIGHT & LICENSE
    Copyright (c) The University of Oxford 2006. 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

