The following examples illustrate how commit scripts work. Each example is followed by a line-by-line explanation.
First Example
The following script applies a transient change to each interface whose name begins with so-, setting the encapsulation to ppp. (For a SLAX version of this example, see SLAX Syntax.)
1 <?xml version="1.0"?>
2 <xsl:stylesheet version="1.0"
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4 xmlns:junos="http://xml.juniper.net/junos/*/junos"
5 xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm"
6 xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0">
7 <xsl:import href="../import/junos.xsl"/>
8 <xsl:template match="configuration">
9 <xsl:for-each select="interfaces/interface[starts-with(name, 'so-')
and unit/family/inet]">
10 <transient-change>
11 <interfaces>
12 <interface>
13 <name><xsl:value-of select="name"/></name>
14 <encapsulation>ppp</encapsulation>
15 </interface>
16 </interfaces>
17 </transient-change>
18 </xsl:for-each>
19 </xsl:template>
20 </xsl:stylesheet>
Explanation of First Example
Following is an explanation of each line in the script.
Lines 1 through 8 are the commit script boilerplate. They are explained in Boilerplate for Commit Scripts.
1 <?xml version="1.0"?>
2 <xsl:stylesheet version="1.0"
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4 xmlns:junos="http://xml.juniper.net/junos/*/junos"
5 xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm"
6 xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0">
7 <xsl:import href="../import/junos.xsl"/>
8 <xsl:template match="configuration">
Line 9 is an <xsl:for-each> programming instruction that examines each interface node whose names starts with so- and that has family inet enabled on any unit.
9 <xsl:for-each select="interfaces/interface[starts-with(name, 'so-')
and unit/family/inet]">
Line 10 is the open tag for a transient change. The possible contents of the <transient-change> element are the same as the contents of the <configuration> tag element in the JUNOScript <load-configuration> operation.
10 <transient-change>
Lines 11 through 16 represent the content of the transient change. The encapsulation is set to ppp.
11 <interfaces>
12 <interface>
13 <name><xsl:value-of select="name"/></name>
14 <encapsulation>ppp</encapsulation>
15 </interface>
16 </interfaces>
Lines 17 through 19 close all open tags in this template.
17 </transient-change>
18 </xsl:for-each>
19 </xsl:template>
Line 20 closes the style sheet and the commit script.
- 20</xsl:stylesheet>
Second Example
The following sample script finds interfaces that have an International Organization for Standardization (ISO) protocol enabled, and ensures that these interfaces also have Multiprotocol Label Switching (MPLS) enabled and are included at the [edit protocols mpls interface] hierarchy level. (For a SLAX version of this example, see SLAX Syntax.)
1 <?xml version="1.0"?>
2 <xsl:stylesheet version="1.0"
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
4 xmlns:junos="http://xml.juniper.net/junos/*/junos"
5 xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm"
6 xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0">
7 <xsl:import href="../import/junos.xsl"/>
8 <xsl:template match="configuration">
9 <xsl:variable name="mpls" select="protocols/mpls"/>
10 <xsl:for-each select="interfaces/interface/unit[family/iso]">
11 <xsl:variable name="ifname" select="concat(../name, '.', name)"/>
12 <xsl:if test="not(family/mpls)">
13 <xsl:call-template name="jcs:emit-change">
14 <xsl:with-param name="message">
15 <xsl:text>
16 Adding 'family mpls' to ISO-enabled interface
17 </xsl:text>
18 </xsl:with-param>
19 <xsl:with-param name="content">
20 <family>
21 <mpls/>
22 </family>
231 </xsl:with-param>
24 </xsl:call-template>
25 </xsl:if>
26 <xsl:if test="$mpls and not($mpls/interface[name = $ifname])">
27 <xsl:call-template name="jcs:emit-change">
28 <xsl:with-param name="message">
29 <xsl:text>Adding ISO-enabled interface </xsl:text>
30 <xsl:value-of select="$ifname"/>
31 <xsl:text> to [protocols mpls]</xsl:text>
32 </xsl:with-param>
33 <xsl:with-param name="dot" select="$mpls"/>
34 <xsl:with-param name="content">
35 <interface>
36 <name>
37 <xsl:value-of select="$ifname"/>
38 </name>
39 </interface>
40 </xsl:with-param>
41 </xsl:call-template>
42 </xsl:if>
43 </xsl:for-each>
44 </xsl:template>
45 </xsl:stylesheet>
Explanation of Second Example
Following is an explanation of each line in the script. For brevity, Lines 1 through 7 of the template boilerplate are omitted.
Line 8 opens the template and is explained in Boilerplate for Commit Scripts.
- 8 <xsl:template match="configuration">
Line 9 saves a reference to the [edit protocols mpls] hierarchy level so that it can be referenced in the following for-each loop.
9 <xsl:variable name="mpls" select="protocols/mpls"/>
Line 10 examines each interface unit (logical interface) on which ISO is enabled. The select stops at the unit, but the predicate limits the selection to only those units that contain an <iso> element nested under a <family> element.
10 <xsl:for-each select="interfaces/interface/unit[family/iso]">
Line 11 builds the interface name in a variable. First, the name attribute of the variable declaration is set to ifname. In the JUNOS software, an interface name is the concatenation of the device name, a period, and the unit number. At this point in the script, the context node is the unit number, because Line 10 changes the context to interfaces/interface/unit. The ../name refers to the <name> element of the parent node of the context node, which is the device name (type-fpc/pic/port). The "name" token in the XPath expression refers to the <name> element of the context node, which is the unit number (unit-number). After the concatenation is performed, the XPath expression in Line 11 resolves to type-fpc/pic/port.unit-number. As the <xsl:for-each> instruction in Line 10 traverses the hierarchy and locates ISO-enabled interfaces, the interface names are recursively stored in the ifname variable.
11 <xsl:variable name="ifname" select="concat(../name, '.', name)"/>
Line 12 evaluates as true for each ISO-enabled interface that does not have MPLS enabled.
12 <xsl:if test="not(family/mpls)">
Line 13 calls the <jcs:emit-change> template, which is a helper or convenience template in the junos.xsl file discussed in Importing the junos.xsl File.
13 <xsl:call-template name="jcs:emit-change">
Lines 14 through 18 use the message parameter from the <jcs:emit-change> template. The message parameter is a shortcut you can use instead of explicitly including the <warning>, <edit-path>, and <statement> elements.
14 <xsl:with-param name="message">
15 <xsl:text>
16 Adding 'family mpls' to ISO-enabled interface
17 </xsl:text>
18 </xsl:with-param>
Lines 19 through 23 use the content parameter from the <jcs:emit-change> template. The content parameter specifies the change to make, relative to the current context node.
19 <xsl:with-param name="content">
20 <family>
21 <mpls/>
22 </family>
23 </xsl:with-param>
Lines 24 and 25 close the tags opened in Lines 13 and 12, respectively.
24 </xsl:call-template>
25 </xsl:if>
Line 26 tests whether MPLS is already enabled and if this interface is not configured at the [edit protocols mpls interface] hierarchy level.
26 <xsl:if test="$mpls and not($mpls/interface[name = $ifname])">
Lines 27 through 41 contain another invocation of the <jcs:emit-change> template. In this invocation, the interface is added at the [edit protocols mpls interface] hierarchy level.
27 <xsl:call-template name="jcs:emit-change">
28 <xsl:with-param name="message">
29 <xsl:text>Adding ISO-enabled interface </xsl:text>
30 <xsl:value-of select="$ifname"/>
31 <xsl:text> to [edit protocols mpls]</xsl:text>
32 </xsl:with-param>
33 <xsl:with-param name="dot" select="$mpls"/>
34 <xsl:with-param name="content">
35 <interface>
36 <name>
37 <xsl:value-of select="$ifname"/>
38 </name>
39 </interface>
40 </xsl:with-param>
41 </xsl:call-template>
Lines 42 through 45 close all open elements.
42 </xsl:if>
43 </xsl:for-each>
44 </xsl:template>
45 </xsl:stylesheet>