Zabbixの監視アラートでBacklogの課題に自動起票 

こんちは！
エキゾ大好き加藤です。

Zabbix監視アラートが発生した時に、Backlogへ自動起票できるようにしてみた

内容としては、Zabbixでアラートが発生すると

1. プロジェクトの課題に新規で起票
2. 課題内容は以下

- 課題の種別を「タスク」
- 件名にはアラートの件名
- 詳細にはアラート内容
- 担当者
- 通知者(複数可)

といった感じ

※動作確認環境
CentOS Linux release 7.4.1708
Python 2.7.5
zabbix-server 3.2.10

## 事前準備
- Backlogを準備してね
- Backlog APIkeyを発行してね

# 1. Zabbixサーバー
## 1.1. pythonスクリプト
今回はhttplibを使ってみました。
しょぼエンジニアのスクリプトなので、ご了承ください。

```create-issue.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import httplib
import sys
import json

args = sys.argv
space = args[1]
project = args[2]
summary = args[3] #Backlog issue subject
description = args[4] #Backlog issue details
assigneeid = args[5]
notifieduserid = args[6]

url_api = "/api/v2/"

### 環境によって変更 ###
api_key = "*********"
issuetypeid = "*******"
priorityid = "3"

def get_projectid(url_code):
  url = url_api + "projects/%s?apiKey=%s" % (url_code, api_key)
  connect = httplib.HTTPSConnection(host = space + ".backlog.jp", port = 443)
  connect.request("GET", url)
  response = connect.getresponse()
  body = response.read()
  connect.close()
  data = json.loads(body)
  projectid = data['id']

  return projectid

def post_issue(projectid, summary, issuetypeid, priorityid, assigneeid, notifieduserid, description):
  backlog_params = {
    "projectId" : projectid,
    "summary" : summary,
    "issueTypeId" : issuetypeid,
    "priorityId" : priorityid,
    "assigneeId" : assigneeid,
    "notifiedUserId" : notifieduserid.split(','),
    "description" : description
  }

  params = json.dumps(backlog_params)

  headers = {
    "Accept":"application/json",
    "Content-Type":"application/json",
  }

  url = url_api + "issues?apiKey=%s" % (api_key)
  connect = httplib.HTTPSConnection(host = space + ".backlog.jp", port = 443)
  connect.request("POST", url, params, headers)
  response = connect.getresponse()
  connect.close()

pid = get_projectid(project)

post_issue(pid, summary, issuetypeid, priorityid, assigneeid, notifieduserid, description)
```

上記のスクリプトを
`/usr/lib/zabbix/alertscripts/`に配置します。

## 1.2. Zabbixコンソール
以下にユーザーで指定する方法を書きます！

### 1.2.1. メディアタイプの作成
<img width="770" alt="メディアタイプ.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/e8998341-5701-37fa-4a44-571165de122d.png">

| パラメータ番号| 説明               | 補足                |
|:-----------|:------------------|:-------------------|
| パラメータ 1  | BacklogのスペースID |              |
| パラメータ 2  | Backlogプロジェクト名 |              |
| パラメータ 3  | Backlog課題の件名  |　{ALERT.SUBJECT}でアクションの「件名」をそのまま出力できる |
| パラメータ 4  | Backlog課題のメッセージ部分 | {ALERT.MESSAGE}とすることでアクションで設定するメッセージ内容をそのまま出力できる|
| パラメータ 5  | Backlog課題の担当者 | IDで記載 |
| パラメータ 6  | Backlog課題の通知者 | IDで記載(複数指定の場合は「`,`」で区切る)             |

### 1.2.2. ユーザーの作成
BacklogAPI用ユーザーを作成
グループの権限は「すべてのグループ【読込】」があればよく、Zabbixコンソールへのログイン権限もいらない
<img width="735" alt="ユーザー.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/45ee43d4-808b-86e9-5cd4-7e67ba9032ab.png">

メディア設定でタイプの設定は、前項で作成したメディアタイプを選択
【Backlog_AddIssue】
<img width="673" alt="メディア.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/9d5938ce-9d08-6345-96b2-2c9f8409290a.png">

ユーザーの権限はユーザーグループで設定するので、割り当てたグループの権限があっているか確認
<img width="754" alt="権限.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/b4b8cbb1-4e2d-f40c-e879-decea4396a3c.png">

### 1.2.3. アクションの作成
新規にアクションを作成します。
- Backlogの課題に起票したい件名とメッセージを入力します。
- 実行内容に作成したBacklogAPI用ユーザーを指定します。
- 使用するメディアを作成したメディアタイプに変更します。
<img width="775" alt="アクション.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/ca79ba21-accf-96b9-fa93-ce9d7c29e4fc.png">

ここまで完了です。
アラートを発生してみてください。


# ※ 補足
## ユーザーのID検索

```
curl -X GET https://[スペースID].backlog.jp/api/v2/projects/[プロジェクト名]/users?apiKey=[API Key] -u [ユーザー]:[パスワード] |jq
```

## 課題タイプの検索

```
curl -X GET https://[スペースID].backlog.jp/api/v2/projects/[プロジェクト名]/issueTypes?apiKey=[API Key] -u [ユーザー]:[パスワード] |jq
```

## Python 3系の場合
たぶん下記で動くと思います。
Python 3.6.1の私のMac環境では、引数つけてたたいたら一応動きました。
(Zabbixでは確認してません)
httplibをhttp.clientに置き換える必要があるっす

```create-issue.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import http.client
import sys
import json

args = sys.argv
space = args[1]
project = args[2]
summary = args[3] #Backlog issue subject
description = args[4] #Backlog issue details
assigneeid = args[5]
notifieduserid = args[6]

url_api = "/api/v2/"

### 環境によって変更 ###
api_key = "*********"
issuetypeid = "*******"
priorityid = "3"

def get_projectid(url_code):
  url = url_api + "projects/%s?apiKey=%s" % (url_code, api_key)
  connect = http.client.HTTPSConnection(host = space + ".backlog.jp", port = 443)
  connect.request("GET", url)
  response = connect.getresponse()
  body = response.read()
  connect.close()
  data = json.loads(body)
  projectid = data['id']

  return projectid

def post_issue(projectid, summary, issuetypeid, priorityid, assigneeid, notifieduserid, description):
  backlog_params = {
    "projectId" : projectid,
    "summary" : summary,
    "issueTypeId" : issuetypeid,
    "priorityId" : priorityid,
    "assigneeId" : assigneeid,
    "notifiedUserId" : notifieduserid.split(','),
    "description" : description
  }

  params = json.dumps(backlog_params)

  headers = {
    "Accept":"application/json",
    "Content-Type":"application/json",
  }

  url = url_api + "issues?apiKey=%s" % (api_key)
  connect = http.client.HTTPSConnection(host = space + ".backlog.jp", port = 443)
  connect.request("POST", url, params, headers)
  response = connect.getresponse()
  connect.close()

pid = get_projectid(project)

post_issue(pid, summary, issuetypeid, priorityid, assigneeid, notifieduserid, description)
```

## アクションで直接たたいても動きまする！
<img width="789" alt="アクション_リモートコマンド.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/f767ebcd-ee8e-fcda-6bc9-33c2968000c8.png">

実行内容のタイプ：「リモートコマンド」
ターゲットリスト：「現在のホスト」

コマンドの中身に下記のような感じで記載したら同じ感じでBacklogに起票されます。

```
message="ホスト名：{HOST.NAME}\n発生日時: {EVENT.DATE} {EVENT.TIME}\n深刻度：{TRIGGER.SEVERITY}\nトリガー：{TRIGGER.NAME}\n{ITEM.VALUE1}\n"
description=`echo -e "$message"`

/usr/lib/zabbix/alertscripts/create-issue.py "スペースID" "プロジェクト名" "{HOST.NAME}：{TRIGGER.NAME}" "$description" "担当者ID" "通知者ID1,通知者ID2"
```

この方法だと、メディアタイプの設定やBacklogAPI用のユーザー作成もいりません。
好きな方でどうぞ

おわり