YANG:
- Yet Another Next Generation
- Data Modeling language used with NETCONF and RESTCONF.
- Originally came from Structure of Management Information next generation (SMIng).
- Uses tree like structure similar to XML.
- Modules start with top level ‘Container‘ objects.
- Ex. in networking – part of a router/switch. Container could equal ‘routing table’ or ‘interface’.
- Leafs – Descriptive objects that are within Containers.
- Ex. Name of interface, type of interface, state of interface.
- Each leaf has a ‘Type‘
- Ex. String or Boolean.
- Makes distinction between state related information and configuration items.
- RW – Read/Write
- RO – Read Only
NETCONF:
- Network Configuration Protocol
- Utilizes YANG data models and uses TCP 830
- Can decipher whether it’s dealing with operational/state data or configuration data.
- Encodes with XML or JSON.
- Common NETCONF Operations:
- <get>, <validate>, <get-config>, <lock>, <unlock>, <delete-config>.
- Uses RPC for messaging and SSHv2 – Need v2 enabled on Cisco boxes.
- NETCONF Agent – Router, Switch, NETCONF capable devices.
- NETCONF Manager – App used by operators.
- Datastores – Tables of data stored by the agent.
- <Running>
- <Startup>
- <Candidate>
Enabling NETCONF on Cisco IOS-XE:
- Enable SSHv2
- username cisco privilege 15 password cisco
- ip domain name mickx009.org
- crypto key generate rsa modulus 2048
- line vty – transport input ssh, login local (if local username is needed – if not AAA needs to be configured)
- ip ssh version 2
- Turn on NETCONF
- router(config)#netconf-yang
NETCONF/YANG with Python NCCLIENT:
NCCLIENT is a NETCONF Software Development Kit that operates in Python to assist with connecting to NETCONF Agents. After installing NCCLIENT via PIP, all that’s needed is for the library to be imported into Python scripts.
– ‘from ncclient import manager’
Connecting to a NETCONF enabled IOS-XE device in Python requires using the NCCLIENT manager.connect option, host, port, username and password. This can be accomplished with a python with statement.

Above shows a script doing the following:
- Importing the NCCLIENT Manager
- Creating a dictionary specifying the router hostname, credentials, etc
- Using a with statement referring back to the dictionary for credentials, etc
- Creating NETCONF authentication into a variable that can be used moving forward
- And printing all NETCONF capabilities with 50 ‘*’ in between each line.
Making configuration changes on an IOS-XE device with NETCONF can be done with the NCCLIENT edit-config and a config template in a YANG model. Below is the IETF interfaces template in XML:

The template above can be opened in a Python script. With the Python format function, one can then fill in each ‘mustache’ as they see fit.

The script above does just that. From the top the script does the following:
- Imports NCCLIENT Manager
- Imports a dictionary with an IOS-XE router login/port/IP information
- Opens the template called ‘config_template’ which allows us to change the interface description.
- Changes the mustache variables to whatever is entered in “”
- Adds the change to the running container, or running config.
- Prints out the NETCONF reply, which is a simple ok
For clarity, the dictionary in the ‘routerinfo’ file looks like this:

RESTCONF:
- REST – Representational State Transfer
- REST APIs
- Runs HTTP verbs like GET, PUT, POST, DELETE
- Typically encoded in JSON or XML.
- CRUD
- Create
- Read
- Update
- Delete
- RESTCONF:
- Uses HTTPS instead of SSH
- Uses JSON primarily
- Sessionless, stateless
Enabling RESTCONF in IOS-XE:
- Enable SSHv2
- username cisco privilege 15 password cisco
- ip domain name mickx009.org
- crypto key generate rsa modulus 2048
- line vty – transport input ssh, login local (if local username is needed – if not AAA needs to be configured)
- ip ssh version 2
- Turn on RESTCONF
- router(config)#restconf
- ip http server
- ip http authentication local
- ip http secure server
RESTCONF/YANG with Postman
Connecting to a Cisco IOS-XE device with Postman requires the following:
Headers:

URL:

Notice we are going into the RESTCONF root and finding the NETCONF capabilities.
Authorization:

Notice the Basic Auth, username and password.
And when the GET request is sent, received in Postman is the list of capabilities below.

In the capabilities list the location /restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces can be found. This will provide some detailed information about every interface on the IOS-XE device in JSON format.

Another interface example uses the location /restconf/data/Cisco-IOS-XE-native:native/interface/GigabitEthernet=<interface number>

This will zoom into a specific IOS-XE interface with some slightly different data.
Those were all HTTP GET requests, but POSTS can be completed as well. All of the headers, authorization are the same, but now a body is needed to push to the device. Below is an example of adding a Loopback interface to the router.

Above we have changed the GET to POST, then added a body onto what’s being sent to the IOS-XE device. It’s easiest to run a GET, copy how the YANG model is formatted, then add and change as needed in the body. At least for a simple task like adding a Loopback interface to a device.
This was the IETF formatting, but Cisco has their own models as well that can be found under the capabilities list.
To remove the Loopback that was just created, the request type needs to be changed to DELETE and the URL needs to be zeroed into the interface. When creating the interface, the URL used was below:
https://<host IP>/restconf/data/ietf-interfaces:interfaces
When deleting the interface, the URL is below:
https://<host IP>/restconf/data/ietf-interfaces:interfaces/interface=Loopback1
The response will be a ‘no content per below.

RESTCONF/YANG with Python Requests:
Connecting to an IOS-XE device with Python Requests is somewhat similar to connecting to other network devices via APIs. Requires the URL, headers, and creating response objects to gather and manipulate data on.
First we need to import requests, json, and pprint (optional), then create an object with the host IP and credentials.

Next we’ll throw in the following headers in dictionary format as well, just like the router object above.

Then we’ll do the RESTCONF URL. This one is a native Cisco IOS-XE call.

After those basic items are added to the script, we then need to create the HTTP request that’s referencing the above items. Below is a GET request that references the router, headers, and url.
The response will be then formatted into a Python dictionary with the .json() addition, and then we’re printing the admin-status, description, and ether-stats.

Converting to dictionary allows us to easily cherry pick key values we want to print to screen. Below is an image of just a pprint of api_data – ie. pprint(api_data) at the bottom of the script.

Adding the specific Keys to print can narrow down what we want back from the script – ie. pprint(api_data[“Cisco-IOS-XE-interfaces-oper:interface”][“admin-status”])

The HTTPS verification can be ignored. The response back was the value from Key ‘admin-status’.
On-change subscription with gRPC:
Enabling on-change subscription on an IOS-XE device requires below commands:
router(config)#telemetry ietf subscription 1
router(config-mdt-subs)#receiver ip address 10.30.1.50 57000 protocol grpc-tcp (or grpc-tls if TIG stack supports TLS)
router(config-mdt-subs)#source-address <source interface IP where data should be sent from>
router(config-mdt-subs)#filter xpath /cdp/ios-xe-oper:cdp-neighbor-details/cdp-neighbor-detail
router(config-mdt-subs)#stream yang-push
router(config-mdt-subs)#encoding encode-kvgpb

The above commands will allow an IOS-XE device to push streaming telemetry data to a TIG stack. The encode-kvgpb allows encoding for a TIG stack. The xpath is the xpath location where the switch is watching for changes. The update-policy on-change allows the switch to watch for changes to CDP neighbors and send that data to TIG if there are in fact changes.