はじめに
「Cisco DNA Center」とは、Ciscoが提供するDNA(デジタルネットワークアーキテクチャ)のフロントエンドとして、管理者が利用する機能やツールを集約したダッシュボードです。
拠点からクラウドまで、あらゆるネットワークをエンドツーエンドで管理でき、以下を迅速かつ直感的に行うことができます。
- ネットワークのデザイン、プロビジョニング
- ネットワークのポリシー設計と適用
- ネットワークのアシュアランス(パフォーマンスの最適化、障害の予兆検知等)
※DNAの概要はCisco Digital Network Architecture 入門を参照
WebブラウザからのGUI操作だけでなく、ノースバウンドAPIとしてREST APIを提供しており、Postman、Python、Ansible等からDNA Center経由でネットワーク情報の取得、設定追加・変更・削除を行うことができます。
PostmanやPythonによる操作は、Cisco DevNet Learning LabsのCisco DNA Center のプログラマビリティの紹介で分かりやすく解説されています。
今回は、上記のCisco DNA Center Northbound API "Hello Network" (Japanese)で紹介されている、ネットワーク機器の一覧取得をAnsibleで実施してみたいと思います。
用意した環境
-
Ansible
CentOSにインストールした2.8.3を使用。 -
DNA Center
Cisco DevNetのSandboxに、Always On(常時接続可能)とReserve(要予約)の環境が用意されています。今回はCisco DNA Center 1.2.10 (Always-On)を利用しました。
構成概要は以下の通りです。
Inventory
Ansibleのターゲットノードは、NW機器ではなくDNA Centerです。そのため、ansible_host
、ansible_port
、username
、password
はいずれもDNA Centerのものを指定します。
[cisco]
DNA_Center ansible_host=sandboxdnac2.cisco.com ansible_port=443
[cisco:vars]
username=[DNA Centerのユーザ名]
password=[DNA Centerのパスワード]
Playbook
大まかな流れは以下の通りです。
-
認証トークンの要求
HTTPS POSTメソッドを使用して、以降のAPIコールで使う認証トークンを取得します。
Ansibleのモジュールとしては、HTTP/HTTPSアクセスで汎用的に使われるuriモジュールを使用しています。初回はBasic認証を使ってDNA Centerへログインするのですが、force_basic_auth
がデフォルト値のno
だとログインに失敗するため、yes
にしています。また、今回はテスト用の簡易環境のため、validate_certs
をno
とし、SSL証明書のバリデーションを無効化しています。 -
認証トークンの抽出
1.のレスポンスメッセージから認証トークンを抽出し、変数auth_token
に格納します。 -
認証トークンの表示
-
ネットワークデバイス一覧の取得
HTTPS GETメソッドを使用して、DNA Centerが管理するネットワークデバイスの一覧を取得します。URLの末尾を~/network-device
とする事でデバイス情報を取得可能です。認証トークンは先ほど取得したauth_token
を使います。 -
デバイス一覧から必要な値を抽出
Cisco DevNet Learning Labsと表示結果を揃えるため、各デバイスの情報の中からhostname
(ホスト名)、managementIpAddress
(管理IPアドレス)、platformId
(型番)、softwareVersion
(ソフトウェアバージョン)、role
(ロール)、upTime
(起動時間)を抽出しています。 -
デバイス一覧の表示
---
- hosts: cisco
gather_facts: no
connection: local
vars:
device_list_extracted: [['hostname', 'managementIpAddress', 'platformId', 'softwareVersion', 'role', 'upTime']]
tasks:
- name: Get authencation token # (1)
uri:
url: https://{{ansible_host}}:{{ansible_port}}/api/system/v1/auth/token
method: POST
url_username: "{{ username }}"
url_password: "{{ password }}"
force_basic_auth: yes
validate_certs: no
register: result
- name: Extract authentication token # (2)
set_fact:
auth_token: "{{ result.json['Token'] }}"
- name: Display authentication token # (3)
debug:
msg: "{{ auth_token }}"
- name: Get network device list # (4)
uri:
url: https://{{ansible_host}}:{{ansible_port}}/api/v1/network-device
method: GET
validate_certs: no
headers:
X-auth-token: "{{ auth_token }}"
register: device_list
- name: Extract necessary data from the device list # (5)
set_fact:
device_list_extracted: "{{ device_list_extracted + [[item.hostname, item.managementIpAddress,
item.platformId, item.softwareVersion, item.role, item.upTime]] }}"
loop: "{{ device_list.json['response'] | flatten(levels=1) }}"
- name: Display extracted device list # (6)
debug:
msg: "{{ device_list_extracted }}"
出力結果
Display extracted device listで、デバイス情報が取得できている事が分かります。
$ ansible-playbook -i inventory_dnac1 playbook_dnac_device_list2.yml
PLAY [cisco] ****************************************************************************************************************************************
TASK [Get authencation token] ***********************************************************************************************************************
ok: [DNA_Center]
TASK [Extract authentication token] *****************************************************************************************************************
ok: [DNA_Center]
TASK [Display authentication token] *****************************************************************************************************************
ok: [DNA_Center] => {
"msg": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.(省略)"
}
TASK [Get network device list] **********************************************************************************************************************
ok: [DNA_Center]
TASK [Extract necessary data from the device list] **************************************************************************************************
ok: [DNA_Center] => (item={'location': None, 'type': 'Cisco 3504 Wireless LAN Controller', 'errorCode': 'ERROR-
CONNECTION-CLOSED', 'family': 'Wireless Controller', 'role': 'ACCESS', 'lastUpdateTime': 1566658953979, (省略)
TASK [Display extracted device list] ****************************************************************************************************************
ok: [DNA_Center] => {
"msg": [
[
"hostname",
"managementIpAddress",
"platformId",
"softwareVersion",
"role",
"upTime"
],
[
"3504_WLC",
"10.10.20.51",
"AIR-CT3504-K9",
"8.5.140.0",
"ACCESS",
"159 days, 5:29:33.00"
],
[
"leaf1.labb.local",
"10.10.20.81",
"C9300-48U",
"16.6.4a",
"ACCESS",
"126 days, 22:15:30.99"
],
[
"leaf2.labb.local",
"10.10.20.82",
"C9300-48U",
"16.6.4a",
"ACCESS",
"126 days, 4:48:27.30"
],
[
"spine1.abc.in.labb.local",
"10.10.20.80",
"WS-C3850-24P-L",
"16.3.5b",
"DISTRIBUTION",
"159 days, 6:00:01.52"
],
(省略)
]
}
PLAY RECAP ******************************************************************************************************************************************
DNA_Center : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
最後に
今回はuriモジュールを使用しましたが、World Wide TechnologyからDNA Center用のサードパーティーモジュールがリリースされています。こちらを触ってみた結果も別記事でご紹介したいと思います。
GitHub - jandiorio/ansible-dnac-modules