LoginSignup
13
14

More than 3 years have passed since last update.

Genie Parser/OpsによるCisco機器のログ取得・構文解析

Last updated at Posted at 2019-07-13

はじめに

Ciscoが公開しているPythonベースのテストフレームワーク/フィーチャーライブラリー「pyATS/Genie」の内、Genie ParserとOpsを使ってみた結果をメモしておきます。

1-1. Genie Parserとは

NW機器のshowコマンド結果を構文解析し、テキストデータを「xの値はy」のようにプログラムが扱いやすい形式に変換します。2019年7月時点で1000を超えるパーサーが存在し、Cisco IOS、IOS-XE、IOS-XR、NX-OS、ASA、Junosの各種showコマンドに対応しています。

参考URL:
Parser一覧
GitHub - genieparser

1-2. Pythonコード例

Python環境のセットアップは前回の記事を参照願います。(Testbedも用意する必要あり。)
以下はCisco CSR1000Vのshow interfaces GigabitEthernet1をパースする例です。

genie8-1.py
from genie.conf import Genie
from pprint import pprint

testbed = Genie.init('testbed_devnet3.yaml')   # Testbedを指定
device = testbed.devices['csr1000v-1']   # ホスト名を指定

device.connect()

output = device.parse('show interfaces GigabitEthernet1')
pprint(output)

1-3. 実行結果

$ python genie8-1.py
# 途中の実行ログは省略
{'GigabitEthernet1': {'arp_timeout': '04:00:00',
                      'arp_type': 'arpa',
                      'auto_negotiate': True,
                      'bandwidth': 1000000,
                      'counters': {'in_broadcast_pkts': 0,
                                   'in_crc_errors': 0,
                                   'in_errors': 0,
                                   'in_frame': 0,
                                   'in_giants': 0,
                                   'in_ignored': 0,
                                   'in_mac_pause_frames': 0,
                                   'in_multicast_pkts': 0,
                                   'in_no_buffer': 0,
                                   'in_octets': 3984819,
                                   'in_overrun': 0,
                                   'in_pkts': 41999,
                                   'in_runts': 0,
                                   'in_throttles': 0,
                                   'in_watchdog': 0,
                                   'last_clear': 'never',
                                   'out_babble': 0,
                                   'out_buffer_failure': 0,
                                   'out_buffers_swapped': 0,
                                   'out_collision': 0,
                                   'out_deferred': 0,
                                   'out_errors': 0,
                                   'out_interface_resets': 0,
                                   'out_late_collision': 0,
                                   'out_lost_carrier': 0,
                                   'out_mac_pause_frames': 0,
                                   'out_no_carrier': 0,
                                   'out_octets': 414844,
                                   'out_pkts': 2545,
                                   'out_underruns': 0,
                                   'out_unknown_protocl_drops': 168,
                                   'rate': {'in_rate': 3000,
                                            'in_rate_pkts': 5,
                                            'load_interval': 300,
                                            'out_rate': 0,
                                            'out_rate_pkts': 0}},
                      'delay': 10,
                      'description': "MANAGEMENT INTERFACE - DON'T TOUCH ME",
                      'duplex_mode': 'full',
                      'enabled': True,
                      'encapsulations': {'encapsulation': 'arpa'},
                      'flow_control': {'receive': False, 'send': False},
                      'ipv4': {'10.10.20.48/24': {'ip': '10.10.20.48',
                                                  'prefix_length': '24'}},
                      'keepalive': 10,
                      'last_input': '00:00:00',
                      'last_output': '00:00:00',
                      'line_protocol': 'up',
                      'link_type': 'auto',
                      'mac_address': '0050.56ac.6cb1',
                      'media_type': 'Virtual',
                      'mtu': 1500,
                      'oper_status': 'up',
                      'output_hang': 'never',
                      'phys_address': '0050.56ac.6cb1',
                      'port_channel': {'port_channel_member': False},
                      'port_speed': '1000',
                      'queues': {'input_queue_drops': 0,
                                 'input_queue_flushes': 0,
                                 'input_queue_max': 375,
                                 'input_queue_size': 0,
                                 'output_queue_max': 40,
                                 'output_queue_size': 0,
                                 'queue_strategy': 'fifo',
                                 'total_output_drop': 0},
                      'reliability': '255/255',
                      'rxload': '1/255',
                      'txload': '1/255',
                      'type': 'CSR vNIC'}}

2-1. Genie Opsとは

デバイスの設定情報やオペレーション状態をフィーチャー単位(1つのshowコマンドではなく、例えばinterfaceに関連する複数のshowコマンド)で取得するPythonオブジェクトです。
以前ご紹介したGenie Confと同様、OSによるコマンドの違いを意識することなく、情報の取得が可能です。例えば、IOS-XEでinterface関連の情報を取得する場合、Genie Opsのlearnメソッドにて、以下のCLIコマンドが実行されます。

  • show interfaces
  • show vrf
  • show interfaces accounting
  • show ip interface
  • show ipv6 interface

他にも、routing、bgp、ospf、mcast、acl、vlan、stp、platform等のフィーチャーをサポートしています(詳細は下記GitHubを参照)。
出力結果(info)は、Parserでパースしたものが出力されます。

参考URL:
Ops User Guide
DevNet Workshop (DEVWKS-2601)- pyATS Genie Ops and Parsers
GitHub - Genie Ops

2-2. Pythonコード例①(interface)

interface関連のフィーチャーを取得する例です。learnメソッド内の引数で、interfaceを指定することで、関連情報を取得できます。

genie8-2.py
from genie.conf import Genie
from pprint import pprint

testbed = Genie.init('testbed_devnet3.yaml')
device = testbed.devices['csr1000v-1']

device.connect()

interface = device.learn('interface')
pprint(interface.info)

2-3. 実行結果①(interface)

Genie Parserの結果と比較すると、accounting関連の情報が追加されています。また、interfaceのステータス情報は、エラーカウント内訳などが表示されずコンパクトになっています。

$ python genie8-2.py
# 途中の実行ログは省略
{'': {'accounting': {'arp': {'chars_in': 480,
                             'chars_out': 540,
                             'pkts_in': 8,
                             'pkts_out': 9},
                     'ip': {'chars_in': 4689480,
                            'chars_out': 566379,
                            'pkts_in': 50575,
                            'pkts_out': 3530},
                     'other': {'chars_in': 32820,
                               'chars_out': 634,
                               'pkts_in': 428,
                               'pkts_out': 10}},
      'switchport_enable': False},
 'GigabitEthernet1': {'auto_negotiate': True,
                      'bandwidth': 1000000,
                      'counters': {'in_broadcast_pkts': 0,
                                   'in_crc_errors': 0,
                                   'in_errors': 0,
                                   'in_mac_pause_frames': 0,
                                   'in_multicast_pkts': 0,
                                   'in_octets': 4873797,
                                   'in_pkts': 51634,
                                   'last_clear': 'never',
                                   'out_errors': 0,
                                   'out_mac_pause_frames': 0,
                                   'out_octets': 561534,
                                   'out_pkts': 3504,
                                   'rate': {'in_rate': 3000,
                                            'in_rate_pkts': 4,
                                            'load_interval': 300,
                                            'out_rate': 0,
                                            'out_rate_pkts': 0}},
                      'delay': 10,
                      'description': "MANAGEMENT INTERFACE - DON'T TOUCH ME",
                      'duplex_mode': 'full',
                      'enabled': True,
                      'encapsulation': {'encapsulation': 'arpa'},
                      'flow_control': {'receive': False, 'send': False},
                      'ipv4': {'10.10.20.48/24': {'ip': '10.10.20.48',
                                                  'prefix_length': '24',
                                                  'secondary': False}},
                      'mac_address': '0050.56ac.6cb1',
                      'mtu': 1500,
                      'oper_status': 'up',
                      'phys_address': '0050.56ac.6cb1',
                      'port_channel': {'port_channel_member': False},
                      'port_speed': '1000',
                      'switchport_enable': False,
                      'type': 'CSR vNIC'},
# GigabitEthernet2,3の結果は省略
                     }

2-4. Pythonコード例②(interface一部表示)

出力結果は辞書形式のため、特定のキーの値のみを表示できます。例えば、コード例①を以下の通り書き換えることで、GigabitEthernet1のオペレーション状態(up/down)のみ表示できます。

pprint(interface.info['GigabitEthernet1']['oper_status'])

2-5. 実行結果②(interface一部表示)

'up'

2-6. Pythonコード例③(interface一部取得)

コード例②は情報を一式取得した後、表示の段階で絞っていましたが、取得段階で対象を絞ることも可能です。例えば、各IFのBandwidthだけ取得できれば良い場合、learnメソッドの引数に、以下の通りattributesを指定します。

interface = device.learn('interface', attributes=['info[(.*)][bandwidth]'])

2-7. 実行結果③(interface一部取得)

実行中のログは省略していますが、取得コマンドはshow interfacesshow vrfの2つに絞られていました。実行時間を短くしたい場合は、こちらの方が良いかも知れません。

{'GigabitEthernet1': {'bandwidth': 1000000, 'switchport_enable': False},
 'GigabitEthernet2': {'bandwidth': 1000000, 'switchport_enable': False},
 'GigabitEthernet3': {'bandwidth': 1000000, 'switchport_enable': False}}

2-8. Pythonコード例④(routing)

learnメソッド内の引数を、routingを変更することでrouting関連情報を取得できます。

genie8-4.py
from genie.conf import Genie
from pprint import pprint

testbed = Genie.init('testbed_devnet3.yaml')
device = testbed.devices['csr1000v-1']

device.connect()

routing = device.learn('routing')
pprint(routing.info)

2-9. 実行結果④(routing)

$ python genie8-4.py
# 途中の実行ログは省略
{'vrf': {'default': {'address_family': {'ipv4': {'routes': {'0.0.0.0/0': {'active': True,
                                                                          'metric': 0,
                                                                          'next_hop': {'next_hop_list': {1: {'index': 1,
                                                                                                             'next_hop': '10.10.20.254',
                                                                                                             'outgoing_interface': 'GigabitEthernet1'}}},
                                                                          'route': '0.0.0.0/0',
                                                                          'route_preference': 1,
                                                                          'source_protocol': 'static',
                                                                          'source_protocol_codes': 'S*'},
                                                            '10.10.20.0/24': {'active': True,
                                                                              'next_hop': {'outgoing_interface': {'GigabitEthernet1': {'outgoing_interface': 'GigabitEthernet1'}}},
                                                                              'route': '10.10.20.0/24',
                                                                              'source_protocol': 'connected',
                                                                              'source_protocol_codes': 'C'},
                                                            '10.10.20.48/32': {'active': True,
                                                                               'next_hop': {'outgoing_interface': {'GigabitEthernet1': {'outgoing_interface': 'GigabitEthernet1'}}},
                                                                               'route': '10.10.20.48/32',
                                                                               'source_protocol': 'local',
                                                                               'source_protocol_codes': 'L'}}}}}}}

所感

他のパーサーとして、textFSMとNTC-templateの組み合わせもあります。以下記事にも記載した通り、それぞれ良い所があるので、今後使い分けて行きたいです。

Ansibleのparse_genieフィルターと通信確認表を使ったNWテスト

13
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14