Introduction
Within this tutorial we will use NETCONF and YANG to configure an interface upon a Cisco CSR router using a combination of Python and the BASH CLI.
Furthermore we will use 2 main tools – Pyang and Pyangbind. Before we start lets have a quick overview on what these tools do,
Pyang is a YANG validator, transformator and code generator, written in python. It can be used to validate YANG modules for correctness, to transform YANG modules into other formats, and to generate code from the modules.
– https://github.com/mbj4668/pyang
PyangBind is a plugin for Pyang that generates a Python class hierarchy from a YANG data model. The resulting classes can be directly interacted with in Python.
– https://github.com/robshakir/pyangbind
Environment
Before we start there are a few things we need to cover.
Enable NETCONF/YANG
First of all NETCONF and YANG must be enabled. To do so, simply enter the following,
csr1000v(config)# netconf-yang
Dependencies
The following Python modules will also need to be installed.
sudo pip install ncclient pyang pyangbind sudo pip install git+https://github.com/rickd3/commontools.git
Steps
We will now guide you through the various steps required in updating the CSR using NETCONF/YANG. To summarize the steps,
- First the capabilities of the device are confirmed. In other words we clarify what models and YANG operations are supported by the device.
- A NETCONF session is established to the device (via the ncclient module).
- The capabilities of the device retrieved.
- The YANG model that we will be using is reviewed for any imports. All YANG models are then saved as individual files.
- Pyangbind is then used to create a Python binding file to provide a Python (class) representation of the model within Python (when imported).
- The Pybind file is then imported into Python and worked upon. Applying the required changes to our model. The model is then saved to file as JSON.
- The JSON file is reconverted to XML, then applied to the device via NETCONF.
- Finally, the changes are confirmed.
Confirm Capabilities
The first thing in the workflow of NETCONF and YANG is to confirm the device capabilities and supported YANG models.
from file import read_file, write_file from ncclient import manager m = manager.connect(host='10.29.1.110', port=830, username='cisco', password='cisco', device_params={'name': 'csr'}) for c in m.server_capabilities: print c ... urn:ietf:params:xml:ns:yang:smiv2:SNMP-FRAMEWORK-MIB?module=SNMP-FRAMEWORK-MIB&revision=2002-10-14 urn:ietf:params:xml:ns:yang:cisco-policy-target?module=cisco-policy-target&revision=2016-03-30 urn:ietf:params:xml:ns:yang:smiv2:CISCO-CBP-TARGET-TC-MIB?module=CISCO-CBP-TARGET-TC-MIB&revision=2006-03-24 urn:ietf:params:netconf:capability:notification
Gather YANG Models
Confirm Imports
The model that we will use to config the interface will be ietf-ip. However we must also check for any imports. What is an import? As defined by RFC 6020, it is,
The “import” statement makes definitions from one module available inside another module or submodule.
We can do this by printing the YANG modules schema. Like so,
print m.get_schema('ietf-ip') ... import ietf-interfaces { prefix if; } import ietf-inet-types { prefix inet; } import ietf-yang-types { prefix yang; }
Save YANG Models
After confirming all of the YANG models that are required, we save each model to a file.
yang_models = ["ietf-interfaces", "ietf-inet-types", "ietf-yang-types"] for model in yang_models: schema = m.get_schema(model) write_file(schema.data, "{}.yang".format(model))
Build Python Binding
We will now build the Python YANG binding, which is done via the PyandBind plugin for pyang. PyangBind is a plugin for Pyang that generates a Python class hierarchy from a YANG data model. Interaction to resulting classes can then be performed within Python.
First, let us define the path of PyangBind as an environment variable.
$ export PYBINDPLUGIN=`/usr/bin/env python -c \ 'import pyangbind; import os; print "%s/plugin" % os.path.dirname(pyangbind.__file__)'` $ echo $PYBINDPLUGIN
We then run Pyang, using the Pyangbind module. Within the command we set the file type, the output filename and the YANG models we are ingesting.
$ pyang --plugindir $PYBINDPLUGIN -f pybind -o ietf_ip_binding.py ietf-ip.yang ietf-interfaces.yang ietf-inet-types.yang
Model Changes
Now that we have our Python binding, we can import this and work upon the model using the standard Python features.
First we import the binding,
from ietf_ip_binding import ietf_interfaces from pprint import pprint model = ietf_interfaces() model.get() ... {'interfaces-state': {'interface': OrderedDict()}, 'interfaces': {'interface': OrderedDict()}}
Lets add an interface to the model,
interface_ge3 = model.interfaces.interface.add('GigabitEthernet3') pprint(interface_ge3.get()) ... {'description': u'', 'enabled': True, 'ipv4': {'address': OrderedDict(), 'enabled': True, 'forwarding': False, 'mtu': 0, 'neighbor': OrderedDict()}, 'ipv6': {'address': OrderedDict(), 'autoconf': {'create-global-addresses': True, 'create-temporary-addresses': False, 'temporary-preferred-lifetime': 86400L, 'temporary-valid-lifetime': 604800L}, 'dup-addr-detect-transmits': 1L, 'enabled': True, 'forwarding': False, 'mtu': 0L, 'neighbor': OrderedDict()}, 'link-up-down-trap-enable': u'', 'name': u'GigabitEthernet3', 'type': u''}
Great. Lets make some changes to the interface (add ip/mask and admin down),
interface_ge3.enabled = False interface_ge3_addr = interface_ge3.ipv4.address.add('2.2.2.2') interface_ge3_addr.netmask = '255.255.0.0' pprint(interface_ge3.get()) ... {'description': u'', 'enabled': False, 'ipv4': {'address': OrderedDict([('2.2.2.2', {'ip': u'2.2.2.2', 'netmask': u'255.255.0.0', 'prefix-length': 0})]), 'enabled': False, 'forwarding': False, 'mtu': 1460,
This model is then saved back into a file. Please note : Pyang currently only supports JSON as a data type for export.
import pyangbind.lib.pybindJSON as pybindJSON from file import read_file, write_file json_data = pybindJSON.dumps(model, mode='ietf') write_file(json_data, "interface_ge3.json")
Apply Changes
Before we apply the changes, we must convert our JSON YANG model back to XML. Like so,
pyang -f jtox -o interface.jtox ietf-ip.yang ietf-interfaces.yang ietf-inet-types.yang ietf-yang-types.yang json2xml -t config -o interface_ge3.xml interface.jtox interface_ge3.json
Now that we have the YANG model as XML, we use NETCONF to perform the <edit-config> operation upon the device, which will apply the changes into our requested datastore (running).
from file import read_file, write_file from ncclient import manager m = manager.connect(host='10.29.1.110', port=830, username='cisco', password='cisco', device_params={'name': 'csr'}) xml = read_file("interface_ge3.xml") if m.edit_config(target='running', config=xml): print "success" else: print "unsuccessful" m.close_session()
Confirm Changes
To confirm our changes have been made we can go onto the device and issue a show run against the interface.
csr1000v#show run interface GigabitEthernet3 Building configuration... Current configuration : 147 bytes ! interface GigabitEthernet3 description to iosv-1 ip address 2.2.2.2 255.255.0.0 shutdown negotiation auto no mop enabled no mop sysid end
References
http://networkop.co.uk/blog/2017/01/25/netconf-intro/
- How to Configure a BIND Server on Ubuntu - March 15, 2018
- What is a BGP Confederation? - March 6, 2018
- Cisco – What is BGP ORF (Outbound Route Filtering)? - March 5, 2018
Want to become a networking expert?
Here is our hand-picked selection of the best courses you can find online:
Cisco CCNA 200-301 Certification Gold Bootcamp
Complete Cyber Security Course – Network Security
Internet Security Deep Dive course
Python Pro Bootcamp
and our recommended certification practice exams:
AlphaPrep Practice Tests - Free Trial