Example: Creating a Complex Configuration Based on a Simple Interface Configuration

This example uses a macro to automatically expand a simple interface configuration by generating a transient change that assigns a default encapsulation type, configures multiple routing protocols on the interface, and applies multiple configuration groups. The Junos OS management (mgd) process inspects the configuration, looking for apply-macro params statements included at the [edit interfaces interface-name] hierarchy level.

When the script finds an apply-macro params statement, it performs the following actions:

XSLT Syntax

<?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">
        <xsl:variable name="top" select="."/>
        <xsl:for-each select="interfaces/interface/apply-macro[name = 'params']">
            <xsl:variable name="description"
                    select="data[name = 'description']/value"/>
            <xsl:variable name="inet-address"
                    select="data[name = 'inet-address']/value"/>
            <xsl:variable name="encapsulation"
                    select="data[name = 'encapsulation']/value"/>
            <xsl:variable name="isis-level-1"
                    select="data[name = 'isis-level-1']/value"/>
            <xsl:variable name="isis-level-1-metric"
                    select="data[name = 'isis-level-1-metric']/value"/>
            <xsl:variable name="isis-level-2"
                    select="data[name = 'isis-level-2']/value"/>
            <xsl:variable name="isis-level-2-metric"
                    select="data[name = 'isis-level-2-metric']/value"/>
            <xsl:variable name="ifname" select="concat(../name, '.0')"/>
            <transient-change>
                <interfaces>
                    <interface>
                        <name><xsl:value-of select="../name"/></name>
                        <apply-groups>
                            <name>interface-details</name>
                        </apply-groups>
                        <xsl:if test="$description">
                            <description>
                                <xsl:value-of select="$description"/>
                            </description>
                        </xsl:if>
                        <encapsulation>
                            <xsl:choose>
                                <xsl:when test="string-length($encapsulation) &gt; 0">
                                    <xsl:value-of select="$encapsulation"/>
                                </xsl:when>
                                <xsl:otherwise>cisco-hdlc</xsl:otherwise>
                            </xsl:choose>
                        </encapsulation>
                        <unit>
                            <name>0</name>
                            <xsl:if test="string-length($inet-address) &gt; 0">
                                <family>
                                    <inet>
                                        <address>
                                            <xsl:value-of select="$inet-address"/>
                                        </address>
                                    </inet>
                                </family>
                            </xsl:if>
                        </unit>
                    </interface>
                </interfaces>
                <protocols>
                    <rsvp>
                        <interface>
                            <name><xsl:value-of select="$ifname"/></name>
                        </interface>
                    </rsvp>
                    <isis>
                        <interface>
                            <name><xsl:value-of select="$ifname"/></name>
                            <xsl:if test="$isis-level-1 or $isis-level-1-metric">
                                <level>
                                    <name>1</name>
                                    <xsl:if test="$isis-level-1">
                                        <xsl:element name="{$isis-level-1}"/>
                                    </xsl:if>
                                    <xsl:if test="$isis-level-1-metric">
                                        <metric>
                                            <xsl:value-of select="$isis-level-1-metric"/>
                                        </metric>
                                    </xsl:if>
                                </level>
                            </xsl:if>
                            <xsl:if test="$isis-level-2 or $isis-level-2-metric">
                                <level>
                                    <name>2</name>
                                    <xsl:if test="$isis-level-2">
                                        <xsl:element name="{$isis-level-2}"/>
                                    </xsl:if>
                                    <xsl:if test="$isis-level-2-metric">
                                        <metric>
                                            <xsl:value-of select="$isis-level-2-metric"/>
                                        </metric>
                                    </xsl:if>
                                </level>
                            </xsl:if>
                        </interface>
                    </isis>
                    <ldp>
                        <interface>
                            <name><xsl:value-of select="$ifname"/></name>
                        </interface>
                    </ldp>
                </protocols>
            </transient-change>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

SLAX Syntax

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 {
    var $top = .;
    for-each (interfaces/interface/apply-macro[name = 'params']) {
        var $description = data[name = 'description']/value;
        var $inet-address = data[name = 'inet-address']/value;
        var $encapsulation = data[name = 'encapsulation']/value;
        var $isis-level-1 = data[name = 'isis-level-1']/value;
        var $isis-level-1-metric = data[name = 'isis-level-1-metric']/value;
        var $isis-level-2 = data[name = 'isis-level-2']/value;
        var $isis-level-2-metric = data[name = 'isis-level-2-metric']/value;
        var $ifname = ../name _ '.0';
        <transient-change> {
            <interfaces> {
                <interface> {
                    <name> ../name;
                    <apply-groups> {
                        <name> "interface-details";
                    }
                    if ($description) {
                        <description> $description;
                    }
                    <encapsulation> {
                        if (string-length($encapsulation) > 0) {
                            expr $encapsulation;
                        } else {
                            expr "cisco-hdlc";
                        }
                    }
                    <unit> {
                        <name> "0";
                        if (string-length($inet-address) > 0) {
                            <family> {
                                <inet> {
                                    <address> $inet-address;
                                }
                            }
                        }
                    }
                }
            }
            <protocols> {
                <rsvp> {
                    <interface> {
                        <name> $ifname;
                    }
                }
                <isis> {
                    <interface> {
                        <name> $ifname;
                        if ($isis-level-1 or $isis-level-1-metric) {
                            <level> {
                                <name> "1";
                                if ($isis-level-1) {
                                    <xsl:element name="{$isis-level-1}">;
                                }
                                if ($isis-level-1-metric) {
                                    <metric> $isis-level-1-metric;
                                }
                            }
                        }
                        if ($isis-level-2 or $isis-level-2-metric) {
                            <level> {
                                <name> "2";
                                if ($isis-level-2) {
                                    <xsl:element name="{$isis-level-2}">;
                                }
                                if ($isis-level-2-metric) {
                                    <metric> $isis-level-2-metric;
                                }
                            }
                        }
                    }
                }
                <ldp> {
                    <interface> {
                        <name> $ifname;
                    }
                }
            }
        }
    }
}

Testing the ex-if-params Script

To test the ex-if-params script, perform the following steps:

  1. Copy the XSLT or SLAX script from Example: Creating a Complex Configuration Based on a Simple Interface Configuration into a text file, name the file ex-if-params.xsl or ex-if-params.slax as appropriate, and copy it to the /var/db/scripts/commit directory on the device.
  2. Select the following configuration stanzas, and press Ctrl+c to copy them to the clipboard. If you are using the SLAX version of the script, change the filename at the [edit system scripts commit file] hierarchy level to ex-if-params.slax.

    system {scripts {commit {allow-transients;file ex-if-params.xsl;}}}groups {interface-details {interfaces {<so-*/*/*> {clocking internal;}}}}interfaces {so-1/2/3 {apply-macro params {description "Link to Hoverville";encapsulation ppp;inet-address 10.1.2.3/28;isis-level-1 enable;isis-level-1-metric 50;isis-level-2-metric 85;}}}
  3. In configuration mode, issue the load merge terminal command to merge the stanzas into your device configuration:

    [edit]user@host# load merge terminal[Type ^D at a new line to end input]... Paste the contents of the clipboard here ...
    1. At the prompt, paste the contents of the clipboard using the mouse and the paste icon.
    2. Press Enter.
    3. Press Ctrl+d.
  4. Issue the commit command.

    [edit]
    user@host# commit

When you issue the show interfaces | display commit-scripts | display inheritance configuration mode command, the following output appears:

[edit]user@host# show interfaces | display commit-scripts | display inheritanceso-1/2/3 {apply-macro params {clocking internal;description "Link to Hoverville";encapsulation ppp;inet-address 10.1.2.3/28;isis-level-1 enable;isis-level-1-metric 50;isis-level-2-metric 85;}description "Link to Hoverville";#### 'internal' was inherited from group 'interface-details'##clocking internal;encapsulation ppp;unit 0 {family inet {address 10.1.2.3/28;}}}

When you issue the show protocols | display commit-scripts configuration mode command, the following output appears:

[edit]user@host# show protocols | display commit-scriptsrsvp {interface so-1/2/3.0;}isis {interface so-1/2/3.0 {level 1 {enable;metric 50;}level 2 metric 85;}}ldp {interface so-1/2/3.0;}