Generating a Persistent or Transient Change
To generate a persistent or transient change, follow these steps:
- At the start of the script, include the Extensible
Stylesheet Language Transformations (XSLT) or Stylesheet Language
Alternative Syntax (SLAX) boilerplate from Required Boilerplate for Commit Scripts. It is reproduced here for convenience:
XSLT Boilerplate
<?xml version="1.0" standalone="yes"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:junos="http://xml.juniper.net/junos/*/junos"
xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm"
xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0">
<xsl:import href="../import/junos.xsl"/>
<xsl:template match="configuration">
<!-- ... Insert your code here ... -->
</xsl:template>
</xsl:stylesheet>SLAX Boilerplate
version 1.0;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";
match configuration {
/*
* Insert your code here
*/
} At the position indicated by the comment “Insert your code here,” include one or more XSLT programming instructions or their SLAX equivalents. For detailed information, see Summary of XPath and XSLT Constructs and Summary of SLAX Statements. Commonly used XSLT constructs include the following.
- <xsl:choose> <xsl:when> <xsl:otherwise>—Conditional construct that causes different instructions to be processed in different circumstances. The <xsl:choose> instruction contains one or more <xsl:when> elements, each of which tests an XPath expression. If the test evaluates as true, the XSLT processor executes the instructions in the <xsl:when> element. The XSLT processor processes only the instructions contained in the first <xsl:when> element whose test attribute evaluates as true. If none of the <xsl:when> elements’ test attributes evaluate as true, the content of the <xsl:otherwise> element, if there is one, is processed.
- <xsl:for-each select="xpath-expression">—Programming instruction that tells the XSLT processor to gather together a set of nodes and process them one by one. The nodes are selected by the Extensible Markup Language (XML) Path Language (XPath) expression in the select attribute. Each of the nodes is then processed according to the instructions contained in the <xsl:for-each> instruction. Code inside an <xsl:for-each> instruction is evaluated recursively for each node that matches the XPath expression. The context is moved to the node during each pass.
- <xsl:if test="xpath-expression">—Conditional construct that causes instructions to be processed if the XPath expression in the test attribute evaluates to true.
For example, the following XSLT programming instructions select each SONET/SDH interface that does not have the MPLS protocol family enabled:
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-')]/unit">
<xsl:if test="not(family/mpls)">For more information about how to use programming instructions, including examples and pseudocode, see XSLT Programming Instructions Overview. For information about writing scripts in SLAX instead of XSLT, see SLAX Overview.In SLAX, the for-each and if constructs look like this:
for-each (interfaces/interface[starts-with(name, 'so-')]/unit) {
if (not(family/mpls)) {- Include instructions for changing the configuration.
There are two ways to generate a persistent change and two ways to
generate a transient change. To generate a persistent change, you
can either reference the <jcs:emit-change> template or
include a <change> element. To generate a persistent change,
you can either reference the <jcs:emit-change> template
and pass in the tag parameter with 'transient-change' selected or include a <transient-change> element.
The <jcs:emit-change> template allows for more efficient, less error-prone scripting because you can define the content of the change without specifying the complete XML hierarchy for the affected statement. Instead, the XML hierarchy is defined in the XPath expression contained in the script’s programming instruction.
Consider the following examples. Both of the persistent change examples have the same result, even though they place the unit statement in different locations in the <xsl:for-each> and <xsl:if> programming instructions. In both cases, the script searches for SONET/SDH interfaces that do not have the MPLS protocol family enabled, adds the family mpls statement at the [edit interfaces so-fpc/pic/port unit logical-unit-number] hierarchy level, and emits a warning message stating that the configuration has been changed. Likewise, both of the transient change examples have the same result. They both set Point-to-Point Protocol (PPP) encapsulation on all SONET/SDH interface that have IP version 4 (IPv4) enabled.
Persistent Change Generated with the <jcs:emit-change> Template
In this example, the content of the persistent change (contained in the content parameter) is specified without including the complete XML hierarchy. Instead, the XPath expression in the <xsl:for-each> programming instruction sets the context for the change.
The message parameter is also included. This parameter causes the <jcs:emit-change> template to call the <xnm:warning> template, which sends a warning notification to the CLI. The message parameter automatically includes the current hierarchy information in the warning message. (For more information about the parameters available with the <jcs:emit-change> template, see jcs:emit-change Template.)
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-')]/unit">
<xsl:if test="not(family/mpls)">
<xsl:call-template name="jcs:emit-change">
<xsl:with-param name="content">
<family>
<mpls/>
</family>
</xsl:with-param>
<xsl:with-param name="message">
<xsl:text>Adding 'family mpls' to SONET interface.</xsl:text>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
</xsl:for-each>Persistent Change Generated with the <change> Element
In this example, the complete XML hierarchy leading to the affected statement must be included as child elements of the <change> element.
This example includes the current hierarchy information in the warning message by referencing the <jcs:edit-path> and <jcs:statement> templates. For more information about warning messages, see Overview of Generating Custom Warning, Error, and System Log Messages.
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-')]">
<xsl:if test="not(unit/family/mpls)">
<change>
<interfaces>
<interface>
<name><xsl:value-of select="name"/></name>
<unit>
<name><xsl:value-of select="unit/name"/></name>
<family>
<mpls/>
</family>
</unit>
</interface>
</interfaces>
</change>
<xnm:warning>
<xsl:call-template name="jcs:edit-path"/>
<xsl:call-template name="jcs:statement">
<xsl:with-param name="dot" select="unit/name"/>
</xsl:call-template>
<message>Adding 'family mpls' to SONET interface.</message>
</xnm:warning>
</xsl:if>
</xsl:for-each>Transient Change Generated with the <jcs:emit-change> Template
In this example, the content of the transient change (contained in the content parameter) is specified without including the complete XML hierarchy. Instead, the XPath expression in the <xsl:for-each> programming instruction sets the context of the change. The and operator in the XPath expression means both operands are true when converted to Booleans; the second operand is not evaluated if the first operand is false.
The tag parameter is included with 'transient-change' selected. Without the tag parameter, the <jcs:emit-change> template generates a persistent change by default. (For more information about the parameters available with the <jcs:emit-change> template, see Junos Named Templates in the jcs Namespace.)
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-') \
and unit/family/inet]">
<xsl:call-template name="jcs:emit-change">
<xsl:with-param name="tag" select="'transient-change'"/>
<xsl:with-param name="content">
<encapsulation>ppp</encapsulation>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>Transient Change Generated with the <transient-change> Element
In this example, the complete XML hierarchy leading to the affected statement must be included as child elements of the <transient-change> element.
<xsl:for-each select="interfaces/interface[starts-with(name, 'so-')\
and unit/family/inet]">
<transient-change>
<interfaces>
<interface>
<name><xsl:value-of select="name"/></name>
<encapsulation>ppp</encapsulation>
</interface>
</interfaces>
</transient-change>
</xsl:for-each> - Save the script with a meaningful name.
- Copy the script to either the
/var/db/scripts/commitdirectory on the device hard drive or the/config/scripts/commitdirectory on the flash drive. For information about setting the storage location for commit scripts, see Storing Commit Scripts in Flash Memory.If the device has dual Routing Engines and you want the script to take effect on both of them, you must copy the script to the
/var/db/scripts/commitor the/config/scripts/commitdirectory on both Routing Engines. The commit synchronize command does not copy scripts between Routing Engines. - where filename is the name you assigned in Step 4.
Enable the script by including the file statement at the [edit system scripts commit] hierarchy level:
If the script makes transient changes, include the allow-transients statement at the [edit system scripts commit] hierarchy level:
[edit system scripts commit]allow-transients;
If all the commit scripts run without errors, any transient changes are loaded into the checkout configuration, but not to the candidate configuration. Any persistent changes are loaded into the candidate configuration. The commit process then continues by validating the configuration and propagating changes to the affected processes on the device.
To display the configuration with both persistent and transient changes applied, issue the show | display commit-scripts configuration mode command:
To display the configuration with only persistent changes applied, issue the show | display commit-scripts no-transients configuration mode command:
Persistent changes work like the load merge command in that they cause the Junos OS to merge the incoming configuration into the current candidate configuration. If the existing configuration and the persistent change contain conflicting statements, the statements in the persistent change override those in the existing configuration. Transient changes work like the load update command in that they cause the software to replace only the configuration that has changed.
Hide Navigation Pane
Show Navigation Pane
Download
SHA1