ncclient
Python

ncclient

In this module, you are going to use a Python library called ncclient to map the L2VNI you created previously to the NVE (VTEP) interface. Coincidentally, the Ansible netconf_config and netconf_get modules that you used in the previous module actually leverage the ncclient library to perform their respective NETCONF tasks.


Step 1 - Create New Python File

Create a new Python file in the nxapilab directory.


cd /home/pod21/workspace/nxapilab
touch /home/pod21/workspace/nxapilab/nx_ncclient_config.py
code-server -r /home/pod21/workspace/nxapilab/nx_ncclient_config.py

    

Step 2 - Import the ncclient Connection Manager

The ncclient library is like any other package in Python; it must be imported, or particular methods must be imported. Below, you are going to import the ncclient connection manager that handles the connections to NETCONF-enabled devices. Either copy or type the import statements below and place them at the top of your Python file.


from ncclient import manager
from ncclient.xml_ import to_ele


Step 3 - Create Main Function

Like the previous Python scripts you have written in this lab, below is the main function of the program. A list of dictionaries is used for the device connectivity information found at line 10. Line 14 uses a loop for iterating over the device list. Lines 16-19 instantiate an ncclient manager object for each device using the information found in the device dictionary. Lines 22-43 are the XML RPC payload. This is similar to the XML file created in the previous Ansible NETCONF section. Lastly, line 45 is the actual NETCONF operation: edit-config. Notice that the edit-config operation is a method provided by the ncclient connection manager object that is created as m. The connection manager object takes two arguments: the RPC payload and the target datastore.


def main():
    """
    Main method that prints netconf capabilities of device.
    """
    # Device dictionary to use
    devices = [
        {"ip": "10.15.21.21", "port": "830", "platform": "nexus",}, 
        {"ip": "10.15.21.22", "port": "830", "platform": "nexus",}
    ]
    for device in devices:
        # ncclient manager instantiation for nexus
        with manager.connect(host=device['ip'], port=device['port'], username='admin',
                                password='cisco.123', hostkey_verify=False,
                                device_params={'name': device['platform']},
                                look_for_keys=False, allow_agent=False) as m:

            # Config RPC
            config_rpc = '''
                    <config>
                        <System xmlns="http://cisco.com/ns/yang/cisco-nx-os-device">  
                        <eps-items>
                            <epId-items>
                            <Ep-list>
                                <epId>1</epId>
                                <adminSt>enabled</adminSt>
                                <nws-items>
                                <vni-items>
                                    <Nw-list>
                                    <vni>10016</vni>
                                    <mcastGroup>239.0.0.16</mcastGroup>
                                    </Nw-list>
                                </vni-items>
                                </nws-items>
                            </Ep-list>
                            </epId-items>
                        </eps-items>
                        </System>
                    </config>
                    '''

            # Edit Config RPC
            reply = m.edit_config(config_rpc, target='running')
            print(reply)

            # Save RPC
            rpc = '''
                <copy_running_config_src xmlns="http://cisco.com/ns/yang/cisco-nx-os-device">
                        <startup-config/>
                </copy_running_config_src>
                '''
            reply = m.dispatch(to_ele(rpc))
            print(reply)


Step 4 - Setup Call of Main Function

The last bit of Python is to call the main function you defined above.


if __name__ == '__main__':
    main()


Step 5 - Run Python Script

Once you have finished with your code, execute your ncclient Python script:


python nx_ncclient_config.py

    

Upon a successful execution, you should see four rpc-reply messages with an ok as the reply return.


        <?xml version="1.0" encoding="UTF-8"?>
        <rpc-reply xmlns:nxos="http://www.cisco.com/nxos:1.0" xmlns:if="http://www.cisco.com/nxos:1.0:if_manager" xmlns:nfcli="http://www.cisco.com/nxos:1.0:nfcli" xmlns:vlan_mgr_cli="http://www.cisco.com/nxos:1.0:vlan_mgr_cli" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:4f7f036e-2fa7-4647-a623-7ec4f5b4cb9b">
            <ok/>
        </rpc-reply>

        <?xml version="1.0" encoding="UTF-8"?>
        <rpc-reply xmlns:nxos="http://www.cisco.com/nxos:1.0" xmlns:if="http://www.cisco.com/nxos:1.0:if_manager" xmlns:nfcli="http://www.cisco.com/nxos:1.0:nfcli" xmlns:vlan_mgr_cli="http://www.cisco.com/nxos:1.0:vlan_mgr_cli" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:a915ce07-fa27-487c-b9f9-7eb5c7da1c28">
            <ok/>
        </rpc-reply>

        <?xml version="1.0" encoding="UTF-8"?>
        <rpc-reply xmlns:nxos="http://www.cisco.com/nxos:1.0" xmlns:if="http://www.cisco.com/nxos:1.0:if_manager" xmlns:nfcli="http://www.cisco.com/nxos:1.0:nfcli" xmlns:vlan_mgr_cli="http://www.cisco.com/nxos:1.0:vlan_mgr_cli" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:164fb21b-ec2d-418a-b3b4-6a1129e9f0b1">
            <ok/>
        </rpc-reply>

        <?xml version="1.0" encoding="UTF-8"?>
        <rpc-reply xmlns:nxos="http://www.cisco.com/nxos:1.0" xmlns:if="http://www.cisco.com/nxos:1.0:if_manager" xmlns:nfcli="http://www.cisco.com/nxos:1.0:nfcli" xmlns:vlan_mgr_cli="http://www.cisco.com/nxos:1.0:vlan_mgr_cli" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="urn:uuid:aafad1f1-0a12-4971-940e-7c3ca0992010">
            <ok/>
        </rpc-reply>
    

Upon successful execution of this Python code, the VNI will be mapped to the NVE interface for your leaf switches. You can confirm this two ways:

  1. The output with the rpc-reply containing "ok" confirming a successful operation, or
  2. Log in to the leaf switches and check the existing VNIs mapped under the NVE interface.

Continue to the last bonus section to work with RESTCONF.