0

I am trying to create a textfsm template for command of a Cisco switch. the command is show platform. This command doesn't have a predefined template in ntc-templates. The CLI command output (Serials and MAC addresses are fake):

Switch  Ports    Model                Serial No.   MAC address     Hw Ver.       Sw Ver.
------  -----   ---------             -----------  --------------  -------       --------
 1       32     C9200-24P             2FCYCZBVY4R  df68.ebfc.44bb  V01           17.03.03
 2       32     C9200-24P             PW73B4U6UVW  982a.7043.0b7f  V01           17.03.03
 3       32     C9200-24P             PRJ5QKQE73S  3b9f.390b.04d2  V01           17.03.03
Switch/Stack Mac Address : df68.ebfc.44bb - Local Mac Address
Mac persistency wait time: Indefinite
                                   Current
Switch#   Role        Priority      State
-------------------------------------------
*1       Active          15         Ready
 2       Standby         14         Ready
 3       Member          13         Ready

My Python try is as follows:

import textfsm

plat = """
Switch  Ports    Model                Serial No.   MAC address     Hw Ver.       Sw Ver.
------  -----   ---------             -----------  --------------  -------       --------
 1       32     C9200-24P             2FCYCZBVY4R  df68.ebfc.44bb  V01           17.03.03
 2       32     C9200-24P             PW73B4U6UVW  982a.7043.0b7f  V01           17.03.03
 3       32     C9200-24P             PRJ5QKQE73S  3b9f.390b.04d2  V01           17.03.03
Switch/Stack Mac Address : df68.ebfc.44bb - Local Mac Address
Mac persistency wait time: Indefinite
                                   Current
Switch#   Role        Priority      State
-------------------------------------------
*1       Active          15         Ready
 2       Standby         14         Ready
 3       Member          13         Ready
"""

with open("plat.textfsm") as template:
    fsm = textfsm.TextFSM(template)
    result = fsm.ParseText(plat)

print(fsm.header)
print(result)

and the plat.textfsm template file

Value SWITCH ([1-8])
Value PORTS (\d+)
Value MODEL (\S+|\S+\d\S+)
Value SERIAL (\S+)
Value MAC ([0-9a-f]{4}\.[0-9a-f]{4}\.[0-9a-f]{4})
Value HARDWARE (\S+)
Value VERSION (\S+)
Value ROLE (Active|Standby|Member)
Value PRIORITY ([1-9]|1[0-5])
Value STATE (\S+)

Start
  ^.${SWITCH}\s+${PORTS}\s+${MODEL}\s+${SERIAL}\s+${MAC}\s+${HARDWARE}\s+${VERSION} -> Stack
  
Stack
  ^.*${ROLE}\s+${PRIORITY}\s+${STATE} -> Record

The output I get so far is:

['SWITCH', 'PORTS', 'MODEL', 'SERIAL', 'MAC', 'HARDWARE', 'VERSION', 'ROLE', 'PRIORITY', 'STATE']
[['1', '32', 'C9200-24P', '2FCYCZBVY4R', 'df68.ebfc.44bb', 'V01', '17.03.03', 'Active', '15', 'Ready'], 
['', '', '', '', '', '', '', 'Standby', '14', 'Ready'], 
['', '', '', '', '', '', '', 'Member', '13', 'Ready']]

I want to add Role, Priority, Current State to each list in the output like:

['SWITCH', 'PORTS', 'MODEL', 'SERIAL', 'MAC', 'HARDWARE', 'VERSION', 'ROLE', 'PRIORITY', 'STATE']
[['1', '32', 'C9200-24P', '2FCYCZBVY4R', 'df68.ebfc.44bb', 'V01', '17.03.03', 'Active', '15', 'Ready'],
['2', '32', 'C9200-24P', 'PW73B4U6UVW', '982a.7043.0b7f', 'V01', '17.03.03', 'Standby', '14', 'Ready'],
['3', '32', 'C9200-24P', 'PRJ5QKQE73S', '3b9f.390b.04d2', 'V01', '17.03.03', 'Member', '13', 'Ready']]

How can I edit the textfsm template to do this using the provided command output? What am I missing to get the correct output?

Tes3awy
  • 2,166
  • 5
  • 29
  • 51

1 Answers1

0

From my understanding, using textfsm, it might not be possible to get every data from your output. Because structure of the data can be changed by release or product. ** TextFSM is a Python module that implements a template based state machine for parsing semi-formatted text. Originally developed to allow programmatic access to information given by the output of CLI driven devices, such as network routers and switches, it can however be used for any such textual output.

The engine takes two inputs - a template file, and text input (such as command responses from the CLI of a device) and returns a list of records that contains the data parsed from the text.

A template file is needed for each uniquely structured text input. Some examples are provided with the code and users are encouraged to develop their own.

By developing a pool of template files, scripts can call textFSM to parse useful information from a variety of sources. It is also possible to use different templates on the same data, in order to create different tables (or views). **

What I can recommend in this point to create your own template using TTP (Template Text Parser) for parsing, so that you can get data as per your requirements.

Please see the following template and codes I have written to capture data you need from show platform output:

from ttp import ttp
import json

data_to_parse = """
Switch  Ports    Model                Serial No.   MAC address     Hw Ver.       Sw Ver.
------  -----   ---------             -----------  --------------  -------       --------
 1       32     C9200-24P             2FCYCZBVY4R  df68.ebfc.44bb  V01           17.03.03
 2       32     C9200-24P             PW73B4U6UVW  982a.7043.0b7f  V01           17.03.03
 3       32     C9200-24P             PRJ5QKQE73S  3b9f.390b.04d2  V01           17.03.03
Switch/Stack Mac Address : df68.ebfc.44bb - Local Mac Address
Mac persistency wait time: Indefinite
                                   Current
Switch#   Role        Priority      State
-------------------------------------------
*1       Active          15         Ready
 2       Standby         14         Ready
 3       Member          13         Ready
"""

template = """
<group name="SHOW_PLATFORM">
*{{switch_id|DIGIT}}       {{Role}}          {{Priority|DIGIT}}         {{Current_State}}
</group>
<group name="SHOW_PLATFORM">
 {{switch_id|DIGIT}}       {{Role}}         {{Priority|DIGIT}}         {{Current_State}}
</group>
"""

def show_platform(data_to_parse):
    ttp_template = template

    parser = ttp(data=data_to_parse, template=ttp_template)
    parser.parse()

    # print result in JSON format
    results = parser.result(format='json')[0]
    #print(results)

    #converting str to json. 
    result = json.loads(results)

    return(result)

print(show_platform(data_to_parse))

Find the output as below:

[{'SHOW_PLATFORM': [{'Current_State': 'Ready', 'Priority': '15', 'Role': 'Active', 'switch_id': '1'}, {'Current_State': 'Ready', 'Priority': '14', 'Role': 'Standby', 'switch_id': '2'}, {'Current_State': 'Ready', 'Priority': '13', 'Role': 'Member', 'switch_id': '3'}]}]

enter image description here

Baris Ozensel
  • 433
  • 1
  • 3
  • 11