Val:~$ whoami

I am Val Glinskiy, network engineer specializing in data center networks. TIME magazine selected me as Person of the Year in 2006.

Search This Blog

Sunday, April 08, 2018

YAML, YANG, ETC

    I started reading on YANG models and OpenConfig about 2 years ago. Around that time I also wrote a script to provision Clos IP fabric. The data structure that script uses to populate Jinja2 templates was totally made up. So, I decided to convert that data structure into OpenConfig-compliant one with a distant goal of feeding it to the switches directly via NETCONF, bypassing the templates. Since I have little desire to create XML files manually, the plan was to write data in YAML, convert into JSON with a simple python script and then use pyang to validate data structure and generate model-compliant XML.
   Before doing all that I completed Cisco's DevNet "NETCONF/YANG on Nexus" lab parts 1, 2 and 3.  Part 3 of the lab uses OpenConfig YANG models, so you can skip part 2 entirely.  XML in Cisco's script looked simple enough, but it took me couple of short days of reading RFCs and data models,   trials, errors and reading data models again to come up with YAML file that pyang finally validated and converted into XML. Here is what I got:
---
"openconfig-interfaces:interfaces":
  interface:   
   - name: eth1/1
     config: 
        name: eth1/1
        type: ethernetCsmacd
     subinterfaces:
         subinterface:
            - index: 0
              openconfig-if-ip:ipv4:
                addresses:
                    address:
                       - ip: 172.16.1.0
                         config:
                            ip: 172.16.1.0
                            prefix-length: 31
You can see XML file that pyang generated here. Pyang writes everything in one line, so I edited it for readability. I used another script to push resulted XML to virtual Nexus switch. And it did not work. The error message said that namespace was empty. (Since Cisco gives access to NX-OS sandbox only for one hour, I had to setup my own sandbox. I'll write another post about it). Another few short hours and manual XML editing - nobody should be editing XML manually - I came up with something that my virtual Nexus accepted (github).
<config>
    <interfaces xmlns="http://openconfig.net/yang/interfaces">
        <interface>
            <name>eth1/1</name>
            <config>
                <name>eth1/1</name>
                <description>OpenConfig</description>
                <type>ianaift:ethernetCsmacd</type>
            </config>
            <subinterfaces>
                <subinterface>
                    <index>0</index>
                    <ipv4>
                        <addresses>
                            <address>
                                <ip>172.16.1.0</ip>
                                <config>
                                    <ip>172.16.1.0</ip>
                                    <prefix-length>31</prefix-length>
                                </config>
                            </address>
                        </addresses>
                    </ipv4>
                </subinterface>
            </subinterfaces>
        </interface>
    </interfaces>
</config>

But I had to add "no switchport" command to Eth1/1 manually first. I could not find anything in OpenConfig or IETF models to make switch do it.
Now is time to save my hard-won changes to startup config - see commented line 29 in the script. It's commented, because virtual switch complained that "startup" is incorrect datastore, while RFC6241 says otherwise. It became clear why switch and RFC disagreed after I looked at switch's NETCONF capabilities:
urn:ietf:params:netconf:capability:writable-running:1.0
urn:ietf:params:netconf:capability:rollback-on-error:1.0
urn:ietf:params:netconf:capability:confirmed-commit:1.1
urn:ietf:params:netconf:capability:validate:1.1
http://cisco.com/ns/yang/cisco-nx-os-device?revision=2017-08-31&module=Cisco-NX-OS-device&deviations=Cisco-NX-OS-device-deviations
urn:ietf:params:netconf:base:1.0
urn:ietf:params:netconf:base:1.1
urn:ietf:params:netconf:capability:candidate:1.0
http://openconfig.net/yang/bgp?revision=2016-06-06&module=openconfig-bgp&deviations=openconfig-bgp-deviations
http://openconfig.net/yang/interfaces?revision=2016-05-26&module=openconfig-interfaces&deviations=openconfig-interfaces-deviations
http://openconfig.net/yang/interfaces/ip?revision=2016-05-26&module=openconfig-if-ip&deviations=openconfig-if-ip-deviations

Capability ":startup" is missing. So, no way to save configuration via NETCONF, I guess.
I am going to check the extent of OpenConfig support on Juniper and Arista devices and for now implement 1st step of my plan - convert totally bogus data structure into OpenConfig-compliant.