• NCClient Example with EOS

 
 
Print Friendly, PDF & Email

Introduction

Ncclient is a python library that provides a set of tools to interact with and manipulate devices supporting NETCONF server functionality. The goal of this article is to assist users to leverage ncclient effectively with EOS. This article will outline the use of  ncclient to configure Arista devices using EOS CLI commands, as well as YANG modelled data (and a combination of the two).  This article is not intended to be a full tutorial on YANG or EOS supported YANG models. Arista EOS strives to support open YANG models via support of OpenConfig models wherever possible. At times vendor specific models are required for full compatibility with EOS configuration components. For information on YANG models supported by various versions of EOS, please refer to the TOI’s available here (be sure to select the TOI tab):

https://www.arista.com/en/support/software-download

or here

https://eos.arista.com/toi

In addition to the YANG models that are supported by EOS, it is possible to send arbitrary CLI commands to an EOS device via NETCONF.  An example will be provided later in this document.

Configuring EOS

Before examining the ncclient configuration we need to ensure  EOS is configured to accept NETCONF sessions. Note the below configuration enables NETCONF over ssh on port 22 (ssh):

management api netconf
transport ssh def

Example Python Function

Following is an example python function that will execute our RPC against an EOS device. This function can be standalone, part of a larger script or even in  a separate script:

from ncclient import manager
from ncclient.xml_ import to_ele

def execrpc(hostip, uname, passw, rpc):
   conn=manager.connect(host=hostip,port=22,username=uname,password=passw, timeout=60,hostkey_verify=False,
   device_params={'name':'default'})
   rpcreply = conn.dispatch(to_ele(rpc))
   conn.close_session()

The above example is importing the manager function from ncclient as well as importing to_ele to parse the xml formatted RPC being sent to EOS. In addition, the script will  pass the switch IP, username , password and RPC to be executed. Finally, the RPC reply will be recorded for error checking and the NETCONF session will be terminated.

Example RPCs

Following is a sample RPC that can be executed against our EOS device. Below is a function using OpenConfig YANG models to configure an interface as an access port in a specific vlan:

def intfrpc(vlan, port, descr):
   intfrpc = """<nc:edit-config xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
   <target>
   <running/>
   </target>
   <config>
   <interfaces xmlns="http://openconfig.net/yang/interfaces">
   <interface>
   <name>Ethernet%s</name>
   <config>
   <description>%s</description>
   </config>
   <ethernet xmlns="http://openconfig.net/yang/interfaces/ethernet">
   <switched-vlan xmlns="http://openconfig.net/yang/vlan">
   <config>
   <access-vlan>%s</access-vlan>
   <interface-mode>ACCESS</interface-mode>
   </config>
   </switched-vlan>
   </ethernet>
   </interface>
   </interfaces>
   </config>
   </nc:edit-config>""" % (port, descr, vlan)
   return (intfrpc)

Now we will illustrate how to create the same configuration using CLI commands:

def intfrpc(vlan, port, descr):
   intfrpc = """<nc:edit-config xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
   <target>
   <running/>
   </target>
   <commands>
   <command>interface ethernet %s</command>
   <command>description %s</command>
   <command>switchport access vlan%s</command>
   </commands>
   </nc:edit-config>""" % (port, descr, vlan)
   return (intfrpc)

The two methods can also be combined to create a more complex RPC. The below RPC configures an SVI as well as some EVPN parameters.
Note that this example also includes use of Arista specific YANG models to fill in configuration parameters not covered by Openconfig models:

def irbrpc(vrf, vlan, svi, bgpas, rd, imprt, exprt, vni):
   snetrpc = """<nc:edit-config xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
   <target>
   <running/>
   </target>
   <commands>
   <command>interface vlan %s</command>
   <command>vrf %s</command>
   <command>ip address virtual %s/24</command>
   <command>ip attached-host route export</command>
   </commands>
   <config>
   <arista xmlns="http://arista.com/yang/experimental/eos">
   <eos>
   <evpn xmlns="http://arista.com/yang/experimental/eos/evpn">
   <evpn-instances>
   <evpn-instance>
   <name>%s</name>
   <config>
   <instance-type>VLAN</instance-type>
   <name>%s</name>
   <redistribute>LEARNED</redistribute>
   <redistribute>ROUTER_MAC</redistribute>
   <redistribute>HOST_ROUTE</redistribute>
   <route-distinguisher>%s</route-distinguisher>
   </config>
   <route-target>
   <config>
   <auto-export>false</auto-export>
   <export>%s</export>
   <import>%s</import>
   </config>
   </route-target>
   <vlans>
   <vlan>
   <vlan-id>%s</vlan-id>
   <config>
   <vlan-id>%s</vlan-id>
   </config>
   </vlan>
   </vlans>
   </evpn-instance>
   </evpn-instances>
   </evpn>
   </eos>
   </arista>
   <network-instances xmlns="http://openconfig.net/yang/network-instance"><network-instance>
   <name>default</name>
   <vlans>
   <vlan>
   <vlan-id>%s</vlan-id>
   <config>
   <mac-learning xmlns="http://arista.com/yang/openconfig/network-instance/vlan/augments">true</mac-learning>
   <name>VLAN_%s</name>
   <status>ACTIVE</status>
   <vlan-id>%s</vlan-id>
   </config>
   <members/>
   </vlan>
   </vlans>
   </network-instance>
   </network-instances>
   <interfaces xmlns="http://openconfig.net/yang/interfaces">
   <interface>
   <name>Vxlan1</name>
   <arista-vxlan xmlns="http://arista.com/yang/experimental/eos/vxlan">
   <config>
   <vlan-to-vnis>
   <vlan-to-vni>
   <vlan>%s</vlan>
   <vni>%s</vni>
   </vlan-to-vni>
   </vlan-to-vnis>
   </config>
   </arista-vxlan>
   </interface>
   <interface>
   <name>Vlan%s</name>
   <arista-varp xmlns="http://arista.com/yang/experimental/eos/varp/intf">
   <virtual-address>
   <config>
   <ip>%s</ip>
   <prefix-length>24</prefix-length>
   </config>
   </virtual-address>
   </arista-varp>
   <config>
   <description>VLAN_%s</description>
   <enabled>true</enabled>
   <name>Vlan%s</name>
   <tpid xmlns="http://openconfig.net/yang/vlan" xmlns:oc-vlan-types="http://openconfig.net/yang/vlan-types">oc-vlan-types:TPID_0X8100</tpid>
   <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:l3ipvlan</type>
   </config>
   <routed-vlan xmlns="http://openconfig.net/yang/vlan">
   <config>
   <vlan>Vlan%s</vlan>
   </config>
   </routed-vlan>
   </interface>
   </interfaces>
   </config>
   </nc:edit-config>""" % (vlan, vrf, svi, vlan, vlan, rd, exprt, imprt, vlan,
   vlan, vlan, vlan, vlan, vlan, vni, vlan, svi, vlan, vlan, vlan)
   return (irbrpc)

Conclusion

To wrap up the example, the below code can be added to the python script to execute the IRB RPC. The example will use hard coded values, which is not ideal. It is left to the user to programmatically obtain the values, whether it be via manual input or derived using some other method.  Note that this example assumes that “vrf instance example-vrf” was previously configured. Also note that 4.23.3M or later EOS is required for the IRB YANG models.

vlan = ‘100’
vrf = ‘example-vrf’
svi = ‘1.1.1.1’
bgpas = ‘1’
rd = ‘1:1’
exprt = ‘2:2’
imprt = ‘3:3’
vni = ‘10000’
hostip = ‘192.168.56.101’
uname = ‘admin’
passw = ‘arista’
def main():
    rpc = irbrpc(vrf, vlan, svi, bgpas, rd, imprt, exprt, vni)
    execrpc(hostip, uname, passw, rpc)

if __name__ == "__main__":
   main()

Viewing the before and after configuration exhibits the below configuration was added:

vlan 100
   name VLAN_100
!
interface Vlan100
   description VLAN_100
   vrf example-vrf
   ip attached-host route export
   ip address virtual 1.1.1.1/24
!
interface Vxlan1
   vxlan vlan 100 vni 10000
!
router bgp 1
   vlan 100
      rd 1:1
      route-target import 3:3
      route-target export 2:2
      redistribute learned

 

Follow

Get every new post on this blog delivered to your Inbox.

Join other followers: