[Contents] [Prev] [Next] [Index] [Report an Error]

Example: Creating Custom Configuration Syntax with Macros

Figure 9 shows a macro that uses custom syntax and the corresponding expansion to standard JUNOS command-line interface (CLI) syntax.

Figure 9: Sample Macro and Corresponding JUNOS CLI Expansion

Image g017029.gif

In this example, the JUNOS management process (mgd) inspects the configuration, looking for apply-macro statements. For each apply-macro statement with the color parameter included at the [edit protocols mpls] hierarchy level, the script generates a transient change, using the data provided within the apply-macro statement to expand the macro into a standard JUNOS administrative group for LSPs.

For this example to work, an apply-macro statement must be included at the [edit protocols mpls] hierarchy level with a set of addresses, a color, and a group-value parameter. The commit script converts each address to an LSP configuration, and the script converts the color parameter into an administrative group.

Following are the commit script instructions that expand the macro in Figure 9 and a line-by-line explanation of the script:

XSLT Syntax

1    <?xml version="1.0" standalone="yes"?>
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="$mpls/apply-macro[data/name = 'color']">
11                <xsl:variable name="color" select="data[name = 'color']/value"/>
12                <xsl:for-each select="$mpls/apply-macro[data/name = 'group-value']">
13                    <xsl:variable name="group-value" select="data[name =                                 'group-value']/value"/>
14                    <transient-change>
15                        <protocols>
16                            <mpls>
17                                <admin-groups>
18                                    <name>
19                                        <xsl:value-of select="$color"/>
20                                    </name>
21                                    <group-value>
22                                        <xsl:value-of select="$group-value"/>
23                                    </group-value>
24                                </admin-groups>
25                                <xsl:for-each select="data[not(value)]/name">
26                                    <label-switched-path>
27                                        <name>
28                                            <xsl:value-of select="concat($color, '-lsp-', .)"/>
29                                        </name>
30                                        <to><xsl:value-of select="."/></to>
31                                        <admin-group>
32                                            <include-any>
33                                                <xsl:value-of select="$color"/>
34                                            </include-any>
35                                        </admin-group>
36                                    </label-switched-path>
37                                </xsl:for-each>
38                            </mpls>
39                        </protocols>
40                    </transient-change>
41                </xsl:for-each>
42            </xsl:for-each>
43        </xsl:template>
44    </xsl:stylesheet>

Lines 1 through 8 (and Lines 43 and 44) are the boilerplate that you include in every commit script.

1    <?xml version="1.0" standalone="yes"?>
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 assigns the [edit protocols mpls] hierarchy level to a variable called $mpls.

9    <xsl:variable name="mpls" select="protocols/mpls"/>

Line 10 selects every apply-macro statement at the [edit protocols mpls] hierarchy level that contains the color parameter. The sample configuration in Figure 9 contains only one apply-macro statement. Therefore, this <xsl:for-each> programming instruction takes effect only once.

10    <xsl:for-each select="$mpls/apply-macro[data/name = 'color']">

Line 11 assigns the value of the color parameter, in this case blue, to a variable called $color.

11<xsl:variable name="color" select="data[name = 'color']/value"/>

Line 12 selects every apply-macro statement at the [edit protocols mpls] hierarchy level that contains the color parameter. The sample configuration in Figure 9 contains only one apply-macro statement. Therefore, this <xsl:for-each> programming instruction takes effect only once.

12<xsl:for-each select="$mpls/apply-macro[data/name = 'color']">

Line 13 assigns the value of the group-value parameter, in this case 0, to a variable called $group-value.

13    <xsl:variable name="group-value" select="data[name = 'group-value']/value"/>

Lines 14 through 16 generate a transient change at the [edit protocols mpls] hierarchy level.

14    <transient-change>
15        <protocols>
16            <mpls>

Lines 17 through 24 add the admin-groups statement to the configuration and assign the value of the $color variable to the group name and the value of the $group-value variable to the group value.

17    <admin-groups>
18        <name>
19            <xsl:value-of select="$color"/>
20        </name>
21        <group-value>
22            <xsl:value-of select="$group-value"/>
23        </group-value>
24    </admin-groups>

The resulting configuration statements are as follows:

admin-groups {
    blue 0;
}

Line 25 selects the name of every parameter that does not already have a value assigned to it, which in this case are the four IP addresses. This <xsl:for-each> programming instruction uses recursion through the macro and selects each IP address in turn. The color and group-value parameters each already have a value assigned (blue and 0, respectively), so this line does not apply to them.

25<xsl:for-each select="data[not(value)]/name">

Line 26 adds the label-switched-path statement in the configuration.

26<label-switched-path>

Lines 27 through 29 assign the label-switched-path a name that concatenates the value of the $color variable, the text -lsp-, and the current IP address currently selected by Line 25 (represented by the “ .” ).

27    <name> 
28        <xsl:value-of select="concat($color, '-lsp-', .)"/>
29    </name>

Line 30 adds the to statement to the configuration and sets its value to the IP address currently selected by Line 25.

30<to><xsl:value-of select="."/></to>

Lines 31 through 35 add the admin-group include-any statement to the configuration and sets its value to the value of the $color variable.

31    <admin-group>
32        <include-any>
33            <xsl:value-of select="$color"/>
34        </include-any>
35    </admin-group>

The resulting configuration statements (for one pass) are as follows:

label-switched-path blue-lsp-10.1.1.1 {
to 10.1.1.1;
admin-group include-any blue;
}

Lines 36 through 42 are closing tags.

36                                    </label-switched-path>
37                                </xsl:for-each>
38                            </mpls>
39                        </protocols>
40                    </transient-change>
41                </xsl:for-each>
42            </xsl:for-each>

Lines 43 and 44 are closing tags for Lines 8 and 2, respectively.

43        </xsl:template>
44    </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 $mpls = protocols/mpls;

    for-each ($mpls/apply-macro[data/name = 'color']) {
        var $color = data[name = 'color']/value;

        for-each ($mpls/apply-macro[data/name = 'group-value']) {
            var $group-value = data[name='group-value']/value;
            <transient-change> {
                <protocols> {
                    <mpls> {
                        <admin-groups> {
                            <name> $color;
                            <group-value> $group-value;
                        }
                        for-each (data[not(value)]/name) {
                            <label-switched-path> {
                                <name> $color _ '-lsp-' _ .;
                                <to> .;
                                <admin-group> {
                                    <include-any> $color;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

For more information, see Configuring Administrative Groups for LSPs.


[Contents] [Prev] [Next] [Index] [Report an Error]