In this article we will be talking about converting the output from Cisco XR into a Json File for further utilization or automation. The following code can be used and can be redesigned to work with several other commands and output in other variants of Cisco XE, XR etc., as well as other vendor devices.
Requirements:
> Python3
> Netmiko
> TextFSM
> Json
Netmiko library is one of the most useful libraries made. We can use this library with several other vendors as defined on this website: https://ktbyers.github.io/netmiko/docs/netmiko/index.html
TextFSM library is made by Google. It is a state machine which uses regular expression to parse the output in a template defined by us.
Json library is required so that we dump the data in the json format. json.loads
take a string as input and returns a dictionary as output. json.dumps
take a dictionary as input and returns a string as output.
Let’s start:
Make sure to pip install netmiko and textfsm before proceeding with the below code:
from netmiko import ConnectHandler import jtextfsm as textfsm import json IP="DEVICE IP" username="YOURUSERNAME" password="YOURPASS" port=[PORT NUMBER] dev=ConnectHandler(device_type='cisco_xr',ip=IP,username=username,password=password, port = port) output=dev.send_command("show bgp summary")
#****Template Parser code*********# template=open("showbgp.textfsm") re_t=textfsm.TextFSM(template) fsm_res=re_t.ParseText(output) print(fsm_res)
#********json Template code********# info={} data={"Neighbors":info} li=re_t.header #this will get the headings we got from our output with above regex.c=len(fsm_res) count=0 for i in fsm_res: count=count+1 id=count info[id]=dict(zip(li,i))
print(json.dumps(data,indent=4)) dev.disconnect() print('done')
The above code is pretty normal and neat, we are getting the output in the “output” variable for show bgp summary and we are putting it in textfsm format and getting a list of list output, then converting the Multi-list which is stored in “fsm_res” to json format.
The next most important thing is writing a regex to filter-out the output that we want. The creation of this regex textfsm file is very easy and for testing purpose you can also use https://regex101.com/ to see if you are filtering out the output that you actually want. Make Sure to put both the files in the same directory before running this.
file : showbgp.textfsm
Value Neighbor (\d+.\d+.\d+.\d+.) Value Spk (\d+) Value AS (\d+) Value MsgRcvd (\d+) Value MsgSent (\d+) Value TblVer (\d+) Value InQ (\d+) Value OutQ (\d+) Value up_down (\d+:\d+:\d+) Value St (\S+) Start ^${Neighbor}\s+${Spk}+\s+${AS}+\s+${MsgRcvd}\s+${MsgSent}+\s+${TblVer}+\s+${InQ}\s+${OutQ}+\s+${up_down}+\s+${St} -> Record EOF
Let’s go step by step to understand how we created this file:
The “Value” defines the variable name, now you can have anything defined under variable name, you can put the variable name anything you like. But here the most important part is the regex value that are defined after the variable. Example:
Value Neighbor (\d+.\d+.\d+.\d+.)
Value is a predefined Textfsm keyword which defines the variable and your regex.
Neighbor here is nothing but the variable name, which can be anything.
(\d+.\d+.\d+.\d+.) regex defines what type of information/value from the output, the Neighbor variable will carry. The regex (\d+.\d+.\d+.\d+.) means this is an IP address.
Now let’s look into the output that we are getting from the device and the output that we want:
BGP router identifier *.*.*.*, local AS number 198 BGP generic scan interval 60 secs Non-stop routing is enabled BGP table state: Active Table ID: 0xe0000000 RD version: 10 BGP main routing table version 10 BGP NSR Initial initsync version 9 (Reached) BGP NSR/ISSU Sync-Group versions 0/0 BGP scan interval 60 secs BGP is operating in STANDALONE mode. Process RcvTblVer bRIB/RIB LabelVer ImportVer SendTblVer StandbyVer Speaker 10 10 10 10 10 0 Some configured eBGP neighbors (under default or non-default vrfs) do not have both inbound and outbound policies configured for IPv4 Unicast address family. These neighbors will default to sending and/or receiving no routes and are marked with '!' in the output below. Use the 'show bgp neighbor <nbr_address>' command for details. Neighbor Spk AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down St/PfxRcd 10.10.20.20 0 13999 0 0 0 0 0 00:00:00 Idle! 192.168.1.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.2.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.3.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.4.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.5.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.6.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.7.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.8.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.9.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.10.2 0 199 0 0 0 0 0 00:00:00 Idle 192.168.11.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.12.2 0 199 0 0 0 0 0 00:00:00 Active 192.168.13.2 0 199 0 0 0 0 0 00:00:00 Active 198.0.0.1 0 198 0 0 0 0 0 00:00:00 Idle 198.18.58.54 0 22773 0 0 0 0 0 00:00:00 Idle 199.38.111.145 0 9644 6383 6383 0 0 0 3d09h Active
See we want output starting with first IP under Neighbor: Neighbor Spk AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down St/PfxRcd 10.10.20.20 0 13999 0 0 0 0 0 00:00:00 Idle! 192.168.1.2 0 199 0 0 0 0 0 00:00:00 Active ...
So to get the output from neighbor ip which is actually IP (10.10.20.20), we need to create a regex which could cover IP address uptill Idle! value and these values will be stored in the Variables you have defined under the regex like varibale Neighbor will carry IP address, Spk will carry 0 and so on…
The working regex in our scenario is:
^(\d+.\d+.\d+.\d+.)\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+:\d+:\d+)\s+(\S+)
Use the above regex on website regex101, the link given above to verify if you selecting the correct values that you want.
Now the variables that you have defined above with the regex will substitute the value in :
^${Neighbor}\s+${Spk}+\s+${AS}+\s+${MsgRcvd}\s+${MsgSent}+\s+${TblVer}+\s+${InQ}\s+${OutQ}+\s+${up_down}+\s+${St} -> Record
When the textfsm will read the file after the Start value is defined.
Any output can be filtered out using the regex that you will create and this data can be written in any format of your liking.
I hope you find the above article helpful while automating your network.