はじめに
みなさんAnsibleのネットワークモジュール使ってますか?
ネットワークの通信テストを自動化するにあたって、pingだけじゃなくて、tracerouteも出来たらいいなーって思うことありますよね?
そんなアナタのために、Cisco IOS用のios_tracerouteモジュールを作っちゃいましたよ!(無理矢理)
使い方
公式のレポジトリにはマージされていないので、使うには以下の操作が必要です。
(Red Hatさん、プルリク出したから通してね)
-
GitHubからのデータ取得
GitHubレポジトリansible_ios_traceroute_moduleをクローンもしくはダウンロード。 -
モジュールの格納
自作モジュールをAnsibleが認識できるよう、[Best Practices > Directory Layout]
(https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html#directory-layout)に従って`library`ディレクトリを作成し、直下に取得したPythonモジュール(ios_traceroute.py)を格納。 -
パスの追加
ansible.cfg
ファイルにlibrary
ディレクトリへのパスを追加。
[defaults]
library = /home/centos/ansible/library
※ansible.cfg
の格納先は、ansible --version
コマンドのconfig file
で確認可能です。
[centos@localhost ~]$ ansible --version
ansible 2.9.0
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/centos/ansible/library']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.7 (default, Dec 5 2018, 15:02:05) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
Playbook
Playbookサンプル
大まかな流れは以下の通りです。
-
ios_traceroute
モジュールで、NW機器自身のアドレス(192.168.100.201)から172.16.1.100宛てにtracerouteを実施。 -
debug
モジュールで、出力結果を表示。 -
assert
モジュールで、7ホップ目に特定のIPアドレス(172.30.100.1)を経由するかチェック。
---
- hosts: cisco
gather_facts: no
connection: network_cli
tasks:
- name: execute traceroute
ios_traceroute:
dest: 172.16.1.100
probe: 4
source: 192.168.100.201
ttl_min: 1
ttl_max: 20
register: result_traceroute
- name: debug traceroute
debug:
msg: "{{ result_traceroute }}"
- name: check if the traceroute results always include specific transit ip address in hop 7
assert:
that:
- result_traceroute.hop['7'] == ['172.30.100.1']
使用可能なオプション
ios_traceroute
モジュール内で使用可能なオプションは以下の通りです。
これらの内、dest
のみ必須項目になります。それ以外の項目は、指定しない場合、各IOS機器のデフォルト値が使用されます。
probe:
description:
- 各ホップで送信するパケットの数
type: int
dest:
description:
- 宛先IPアドレスもしくはホスト名(NW機器で名前解決できる必要あり)
type: str
required: true
source:
description:
- 送信元IPアドレス
type: str
udp:
description:
- UDPパケットのポート番号
type: int
ttl_min:
description:
- 最小TTL値(ttl_minとttl_maxはセットで指定する必要あり)
type: int
ttl_max:
description:
- 最大TTL値
type: int
vrf:
description:
- 転送に使用するVRF
type: str
実行結果
※グローバルIPアドレスを含んでいるため、Netconanというツールを使ってデタラメなアドレスに変換しています。
TASK [debug traceroute]のcommands
で実際に実行したコマンド、output
で加工前の出力結果、hop
でホップ数とIPアドレスのみ抽出した結果を確認できます。
最後のTASKで、7ホップ目で想定IPアドレスを経由することが確認でき、「All assertions passed」となっています。
PLAY [cisco] ************************************************************************************************************
TASK [execute traceroute] ***********************************************************************************************
ok: [test3]
TASK [debug traceroute] *************************************************************************************************
ok: [test3] => {
"msg": {
"changed": false,
"commands": [
"traceroute 172.174.88.165 source 192.168.173.198 probe 4 ttl 1 20"
],
"failed": false,
"hop": {
"1": [
"192.168.173.43"
],
"10": [
"108.224.66.109",
"108.224.66.161",
"108.224.66.172"
],
"11": [
"108.254.165.36",
"172.159.216.191"
],
"12": [
"215.123.152.64",
"74.246.135.251",
"222.152.243.188"
],
"13": [
"108.224.67.238",
"108.224.67.103"
],
"14": [
"108.224.80.18",
"108.224.80.23"
],
"15": [
"172.174.88.165"
],
"2": [],
"3": [
"172.30.231.192"
],
"4": [
"126.244.74.242"
],
"5": [
"18.232.93.6",
"18.232.93.1"
],
"6": [
"18.235.248.200",
"18.235.248.207"
],
"7": [
"68.32.20.116"
],
"8": [],
"9": [
"74.246.135.176",
"108.224.82.72",
"108.224.82.242"
]
},
"output": [
"Type escape sequence to abort.",
"Tracing the route to 172.174.88.165",
"VRF info: (vrf in name/id, vrf out name/id)",
" 1 192.168.173.43 186 msec 16 msec 13 msec 11 msec",
" 2 * * * * ",
" 3 172.30.231.192 51 msec 55 msec 44 msec 62 msec",
" 4 126.244.74.242 54 msec 79 msec 39 msec 59 msec",
" 5 18.232.93.6 43 msec",
" 18.232.93.1 63 msec",
" 18.232.93.6 60 msec",
" 18.232.93.1 64 msec",
" 6 18.235.248.200 56 msec 80 msec 53 msec",
" 18.235.248.207 62 msec",
" 7 68.32.20.116 61 msec 55 msec 59 msec 39 msec",
" 8 * * * * ",
" 9 108.224.82.72 57 msec",
" 74.246.135.176 39 msec",
" 108.224.82.242 60 msec 61 msec",
" 10 108.224.66.161 62 msec",
" 108.224.66.109 70 msec",
" 108.224.66.172 72 msec",
" 108.224.66.161 54 msec",
" 11 108.254.165.36 [MPLS: Label 27008 Exp 4] 70 msec",
" 172.159.216.191 [MPLS: Label 178553 Exp 4] 57 msec",
" 108.254.165.36 [MPLS: Label 25624 Exp 4] 71 msec 56 msec",
" 12 74.246.135.251 79 msec",
" 222.152.243.188 77 msec",
" 74.246.135.251 60 msec",
" 215.123.152.64 53 msec",
" 13 108.224.67.238 58 msec 62 msec",
" 108.224.67.103 70 msec 68 msec",
" 14 108.224.80.23 58 msec",
" 108.224.80.18 59 msec",
" 108.224.80.23 70 msec 70 msec",
" 15 172.174.88.165 77 msec 60 msec 61 msec 63 msec"
]
}
}
TASK [check if the traceroute results (dict) always include specific transit ip address in hop 7] ***********************
ok: [test3] => {
"changed": false,
"msg": "All assertions passed"
}
PLAY RECAP **************************************************************************************************************
test3 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
最後に
このモジュールは、標準のtracerouteコマンドを使って、1行の中でオプションを指定するようにしています。
複数のルータ、スイッチでテストをしていますが、古いバージョンではコマンドがサポートされておらず、はじかれるかもしれません。その時は諦めてくださいw
プルリクが通ったら、調子に乗って他のOSのモジュールも作ってみようと思います!