Example: Change the Configuration Using a NETCONF Perl Client Application
The NETCONF Perl distribution includes several
sample Perl scripts to perform various functions on devices running
Junos OS. The edit_configuration.pl script locks, modifies, uploads, and commits the configuration on
a device. It uses the basic structure for sending requests but also
defines a graceful_shutdown
subroutine
that handles errors. The following sections describe the different
functions that the script performs:
Handling Error Conditions
The graceful_shutdown
subroutine
in the edit_configuration.pl script
handles errors encountered in the NETCONF session. It employs the
following additional constants:
# query execution status constants use constant REPORT_SUCCESS => 1; use constant REPORT_FAILURE => 0; use constant STATE_CONNECTED => 1; use constant STATE_LOCKED => 2; use constant STATE_CONFIG_LOADED => 3;
The first two if
statements in the subroutine
refer to the STATE_CONFIG_LOADED
and STATE_LOCKED
conditions, which apply specifically to
loading a configuration in the edit_configuration.pl script.
sub graceful_shutdown { my ($jnx, $state, $success) = @_; if ($state >= STATE_CONFIG_LOADED) { # We have already done an <edit-config> operation # - Discard the changes print "Discarding the changes made ...\n"; $jnx->discard_changes(); if ($jnx->has_error) { print "Unable to discard <edit-config> changes\n"; } } if ($state >= STATE_LOCKED) { # Unlock the configuration database $jnx->unlock_config(); if ($jnx->has_error) { print "Unable to unlock the candidate configuration\n"; } } if ($state >= STATE_CONNECTED) { # Disconnect from the Netconf server $jnx->disconnect(); } if ($success) { print "REQUEST succeeded !!\n"; } else { print "REQUEST failed !!\n"; } exit; }
Locking the Configuration
The main section of the edit_configuration.pl script begins by establishing a connection to a NETCONF server.
It then invokes the lock_configuration
method
to lock the configuration database. If an error occurs, the script
invokes the graceful_shutdown
subroutine
described in Handling Error Conditions.
print "Locking configuration database ...\n"; my %queryargs = ( 'target' => 'candidate' ); $res = $jnx->lock_config(%queryargs); # See if you got an error if ($jnx->has_error) { print "ERROR: in processing request \n $jnx->{'request'} \n"; graceful_shutdown($jnx, STATE_CONNECTED, REPORT_FAILURE); }
Reading In the Configuration Data
In the following code sample, the edit_configuration.pl script reads in and parses a file that contains Junos XML configuration tag elements or ASCII-formatted statements. A detailed discussion of the functional subsections follows the complete code sample.
# Load the configuration from the given XML file print "Loading configuration from $xmlfile \n"; if (! -f $xmlfile) { print "ERROR: Cannot load configuration in $xmlfile\n"; graceful_shutdown($jnx, STATE_LOCKED, REPORT_FAILURE); } # Read in the XML file my $config = read_xml_file($xmlfile); print "\n\n$config \n\n"; %queryargs = ( 'target' => 'candidate' ); # If we are in text mode, use config-text arg with wrapped # configuration-text, otherwise use config arg with raw XML if ($opt{t}) { $queryargs{'config-text'} = '<configuration text> . $config . </configuration-text>'; } else { $queryargs{'config'} = $config;
The first subsection of the preceding code sample verifies the
existence of the file containing configuration data. The name of the
file was previously obtained from the command line and assigned to
the $xmlfile
variable. If the file does
not exist, the script invokes the graceful_shutdown
subroutine.
print "Loading configuration from $xmlfile \n"; if (! -f $xmlfile) { print "ERROR: Cannot load configuration in $xmlfile\n"; graceful_shutdown($jnx, STATE_LOCKED, REPORT_FAILURE); }
The script then invokes the read_xml_file
subroutine, which opens the file for reading and assigns its contents
to the $config
variable. The queryargs
key target
is
set to the value candidate
. When the script
calls the edit_configuration
method, the
candidate configuration is edited.
# Read in the XML file my $config = read_xml_file($xmlfile); print "\n\n$config \n\n"; %queryargs = ( 'target' => 'candidate' );
If the -t
command-line option was included when the edit_configuration.pl script was invoked, the file
referenced by the $xmlfile
variable should
contain ASCII-formatted configuration statements like those returned
by the CLI configuration-mode show
command. If the configuration
statements are in ASCII-formatted text, the script encloses the configuration
stored in the $config
variable within the configuration-text
tag element and stores the result
in the value associated with the queryargs
hash key config-text
.
If the -t
command-line option was not included when
the edit_configuration.pl script
was invoked, the file referenced by the $xmlfile
variable contains Junos XML configuration tag elements. In this
case, the script stores just the $config
variable as the value associated with the queryargs
hash key config
.
if ($opt{t}) { $queryargs{'config-text'} = '<configuration text> . $config . </configuration-text>'; } else { $queryargs{'config'} = $config;
Editing the Configuration Data
The script invokes the edit_config
method to load the configuration changes onto the device. It invokes
the graceful_shutdown
subroutine if the
response from the NETCONF server has errors.
$res = $jnx->edit_config(%queryargs); # See if you got an error if ($jnx->has_error) { print "ERROR: in processing request \n $jnx->{'request'} \n"; # Get the error my $error = $jnx->get_first_error(); get_error_info(%$error); # Disconnect graceful_shutdown($jnx, STATE_LOCKED, REPORT_FAILURE);
Committing the Configuration
If there are no errors up to this point, the script invokes
the commit
method to commit the configuration
on the device and make it the active configuration.
# Commit the changes print "Committing the <edit-config> changes ...\n"; $jnx->commit(); if ($jnx->has_error) { print "ERROR: Failed to commit the configuration.\n"; graceful_shutdown($jnx, STATE_CONFIG_LOADED, REPORT_FAILURE); }