Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

 
 

Create Action Scripts for YANG RPCs on Junos Devices

You can add YANG data models that define custom remote procedure calls (RPCs) on supported Junos devices. When you add a nonnative YANG RPC to a device, you must also supply an action script that serves as the RPC’s handler. The RPC definition references the action script, which is invoked when the RPC is executed. The action script performs the operations and retrieves the information required by the RPC and returns any necessary XML output elements as defined in the RPC output statement.

Action scripts can be written in Stylesheet Language Alternative SyntaX (SLAX) or Python. SLAX action scripts are similar to SLAX op scripts and can perform any function available through the RPCs supported by the Junos XML management protocol and the Junos XML API. Python action scripts can leverage all of the features and constructs in the Python language, which provides increased flexibility over SLAX scripts. In addition, Python action scripts support Junos PyEZ APIs, which facilitate executing RPCs and performing operational and configuration tasks on Junos devices. Python scripts can also leverage the lxml library, which simplifies XPath handling. Also, starting in Junos OS Release 19.3R1, devices running Junos OS with Upgraded FreeBSD support using IPv6 in Python action scripts.

This topic discusses how to create an action script, including how to parse the RPC input arguments, access operational and configuration data in the script, emit the XML output, and validate and load the script on a device.

Action Script Boilerplate

SLAX Script Boilerplate

SLAX action scripts must include the necessary boilerplate for both basic script functionality as well as any optional functionality used within the script such as the Junos OS extension functions and named templates. In addition, the script must declare all RPC input parameters using the param statement. The SLAX action script boilerplate is as follows:

Python Script Boilerplate

Python action scripts must include an interpreter directive line that specifies the Python version used to execute the script. Table 1 outlines the interpreter directive lines you can use in the different releases.

Table 1: Python Action Script Interpreter Directive Lines
Python Version Interpreter Directive Lines Supported Releases

Python 3

#!/usr/bin/python3
or
#!/usr/bin/env python3

Junos OS Release 20.2R1 and later

Junos OS Evolved Release 21.1R1 and later

Python 2.7

#!/usr/bin/python
or
#!/usr/bin/env python

Junos OS Release 20.1 and earlier

Junos OS Evolved Release 22.2 and earlier

Note:

Starting in Junos OS Release 20.2R1 and Junos OS Evolved Release 22.3R1, the device uses Python 3 to execute YANG action and translation scripts. In earlier releases, Junos OS only uses Python 2.7 to execute these scripts, and Junos OS Evolved uses Python 2.7 by default to execute the scripts.

In addition, Python action scripts should import any libraries, modules, or objects that are used in the script. For example, in addition to standard Python libraries, Python action scripts might import the following:

  • jcs library—Enables the script to use Junos OS extension functions and Junos OS named template functionality in the script.

  • jnpr.junos module and classes—Enables the script to use Junos PyEZ.

  • lxml library—Simplifies XPath handling.

For example:

Parsing RPC Input Arguments

Input Argument Overview

An RPC can define input parameters using the optional input statement. When you execute an RPC and provide input arguments, Junos OS invokes the RPC’s action script and passes those arguments to the script. In a Python or SLAX action script, you can access the RPC input arguments in the same manner as you would access command-line arguments for a normal Python script or a Junos OS SLAX op script, respectively.

Consider the following input statement for the get-host-status RPC:

The RPC can be executed in the CLI or through a NETCONF or Junos XML protocol session. For example, you might execute the following command in the CLI:

Similarly, you might execute the following RPC in a remote session:

When you execute the command or RPC, the device invokes the action script and passes in the arguments. The following sections discuss how to process the arguments in the SLAX or Python action script.

Note:

Starting in Junos OS Release 19.2R1, custom YANG RPCs support input parameters of type empty when executing the RPC’s command in the Junos OS CLI, and the value passed to the action script is the parameter name. In earlier releases, input parameters of type empty are only supported when executing the RPC in a NETCONF or Junos XML protocol session, and the value passed to the action script is the string 'none'.

SLAX Script Input Arguments

In SLAX action scripts, you must declare input parameters using the param statement. The parameter names must be identical to the parameter names defined in the YANG module.

When invoked, the script assigns the value for each argument to the corresponding parameter, which you can then reference throughout the script. You must include the dollar sign ($) symbol both when you declare the parameter and when you access its value. If a parameter is type empty, the parameter name is passed in as its value.

Note:

For more information about SLAX parameters, see SLAX Parameters Overview in the Automation Scripting User Guide.

Python Script Input Arguments

For Python action scripts, the arguments are passed to the script as follows:

  • The first argument is always the action script's file path.

  • The next arguments in the list are the name and value for each input parameter supplied by the user.

    The argument name is passed in as follows:

    • In Junos OS Release 21.1 and earlier, the device passes in the name of the argument.

    • In Junos OS Release 21.2R1 and later, the device prefixes a single hyphen (-) to single-character argument names and prefixes two hyphens (--) to multi-character argument names.

    Note:

    When you execute the RPC’s command in the CLI, the arguments are passed to the script in the order given on the command line. In a NETCONF or Junos XML protocol session, the order of arguments in the XML is arbitrary, so the arguments are passed to the script in the order that they are declared in the RPC input statement.

  • The last two arguments in the list, which are supplied by the system and not the user, are 'rpc_name' and the name of the RPC.

The following sections discuss how to handle the arguments that are passed to Python action scripts in the different releases.

Python Action Scripts (21.2R1 or later)

Starting in Junos OS Release 21.2R1 and Junos OS Evolved Release 21.2R1, when the device passes the input argument names to the Python action script, it prefixes a single hyphen (-) to single-character argument names and prefixes two hyphens (--) to multi-character argument names. This enables you to use standard command-line parsing libraries to handle the arguments.

For the previous YANG RPC example, the action script's sys.argv input argument list is:

The following sample Python code uses the argparse library to handle the arguments. In this case, the parser must also account for the rpc_name argument that the system passes to the script.

Python Action Scripts (21.1 and earlier)

In Junos OS Release 21.1 and earlier, the device passes the input argument names to the Python action script exactly as they are given in the command or RPC. You can access the input arguments through the sys.argv list.

For the previous YANG RPC example, the action script's sys.argv input argument list is:

The following sample Python code demonstrates one way to extract the value for each argument from the sys.arv list for the example RPC. The example first defines a dictionary containing the possible argument names as keys and a default value for each argument. The code then checks for each key in the sys.argv list and retrieves the index of the argument name in the list, if it is present. The code then extracts the argument’s value at the adjacent index position, and stores it in the dictionary for the appropriate key. This method ensures that if the arguments are passed to the script in a different order during execution, the correct value is retrieved for a given argument.

Retrieving Operational and Configuration Data

Action scripts can retrieve operational and configuration data from a device running Junos OS and then parse the data for necessary information. SLAX action scripts can retrieve information from the device by executing RPCs supported by the Junos XML management protocol and the Junos XML API. Python action scripts can retrieve operational and configuration information by using Junos PyEZ APIs or by using the cli -c 'command' to execute CLI commands in the action script as you would from the shell. To retrieve operational information with the cli -c method, include the desired operational command. To retrieve configuration information, use the show configuration command.

The following SLAX snippet executes the show interfaces command on the local device by using the equivalent <get-interface-information> request tag:

The following Python code uses Junos PyEZ to execute the get_interface_information RPC, which is equivalent to the show interfaces CLI command:

Note:

For information about using Junos PyEZ to execute RPCs on devices running Junos OS, see Using Junos PyEZ to Execute RPCs on Devices Running Junos OS.

The following Python code executes the show interfaces | display xml command and converts the string output into an XML tree that can be parsed for the required data using XPath constructs:

Emitting the RPC XML Output

An RPC can define output elements using the optional output statement. The action script must define and emit any necessary XML elements for the RPC output. The XML hierarchy emitted by the script should reflect the tree defined by the containers and leaf statements in the definition of the RPC output statement. To return the XML output, the action script must emit the RPC output hierarchy, and only the output hierarchy. SLAX scripts must use the copy-of statement to emit the XML, and Python scripts can use print statements.

For example, consider the following YANG RPC output statement:

The action script must generate and emit the corresponding XML output, for example:

After retrieving the values for the required output elements, a Python script might emit the XML output hierarchy by using the following code:

Similarly, a SLAX action script might use the following:

Validating and Loading Action Scripts on a Device

In your YANG RPC definition, you specify the RPC’s action script by including the junos:command and junos:action-execute statements and the junos:script substatement, which takes the action script’s filename as its value. You must define one and only one action script for each RPC. For example:

Note:

Starting in Junos OS Release 17.3, the action-execute statement is a substatement to command. In earlier releases, the action-execute and command statements are placed at the same level, and the command statement is optional.

Note:

YANG modules that define RPCs for devices running Junos OS must import the Junos OS DDL extensions module.

Python action scripts must meet the following requirements before you can execute the scripts on devices running Junos OS.

  • File owner is either root or a user in the Junos OS super-user login class.

  • Only the file owner has write permission for the file.

  • Script includes an interpreter directive line as outlined in Action Script Boilerplate.

  • The language python or language python3 statement is configured at the [edit system scripts] hierarchy level to enable the execution of unsigned Python scripts.

Note:

Starting in Junos OS Release 20.2R1 and Junos OS Evolved Release 22.3R1, the device uses Python 3 to execute YANG action and translation scripts. In earlier releases, Junos OS only uses Python 2.7 to execute these scripts, and Junos OS Evolved uses Python 2.7 by default to execute the scripts.

Note:

Users can only execute unsigned Python scripts on devices running Junos OS when the script's file permissions include read permission for the first class that the user falls within, in the order of user, group, or others.

You can validate the syntax of an action script in the CLI by issuing the request system yang validate action-script command and providing the path to the script. For example:

To use an action script, you must load it onto the device with the YANG module that contains the corresponding RPC. You use the request system yang add or request system yang update commands to add YANG modules and their associated action scripts to a new or existing YANG package on the device. After you add the modules and action scripts to the device, you can execute your custom RPCs. When you execute an RPC, the device invokes the referenced script.

Troubleshooting Action Scripts

By default, action scripts log informational trace messages when the script executes. You can view the trace messages to verify that the RPC invoked the script and that the script executed correctly. If the script fails for any reason, the errors are logged to the trace file.

Junos OS

To view action script trace messages on Junos OS devices running, view the contents of the action.log trace file.

Junos OS Evolved

To view action script trace messages on Junos OS Evolved devices, view the cscript application trace messages, which include trace data for all script types.

Change History Table

Feature support is determined by the platform and release you are using. Use Feature Explorer to determine if a feature is supported on your platform.

Release
Description
22.3R1-EVO
Starting in Junos OS Evolved Release 22.3R1, Junos OS Evolved uses Python 3 to execute YANG action and translation scripts.
21.2R1 and 21.2R1-EVO
Starting in Junos OS Release 21.2R1 and Junos OS Evolved Release 21.2R1, when the device passes command-line arguments to a Python action script, it prefixes a single hyphen (-) to single-character argument names and prefixes two hyphens (--) to multi-character argument names.
20.2R1
Starting in Junos OS Release 20.2R1, Junos OS uses Python 3 to execute YANG action and translation scripts.
19.2R1
Starting in Junos OS Release 19.2R1, custom YANG RPCs support input parameters of type empty when executing the RPC’s command in the Junos OS CLI, and the value passed to the action script is the parameter name.
17.3R1
Starting in Junos OS Release 17.3, the action-execute statement is a substatement to command.