将 Junos PyEZ 表与 TextFSM 模板配合使用
总结 Junos PyEZ 操作表可以单独引用 TextFSM 模板,也可以与 Junos PyEZ 视图结合使用,以解析来自任何网络设备的 CLI 或 VTY 命令输出。
了解文本FSM 模板
Junos PyEZ 操作表可以从 CLI 或 VTY 命令输出中提取数据。该表可以引用视图以将命令输出中的字段映射到 Python 对象。从 Junos PyEZ 2.4.0 版开始,Junos PyEZ 操作表还可以单独引用 TextFSM 模板或与视图一起引用,以解析命令输出。Junos PyEZ 操作表可以使用 TextFSM 模板解析来自任何网络设备的命令输出,而与供应商、网络操作系统或命令无关。
TextFSM 是一个 Python 库,用于解析来自网络设备的半格式 CLI 输出,例如 show 命令输出。它由Google开发,后来在Apache 2.0许可下发布。该模块需要一个模板和一些输入文本。该模板使用正则表达式来描述如何解析数据,您可以定义多个模板并将其应用于同一数据。
TextFSMCliTable的类使用户能够将给定平台上的命令映射到分析命令输出的模板。Network to Code是一家网络自动化公司,它为网络设备开发了一个Python包装器CliTable以及一个TextFSM模板存储库。您可以根据需要在 Junos PyEZ 服务器或虚拟环境中安装ntc-templates库,然后在 Junos PyEZ 表中引用 NTC 模板和其他 TextFSM 模板。
NTC 模板解析显示网络设备的命令输出。每个 NTC 模板定义给定命令的预期输出字段,并为每个项目将数据映射到标头。NTC 模板文件名标识供应商、网络操作系统和命令(带下划线),因此系统可以轻松确定用于给定平台和命令的模板。
vendor_os_command.textfsm
例如,考虑 juniper_junos_show_arp_no-resolve.textfsm 模板。
Value Required MAC ([A-Fa-f0-9\:]{17})
Value Required IP_ADDRESS ([A-Fa-f0-9:\.]+)
Value Required INTERFACE (\S+)
Value FLAGS (\S+)
Start
^MAC\s+Address\s+Address\s+Interface\s+Flags\s*$$
^${MAC}\s+${IP_ADDRESS}\s+${INTERFACE}\s+${FLAGS} -> Record
^Total.*
^\s*$$
^{master:\d+}
^. -> Error
该模板解析 show arp no-resolve 来自瞻博网络 Junos 设备的命令输出。
user@host> show arp no-resolve MAC Address Address Interface Flags 02:01:00:00:00:05 10.0.0.5 em0.0 none 30:7c:5e:48:4b:40 198.51.100.77 fxp0.0 none f8:c0:01:18:8b:67 198.51.100.254 fxp0.0 none 02:00:00:00:00:10 128.0.0.50 em0.0 none Total entries: 4
Junos PyEZ 操作表可以使用 NTC 模板或其他 TextFSM 模板来解析非结构化命令输出。该表通过定义以下字段来使用 TextFSM 模板。Junos PyEZ 使用和command值来确定platform模板的文件名。
command: command- 生成要解析的输出的命令。该命令必须映射到 NTC 模板或其他 TextFSM 模板的文件名中的命令字符串。key: key- 在 TextFSM 模板或 Junos PyEZ 视图中定义的字段,用于唯一标识记录项。platform: platform- TextFSM 模板的供应商和操作系统,例如juniper_junos。平台值必须与 NTC 模板或其他 TextFSM 模板的文件名中的平台字符串匹配。use_textfsm: True— 指示 Junos PyEZ 表应使用给定平台和命令的 TextFSM 模板解析命令输出。
如何使用 TextFSM 模板解析命令输出
Junos PyEZ 表可以使用 TextFSM 模板(包括预定义的 NTC 模板)来解析来自 Junos 设备的 show 命令输出。
要在 Junos PyEZ 表中使用 TextFSM 模板,请执行以下操作:
ntc-templates在 Junos PyEZ 服务器或虚拟环境中安装库。user@host:~$ pip3 install ntc_templates
创建自定义 Junos PyEZ 表,其中包含
command、key、platform和use_textfsm参数,以及操作所需的任何其他参数。--- ArpTableTextFSM: command: show arp no-resolve platform: juniper_junos key: MAC use_textfsm: True
Junos PyEZ 应用程序使用 and
platformcommand值来确定模板的文件名,在本例中为 juniper_junos_show_arp_no-resolve.textfsm。创建一个使用该表检索数据的 Junos PyEZ 应用程序。
from jnpr.junos import Device from jnpr.junos.factory.factory_loader import FactoryLoader from pprint import pprint import json import yaml import yamlordereddictloader yaml_table = """ --- ArpTableTextFSM: command: show arp no-resolve platform: juniper_junos key: MAC use_textfsm: True """ globals().update(FactoryLoader().load(yaml.load(yaml_table, Loader=yamlordereddictloader.Loader))) with Device(host='router1.example.net') as dev: arp_stats = ArpTableTextFSM(dev).get() pprint(json.loads(arp_stats.to_json()))
执行应用程序。
user@host:~$ python3 junos-pyez-arptable-textfsm.py {'02:00:00:00:00:10': {'FLAGS': 'none', 'INTERFACE': 'em0.0', 'IP_ADDRESS': '128.0.0.50'}, '02:01:00:00:00:05': {'FLAGS': 'none', 'INTERFACE': 'em0.0', 'IP_ADDRESS': '10.0.0.5'}, '30:7c:5e:48:4b:40': {'FLAGS': 'none', 'INTERFACE': 'fxp0.0', 'IP_ADDRESS': '198.51.100.77'}, 'f8:c0:01:18:8b:67': {'FLAGS': 'none', 'INTERFACE': 'fxp0.0', 'IP_ADDRESS': '198.51.100.254'}}该表使用 NTC 模板提取输出字段。对于每个表项,应用程序返回定义的键和每个字段的数据。
如何将 TextFSM 模板与 Junos PyEZ 视图配合使用来解析命令输出
Junos PyEZ 表可以组合 TextFSM 模板和 Junos PyEZ 视图来解析命令输出。文本FSM 模板将数据映射到标头。在视图中,您可以将变量名称映射到模板中为要返回的字段定义的标题。这很有用,例如,当您想要使用与模板中定义的变量名称不同的变量名称时,或者当您想要返回不同的字段时。Junos PyEZ 仅返回 TextFSM 模板和 Junos PyEZ 视图通用的字段。
下面的示例使用 juniper_junos_show_arp_no-resolve.textfsm 模板来分析命令输出。Junos PyEZ 视图将数据映射到新的变量名称,并且仅返回字段的子集。若要查看模板,请参阅 了解 TextFSM 模板。
要使用 TextFSM 模板和 Junos PyEZ 表中的视图,请执行以下操作:
创建自定义 Junos PyEZ 表,其中包含
command、key、use_textfsmplatform和view参数,以及操作所需的任何其他参数。--- ArpTableTextFSM2: command: show arp no-resolve platform: juniper_junos key: - ip - mac use_textfsm: True view: ArpViewTextFSM2创建 Junos PyEZ 视图,用于定义要返回的模板字段以及每个字段的相应变量名称。
ArpViewTextFSM2: fields: mac: MAC ip: IP_ADDRESS interface: INTERFACE在这种情况下,视图不会映射
FLAGSTextFSM 模板中定义的字段,并且分析的数据不包括此值。创建一个使用该表检索数据的 Junos PyEZ 应用程序。
from jnpr.junos import Device from jnpr.junos.factory.factory_loader import FactoryLoader from pprint import pprint import json import yaml import yamlordereddictloader yaml_table = """ --- ArpTableTextFSM2: command: show arp no-resolve platform: juniper_junos key: - ip - mac use_textfsm: True view: ArpViewTextFSM2 ArpViewTextFSM2: fields: mac: MAC ip: IP_ADDRESS interface: INTERFACE """ globals().update(FactoryLoader().load(yaml.load(yaml_table, Loader=yamlordereddictloader.Loader))) with Device(host='router1.example.net') as dev: arp_stats = ArpTableTextFSM2(dev).get() pprint(json.loads(arp_stats.to_json()))
执行应用程序。
user@host:~$ python3 junos-pyez-arptable-textfsm2.py {"('10.0.0.5', '02:01:00:00:00:05')": {'interface': 'em0.0', 'ip': '10.0.0.5', 'mac': '02:01:00:00:00:05'}, "('128.0.0.50', '02:00:00:00:00:10')": {'interface': 'em0.0', 'ip': '128.0.0.50', 'mac': '02:00:00:00:00:10'}, "('198.51.100.254', 'f8:c0:01:18:8b:67')": {'interface': 'fxp0.0', 'ip': '198.51.100.254', 'mac': 'f8:c0:01:18:8b:67'}, "('198.51.100.77', '30:7c:5e:48:4b:40')": {'interface': 'fxp0.0', 'ip': '198.51.100.77', 'mac': '30:7c:5e:48:4b:40'}}该表使用 NTC 模板和视图提取输出字段。对于每个表项,应用程序返回定义的键和映射到视图中定义的变量名称的字段的数据。
如何使用自定义文本FSM模板
Junos PyEZ 表可以使用作为程序包的一部分 ntc-templates 安装的 TextFSM 模板,也可以引用自定义 TextFSM 模板。要在 Junos PyEZ 应用程序中使用自定义 TextFSM 模板,必须暂存模板,然后在定义表实例时指定模板目录的绝对路径。
要在 Junos PyEZ 表中使用自定义 TextFSM 模板,请执行以下操作:
为自定义模板创建目录。
user@host:~$ mkdir TextFSMTemplates
在模板目录中,创建模板并使用 .textfsm 文件名约定命名platform_command文件。
user@host:~$ vi TextFSMTemplates/my_platform_show_arp_no-resolve.textfsm
创建一个 Junos PyEZ 表,该表定义与模板文件名相同的
platformcommand值。--- ArpTableTextFSM3: command: show arp no-resolve platform: my_platform key: - MAC - IP_ADDRESS use_textfsm: True在 Junos PyEZ 应用程序中,在定义表实例时指定自定义模板目录的绝对路径。
from jnpr.junos import Device from jnpr.junos.factory.factory_loader import FactoryLoader from pprint import pprint import json import yaml import yamlordereddictloader yaml_table = """ --- ArpTableTextFSM3: command: show arp no-resolve platform: my_platform key: - MAC - IP_ADDRESS use_textfsm: True """ globals().update(FactoryLoader().load(yaml.load(yaml_table, Loader=yamlordereddictloader.Loader))) with Device(host='router1.example.net') as dev: arp_stats = ArpTableTextFSM3(dev, template_dir='/home/user/TextFSMTemplates').get() pprint(json.loads(arp_stats.to_json()))
执行应用程序。
user@host:~$ python3 junos-pyez-arptable-textfsm3.py
如何将 Junos PyEZ 表与 TextFSM 模板一起使用来解析任何供应商的命令输出
Junos PyEZ 表可以使用 TextFSM 模板来解析来自任何供应商网络设备的命令输出。您可以在 Python 应用程序中检索输出,也可以从文件中读取输出。然后,在创建 Junos PyEZ 表实例时,可以将命令输出字符串传递给表的 raw 参数,而不是传入 Device 实例。
例如,请考虑以下 TextFSM 模板:
user@host:~$ cat TextFSMTemplates/cisco_xr_show_alarms_detail.textfsm
Value Required description (.+?)
Value Required location (\S+)
Value aid (\S+)
Value tag (\S+)
Value module (\S+)
Start
# Match the timestamp at beginning of command output
^Active Alarms (Detail) for .+
^-+ -> Continue.Record
^Description:\s+${description}\s*$$
^Location:\s+${location}
^AID:\s+${aid}
^Tag String:\s+${tag}
^Module Name:\s+${module}
该模板分析 show alarms detail 来自给定设备的命令输出。
RP/0/RP0/CPU0:host#show alarms detail Wed May 5 12:17:00.187 UTC -------------------------------------------------------------------------------- Active Alarms (Detail) for 0/RP0 -------------------------------------------------------------------------------- Description: hw_optics: RX LOS LANE-0 ALARM Location: 0/RP0/CPU0 AID: XR/HW_OPTICS/5 Tag String: DEV_SFP_OPTICS_PORT_RX_LOS_LANE0 Module Name: Optics0/0/0/31 EID: CHASSIS/LCC/1:CONTAINER/CC/1:PORT/OPTICS/31 Reporting Agent ID: 196713 Pending Sync: false Severity: Major Status: Set Group: Software Set Time: 04/27/2021 09:47:16 UTC Clear Time: - Service Affecting: NotServiceAffecting Transport Direction: NotSpecified Transport Source: NotSpecified Interface: N/A Alarm Name: OPTICS RX LOS LANE-0 -------------------------------------------------------------------------------- Description: hw_optics: RX LOS LANE-1 ALARM Location: 0/RP0/CPU0 AID: XR/HW_OPTICS/6 Tag String: DEV_SFP_OPTICS_PORT_RX_LOS_LANE1 Module Name: Optics0/0/0/31 EID: CHASSIS/LCC/1:CONTAINER/CC/1:PORT/OPTICS/31 Reporting Agent ID: 196713 Pending Sync: false Severity: Major Status: Set Group: Software Set Time: 04/27/2021 09:47:16 UTC Clear Time: - Service Affecting: NotServiceAffecting Transport Direction: NotSpecified Transport Source: NotSpecified Interface: N/A Alarm Name: OPTICS RX LOS LANE-1 ...
以下示例定义了一个 Junos PyEZ 表,该表使用自定义 TextFSM 模板 cisco_xr_show_alarms_detail.textfsm,并结合视图来分析 show alarms detail 命令输出。该示例使用该库直接从 netmiko 设备检索数据。当应用程序创建 Table 实例时, raw 参数传入命令输出,并且参数 template_dir 定义包含自定义模板的目录的路径。
from netmiko import ConnectHandler
from jnpr.junos.factory.factory_loader import FactoryLoader
from pprint import pprint
import json
import yaml
import yamlordereddictloader
yaml_table = """
---
XRAlarmsTable:
command: show alarms detail
key:
- description
- location
platform: cisco_xr
use_textfsm: True
view: XRAlarmsView
XRAlarmsView:
fields:
description: description
location: location
aid: aid
tag: tag
module: module
severity: severity
status: status
group: group
time: time
affect: affect
"""
dev_credentials = {
'device_type': 'cisco_xr',
'host': '198.51.100.101',
'username': 'admin',
'password': 'password',
}
net_connect = ConnectHandler(**dev_credentials)
output = net_connect.send_command('show alarms detail')
globals().update(FactoryLoader().load(yaml.load(yaml_table, Loader=yamlordereddictloader.Loader)))
stats = XRAlarmsTable(raw=output, template_dir='/home/user/TextFSMTemplates').get()
pprint(json.loads(stats.to_json()))
with open('show-alarms-detail.txt', 'w') as fp:
fp.write(output)
执行应用程序时,它会从设备检索命令输出,并使用指定目录中的 TextFSM 模板和视图来分析输出。Junos PyEZ 仅返回 TextFSM 模板和 Junos PyEZ 视图通用的字段。应用程序还将命令输出保存到文件中,以便稍后可以处理输出,如下例所示。
user@host:~$ python3 junos-pyez-textfsm-alarms.py
{"('hw_optics: RX LOL LANE-0 ALARM', '0/RP0/CPU0')": {'aid': 'XR/HW_OPTICS/29',
'description': 'hw_optics: '
'RX LOL '
'LANE-0 '
'ALARM',
'location': '0/RP0/CPU0',
'module': 'Optics0/0/0/31',
'tag': 'DEV_SFP_OPTICS_PORT_RX_CDR_LOL_LANE0'},
"('hw_optics: RX LOL LANE-1 ALARM', '0/RP0/CPU0')": {'aid': 'XR/HW_OPTICS/30',
'description': 'hw_optics: '
'RX LOL '
'LANE-1 '
'ALARM',
'location': '0/RP0/CPU0',
'module': 'Optics0/0/0/31',
'tag': 'DEV_SFP_OPTICS_PORT_RX_CDR_LOL_LANE1'},
...
以下示例使用与上一示例相同的 TextFSM 模板和 Junos PyEZ 视图,但在本例中,命令输出是从文件中读取的。
from jnpr.junos.factory.factory_loader import FactoryLoader
from pprint import pprint
import json
import yaml
import yamlordereddictloader
yaml_table = """
---
XRAlarmsTable:
command: show alarms detail
key:
- description
- location
platform: cisco_xr
use_textfsm: True
view: XRAlarmsView
XRAlarmsView:
fields:
description: description
location: location
aid: aid
tag: tag
module: module
severity: severity
status: status
group: group
time: time
affect: affect
"""
with open('show-alarms-detail.txt') as fp:
output = fp.read()
globals().update(FactoryLoader().load(yaml.load(yaml_table, Loader=yamlordereddictloader.Loader)))
stats = XRAlarmsTable(raw=output, template_dir='/home/user/TextFSMTemplates').get()
pprint(json.loads(stats.to_json()))