Importing the junos.xsl File

The import file junos.xsl contains several useful templates that you can call within commit scripts, op scripts, and event scripts. To use these templates, you must map to the jcs namespace in your style sheet declaration. You must also import the junos.xsl file. Both of these steps are shown in the following examples:

XSLT Syntax

<?xml version=”1.0”?>
<xsl:stylesheet version=”1.0”
             xmlns:jcs="http://xml.juniper.net/junos/commit-scripts/1.0">
    <xsl:import href="../import/junos.xsl"/>
    ...
</xsl: stylesheet>

SLAX Syntax

version 1.0;
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
import "../import/junos.xsl";

Templates in the junos.xsl File

Named templates in the junos.xsl file use the jcs: prefix to avoid conflicting with user-defined templates of the same name in a script. The templates in the jcs: namespace allow you to accomplish scripting tasks more easily. To use these templates in your scripts, you include <xsl:call-template name="name"> elements and pass in any required or optional parameters. The name attribute specifies the name of the called template.

The <xsl:template match="/"> template is an unnamed template in the junos.xsl file that allows you to use shortened XPath expressions in your scripts.

The templates are discussed in more detail in the following sections:

<jcs:edit-path> Template

The <jcs:edit-path> template generates an <edit-path> element suitable for inclusion in an <xnm:error> or <xnm:warning> element. The location of the configuration error is passed as dot into the <jcs:edit-path> template. This location defaults to “ .” , the current position in the XML hierarchy. You can alter the default by including the select attribute of the dot parameter. The following example demonstrates how to call this template in a commit script and set the context to the [edit chassis] hierarchy level:

The <jcs:edit> template generates an <edit-path> element suitable for inclusion in an <xnm:error> or <xnm:warning> element. The location of the configuration error is passed as dot into the <jcs:edit-path> template. This location defaults to “ .” , the current position in the XML hierarchy. You can alter the default by including the select attribute of the dot parameter. The following example demonstrates how to call this template in a commit script and set the context to the [edit chassis] hierarchy level:

<xsl:if test="not(chassis/source-route)">
    <xnm:warning>
        <xsl:call-template name="jcs:edit-path">
            <xsl:with-param name="dot" select="chassis"/>
        </xsl:call-template>
        <message>IP source-route processing is not enabled.</message>
    </xnm:warning>
</xsl:if>

When you commit a configuration that does not enable IP source routing, the <xnm:warning> element results in the following command-line interface (CLI) output:


user@host# commit
[edit chassis] # The hierarchy level is generated by the <jcs:edit-path> template.
    warning: IP source-route processing is not enabled.
commit complete

<jcs:emit-change> Template

The <jcs:emit-change> template generates a <change> element, which results in a persistent change to the configuration.

This template includes the following optional parameters:

The following example demonstrates how to call this template in a commit script:

<xsl:template match="configuration">
    <xsl:for-each select="interfaces/interface/unit[family/iso]">
        <xsl:if test="not(family/mpls)">
            <xsl:call-template name="jcs:emit-change">
                <xsl:with-param name="message">
                    <xsl:text>Adding 'family mpls' to ISO-enabled interface</xsl:text>
                </xsl:with-param>
                <xsl:with-param name="content">
                    <family>
                        <mpls/>
                    </family>
                </xsl:with-param>
            </xsl:call-template>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

When you commit a configuration that includes one or more interfaces that have IS-IS enabled but do not have the family mpls statement included at the [edit interfaces interface-name unit logical-unit-number] hierarchy level, the <jcs:emit-change> template adds the family mpls statement to the configuration and generates the following CLI output:

[edit]

user@host# commit
[edit interfaces interface so-1/2/3 unit 0]
    warning: Adding 'family mpls' to ISO-enabled interface
[edit interfaces interface so-1/2/3 unit 0]
    warning: Adding ISO-enabled interface so-1/2/3.0 to [protocols mpls]
[edit interfaces interface so-1/3/2 unit 0]
    warning: Adding 'family mpls' to ISO-enabled interface
[edit interfaces interface so-1/3/2 unit 0]
    warning: Adding ISO-enabled interface so-1/3/2.0 to [protocols mpls]
commit complete

The content parameter of the <jcs:emit-change> template provides a simpler method for specifying a change to the configuration. For example, consider the following code:

<xsl:with-param name="content">
    <family>
        <mpls/>
    </family>
</xsl:with-param>

The <jcs:emit-change> template converts the content parameter into a <change> request. The <change> request inserts the provided partial configuration content into the complete hierarchy of the current context node. Thus, the <jcs:emit-change> template changes the hierarchy information in the content parameter into the following code:

<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>

If a transient change is required, the tag parameter can be passed in as 'transient-change', as shown here:

<xsl:with-param name="tag" select="'transient-change'"/>

The extra quotation marks are required to allow XSLT to distinguish between the string "transient-change" and the contents of a node named "transient-change". If the change is relative to a node other than the context node, the parameter "dot" can be set to that node, as shown in the following example, where context is set to the [edit chassis] hierarchy level:

<xsl:for-each select="interfaces/interface/unit">
    ...
    <xsl:call-template name="jcs:emit-change">
        <xsl:with-param name="dot" select="chassis"/>
            ...

<jcs:emit-comment> Template

The <jcs:emit-comment> template emits a simple comment that indicates a change was made by a commit script. The template contains a <junos:comment> element. You never call the <jcs:emit-comment> template directly. Rather, you include its <junos:comment> element and the child element <xsl:text> inside a call to the <jcs:emit-change> template, a <change> element, or a <transient-change> element. The following example demonstrates how to call this template in a commit script:

<xsl:call-template name="jcs:emit-change">
    <xsl:with-param name="content">
        <term>
            <name>very-last</name>
            <junos:comment>
                <xsl:text>This term was added by a commit script</xsl:text>
            </junos:comment>
            <then>
                <accept/>
            </then>
        </term>
    </xsl:with-param>
</xsl:call-template>

When you issue the show firewall configuration mode command, the following output appears:

[edit]

user@host# show firewall
family inet {
    term very-last {
          /* This term was added by a commit script */
    then accept;
    }
}

<jcs:statement> Template

The <jcs:statement> template generates a <statement> element suitable for inclusion in an <xnm:error> or <xnm:warning> element. The parameter dot can be passed into the <jcs:statement> template if the error is not at the current position in the XML hierarchy. The following example demonstrates how to call this template in a commit script:

<xnm:error>
    <xsl:call-template name="jcs:edit-path"/>
    <xsl:call-template name="jcs:statement">
        <xsl:with-param name="dot" select="mtu"/>
    </xsl:call-template>
    <message>
        <xsl:text>SONET interfaces must have a minimum MTU of </xsl:text>
        <xsl:value-of select="$min-mtu"/>
        <xsl:text>.</xsl:text>
    </message>
</xnm:error>

When you commit a configuration that includes a SONET/SDH interface with a maximum transmission unit (MTU) setting less than a specified minimum, the <xnm:error> element results in the following CLI output:

[edit]

user@host# commit
[edit interfaces interface so-1/2/3]
    'mtu 576;'  # mtu statement generated by the <jcs:statement> template
    SONET interfaces must have a minimum MTU of 2048.
error: 1 error reported by commit scripts
error: commit script failure

The test of the MTU setting is not performed in the <xnm:error> element. For the full example, see Example: Imposing a Minimum MTU Setting.

<xsl:template match="/"> Template

The <xsl:template match="/"> template is an unnamed template in the junos.xsl file that allows you to use shortened XPath expressions in your scripts.

The JUNOS management process (mgd) generates the output document as the product of its evaluation of the input document, as shown in Figure 3.

Figure 3: Commit Script Input and Output

Image g017027.gif

Generally, an XSLT engine uses recursion to evaluate the entire input document. However, the <xsl:apply-templates> instruction allows you to limit the scope of the evaluation so that the management process (the JUNOS Software’s XSLT engine) must evaluate only a subset of the input document.

The <xsl:template match="/"> template is an unnamed template that uses the <xsl:apply-templates> instruction to specify the contents of the input document’s <configuration> element as the only node to be evaluated in the generation of the output document.

The <xsl:template match="/"> template contains the following tags:

1    <xsl:template match="/">
2        <commit-script-results>
3            <xsl:apply-templates select="commit-script-input/configuration"/>
4        </commit-script-results>
5    </xsl:template>

Line 1 matches the root node of the input document. When the management process sees the root node of the input document, this template is applied.

1    <xsl:template match="/">

Line 2 designates the root, top-level tag of the output document. Thus, Line 2 specifies that the evaluation of the input document results in an output document whose top-level tag is <commit-script-results>.

2        <commit-script-results>

Line 3 limits the scope of the evaluation of the input document to the contents of the <configuration> element, which is a child of the <commit-script-input> element.

3            <xsl:apply-templates select="commit-script-input/configuration"/>

Lines 4 and 5 are closing tags.

You do not need to explicitly include the <xsl:template match="/"> template in your scripts because this template is included in the import file junos.xsl.

When the <xsl:template match="/"> template executes the <xsl:apply-templates> instruction, the script jumps to a template that matches the <configuration> tag. This template, <xsl:template match="configuration">, is part of the commit script boilerplate that you must include in all of your commit scripts:

<xsl:template match="configuration">
    <!- - ... insert your code here ... - ->
</xsl:template>

Thus, the import file junos.xsl contains a template that points to a template explicitly referenced in your script.

The following example contains the <xsl:if> programming instruction and the <xnm:warning> element. The logical result of both templates is:

<commit-script-results>    <!- - from template in junos.xsl import file - ->
    <xsl:if test="not(system/host-name)"> <!- - from "configuration" template - ->
        <xnm:warning xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm">
            <edit-path>[edit system]</edit-path>
            <statement>host-name</statement>
            <message>Missing a hostname for this router.</message>
        </xnm:warning>
    </xsl:if>    <!- - end of "configuration" template - ->
</commit-script-results>    <!- - end of template in junos.xsl import file - ->

When you import the junos.xsl file and explicitly include the <xsl:template match="configuration"> tag in your commit script, the context (dot) moves to the <configuration> node. This allows you to write all XPath expressions relative to that point. This technique allows you to simplify the XPath expressions you use in your commit scripts. For example, instead of writing this, which matches the router with hostname atlanta:

<xsl:if test="starts-with(commit-script-input/configuration/system/host-name, 'atlanta')">

You can write this:

<xsl:if test="starts-with(system/host-name, 'atlanta')">