Using Salt to Execute RPCs on Devices Running Junos OS
Juniper Networks provides support for using
Salt to manage devices running Junos OS, and the Junos execution and
state modules (for Salt) define functions that enable you to perform
operational and configuration tasks on the managed devices. The salt.modules.junos.rpc
execution function and
the salt.states.junos.rpc
state function enable you
to execute remote procedure calls (RPCs) on devices running Junos
OS to perform operations or retrieve information.
The following sections discuss how to use the functions, parse the device response, specify the output format, and save the output to a file.
Understanding the Junos XML API
The Junos XML API is an XML representation of Junos OS configuration statements and operational mode commands. It defines an XML equivalent for all statements in the Junos OS configuration hierarchy and many of the commands that you issue in CLI operational mode. Each operational mode command with a Junos XML counterpart maps to a request tag element and, if necessary, a response tag element. Request tags are used in remote procedure calls (RPCs) within NETCONF or Junos XML protocol sessions to request information from a device running Junos OS. The server returns the response using Junos XML elements enclosed within the response tag element.
All operational commands that have Junos XML counterparts are
listed in the Junos XML API Explorer. You can also display the Junos XML
request tag element for any operational mode command that has a Junos
XML counterpart on the CLI by appending the | display xml rpc
option after the command. The following example displays the request
tag for the show route
command:
user@router> show route | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/19.2R1/junos"> <rpc> <get-route-information> </get-route-information> </rpc> </rpc-reply>
When you use Salt to manage a device running Junos OS, you can
use the junos.rpc
function to execute the
RPC on the device and return the response.
junos.rpc Function Syntax
The salt.modules.junos.rpc
execution function syntax
is:
salt 'target' junos.rpc rpc dest=dest format=format arg1=arg1-value arg2=arg2-value
The salt.states.junos.rpc
state function supports
the following syntaxes:
rpc: junos.rpc: - dest: dest - format: format - arg1: arg1-value - arg2: arg2-value
id: junos.rpc: - name: rpc - dest: dest - format: format - arg1: arg1-value - arg2: arg2-value
where:
arg=arg-value
—(Optional) One or more RPC arguments to include and their corresponding values, for example,interface-name=ge-1/1/1
orterse=True
.dest
—(Optional) Path of the destination file on the proxy minion server to which the RPC reply is written. If you do not specify an absolute path on the target device, the path is relative to the top-level root (/) directory.id
—User-defined identifier for the state declaration.format
—(Optional) Format of the RPC reply written to the destination file, if specified. Specifytext
,xml
, orjson
.rpc
—Remote procedure call to execute on the device running Junos OS, for example,get-system-uptime-information
.
How to Execute RPCs with the junos.rpc Execution Function
The salt.modules.junos.rpc
execution function enables
you to execute an RPC on a device running Junos OS. The function requires
one argument, which is the RPC to execute. If the operation is successful,
the command returns out: True
, and the rpc_reply
key includes the RPC reply.
For example, the following command executes the get-system-uptime-information
RPC on the target device
and displays the response in standard output:
saltuser@salt-master:~$ sudo salt 'router1' junos.rpc get-system-uptime-information router1: ---------- out: True rpc_reply: ---------- system-uptime-information: ---------- current-time: ---------- date-time: 2019-06-13 17:01:32 PDT last-configured-time: ---------- date-time: 2019-06-12 18:47:12 PDT time-length: 22:14:20 user: saltuser ...
For information about specifying RPC arguments or the function’s output format and location, see:
How to Execute RPCs with the junos.rpc State Function
You can use the salt.states.junos.rpc
state function within a
Salt state file to execute RPCs on a device running Junos OS. You
can define the RPC as the first line of the data structure, or you
can define it within the function’s argument list. If you need
to execute the same RPC multiple times within the same state file,
you must define the RPC within the argument list.
The following state file uses the junos.rpc
state function to execute two RPCs on the target device and save
the output to a file. In this case, the proxy identifier stored in
the id
grain is included in the destination
filename to distinguish the output files when the state is applied
to multiple targets.
saltuser@salt-master:~$ cat /srv/salt/junos_rpc.sls get-system-uptime-information: junos.rpc: - dest: /var/log/salt/output/{{ grains['id'] }}_junos_rpc_system_uptime.xml get-interface-information: junos.rpc: - interface-name: fxp0.0 - terse: True - dest: /var/log/salt/output/{{ grains['id'] }}_fxp0_status.txt - format: text
When you apply the state, the Salt master displays the RPC reply for each RPC in standard output and also saves the output to the corresponding destination file on the proxy minion server.
saltuser@salt-master:~$ sudo salt 'router1' state.apply junos_rpc router1: ---------- ID: get-system-uptime-information Function: junos.rpc Result: True Comment: Started: 23:49:00.633541 Duration: 180.134 ms Changes: ---------- out: True rpc_reply: ---------- system-uptime-information: ---------- current-time: ---------- date-time: 2019-07-26 16:49:00 PDT last-configured-time: ---------- date-time: 2019-07-24 10:17:34 PDT time-length: 2d 06:31 user: saltuser protocols-started-time: ---------- date-time: 2019-07-01 07:07:27 PDT time-length: 3w4d 09:41 system-booted-time: ---------- date-time: 2019-07-01 07:03:56 PDT time-length: 3w4d 09:45 time-source: NTP CLOCK uptime-information: ---------- active-user-count: 1 date-time: 4:49PM load-average-1: 0.01 load-average-15: 0.01 load-average-5: 0.04 up-time: 25 days, 9:45 ---------- ID: get-interface-information Function: junos.rpc Result: True Comment: Started: 23:49:00.813806 Duration: 900.33 ms Changes: ---------- out: True rpc_reply: Interface Admin Link Proto Local Remote fxp0.0 up up inet 198.51.100.2/24 Summary for router1 ------------ Succeeded: 2 (changed=2) Failed: 0 ------------ Total states run: 2 Total run time: 1.080 s
saltuser@minion:~$ ls /var/log/salt/output router1_fxp0_status.txt router1_junos_rpc_system_uptime.xml
If the state is applied to multiple targets, Salt generates different output files for each target on the proxy minion server in this case, because the defined filename references a unique identifier.
saltuser@salt-master:~$ sudo salt '*' state.apply junos_rpc
saltuser@minion:~$ ls /var/log/salt/output router1_fxp0_status.txt router1_junos_rpc_system_uptime.xml router2_fxp0_status.txt router2_junos_rpc_system_uptime.xml
State files cannot use the same state identifier multiple times in a file. Therefore, if you want to use the same RPC request tag multiple times in a state file, you must define the RPC in the function’s argument list. For example:
saltuser@salt-master:~$ cat /srv/salt/junos_rpc.sls Get fxp0 interface information: junos.rpc: - name: get-interface-information - interface-name: fxp0.0 - terse: True - dest: /var/log/salt/output/{{ grains['id'] }}_fxp0_status.txt - format: text Get ge interface information: junos.rpc: - name: get-interface-information - interface-name: ge-1* - terse: True - dest: /var/log/salt/output/{{ grains['id'] }}_ge_interfaces_status.txt - format: text
How to Specify RPC Arguments
The junos.rpc
function supports specifying
keyword arguments and values for an RPC. If an argument takes a value,
include the argument name and specify the value. If an argument does
not require a value, set its value equal to True
.
For example, the following RPC includes two arguments, one of which takes a value:
saltuser@router1> show interfaces ge-1/1/1 terse | display xml rpc <rpc-reply xmlns:junos="http://xml.juniper.net/junos/18.4R1/junos"> <rpc> <get-interface-information> <terse/> <interface-name>ge-1/1/1</interface-name> </get-interface-information> </rpc> <cli> <banner></banner> </cli> </rpc-reply>
To execute the equivalent RPC on the Salt master command line,
include the interface-name='ge-1/1/1'
and terse=True
arguments.
saltuser@salt-master:~$ sudo salt 'router1' junos.rpc get-interface-information interface-name='ge-1/1/1' terse=True
Similarly, in a Salt state file:
saltuser@salt-master:~$ cat /srv/salt/junos_interface_information.sls get-interface-information: junos.rpc: - interface-name: ge-1/1/1 - terse: True
You can specify Junos OS arguments by using the hyphenated element name or by using underscores in place of any hyphens.
When you execute commands on the Salt master command
line, Salt passes the CLI input through PyYAML
to ensure it is loaded as a proper Python data type. In some cases,
arguments that take an integer or that take a string value that parses
to an integer might not be parsed correctly. For those arguments,
you can provide the value using one of the following methods:
Use a backslash ( \ ) to escape quotation marks around string values.
Use double quotation marks to enclose single quotation marks and vice versa.
Include the
--no-parse=param_name
option.
For example:
saltuser@salt-master:~$ sudo salt 'router1' junos.rpc get-route-engine-information slot=\'0\' saltuser@salt-master:~$ sudo salt 'router1' junos.rpc get-route-engine-information slot="'0'" saltuser@salt-master:~$ sudo salt 'router1' junos.rpc get-route-engine-information slot='0' --no-parse=slot
How to Save the RPC Output to a File
When you execute the junos.rpc
function,
you can save the returned data in a file on the proxy minion server
by including the dest
argument and specifying
the path of the destination file. If you do not specify an absolute
path, the path is relative to the top-level root (/) directory. If
an output file already exists with the target name, the new file overwrites
the old file.
The dest
argument does not save the
entire Salt command response in the file. It only saves the RPC reply
contained within the rpc_reply
key.
The following command displays the output from the get-system-uptime-information
RPC and saves the rpc_reply
value to the specified path on the proxy
minion server:
saltuser@salt-master:~$ sudo salt 'router1' junos.rpc get-system-uptime-information dest='/home/saltuser/rpc_output.txt'
saltuser@minion:~$ ls rpc_output.txt
How to Specify the Format for the RPC Output
By default, the junos.rpc
function
returns the RPC output in XML format for both the data displayed in
standard output as well as the data saved to the destination file,
if specified. To specify a different output format, include the format
argument, and set the value equal to the desired
format. To request text format or Junos XML elements, use text
or xml
respectively.
To save the junos.rpc
output to the destination
file in JSON format, specify json
.
The following command executes the get-system-uptime-information
RPC and returns the data in text format:
saltuser@salt-master:~$ sudo salt 'router1' junos.rpc get-system-uptime-information format=text dest=/home/saltuser/router1-get-system-uptime-information.txt router1: ---------- out: True rpc_reply: Current time: 2019-07-29 17:15:03 PDT Time Source: NTP CLOCK System booted: 2019-07-01 07:03:56 PDT (4w0d 10:11 ago) Protocols started: 2019-07-01 07:07:27 PDT (4w0d 10:07 ago) Last configured: 2019-07-24 10:17:34 PDT (5d 06:57 ago) by saltuser 5:15PM up 28 days, 10:11, 1 user, load averages: 0.91, 0.30, 0.15
The output is also written in the requested format to the destination file on the proxy minion server.
saltuser@minion:~$ cat /home/saltuser/router1-get-system-uptime-information.txt Current time: 2019-07-29 17:15:03 PDT Time Source: NTP CLOCK System booted: 2019-07-01 07:03:56 PDT (4w0d 10:11 ago) Protocols started: 2019-07-01 07:07:27 PDT (4w0d 10:07 ago) Last configured: 2019-07-24 10:17:34 PDT (5d 06:57 ago) by saltuser 5:15PM up 28 days, 10:11, 1 user, load averages: 0.91, 0.30, 0.15