Collection Hook
Collection Hook
は、Collectionの登録、変更、削除時に実行されるカスタムスクリプトを作成できるサービスです。
例えば、外部のメトリックサーバとZabbixでデータを同期したい場合、Collection登録時に対応する管理ホストをZabbixに自動登録しておき、ReflectionでZabbixにメトリック転送する場合などが該当します。
Collectionのrun_script
に紐づけることで実行されます。
Collection Hookが保有する属性
属性 | 概要 | 備考 |
---|---|---|
name |
フックの名前を指定します。 | ユニークである必要があります。 |
script |
カスタムスクリプトを記述します。 | - |
Note
カスタムスクリプトで参照できるパラメータは以下の通りです。ビルトイン関数や共通コンテキストも同様に利用可能です。
参照変数の内容を書き換えたい場合は、グローバル宣言を使用する必要があります。
Method | Variable | Description |
---|---|---|
POST | collection |
POSTされたCollection辞書 |
PUT | collection |
PUTされたCollection辞書(変更後) |
PUT | previous |
変更前のCollection辞書 |
DELETE | collection |
削除するCollection辞書 |
サンプル
以下はCollection登録時にZabbixに管理ホストや監視アイテムを自動登録するカスタムスクリプトの例です。
Collectionが保有するcorrelation_infoを参照してホストを作成します。またZabbix側のホストグループIDやホストIDもcorrelation_infoに取り込んで後段のReflectionにも伝搬させることができます。correlation_infoを更新するためには先頭行のcollection
変数へのglobal宣言が必要です。
- name: createHost
script: |-
global collection
async def jsonrpc(token, method, **params):
payload = MU(dict(jsonrpc="2.0", method=method, params=params, id=1, auth=token))
r = await callout(url=collection["correlation_info"]["zabbix_url"],
method=POST,
headers={"Content-Type": "application/json-rpc"},
body=payload.dictionary)
if r.error:
raise Error(r.code, reason="Communication failure occurred")
result = MU(json.loads(r.body))
return result
# Zabbix認証トークン取得
r = await jsonrpc(None, "user.login", user=collection["correlation_info"]["zabbix_username"],
password=collection["correlation_info"]["zabbix_password"])
if r.error:
raise Error(500, reason="Unable to get token", body=r.error.dictionary)
token = r.result
qprint("Zabbix Token: %r" % token)
# ホストグループ登録
r = await jsonrpc(token, "hostgroup.create", name=collection["correlation_info"]["zabbix_hostgroup"])
# 重複登録の場合以外は例外発出
if r.error and r.error.code != -32602:
raise Error(500, reason="Unable to create host group", body=r.error.dictionary)
# ホストグループID取得
r = await jsonrpc(token, "hostgroup.get", output="extend", filter={"name": [collection["correlation_info"]["zabbix_hostgroup"]]})
if r.error:
raise Error(500, reason="Unable to retrieve host group", body=r.error.dictionary)
groupid = r.result[0].groupid
qprint("Host Group ID: %r" % groupid)
# ホスト登録
r = await jsonrpc(token, "host.create", host=collection["hostname"],
interfaces=[{"type": 1, "main": 1,"useip": 1, "ip": collection["address"], "dns": "", "port": "10050"}],
groups=[{"groupid": groupid}])
# 重複登録の場合以外は例外発出
if r.error and r.error.code != -32602:
raise Error(500, reason="Unable to create host", body=r.error.dictionary)
# ホストID取得
r = await jsonrpc(token, "host.get", filter={"name": [collection["hostname"]]})
if r.error:
raise Error(500, reason="Unable to get host", body=r.error.dictionary)
hostid = r.result[0].hostid
qprint("Host ID: %r" % hostid)
# 監視アイテム登録
r = await jsonrpc(token, "item.create", name="tcpActiveOpens",
key_="tcpActiveOpens",
hostid=hostid,
type=2,
value_type=3)
if r.error:
raise Error(500, reason="Unable to create tcpActiveOpens item", body=r.error.dictionary)
r = await jsonrpc(token, "item.create", name="tcpPassiveOpens",
key_="tcpPassiveOpens",
hostid=hostid,
type=2,
value_type=3)
if r.error:
raise Error(500, reason="Unable to create tcpPassiveOpens item", body=r.error.dictionary)
for i in ["Gi1", "Gi2", "Gi3"]:
r = await jsonrpc(token, "item.create", name="{}.traffic.in.bps".format(i),
key_="{}.traffic.in.bps".format(i),
hostid=hostid,
type=2,
value_type=0)
if r.error:
raise Error(500, reason="Unable to create {}.traffic.in.bps item".format(i), body=r.error.dictionary)
r = await jsonrpc(token, "item.create", name="vmStatus",
key_="vmStatus",
hostid=hostid,
type=2,
value_type=3)
if r.error:
raise Error(500, reason="Unable to create vmStatus item", body=r.error.dictionary)
r = await jsonrpc(token, "item.create", name="pingDelay",
key_="pingDelay",
hostid=hostid,
type=2,
value_type=0)
if r.error:
raise Error(500, reason="Unable to create vmStatus item", body=r.error.dictionary)
collection["correlation_info"]["zabbix_hostgroupid"] = groupid
collection["correlation_info"]["zabbix_hostid"] = hostid
qprint(MU(collection).yaml_format)
Collection Hookのテストは、Collection
組込みオブジェクトを利用してください。カスタムスクリプトにqprint
を埋め込みREPLのdebug機能で出力確認すると効率的です。
>>> debug()↵
Disconnected the currently subscribed channel and connected to the debug channel ['xaas.southbound.channel']
debug channel connected
>>> c = await Collection.load("CSR1000v")↵
... await c.hook("createHost")↵
... ↵
Zabbix Token: '8cadc3fb0d9e971bfe101714b64ef148'
Host Group ID: '22'
Host ID: '10325'
↵
__FILE__: axis/handson/collections/CSR1000v.yml
__WORKSPACE__: axis-edge/hands-on_plugins
address: 192.168.2.200
collections:
- csr1000v
correlation_info:
snmp_community: public
vmid: 75CE72DHP742RGQCMLI1MCRFK8I1KRNS
vmware_endpoint: http://localhost:8697
vmware_password: Qmonus!2021
vmware_username: qmonus
zabbix_host: localhost
zabbix_hostgroup: qmonus-example
zabbix_hostgroupid: '22'
zabbix_hostid: '10325'
zabbix_password: zabbix
zabbix_port: 10051
zabbix_url: http://localhost:80/api_jsonrpc.php
zabbix_username: Admin
enable: true
hostname: CSR1000v
target_id: e22ea82a612311eb92f7acde48001122
update: '2021-02-08T10:22:17.167850+09:00'
version: 9
>>> debug(False)↵
debug channel disconnected
>>>
Note
上記スクリプトをお試しする場合は、Zabbixサーバが必要です。
docker pull zabbix/zabbix-appliance
docker run --name zabbix-appliance -t -p 10051:10051 -p 80:80 -d zabbix/zabbix-appliance