【5.0対応済】Python3でZabbix API – ホストの一覧を取得

2020年9月8日Python,Zabbix,Zabbix API

こんにちは。プラットフォーム技術部の飯出(いいで)です。

Zabbix APIの紹介記事も第3弾となりました。以前より読んでいただいている方は、Python3を使ったZabbix APIの呼び出し方も理解いただけたと思います。この記事からは実践編と題しまして「Zabbix APIを使ったホスト一覧の取得方法」について、解説します。

この記事の実装サンプルでは、以前の記事で実装した内容を再利用して説明しています。Googleなどの検索結果から直接この記事に訪れた方は、一度、以下の記事を読んでいただけますと幸いです。

ホスト1台の情報を取得する

手始めに、Zabbix APIを使ってホスト1台の情報を取得します。使用するメソッドは、host.getです。公式のマニュアルはこちらです。

要求フォーマット

{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
        "filter": {
            "host": [
                "Zabbix server"
            ]
        }
    },
    "auth": "********************************",
    "id": 1
}

応答フォーマット

{
    "jsonrpc": "2.0",
    "result": [
        {
            "hostid": "10160",
            "proxy_hostid": "0",
            "host": "Zabbix server",
            "status": "0",
            "disable_until": "0",
            "error": "",
            "available": "0",
            "errors_from": "0",
            "lastaccess": "0",
            "ipmi_authtype": "-1",
            "ipmi_privilege": "2",
            "ipmi_username": "",
            "ipmi_password": "",
            "ipmi_disable_until": "0",
            "ipmi_available": "0",
            "snmp_disable_until": "0",
            "snmp_available": "0",
            "maintenanceid": "0",
            "maintenance_status": "0",
            "maintenance_type": "0",
            "maintenance_from": "0",
            "ipmi_errors_from": "0",
            "snmp_errors_from": "0",
            "ipmi_error": "",
            "snmp_error": "",
            "jmx_disable_until": "0",
            "jmx_available": "0",
            "jmx_errors_from": "0",
            "jmx_error": "",
            "name": "Zabbix server",
            "description": "The Zabbix monitoring server.",
            "tls_connect": "1",
            "tls_accept": "1",
            "tls_issuer": "",
            "tls_subject": "",
            "tls_psk_identity": "",
            "tls_psk": ""
        }
    ],
    "id": 1
}

なんとなくホストの情報が取得できるのがわかりますが…説明しよう!(戦隊モノ風)

ホスト情報の概要(Host Object)

公式のマニュアルはこちらです。

英語だとわかりにくいので、日本語化してみました。

プロパティ宣言型説明
hostidstringホストのID(読取専用)
host(必須)stringホストの名前
availableintegerZabbixエージェントの状態(読取専用)
・0: 不明(規定値)
・1: 利用可
・2: 利用不可
descriptiontextホストの説明
disable_untiltimestampZabbixエージェントが利用できない場合における次回のポーリング時間
(読取専用)
errorstringZabbixエージェントが利用できない場合におけるエラーテキスト
(読取専用)
errors_fromtimestampZabbixエージェントが利用できなくなった時間(読取専用)
flagsintegerこのホストがどのように登録されたか(読取専用)
・0: 一般的な登録
・4: ディスカバリによる登録
inventory_modeintegerホストインベントリ: 作成モード
・-1: 無効(規定値)
・ 0: マニュアル
・ 1: 自動
ipmi_authtypeintegerIPMI: 認証アルゴリズム
・-1: 標準(規定値)
・ 0: なし
・ 1: MD2
・ 2: MD5
・ 4: Straight
・ 5: OEM
・ 6: RMCP+
ipmi_availableintegerZabbixエージェントの状態(読取専用)
・0: 不明(規定値)
・1: 利用可
・2: 利用不可
ipmi_disable_untiltimestampIPMIエージェントが利用できない場合における次回のポーリング時間
(読取専用)
ipmi_errorstringIPMIエージェントが利用できない場合におけるエラーテキスト
(読取専用)
ipmi_errors_fromtimestampIPMIエージェントが利用できなくなった時間(読取専用)
ipmi_passwordstringIPMI: パスワード
ipmi_privilegeintegerIPMI: 特権レベル
・1: コールバック
・2: ユーザー
・3: オペレータ
・4: Admin
・5: OEM
ipmi_usernamestringIPMI: ユーザー名
jmx_availableintegerJMXエージェントの状態(読取専用)
・0: 不明(規定値)
・1: 利用可
・2: 利用不可
jmx_disable_untiltimestampJMXエージェントが利用できない場合における次回のポーリング時間
(読取専用)
jmx_errorstringJMXエージェントが利用できない場合におけるエラーテキスト
(読取専用)
jmx_errors_fromtimestampJMXエージェントが利用できなくなった時間(読取専用)
maintenance_fromtimestampメンテナンスの開始時間(読取専用)
maintenance_statusintegerメンテナンスの状況(読取専用)
・0: メンテナンスなし(規定値)
・1: メンテナンスが有効になっている
maintenance_typeintegerメンテナンス時におけるデータ収集状態(読取専用)
・0: データ収集あり(規定値)
・1: データ収集なし
maintenanceidstringホスト上で現在有効になっているメンテナンスのID(読取専用)
namestringホストの表示名
proxy_hostidstringホストの監視に用いるプロキシのID
snmp_availableintegerSNMPエージェントの状態(読取専用)
・0: 不明(規定値)
・1: 利用可
・2: 利用不可
snmp_disable_untiltimestampSNMPエージェントが利用できない場合における次回のポーリング時間
(読取専用)
snmp_errorstringSNMPエージェントが利用できない場合におけるエラーテキスト
(読取専用)
snmp_errors_fromtimestampSNMPエージェントが利用できなくなった時間(読取専用)
statusintegerホストの状態
・0: 監視されている(規定値)
・1: 監視されていない
tls_connectinteger暗号化: ホストへの接続
tls_acceptinteger暗号化: ホストからの接続
tls_issuerstring暗号化: 証明書の発行者
tls_subjectstring暗号化: 証明書のサブジェクト
tls_psk_identitystring暗号化: PSKアイデンティティ
tls_pskstring暗号化: PSK

ホスト「Zabbix server」を取得する

では、ホストの情報を実際に取得してみましょう。

Zabbix Applianceの構築時に設定されているホスト「Zabbix server」の情報を取得します。実装の土台には、前回の記事で紹介した「ログイン~ログアウト、一連の流れ」を使います。前回の記事はこちらです。

プログラム

以下のプログラムの中で、ハイライトしている部分がホスト固有の実装です。Zabbixサーバーに情報を取得したいホスト名を渡すと、Zabbixサーバーの応答(result)の中に配列(list)、その中に辞書(dictionary)を格納した階層構造でホスト情報を返却します。

「今回はホスト1台分の情報を取得するのでは?」と思われるかもしれませんが、Zabbix APIはホストの台数に関係なく、配列の中に情報を格納してきます。

import os
import traceback
from function import login, logout, invoke
 
def main():
    server = "http://hostname/zabbix"
    user = "Admin"
    password = "******"
    session_id = ""
 
    hostname = [
        "Zabbix server"
    ]
 
    try:
        session_id = login(server, user, password)
        if 0 < len(session_id):
            request = {
                "jsonrpc": "2.0",
                "method": "host.get",
                "params": {
                    "filter": {
                        "host": hostname
                    }
                },
                "auth": session_id,
                "id": 1
            }
 
            response = {}
            if invoke(server, request, response):
                for item in response["result"]:
                    for key, value in item.items():
                        print("{}: {}".format(key, value))
 
            else:
                print("{}: error: message={}, data={}, code={}".format(
                    os.path.basename(__file__),
                    response["error"]["message"],
                    response["error"]["data"],
                    response["error"]["code"])
                )
 
    except Exception as e:
        print("{}: exception: {}".format(
            os.path.basename(__file__),
            traceback.format_exc())
        )
 
    finally:
        if 0 < len(session_id):
            # ログインしたら、忘れずにログアウトしましょう
            logout(server, session_id)

if __name__ == "__main__":
    main()

実行結果

PS C:\zabbixapi\sample> python3 .\sample-03.py
hostid: 10084
proxy_hostid: 0
host: Zabbix server
status: 0
disable_until: 0
error:
available: 1
errors_from: 0
lastaccess: 0
ipmi_authtype: -1
ipmi_privilege: 2
ipmi_username:
ipmi_password:
ipmi_disable_until: 0
ipmi_available: 0
snmp_disable_until: 0
snmp_available: 0
maintenanceid: 0
maintenance_status: 0
maintenance_type: 0
maintenance_from: 0
ipmi_errors_from: 0
snmp_errors_from: 0
ipmi_error:
snmp_error:
jmx_disable_until: 0
jmx_available: 0
jmx_errors_from: 0
jmx_error:
name: Zabbix server
flags: 0
templateid: 0
description:
tls_connect: 1
tls_accept: 1
tls_issuer:
tls_subject: 
tls_psk_identity:
tls_psk:
proxy_address:
auto_compress: 1
discover: 0
inventory_mode: -1

「Zabbix server」のホスト情報がちゃんと取得できましたね!

「応答の数値がわかりづらい」と思った方へ

「Zabbix APIの応答結果が数値でわかりづらい」と思う方は少なくないと思います。この場合において、Zabbix APIはいわゆる区分値を応答しています。この区分値の定義ですが、defines.inc.phpに実装があります。Zabbixのソースコードをダウンロードしてファイルを解凍すると、ui/includeディレクトリの中にあります。

例えば、ipmi_authtypeの区分値はどのようになっているか、以下に抜粋します。

// IPMI
define('IPMI_AUTHTYPE_DEFAULT',		-1);
define('IPMI_AUTHTYPE_NONE',		0);
define('IPMI_AUTHTYPE_MD2',			1);
define('IPMI_AUTHTYPE_MD5',			2);
define('IPMI_AUTHTYPE_STRAIGHT',	4);
define('IPMI_AUTHTYPE_OEM',			5);
define('IPMI_AUTHTYPE_RMCP_PLUS',	6);
    

これをPython3で実装しましょう。そう、Enumを定義します。

import enum

class IPMIAuthType(enum.IntEnum):
    DEFAULT = -1
    NONE = 0
    MD2 = 1
    MD5 = 2
    STRAIGHT = 3
    OEM = 4
    RMCP_PLUS = 5
    

定義したEnumは、以下のように使います。

ipmi_authtype = IPMIAuthType(int(response["result"][0]["ipmi_authtype"]))

print(ipmi_authtype)
print(ipmi_authtype.value)

実行結果は以下のとおりです。区分値の名前も値も出力できます。

IPMIAuthType.DEFAULT
-1

実装量は増えてしまいますが、見やすくなりましたね。

取得したホスト情報をCSV形式に変換する

このままでは実用に耐えないので、Excelなどで読み込みやすいようにカンマ区切り(CSV形式)でホストの情報を出力してみたいと思います。以下のプログラムでハイライトしている部分を改造しています。

プログラム

import os
import traceback
from function import login, logout, invoke

def main():
    server = "http://hostname/zabbix"
    user = "Admin"
    password = "******"
    session_id = ""

    hostname = [
        "Zabbix server"
    ]

    try:
        session_id = login(server, user, password)
        if 0 < len(session_id):
            request = {
                "jsonrpc": "2.0",
                "method": "host.get",
                "params": {
                    "filter": {
                        "host": hostname
                    }
                },
                "auth": session_id,
                "id": 1
            }

            response = {}
            if invoke(server, request, response):
                is_first = True
                for item in response["result"]:
                    if is_first:
                        print(",".join(item.keys()).rstrip())
                        is_first = False
                    
                    print(",".join(item.values()).rstrip())

            else:
                print("{}: error: message={}, data={}, code={}".format(
                    os.path.basename(__file__),
                    response["error"]["message"],
                    response["error"]["data"],
                    response["error"]["code"])
                )
            
    except Exception as e:
        print("{}: exception: {}".format(
            os.path.basename(__file__),
            traceback.format_exc())
        )

    finally:
        if 0 < len(session_id):
            # ログインしたら、忘れずにログアウトしましょう
            logout(server, session_id)

if __name__ == "__main__":
    main()

これで先頭行にヘッダーを、2行目以降にホストの情報を出力できました。実行結果は割愛します(ブログのスタイルでは見づらい・読みづらい)が、出力結果を一度テキストファイルに貼り付けて保存した後に、Excelで開くと表ができあがります。

ホストの一覧を取得する

やっと本題にたどり着きました(汗)
でも、ここまで来ればホストの一覧を簡単に取得できるようになっています。早速実装しましょう!

要求フォーマット

{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
        "output": "extend"
    },
    "auth": "********************************",
    "id": 1
}

応答フォーマット

ホスト1台の情報を取得したときと同じ。

プログラム

以下のプログラムでハイライトしている部分を改造しています。また、ホスト名を指定する必要が無くなりましたので、ホスト名の配列(hostname = [ “Zabbix server" ])も削除しました。

import os
import traceback
from function import login, logout, invoke
 
def main():
    server = "http://hostname/zabbix"
    user = "Admin"
    password = "******"
    session_id = ""
 
    try:
        session_id = login(server, user, password)
        if 0 < len(session_id):
            request = {
                "jsonrpc": "2.0",
                "method": "host.get",
                "params": {
                    "output": "extend"
                },
                "auth": session_id,
                "id": 1
            }
 
            response = {}
            if invoke(server, request, response):
                is_first = True
                for item in response["result"]:
                    if is_first:
                        print(",".join(item.keys()).rstrip())
                        is_first = False
                     
                    print(",".join(item.values()).rstrip())
 
            else:
                print("{}: error: message={}, data={}, code={}".format(
                    os.path.basename(__file__),
                    response["error"]["message"],
                    response["error"]["data"],
                    response["error"]["code"])
                )
             
    except Exception as e:
        print("{}: exception: {}".format(
            os.path.basename(__file__),
            traceback.format_exc())
        )
 
    finally:
        if 0 < len(session_id):
            # ログインしたら、忘れずにログアウトしましょう
            logout(server, session_id)

if __name__ == "__main__":
    main()

ホストの一覧を取得できました。これで監視対象ホストの管理簿を簡単に作れますね!今回の実装は、ここまで。

Zabbix 4.0→5.0の変更点

バージョン5.0でホスト情報を取得する際における変更点の中で、特にZabbix API呼び出しに影響がある点について、紹介します。バージョン4.2ならびに4.4で追加となった機能もありますが、当社ではLTS版単位でバージョンアップ情報を扱っています。

ホスト情報にタグが追加

バージョン5.0からホスト情報にタグが指定できるようになった関係で、Zabbix APIにおけるホスト情報の取得時にタグが取得できるようになりました。要求フォーマットに以下でハイライトしている部分の構文を追加することによって、ホスト情報の取得時にホストに指定したタグの一覧を取得できます。

要求フォーマット

{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
        "output": "extend",
        "selectTags": [
            "tag", "value"
        ]
    },
    "auth": "********************************",
    "id": 1
}

応答パラメーター「inventory_mode」の取得方法が変わった

バージョン5.0から応答パラメーター「inventory_mode」の取得方法が変わりました。バージョン4.0までは、ホストインベントリ情報に格納されていた本パラメーターですが、バージョン5.0より取得位置が変更となり、ホスト情報の中に含まれています。

なお、ホストインベントリ情報からは取得できなくなっていますので、Zabbix APIを使ってホストインベントリ情報を取得している方はご注意ください。なお、Zabbix APIを使ったホストインベントリ情報の取得方法については後日、別の記事で紹介できたらと思います。

まとめ

この記事では、Zabbix APIを呼び出して監視対象のホスト一覧を取得する実装について紹介しました。ネットワークディスカバリを使用してホストの登録を自動化している環境などでは、監視対象ホストの棚卸し作業などを実施する場合に有効活用できるのではないでしょうか。

次回は「ホストを登録する方法」を紹介したいと思います。

アークシステムは Zabbix Japan LLC の認定パートナー企業です。 当社はZabbixバージョン1.1の時代から監視ソリューションの活用を進め、Zabbixに関する製品・サービスの販売に加え、Zabbix関連サービスの提供を行っています。

Zabbixに関するお問い合わせはこちらからお願いいたします。
  • 株式会社アークシステムの予約・来訪管理システム BRoomHubs
  • 低コスト・短納期で提供するまるごとおまかせZabbix