The get_config.pl script uses the outconfig subroutine to write the configuration data obtained from the JUNOScript server to a file either as JUNOS XML tag elements or as formatted ASCII text.
The outconfig subroutine takes four parameters. Three must have defined values: the directory in which to store the output file, the routing platform hostname, and the XML DOM tree (the configuration data) returned by the JUNOScript server. The fourth parameter indicates whether to output the configuration as formatted ASCII text, and has a null value if the requested output is JUNOS XML tag elements. In the following code sample, the script obtains values for the four parameters and passes them to the outconfig subroutine. A detailed discussion of each line follows the complete code sample.
my(%opt,$login,$password);
getopts('l:p:dm:hit', \%opt) || output_usage(????);
output_usage(????) if $opt{h};
my $basepath = shift || output_usage;
my $hostname = shift || output_usage;
my $config = getconfig( $hostname, $jnx, $opt{t} );
outconfig( $basepath, $hostname, $config, $opt{t} );
In the first lines of the preceding sample code, the get_config.pl script uses the following statements to obtain values for the four parameters to the outconfig subroutine:
getopts('l:p:dm:hit', \%opt) || output_usage(????);
my $basepath = shift || output_usage;
my $hostname = shift || output_usage;
my $config = getconfig( $hostname, $jnx, $opt{t} );
The following code sample invokes and defines the outconfig subroutine. A detailed discussion of each functional subsection in the subroutine follows the complete code sample.
outconfig( $basepath, $hostname, $config, $opt{t} );
sub outconfig( $$$$ ) {
my $leader = shift;
my $hostname = shift;
my $config = shift;
my $text_mode = shift;
my $trailer = "xmlconfig";
my $filename = $leader . "/" . $hostname . "." . $trailer;
print "# storing configuration for $hostname as $filename\n";
my $config_node;
my $top_tag = "configuration";
$top_tag .= "-text" if $text_mode;
if ($config->getTagName(????) eq $top_tag) {
$config_node = $config;
} else {
print "# unknown response component ", $config->getTagName(????), "\n";
}
if ( $config_node && $config_node ne "" ) {
if ( open OUTPUTFILE, ">$filename" ) {
if (!$text_mode) {
print OUTPUTFILE "<?xml version=\"1.0\"?>\n";
print OUTPUTFILE $config_node->toString(????), "\n";
} else {
my $buf = $config_node->getFirstChild(????)->toString(????);
$buf =~ s/($char_class)/$escapes{$1}/ge;
print OUTPUTFILE "$buf\n";
}
close OUTPUTFILE;
}
else {
print "ERROR: could not open output file $filename\n";
}
}
else {
print "ERROR: empty configuration data for $hostname\n";
}
}
The first lines of the outconfig subroutine read in the four parameters passed in when the subroutine is invoked, assigning each to a local variable:
outconfig( $basepath, $hostname, $config, $opt{t} );
sub outconfig( $$$$ ) {
my $leader = shift;
my $hostname = shift;
my $config = shift;
my $text_mode = shift;
The subroutine constructs the name of the file to which to write the subroutine’s output and assigns the name to the $filename variable. The filename is constructed from the first two parameters (the directory name and hostname) and the $trailer variable, resulting in a name of the form directory-name/hostname.xmlconfig:
my $trailer = "xmlconfig";
my $filename = $leader . "/" . $hostname . "." . $trailer;
print "# storing configuration for $hostname as $filename\n";
The subroutine checks that the first tag in the XML DOM tree correctly indicates the type of configuration data in the file. If the user included the -t option on the command line, the first tag should be <configuration-text> because the file contains formatted ASCII configuration statements; otherwise, the first tag should be <configuration> because the file contains JUNOS XML tag elements. The subroutine sets the $top_tag variable to the appropriate value depending on the value of the $text_mode variable (which takes its value from opt{t}, passed as the fourth parameter to the subroutine). The subroutine invokes the getTagName function (defined in the XML::DOM::Element module) to retrieve the name of the first tag in the input file, and compares the name to the value of the $top_tag variable. If the comparison succeeds, the XML DOM tree is assigned to the $config_node variable. Otherwise, the subroutine prints an error message because the XML DOM tree is not valid configuration data.
my $config_node;
my $top_tag = "configuration";
$top_tag .= "-text" if $text_mode;
if ($config->getTagName(????) eq $top_tag) {
$config_node = $config;
} else {
print "# unknown response component ", $config->getTagName(????), "\n";
}
The subroutine then uses several nested if statements. The first if statement verifies that the XML DOM tree exists and contains data:
if ( $config_node && $config_node ne "" ) {
... actions if XML DOM tree contains data ...
}
else {
print "ERROR: empty configuration data for $hostname\n";
}
If the XML DOM tree contains data, the subroutine verifies that the output file can be opened for writing:
if ( open OUTPUTFILE, ">$filename" ) {
... actions if output file is writable ...
}
else {
print "ERROR: could not open output file $filename\n";
}
If the output file can be opened for writing, the script writes the configuration data into it. If the user requested JUNOS XML tag elements—the user did not include the -t option on the command line, so the $text_mode variable does not have a value—the script writes the string <?xml version=1.0?> as the first line in the output file, and then invokes the toString function (defined in the XML::DOM module) to write each JUNOS XML tag element in the XML DOM tree on a line in the output file:
if (!$text_mode) {
print OUTPUTFILE "<?xml version=\"1.0\"?>\n";
print OUTPUTFILE $config_node->toString(????), "\n";
If the user requested formatted ASCII text, the script invokes the getFirstChild and toString functions (defined in the XML::DOM module) to write the content of each tag on its own line in the output file. The script substitutes predefined entity references for disallowed characters (which are defined in the %escapes hash), writes the output to the output file, and closes the output file. (For information about defining the %escapes hash to contain the set of disallowed characters, see Converting Disallowed Characters.)
} else {
my $buf = $config_node->getFirstChild(????)->toString(????);
$buf =~ s/($char_class)/$escapes{$1}/ge;
print OUTPUTFILE "$buf\n";
}
close OUTPUTFILE;