この記事は、ケーシーエスキャロット Advent Calendar 2019の25日目の記事です。
現在、複数サーバーの保守を微力ながら担当しているのですが、
Zabbixでの監視要件について資料が必要となったので、
ホスト毎の監視要件を一瞬でまとめるスクリプトの実装に取り掛かりました。
まず、Zabbixには管理画面だけではなく、便利なAPIも用意されているとの事。
APIから参照・登録が出来ちゃうので、ShellからcurlでAPI呼び出して簡単に
一覧を作る方向で進めました。
APIの事を、色々調べてみると、
まーー数が多くて、どこから手を付ければよいのか・・・という感じで
途方に暮れました。。
公式ドキュメント
https://www.zabbix.com/documentation/3.0/manual/api
という事で、
今回は単純に「ホスト毎のアイテムの一覧」だけを作るに徹するとして、
それを実現する為のAPI以外はスルーして進めました。
APIの呼び出し方としては、基本的にJSON-RPC(プロトコル)を利用します。
JSON-RPCを一言で言いますと、Jsonを使ったRPCプロトコルです。
詳細はWiki参照
https://ja.wikipedia.org/wiki/JSON-RPC
書き方としては、requestに、method、id、params、jsonrpcを渡すことがベースになります。
- method
- 実行メソッド名
- params
- Postで渡す引数(リストで渡します)
- id
- 実行番号
- jsonrpc
- バージョン2.0固定
例
{"method":"user.login", "id":1, "params":{"user":"testuser", "password":"testpassword"}, "jsonrpc":"2.0"}'
レスポンスはresultに結果が格納されて帰ってきます。
という感じで、次に進みます。
まず、Zabbix APIを利用する際には認証から始めます。(token取得)
※メソッドはuser.loginを利用
curl -X GET -H "Content-Type:application/json-rpc" ¥
-d '{"auth":null, "method":"user.login", "id":1, "params":{"user":"testuser", "password":"testpassword"}, "jsonrpc":"2.0"}' ¥
http://zabbix-server/zabbix/api_jsonrpc.php
結果、こんな感じで帰ってきます。
{"jsonrpc":"2.0","result":"abcdefg1234567890abcdefg12345678","id":1}
resultに認証tokenが格納されます。
次に取得した認証tokenを使って、アイテム一覧を取得します。
※メソッドにitem.getを利用
curl -X GET -H "Content-Type:application/json-rpc" ¥
-d '{"auth":"abcdefg1234567890abcdefg12345678", "method":"item.get", "id":1, "params":{"output":"extend", "selectOperations": "extend", "selectHosts" : "extend"}, "jsonrpc":"2.0"}' ¥
http://zabbix-server/zabbix/api_jsonrpc.php
結果、見るに堪えない状態になるので、jqコマンドで補正して出しました。
curl -X GET -H "Content-Type:application/json-rpc" ¥
-d '{"auth":"abcdefg1234567890abcdefg12345678", "method":"item.get", "id":1, "params":{"output":"extend", "selectOperations": "extend", "selectHosts" : "extend"}, "jsonrpc":"2.0"}' ¥
http://zabbix-server/zabbix/api_jsonrpc.php | jq -r .result
結果こんな感じです(かなり省略)
[
{
"prevvalue": "test.co.jp",
:
:
"hosts": [
{
"description": "zzzzzzzzzzzzzzzzz",
:
:
"name": "テストサーバー",
:
:
}
],
:
:
:
"status": "0",
:
:
"hostid": "90000",
"name": "Host name of A Process running",
:
:
:
},
以下省略
この結果を使って、各対象毎に紐づいているhostidが、
90000、90001、90002として定義されている
アイテム名、対象ホスト名、ステータス(0:有効 1:無効)を
CSVファイルで出力しようかなと思います。
#!/bin/sh -x
# 認証token取得
token=`curl -X GET -H "Content-Type:application/json-rpc" -d '{"auth":null, "method":"user.login", "id":1, "params":{"user":"admin", "password":"hirakegoma"}, "jsonrpc":"2.0"}' http:/http://zabbix-server/zabbix/api_jsonrpc.php | jq -r .result`
# item情報取得(zabbix-item.jsonへ出力)
curl -X GET -H "Content-Type:application/json-rpc" -d @- http://zabbix-server/zabbix/api_jsonrpc.php > zabbix-item.json << EOS
{"auth":"$token", "method":"item.get", "id":1, "params":{"output":"extend", "selectOperations": "extend", "selectHosts" : "extend"}, "jsonrpc":"2.0"}
EOS
# hostedが90000/90001/90002対象のitemに絞り
# item名、対象ホスト名、ステータス(0:有効 1:無効)をzabbix-item-tmp.jsonに出力
cat zabbix-item.json | jq '.result[] | select(.hostid == "90000" or .hostid == "90001" or .hostid == "90002")' | jq '[.name, .hosts[].name, .status'] > zabbix-item-tmp.json
numLine=1
name=""
hostname=""
status=""
rm -rf zabbix-get-item.csv
cat zabbix-item-tmp.json | while read line
do
if [ "$line" = "[" ]; then
continue
fi
if [ "$line" = "]" ]; then
echo $name$hostname$status >> zabbix-get-item.csv
numLine=1
continue
fi
if [ $numLine -eq 1 ]; then
name=$line
elif [ $numLine -eq 2 ]; then
hostname=$line
elif [ $numLine -eq 3 ]; then
tmp=${line%¥"}
status=${tmp#¥"}
fi
numLine=$((numLine + 1)) # 行数を1増やす
done
全然もっと楽な方法ありそうですが、取り合えずこんな感じで出来ました。