Blog Viewer

Scripting How-To: Access RPC on demand

By Erdem posted 02-19-2014 04:30


Access RPC On Demand Directly


You should always have the ability to do anything that the Junos OS or XML API provide. Each Device variable has an rpc property to make accessing Junos OS at this low level easy. Junos PyEZ  has metaprogramming to do what you want only when you need it (on demand).
The term "metaprogramming" means that the rpc will dynamically create Junos OS XML Remote Procedure Calls (RPCs) as you invoke them, rather than pre-coding them as part of the Junos PyEZ library.
In other words, if a Junos OS device provides thousands of RPCs, Junos PyEZ does not contain thousands of RPC functions. It metaprograms only the RPCs that you use, keeping the size of this module small, and the portability flexible.

Usage Example

The following illustrates a basic example using the Device.rpc property to retrieve the inventory, and display the model and serial number information. 
1 from jnpr.junos import Device
2 jdev = Device(user='jeremy', host='vsrx_cyan', password='jeremy1')
3 # invoke the RPC equivalent to "show chassis hardware"
4 inv = jdev.rpc.get_chassis_inventory()
5 # use XPath expressions to extract the data from the Junos/XML response# the :inv: variable is an lxml Element object
6 print "model: %s" % inv.findtext('chassis/description')print "serial-number: %s" %inv.findtext('chassis/serial-number')
7 jdev.close()

RPC Command

It is very easy to determine a Junos OS XML API command. On a Junos CLI you use the | display xml rpc mechanism, as illustrated:
01 jeremy@junos> show chassis hardware | display xml rpc
02 <rpc-reply xmlns:junos="">
03     <rpc>
04         <get-chassis-inventory>
05         </get-chassis-inventory>
06     </rpc>
07     <cli>
08         <banner></banner>
09     </cli>
10 </rpc-reply>
The content between the rpc elements is the XML RPC command, in this case get-chassis-inventory. As you can see from the above code example, to invoke this API, use the NETCONF object rpc attribute and invoke a method name corresponding to the XML RPC command. If the command has dashes (-), swap them to underscores (_). 
1 inv = jdev.rpc.get_chassis_inventory()
If the command has parameters, do the same. Here is an example retrieving the status of a given interface: 


01 jeremy@junos> show interfaces ge-0/0/0 media | display xml rpc
02 <rpc-reply xmlns:junos="">
03     <rpc>
04         <get-interface-information>
05                 <media/>                <interface-name>ge-0/0/0</interface-name>        </get-interface-information>
06     </rpc>
07     <cli>
08         <banner></banner>
09     </cli>
10 </rpc-reply>

The equivalent Python would look like this: 

1 rsp = jdev.rpc.get_interface_information( media=True, interface_name='ge-0/0/0' )
Here the media parameter does not take a value, so you simply assign it to True. Again, for parameter names that contain dashes, you swap them for underscores; interface-name becomes interface_name


RPC Response


It is very easy to determine the response of a Junos OS XML API command. On a Junos OS CLI you use the | display xml mechanism: 


01 jeremy@junos> show chassis hardware | display xml
02 <rpc-reply xmlns:junos="">
03     <chassis-inventory xmlns="">
04         <chassis junos:style="inventory">
05             <name>Chassis</name>
06             <serial-number>AD2909AA0096</serial-number>
07             <description>SRX210H</description>
08             <chassis-module>
09                 <name>Routing Engine</name>
10                 <version>REV 28</version>
11                 <part-number>750-021779</part-number>
12                 <serial-number>AAAH4755</serial-number>
13                 <description>RE-SRX210H</description>
14             </chassis-module>
15             <chassis-module>
16                 <name>FPC 0</name>
17                 <description>FPC</description>
18                 <chassis-sub-module>
19                     <name>PIC 0</name>
20                     <description>2x GE, 6x FE, 1x 3G</description>
21                 </chassis-sub-module>
22             </chassis-module>
23             <chassis-module>
24                 <name>FPC 1</name>     
25                 <version>REV 04</version>
26                 <part-number>750-023367</part-number>
27                 <serial-number>AAAG7981</serial-number>
28                 <description>FPC</description>
29                 <chassis-sub-module>
30                     <name>PIC 0</name>
31                     <description>1x T1E1 mPIM</description>
32                 </chassis-sub-module>
33             </chassis-module>
34             <chassis-module>
35                 <name>Power Supply 0</name>
36             </chassis-module>
37         </chassis>
38     </chassis-inventory>
39     <cli>
40         <banner></banner>
41     </cli>
42 </rpc-reply>

The result of the RPC command is an lxml element, set at the first element after the <rpc-reply>. In the above example, that would be<chassis-inventory>. Given that, any XPath expression is relative. So to extract the chassis serial number, the XPath expression is simply chassis/serial-number.

1 inv = jdev.rpc.get_chassis_inventory()
2 print "model: %s" % inv.findtext('chassis/description')print "serial-number: %s" %inv.findtext('chassis/serial-number')
Since the response variable is an lxml element, you can use any routine available from that library.
For details, refer to the lxml documentation.