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ライセンスの下でリリースされました。モジュールには、テンプレートといくつかの入力テキストが必要です。テンプレートでは、正規表現を使用してデータの解析方法を記述し、複数のテンプレートを定義して同じデータに適用できます。
TextFSMCliTableのクラスを使用すると、ユーザーは特定のプラットフォーム上のコマンドを、コマンド出力を解析するテンプレートにマップできます。ネットワーク自動化企業である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-templatesJunos PyEZサーバーまたは仮想環境にライブラリをインストールします。user@host:~$ pip3 install ntc_templates
、
key、platformuse_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_textfsmview、 引数、および操作に必要な追加の引数を含む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値を定義するplatformJunos PyEZテーブルを作成します。--- ArpTableTextFSM3: command: show arp no-resolve platform: my_platform key: - MAC - IP_ADDRESS use_textfsm: TrueJunos 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()))