Coding Essentials I – NetDevOps Series, Part 3


May 23, 2019 - 0 Comments

Previous posts in the NetDevOps Series are available here.

Let’s do a quick review of the different foundational coding building blocks that network engineers need to understand and use when entering the programmability world.

YANG data models

Data models are conceptual representations of data, defining the specific information that needs to be included and the format to represent it. A data model can be accessed by multiple source applications, via different communication protocols.

YANG (Yet Another Next Generation) is a data modelling language defined originally in RFC 6020 and updated later in RFC 7950. It uses XML to describe the data model for network devices, and it is composed of modules and sub-modules that represent individual YANG files. YANG modules are self-documenting hierarchical tree structures for organizing data.

+--rw interfaces
      | +--rw interface* [name]
      | +--rw name string
      | +--rw description? string
      | +--rw type identityref
      | +--rw enabled? boolean
      | +--rw link-up-down-trap-enable? enumeration
      +--ro interfaces-state
         +--ro interface* [name]
            +--ro name string
            +--ro type identityref
            +--ro admin-status enumeration
            +--ro oper-status enumeration
            +--ro last-change? yang:date-and-time
            +--ro if-index int32
            +--ro phys-address? yang:phys-address
            +--ro higher-layer-if* interface-state-ref
            +--ro lower-layer-if* interface-state-ref
            +--ro speed? yang:gauge64
            +--ro statistics
               +--ro discontinuity-time yang:date-and-time
               +--ro in-octets? yang:counter64
               +--ro in-unicast-pkts? yang:counter64
               +--ro in-broadcast-pkts? yang:counter64
               +--ro in-multicast-pkts? yang:counter64
               +--ro in-discards? yang:counter32
               +--ro in-errors? yang:counter32
               +--ro in-unknown-protos? yang:counter32

As you can see in the example, YANG modules are used to model configuration and state data. Configuration data can be modified (rw), while State data can only be read (ro).

YANG is based on standards from IETF, OpenConfig and others. It is supported by most networking vendors in their own devices, and allows them to augment or deviate models, in order to include vendor / platform specific information.

NetDevOps Series 3

 

YANG data models are publicly available here. As you browse through the hundreds of them, you might soon realize that finding the model you are looking for may be quite time-consuming. To make your life easier please take a look at Cisco YANG Explorer, an open-source YANG browser and RPC builder application to experiment with YANG data models.

NetDevOps Series 3

Once you decide to use YANG data models in your code, you will need to use libraries for your preferred programming language. If your choice is Python, as it is for many network engineers, you should definitely checkout pyang. This Python library can be used to validate YANG modules for correctness, to transform YANG modules into other formats, and even to generate code from the modules.

Finally you might also be interested in taking a look at the capabilities offered by the YANG Catalog, a registry that allows users to find models relevant to their use cases from the large and growing number of YANG modules being published. You may read-access it via NETCONF or REST, to validate YANG modules, search the catalog, view module’s details, browse modules and much more.

JSON and XML

Now that we know how to model data and store it locally, we need to start considering how to communicate it machine-to-machine. It is critical that our system knows how to send requests to network devices, and what format to expect when receiving responses.

The classic approach with CLI provides us with structured data:

GigabitEthernet1 is up, line protocol is up
Description: TO_vSWITCH0
  Internet address is 172.16.11.11/24
  MTU 1500 bytes, BW 1000000 Kbit/sec, DLY 10 usec,
      reliability 255/255, txload 1/255, rxload 1/255
  Encapsulation ARPA, loopback not set
  Keepalive set (10 sec)
  Full Duplex, 1Gbps, media type is RJ45

This type of text output is great for human-machine interaction, because our brain easily understands the information reading through it. However, this is not a good format for machine-to-machine communication, because the system receiving this text would need to be programmed to parse through it, in order to extract the values for the different included fields. Yes, we could program the system to do it, using regular expressions. But there would be important drawbacks: not only implementing how to extract the relevant keys and values, but also how to do it for different platforms and vendors. Please consider that each OS will provide a slightly / largely different text output to show the same kind of info. So, we would need to parse things differently for each case… definitely not the best approach.

Considering that we have defined a common data model, let’s also agree on a common format to exchange that data. Instead of the previous text we would like to receive something like the following:

{
    "description": " TO_vSWITCH0",
    "ipv4Address": "172.16.11.11",
    "ipv4Mask": "255.255.255.0",
    "portName": "GigabitEthernet1",
}

This is an example of data in structured format, and it is critical for our systems to easily process information exchanged between machines.

There are two common formats for data interchange being used these days: JSON and XML.

JSON

JSON (JavaScript Object Notation) is more modern and commonly used by new APIs. With its simple key:value approach, it is very lightweight, easy for systems to generate and parse, but also easy for humans to read.

{
    "className": "GRETunnelInterface", 
    "status": "up",
    "interfaceType": "Virtual"
    "pid": "C9300-48U",
    "serialNo": "FCW2123L0N3",
    "portName": "Tunnel201"
}

No, you don’t need to know any JavaScript to work with JSON. They just happen to share the syntax, but no need at all to be a JavaScript developer when using JSON as the data transfer format between systems.

Python users can easily work with JSON, using its own standard library:

import json

This library allows you to easily work with JSON as native Python objects. Very often you will import JSON data into Python dictionaries, with an array of key:value pairs that enables you to search for the field you require by just running a standard search for a certain key.

Later we will discuss communication protocols, but for your reference please make a note that both REST APIs and RESTCONF support JSON and XML.

XML

XML (eXtensible Markup Language) is a bit older, but still used by a lot of APIs. It is used for data transfer, but sometimes also to store info. It is language-independent and designed to be self-descriptive, although, compared to JSON, tagging makes it a little bit more difficult to read for humans.

{
    <interface>
        <name>GigabitEthernet1</name>
        <description>TO_vSWITCH0</description>
        <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:
                  iana-if-type">ianaift:ethernetCsmacd</type>
            <enabled>true</enabled>
            <ipv4 xmlns="urn:ietf:params:xml:ns:yang:ietf-ip">
                <address>
                    <ip>172.16.11.11</ip>
                    <netmask>255.255.255.0</netmask>
                </address>
            </ipv4>
    </interface>
}

XML is not the same as HTML: XML carries data, while HTML represents it.

Python users also benefit from multiple available resources to work with XML, like ElementTree objects, Document Object Model (DOM), Minimal DOM Implementation (minidom), and xmltodict.

You may learn more about XML in this tutorial.

By now you should have a clearer view on the relationship between YANG and JSON/XML. YANG is the data model that stores information about network devices configuration and status. JSON and XML are data exchange formats to represent the information stored in the data model, so it can be easily understood by both machines and humans.

NetDevOps Series 3

JSON displays information in a clearer way and will be used more frequently by modern systems. However, XML is still required for multiple systems that support it exclusively.

In my next posts we will continue exploring some of the required coding essentials to be a successful programmability champion. See you next week, stay tuned!

Any questions or comments please let me know in the comments section below, Twitter or LinkedIn.

Join DevNet: access the learning labs, docs, and sandboxes you need for network automation. And check out this expert-led, video course for learning network programmability basics.



In an effort to keep conversations fresh, Cisco Blogs closes comments after 60 days. Please visit the Cisco Blogs hub page for the latest content.