A Quick Look of YANG Data Modeling for Network Automation.

A Quick Look of YANG Data Modeling for Network Automation.

Hi, As we know a core component of modern automation technology is the language YANG (Yet Another Next Generation). So, Let's explore YANG data modelling.

What is YANG ???

YANG is a data modelling language used to describe the configuration and state data of network devices. It is designed to be human-readable and machine-processable, making it easier to create, modify, and manage network configurations.?YANG models define a hierarchical data structure that can be used for operations based on network configuration management protocols such as NETCONF/RESTCONF.

YANG is maintained by?IETF working group -NETMOD, Refer-?RFC 7950 for more details.

Now the question is, what is a data model of a configuration/state of a network device?

For the answer, Let's assume a scenario where we have to configure IP interface attributes on a specific router.

So we need to supply: an interface name, an IP address and a subnet mask. and also we have to enable the interface.

Now, as simple as the above scenario, what we just did was describe a data model for an IP interface. A YANG model will do the same but uses strict syntax rules to make the model standardized and easy to process with computers.

YANG SYNTAX

Let's take our IP interface example, but this time we'll describe the model using YANG rather than plain English.

Let's redo our IP interface example, but this time we'll describe the model using YANG rather than plain English.

I have used RHEL for this demo. Before we write our YANG model, let's install "pyang", which will allow us to interact with our model.

pyang has two dependencies also make sure to install the same as below:

# Install pyang dependencies
sudo yum install -y xsltproc libxml2-utils

# Clone the pyang repo
git clone https://github.com/mbj4668/pyang

# Install pyang
cd pyang
sudo python setup.py install        

With that done, let's create a new file for defining our YANG model. The file extension must be "yang". I'll name my file:

test-interfaces.yang        

We'll now open the file in a text editor or you can use vscode editor.

WRITING OUR FIRST YANG STATEMENTS

At the top of the file, we'll add a "module" statement followed by the name of our module and a braces block. The module name must match the name of our file.

module test-interfaces {
  
}        

All of the content we now add to the file will go inside the module braces.

Let’s add header information, meta-information, and revision history to our module. Strings are terminated by semicolons instead of newline characters to allow long strings to be written over multiple lines while preserving readability.

yang-version 1.1;

namespace "https://com/example/test-interfaces";

prefix testinterfaces;

organization 
  "ABCD";

contact
  "Support: https://test.com"; //You can add your link

description
  "This YANG module has been created for the purpose of a tutorial.
   It defines the model for a basic ethernet interface";

revision "2020-01-03" {
  description
    "Initial Revision";
  reference
    "Learn YANG - Full Tutorial for Beginners";
}        

The labels yang-version, namespace, organization, etc are known as "statements" in YANG terminology. Let's go over the function of each statement below.

  • yang-version?- Identifies the YANG language specification that the module will conform to. We'll ensure our module conforms to YANG 1.1 which is defined in RFC 7950.
  • namespace?- This is an XML namespace that must be unique for the module. We used a URL but you can use a URN, URI or any other unique identifier here. The namespace specified here must match the namespace on any XML objects which conform to our YANG model.
  • prefix?- A short and unique string to identify our module. This prefix may be used in other YANG modules to import definitions contained in this one.
  • organization?- A string identifying the entity responsible for the module.
  • contact?- Contact details for the entity responsible for the module.
  • description?- A description of the module.
  • revision?- Used for version control. Each edit to a YANG module will add a new revision statement detailing the changes in sub-statements.

With the header & meta information now out of the way, we can move on to our module definition.

HOW TO CREATE A CUSTOM DATA TYPE

Let’s define custom data types for the IPv4 address and subnet mask in the “dotted-quad” notation and add them to our YANG module.

typedef dotted-quad {
  type string {
    pattern
      '(^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$)';
  }
  description
    "Four octets written as decimal numbers and
     separated with the '.' (full stop) character.";
}        

Why not use a string instead of defining a custom data type?

While this would work, it would certainly be a bad practice. In all programming, it is always best to add constraints on the lowest layers to avoid a later reliance on higher layers for error checking.

UNDERSTANDING CONFIGURATION DATA AND STATE DATA

Moving on, let's now add a "container" for our interfaces.

container interfaces {

}        

Our "interfaces" container will hold the child nodes for our configuration data and state data.

Let's distinguish between these two data types below.

  • Configuration Data?- These are read/write configuration fields. For our interface example, this would be the interface name, IP address, subnet mask, and admin enabled/disabled.
  • State Data?- These are read-only operational data fields. Our interface example could include a packet counter and an operational state (physically up or down).

Again, remember that YANG modules will only define the structure of configuration and state data. It will not contain an instantiated value of the data.

ADDING OUR CONFIGURATION DATA

We'll now add a list to our container for defining our interface configuration data.

list interface {
  key "name";
  leaf name {
    type string;
    mandatory "true";
    description
      "Interface name. Example value: GigabitEthernet 0/0/0";
  }
  leaf address {
    type dotted-quad;
    mandatory "true";
    description
      "Interface IP address. Example value: 10.10.10.1";
  }
  leaf subnet-mask {
    type dotted-quad;
    mandatory "true";
    description
      "Interface subnet mask. Example value: 255.255.255.0";
  }
  leaf enabled {
    type boolean;
    default "false";
    description
      "Enable or disable the interface. Example value: true";
  }
}        

Our interface configuration data is quite readable. We have four leaf nodes that define the attributes of an interface. These are labelled with the identifiers "name", "address", "subnet-mask" and "enabled".

Three of the leaf nodes are marked as mandatory. The "enabled" node is optional and will have a default " false " value if not specified.

You'll also notice that the data type of the "address" and "subnet-mask" is "dotted-quad". This matches the identifier of our earlier definition.

ADDING OUR STATE DATA

Let's now add our state data to the interfaces container.

list interface-state {
  config false;
  key "name";
  leaf name {
    type string;
    description
      "Interface name. Example value: GigabitEthernet 0/0/0";
  }
  leaf oper-status {
    type enumeration {
      enum up;
      enum down;
    }
    mandatory "true";
    description
      "Describes whether the interface is physically up or down";
  }
}        

Looking at the state data you'll notice that one key difference is the "config" statement which is set to false. This indicates that the child nodes belonging to the list are read-only.

You'll also notice the enumeration data type that we hadn't used before. This is another built-in type, which allows us to restrict the valid values for the "oper-status" node to a finite set; in our case, the operational status will only ever be up or down.

That concludes the construction of our YANG module for an interface. We may now proceed to interact with the module using pyang.

HOW TO VALIDATE A YANG MODULE

The first cool trick to learn with pyang is how to do basic validation. Run the command below to ensure the YANG module is syntactically correct.

pyang test-interfaces.yang        

If all is well the output should come out clean. If there are syntax errors in the module the command will print a message explaining the issue.

To demonstrate this, let's introduce a typographical error by replacing the type "enumeration" with the word spelt incorrectly, "enumeration". Running the validation command again will highlight the error.

test-interfaces.yang:68: error: type "inumeration" not found in module "test-interfaces"        

All right, now that we have confirmed that, let's fix our spelling mistake.

HOW TO VIEW THE SCHEMA TREE

The next great trick to learn is how to view the schema tree of your YANG module. The schema tree is a summarised visual form of our YANG data model. You can view the tree by adding the format specifier option to your command.

pyang -f tree test-interfaces.yang        

Here's how the output will look for our example.

module: test-interfaces
  +--rw interfaces
     +--rw interface* [name]
     |  +--rw name           string
     |  +--rw address        dotted-quad
     |  +--rw subnet-mask    dotted-quad
     |  +--rw enabled?       boolean
     +--ro interface-state* [name]
        +--ro name           string
        +--ro oper-status    enumeration        

The "rw" acronym is short for read-write. The "ro" acronym is short for read-only.

The rest of the tree is quite self-explanatory. The question mark next to the "enabled" node indicates that this object is optional.

Let's Explore "YANG2DSDL".

YANG2DSDL is a tool that translates YANG data models to DSDL schemas and validates instance documents.?It is used to define custom data types for IPV4 address and subnet masks in “dotted-quad” notation and add them to a YANG module.

YANG2DSDL is part of the Pyang project, which is an extensible YANG validator and converter written in Python.?Pyang includes several other tools for working with YANG data models, such as?pyang, which is a YANG validator and converter, and?yang2html, which generates HTML documentation from YANG modules.

HOW TO VALIDATE A DATA INSTANCE

This will be easier to understand with an example. Below is an XML instance of the YANG module which we defined today.

<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
  <interfaces xmlns="https://com/example/test-interfaces">    <interface>
      <name>GigabitEthernet 0/0/0</name>
      <address>10.10.10.1</address>
      <subnet-mask>255.255.255.0</subnet-mask>
    </interface>
    <interface>
      <name>GigabitEthernet 0/0/1</name>
      <address>192.168.1.1</address>
      <subnet-mask>255.255.255.0</subnet-mask>
    </interface>
  </interfaces>
</data>        

If you are familiar with NETCONF this XML data object will look familiar. This is what a payload looks like in a NETCONF request to edit the configuration of a network device.

We'll now use yang2dsdl to ensure the XML object is valid. Save the XML object to a file. We called our file:

data.xml        

We can now run the command below which will generate the DSDL schemas of our YANG module and validate our data instance.

yang2dsdl -v data.xml test-interfaces.yang        

The program output is shown below.

== Generating RELAX NG schema './test-interfaces-data.rng'
Done.

== Generating Schematron schema './test-interfaces-data.sch'
Done.

== Generating DSRL schema './test-interfaces-data.dsrl'
Done.

== Validating grammar and datatypes ...
data.xml validates

== Adding default values... done.

== Validating semantic constraints ...
No errors found.        

We can see that no errors were found.

We'll now put an invalid IP address into our XML file and rerun the validation. You'll get an error like the one below.

== Validating grammar and datatypes ...
data.xml:5: element address: Relax-NG validity error : Error validating datatype string
data.xml:5: element address: Relax-NG validity error : Element address failed to validate content
data.xml:3: element interface: Relax-NG validity error : Invalid sequence in interleave
data.xml:3: element interface: Relax-NG validity error : Element interface failed to validate content
Relax-NG validity error : Extra element interface in interleave
data.xml:3: element interface: Relax-NG validity error : Element interfaces failed to validate content
data.xml fails to validate        

There we go, that's everything essential you need to learn about YANG!

With a solid grasp of the concepts of the YANG language, you'll find that automation solutions built on top of the NETCONF protocol become demystified.

NETCONF is the protocol for sending and receiving configuration data and state data of network devices. And YANG is the language that describes the structure of this data.

I hope this article will be helpful, here are some resources and references.

Few Other Resources/References::

Does each YANG module have a unique prefix?

Your post is fantastic! The clarity and lucidity of your explanation are truly appreciated. Thank you! 1. Can you explain how this YANG model is used for replying to The RPC? 2. The YANG models are quite large files. How can one effectively understand and work with them??, any python library is there for this?

James Chibole

At the cuttng edge of IT Systems, Applications and Deployments

2 年

Thank you for this post, it is well explained.

Vivek Sood

I build stuff!

3 年

Very well explained.

要查看或添加评论,请登录

Sachin Verma的更多文章

社区洞察

其他会员也浏览了