Zabbixで監視を自動化したりしているのですが、マップも監視対象が追加された時点で自動的に作成できれば便利だなと思ったのでZabbix API経由からマップを作成する手順について簡単にですがまとめてみます。
環境
サーバ情報
項目 | 内容・バージョン |
---|---|
OS | CentOS 7.4 |
Zabbix | 3.0.13-2 |
開発情報
項目 | 内容・バージョン |
---|---|
Python | 3.4.4 |
Zabbix Map APIドキュメント
テンプレート
今回は、以下のテンプレートを元に処理を書いていきます。
# !/usr/bin/env python3
from collections import defaultdict
import requests
import json
import atexit
class zbxapi:
"""
Zabbix APIを処理するクラス
"""
def __init__(self):
self.url = ''
self.user = ''
self.passwd = ''
self.token = ''
def login(self):
"""
ログインメソッド
ログインに成功したらTokenを取得する
:rtype: str
:return: Zabbix API Auth Token
"""
params = multi_dimension_dict(1)
params['user'] = self.user
params['password'] = self.passwd
# Tokenを取得
r = self.post('user.login', params)
self.token = json.loads(r)['result']
def logout(self):
"""
ログアウトメソッド
:rtype: str
:return: ログアウトの成功(True)・失敗(False)
"""
params = {}
r = self.post('user.logout', params)
return json.loads(r)['result']
def get(self, method, params):
"""
Zabbixから情報を取得するメソッド
:type method: str
:param method: Zabbix APIメソッド
:type params: dict
:param params: 取得したい情報のパラメーター
:rtype: json
:return: レスポンスボディ
"""
data = multi_dimension_dict(1)
data['jsonrpc'] = '2.0'
data['method'] = method
data['params'] = params
data['id'] = 1
data['auth'] = self.token
r = requests.get(self.url,
data=json.dumps(data),
headers=get_headers(),
verify=False)
if (r.status_code == 200):
return r.text
def post(self, method, params):
"""
Zabbixへ情報を送るメソッド
:type method: str
:param method: Zabbix APIメソッド
:type params: dict
:param params: 送信する情報のパラメーター
:rtype: json
:return: レスポンスボディ
"""
data = multi_dimension_dict(1)
data['jsonrpc'] = '2.0'
data['method'] = method
data['params'] = params
data['id'] = 1
if(self.token): data['auth'] = self.token
r = requests.post(self.url,
data=json.dumps(data),
headers=get_headers(),
verify=False)
if(r.status_code == 200):
return(r.text)
def multi_dimension_dict(dimension, callable_obj=int):
"""
pythonで多次元連想配列を使う関数
参照元: http://materia.jp/blog/20121119.html
"""
nodes = defaultdict(callable_obj)
for i in range(dimension-1):
p = nodes.copy()
nodes = defaultdict(lambda : defaultdict(p.default_factory))
return nodes
def get_headers():
"""
ヘッダー情報
:rtype: dict
:return: Zabbix APIを実行するためのヘッダー
"""
headers = {
'Content-Type':'application/json-rpc'
}
return headers
if __name__ == "__main__":
# Login
zapi = zbxapi()
zapi.url = 'http://IP or FQDN/zabbix/api_jsonrpc.php'
zapi.user = 'admin'
zapi.passwd = 'zabbix'
zapi.login()
atexit.register(zapi.logout)
# ここから処理を書いていく
以下からは # ここから処理を書いていく
以降を書いていきます。
マップ自動生成をやってみた
マップ作成編
まずは、シンプルなマップを作ってみます。
# ここから処理を書いていく
# Create Map.
params = {}
params['name'] = "Map"
params['width'] = 600
params['height'] = 600
r = zapi.post('map.create', params)
print(json.dumps(json.loads(r), indent=2))
パラメーター | 説明 |
---|---|
name | マップの名前 |
width | マップ幅のサイズ |
height | マップ高さのサイズ |
実行します。
以下はレスポンスボディです。
{
"jsonrpc": "2.0",
"result": {
"sysmapids": [
"12"
]
},
"id": 1
}
マップが作成されているか確認します。
マップ作成と同時にアイコンを追加
マップ作成と作成したマップにアイコンを追加する処理を一度にやってみようと思います。
# ここから処理を書いていく
# Element.
element = {}
element['elementid'] = 10105
element['selementid'] = 1
element['elementtype'] = 0
element['iconid_off'] = 101
# Create Map.
params = {}
params['name'] = "Map"
params['width'] = 600
params['height'] = 600
params['selements'] = [element]
r = zapi.post('map.create', params)
print(json.dumps(json.loads(r), indent=2))
パラメーター | 説明 |
---|---|
elementid | エレメント(アイコン)に紐づけるID(ホストやグループ) |
selementid | マップ内で判別するエレメントのID、これを元にエレメント同士を紐付けたりします |
elementtype | マップエレメントのタイプ、エレメントはhostなのかmapなのかなど |
iconid_off | アイコンの種類 |
selements | エレメントを配列で渡す |
注意点としては、アイコンに紐づけるホストなどがZabbixに登録されている必要があります。
elementid
は省略できません。
ここでは example01
というホストを手動で登録してURLから hostid
を取得しています。
決して自動で取得する処理を書くのがめんどくさかった訳では...
ただし elementtype
が 4(イメージ)
の場合は elementid
が実在していないものでも登録出来ちゃいます。
実行するとMapにアイコンが出来ています。
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"sysmapids": [
"13"
]
}
}
アイコンの種類について
参考までに iconid_off
の情報については以下に保存してあります。
imageid
を iconid_off
に指定します。
https://gist.github.com/sky-joker/727f319e0f0601f2b08004de05ce0f17
ちなみに取得の仕方は以下のようにします。
# ここから処理を書いていく
params = {}
params['output'] = ["imageid", "name"]
r = zapi.get('image.get', params)
print(json.dumps(json.loads(r), indent=2))
アイコンの座標を指定する
座標を指定しない場合は、全てのアイコンは画面左上に出来てしまうので座標を指定してみます。
# ここから処理を書いていく
# Element.
element = {}
element['elementid'] = 10105
element['selementid'] = 1
element['elementtype'] = 0
element['iconid_off'] = 101
element['x'] = 100
element['y'] = 100
(snip)
パラメーター | 説明 |
---|---|
x | アイコンのx座標を指定します |
y | アイコンのy座標を指定します |
実行するとアイコンが指定した座標に配置されています。
{
"jsonrpc": "2.0",
"result": {
"sysmapids": [
"14"
]
},
"id": 1
}
アイコンを紐づけてみる
マップにアイコンを2つ登録してお互いを紐づけてみます。
# ここから処理を書いていく
# Element1.
element1 = {}
element1['elementid'] = 10105
element1['selementid'] = 1
element1['elementtype'] = 0
element1['iconid_off'] = 101
element1['x'] = 100
element1['y'] = 100
# Element2.
element2 = {}
element2['elementid'] = 10106
element2['selementid'] = 2
element2['elementtype'] = 0
element2['iconid_off'] = 101
element2['x'] = 350
element2['y'] = 100
# Element Link.
elementLink = {
'selementid1': element1['selementid'],
'selementid2': element2['selementid']
}
# Create Map.
params = {}
params['name'] = "Map"
params['width'] = 600
params['height'] = 600
params['selements'] = [element1, element2]
params['links'] = [elementLink]
r = zapi.post('map.create', params)
print(json.dumps(json.loads(r), indent=2))
パラメーター | 説明 |
---|---|
links | 紐づけたいエレメントの selementid を渡します |
実行するとアイコンが2つ出来て紐づけられています。
{
"id": 1,
"jsonrpc": "2.0",
"result": {
"sysmapids": [
"16"
]
}
}
マップをアップデートする
既に作成したマップをアップデート(アイコンを追加したり)してみます。
# ここから処理を書いていく
# Element1.
element1 = {}
element1['elementid'] = 10105
element1['selementid'] = 1
element1['elementtype'] = 0
element1['iconid_off'] = 101
element1['x'] = 100
element1['y'] = 100
# Element2.
element2 = {}
element2['elementid'] = 10106
element2['selementid'] = 2
element2['elementtype'] = 0
element2['iconid_off'] = 101
element2['x'] = 350
element2['y'] = 100
# Element Link.
elementLink = {
'selementid1': element1['selementid'],
'selementid2': element2['selementid']
}
# Update Map.
params = {}
params['sysmapid'] = 18
params['selements'] = [element1, element2]
params['links'] = [elementLink]
r = zapi.post('map.update', params)
print(json.dumps(json.loads(r), indent=2))
パラメーター | 説明 |
---|---|
sysmapid | アップデート対象のsysmapid |
作成時と違うのは、対象の sysmapid
を指定します。
sysmapidはマップのURLとか作成時のレスポンスボディから確認できます。
独り言
今回は、シンプルな処理しかしなかったから多次元連想配列(multi_dimension_dict)は使わなかった。。。