Zabbix API で Shell からメンテナンスを操作する(Zabbix4.4)

## 背景とか
[Zabbix API で Shell からメンテナンスを操作する](https://kakakakakku.hatenablog.com/entry/2016/06/14/232806)を見て、Zabbix4系でもGUIをポチポチしないで、API経由でZabbixのメンテナンスが作成できたら良いなと思って作りました。
[Zabbix APIからのメンテナンス操作について](Zabbix APIからのメンテナンス操作について)も参考にさせて頂きました。
筆者がシェルスクリプト(bash)しか理解していないため、シェルスクリプトで書いてます。

## 環境
- CentOS Linux release 7.7.1908 (Core)
- CentOS Linux release 8.0.1905 (Core)　←動作確認用に使っただけです。
- Zabbix 4.4.0

## 実行結果
まずは結果から記載します。

対象機器：c2960
メンテンナンス名：再起動のため

```
$ ./create_maintenance_period.sh c2960 再起動のため
 [INFO] Successfully created a maintenance period.
 [INFO] Hostname: c2960
 [INFO] Maintenance Name: 再起動のため
 [INFO] Maintenance_id: 28
```

Zabbixのメンテナンスタブを開くと「再起動のため」という名前でメンテナンス期間が作成されています。
![SnapCrab_NoName_2019-11-23_13-17-56_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277982/196bbef7-1d81-229b-4655-493d3390cdb6.jpeg)

さらに詳細を確認すると、コマンドを実行した時間からちょうど１時間後まで、メンテナンス時間が設定されていることが確認できます。
![SnapCrab_NoName_2019-11-23_13-20-40_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277982/c2dad748-6e1e-bef7-9ad2-506f69b2d199.jpeg)

「ホストとホストグループ」を確認すると、今回対象となっている「c2960」がホストとして対象になっていることが確認出来ます。
![SnapCrab_NoName_2019-11-23_13-20-48_No-00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277982/4ef47e17-1f0e-8d22-cd8d-3b9acce8d835.jpeg)



## シェルスクリプト
指定したホストに対して１時間のメンテナンス期間をzabbixに設定します。
上記記載の通り、CentOS7と8の両方で動作を確認しています。実行に際しroot権限は不要です。
jqを使っているので、jqのインストールが必要になります。CentOS7はデフォルトで入ってないので入れる必要があります。CentOS8はデフォで入ってたような…忘れました。
もし入っていない場合はyumなりdnfなりでインストールをお願いします。
※本当はあまり外部からダウンロードする必要があるコマンドに頼りたくないのですが、便利なものは仕方ない。。

```create_maintenance_period.sh
#!/bin/bash
#
# Create maintanance period on zabbix for specific host.
# Default maintenance period is 1 hours.
# If you need to change the period, change folowing values:
#  - time_till=`date "+%s" -d "1 hours"`
#  - "period": 3600
#
# Usage
#  Arguments:
#  $1 hostname(zabbix registered)
#  $2 zabbix maintenance name
#    Note: $2 cannot contain any spaces.
#
# Example
# ./create_maintenance_period.sh centos8 "Sunday_maintenance"
# ./create_maintenance_period.sh centos8 centos8_メモリ増設のため
#


# Initial settings
zbx_endpoint="http://zabbix4/zabbix/api_jsonrpc.php"
user="arkey22"
password="XXXXXXXXXXXX"
time_since=`date +%s`
time_till=`date "+%s" -d "1 hours"`

# Get token
token=`curl -s -d '{
    "jsonrpc": "2.0",
    "method": "user.login",
    "params": {
        "user": "'$user'",
        "password": "'$password'"
    },
    "id": 1,
    "auth": null
}' -H "Content-Type: application/json-rpc" $zbx_endpoint | awk -F'"' '{print $8}'`

# Get host id
host_id=`curl -s -d '{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
          "output": [
            "hostid"
           ],
        "filter": {
          "host": [
                  "'$1'"
            ]
        }
    },
    "auth": "'${token}'",
    "id": 1
}' -H "Content-Type: application/json-rpc" ${zbx_endpoint} | jq -r '.result[].hostid'`

# Create maintenance
maintenance_id=`curl -s -d '{
  "jsonrpc": "2.0",
  "method": "maintenance.create",
  "params": {
    "name": "'$2'",
    "active_since": '$time_since',
    "active_till": '$time_till',
    "hostids": [
      "'$host_id'"
    ],
    "timeperiods": [
      {
        "period": 3600
      }
    ]
  },
  "id": 1,
  "auth": "'${token}'"
}' -H "Content-Type: application/json-rpc" ${zbx_endpoint} | jq -r '.result.maintenanceids[]'`
if [ $? -eq 0 ]; then
  /bin/echo -e "[INFO] Successfully created a maintenance period."
  /bin/echo -e "[INFO] Hostname: $1"
  /bin/echo -e "[INFO] Maintenance Name: $2"
  /bin/echo -e "[INFO] Maintenance_id: $maintenance_id"
else
  /bin/echo -e "[ERROR] Failed to create maintenance period."
fi
```

## 最後に
シェルスクリプトでjsonを扱うと、json内で変数を記載しても展開されなくてハマりました。
今回は変数をシングルクォーテーションで囲うことで回避しました。
また、引数としてメンテナンス名を渡す際にスペースを入れると正常に動作しませんでした。

```
$./create_maintenance_period.sh c2960 "Sunday maintenance"
```

シェルスクリプトの書き方の問題だと思うのですが、解決に至らず放置して仕様としました。

ここまでご覧いただき、ありがとうございました。