LoginSignup
9
9

More than 5 years have passed since last update.

Ansibleのnapalm-ansibleモジュールでネットワークテストを自動化してみた

Last updated at Posted at 2018-11-08

はじめに

前回は、Ansibleのサードパーティー製モジュール群napalm-ansibleの内、設定変更系のモジュールnapalm_install_configの動作確認を行いました。
Ansibleのnapalm-ansibleモジュールでCisco IOSの設定変更をしてみた

今回は、napalm_validateモジュールを使って、ネットワークテストの自動化をしてみました。

napalm-ansibleの概要セットアップ方法は前回の記事を参照願います。ただし、今回はSCPサーバの有効化は不要です。

napalm_validateモジュールで出来ること

想定結果を記載したYAML形式のファイル(Validationファイル)と、実機のステータスを比較し、その結果を出力することが可能です。

例えば、以下のようなValidationファイルを作成し、GigabitEthernet1の

  • (1) rxのエラーカウントがゼロであること
  • (2) rxのUnicastパケットカウントが10より大きいこと(カウントアップが見られること)
  • (3) txのエラーカウントがゼロであること
  • (4) txのUnicastパケットカウントが10より大きいこと(カウントアップが見られること)

を想定結果として記載します。

validate_sample.yml
---
- get_interfaces_counters:
    GigabitEthernet1:
      rx_errors: 0                #(1)
      rx_unicast_packets: '>10'   #(2)
      tx_errors: 0                #(3)
      tx_unicast_packets: '>10'   #(4)

これに対し、取得したインタフェース情報(以下のようなnapalm_get_facts モジュールで取得したデータ)を比較しているイメージです。

"napalm_interfaces_counters": {
                "GigabitEthernet1": {
                    "rx_broadcast_packets": 0, 
                    "rx_discards": 0, 
                    "rx_errors": 0,                 #(1)
                    "rx_multicast_packets": 0, 
                    "rx_octets": 11616019, 
                    "rx_unicast_packets": 97110,    #(2)
                    "tx_broadcast_packets": -1, 
                    "tx_discards": 0, 
                    "tx_errors": 0,                 #(3)
                    "tx_multicast_packets": -1, 
                    "tx_octets": 8023672, 
                    "tx_unicast_packets": 61613     #(4)
                }

napalm_get_facts モジュールについては、てくなべ (tekunabe)さんのブログで分かり易くまとめられています。
Ansible の napalm-ansible モジュール群でCisco IOS 機器の様々な情報を取得する

Cisco IOSで取得できる情報は、執筆時点(2018年11月)で以下の通りです。

  • get_arp_table
  • get_bgp_neighbors
  • get_bgp_neighbors_detail
  • get_config
  • get_environment
  • get_facts
  • get_interfaces
  • get_interfaces_counters
  • get_interfaces_ip
  • get_ipv6_neighbors_table
  • get_lldp_neighbors
  • get_lldp_neighbors_detail
  • get_mac_address_table
  • get_network_instances
  • get_ntp_peers
  • get_ntp_servers
  • get_ntp_stats
  • get_optics
  • get_probes_config
  • get_snmp_information
  • get_users
  • is_alive
  • ping
  • traceroute

※最新情報はこちらを参照願います。

Ansible実行(成功例)

Validationファイル

数ある中から、個人的に使えそうなものをピックアップしてみました。

validate.yml
---
- get_facts:
    hostname: csr1
    os_version: CSR1000V Software, Version 15.5(3)S5, RELEASE SOFTWARE (fc2)
    interface_list:
      _mode: strict
      list:
        - GigabitEthernet1
        - GigabitEthernet2
        - GigabitEthernet3
        - Tunnel1
        - Loopback0

- get_interfaces_ip:
    GigabitEthernet1:
      ipv4:
        192.168.1.100:
          prefix_length: 24

- get_interfaces:
    GigabitEthernet1:
      is_enabled: true
      speed: 1000

- get_interfaces_counters:
    GigabitEthernet1:
      rx_errors: 0
      rx_unicast_packets: '>10'
      tx_errors: 0
      tx_unicast_packets: '>10'

- get_environment:
    memory:
      used_ram: '<400000000'  #メモリ使用域が400,000,000Byteより低いこと
    cpu:
       0:
        '%usage': '<15.0'   #CPU使用率が15%より低いこと

- ping:
    _name: ping_gateway
    _kwargs:
      destination: 192.168.1.1
      source: 192.168.1.100
      size: 1500
      count: 100
    success:
      packet_loss: 0      #パケロスがないこと
      rtt_max: '<1000.0'  #1=0.1msec ⇒ 100msecより速いこと
      rtt_avg: '<500.0'   #1=0.1msec ⇒ 50msecより速いこと
    _mode: strict

Playbook

基本的にはValidationファイルのパスを指定するだけの、シンプルなものになっています。

playbook7.yml
---
- hosts: cisco
  gather_facts: no
  connection: local

  tasks:
    - name: get validation report
      napalm_validate:
        provider: "{{ cli }}"
        validation_file: '/home/<ユーザ名>/ansible/validate.yml'
      register: result

    - name: debug
      debug:
        msg: "{{ result }}"

  vars:
    cli:
      hostname: "{{ inventory_hostname }}"
      username: "{{ ansible_username }}"
      password: "{{ ansible_password }}"
      dev_os: "ios"
      #ユーザーの権限レベルが0の場合、以下コマンドでenableパスワードを指定
      optional_args: {'secret': 'csr1'}

実行結果

それぞれの確認項目について、"complies": true or falseで結果が分かります。
成功した場合、CPU使用率等の具体的な値は表示されませんので、必要に応じてnapalm_get_factsモジュールで値を確認すると良いと思います。

[<ユーザ名>@localhost library]$ ansible-playbook -i inventory playbook7.yml

PLAY [cisco] ********************************************************************************

TASK [get validation report] ****************************************************************
ok: [192.168.1.100]

TASK [debug] ********************************************************************************
ok: [192.168.1.100] => {
    "msg": {
        "changed": false,
        "compliance_report": {
            "complies": true,
            "get_environment": {
                "complies": true,
                "extra": [],
                "missing": [],
                "present": {
                    "cpu": {
                        "complies": true,
                        "nested": true
                    },
                    "memory": {
                        "complies": true,
                        "nested": true
                    }
                }
            },
            "get_facts": {
                "complies": true,
                "extra": [],
                "missing": [],
                "present": {
                    "hostname": {
                        "complies": true,
                        "nested": false
                    },
                    "interface_list": {
                        "complies": true,
                        "nested": true
                    },
                    "os_version": {
                        "complies": true,
                        "nested": false
                    }
                }
            },
            "get_interfaces": {
                "complies": true,
                "extra": [],
                "missing": [],
                "present": {
                    "GigabitEthernet1": {
                        "complies": true,
                        "nested": true
                    }
                }
            },
            "get_interfaces_counters": {
                "complies": true,
                "extra": [],
                "missing": [],
                "present": {
                    "GigabitEthernet1": {
                        "complies": true,
                        "nested": true
                    }
                }
            },
            "get_interfaces_ip": {
                "complies": true,
                "extra": [],
                "missing": [],
                "present": {
                    "GigabitEthernet1": {
                        "complies": true,
                        "nested": true
                    }
                }
            },
            "ping_gateway": {
                "complies": true,
                "extra": [],
                "missing": [],
                "present": {
                    "success": {
                        "complies": true,
                        "nested": true
                    }
                }
            },
            "skipped": []
        },
        "failed": false
    }
}

PLAY RECAP **********************************************************************************
192.168.1.100              : ok=2    changed=0    unreachable=0    failed=0   

Ansible実行(失敗例)

Validationファイル

Ping確認の想定RTTを一桁減らしてみます。

validate2.yml
---
- ping:
    _name: ping_gateway
    _kwargs:
      destination: 192.168.1.1
      source: 192.168.1.100
      size: 1500
      count: 100
    success:
      packet_loss: 0      #パケロスがないこと
      rtt_max: '<100.0'  #1=0.1msec ⇒ 10msecより速いこと
      rtt_avg: '<50.0'   #1=0.1msec ⇒ 5msecより速いこと
    _mode: strict

実行結果

-vvvオプションを使用して、詳細なメッセージを表示した結果です。
"rtt_avg""rtt_max"が想定結果を上回り、"complies": falseとなっているのが分かります。

[<ユーザ名>@localhost library]$ ansible-playbook -i inventory playbook7.yml -vvv
---<中略>---
PLAYBOOK: playbook7.yml *********************************************************************
1 plays in playbook7.yml

PLAY [cisco] ********************************************************************************
META: ran handlers

TASK [get validation report] ****************************************************************
---<中略>---
fatal: [192.168.1.100]: FAILED! => {
    "changed": false,
    "compliance_report": {
        "complies": false,
        "ping_gateway": {
            "complies": false,
            "extra": [],
            "missing": [],
            "present": {
                "success": {
                    "complies": false,
                    "diff": {
                        "complies": false,
                        "extra": [],
                        "missing": [],
                        "present": {
                            "packet_loss": {
                                "complies": true,
                                "nested": false
                            },
                            "rtt_avg": {
                                "actual_value": 130.0,
                                "complies": false,
                                "expected_value": "<50.0",
                                "nested": false
                            },
                            "rtt_max": {
                                "actual_value": 191.0,
                                "complies": false,
                                "expected_value": "<100.0",
                                "nested": false
                            }
                        }
                    },
                    "nested": true
                }
            }
        },
        "skipped": []
    },
    "invocation": {
  ---<中略>--
    "msg": "Device does not comply with policy"

所感

確認できる項目は限られていますが、一度Validationファイルを作ってしまえば、パラメータ部分を変えて使い回せるので便利だと感じました。
確認できない項目は、ntc-templatesというコマンド出力結果パース用のテンプレート集とassertモジュールを組み合わせて使う選択肢もあると思います。
どちらでもサポートされていない確認項目については、テンプレートを自作するかPythonでコードを書くしかないのかな。。

9
9
1

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
9
9