TextFSMテンプレートでJunos PyEZテーブルを使用する
概要 Junos PyEZ op テーブルは、TextFSM テンプレートを単独で、または Junos PyEZ ビューと組み合わせて参照し、任意のネットワーク デバイスからの CLI または VTY コマンド出力を解析できます。
TextFSMテンプレートを理解する
Junos PyEZ op テーブルは、CLI または VTY コマンド出力からデータを抽出できます。テーブルはビューを参照して、コマンド出力のフィールドを Python オブジェクトにマップできます。Junos PyEZ リリース 2.4.0 以降、Junos PyEZ op テーブルは、TextFSM テンプレートを単独で、またはビューと組み合わせて参照し、コマンド出力を解析することもできます。Junos PyEZ op テーブルでは、TextFSM テンプレートを使用して、ベンダー、ネットワーク オペレーティング システム、コマンドに関係なく、任意のネットワーク デバイスからのコマンド出力を解析できます。
TextFSM
は、show コマンド出力などのセミフォーマットの CLI 出力をネットワーク デバイスから解析する Python ライブラリです。これはGoogleによって開発され、後にApache 2.0ライセンスの下でリリースされました。モジュールには、テンプレートといくつかの入力テキストが必要です。テンプレートでは、正規表現を使用してデータの解析方法を記述し、複数のテンプレートを定義して同じデータに適用できます。
TextFSM
CliTable
のクラスを使用すると、ユーザーは特定のプラットフォーム上のコマンドを、コマンド出力を解析するテンプレートにマップできます。ネットワーク自動化企業であるNetwork to Codeは、ネットワークデバイス用のTextFSMテンプレートのリポジトリとともに、用のPythonラッパーCliTable
を開発しました。必要に応じて、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は、 platform
および command
の値を使用してテンプレートのファイル名を決定します。
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テーブルでは、定義済みNTCテンプレートを含むTextFSMテンプレートを使用して、Junosデバイスからのshowコマンド出力を解析できます。
Junos PyEZテーブルでTextFSMテンプレートを使用するには、以下を行います。
ntc-templates
Junos PyEZサーバーまたは仮想環境にライブラリをインストールします。user@host:~$ pip3 install ntc_templates
、
key
、platform
use_textfsm
、 引数、および操作に必要な追加の引数を含むcommand
カスタム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 テンプレートとビューを使用して出力フィールドを抽出します。テーブル項目ごとに、アプリケーションは定義されたキーと、ビューで定義された変数名にマップされたフィールドのデータを返します。
カスタムテキストFSMテンプレートの使用方法
Junos PyEZ テーブルでは、パッケージの一部として ntc-templates
インストールされた TextFSM テンプレートを使用することも、カスタム TextFSM テンプレートを参照することもできます。Junos PyEZアプリケーションでカスタムTextFSMテンプレートを使用するには、テンプレートをステージングし、Tableインスタンスを定義する際にテンプレートディレクトリへの絶対パスを指定する必要があります。
Junos PyEZテーブルでカスタムTextFSMテンプレートを使用するには:
カスタムテンプレート用のディレクトリを作成します。
user@host:~$ mkdir TextFSMTemplates
テンプレートディレクトリで、テンプレートを作成し、.textfsm ファイル名のplatform_command規則を使用してファイルに名前を付けます。
user@host:~$ vi TextFSMTemplates/my_platform_show_arp_no-resolve.textfsm
テンプレートファイル名と同じ と
command
値を定義するplatform
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
TextFSMテンプレートを含むJunos PyEZテーブルを使用して、ベンダーのコマンド出力を解析する方法
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を使用する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 テンプレートを使用して出力が解析されます。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()))