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);
}