The End (Of Templates) Is Near!
What would network automation that didn't depend on templates look like? I've been interested in this topic for a long time, but didn't have the time to follow up on that interest. So, my goal for this assignment was to dive into some of the technologies that have been developed to make model driven network configuration and operations possible.
Once again, I'm using the Junos vQFX devices for this lab. This led to an interesting challenge that I'll go into more below.
I began my adventures by experimenting with NAPALM-YANG and pyang/pyangbind. NAPALM-YANG had a couple of interesting features, but I couldn't really wrap my head around any practical use-cases. It also didn't look like it was under very active development. Pyang & pyangbind are under more active development, but it looked like it was going to be a lot of work to utilize them; however, playing with them helped me gain a better understanding of what YANG actually was (and was not); however, after going through a few tutorials I found my self thinking "ok, now what?".
After toiling about for a few days I ran across a NANOG 68 video titled Ok, We Got YANG Data Models. Now What. The first thing I noticed was that it was a Cisco presentation - and my initial feeling was, "Uhg, this is just going to be a ridiculous over-hyped sales pitch..." However, I was very surprised to learn that Cisco had open sourced a real solidly designed YANG code generation library named YDK-GEN. The beauty of this library is that it can create bindings in multiple languages, including Go, Python and C++. Each language binding comes with a huge set of pre-built bindings (for all the languages they currently support mentioned above) for Cisco OS's and some of the OpenConfig & IETF models as well.
I was highly impressed with the NANOG presentation and the YDK-Gen and YDK-Py libraries. Since I was using a Junos lab, I needed to create my own Junos YANG model Python bindings. I first tracked down and copied the Junos YANG models I was interested in implementing from here. Then I followed the directions from here to create my Python bindings. NOTE: If you want to generate your own YDK bindings, using the provided docker image will save you some time and trouble. Here is the model bundle profile I wrote to generate Junos Python bindings. The generated bindings are here. Once I had the
tar.gz, I just needed to
pip install (which happens in the vagrant file) and off I went!
Cisco has also released a web-based YANG explorer, which greatly helps with navigating and making sense of a particular yang model. I found this hugely helpful while I was navigating the yang tree in the Python bindings, which isn't always intuitive.
The easiest way to get yang-explorer running is to use the dockerfile here.
Edge Builder Lab
The lab is pretty simple. I wanted to create a simple data-model that modeled edges between two nodes. Then, I'd use
ydk-py to configure the edges, which consists of configuring the interfaces and BGP adjacencies. My goal, as mentioned above, was to leverage NETCONF and YANG Model bindings to configure a device -- and NOT use any templatized CLI commands!
Topology (find this setup here)
========== | server | ========== _____________|_____________ | | em3| em3| ============= ============= | | em5 - em7 | | | vqfx1 | ------------- | vqfx2 | | | ------------- | | ============= =============
Before running the script, only
em3 is configured for management traffic. After running the script the inter-chassis links (em5 - em7) will be configured.
Steps to reproduce lab
NOTE: This YDK tooling is executed from a vagrant box, not your local machine; however, the initial provisioning of the lab linux server and vqfx devices requires
junos-eznc be installed locally -- which is installed into a virtualenv during the
pipenv install portion below.
git checkout https://github.com/ctopher78/network-automation-course.git cd network-automation-course/Homework3 pipenv install pipenv shell vagrant up vagrant ssh ydk-py-ubuntu cd samples/ python crud_provider.py
vagrant@server:samples$ python crud_provider.py Configuring edges for: vqfx2 setting up netconf provider for: '10.10.2.1' adding neighbor '10.10.5.1', peer asn '60001' adding neighbor '10.10.6.1', peer asn '60001' adding neighbor '10.10.7.1', peer asn '60001' Configuring edges for: vqfx1 setting up netconf provider for: '10.10.1.1' adding neighbor '10.10.5.2', peer asn '60002' adding neighbor '10.10.6.2', peer asn '60002' adding neighbor '10.10.7.2', peer asn '60002'
vagrant@vqfx1> show interfaces terse em[5-7]* Interface Admin Link Proto Local Remote em5 up up em6 up up em7 up up
vagrant@vqfx1> show bgp summary | match "10\.10\.[5-7]\.2"
vagrant@vqfx1> show interfaces terse em[5-7]* Interface Admin Link Proto Local Remote em5 up up em5.0 up up inet 10.10.5.1/30 em6 up up em6.0 up up inet 10.10.6.1/30 em7 up up em7.0 up up inet 10.10.7.1/30
vagrant@vqfx1> show bgp summary | match "10\.10\.[5-7]\.2" 10.10.5.2 60002 25 23 0 0 9:39 1/5/5/0 0/0/0/0 10.10.6.2 60002 25 23 0 0 9:35 1/5/5/0 0/0/0/0 10.10.7.2 60002 24 22 0 0 9:31 1/5/5/0 0/0/0/0
The (very) simple data model for this is here.