Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

Announcement: Try the Ask AI chatbot for answers to your technical questions about Juniper products and solutions.

close
header-navigation
keyboard_arrow_up
close
keyboard_arrow_left
Automation Scripting User Guide
Table of Contents Expand all
list Table of Contents
file_download PDF
{ "lLangCode": "en", "lName": "English", "lCountryCode": "us", "transcode": "en_US" }
English
keyboard_arrow_right

Example: Generate Persistent and Transient Configuration Changes Using Commit Scripts

date_range 16-Feb-24

Example: Generating a Persistent Change

Junos OS commit scripts enable users to customize the validation process of their configurations in accordance with their own practices and policies and enforce custom configuration rules during the commit process. This example demonstrates a commit script that generates a persistent change that adds the family mpls statement in the configuration of SONET/SDH interfaces when the statement is not already included in the configuration. If you do not explicitly configure the MPLS protocol family on an interface, the interface is not enabled for MPLS applications.

Requirements

This example uses the following hardware and software components:

  • Device running Junos OS with one or more SONET/SDH interfaces.

  • Junos OS Release 16.1R3 or later release when using a Python script.

Overview and Commit Script

The commit script in this example finds all SONET/SDH interfaces that have a logical interface configured but that do not have the family mpls statement configured. For these interfaces, the script adds the family mpls statement to the interface configuration as a persistent change at the [edit interfaces interface-name unit logical-unit-number] hierarchy level. The script is shown in SLAX, XSLT, and Python.

The SLAX and XSLT versions of the commit script generate the persistent change by using the jcs:emit-change template, which is a helper template contained in the junos.xsl import file. The tag parameter of the jcs:emit-change template is omitted, which directs the script to emit the change as a persistent change. The content parameter of the jcs:emit-change template includes the configuration statements to add as a persistent change. The message parameter of the jcs:emit-change template includes the warning message to be displayed in the CLI, notifying you that the configuration has been changed.

The Python version of the commit script generates the persistent change by using the jcs.emit_change() function, which is imported from the jcs module. The Python script indicates that this is a persistent change by passing in the positional argument 'change'.

XSLT Syntax

content_copy zoom_out_map
<?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:for-each select="interfaces/interface[starts-with(name, 'so-')]/unit">
            <xsl:if test="not(family/mpls)">
                <xsl:call-template name="jcs:emit-change">
                    <xsl:with-param name="message">
                        <xsl:text>Adding 'family mpls' to SONET/SDH 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>
</xsl:stylesheet>

SLAX Syntax

content_copy zoom_out_map
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 {
    for-each (interfaces/interface[starts-with(name, 'so-')]/unit) {
        if (not(family/mpls)) {
            call jcs:emit-change() {
                with $message = {
                    expr "Adding 'family mpls' to SONET/SDH interface.";
                }
                with $content = {
                    <family> {
                        <mpls>;
                    }
                }
            }
        }
    }
}

Python Syntax

content_copy zoom_out_map
from junos import Junos_Configuration
import jcs

def main():
    # Get configuration root object
    root = Junos_Configuration

    for element in root.xpath("./interfaces/ \
        interface[starts-with(name,'so-')]/unit"):
        if element.find('family/mpls') is None:
            if_name = element.find('../name').text
            unit_name = element.find('name').text
            change_xml = """
            <interfaces>
               <interface>
                  <name>{0}</name>
                  <unit>
                     <name>{1}</name>
                     <family>
                        <mpls>
                        </mpls>
                     </family>
                  </unit>
               </interface>
            </interfaces>
            """.format(if_name, unit_name).strip()
            jcs.emit_change(change_xml, "change", "xml")
            jcs.emit_warning("Adding 'family mpls' to SONET/SDH interface: " + if_name)

if __name__ == '__main__':
    main()

Configuration

Procedure

Step-by-Step Procedure

To download, enable, and test the script.

  1. Copy the script into a text file, name the file mpls.xsl, mpls.slax, or mpls.py as appropriate, and copy it to the /var/db/scripts/commit/ directory on the device.

    Note:

    Unsigned Python scripts must be owned by either root or a user in the Junos OS super-user login class, and only the file owner can have write permission for the file.

  2. In configuration mode, configure the file statement and the script filename at the [edit system scripts commit] hierarchy level.

    content_copy zoom_out_map
    [edit]
    user@host# set system scripts commit file mpls.xsl
    
  3. If the script is written in Python, enable the execution of unsigned Python scripts.

    content_copy zoom_out_map
    [edit]
    user@host# set system scripts language python
    
    Note:

    Configure the language python3 statement to use Python 3 to execute Python scripts, or configure the language python statement to use Python 2.7 to execute Python scripts. For more information, see language.

  4. To test that the commit script generates the persistent change correctly, make sure that the configuration contains the condition that elicits the change. To test this script, ensure that the family mpls statement is not included at the [edit interfaces so-fpc/pic/port unit logical-unit-number] hierarchy level for at least one SONET/SDH interface.

  5. Issue the commit check command to preview a trace of commit script processing to verify that the script will add the persistent change to the candidate configuration. The commit check command verifies the syntax of the configuration prior to a commit, but it does not commit the changes.

    The commit script in this example produces a message for each change it makes. Use the commit check command to preview these messages to determine whether the script will update the configuration with the family mpls statement for the appropriate interfaces.

    Issue the commit check | display xml command to display the XML-formatted version of the message. The sample output indicates that the script will add the family mpls statement to the so-2/3/4.0 interface configuration during the commit operation.

    content_copy zoom_out_map
    [edit]
    user@host# commit check | display xml
    <rpc-reply xmlns:junos="http://xml.juniper.net/junos/11.2R1/junos">
        <commit-results>
            <routing-engine junos:style="normal">
                <name>re0</name>
                <xnm:warning xmlns:xnm="http://xml.juniper.net/xnm/1.1/xnm">
                    <edit-path>
                        [edit interfaces interface so-2/3/4 unit 0]
                    </edit-path>
                    <message>
                        Adding 'family mpls' to SONET/SDH interface.
                    </message>
                </xnm:warning>
                <commit-check-success/>
            </routing-engine>
        </commit-results>
    </rpc-reply>
  6. To display a detailed trace of commit script processing, issue the commit check | display detail command. In the sample output, there is one persistent change that will be loaded into the configuration during the commit operation.

    content_copy zoom_out_map
    [edit]
    user@host# commit check | display detail
    2011-06-17 14:17:35 PDT: reading commit script configuration
    2011-06-17 14:17:35 PDT: testing commit script configuration
    2011-06-17 14:17:35 PDT: opening commit script '/var/db/scripts/commit/mpls.xsl'
    2011-06-17 14:17:35 PDT: reading commit script 'mpls.xsl'
    2011-06-17 14:17:35 PDT: running commit script 'mpls.xsl'
    2011-06-17 14:17:35 PDT: processing commit script 'mpls.xsl'
    2011-06-17 14:17:35 PDT: no errors from mpls.xsl
    2011-06-17 14:17:35 PDT: saving commit script changes for script mpls.xsl
    2011-06-17 14:17:35 PDT: summary of script mpls.xsl: changes 1, transients 0, syslog 0
    2011-06-17 14:17:35 PDT: start loading commit script changes
    2011-06-17 14:17:35 PDT: loading commit script changes into real db
    2011-06-17 14:17:35 PDT: finished commit script changes into real db
    2011-06-17 14:17:35 PDT: no transient commit script changes
    2011-06-17 14:17:35 PDT: finished loading commit script changes
    2011-06-17 14:17:35 PDT: copying juniper.db to juniper.data+
    2011-06-17 14:17:35 PDT: finished copying juniper.db to juniper.data+
    ...
    configuration check succeeds
  7. After verifying that the script produces the correct changes, issue the commit command to start the commit operation and execute the script.

    content_copy zoom_out_map
    user@host# commit
    

Verification

Verifying the Configuration

Purpose

Verify that the correct changes are integrated into the configuration.

Action

After executing the commit operation, view the configuration by issuing the show interfaces configuration mode command. If the MPLS protocol family is not enabled on one or more SONET/SDH interfaces before the script runs, the output is similar to the following:

content_copy zoom_out_map
[edit]
user@host# show interfaces
... other configured interface types ...
so-2/3/4 {
    unit 0 {
        family mpls; # Added by persistent change
    }
}
... other configured interface types ...

Example: Generating a Transient Change

This example uses a commit script to set PPP encapsulation on all SONET/SDH interfaces with the IPv4 protocol family enabled. The changes are added as transient changes.

Requirements

This example uses the following hardware and software components:

  • Device running Junos OS with one or more SONET/SDH interfaces.

  • Junos OS Release 16.1R3 or later release when using a Python script.

Overview and Commit Script

The commit script in this example finds all SONET/SDH interfaces with the IPv4 protocol family enabled in the configuration and adds the encapsulation ppp statement to the interface configuration. The commit script generates a transient change, which adds the change to the checkout configuration but not the candidate configuration. The script is shown in SLAX, XSLT, and Python.

The SLAX and XSLT versions of the commit script generate the transient change by using the jcs:emit-change template, which is a helper template contained in the junos.xsl import file. The tag parameter of the jcs:emit-change template has the value transient-change, which directs the script to emit the change as a transient change rather than a persistent change. The content parameter of the jcs:emit-change template includes the configuration statements to be added as a transient change.

The Python version of the commit script generates the transient change by using the jcs.emit_change() function, which is imported from the jcs module. The Python script indicates that this is a transient change by passing in the positional argument 'transient-change'.

XSLT Syntax

content_copy zoom_out_map
<?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:for-each select="interfaces/interface[starts-with(name, 'so-')
                          and unit/family/inet]">
            <xsl:call-template name="jcs:emit-change">
                <xsl:with-param name="tag" select="'transient-change'"/>
                <xsl:with-param name="content">
                    <encapsulation>ppp</encapsulation>
                </xsl:with-param>
            </xsl:call-template>
        </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet>

SLAX Syntax

content_copy zoom_out_map
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 {
    for-each (interfaces/interface[starts-with(name, 'so-') and unit/family/inet]) {
        call jcs:emit-change($tag = 'transient-change') {
            with $content = {
                <encapsulation> "ppp";
            }
        }
    }
}

Python Syntax

content_copy zoom_out_map
from junos import Junos_Configuration
import jcs

def main():
    # Get configuration root object
    root = Junos_Configuration

    for element in root.xpath("./interfaces/ \
        interface[starts-with(name,'so-') and unit/family/inet]"):
        if_name = element.find('name').text
        change_xml = """
        <interfaces>
           <interface>
              <name>{0}</name>
              <encapsulation>ppp</encapsulation>
           </interface>
        </interfaces>
        """.format(if_name).strip()
        jcs.emit_change(change_xml, "transient-change", "xml")
        jcs.emit_warning("Adding 'ppp' encapsulation to SONET interface: " + if_name)
        jcs.emit_warning(change_xml)

if __name__ == '__main__':
    main()

Configuration

Procedure

Step-by-Step Procedure

To download, enable, and test the script.

  1. Copy the script into a text file, name the file encap-ppp.xsl, encap-ppp.slax, or encap-ppp.py as appropriate, and copy it to the /var/db/scripts/commit/ directory on the device.

    Note:

    Unsigned Python scripts must be owned by either root or a user in the Junos OS super-user login class, and only the file owner can have write permission for the file.

  2. In configuration mode, configure the file statement and the script filename at the [edit system scripts commit] hierarchy level.

    content_copy zoom_out_map
    [edit]
    user@host# set system scripts commit file encap-ppp.xsl
    
  3. Configure the allow-transients statement to enable commit scripts to load transient changes into the checkout configuration.

    content_copy zoom_out_map
    [edit]
    user@host# set system scripts commit allow-transients
    
  4. If the script is written in Python, enable the execution of unsigned Python scripts.

    content_copy zoom_out_map
    [edit]
    user@host# set system scripts language python3
    
    Note:

    Configure the language python3 statement to use Python 3 to execute Python scripts, or configure the language python statement to use Python 2.7 to execute Python scripts. For more information, see language.

  5. To test that the commit script generates the transient change correctly, make sure that the configuration contains the condition that elicits the change. Ensure that the encapsulation ppp statement is not included at the [edit interfaces so-fpc/pic/port] hierarchy level for at least one SONET/SDH interface.

  6. Issue the commit check command to preview a trace of commit script processing to verify that the script will add the transient change to the checkout configuration. The commit check command verifies the syntax of the configuration prior to a commit, but it does not commit the changes.

    Issue the commit check | display detail command to display a detailed trace of commit script processing. In the sample output, there are two transient changes that are loaded into the checkout configuration.

    content_copy zoom_out_map
    [edit]
    user@host# commit check | display detail
    2011-06-15 12:07:30 PDT: reading commit script configuration
    2011-06-15 12:07:30 PDT: testing commit script configuration
    2011-06-15 12:07:30 PDT: opening commit script '/var/db/scripts/commit/encap-ppp.xsl'
    2011-06-15 12:07:30 PDT: reading commit script 'encap-ppp.xsl'
    2011-06-15 12:07:30 PDT: running commit script 'encap-ppp.xsl'
    2011-06-15 12:07:30 PDT: processing commit script 'encap-ppp.xsl'
    2011-06-15 12:07:30 PDT: no errors from encap-ppp.xsl
    2011-06-15 12:07:30 PDT: saving commit script changes for script encap-ppp.xsl
    2011-06-15 12:07:30 PDT: summary of script encap-ppp.xsl: changes 0, transients 2 (allowed), syslog 0
    2011-06-15 12:07:30 PDT: start loading commit script changes
    2011-06-15 12:07:30 PDT: no commit script changes
    2011-06-15 12:07:30 PDT: updating transient changes into transient tree
    2011-06-15 12:07:30 PDT: finished loading commit script changes
    2011-06-15 12:07:30 PDT: copying juniper.db to juniper.data+
    2011-06-15 12:07:30 PDT: finished copying juniper.db to juniper.data+
    2011-06-15 12:07:30 PDT: exporting juniper.conf
    2011-06-15 12:07:30 PDT: merging transient changes
    ...
    configuration check succeeds
  7. After verifying that the script produces the correct changes, issue the commit command to start the commit operation and execute the script.

    content_copy zoom_out_map
    user@host# commit
    

Verification

Verifying the Configuration

Purpose

Verify that the correct changes are integrated into the checkout configuration. If there are one or more SONET/SDH interfaces with the IPv4 protocol family enabled, you should see the encapsulation ppp statement added as a transient change to the interface hierarchy.

Action

To view the configuration with transient changes, issue the show interfaces | display commit-scripts configuration mode command. The show interfaces | display commit-scripts command displays all the statements that are in the configuration, including statements that are generated by transient changes. If there are one or more SONET/SDH interfaces with the IPv4 protocol family enabled, the output is similar to the following:

content_copy zoom_out_map
[edit]
user@host# show interfaces | display commit-scripts
... 
so-1/2/3 {
    mtu 576;
    encapsulation ppp; /* Added by transient change. */
    unit 0 {
        family inet {
            address 10.0.0.3/32;
        }
    }
}
so-1/2/4 {
    encapsulation ppp; /* Added by transient change. */
    unit 0 {
        family inet {
            address 10.0.0.4/32;
        }
    }
}
so-2/3/4 {
    encapsulation cisco-hdlc; # Not affected by the script, because IPv4 protocol
                              # family is not configured on this interface.
    unit 0 {
        family mpls;
    }
}

Troubleshooting

Troubleshooting Commit Errors

Problem

The CLI generates an invalid transient change error, and the commit fails.

content_copy zoom_out_map
user@host# commit check
error: invalid transient change generated by commit script: encap-ppp.xsl
warning: 1 transient change was generated without [system scripts commit allow-transients]
error: 1 error reported by commit scripts
error: commit script failure
Solution

You must configure the allow-transients statement at the [edit system scripts commit] hierarchy level to enable commit scripts to load transient changes into the checkout configuration.

Configure the following statement to allow transient changes:

content_copy zoom_out_map
[edit]
user@host# set system scripts commit allow-transients
footer-navigation