Monday, January 5, 2015

Controlling Junos with Python & PyEZ, Part 2: Getting Info, RPC on Demand


At first part of this post, i've tried to explain how to install PyEZ module on Windows, and how to get the device name. Surely the power of python, PyEZ framework and XML API of Junos is not limited with that, so let's get into detail.

RPC on Demand


For any command you can execute on Junos CLI, you can invoke it's RPC equivalent. To determine an RPC equivalent of a command, you use the | display xml rpc mechanism as illustrated:

etorun@as34984-lg> show route 1.0.0.0 | display xml rpc 
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/12.3R8/junos">
    <rpc>
        <get-route-information>
                <destination>1.0.0.0</destination>
        </get-route-information>
         </rpc>
        <cli>
            <banner></banner>
        </cli>
    </rpc-reply

The content between the "<rpc>...</rpc>" is the XML RPC command, in this case "get_route_information". Be careful you need to swap dashes (-) to underscores(_) 

show_route_output = testdevice.rpc.get_route_information(destination="1.0.0.0")

If you wanted search active route for 1.0.0.0 in inet.0 table, then you need to add parameters to the same command, but the command you need to execute to get the rpc equivalent does not change.
etorun@as34984-lg> show route 1.0.0.0 table inet.0 active-path | display xml rpc 
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/12.3R8/junos">
    <rpc>
        <get-route-information>
                <destination>1.0.0.0</destination>
                <table>inet.0</table>
                <active-path/>
        </get-route-information>
         </rpc>
        <cli>
            <banner></banner>
        </cli>
    </rpc-reply>

However you need to add these extra parameters to python equivalent

show_route_output = testdevice.rpc.get_route_information(destination="1.0.0.0", table="inet.0", active_path=True) 

The "active-path" parameter does not take any value, so just assign it to True

To determine the  RPC response use the | display xml mechanism

etorun@as34984-lg> show route 1.0.0.0 table inet.0 active-path | display xml        
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/12.3R8/junos">
    <route-information xmlns="http://xml.juniper.net/junos/12.3R8/junos-routing">
        <route-table>
            <table-name>inet.0</table-name>
            <destination-count>584861</destination-count>
            <total-route-count>1169721</total-route-count>
            <active-route-count>577542</active-route-count>
            <holddown-route-count>2</holddown-route-count>
            <hidden-route-count>14636</hidden-route-count>
            <rt junos:style="brief">
                <rt-destination>1.0.0.0/24</rt-destination>
                <rt-entry>
                    <active-tag>*</active-tag>
                    <current-active/>
                    <last-active/>
                    <protocol-name>BGP</protocol-name>
                    <preference>170</preference>
                    <age junos:seconds="791658">1w2d 03:54:18</age>
                    <med>0</med>
                    <local-preference>190</local-preference>
                    <learned-from>92.44.0.248</learned-from>
                    <as-path>15169 I
                    </as-path>
                    <validation-state>unverified</validation-state>
                    <nh>
                        <selected-next-hop/>
                        <to>213.14.125.85</to>
                        <via>ge-1/0/3.100</via>
                    </nh>
                </rt-entry>
            </rt>
        </route-table>
    </route-information>
    <cli>
        <banner></banner>
    </cli>
</rpc-reply>

Trying It Out

Imagine you need to take the active as-path value of 1.0.0.0/24. Then the python script should be:

from jnpr.junos import Device
from jnpr.junos import Device
router = Device(user='admin', host='10.0.0.1', password='logmein')
router.open()
# invoke the RPC equivalent to "show route 1.0.0.0 table inet.0 active-path"
show_route_output = router.rpc.get_route_information(destination="1.0.0.0", table="inet.0", active_path=True) 
# use XPath expressions to extract the data from the Junos/XML response# the :show_route_output: variable is an lxml Element object
print "the as-path value is: %s" % show_route_output.findtext('route-table/rt/rt-entry/as-path')
router.close()

Here is the output when i run the .py file from windows powershell:


If you wanted to have a look, I did benefit from RPC On Demand page of Juniper Tech Wiki when writing this post.

0 comments:

Post a Comment

 

Internetworking Hints Copyright © 2011 -- Template created by O Pregador -- Powered by Blogger