Table Of Contents
Cisco IOS XR Perl Scripting Toolkit
Cisco IOS XR Perl Scripting Toolkit Concepts
Security Implications for the Cisco IOS XR Perl Scripting Toolkit
Prerequisites for Installing the Cisco IOS XR Perl Scripting Toolkit
Installing the Cisco IOS XR Perl Scripting Toolkit
Using the Cisco IOS XR Perl XML API in a Perl Script
Handling Types of Errors for the Cisco IOS XR Perl XML API
Starting a Management Session on a Router
Closing a Management Session on a Router
Sending an XML Request to the Router
Using Response Objects
Using the Error Objects
Using the Configuration Services Methods
Using the Cisco IOS XR Perl Data Object Interface
Understanding the Perl Data Object Documentation
Creating Data Objects
Specifying the Schema Version to Use When Creating a Data Object
Using the Data Operation Methods on a Data Object
get_data Method
find_data Method
get_keys Method
get_entries Method
set_data Method
delete_data Method
Using the Batching API
batch_start Method
batch_send Method
Displaying Data and Keys Returned by the Data Operation Methods
Specifying the Session to Use for the Data Operation Methods
Cisco IOS XR Perl Notification and Alarm API
Registering for Alarms
Deregistering an Existing Alarm Registration
Deregistering All Registration on a Particular Session
Receiving an Alarm on a Management Session
Using the Debug and Logging Facilities
Debug Facility Overview
Logging Facility Overview
Examples of Using the Cisco IOS XR Perl XML API
Configuration Examples
Setting the IP Address of an Interface
Configuring a Simple BGP Neighbor
Adding a List of Neighbors to a BGP Neighbor Group
Displaying the Members of Each BGP Neighbor Group
Setting Up ISIS on an Interface
Finding the Circuit Type That is Currently Configured for an Interface for ISIS
Configuring a New Instance, Area, and Interface for OSPF
Getting a List of the Usernames That are Configured on the Router
Finding the IP Address of All Interfaces That Have IP Configured
Adding an Entry to the Access Control List
Denying Access to a Set of Interfaces from a Particular IP Address
Performing Actions Whenever Certain Events Occur for Notifications
Operational Examples
Retrieving the Operational Information for All Interfaces on the Router
Retrieving the Link State Database for a Particular Level for ISIS
Getting a List of All Interfaces on the System
Retrieving the Combined Interface and IP Information for Each Interface
Listing the Hostname and Interface for Each ISIS Neighbor
Recreating the Output of the show ip interfaces CLI Command
Producing a Textual Output Similar to the show bgp neighbors CLI Command
Displaying Tabular XML Data in a Generic HTML Table Using XSLT
Displaying the Interface State in a Customized HTML Table
Displaying the BGP Neighbor Operational Data in a Complex HTML Format
Cisco IOS XR Perl Scripting Toolkit
This chapter describes the Cisco IOS XR Perl Scripting Toolkit as an alternative method to the existing management methods that enables the router to be managed by a Perl script running on a separate machine. Management commands and data are sent to and from the router in the form of extensible markup language (XML) over either a Telnet or an SSH connection. The well-defined and consistent structure of XML, which is used for both commands and data, makes it easy to write scripts that can interactively manage the router, display information returned from the router in the format required, or manage multiple routers at once.
The following sections describe how to use the Cisco IOS XR Perl Scripting Toolkit:
•
Cisco IOS XR Perl Scripting Toolkit Concepts
•
Security Implications for the Cisco IOS XR Perl Scripting Toolkit
•
Prerequisites for Installing the Cisco IOS XR Perl Scripting Toolkit
•
Installing the Cisco IOS XR Perl Scripting Toolkit
•
Using the Cisco IOS XR Perl XML API in a Perl Script
•
Handling Types of Errors for the Cisco IOS XR Perl XML API
•
Starting a Management Session on a Router
•
Closing a Management Session on a Router
•
Sending an XML Request to the Router
•
Using Response Objects
•
Using the Error Objects
•
Using the Configuration Services Methods
•
Using the Cisco IOS XR Perl Data Object Interface
•
Cisco IOS XR Perl Notification and Alarm API
•
Examples of Using the Cisco IOS XR Perl XML API
Cisco IOS XR Perl Scripting Toolkit Concepts
Table 15-1 describes the toolkit concepts. Some sample scripts are modified and show how to use the API in your own scripts.
Table 15-1 List of Concepts for the IOS XR Perl Scripting Toolkit
Concept
|
Definition
|
Cisco IOS XR Perl XML API1
|
Consists of the core of the toolkit and provides the ability to create management sessions, send management requests, and receive responses by using Perl objects and methods.
|
Cisco IOS XR Perl Data Object API
|
Allows management requests to be sent and responses received entirely using Perl objects and data structures without any knowledge of the underlying XML.
|
Cisco IOS XR Perl Notification/Alarm API
|
Allows a script to register for notifications (for example, alarms), on a management session and receive the notifications asynchronously as Perl objects.
|
Security Implications for the Cisco IOS XR Perl Scripting Toolkit
Similar to using the command-line interface (CLI) over a Telnet or Secured Shell (SSH) connection, all authentication and authorization are handled by authentication, authorization, and accounting (AAA) on the router. A script prompts you to enter a password at run time, which ensures that passwords never get stored on the client machine. Therefore, the security implications for using the toolkit are identical to the CLI over the same transport.
Prerequisites for Installing the Cisco IOS XR Perl Scripting Toolkit
To use the toolkit, you must have installed Perl version 5.6 on the client machine that runs UNIX and Linux. To use the SSH transport option, you must have the SSH client executable installed on the machine and in your path.
You need to install the following specific standard Perl modules to use the various functions:
•
XML::LibXML—This module is essential for using the Perl XML API and requires that the libxml2 library be installed on the system first, which must be the version that is compatible with the version of XML::LibXML. The toolkit is tested to work with XML::LibXML version 1.58 and libxml2 version 2.6.6. If you are installing libxml2 from a source, you must apply the included patch file before compiling.
•
Term::ReadKey (optional but recommended)—This module reads passwords without displaying them on the screen.
•
Net::Telnet—This module is needed if you are using the Telnet or SSH transport modules.
If one of the modules is not available in the current version, you are warned during the installation process. Before installing the toolkit, you should install the current versions of the modules. You can obtain all modules from the following location: http://www.cpan.org/
The following modules are not necessary for using the API, but are required to run some sample scripts:
•
XML::LibXSLT—This module is needed for the sample scripts that use XSLT to produce HTML pages. The module also requires that the libxslt library be installed on the system first. The toolkit is tested to work with XML::LibXSLT version 1.57 and libxslt version 1.1.3.
•
Mail::Send—This module is needed only for the notifications example script.
Installing the Cisco IOS XR Perl Scripting Toolkit
The Cisco IOS XR Perl Scripting Toolkit is distributed in a file named Cisco-IOS_XR-Perl-Scripting-Toolkit-<version>.tar.gz.
To install the Cisco IOS XR Perl Scripting Toolkit, perform the following steps:
Step 1
Extract the contents from the directory in which the file resides by entering the following command:
tar -f Cisco-IOS_XR-Perl-Scripting-Toolkit-<version>.tar.gz -xzC <destination>
Table 15-2 defines the parameters.
Table 15-2 Toolkit Installation Directory Parameters
Name
|
Description
|
<version>
|
Defines the version of the toolkit that you want to install, for example, version 1.0.
|
<destination>
|
Specifies the existing directory in which you want to create the toolkit installation directory. A directory called Cisco-IOS_XR-Perl-Scripting-Toolkit-<version> is created within the <destination> directory along with the extracted contents.
|
Step 2
Use the cd command to change to the toolkit installation directory and enter the following command:
If the command gives a warning that one of the prerequisite modules is not found, download and install the applicable module from the Comprehensive Perl Archive Network (CPAN) before using the API.
Step 3
Use the make command to maintain a set of programs, as shown in the following example:
Step 4
Use the make install command, as shown in the following example:
Ensure that you have the applicable permission requirements for the installation. You may need to have root privileges.
If you do not encounter any errors, the toolkit is installed successfully. The Perl modules are copied into the appropriate directory, and you can use your own Perl scripts.
Using the Cisco IOS XR Perl XML API in a Perl Script
To use the Cisco IOS XR Perl XML API in a Perl application, import the module by including the following statement at the top of the script:
If you are using the Data Object interface, you can specify extra import options in the statement.
For more information about the objects, see "Creating Data Objects" section.
Handling Types of Errors for the Cisco IOS XR Perl XML API
The following types of errors can occur when using the Cisco IOS XR Perl XML API:
•
Errors returned from the router—Specify that the errors are produced during the processing of an XML request and are returned to you in an XML response document. For more information about how these errors are handled, see "Using the Error Objects" section.
•
Errors produced within the Perl XML API modules—Specify that the script cannot continue. The module causes the script to be terminated with the appropriate error message. If the script writer wants the script to handle these error types, the writer must write the die handlers (for example, enclose the call to the API function within an eval{} block).
Starting a Management Session on a Router
Before any requests are sent, a management session must be started on the router, which is done by creating a new object of type named Cisco::IOS_XR. The new object is used for all further requests during the session, and the session is ended when the object is destroyed. A Cisco::IOS_XR object is created by calling Cisco::IOS_XR::new.
Table 15-3 lists the optional parameters specified as arguments.
Table 15-3 Argument Definitions
Name
|
Description
|
use_command_line
|
Controls whether or not the new() method parses the command-line options given when the script was invoked. If the value of the argument is true, which is the default, the command-line options specify or override any of the subsequent arguments and control debug and logging options. The value of 0 defines the value as false.
|
interactive
|
If the value of the argument is true, the script prompts you for the username and password if they have not been specified either in the script or on the command line. The Term::ReadKey module must be installed.
The most secure way of using the toolkit is for the input not to be echoed to the screen, which avoids hard coding or any record of passwords having been used. The default value is false. For example, the script does not ask for user input. As a command-line option, the interactive argument does not take any arguments. You can specify -interactive to turn on the interactive mode.
|
transport
|
Means by which the Perl application should connect to the router, which defaults to Telnet. If a different value is specified, the new() method searches for a package called Cisco::IOS_XR::Transport::<transport_name>. If found, the Perl application uses that package to connect to the router.
|
ssh_version
|
If the chosen transport option is SSH and the SSH executable on your system supports SSH v2, specifies which version of SSH you want to use for the connection. The valid values are 1 and 2. If the SSH executable supports only version 1, an error is caused by specifying the ssh_version argument.
|
host
|
Specifies the name or IP address of the router to which to connect. The router console or auxiliary ports should not be used because they are likely to cause problems for the script when logging in and offer significantly lower performance than a management port.
|
port
|
Specifies the TCP port for the connection. The default value depends on the transport being used.
|
username
|
Specifies the username to log in to the router.
|
password
|
Specifies the corresponding password.
|
connection_timeout
|
Specifies the timeout value that is used to connect and log in to the session. If not specified, the default value is 5 seconds.
|
response_timeout
|
Specifies the timeout value that is used when waiting for a response to an XML request. If not specified, the default value is 10 seconds.
|
prompt
|
Specifies the prompt that is displayed on the router after a successful log in. The default is <host>#.
|
The following example shows the arguments given using the standard Perl hash notation:
my $session = new Cisco::IOS_XR(transport => 'telnet',
connection_timeout => 3);
Table 15-4 describes the additional command-line options that can be specified.
Table 15-4 Command-Line Options
Name
|
Description
|
debug
|
Turns on the specified debug type and can be repeated to turn on more than one type.
|
logging
|
Turns on the specified logging type and can be repeated to turn on more than one type.
|
log_file
|
Specifies the name of the log file to use.
|
telnet_input_log
|
Specifies the file used for the Telnet input log, if you are using Telnet.
|
telnet_dump_log
|
Specifies the file used for the Telnet dump log, if you are using Telnet
|
To use the command-line options when invoking a script, use the -option value format (assuming the option has a value). The option name does not need to be given in full, but must be long enough to be distinguished from other options. The following example is displayed:
perl my_script.pl -host my_router -user john -interactive -debug xml
Closing a Management Session on a Router
When an object of type Cisco::IOS_XR is created, the transport connection to the router and any associated resources on the router are maintained until the object is destroyed and automatically cleaned. For most scripts, the process should occur automatically when the script ends.
If you want to close a particular session during the course of the script, use the close() method. You can perform an operation on a large set of routers sequentially, and not keep all sessions open for the duration of the script, as displayed in the following example:
my $session1 = new Cisco::IOS_XR(host => `router1', ...);
my $session2 = new Cisco::IOS_XR(host => `router2', ...);
Sending an XML Request to the Router
Requests and responses pass between the client and router in the form of XML. Depending on whether the XML is stored in a string or file, you can construct an XML request that is sent to the router using either the send_req or send_req_file method. Some requests are sent without specifying any XML by using the configuration services methods, for example, commit and lock or the Data Object interface.
The following example shows how to send an XML request in the form of a string:
my $xml_req_string = `<?xml...><Request>...</Request>';
my $response = $session->send_req($xml_req_string);
The following example shows how to send a request stored in a file:
my $response = $session->send_req_file('request.xml');
Using Response Objects
Both of the send_req and send_req_file methods return a Cisco::IOS_XR::Response object, which contains the XML response returned by the router.
Note
Both send methods handle iterators in the background; so if a response consists of many parts, the response object returned is the result of merging them back together.
Retrieving the Response XML as a String
The following example shows how to use the to_string method:
$xml_response_string = $response->to_string;
Writing the Response XML Directly to a File
The following example shows how to use the write_file method by specifying the name of the file to be written:
$response->write_file('response.xml');
Retrieving the Data Object Model Tree Representation of the Response
The following example shows how to retrieve a Data Object Model (DOM) tree representation for the response:
my $document = $response->get_dom_tree;
You should be familiar with the DOM, which an XML document represents an object tree structure. For more information, see http://www.w3.org/DOM/
Note
The returned DOM tree type will be of type XML::LibXML::Document, because this is the form in which the response is held internally. The method is quick, because it does not perform extra parsing and should be used in preference to retrieving the string form of the XML and parsing it again (unless a different DOM library is used).
Determining if an Error Occurred While Processing a Request
The following example shows how to determine if an error occurred while processing a request:
my $error = $response->get_error;
If it is only of interest whether errors occurred but not what all the errors were, use the get_error method to return one error from the response. This returns an error object that represents the first error found or is undefined if none were found.
Retrieving a List of All Errors Found in the Response XML
The following example shows how to list all errors that occurred rather than just one by using the get_errors method:
my @errors = $response->get_errors;
The get_errors method returns an array of error objects that represents all errors that were found in the response XML. For more information, see "Using the Error Objects" section.
Using the Error Objects
Error objects are returned when calling the get_error and get_errors methods on a response object, and are used to represent an error encountered in an XML response. Table 15-5 lists the methods for the object.
Table 15-5 List of Methods for the Object
Method
|
Description
|
get_message
|
Returns the error message string that was found in the XML.
|
get_code
|
Returns the corresponding error code.
|
get_element
|
Returns the tag name of the XML element in which the error was found.
|
get_dom_node
|
Returns a reference to the element node in the response DOM1 tree.
|
to_string
|
Returns a string that contains the error message, code, and element name. If the error object is used in a scalar context, the method is used automatically to convert it to a string. The following example displays all information in an error:
Error encountered in object ConfederationPeerASTable: 'XMLMDA' detected
the 'warning' condition 'The XML request does not conform to the schema.
A child element of the element on which this error appears includes a
non-existent naming, filter, or value element. Please check the request
against the schema.' Error code: 0x4368a000
|
Using the Configuration Services Methods
Methods are provided to enable the standard configuration services operations to be performed without knowledge of the underlying XML. These are the operations that are usually performed at the start or end of a configuration session, such as locking the running configuration or saving the configuration to a file.
The config_commit() function takes the following optional arguments:
•
mode
•
label
•
comment
Committing the Target Configuration
The arguments are specified in any order using the standard Perl hash notation, as shown in the following example:
$response = $session->config_commit(Label => 'Example1', Comment => 'Just an example');
A response object is returned from which any errors can be extracted, if desired. To retrieve the commit ID that was assigned to the commit upon success, you can call the get_commit_id() method on the response object, as shown in the following example:
$commit_id = $response->get_commit_id();
Locking and Unlocking the Running Configuration
The following example shows how to use the config_lock and config_unlock functions, which take no arguments:
$error = $session->config_lock;
$error = $session->config_unlock;
Loading a Configuration from a File
The following example shows how to contain a filename as an argument:
$error = $session->config_load(Filename => 'test_config.cfg');
Loading a Failed Configuration
The following example shows how to use the config_load_failed function, which take no arguments:
$error = $session->config_load_failed;
Saving a Configuration to a File
The following example shows how to use two arguments for the config_save() function:
$error = $session->config_save(Filename => 'disk0:/my_config.cfg', Overwrite => 'true');
The first argument shows how to use the filename to which to write and the Boolean overwrite setting. The filename must be given with a full path. The second argument is optional.
Clearing the Target Configuration
The following example shows how to use the config_clear function, which takes no arguments:
$error = $session->config_clear;
Getting a List of Recent Configuration Commits
The following example shows how to use the config_get_history() function that takes the optional arguments Maximum and RollbackOnly, which can be specified in any order by using the standard Perl hash notation:
$response = $session->config_get_history(Maximum => 10, RollbackOnly => `true');
It returns a response object in which the method get_entries can be called. This returns an array of entry objects from which the get_key method can be called to retrieve the CommitID and get_data to retrieve the rest of the fields.
Rolling Back to a Previous Configuration
The following example shows how to use the config_rollback() function that takes the optional arguments Label and Comment, and exactly one of the two arguments CommitID or Previous:
$error = $session->config_rollback(Label => `Rollback test', CommitID => 1000000072);
These arguments can be specified in any order using the standard Perl hash notation.
Getting a List of Current Configuration Sessions
The following example shows how to use the config_get_sessions function, which takes no arguments:
$response = $session->config_get_sessions;
It returns a response object in which the method get_entries can be called. This returns an array of entry objects in which the method get_key method can be called to retrieve the session ID and get_data method to retrieve the rest of the fields.
Sending a Command-Line Interface Configuration Command
The following example shows how to use the config_cli() function, which takes a string argument containing the CLI format configuration that you want to apply to the router:
$response = $session->config_cli($cli_command);
To retrieve the textual CLI response from the response object returned, you can use the get_cli_response() method, as shown in the following example:
$response_text = $response->get_cli_response();
Note
Apart from the config_commit, config_get_history, config_get_sessions, and config_cli methods, each of the other methods returns a reference to an error object if an error occurs or is undefined. For more information, see "Using the Error Objects" section.
Using the Cisco IOS XR Perl Data Object Interface
Instead of having to specify the XML requests explicitly, the interface allows access to management data using a Perl notation. The Data Object interface is a Perl representation of the management data hierarchy stored on the router. It consists of objects of type Cisco::IOS_XR::Data, which corresponds to items in the IOS_XR management data hierarchy, and a set of methods for performing data operations on them.
To use the Data Object interface, a knowledge is needed of the underlying management data hierarchy. The management data on an IOS_XR router all under one of six root objects, namely Configuration, Operational, Action, AdminConfiguration, AdminOperational, and AdminAction. The objects that lie below these objects in the hierarchy, along with definitions of any datatypes or filters that are used by them, are documented in the Perl Data Object Documentation.
A hash structure is defined to be a scalar (that is, basic) type, for example, string or number, a reference to a hash whose values are hash structures, or a reference to an array whose values are hash structures. This standard Perl data structure corresponds naturally to the structure of management data on an IOS_XR router. The following example shows how to use a hash structure:
# reference to a hash of basic types
my $struct2 = {Forename => $struct1, Surname => `smith'};
# reference to an array of basic types
my $struct3 = (`dog', `budgie', `cat');
# reference to a hash of references and basic types
my $struct4 = {Name => $struct2, Age => `30', Pets => $struct3};
The following sections describe how to use the Perl Data Object Documentation:
•
Understanding the Perl Data Object Documentation
•
Creating Data Objects
•
Specifying the Schema Version to Use When Creating a Data Object
•
Using the Data Operation Methods on a Data Object
•
Using the Batching API
•
Displaying Data and Keys Returned by the Data Operation Methods
•
Specifying the Session to Use for the Data Operation Methods
Understanding the Perl Data Object Documentation
The Perl Data Object Documentation consists of many files, and each contains a subtree of the total management data hierarchy. The main part of each filename tells you the area of management data to which that file refers, and the suffix usually tells you which root object that file's data lies below. For example, a file containing configuration data usually not end in _cfg.html. Some files may not contain any object definitions but just some data types or filter definitions, and usually do not end in _common.html.
For leaf objects, the object definition describes the data that the object contains. For nonleaf objects, the definition provides a list of the object's children within the tree. More precisely, the object definition consists of the following items:
•
Name of the object.
•
Brief description of what data is contained in the object or in the subtree below.
•
List of the required task IDs that are required to access the data in the object and subtree.
•
List of parent objects and the files in which they are defined, if the object is the top-level object in that file.
•
If the object is a leaf object (for example, data is contained without child objects), and its name is not unique within that file, parent objects are listed.
•
If the object is a table entry, a list of the keys that are needed to identify a particular item in that table. For each key, a name, description, and datatype are given.
•
If the object is a table, a list of the filters that can be applied to that table.
•
If the object is a leaf object, a list of the value items that are contained. For each value item, a name, description, and datatype are given.
•
If the object is a leaf object, its default value (for example, the values for each of its value items that would be assumed if the object did not exist), if there is one.
•
List of the data operation methods, get_data, set_data, and so forth that are applicable to the object. For more information, see "Specifying the Schema Version to Use When Creating a Data Object" section
Creating Data Objects
Data objects form a tree corresponding to a section of the data hierarchy. The first object to be created is one of the root data objects, and is created by a call to Cisco::IOS_XR::Data::<object_name>. For example, <object_name> is one of the following objects:
•
Configuration
•
Operational
•
Action
•
AdminOperational
•
AdminAction
The following example shows how to create the Operational object:
my $oper = Cisco::IOS_XR::Data::Operational;
Because the syntax is rather lengthy for a task that is relatively common, there is a shorter way of creating a data object, which eliminates the need for the Cisco::IOS_XR::Data:: at the front of the function name. This is achieved by importing the symbols for the root data object functions when using the Cisco::IOS_XR package at the top of the script. The following example shows how to import the Configuration and Operational functions:
use Cisco::IOS_XR qw(Configuration Operational);
The following example shows how to import all the root data objects without listing them explicitly:
use Cisco::IOS_XR qw(:root_objects);
Note
If there is a function in the script's name space with a name that is one of Configuration, Operational, and so forth, the root data objects cannot be imported with use Cisco::IOS_XR qw(Configuration Operational) and refer to the objects simply as Configuration, as this may not have the desired effect due to the ambiguity. Instead, you have to refer to them with the more lengthy Cisco::IOS_XR::Data::Configuration (that is, fully qualified) syntax.
If the root data object is Configuration, additional arguments can be specified that are given as name and value pairs. The Source argument can have values such as ChangedConfig, CurrentConfig, MergedConfig (the default value if the Source argument is not specified), and CommitChanges. If CommitChanges is specified, one of the two arguments ForCommitID and SinceCommitID must also be specified, as shown in the following example:
my $config = Configuration(Source => `CommitChanges', ForCommitID => 1000083);
Data objects can be created from existing ones by calling a method on the existing object for which the name is that of the new object that you want to create. The object from which the new object was created is known as its parent, as shown in the following example:
my $config = Configuration;
If references to the intermediate objects are not required, the syntax allows a very compact way of creating objects as the methods can be strung together. The following example shows how to create a BGP object whose parent is Configuration:
my $bgp = Configuration->BGP;
If an object is an item in a table, its keys can be specified as arguments when the object is created by using the standard Perl hash notation. The following example shows how to create an object corresponding to the interface configuration for interface Ethernet 0/0/0/0:
my $if_conf = Configuration->InterfaceConfigurationTable->
InterfaceConfiguration(`Active' => `act', `Name' => `Ethernet0/0/0/0');
Keys can also be specified by passing a hash structure as an argument. The hash structure would usually have been returned as a key from one of the data operation methods, for example, get_keys, but can be defined explicitly, as in the following alternative to the previous example:
my $key = {`Active' => `act', `Name' => `Ethernet0/0/0/0'};
my $if_conf = Configuration->InterfaceConfigurationTable->InterfaceConfiguration($key);
There may be some occasions when it is better to keep references to the intermediate data objects, such as when you want to refer to more than one item in a table. The following example shows how to refer to more than one interface in the interface configuration table:
my $if_1_key = {`Active' => `act', `Name' => `Ethernet0/0/0/0'};
my $if_2_key = {`Active' => `act', `Name' => `POS0/4/0/0'};
my $if_conf_table = Configuration->InterfaceConfigurationTable;
my $if_conf_1 = $if_conf_table->InterfaceConfiguration($if_1_key);
my $if_conf_2 = $if_conf_table->InterfaceConfiguration($if_2_key);
Currently, there is no checking within the library that the object names specified are valid. However, when a data operation is performed on a data object, and if the object hierarchy is invalid, the response from the router should contain an error to this effect. For information on the valid object names in the data hierarchy, see "Understanding the Perl Data Object Documentation" section.
Specifying the Schema Version to Use When Creating a Data Object
If you want to specify which version of a particular schema you are using, you may pass this information as arguments when creating the relevant data object. The router checks this information against its own schema versions when it receives a request, and rejects the request if the versions are not compatible. For more information about versioning, see "Cisco XML Schema Versioning."
The object in which this information should be specified is the top-level object within the schema whose version you want to specify. This information is found at the top of the page of the schema. For more information, see "Understanding the Perl Data Object Documentation" section. For example, you may want to specify that using BGP schema version 1.4. The following example shows how to create a BGP object:
my $bgp = Configuration->BGP(MajorVersion => 1, MinorVersion => 4);
The object can then be used in the normal way to create child objects. Whenever any data operation request is sent using one of these objects, the specified version information is always included.
Using the Data Operation Methods on a Data Object
To access the management data on the router, data operation methods, which can be called on data objects, are provided for the getting, setting, and deletion of the corresponding data. The management session in which they act is the current session, and usually the most recent Cisco::IOS_XR object to be created. For more information on how to manually set which session to use for the data operation methods, see "Specifying the Session to Use for the Data Operation Methods" section.
The types of data operation methods that are allowed depend on what the root data object is for the data object in question. For example, if the root object is Configuration, getting, setting, and deletion are allowed. If it is Operational, only getting is allowed. The get methods that can be used also depend on whether the data object in question is a leaf object or a table object.
Each of the data operation methods returns a response object from which any errors can be extracted. For more information, see "Using Response Objects" section. For the methods that return values of some sort, a method of the same name is used to actually extract the information required from the response object.
get_data Method
The get_data method can be called on a leaf object and is used to retrieve the data contained in that object. It returns a response object from which the desired data can be extracted by calling the method of the same name, get_data.
The following example shows how to get the data for the interface configuration:
my $response = $if_conf->get_data;
if (defined($response->get_error)) {
die $response->get_error;
my $data = $response->get_data;
find_data Method
The find_data method performs a get request on a leaf object, but with the option of specifying key values for any table entries that occur within the hierarchy as a wildcard rather than as explicit values.
The XML response then contains every occurrence of the required object that matches the combination of key values and wildcards specified in the hierarchy.
Note
Wildcards are supported for only configuration data.
Currently, the function does not interpret the XML response in any way, due to the potentially complex structure of the returned data, and so the returned response object can be used only to extract the XML and any other errors in the usual way.
When specifying the keys for a table entry object, if you want one of the keys to be a wildcard rather than specified explicitly, pass an argument called wildcard value, where the value is the name of the key. If access control lists (ACLs) have been configured, the following example shows how to get the inbound ACLs of all interfaces on the router:
my $response = $if_conf_table->
InterfaceConfiguration(Active => `act', wildcard => `Name')->
IPV4PacketFilter->Inbound->find_data;
If you want one or more of the keys for a particular table entry to be wildcards, the value of the wildcard can be a reference to an array containing the names of those keys. For example, if you want to include any nonactive interface configuration in the above example, you would do the following:
my $response = $if_conf_table->
InterfaceConfiguration(wildcard => [`Name', `Active'])->
IPV4PacketFilter->Inbound->find_data;
get_keys Method
The get_keys method must be called only on a table object and is used to retrieve a list of the keys for each item in the table. It returns a response object from which the keys can be extracted by calling the method of the same name, get_keys. This returns an array of hash structures containing the key values. A returned key can also be used as the parameter to a new data object.
The following example shows how to get the keys for each item in the configuration table and then for each key to create a data object and perform some operations with it:
my $response = $if_conf_table->get_keys;
if (defined($response->get_error)) {
die $response->get_error;
foreach my $key ($response->get_keys) {
my $interface = $if_conf_table->InterfaceConfiguration($key);
# do something with this object such as get_data...
The following two optional arguments can be specified as name and value pairs:
•
Count—Determines the maximum number of table entries that will be returned.
•
Filter—Specifies a reference to a hash whose elements are the arguments to the filter plus an element Filtername that specifies the filter to use, as shown in the following example:
my $table = Operational->BGP->NeighborTable;
my $filter = {FilterName => `BGP_ASFilter', AS => 6};
my $response = $table->get_keys(Count => 10, Filter => $filter);
get_entries Method
Similarly, the get_entries method must be called only on a table object, and is used to retrieve a list of the keys and data for each entry in the table.
It returns a response object from which the entries can be extracted by calling the method of the same name, get_entries. This method returns an array of entry objects. The get_key and get_data methods can then be called on an entry object to extract the key and data for that entry.
The following example shows how to get an array of the keys and data for each item in the interface configuration table and perform some operations with each:
my $response = $if_conf_table->get_entries;
if (defined($response->get_error)) {
die $response->get_error;
foreach my $entry ($response->get_entries) {
my $key = $entry->get_key;
my $data = $entry->get_data;
# do something with these values...
The same optional arguments, Count and Filter, can be specified in the get_keys method.
set_data Method
The set_data method is called only on leaf objects, and sets the data for the object in the specified argument. The argument must be a hash structure; for example, the data is returned by a previous call of get_data or get_entries.
The returned value is a response object from which the entries are extracted. Unless batching is enabled, the returned value is undefined.
The following example shows how to add a IPv4Multicast object to the GlobalAFTable of BGP AS 1 object:
my $data = {`Enabled' => `true'};
my $global_af = Configuration->BGP->AS(`AS' => 1)->Global->
GlobalAFTable->GlobalAF(`AF' => `IPv4Multicast');
my $error = $global_af->set_data($data);
Note
•
If not all items in a leaf object are specified when setting data, the remaining items are set to null (overwrites any value that may have been there previously).
•
If the data is passed to set_data as a hash or basic type (not an array), it can also be provided explicitly rather than by reference, in the same way as keys can be specified.
The following example shows how data that is passed to set_data as a hash or basic type:
my $error = $global_af->set_data(`Enabled' => `true');
If the data to be set is an array, it must be provided by references because if it were given explicitly it would be incorrectly interpreted as a hash.
delete_data Method
The delete_data method can be used on any object, and deletes all data below that object in the hierarchy, as shown in the following example:
my $error = Configuration->BGP->AS(`AS' => 1)->Global->delete_data;
The returned value is a response object from which any errors can be extracted. Unless batching is enabled, the returned value is undefined.
Using the Batching API
By default, whenever the set_data or delete_data methods are called on a data object, the resulting XML request is sent immediately. The script is enabled to verify immediately whether or not the operation was successful. However, if a script wants to set or delete many items at once, this can be a very inefficient method.
By using the batching API, a script can specify that it wants a group of set or delete operations all to be sent together in one XML request. This reduces the overhead of the router having to process multiple requests and reduces the amount of data that needs to be sent. Due to the way two XML requests with overlapping hierarchies are merged, the resulting XML is not as long as the sum of the original two. The common hierarchy is not repeated.
Note
A commit operation cannot be performed within a batch. To enforce this, the config_commit() function dies with an error if it is called while batching is in progress.
batch_start Method
When the batch_start method is called on the session object in question, all subsequent calls of set_data or delete_data are not performed immediately but are stored locally until the batch_send method is called. The following example shows how to enable batching on the session $session:
Note
Any calls to set_data or delete_data between the batch_start and the subsequent batch_send methods return undefined rather than as a response object
batch_send Method
The batch_send method should be called at the point in the script when you want to send all set and delete operations that were made since the previous call to batch_start. The batch_send method sends these operations as a single XML request and returns a single response object. If this response contains no errors, all operations were successful. Otherwise, the details of any error returned must be analyzed to determine which operation caused the error, as shown in the following example:
my $response = $session->batch_send;
my $error = $response->get_error;
die "Error in batch_send: $error";
Note
An error occurs in the script if batch_send is called while batching is not in progress, for example, it must occur after a call to batch_start.
Displaying Data and Keys Returned by the Data Operation Methods
When a key or data is returned either by calling get_data or get_keys functions on a response object, or by calling get_data or get_key functions on an entry object that was returned from the get_entries function, it is always in the form of a value object. This object behaves identically to a hash structure; therefore, the value object can be easily navigated using hash and array dereferencing if required. A key value can be used when creating a new data object or as an argument to the set_data function.
However, if you want to display the whole structure or any parts of it, use the built-in function to_string on any value object that returns a formatted string form of the structure. In fact, you do not need to call the function to_string on the object. Using the value object in a scalar context, automatically converts it to a formatted string. The following code is shown:
my $response = Configuration->InterfaceConfigurationTable
->InterfaceConfiguration(Active => `act', Name => `POS0/2/0/0')
print $response->get_data;
The following example displays that data on the screen in a readable way:
Specifying the Session to Use for the Data Operation Methods
If only one Cisco::IOS_XR object has been created, this management session is automatically used by subsequent data operation methods. In scripts in which more than one Cisco::IOS_XR object has been created, the data operation methods use whichever session is the current session. The session to use for the data operation methods is whichever Cisco::IOS_XR object was the last to be created, unless, you have since asked to change the current session by calling the method use_for_data_operations on the Cisco::IOS_XR object that you want to use.
The following example shows how to create two management sessions and then use the first one for subsequent data operations:
my $session1 = new Cisco::IOS_XR(host => `router1');
# Here the current session is $session1
my $session2 = new Cisco::IOS_XR(host => `router2');
# Here the current session is $session2
$session1->use_for_data_operations;
# Now the current session is $session1 again
Cisco IOS XR Perl Notification and Alarm API
The notification API provides functionality that enables a Perl script to register for and receive asynchronous responses or notifications during a management session on the router. One important type of notification is Alarms for which the specific API is provided.
The API allows a script to register, deregister, and receive alarms using Perl methods and objects. This completely hides the underlying XML from the user in much the same way that the data object API for normal management requests does.
The following sections describe how to use the Alarm API:
•
Registering for Alarms
•
Deregistering an Existing Alarm Registration
•
Deregistering All Registration on a Particular Session
•
Receiving an Alarm on a Management Session
Registering for Alarms
To register for a receipt of alarms on a particular management session, use the alarm_register function of the Cisco::IOS_XR object that represents the management session. The alarm_register function takes as arguments a list of name and value pairs, which specify the set of filter criteria that you want to use to filter the alarms that you receive. If no filter criteria are specified, all alarms are received. For a list of the valid filter criteria, see the "Alarm Registration" section of "Alarms."
The following example shows how to register for receipt of all alarms of Group SYS and Code CONFIG_I:
my $response = $session->alarm_register(Group => `SYS', Code => `CONFIG_I');
The alarm_register function returns a response object that is checked for errors in a normal way. These errors may be returned if a value specified for one of the filter criteria is invalid.
In addition, a successful registration response contains a registration ID, which must be used if the script wants to deregister. In other words, cancel this registration. The registration ID can be extracted from the response object by calling the get_registration_id method, as shown in the following example:
my $registration_id = $response->get_registration_id;
Deregistering an Existing Alarm Registration
To deregister a particular registration, use the alarm_deregister function on the Cisco::IOS_XR object, by giving as an argument for the registration ID that was returned from the initial registration as follows:
my $response = $session->alarm_deregister($registration_id);
The response object that is returned is checked for errors to determine if the deregistration was successful.
Deregistering All Registration on a Particular Session
To deregister all alarm registrations that have been made on a particular management session, use the alarm_deregister_all function as follows:
my $response = $session->alarm_deregister_all;
The response object can be used to check for any errors. Currently, no errors should exist even if there was no registration to deregister on that session.
Receiving an Alarm on a Management Session
After alarms have been registered, the alarm_receive function can be called on the management session object. The alarm_receive function attempts to pick up an alarm from the transport, which may happen immediately if there is already an alarm waiting in the buffer. Otherwise, it waits until one is received. An optional timeout value can be specified as the argument. If an alarm is not received within the timeout limit, the function returns undefined. If no timeout value is specified, the default of an infinite timeout is used, as shown in the following example:
my $alarm = $session->alarm_receive(60); # Wait 60 seconds for an alarm
If an alarm is received within the timeout limit, the function returns an alarm object from which the following values can be extracted:
•
RegistrationID—Specifies the registration ID that was returned from the registration for the matched alarm.
•
SourceID
•
EventID
•
Timestamp
•
Category
•
Group
•
Code
•
Severity
•
State
•
CorrelationID
•
AdditionalText
These values can be extracted using the corresponding get_* functions, as shown in the following example:
my $registration_id = $alarm->get_registration_id;
my $event_id = $alarm->get_event_id;
my $text = $alarm->get_additional_text;
Using the Debug and Logging Facilities
The following sections describe how to control debug and logging facilities within your script:
•
Debug Facility Overview
•
Logging Facility Overview
For more information on how to control debug and logging from the command line when starting a script, see "Starting a Management Session on a Router" section.
Debug Facility Overview
The debug facility displays on the screen run-time information to aid investigation of problems. The user is given fine control over which debug messages are displayed to the screen by allowing the user to specify at any point in the script which types of debug they want to be displayed and which ones they do not.
Note
Debug applies to the script as a whole rather than to each management session.
Table 15-6 lists the current built-in types.
Table 15-6 Definitions for the Debug Types
Type
|
Description
|
transport
|
Specifies the messages relating to the state of the current transport, for example, Telnet or SSH.
|
xml
|
Displays the request and response XML for every request sent to the router that includes those generated by the Data Object interface and configuration services methods.
|
xml_response_parts
|
Displays each part separately if an XML response has been split into multiple parts.
|
user
|
Specifies that the script writer can be used to add his or her own debug messages.
|
To turn on debug, use the Cisco::IOS_XR::debug_on function at any point in your script, giving those types of debug that you want to turn on as arguments. This is shown in the following example:
Cisco::IOS_XR::debug_on(`transport', `xml');
Similarly, to turn off debug for certain types, use the Cisco::IOS_XR::debug_off function. Specifying no arguments turns off all types of debug, as shown in the following example:
Cisco::IOS_XR::debug_off(`xml');
To insert your own debug messages in a script, use the Cisco::IOS_XR::debug function, giving as arguments the type of debug followed by the message. This is shown in the following example:
Cisco::IOS_XR::debug(`user', `This is a user debug message');
In addition to being able to use the built-in type user to add debug messages to the scripts, it is possible to define your own debug types to give greater control over what is displayed. This is done by calling the Cisco::IOS_XR::add_debug_types function and giving as arguments a list of name and value pairs. The name is the name of the new type, and the value is its display name (that is, the string that appears at the beginning of every message of that type when displayed on the screen at run time). This is shown in the following example:
Cisco::IOS_XR::add_debug_types(`general' => `General', `detailed' => `Detailed');
These types can immediately be used to write debug messages, as shown in the following example:
Cisco::IOS_XR::debug(`detailed', `This is a detailed debug message');
Logging Facility Overview
The logging facility leaves an audit trail of usage or diagnoses problems after an error has occurred. The types of logging messages that are supported include all debug types, including any user-defined debug types.
To turn on logging, use the Cisco::IOS_XR::logging_on function at any point in your script, giving those types of messages that you want to turn on for logging as arguments. This is shown in the following example:
Cisco::IOS_XR::logging_on(`transport', `xml');
Similarly, to turn off logging for certain types, use the Cisco::IOS_XR::logging_off function. Logging can be turned off for all types of messages by giving no arguments, as shown in the following example:
Cisco::IOS_XR::logging_off(`xml');
By default, the messages will be written to a file called ios_xr_log.txt in the same directory as the running script. You can specify which file to use with the function Cisco::IOS_XR::set_log_file that can be called at any point in your script. For example, you may want to specify a different log file before carrying out operations on a different management session, as shown in the following example:
Cisco::IOS_XR::set_log_file(`router2_log.txt');
In addition to being able to log each of the standard message types, the Telnet module allows two types of extra logging at a lower level. These can be turned on for the duration of a management session by specifying one of the following arguments when calling Cisco::IOS_XR::new, as listed in Table 15-7.
Table 15-7 Logging Arguments
Type
|
Description
|
telnet_input_log
|
Logs all data received from the router, which usually includes the echoes of everything that is sent.
|
telnet_dump_log
|
Logs all I/O1 through the Telnet connection in a dump format. The dump, however, is less readable than the input log.
|