Blogs

Async NETCONF RPC example with ncclient

By mwiget posted 06-02-2017 08:15

  

Async NETCONF RPC example with ncclient

ncclient is a great Python library that facilitates client-side scripting and application development around the NETCONF protocol: https://github.com/ncclient/ncclient and used by the even more popular PyEz (https://github.com/Juniper/py-junos-eznc)

 

Typically, one uses the provided functions in synchronous mode, where replies are awaited and the result returned. I was however in need of asynchronous mode, where operations return immediately, allowing me to do ‘other stuff’ and periodically check if a result came in and process it accordingly.

In search of example code using async mode turned out to be harder than I thought. Starting from a synchronous example script that sends a RPC command to retrieve software information and extract the hostname from it (https://github.com/ncclient/ncclient/blob/master/examples/juniper/execute-rpc.py), I ended up with the following working asynchronous version of the same script:

 

from ncclient import manager
from ncclient.xml_ import *
import time
from ncclient.devices.junos import JunosDeviceHandler


def connect(host, port, user, password):
    conn = manager.connect(host=host,
                           port=port,
                           username=user,
                           password=password,
                           timeout=10,
                           device_params={'name': 'junos'},
                           hostkey_verify=False)

    junos_dev_handler = JunosDeviceHandler(
        device_params={'name': 'junos',
                       'local': False})

    conn.async_mode = True

    rpc = new_ele('get-software-information')
    obj = conn.rpc(rpc)

    # for demo purposes, we just wait for the result
    while not obj.event.is_set():
        print('waiting for answer ...')
        time.sleep(.3)

    result = NCElement(obj.reply,
                       junos_dev_handler.transform_reply()
                       ).remove_namespaces(obj.reply.xml)

    print 'Hostname: ', result.findtext('.//host-name')


if __name__ == '__main__':
    connect('pe1', 830, 'lab', 'lab123')

 

Executed against a device:

 

$ python async-execute-rpc.py
waiting for answer ...
waiting for answer ...
Hostname:  pe1

Done!


#How-To