Junos PyEZ テーブルと TextFSM テンプレートを使用する
概要 Junos PyEZ op テーブルは、それ自体で、または Junos PyEZ View と組み合わせて TextFSM テンプレートを参照して、任意のネットワーク デバイスからの CLI または VTY コマンド出力を解析できます。
TextFSM テンプレートについて
Junos PyEZ op テーブルを使用すると、CLI や VTY コマンドの出力からデータを抽出できます。表はビューを参照して、コマンド出力のフィールドを Python オブジェクトにマップできます。Junos PyEZ リリース 2.4.0 以降、Junos PyEZ op テーブルは、それ自体または View と組み合わせて TextFSM テンプレートを参照して、コマンド出力を解析することもできます。Junos PyEZ op テーブルでは、TextFSM テンプレートを使用して、ベンダー、ネットワーク オペレーティング システム、コマンドに関係なく、あらゆるネットワーク デバイスからのコマンド出力を解析できます。
TextFSM
は、ネットワーク デバイスからの show コマンド出力などの半フォーマット CLI 出力を解析する Python ライブラリです。これはGoogleによって開発され、その後Apache 2.0ライセンスでリリースされました。モジュールには、テンプレートと入力テキストが必要です。このテンプレートでは、正規表現を使用してデータを解析する方法を説明し、複数のテンプレートを定義して同じデータに適用できます。
TextFSM
'のクラスを使用すると、ユーザーは特定のCliTable
プラットフォーム上のコマンドを、コマンド出力を解析するテンプレートにマッピングできます。ネットワーク自動化会社 Network to Code は、ネットワーク デバイス用CliTable
の TextFSM テンプレートのリポジトリとともに、Python ラッパーを開発しました。Junos PyEZ サーバーまたは仮想環境に必要に応じてライブラリをインストールntc-templates
し、Junos PyEZ テーブル内の NTC テンプレートやその他の TextFSM テンプレートを参照できます。
NTC テンプレートは、ネットワーク デバイスからの show コマンド出力を解析します。各 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 op テーブルでは、NTC テンプレートやその他の TextFSM テンプレートを使用して、非構造化コマンドの出力を解析できます。表では、以下のフィールドを定義することで、TextFSM テンプレートを使用します。Junos PyEZ では、 および command
のplatform
値を使用してテンプレートのファイル名を指定します。
command: command
- 解析する出力を生成するコマンド。コマンドは、NTC テンプレートまたはその他の TextFSM テンプレートのファイル名内のコマンド文字列にマップする必要があります。key: key
— TextFSM テンプレートまたは Junos PyEZ ビューで定義されたフィールドで、レコード項目を一意に識別するために使用されます。platform: platform
— 例えばjuniper_junos
、TextFSM テンプレートのベンダーとオペレーティング システム。プラットフォーム値は、NTC テンプレートまたはその他の TextFSM テンプレートのファイル名内のプラットフォーム文字列と一致する必要があります。use_textfsm: True
—Junos PyEZ テーブルで、特定のプラットフォームとコマンドに対して TextFSM テンプレートを使用して、コマンド出力を解析する必要があることを示します。
TextFSM テンプレートを使用してコマンド出力を解析する方法
Junos PyEZ テーブルでは、定義済みの NTC テンプレートを含む TextFSM テンプレートを使用して、Junos デバイスからの show コマンド出力を解析できます。
Junos PyEZ テーブルで TextFSM テンプレートを使用するには、
ntc-templates
Junos PyEZ サーバーまたは仮想環境にライブラリをインストールします。user@host:~$ pip3 install ntc_templates
、 、
platform
、 引数、およびuse_textfsm
操作にcommand
key
必要な追加の引数を含むカスタム Junos PyEZ テーブルを作成します。--- ArpTableTextFSM: command: show arp no-resolve platform: juniper_junos key: MAC use_textfsm: True
Junos PyEZ アプリケーションでは、
platform
およびcommand
の値を使用してテンプレートのファイル名を指定します。この場合は 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 テンプレートを使用して出力フィールドを抽出します。テーブル項目ごとに、アプリケーションは、定義されたキーと各フィールドのデータを返します。
Junos PyEZ ビューを含む TextFSM テンプレートを使用してコマンド出力を解析する方法
Junos PyEZ テーブルでは、TextFSM テンプレートと Junos PyEZ ビューを組み合わせてコマンド出力を解析できます。TextFSM テンプレートは、データをヘッダーにマッピングします。ビューでは、変数名を、返すフィールドのテンプレートで定義された見出しにマップできます。これは、テンプレートで定義されたものとは異なる変数名を使用する場合や、異なるフィールドを返したい場合などに便利です。Junos PyEZ は、TextFSM テンプレートと Junos PyEZ ビューの両方に共通するフィールドのみを返します。
次の例では 、juniper_junos_show_arp_no-resolve.textfsm テンプレートを使用してコマンドの出力を解析します。Junos PyEZ ビューは、データを新しい変数名にマップし、フィールドのサブセットのみを返します。テンプレートを確認するには、 TextFSM テンプレートについてを参照してください。
Junos PyEZ テーブルで TextFSM テンプレートとビューを使用するには、
操作に必要な追加の引数と、 、
key
、platform
use_textfsm
view
引数を含むcommand
カスタム Junos PyEZ テーブルを作成します。--- 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
この場合、ビューは TextFSM テンプレートで定義されたフィールドをマップ
FLAGS
せず、解析されたデータにはこの値は含まれません。テーブルを使用してデータを取得する 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 テンプレートとビューを使用して出力フィールドを抽出します。アプリケーションは、表項目ごとに、定義されたキーと、ビューで定義された変数名にマップされたフィールドのデータを戻します。
カスタム TextFSM テンプレートの使用方法
Junos PyEZ テーブルは、パッケージの一部としてインストールされている TextFSM テンプレートを ntc-templates
使用することも、カスタム TextFSM テンプレートを参照することもできます。Junos PyEZ アプリケーションでカスタム TextFSM テンプレートを使用するには、テーブル インスタンスを定義するときにテンプレート ディレクトリへの絶対パスを指定する必要があります。
Junos PyEZ テーブルでカスタム TextFSM テンプレートを使用するには、
カスタム テンプレートのディレクトリを作成します。
user@host:~$ mkdir TextFSMTemplates
templates ディレクトリで、テンプレートを作成し、 .textfsm ファイル名表記規則を使用してファイルの名前をplatform_command付けます。
user@host:~$ vi TextFSMTemplates/my_platform_show_arp_no-resolve.textfsm
テンプレートファイル名と同じ
platform
値command
を定義するJunos PyEZテーブルを作成します。--- ArpTableTextFSM3: command: show arp no-resolve platform: my_platform key: - MAC - IP_ADDRESS use_textfsm: True
Junos PyEZ アプリケーションで、Table インスタンスを定義する際にカスタム テンプレート ディレクトリへの絶対パスを指定します。
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 Table インスタンスを作成する場合、インスタンスを渡す代わりに、コマンドの出力文字列を Table の 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 ...
次の例では、カスタム TextFSM テンプレート の cisco_xr_show_alarms_detail.textfsm と View を使用してコマンド出力を解析する Junos PyEZ テーブルを 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 テンプレートと View を使用して出力を解析します。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 View を使用していますが、この場合、コマンド出力はファイルから読み取られます。
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()))