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. Coincidently, the Ansible netconf_config and netconf_get modules that you used in the previous module actually leverage the ncclient library to perform eaches respective NETCONF tasks.


Step 1 - Create New Python File

Create a new Python file on the nxapilab directory.

        
            cd /home/cisco/Documents/nxapilab
            code -r /home/cisco/Documents/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 a ncclient manager object for each device using the information found in the device dictionary. Lines 22-43 are the XML rpc payload. This is like 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 from the connection ncclient 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.8.12", "port": "830", "platform": "nexus",}, 
                    {"ip": "10.15.8.13", "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>
                                '''
            
                        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()
        

Warning

Be sure to save your file! Not saving will result in your code not executing.


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. Login to the leaf switches and check the existing VNIs mapped under the NVE interface.

Continue to the last bonus section to work with RESTCONF.