Zabbix APIでホスト毎のアイテムの一覧を作ってみました 

この記事は、[ケーシーエスキャロット Advent Calendar 2019](https://qiita.com/advent-calendar/2019/kcscarrot)の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ファイルで出力しようかなと思います。

```shell

#!/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
```

全然もっと楽な方法ありそうですが、取り合えずこんな感じで出来ました。