TextFSMテンプレートでJunos PyEZテーブルを使用する
Junos PyEZ運用(op)テーブルは、単独で、またはJunos PyEZビューと一緒にTextFSMテンプレートを参照して、任意のネットワークデバイスからのCLIまたはVTYコマンド出力を解析できます。
TextFSMテンプレートを理解する
Junos PyEZ opテーブルは、ネットワークデバイスのCLIまたはVTYコマンド出力からデータを抽出することができます。テーブルは、ビューを参照して、コマンド出力のフィールドをPythonオブジェクトにマップできます。Junos PyEZ opテーブルは、単独で、またはビューとともにTextFSMテンプレートを参照して、コマンド出力を解析することもできます。Junos PyEZ opテーブルでは、TextFSMテンプレートを使用して、ベンダー、ネットワークOS、コマンドに関係なく、あらゆるネットワークデバイスからのコマンド出力を解析できます。
TextFSM は、ネットワークデバイスからの半フォーマットされたCLI出力(showコマンド出力など)を解析するPythonライブラリです。Google によって開発され、後に Apache 2.0 ライセンスでリリースされました。このモジュールには、テンプレートといくつかの入力テキストが必要です。テンプレートでは、正規表現を使用してデータの解析方法を記述しており、同じデータに対して複数のテンプレートを定義して適用できます。
TextFSMのCliTableクラスを使用すると、ユーザーは特定のプラットフォーム上のコマンドを、コマンド出力を解析するテンプレートにマッピングできます。ネットワーク自動化企業であるNetwork to Codeは、ネットワークデバイス用のTextFSMテンプレートのリポジトリとともに、CliTable用のPythonラッパーを開発しました。必要に応じて、Junos PyEZサーバーまたは仮想環境にntc-templatesライブラリをインストールできます。次に、Junos PyEZテーブルでNTCテンプレートと他のTextFSMテンプレートを参照します。
NTCテンプレートは、ネットワークデバイスからのshowコマンド出力を解析します。各NTCテンプレートは、特定のコマンドに予期される出力フィールドを定義し、各項目について、データをヘッダーにマッピングします。NTCテンプレートのファイル名は、プラットフォーム(ベンダーとネットワークOS)とコマンド(アンダースコア付き)を識別するため、システムは使用するテンプレートを簡単に判断できます。ファイル名の形式では、次の構文を使用します。
platform_command.textfsm
たとえば、 juniper_junos_show_arp_no-resolve.textfsm テンプレートについて考えてみましょう。
Value Required MAC_ADDRESS ([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_ADDRESS}\s+${IP_ADDRESS}\s+${INTERFACE}\s+${FLAGS} -> Record
^Total.*
^\s*$$
^{master:\d+}
^. -> Error
テンプレートは、Junos OSまたはJunos OS Evolvedを実行しているジュニパーネットワークスデバイスからの show arp no-resolve コマンド出力を解析します。
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 172.16.0.50 em0.0 none Total entries: 4
Junos PyEZ opテーブルでは、NTCテンプレートまたはその他のTextFSMテンプレートを使用して、非構造化コマンド出力を解析できます。この表では、次のフィールドを定義することで TextFSM テンプレートを使用します。Junos PyEZ は、 platform 値と command 値を使用してテンプレートのファイル名を決定します。
-
command: command- 解析する出力を生成するコマンド。コマンドは、NTCテンプレートまたはその他のTextFSMテンプレートのファイル名内のコマンド文字列にマップする必要があります。 -
key: key—TextFSMテンプレートまたはJunos PyEZビューで定義されたフィールドで、レコードアイテムを一意に識別するために使用されるフィールド。 -
platform: platform—TextFSMテンプレートのベンダーとOS(例:juniper_junos)。プラットフォーム値は、NTCテンプレートまたはその他のTextFSMテンプレートのファイル名にあるプラットフォーム文字列と一致する必要があります。 -
use_textfsm: True—Trueに設定すると、指定されたプラットフォームとコマンドのTextFSMテンプレートを使用してコマンド出力を解析します。
TextFSM テンプレートを使用してコマンド出力を解析する方法
Junos PyEZテーブルでは、定義済みのNTCテンプレートを含むTextFSMテンプレートを使用して、Junosデバイスからのshowコマンド出力を解析できます。
Junos PyEZ テーブルで TextFSM テンプレートを使用するには:
-
Junos PyEZサーバーまたは仮想環境に
ntc-templatesライブラリをインストールします。user@host:~$ pip install ntc-templates
-
command、key、platform、use_textfsm引数、および操作に必要な追加引数を含むカスタムJunos PyEZ テーブルを作成します。--- ArpTableTextFSM: command: show arp no-resolve platform: juniper_junos key: MAC_ADDRESS use_textfsm: True
Junos PyEZアプリケーションは、
platform値とcommand値を使用してテンプレートのファイル名(この場合は juniper_junos_show_arp_no-resolve.textfsm)を決定します。key値はテンプレートのヘッダーと一致する必要があります。 -
テーブルを使用してデータを取得する Junos PyEZ アプリケーションを作成します。
import json from pprint import pprint import yaml from yamlloader import ordereddict from jnpr.junos import Device from jnpr.junos.factory.factory_loader import FactoryLoader yaml_table = """ --- ArpTableTextFSM: command: show arp no-resolve platform: juniper_junos key: MAC_ADDRESS use_textfsm: True """ globals().update(FactoryLoader().load(yaml.load(yaml_table, Loader=ordereddict.Loader))) with Device(host='router1.example.net') as dev: arp_stats = ArpTableTextFSM(dev).get() pprint(json.loads(arp_stats.to_json()))
-
アプリケーションを実行します。
user@host:~$ python junos-pyez-arptable-textfsm.py {'02:00:00:00:00:10': {'FLAGS': 'none', 'INTERFACE': 'em0.0', 'IP_ADDRESS': '172.16.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 テンプレートについて」を参照してください。
TextFSMテンプレートとJunos PyEZテーブルのビューを使用するには:
-
command、key、platform、use_textfsm、view引数、および操作に必要な追加引数を含むカスタム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_ADDRESS ip: IP_ADDRESS interface: INTERFACEこの場合、ビューは TextFSM テンプレートで定義された
FLAGSフィールドをマップせず、解析されたデータにはこの値が含まれません。 -
テーブルを使用してデータを取得する Junos PyEZ アプリケーションを作成します。
import json from pprint import pprint import yaml from yamlloader import ordereddict from jnpr.junos import Device from jnpr.junos.factory.factory_loader import FactoryLoader yaml_table = """ --- ArpTableTextFSM2: command: show arp no-resolve platform: juniper_junos key: - ip - mac use_textfsm: True view: ArpViewTextFSM2 ArpViewTextFSM2: fields: mac: MAC_ADDRESS ip: IP_ADDRESS interface: INTERFACE """ globals().update(FactoryLoader().load(yaml.load(yaml_table, Loader=ordereddict.Loader))) with Device(host='router1.example.net') as dev: arp_stats = ArpTableTextFSM2(dev).get() pprint(json.loads(arp_stats.to_json()))
-
アプリケーションを実行します。
user@host:~$ python 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'}, "('172.16.0.50', '02:00:00:00:00:10')": {'interface': 'em0.0', 'ip': '172.16.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テンプレートとJunos PyEZビューを使用して出力フィールドを抽出しています。テーブルアイテムごとに、アプリケーションは定義されたキーとビューで定義されたフィールドのデータを返します。
カスタムTextFSMテンプレートの使用方法
Junos PyEZ テーブルでは、 ntc-templates パッケージの一部としてインストールされている TextFSM テンプレートを使用できます。また、カスタム TextFSM テンプレートを参照することもできます。Junos PyEZ アプリケーションでカスタム TextFSM テンプレートを使用するには、まずテンプレートをステージングする必要があります。次に、アプリケーションでテーブルインスタンスを定義するときに、テンプレートディレクトリへの絶対パスを指定します。
Junos PyEZテーブルでカスタムTextFSMテンプレートを使用するには:
-
カスタムテンプレートのディレクトリを作成します。
user@host:~$ mkdir TextFSMTemplates
-
templatesディレクトリでテンプレートを作成し、 platform_command.textfsm ファイル名の規則を使用してファイルに名前を付けます。
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_ADDRESS - IP_ADDRESS use_textfsm: True -
Junos PyEZアプリケーションで、テーブルインスタンスを定義する際にカスタムテンプレートディレクトリへの絶対パスを指定します。
import json from pprint import pprint import yaml from yamlloader import ordereddict from jnpr.junos import Device from jnpr.junos.factory.factory_loader import FactoryLoader yaml_table = """ --- ArpTableTextFSM3: command: show arp no-resolve platform: my_platform key: - MAC_ADDRESS - IP_ADDRESS use_textfsm: True """ globals().update(FactoryLoader().load(yaml.load(yaml_table, Loader=ordereddict.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:~$ python junos-pyez-arptable-textfsm3.py
Junos PyEZテーブルとTextFSMテンプレートを使用して、ベンダーのコマンド出力を解析する方法
Junos PyEZテーブルでは、TextFSMテンプレートを使用して、あらゆるベンダーのネットワークデバイスからのコマンド出力を解析できます。Python アプリケーションは、デバイスから出力を取得するか、ファイルから出力を読み取ることができます。次に、Junos PyEZ Tableインスタンスを作成するときに、Deviceインスタンスを渡す代わりに、コマンド出力文字列をTableのraw引数に渡すことができます。
たとえば、次の 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 の両方を使用して show alarms detail コマンド出力を解析するJunos PyEZ テーブルを定義します。この例では、 netmiko ライブラリを使用して、デバイスから直接データを取得します。アプリケーションが Table インスタンスを作成すると、 raw 引数がコマンド出力に渡され、 template_dir 引数はカスタム テンプレートを含むディレクトリへのパスを定義します。
import json from pprint import pprint import yaml from yamlloader import ordereddict from netmiko import ConnectHandler from jnpr.junos.factory.factory_loader import FactoryLoader 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=ordereddict.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:~$ python 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 ビューを使用していますが、この場合、アプリケーションはファイルからコマンド出力を読み取ります。
import json from pprint import pprint import yaml from yamlloader import ordereddict from jnpr.junos.factory.factory_loader import FactoryLoader 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=ordereddict.Loader))) stats = XRAlarmsTable(raw=output, template_dir='/home/user/TextFSMTemplates').get() pprint(json.loads(stats.to_json()))