この記事はシスコの同志による Cisco Systems Japan Advent Calendar 2021 の 2枚目の 23日目 として投稿しています。
2021年版(1枚目): https://qiita.com/advent-calendar/2021/cisco
2021年版(2枚目): https://qiita.com/advent-calendar/2021/cisco2
2020年版(1枚目): https://qiita.com/advent-calendar/2020/cisco
2020年版(2枚目): https://qiita.com/advent-calendar/2020/cisco2
2019年版: https://qiita.com/advent-calendar/2019/cisco
2018年版: https://qiita.com/advent-calendar/2018/cisco
2017年版: https://qiita.com/advent-calendar/2017/cisco
#はじめに
皆様はじめまして、2020年4月に新卒としてシスコシステムズ合同会社へ入社しました、清水亮佑と申します。 CX(カスタマーエクスペリエンス)のPS(プロフェッショナルサービス)チームで、コンサルティングエンジニアとしてCisco SD-WANを中心に業務に携わっています。
今回はvManage Alarm NotificationsのWebhookを使用してみた話をしていきたいと思います。
#WebhookとvManage Alarm Notifications
Webhookは何かしらのイベントをトリガーに、特定のURLへPOSTリクエストを送信してくれるような仕組みとなります。
Cisco vManageでは、常にCisco SD-WANの環境がモニターされており、障害等が起きるとAlarmという形で知らせてくれます。vManageバージョン18.3より、Alarmに対してWebhookを設定できるようになりました。
今回はAlarm NotificationsのWebhookを活用して、障害でAlarmが発生したときにWebexへチャットが送られてくるよう設定していきます。今回は最新のvManageバージョン20.6.2.1を使用しました。(Apache Log4j 脆弱性の修正バージョンですね。)
#検証環境
vManageとCentOSを同じセグメントに配置し、CentOSの特定ポートで常にHTTPリクエストをListenするよう設定します。Alarmに該当するEventがSD-WAN環境で発生した場合、vManageよりCentOSのListenしているポートへPOSTリクエストが送られ、そのリクエストをもとにWebexへメッセージが送られます。(上記図からcEdgeは省略しています。)
#ChatBotの準備
vManageでWebhookの設定を行っていく前に、まずWebex ChatBotを用意します。去年のCisco Advent CalendarにChatBotの作成が説明されているので、参考にしてください。
https://qiita.com/YasutakaTanabe/items/fa82d9d1b8b75b2db021#step-1-webex%E3%81%AE%E3%83%9C%E3%83%83%E3%83%88%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B5%E5%88%86
とりあえずTokenを用意できるところまで行ければ問題ないです。
また、ChatBotと会話するRoom IDも必要となります。こちらは https://developer.webex.com/docs/api/v1/rooms/list-rooms を使うと簡単に取得できます。(typeはdirect、sortByはlastactivityで設定しておくと楽かも。)"title"がChatBot名のエントリから、IDをメモっておきます。
#Webhookを受け取るサーバの準備
一からPOSTリクエストをListenしてWebexへメッセージを送るアプリケーションを作成するのはめんどくさかったので、Cisco DevNetで色々検索していたところ、運良く同じ事をすでに行っている方がいました。以下をお借りしています。
https://github.com/suchandanreddy/sdwan-apis
こちらのレポジトリに含まれているwebhook.pyをCentOSで走らせることで、POSTリクエストを受け取ることが可能となります。Dependenciesをサクッとインストールして、実行しました。環境変数で準備したChatBotのTokenと、メッセージの送り先となるRoom IDを指定する必要があります。また、webhook.py内のhostを指定する箇所で、10.2.1.13のアドレスと5001ポートを指定しています。
git clone https://github.com/suchandanreddy/sdwan-apis
cd sdwan-apis/webhook
pip3 install -r requirements.txt
export bearer_token=[chatbot_token]
export room_id=[chatbot_roomid]
python3.6 webhook.py
うまく実行できていれば、以下のように表示されるはずです。
* Serving Flask app "webhook" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://10.2.1.13:5001/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 183-822-195
これで10.2.1.13のポート5001でPOSTリクエストを受け取る事が可能となります。
#vManageとWebhookサーバの疎通性確認
試しにvManageよりPOSTリクエストをWebhook URLへ送信してみて、疎通性を確認します。vManageとCentOSは同じセグメントに配置されているので、今回は心配する必要はあまりないですね。
vManage# vshell
vManage:~$ curl -v -X POST -H 'Content-type: application/json' http://10.2.1.13:5001
* Trying 10.2.1.13:5001...
* Connected to 10.2.1.13 (10.2.1.13) port 5001 (#0)
> POST / HTTP/1.1
> Host: 10.2.1.13:5001
> User-Agent: curl/7.69.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 500 INTERNAL SERVER ERROR
< Content-Type: application/json
< Content-Length: 44
< Server: Werkzeug/0.15.3 Python/3.6.8
< Date: Wed, 22 Dec 2021 16:48:18 GMT
<
"Expecting value: line 1 column 1 (char 0)"
* Closing connection 0
CentOS側では以下のようにHTTPリクエストを受け取っていることが確認できます。
* Serving Flask app "webhook" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://10.2.1.13:5001/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 183-822-195
10.2.1.10 - - [22/Dec/2021 11:48:01] "POST / HTTP/1.1" 500 - <-- vManageより送信されたPOSTリクエスト
これで、vManageからWebhookを受け取る準備は完了です。
#Alarm NotificationsのWebhookの設定
ここからは、実際にvManageのAlarm Notificationsを設定していきます。まず、Administration > Settings より Alarm Notifications を有効にします。Emailの設定を行うことで、Alarmの情報をメールで受信することも可能です。今回はWebhookのみを設定するため、チェックはしません。
次に Monitor > Alarms から右上にある Alarm Notifications をクリックし、Webhookの設定を追加していきます。
SeverityやAlarmを指定してWebhookを作成することが可能です。今回は簡単に再現できる障害であるSeverity「Critical」、Alarm Name「OMP All Vsmarts Down」で設定を行っていきます。以下設定画面になります。
SeverityとAlarm NameはDrop Downから選択して設定を行うことが可能です。
今回はWebhookのみを設定するため、Emailのチェックはせず先に進みます。(以前はWebhookのみの使用でもEmailにダミーの設定を入れる必要がありましたが、いつのまにか設定しなくても良くなっていました。)
Webhookにチェックを入れ、Webhook URLと必要であれば認証情報も入力しておきます。認証情報は必要なければダミーの情報を入力しておきます。Webhook Thresholdも適当に100と入力します。
Alarm通知は機器を指定して行うことも可能ですが、今回はAll Devicesで設定していきます。
保存すれば、Alarm NotificationsのWebhook設定は完了です。
#実際に障害を起こしてみる
それでは、最後に障害を起こして、Webhookがちゃんと機能しているか確認してみます。今回はvSmartがすべてDownした時のAlarmにWebhookを設定しているので、ESXiに展開されているvSmartを一度サスペンド状態にしてみました。待つこと数十秒、vManage上の Monitor > Alarms に OMP All Vsmarts Down のAlarmが発生しました。
それと同時にCentOSでPOSTリクエストが受け取られており、その情報がメッセージとしてリアルタイムでWebexにも送信されてきました。
* Serving Flask app "webhook" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://10.2.1.13:5001/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 183-822-195
10.2.1.10 - - [22/Dec/2021 11:48:01] "POST / HTTP/1.1" 500 -
{'suppressed': False, 'message': 'OMP sessions with all vsmarts in the network is down', 'values': [{'name': 'all vsmart'}], 'values_short_display': [{'name': 'all vsmart'}], 'eventname': 'rulename', 'rulename': 'all_vsmarts_down', 'type': 'all_vsmarts_down', 'component': 'OMP', 'severity': 'Critical', 'severity_number': 1, 'entry_time': 1640191627577, 'receive_time': 1640191602846, 'rule_name_display': 'OMP_All_Vsmarts_Down', 'uuid': '97994178-1ce9-4d52-b0d5-6eba40141fbb', 'active': True, 'acknowledged': False, 'possible_causes': ['Trying to determine possible root causes'], 'consumed_events': [{'eventname': 'omp-peer-state-change', 'peer-new-state': 'init', 'eventId': '0d0d77bd-2f80-4822-8c44-dc32e072535b', 'builtBy': 'EventDataCollector', 'component': 'OMP', 'severity-level': 'major', 'vmanage-system-ip': '', 'entry_time': 1640191413000, 'system-ip': '10.2.3.2', 'host-name': '', 'peer': '10.2.3.102'}, {'eventname': 'omp-peer-state-change', 'peer-new-state': 'init', 'eventId': 'b02aca1c-4f89-45ec-8386-25fd9270b5e6', 'builtBy': 'EventDataCollector', 'component': 'OMP', 'severity-level': 'major', 'vmanage-system-ip': '', 'entry_time': 1640192810000, 'system-ip': '10.2.3.2', 'host-name': '', 'peer': '10.2.3.101'}, {'eventname': 'omp-peer-state-change', 'peer-new-state': 'init', 'eventId': '53a2c9cc-3e5b-4ba4-b8dc-78688a518b8b', 'builtBy': 'EventDataCollector', 'component': 'OMP', 'severity-level': 'major', 'vmanage-system-ip': '', 'entry_time': 1640191483000, 'system-ip': '10.2.3.2', 'host-name': '', 'peer': '10.2.3.103'}], 'devices': [{'system-ip': '10.2.3.2'}]}
10.2.1.10 - - [22/Dec/2021 11:50:25] "POST / HTTP/1.1" 500 -
成功です!(HTTPのリスポンスは500でエラーですが、まぁ細かいことは気にしたら負けです、、、)
#最後に
今回はvManage Alarm NotificationsのWebhookの設定を行ってみました。いかかがでしたでしょうか?
Cisco SD-WANの環境内で障害等が起きた場合、Webexへチャットが送られてくるのは案外便利な機能だなと思いました。応用すれば、検証・障害試験等にも活用できると感じました。vManageは他にもAPIが豊富にあるので、いつかREST APIを使ってDevice TemplateやFeature Templateの作成に挑戦してみたいですね。
今回も使用しましたが、Cisco DevNetにはCiscoのプログラマビリティに関するチュートリアルやリソースが多く用意されています。興味を持たれた方は一度訪問してみてください!
https://developer.cisco.com/
ここまでお読みいただき、ありがとうございました。
#免責事項
本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本Webサイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。