はじめに
前回は、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より大きいこと(カウントアップが見られること)
を想定結果として記載します。
---
- 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ファイル
数ある中から、個人的に使えそうなものをピックアップしてみました。
---
- 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ファイルのパスを指定するだけの、シンプルなものになっています。
---
- 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を一桁減らしてみます。
---
- 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でコードを書くしかないのかな。。