Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?

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

How to Use RPCs and Operational Mode Commands in Event Scripts

date_range 14-Jul-21

Most Junos OS operational mode commands have XML equivalents. Event scripts can execute these XML commands on a local or remote device using the remote procedure call (RPC) protocol. All operational mode commands that have XML equivalents are listed in the Junos XML API Operational Developer Reference.

SLAX and XSLT scripts execute RPCs on a local or remote device by using the jcs:invoke() or jcs:execute() extension functions, respectively. In Python scripts, RPCs are easy to execute using Junos PyEZ APIs. Each instance of the Junos PyEZ Device class has an rpc property that enables you to execute any RPC available through the Junos XML API. After establishing a session with a local or remote device, you can execute the RPC by appending the rpc property and RPC method name to the device instance. The return value is an XML object starting at the first element under the <rpc-reply> tag.

Use of RPCs and operational mode commands in event scripts is discussed in more detail in the following sections:

Executing RPCs on a Local Device

In a SLAX or XSLT event script, to execute an RPC on the local device, include the RPC in a variable declaration, and call the jcs:invoke() extension function with the RPC variable as an argument. The following snippet invokes an RPC on the local device:

XSLT Syntax

content_copy zoom_out_map
<xsl:variable name="rpc">
    <get-interface-information/> # Junos RPC for the show interfaces command
</xsl:variable>
<xsl:variable name="out" select="jcs:invoke($rpc)"/>
...

SLAX Syntax

content_copy zoom_out_map
var $rpc = <get-interface-information>;
var $out = jcs:invoke($rpc);

In a Python event script, to execute an RPC on the local device, create the Device instance using an empty argument list, and append the rpc property and the RPC method name and argument list to the device instance.

Python Syntax

content_copy zoom_out_map
from jnpr.junos import Device

with Device() as jdev:
    rsp = jdev.rpc.get_interface_information()
Note:

When you create the Device instance using an empty argument list to connect to the local device, Junos OS uses the access privileges of the user configured at the [edit event-options event-script file filename python-script-user] hierarchy level. If the python-script-user statement is omitted, Junos OS uses the access privileges of the generic, unprivileged user and group nobody.

Executing RPCs on a Remote Device

In a SLAX or XSLT event script, to execute an RPC on a remote device, first include the RPC in a variable declaration, and create a connection handle using the jcs:open() extension function with the arguments required to connect to the remote device. Then call the jcs:execute() extension function and include the connection handle and RPC variable as arguments. For example:

XSLT Syntax

content_copy zoom_out_map
<xsl:variable name="rpc">
    <get-interface-information/> 
</xsl:variable>
<xsl:variable name="connection"
        select="jcs:open('198.51.100.1', 'bsmith', 'test123')"/>
<xsl:variable name="out" select="jcs:execute($connection, $rpc)"/>
<xsl:value-of select="jcs:close($connection)"/>
...

SLAX Syntax

content_copy zoom_out_map
var $rpc = <get-interface-information>;
var $connection = jcs:open("198.51.100.1", "bsmith","test123");
var $out = jcs:execute($connection, $rpc);
expr jcs:close($connection);
...

In a Python event script, to execute an RPC on a remote device, first create an instance of Device using the arguments required to connect to the remote device. Then execute the RPC by appending the rpc property and the RPC method name and argument list to the device instance.

Python Syntax

content_copy zoom_out_map
from jnpr.junos import Device

with Device(host='198.51.100.1', user='bsmith', passwd='test123') as jdev:
    rsp = jdev.rpc.get_interface_information()
Note:

Junos OS connects to and executes operations on the remote device using the access privileges of the user specified in the Device() argument list, even if a different user is configured for the python-script-user statement at the [edit event-options event-script file filename] hierarchy level.

To avoid adding the remote connection details directly into an event script, you can specify remote execution details for each event script that executes RPCs on a remote device at the [edit event-options event-script file filename remote-execution] hierarchy level. We recommend adding the remote execution details to the configuration instead of directly in the event script, because all of the information is available in a single location, and the passphrase is encrypted in the configuration.

For each remote device where an RPC is executed, configure the device hostname and the corresponding username and passphrase.

content_copy zoom_out_map
[edit event-options event-script file filename]
remote-execution {
    remote-hostname {
        username username;
        passphrase passphrase; 
    }
}

The remote hostnames and their corresponding username and passphrase, in addition to the event details, are passed as input to the event script when it is executed by an event policy. For more information about the details that are forwarded to the event script, see Use Event and Remote Execution Details in Event Scripts.

An event script references the remote execution details in the argument list of the function used to create the connection to the remote host. Once the connection has been established, the script can execute RPCs on that device.

In Python event scripts, you reference the remote execution details in the argument list of the Junos PyEZ Device() instance. The following code iterates over the remote execution details for all hosts configured for that event script and connects to and executes the same RPC on each host.

Python Syntax

content_copy zoom_out_map
from junos import Junos_Remote_Execution_Details
from jnpr.junos import Device

def main()    
    for remote in Junos_Remote_Execution_Details():
        hostname = remote.host
        username = remote.user
        passphrase = remote.passwd

        with Device(host=hostname, user=username, passwd=passphrase) as jdev:
            inv = jdev.rpc.get_interface_information() 
            #process RPC information... 

if __name__ == "__main__":
    main() 

In SLAX or XSLT scripts, create a connection to the remote host by using the jcs:open() function and reference the remote execution details in the argument list. For example:

XSLT Syntax

content_copy zoom_out_map
<xsl:variable name="rpc">
    <get-interface-information/> 
</xsl:variable>
<xsl:for-each select="event-script-input/remote-execution-details">
    <xsl:variable name="d" select="remote-execution-detail"/>
    <xsl:variable name="connection"
            select="jcs:open($d/remote-hostname,$d/username,$d/passphrase)"/>
    <xsl:variable name="out" select="jcs:execute($connection, $rpc)"/>
    <xsl:value-of select="jcs:close($connection)"/>
    ...
</xsl:for-each>

SLAX Syntax

content_copy zoom_out_map
var $rpc = <get-interface-information>;
for-each (event-script-input/remote-execution-details) {
    var $d = remote-execution-detail;
    var $connection = jcs:open($d/remote-hostname,$d/username,$d/passphrase);
    var $out = jcs:execute($connection, $rpc);
    expr jcs:close($connection);
     ...
}

To execute an RPC on a remote device, an SSH session must be established. In order for the script to establish the connection, you must either configure the SSH host key information for the remote device on the local device where the script will be executed, or the SSH host key information for the remote device must exist in the known hosts file of the user executing the script. For each remote device where the RPC is executed, configure the SSH host key information using one of the following methods:

  • To configure SSH known hosts on the local device, include the host statement, and specify hostname and host key options for the remote device at the [edit security ssh-known-hosts] hierarchy level of the configuration.

  • To manually retrieve SSH host key information, issue the set security ssh-known-hosts fetch-from-server hostname configuration mode command to instruct Junos OS to connect to the remote device and add the key.

    content_copy zoom_out_map
    user@host# set security ssh-known-hosts fetch-from-server router2
    The authenticity of host 'router2 (198.51.100.1)' can't be established.
    RSA key fingerprint is 30:18:99:7a:3c:ed:40:04:0f:fd:c1:57:7e:6b:f3:90.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'router2,198.51.100.1' (RSA) to the list of known hosts.
  • To manually import SSH host key information from a file, use the set security ssh-known- hosts load-key-file filename configuration mode command and specify the known-hosts file.

    content_copy zoom_out_map
    user@host# set security ssh-known-hosts load-key-file /var/tmp/known_hosts
    Import SSH host keys from trusted source /var/tmp/known_hosts ? [yes,no] (no) yes
  • Alternatively, the user executing the script can log in to the local device, SSH to the remote device, and then manually accept the host key, which is added to that user’s known hosts file. In the following example, root is logged in to router1. In order to execute a remote RPC on router2, root adds the host key of router2 by issuing the ssh router2 operational mode command and manually accepting the key.

    content_copy zoom_out_map
    root@router1> ssh router2
    The authenticity of host 'router2 (198.51.100.1)' can't be established.
    RSA key fingerprint is 30:18:99:7a:3c:ed:40:04:0f:fd:c1:57:7e:6b:f3:90.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'router2,198.51.100.1' (RSA) to the list of known hosts.

After configuring the required SSH host key and obtaining a connection handle to the remote device, the event script can execute RPCs with the jcs:execute() extension function on that remote device.

Displaying the RPC Tags for a Command

You can display the RPC XML tags for operational mode commands in the CLI of the device. To display the RPC XML tags for a command, enter display xml rpc after the pipe symbol ( | ).

The following example displays the RPC tags for the show route command:

content_copy zoom_out_map
user@host> show route | display xml rpc 
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/10.1I0/junos">
    <rpc>
        <get-route-information>
        </get-route-information>
    </rpc>
    <cli>
        <banner></banner>
    </cli>
</rpc-reply>

SLAX and XSLT scripts can execute RPCs using the RPC XML tags. Python scripts must convert the RPC tags and command options into a format suitable for Python. For more information about using Junos PyEZ to execute RPCs and about mapping RPC tags to the corresponding Python method and method arguments, see Using Junos PyEZ to Execute RPCs on Devices Running Junos OS.

Using Operational Mode Commands in Event Scripts

Some operational mode commands do not have XML equivalents. SLAX and XSLT scripts can execute commands that have no XML equivalent by using the <command> element. Python scripts can execute these commands by using the Junos PyEZ cli() method defined in the Device class.

If a command is not listed in the Junos XML API Operational Developer Reference, the command does not have an XML equivalent. Another way to determine whether a command has an XML equivalent is to issue the command followed by the | display xml command.

content_copy zoom_out_map
user@host> operational-mode-command | display xml

If the output includes only tag elements like <output>, <cli>, and <banner>, the command might not have an XML equivalent. In the following example, the output indicates that the show host command has no XML equivalent:

content_copy zoom_out_map
user@host> show host hostname | display xml
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/10.0R1/junos">
   <output>
       ...
    </output>
    <cli>
        <banner></banner>
    </cli>
</rpc-reply>
Note:

For some commands that have an XML equivalent, the output of the piped | display xml command does not include tag elements other than <output>, <cli>, and <banner> only because the relevant feature is not configured. For example, the show services cos statistics forwarding-class command has an XML equivalent that returns output in the <service-cos-forwarding-class-statistics> response tag, but if the configuration does not include any statements at the [edit class-of-service] hierarchy level, then there is no actual data for the show services cos statistics forwarding-class | display xml command to display. The output is similar to this:

content_copy zoom_out_map
user@host> show services cos statistics forwarding-class | display xml
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/8.3I0/junos">
    <cli>
        <banner></banner>
    </cli>
</rpc-reply>

For this reason, the information in the Junos XML API Operational Developer Reference is usually more reliable.

SLAX and XSLT event scripts can execute commands that have no XML equivalent. Use the <command>, <xsl:value-of>, and <output> elements in the script, as shown in the following code snippet. This snippet is expanded and fully described in Example: Display DNS Hostname Information Using an Op Script.

content_copy zoom_out_map
<xsl:variable name="query">
    <command> 
        <xsl:value-of select="concat('show host ', $hostname)"/>
    </command>
</xsl:variable>
<xsl:variable name="result" select="jcs:invoke($query)"/>
<xsl:variable name="host" select="$result"/>
<output>
    <xsl:value-of select="concat('Name: ', $host)"/>
</output>
...

Python event scripts can execute commands that have no XML equivalent by using Junos PyEZ APIs. The cli() method defined in the Device class executes an operational mode command and returns the output in text format. For example:

content_copy zoom_out_map
from jnpr.junos import Device

def main():
    with Device() as jdev:
        res = jdev.cli('show host hostname',  warning=False)
        print (res)

if __name__ == "__main__":
    main()

You can also specify format='xml' to return the output formatted as Junos OS XML elements. For more information about the Junos PyEZ cli method, see http://junos-pyez.readthedocs.org/en/latest/_modules/jnpr/junos/device.html#Device.cli .

footer-navigation