Cisco Restconf - Get Operational Data

Cisco Restconf - Get Operational Data
In: NetDevOps Cisco Python

In this blog post, we'll use Restconf to pull operational data from a Cisco switch. So far in our previous posts, we've looked at getting and changing configuration data. This time, it's all about operational data, which is more like what you see when you use 'show' commands on a switch.

Operational data gives us operational info about what's happening on the switch, like interface stats or VLAN status. With Restconf and Yang, getting this data becomes straightforward.

If you're new to YANG or Restconf, I suggest checking out my previous blog posts for a quick catch-up. They'll help you get the hang of these topics.

How to Install Cisco YANG Suite? (Example with C9300)
In today’s post, we’re diving into Cisco YANG Suite, a tool that makes using netconf/restconf a breeze. If you want to easily configure and manage your network
Cisco Restconf Example
In today’s blog post, we’re going to explore how to interact with a Cisco 9300 switch using RESTCONF and Python. We’ll focus on two main tasks, retrieving VLAN information and then configuring new VLANs.
Restconf - Cisco Interface Configurations (Python)
In this blog post, we will look into the practical use of Restconf for managing Cisco Interface configurations. We will look at a simple Python script that fetches interface

Yang for Operational Data

YANG, the data modelling language used in network configuration, also extends to operational data. If you take a look at the YANG GitHub repository, you'll notice modules ending with -oper. These modules are specifically designed for operational data. Unlike their configuration counterparts, these operational modules focus on the current state of network devices.

For example, alongside the usual VLAN configuration modules, you'll find VLAN operational modules. These allow us to access VLAN information, similar to what you'd expect from show vlan commands but in a more structured and accessible format.

Get VLAN Info

In this first example, we'll look at how to use Restconf to fetch VLAN information from a Cisco switch, akin to the show vlan command's output. Let's break down the script and the output.

import requests
import json

requests.packages.urllib3.disable_warnings()

username = 'admin'
password = 'password'

uri = 'https://10.1.1.1:443/restconf/data/Cisco-IOS-XE-vlan-oper:vlans/vlan'
headers = {
    "accept": "application/yang-data+json",
    "Content-Type": "application/yang-data+json"
}

response = requests.get(
    url=uri,
    headers=headers,
    auth=(username, password),
    verify=False)

print(json.dumps(response.json(), indent=2))

The Python script for retrieving VLAN information begins in a familiar fashion, setting up the necessary imports, disabling warnings, and configuring the credentials for accessing the switch. The target URI in this case points to the Restconf endpoint for VLAN operational data (Cisco-IOS-XE-vlan-oper:vlans/vlan). I did get this URL from the YANG suite as shown below.

After sending a GET request to the switch and receiving the response, the script prints out the JSON data. This data is nicely structured, making it easy to parse and understand, as opposed to the raw text output of traditional CLI commands.

c9300-test#show vlan

VLAN Name                             Status    Ports
---- -------------------------------- --------- -------------------------------
1    default                          active    Te1/0/1, Te1/0/2, Te1/0/3, Te1/0/4, Te1/0/6, Te1/0/7, Te1/0/8, Te1/0/9, Te1/0/10, Te1/0/12, Te1/0/13, Te1/0/15, Te1/0/16, Te1/0/17, Te1/0/18, Te1/0/19, Te1/0/21, Te1/0/22, Te1/0/23, Te1/0/24, Ap1/0/1
10   users                            active    Te1/0/5, Te1/0/14, Te1/0/20
20   servers                          active    Te1/0/11
1002 fddi-default                     act/unsup 
1003 token-ring-default               act/unsup 
1004 fddinet-default                  act/unsup 
1005 trnet-default                    act/unsup 

VLAN Type  SAID       MTU   Parent RingNo BridgeNo Stp  BrdgMode Trans1 Trans2
---- ----- ---------- ----- ------ ------ -------- ---- -------- ------ ------
1    enet  100001     1500  -      -      -        -    -        0      0   
10   enet  100010     1500  -      -      -        -    -        0      0   
20   enet  100020     1500  -      -      -        -    -        0      0   
1002 fddi  101002     1500  -      -      -        -    -        0      0   
1003 tr    101003     1500  -      -      -        -    -        0      0   
1004 fdnet 101004     1500  -      -      -        ieee -        0      0   
1005 trnet 101005     1500  -      -      -        ibm  -        0      0
#output

{
  "Cisco-IOS-XE-vlan-oper:vlan": [
    {
      "id": 1,
      "name": "default",
      "status": "active",
      "vlan-interfaces": [
        {
          "interface": "AppGigabitEthernet1/0/1",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/1",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/2",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/3",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/4",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/6",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/7",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/8",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/9",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/10",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/12",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/13",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/15",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/16",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/17",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/18",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/19",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/21",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/22",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/23",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/24",
          "subinterface": 0
        }
      ]
    },
    {
      "id": 10,
      "name": "users",
      "status": "active",
      "vlan-interfaces": [
        {
          "interface": "TenGigabitEthernet1/0/5",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/14",
          "subinterface": 0
        },
        {
          "interface": "TenGigabitEthernet1/0/20",
          "subinterface": 0
        }
      ]
    },
    {
      "id": 20,
      "name": "servers",
      "status": "active",
      "vlan-interfaces": [
        {
          "interface": "TenGigabitEthernet1/0/11",
          "subinterface": 0
        }
      ]
    },
    {
      "id": 1002,
      "name": "fddi-default",
      "status": "suspend"
    },
    {
      "id": 1003,
      "name": "token-ring-default",
      "status": "suspend"
    },
    {
      "id": 1004,
      "name": "fddinet-default",
      "status": "suspend"
    },
    {
      "id": 1005,
      "name": "trnet-default",
      "status": "suspend"
    }
  ]
}

The output provides detailed information about each VLAN, such as the VLAN ID (id), its name (name), and status (active or suspend). It also lists the interfaces associated with each VLAN under vlan-interfaces

This example highlights the importance of structured data in network management. With structured data, like the JSON output we see here, it becomes significantly easier to parse and work with the information programmatically.

Get Interface Stats

In this next example, we're going to see how Restconf can be used to gather comprehensive statistics for network interfaces, just like the show interface command on a switch. The beauty of using Restconf for this task lies in the structured format of the data it retrieves, which makes it far easier to work with programmatically.

When we run the script to fetch interface stats, it returns a wealth of information. This includes operational and administrative statuses, MAC addresses, and details on interface errors or discards. Essentially, you get all the vital stats that you would from the traditional CLI command, but in a JSON format that's much more manageable for data processing and automation tasks.

import requests
import json

requests.packages.urllib3.disable_warnings()

username = 'admin'
password = 'password'

uri = 'https://10.1.1.1:443/restconf/data/Cisco-IOS-XE-interfaces-oper:interfaces/interface'
headers = {
    "accept": "application/yang-data+json",
    "Content-Type": "application/yang-data+json"
}

response = requests.get(
    url=uri,
    headers=headers,
    auth=(username, password),
    verify=False)

with open ('interface.json', 'w') as w:
    w.write(json.dumps(response.json(), indent=2))

As an example, let's look at the output for a single interface. It provides a detailed snapshot of the interface's current state and performance metrics. This structured output simplifies the task of monitoring network health and troubleshooting issues.

#output

{
      "name": "TenGigabitEthernet1/0/11",
      "interface-type": "iana-iftype-ethernet-csmacd",
      "admin-status": "if-state-up",
      "oper-status": "if-oper-state-lower-layer-down",
      "last-change": "2023-09-12T13:55:23.759+00:00",
      "if-index": 19,
      "phys-address": "02:ad:87:14:27:0c",
      "speed": "10000000000",
      "statistics": {
        "discontinuity-time": "2023-09-12T13:52:57+00:00",
        "in-octets": "0",
        "in-unicast-pkts": "0",
        "in-broadcast-pkts": "0",
        "in-multicast-pkts": "0",
        "in-discards": 0,
        "in-errors": 0,
        "in-unknown-protos": 0,
        "out-octets": 0,
        "out-unicast-pkts": "0",
        "out-broadcast-pkts": "0",
        "out-multicast-pkts": "0",
        "out-discards": "0",
        "out-errors": "0",
        "rx-pps": "0",
        "rx-kbps": "0",
        "tx-pps": "0",
        "tx-kbps": "0",
        "num-flaps": "0",
        "in-crc-errors": "0",
        "in-discards-64": "0",
        "in-errors-64": "0",
        "in-unknown-protos-64": "0",
        "out-octets-64": "0"
      },
      "vrf": "",
      "ipv4": "0.0.0.0",
      "ipv4-subnet-mask": "0.0.0.0",
      "description": "",
      "mtu": 1500,
      "input-security-acl": "",
      "output-security-acl": "",
      "v4-protocol-stats": {
        "in-pkts": "0",
        "in-octets": "0",
        "in-error-pkts": "0",
        "in-forwarded-pkts": "0",
        "in-forwarded-octets": "0",
        "in-discarded-pkts": "0",
        "out-pkts": "0",
        "out-octets": "0",
        "out-error-pkts": "0",
        "out-forwarded-pkts": "0",
        "out-forwarded-octets": "0",
        "out-discarded-pkts": "0"
      },
      "v6-protocol-stats": {
        "in-pkts": "0",
        "in-octets": "0",
        "in-error-pkts": "0",
        "in-forwarded-pkts": "0",
        "in-forwarded-octets": "0",
        "in-discarded-pkts": "0",
        "out-pkts": "0",
        "out-octets": "0",
        "out-error-pkts": "0",
        "out-forwarded-pkts": "0",
        "out-forwarded-octets": "0",
        "out-discarded-pkts": "0"
      },
      "bia-address": "04:bd:97:41:17:0b",
      "ipv4-tcp-adjust-mss": 0,
      "ipv6-tcp-adjust-mss": 0,
      "intf-ext-state-support": [
        null
      ],
      "intf-ext-state": {
        "error-type": "port-error-none",
        "port-error-reason": "port-err-none",
        "auto-mdix-enabled": true,
        "mdix-oper-status-enabled": true,
        "fec-enabled": false,
        "mgig-downshift-enabled": false
      },
      "storm-control": {
        "broadcast": {
          "filter-state": "inactive"
        },
        "multicast": {
          "filter-state": "inactive"
        },
        "unicast": {
          "filter-state": "inactive"
        },
        "unknown-unicast": {
          "filter-state": "inactive"
        }
      },
      "auto-upstream-bandwidth": "0",
      "auto-downstream-bandwidth": "0",
      "ether-state": {
        "negotiated-duplex-mode": "auto-duplex",
        "negotiated-port-speed": "speed-auto",
        "auto-negotiate": true,
        "enable-flow-control": false,
        "media-type": "ether-media-type-rj45"
      },
      "ether-stats": {
        "in-mac-control-frames": "0",
        "in-mac-pause-frames": "0",
        "in-oversize-frames": "0",
        "in-jabber-frames": "0",
        "in-fragment-frames": "0",
        "in-8021q-frames": "0",
        "out-mac-control-frames": "0",
        "out-mac-pause-frames": "0",
        "out-8021q-frames": "0"
}

Closing thoughts

That brings us to the end of our exploration into using Cisco Restconf to fetch operational data. We've seen how it simplifies accessing crucial information like VLAN details and interface stats, presenting it in a structured, easy-to-handle format. This approach not only makes network management more efficient but also opens doors to more advanced automation possibilities.

Table of Contents
Written by
Suresh Vina
Tech enthusiast sharing Networking, Cloud & Automation insights. Join me in a welcoming space to learn & grow with simplicity and practicality.
Comments
More from Packetswitch
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Packetswitch.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.