技術メモ

ネットワークエンジニアがpython, perl等々を気楽に使うための覚え書き

python textfsm(part2) - ciscoルータのconfig解析例

textfsmによるciscoルータのconfig解析例

interfaceセクションのdescription, ip address情報を抽出する解析例をipythonで対話的に・・・

1.モジュールのロードと解析対象ファイルの読み込み

In [1]: import textfsm

In [2]: import pprint

In [3]: ! type sample.log
tky-rt-01#
tky-rt-01#ter len 0
tky-rt-01#
tky-rt-01#
tky-rt-01#sh run
Building configuration...

Current configuration : 3124 bytes
!
!
version 15.2
service timestamps debug datetime msec localtime show-timezone
service timestamps log datetime msec localtime show-timezone
service password-encryption
!
hostname tky-rt-01
!
boot-start-marker
boot-end-marker
!
!
logging buffered 40960
!
no aaa new-model
clock timezone JST 9 0
!
!
no ip source-route
ip cef
!
!
!
!


!
!
!
!
no ip domain lookup
no ipv6 cef
!
!
multilink bundle-name authenticated
!
!
vtp mode transparent
!
!
!
!
!
vlan 2-4
!
!
track 1 interface GigabitEthernet9.901 ip routing
!
!
!
!
!
!
!
!
!
interface GigabitEthernet0
 description LAN switch
 switchport trunk allowed vlan 1-4,1002-1005
 switchport mode trunk
 no ip address
!
interface GigabitEthernet1
 no ip address
 shutdown
!
interface GigabitEthernet2
 no ip address
 shutdown
!
interface GigabitEthernet3
 no ip address
 shutdown
!
interface GigabitEthernet4
 no ip address
 shutdown
!
interface GigabitEthernet5
 no ip address
 shutdown
!
interface GigabitEthernet6
 no ip address
 shutdown
!
interface GigabitEthernet7
 no ip address
 shutdown
!
interface GigabitEthernet8
 no ip address
 shutdown
 duplex auto
 speed auto
!
interface GigabitEthernet9
 no ip address
 duplex full
 speed 10
!
interface GigabitEthernet9.901
 description tagged WAN 1
 encapsulation dot1Q 901
 ip address 10.240.1.1 255.255.255.128
 no ip redirects
 no ip proxy-arp
!
interface Vlan1
 description Tokyo office LAN
 ip address 10.1.1.252 255.255.255.0
 no ip redirects
 no ip proxy-arp
 standby 1 ip 10.1.1.254
 standby 1 priority 120
 standby 1 preempt
 standby 1 track 1 decrement 10
 delay 100
!
interface Vlan2
 description Tokyo office LAN
 ip address 10.1.2.252 255.255.255.0
 no ip redirects
 no ip proxy-arp
 standby 2 ip 10.1.2.254
 standby 2 priority 115
 standby 2 preempt
 delay 200
!
interface Vlan3
 description Tokyo office LAN
 ip address 10.1.3.252 255.255.255.0
 no ip redirects
 no ip proxy-arp
 standby 3 ip 10.1.3.254
 standby 3 priority 120
 standby 3 preempt
 standby 3 track 1 decrement 10
 delay 100
!
interface Vlan4
 description Tokyo office LAN
 ip address 10.1.4.252 255.255.255.0
 no ip redirects
 no ip proxy-arp
 standby 4 ip 10.1.4.254
 standby 4 priority 115
 standby 4 preempt
 delay 200
!
!
router eigrp 10
 distribute-list prefix out_filter out GigabitEthernet9.901
 network 10.1.1.0 0.0.0.255
 network 10.1.2.0 0.0.0.255
 network 10.1.3.0 0.0.0.255
 network 10.1.4.0 0.0.0.255
 network 10.240.1.0 0.0.0.127
!
ip forward-protocol nd
no ip http server
no ip http secure-server
!
!
!
!
ip prefix-list out_filter seq 5 permit 10.1.3.0/24
ip prefix-list out_filter seq 10 permit 10.1.4.0/24
ip prefix-list out_filter seq 15 permit 10.1.1.0/24
ip prefix-list out_filter seq 20 permit 10.1.2.0/24
no cdp run
!
!
control-plane
!
!
!
line con 0
 login
 no modem enable
line aux 0
 no exec
line vty 0 4
 transport input telnet
!
scheduler allocate 20000 1000
!
end

tky-rt-01#
In [4]: with open('sample.log','r') as f:
   ...:         config = f.read()
   ...:
  • In [1-2]: モジュールのロード
  • In [3]: 解析対象ログの内容(show running-config)
  • In [4]: 解析対象テキストは、文字列データとして読み込むこと

2.textfsmの定義ファイル(template)

In [5]: ! type template_tmp.txt
Value Filldown hostname (\S+)
Value interface (\S+)
Value description (.*)
Value Required primary_ip ((?:\d{1,3}\.){3}\d{1,3} (?:\d{1,3}\.){3}\d{1,3})

Start
  ^hostname ${hostname}
  ^interface ${interface}
  ^ description ${description}
  ^ ip address ${primary_ip}(?! secondary)
  ^!$$ -> Record
  • In [5]: 定義ファイル(テンプレート)は、通常、ファイルとして用意する(textfsmへファイルオブジェクトを引数として与えるため)
  • Value定義( Value [option[,option...]] name regex )
    • optionでは、Filldown,Required,List等があり、複数同時に与える場合、(空白を入れずに)カンマで区切ること
    • Filldownを指定した場合、直近にマッチした値を後続行にもコピー(上記では、hostnameをFilldown指定)
    • Requiredを指定した場合、このマッチがないと値の保存が見送られる(上記の例では、primary_ipで指定しているため、物理インターフェースGi0-Gi9におけるマッチの結果は保存されない)
    • Listを指定した場合、マッチした値をリストデータで保持する
    • regexは、丸括弧()で閉じるように記述
  • State定義(Start,EOF,他)
    • Value定義とState定義の間には空行が必要
    • Startの指定は必須、EOFは省略可
    • その他、任意の名前でState定義が可能(多分、あまり使わない)
  • Stateルール( ^ _regex_ [-> _action_] )
    • Stateルールでは、各行で空白2文字(または、ハードタブ)*1とキャレット'^'が必要
    • _regex_はValue定義のnameを用い、${name}の記法で当てはめる
    • _regex_で行末のアンカーを'$'で表したい場合、'$$'とすること(上記の例では、interfaceブロックの区切りを!で限定するのに使用)
    • _action_は、Recordのほか、NoRecord,Clear等もあるが、多分使うことはない・・

3.textfsmの解析実行

In [6]: with open('template_tmp.txt','r') as f:
   ...:         table = textfsm.TextFSM(f)
   ...:         result = table.ParseText(config)
   ...:

In [7]: pprint.pprint(result)
[['tky-rt-01',
  'GigabitEthernet9.901',
  'tagged WAN 1',
  '10.240.1.1 255.255.255.128'],
 ['tky-rt-01', 'Vlan1', 'Tokyo office LAN', '10.1.1.252 255.255.255.0'],
 ['tky-rt-01', 'Vlan2', 'Tokyo office LAN', '10.1.2.252 255.255.255.0'],
 ['tky-rt-01', 'Vlan3', 'Tokyo office LAN', '10.1.3.252 255.255.255.0'],
 ['tky-rt-01', 'Vlan4', 'Tokyo office LAN', '10.1.4.252 255.255.255.0']]

In [8]: table.header
Out[8]: ['hostname', 'interface', 'description', 'primary_ip']
  • In [6]: TextFSM()には定義ファイル(テンプレート)のファイルオブジェクトを与え、ParseText()には、解析対象文字列データを与える。
  • In [7]: 解析結果はリストとして得られる(通常は2次元であるが、'Value List'を定義した場合は階層化される)
  • In [8]: headerプロパティでリストの列情報が得られる

*1:ドキュメント上は'white space'とされ、何でもよさそうであるが、空白1文字や3文字であったりすると、うまく認識されなかった