AnsibleとTextFSMパーサー、TextFSMのネットワーク用テンプレート集であるNTC Templatesを使用するとで、AnsibleからCLIコマンドの出力結果を分析することができます。今回はSi-Rルーターでのping疎通確認とファームウェアのバージョン確認を行ってみました。
環境構築
Ansibleがインストール済みであることを前提とします。
Ansibleのマシンと同セグメントに下記の機器を設置します。
- Si-R G120
- version : V20.54
 - IPv4アドレス : 192.168.50.21/24
 - デフォルトルート : 192.168.50.1
 - ProxyDNS : 有効
 
 
Si-R用Ansibleモジュールのインストール
Si-Rには公式モジュールが存在しないため自作しました。Ansible galaxyからダウンロード可能です。
ansible-galaxy collection install caribouhy.sir
TextFSMのインストール
pipでTextFSMをインストールします。
pip install textfsm
NTC-Templatesのダウンロード
今回使用するフォルダにNTC-Templatesをダウンロードします。なおダウンロードしたリポジトリ内のntc-templatesフォルダのみあればよいため、他は削除しています。使用するテンプレートのみをピックアップしてダウンロードしても問題ないです。
git clone https://github.com/networktocode/ntc-templates.git ntc
mv ntc/ntc_templates/ ./
rm -rf ntc
(オプション)network-engineロールのインストール
ansible-network.network-engineというRoleを使用することでTextFSMによるパース処理を簡潔に記載することができます。
ansible-galaxy role install ansible-network.network-engine
Playbook
下記の2点を実施します。
- ファームウェアバージョンが
V20.54であることを確認する - 
192.168.50.1とwww.google.co.jpへpingを打つ 
---
all:
  children:
    Si_R:
      hosts:
        G120-1:
          ansible_host: 192.168.50.21
      vars:
        ansible_user: admin
        ansible_password: password
        ansible_connection: network_cli
        ansible_network_os: caribouhy.sir.sir
インベントリではansible_network_osとしてcaribouhy.sir.sirを指定してください。基本的にCisco等の他機種と同様の書き方です。
---
- name: Si-R network test
  hosts: Si_R
  gather_facts: false
  tasks:
    # Si-R上でshow system informationコマンドを実行
    - name: Execute show system information
      caribouhy.sir.sir_command:
        commands:
          - show system information
      register: result
    # TextFSMによるパース
    - name: Parse show system information
      ansible.builtin.set_fact:
        sys_info: "{{ result.stdout[0] | parse_cli_textfsm('./ntc_templates/templates/fsas_sir_show_system_information.textfsm') }}"
    # ファームウェアバージョンの判定
    - name: Check firmware version
      ansible.builtin.assert:
        that:
          - sys_info[0].VERSION == "20.54"
        fail_msg: Firmware ver. is not V20.54
    # デフォゲへの疎通確認
    - name: Ping gateway
      caribouhy.sir.ping:
        dest: 192.168.50.1
    # インターネットサイトへの疎通確認
    - name: Ping Google
      caribouhy.sir.ping:
        dest: www.google.co.jp
        source: 192.168.50.21
        afi: ip
        count: 2
caribouhy.sir.sir_commandモジュールでshowコマンドを実行します。parse_cli_textfsmフィルターでCLI出力結果のパースを行い、set_factモジュールで変数に代入します。バージョンの判定はassertモジュールで実施します。
Pingはcaribouhy.sir.pingモジュールを使用します。パラメータの設定により、送信回数やソースIP等を設定可能です。
実行結果
$ ansible-playbook -i inventory.yaml playbook.yml -v
PLAY [Si-R network test] 
************************************************************************
TASK [Execute show system information] 
************************************************************************
ok: [G120-1] => {
    "changed": false,
    "stdout": ["Current-time :(省略)\nUSB   : ------"],
    "stdout_lines": [[(省略)]]
}
TASK [Parse show system information] 
************************************************************************
ok: [G120-1] => {
    "ansible_facts": {
        "sys_info": [{
            "CONFIG_FILE": "config1",
            (省略),
            "SYSTEM": "Si-R G120",
            "VERSION": "20.54"
        }]
    }, 
    "changed": false
}
TASK [Check firmware version] 
***********************************************************************
ok: [G120-1] => {
    "changed": false,
    "msg": "All assertions passed"
}
TASK [Ping gateway] 
************************************************************************
ok: [G120-1] => {
    "changed": false,
    "commands": "ping 192.168.50.1 repeat 5",
    "packet_loss": "0%",
    "packets_rx": 5,
    "packets_tx": 5,
    "rtt": {"avg": 0, "max": 0, "min": 0}
}
TASK [Ping Google]
************************************************************************
ok: [G120-1] => {
    "changed": false,
    "commands": "ping www.google.co.jp v4 source 192.168.50.21 repeat 2",
    "packet_loss": "0%",
    "packets_rx": 2,
    "packets_tx": 2,
    "rtt": {"avg": 7, "max": 7, "min": 7}
}
PLAY RECAP 
************************************************************************
G120-1  : ok=5    changed=0    unreachable=0    failed=0
          skipped=0    rescued=0    ignored=0 
(オプション) network-engineによるパース
ansible-network.network-engineのtextfsm_parserを使用するこで、set_factを使用せずにパースができます。下記のPlaybookで上記と同様の処理を行えます。
set_factとの違いは、パース結果がansible_facts内に格納されます。
---
- name: Si-R network test
  hosts: Si_R
  gather_facts: false
  roles:
    - ansible-network.network-engine
  tasks:
    # Si-R上でshow system informationコマンドを実行
    - name: Execute show system information
      caribouhy.sir.sir_command:
        commands:
          - show system information
      register: result
    # TextFSMによるパース
    - name: Parse show system information
      textfsm_parser:
        file: "./ntc_templates/templates/fsas_sir_show_system_information.textfsm"
        content: "{{ result.stdout[0] }}"
        name: sys_info
    # ファームウェアバージョンの判定
    - name: Check firmware version
      ansible.builtin.assert:
        that:
          - ansible_facts['sys_info'][0].VERSION == "20.54"
        fail_msg: Firmware ver. is not V20.54
    # --------- pingは省略 -------------