Use 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 Explore. 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/1orterse=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_nameoption.
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