LoginSignup
6
4

More than 3 years have passed since last update.

Ansible自作モジュールでNW機器からTracerouteする

Last updated at Posted at 2019-12-18

はじめに

みなさんAnsibleのネットワークモジュール使ってますか?
ネットワークの通信テストを自動化するにあたって、pingだけじゃなくて、tracerouteも出来たらいいなーって思うことありますよね?
そんなアナタのために、Cisco IOS用のios_tracerouteモジュールを作っちゃいましたよ!(無理矢理)

使い方

公式のレポジトリにはマージされていないので、使うには以下の操作が必要です。
(Red Hatさん、プルリク出したから通してね:kissing_heart:

  1. GitHubからのデータ取得
    GitHubレポジトリansible_ios_traceroute_moduleをクローンもしくはダウンロード。

  2. モジュールの格納
    自作モジュールをAnsibleが認識できるよう、Best Practices > Directory Layoutに従ってlibraryディレクトリを作成し、直下に取得したPythonモジュール(ios_traceroute.py)を格納。

  3. パスの追加
    ansible.cfgファイルにlibraryディレクトリへのパスを追加。

ansible.cfg
[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サンプル

大まかな流れは以下の通りです。

  1. ios_tracerouteモジュールで、NW機器自身のアドレス(192.168.100.201)から172.16.1.100宛てにtracerouteを実施。
  2. debugモジュールで、出力結果を表示。
  3. assertモジュールで、7ホップ目に特定のIPアドレス(172.30.100.1)を経由するかチェック。
playbook1_traceroute.yml
---

- 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のモジュールも作ってみようと思います!

6
4
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
6
4