batfish で interface_blacklist を使い、特定インターフェイスをダウンさせる
batfish を利用する際、「コンフィグは変更せずに特定インターフェイスをダウン状態とみなす」為には interface_blacklist
というファイルを使います。 今回はこの interface_blacklist
の使い方をメモしておきます。
検証環境
batfish は Docker コンテナとして起動済みであるものとします。 また、今回のディレクトリ構造は以下の通りです。
├── example
│ └── configs
│ ├── r1.cfg
│ ├── r2.cfg
│ └── r3.cfg
└── sample.py
batfish の解析対象であるコンフィグファイルとして、今回は以下を利用しました。
r1
1
2
3
4
5
6
7
8
9
10
11
12
13
14 hostname r1
!
interface GigabitEthernet0/0
ip address 10.12.1.1 255.255.255.0
no shutdown
!
interface GigabitEthernet0/1
ip address 10.12.2.1 255.255.255.0
no shutdown
!
router ospf 1
network 0.0.0.0 255.255.255.255 area 0.0.0.0
!
end
r2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 hostname r2
!
interface GigabitEthernet0/0
ip address 10.12.1.2 255.255.255.0
no shutdown
!
interface GigabitEthernet0/1
ip address 10.12.2.2 255.255.255.0
no shutdown
!
interface GigabitEthernet0/2
ip address 10.23.0.2 255.255.255.0
no shutdown
!
router ospf 1
network 0.0.0.0 255.255.255.255 area 0.0.0.0
!
end
r3
hostname r3
!
interface GigabitEthernet0/2
ip address 10.23.0.3 255.255.255.0
no shutdown
!
router ospf 1
network 0.0.0.0 255.255.255.255 area 0.0.0.0
!
end
確認用スクリプト
動作確認用のスクリプトには以下を使いました。 ipOwners と Routes を利用しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #!/usr/bin/env python3
# -*- coding:utf-8 -*-
import logging
from pybatfish.client.commands import *
from pybatfish.question import bfq
from pybatfish.question.question import load_questions
logging.getLogger ("pybatfish" ).setLevel (logging.ERROR )
BASENAME = "example"
SNAPSHOT_PATH = "./" + BASENAME
SNAPSHOT_NAME = BASENAME + "_snapshot"
NETWORK_NAME = BASENAME + "_network"
bf_set_network (NETWORK_NAME )
bf_init_snapshot (SNAPSHOT_PATH , name=SNAPSHOT_NAME , overwrite= True )
load_questions ()
result1 = bfq.routes (nodes= "r1" , protocols= "ospf" ).answer ().frame ()
print (
result1.sort_values (by= ["Node" , "VRF" , "Protocol" , "Network" ]).to_string (
index= False
)
)
result2 = bfq.ipOwners ().answer ().frame ()
print (result2.sort_values (by= ["Node" , "VRF" , "Interface" ]).to_string (index= False ))
実行結果は以下の通りです。
# ./sample.py
Node VRF Network Next_Hop_IP Next_Hop_Interface Protocol Metric Admin_Distance Tag
r1 default 10 .23.0.0/24 10 .12.1.2 GigabitEthernet0/0 ospf 2 110 None
r1 default 10 .23.0.0/24 10 .12.2.2 GigabitEthernet0/1 ospf 2 110 None
Node VRF Interface IP Mask Active
r1 default GigabitEthernet0/0 10 .12.1.1 24 True
r1 default GigabitEthernet0/1 10 .12.2.1 24 True
r2 default GigabitEthernet0/0 10 .12.1.2 24 True
r2 default GigabitEthernet0/1 10 .12.2.2 24 True
r2 default GigabitEthernet0/2 10 .23.0.2 24 True
r3 default GigabitEthernet0/2 10 .23.0.3 24 True
インターフェイスをダウンさせる
特定インターフェイスをダウンさせるには interface_blacklist
(拡張子は無し) というファイルを以下の内容で新規作成します。
[{"hostname": "r1", "interface": "GigabitEthernet0/1"},
{"hostname": "r2", "interface": "GigabitEthernet0/1"}]
これをスナップショットパスの直下にアップロードします。 この時点で具体的なディレクトリ構造は以下になりました。
├── example
│ ├── configs
│ │ ├── r1.cfg
│ │ ├── r2.cfg
│ │ └── r3.cfg
│ └── interface_blacklist
└── sample.py
サンプルスクリプトの実行結果が以下のように変化しました。 r1 の Gi0/1 と r2 の Gi0/1 が interface_blacklist
の内容に従って「ダウンしている」とみなされ、処理されていることが分かります。
# ./sample.py
Node VRF Network Next_Hop_IP Next_Hop_Interface Protocol Metric Admin_Distance Tag
r1 default 10 .23.0.0/24 10 .12.1.2 GigabitEthernet0/0 ospf 2 110 None
Node VRF Interface IP Mask Active
r1 default GigabitEthernet0/0 10 .12.1.1 24 True
r1 default GigabitEthernet0/1 10 .12.2.1 24 False
r2 default GigabitEthernet0/0 10 .12.1.2 24 True
r2 default GigabitEthernet0/1 10 .12.2.2 24 False
r2 default GigabitEthernet0/2 10 .23.0.2 24 True
r3 default GigabitEthernet0/2 10 .23.0.3 24 True