Example: Requiring and Restricting Configuration Statements

This example shows you how to use commit scripts to specify required and prohibited configuration statements.

This commit script ensures that the Ethernet management interface (fxp0) is configured and detects when the interface is improperly disabled. The script also detects when the bgp statement is not included at the [edit protocols] hierarchy level. In all cases, the script emits an error message and the commit operation fails.

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:call-template name="error-if-missing">
            <xsl:with-param name="must"
                          select="interfaces/interface[name='fxp0']/
                          unit[name='0']/family/inet/address"/>
            <xsl:with-param name="statement"
                          select="'interfaces fxp0 unit 0 family inet address'"/>
        </xsl:call-template>
        <xsl:call-template name="error-if-present">
            <xsl:with-param name="must"
                          select="interfaces/interface[name='fxp0']/disable
                          | interfaces/interface[name='fxp0']/
                          unit[name='0']/disable"/>
            <xsl:with-param name="message">
                <xsl:text>The fxp0 interface is disabled.</xsl:text>
            </xsl:with-param>
        </xsl:call-template>
        <xsl:call-template name="error-if-missing">
            <xsl:with-param name="must" select="protocols/bgp"/>
            <xsl:with-param name="statement" select="'protocols bgp'"/>
        </xsl:call-template>
    </xsl:template>
    <xsl:template name="error-if-missing">
        <xsl:param name="must"/>
        <xsl:param name="statement" select="'unknown'"/>
        <xsl:param name="message"
                          select="'missing mandatory configuration statement'"/>
        <xsl:if test="not($must)">
            <xnm:error>
                <edit-path><xsl:copy-of select="$statement"/></edit-path>
                <message><xsl:copy-of select="$message"/></message>
            </xnm:error>
        </xsl:if>
    </xsl:template>
    <xsl:template name="error-if-present">
        <xsl:param name="must" select="1"/> <!-- give error if param missing -->
        <xsl:param name="message" select="'invalid configuration statement'"/>
        <xsl:for-each select="$must">
            <xnm:error>
                <xsl:call-template name="jcs:edit-path"/>
                <xsl:call-template name="jcs:statement"/>
                <message><xsl:copy-of select="$message"/></message>
            </xnm:error>
        </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 {
    call error-if-missing($must =
               interfaces/interface[name='fxp0']/unit[name='0']/family/inet/address,
               $statement = 'interfaces fxp0 unit 0 family inet address');
    call error-if-present($must = interfaces/interface[name='fxp0']/disable |
               interfaces/interface[name='fxp0']/unit[name='0']/disable) {
        with $message = {
            expr "The fxp0 interface is disabled.";
        }
    }
    call error-if-missing($must = protocols/bgp, $statement = 'protocols bgp');
}
error-if-missing ($must, $statement = 'unknown', $message =
               'missing mandatory configuration statement') {
    if (not($must)) {
        <xnm:error> {
            <edit-path> {
                copy-of $statement;
            }
            <message> {
                copy-of $message;
            }
        }
    }
}
error-if-present ($must = 1, $message = 'invalid configuration statement') {
    for-each ($must) {
        <xnm:error> {
            call jcs:edit-path();
            call jcs:statement();
            <message> {
                copy-of $message;
            }
        }
    }
}

Testing the ex-no-nukes Script

To test the ex-no-nukes script, perform the following steps:

  1. Copy the XSLT or SLAX script from Example: Requiring and Restricting Configuration Statements into a text file, name the file ex-no-nukes.xsl or ex-no-nukes.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-no-nukes.slax.

    system {scripts {commit {file ex-no-nukes.xsl;}}}interfaces {fxp0 {disable;unit 0 {family inet {address 10.0.0.1/24;}}}}
  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. The following output appears:

    [edit]
    user@host# commit
    [edit interfaces interface fxp0 disable]
        'disable;'
        The fxp0 interface is disabled.
    protocols bgp
        missing mandatory configuration statement
    error: 2 errors reported by commit scripts
    error: commit script failure