採用情報 お問い合わせ

BLOG

API を活用した Zabbix のホスト管理

はじめに

Zabbix で監視をする際に、設定の導入や変更など、Web フロントエンドからの操作だけでは時間がかかってしまうことがあります。Zabbix の API(Application Programing Interface) では、ホストやアイテムなどの作成、削除、一括更新などを行えるため、時間の短縮や管理を容易にすることができる場合があります。

本記事では、CSV ファイルにホストの情報を記載し、Zabbix の API を使用した Python スクリプトでホストを一括作成する例を紹介します。

本記事内での表記・用語について

表記・用語 解説
Zabbix Zabbix LLC 社が提供しているオープンソースの統合監視ソフトウェアを指します。
Zabbix として実装されている機能全般を指す場合にも本表記を適用します。
MIRACLE ZBX Zabbix をベースに、サイバートラストが機能強化・修正を加えてオープンソースとして提供するエンタープライズ向けの統合システム監視ソフトウェアです。

本ソフトウェアは、Zabbix の開発元である Zabbix LLC 社が推奨もしくはサポート提供やスポンサーしているものではありません。

Zabbix API

Zabbix では JSON 形式のデータを HTTP の POST リクエストでおくることで API を呼び出すことができます。Zabbix の API には、ホストやアイテムの作成や更新、取得など多くの種類の API メソッドがあります。
例として、Zabbix にログインし、API を使用する際に必要な認証の API トークンを取得する user.login を curl コマンドで実行する場合は以下のようになります。

# curl --request POST --url '/api_jsonrpc.php'
--header 'Content-Type: application/json-rpc'
--data '{"jsonrpc":"2.0","method":"user.login","params":{"username":"< ユーザー名 >","password":"< パスワード >"},"id":1}'

上記を実行すると以下のようなレスポンスを取得できます。基本的に result に各 API の結果が格納されます。

{"jsonrpc":"2.0","result":"<API トークン >","id":1}

API トークンを取得した後、他 API メソッドを利用する場合、以下のような認証のためのヘッダーを追加する必要があります。

--header 'Authorization: Bearer <API トークン >'

Zabbix API を使用するため、例にあげた HTTP リクエストの中でユーザー毎に変更する必要のある項目は以下です。

パラメーター 説明
url Zabbix API の URL を指定します。基本的に /api_jsonrpc.php は変わらず、前半部分を環境に応じて変更します。
例 : http://127.0.0.1/zabbix/api_jsonrpc.php
data 内の method 使用したい Zabbix API のメソッドを指定します。
data 内の params Zabbix API のメソッドごとに必要な値を指定します。

事前準備

はじめに、バージョン 7.0.x の MIRACLE ZBX サーバーと MIRACLE ZBX Web フロントエンドを構築してください。構築方法は以下のページを参照してください。

今回は以下の環境を使用しています。

OS Alma Linux 9.4
MIRACLE ZBX バージョン 7.0.18-2
データベース MariaDB
Web サーバー Apache
Python バージョン 3.9.18

続いて、ホストの情報を記載した CSV ファイルを用意してください。
1 行目にパラメータ名、2 行目以降に各パラメータの値を入力して各ホスト毎に入力します。オブジェクト型のパラメータは JSON 形式で記入してください。

以下は今回使用した CSV です。

host groups templates interfaces
test host1 [{"groupid": "4"}] [{"templateid": "10001"}] [{"type": 1, "main": 1, "useip": 1, "ip": "127.0.0.1", "dns": "", "port": "10050", "interfaceid": 52}]
test host2 [{"groupid": "4"}] [{"type": 1, "main": 1, "useip": 1, "ip": "127.0.0.1", "dns": "", "port": "10050", "interfaceid": 53}]
test host3 [{"groupid": "4"}]
host,groups,templates,interfaces
test host1,"[
{""groupid"": ""4""}
]","[{""templateid"": ""10001""}]","[{""type"": 1,""main"": 1, ""useip"": 1,""ip"": ""127.0.0.1"",""dns"": """",""port"":""10050"",""interfaceid"":52}]"
test host2,"[
{""groupid"": ""4""}
]",,"[{""type"": 1,""main"": 1, ""useip"": 1,""ip"": ""127.0.0.1"",""dns"": """",""port"":""10050"",""interfaceid"":53}]"
test host3,"[
{""groupid"": ""4""}
]",,

Zabbix API でホストを作成するスクリプト

本章では、実際に Zabbix API を使用してホストを作成する例を紹介します。

内容

ホスト情報が書かれた CSV を読み込み、Zabbix API でホストを作成するスクリプトです。

#!/usr/bin/env python3

import csv
import json
import argparse
import ssl
from urllib.request import urlopen, Request


class ZabbixAPI:
    def __init__(self, url, username, password):
        # リクエストを送る URL の作成
        self.api_url = f"{url}/api_jsonrpc.php"
        self.api_token = None
        # 認証のための API トークンを取得
        if username and password:
            self.login(username, password)

    def login(self, username, password):
        params = {
                "username": username,
                "password": password
        }
        # ログインし、認証トークンを取得
        self.api_token = self._request("user.login", params)

    def logout(self):
        params = "[]"
        # ログアウト
        self._request("user.logout", params)

    def _request(self, method, params):
        # リクエストの作成
        request = Request(
                url=self.api_url,
                data=json.dumps({
                    "jsonrpc":  "2.0",
                    "method":   method,
                    "params":   params,
                    "id":       1
                }).encode(),
                headers={"Content-Type": "application/json-rpc"})
        # 認証トークンを取得済の場合はヘッダーに追加
        if self.api_token is not None:
            request.add_header("Authorization", "Bearer " + self.api_token)
        # HTTPS 向けに設定
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        # リクエストを送信
        response = json.loads(urlopen(request, context=ctx).read().decode("utf-8"))
        if "error" in response:
            self.logout
            raise Exception(f"Zabbix API error: {response['error']}")
        return response["result"]

    def create_host(self, file):
        # host.create のオブジェクト型のパラメータ
        object_parameter = ["groups",
                            "interfaces",
                            "tags",
                            "templates",
                            "macros",
                            "inventory"]
        # csv ファイルを取得し、辞書型で格納
        with open(file) as f:
            reader = csv.DictReader(f)
            hosts = [row for row in reader]
        for host in hosts:
            for param in list(host.keys()):
                # 該当ホストに存在しないパラメータは削除
                if not host[param]:
                    del host[param]
                # オブジェクト型のパラメータは辞書型で格納
                elif param in object_parameter:
                    host[param] = json.loads(host[param])
            print(self._request("host.create", host))


def get_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--url",      required=True,  help="Zabbix URL (e.g. https://127.0.0.1/zabbix)")
    parser.add_argument("--username", required=True,  help="Zabbix username")
    parser.add_argument("--password", required=True,  help="Zabbix password")
    parser.add_argument("--file",     required=True,  help="CSV file path")
    return parser.parse_args()


args = get_args()
api = ZabbixAPI(args.url, args.username, args.password)
api.create_host(args.file)
api.logout

実行例

本節では、前節に記載したスクリプトの実行方法と結果の例を説明します。
スクリプト実行時には以下のオプションが必要です。

オプション 説明
--url Zabbix の URL を指定します。例 : https://127.0.0.1/zabbix
--username Zabbix のユーザー名を指定します。
--password Zabbix のパスワードを指定します。
--file 2 章の事前準備で示した構成の CSV ファイルのパスを指定します。

以下のように実行します。

# python3 create_host.py --url <Zabbix の URL> --username <Zabbix のユーザー名 > --password <Zabbix のパスワード > --file <csv ファイルのパス >

実行し、ホストの ID が表示され、エラー無く完了すると以下のようにホストが追加されます。

 ホストの設定画面

使用した Zabbix API のメソッド

スクリプトで使用した Zabbix API のメソッドは以下です。

メソッド名 説明
user.login Zabbix のユーザー名とパスワードでログインし、API トークンを取得するメソッドです。取得した API トークンをヘッダーに与えることで、他メソッドを使用できます。
user.logout ログアウトし、API トークンを無効にするメソッドです。
host.create 与えたパラメータのホストを作成するメソッドです。

説明

本節ではスクリプトの内容について解説します。
まず、今回のスクリプトでは以下の流れで処理をしています。

  1. オプションで受け取った Zabbix の URL、ユーザー名、パスワードで Zabbix API の user.login を使し、API トークンを取得
  2. ホスト情報がかかれた CSV ファイルを読み取り辞書型として格納
  3. 格納したホスト情報から Zabbix API の host.create を使用し、1 ホストずつ作成
  4. すべてのホスト作成が完了した後、user.logout で API トークンを無効化

続いて、スクリプト内の重要なメソッドについて説明します。

_request メソッド

実際に Zabbix API を使用するため、Zabbix に HTTP リクエストを送信し、レスポンスを取得するメソッドです。

def _request(self, method, params):
        # リクエストの作成
        request = Request(
                url=self.api_url,
                data=json.dumps({
                    "jsonrpc":  "2.0",
                    "method":   method,
                    "params":   params,
                    "id":       1
                }).encode(),
                headers={"Content-Type": "application/json-rpc"})
        # 認証トークンを取得済の場合はヘッダーに追加
        if self.api_token is not None:
            request.add_header("Authorization", "Bearer " + self.api_token)
        # HTTPS 向けに設定
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        # リクエストを送信
        response = json.loads(urlopen(request, context=ctx).read().decode("utf-8"))
        if "error" in response:
            self.logout
            raise Exception(f"Zabbix API error: {response['error']}")
        return response["result"]

引数として method に実行する ZabbixAPI のメソッド、params に Zabbix API に与えるパラメータを辞書型で渡します。

最初に、Zabbix に送信するための HTTP リクエストを作成しています。例として user.login の場合は以下のような内容になっています。

url '/api_jsonrpc.php'
data '{"jsonrpc":"2.0","method":"user.login","params":{"username":"","password":""},"id":1}'
header 'Content-Type: application/json-rpc'

user.login で API トークンを取得済みの場合は、以下のヘッダーを追加します。

header 'Authorization: Bearer <API トークン >'

HTTPS 向けの設定を行い、実際に HTTP リクエストを送信します。その後レスポンスの result を返します。失敗した場合は、ログアウトし、エラーを出力します。

create_host メソッド

CSV ファイルを読み取り、取得したデータを辞書型に格納し、_request メソッドで host.create を実行するメソッドです。

def create_host(self, file):
        # host.create のオブジェクト型のパラメーター
        object_parameter = ["groups",
                            "interfaces",
                            "tags",
                            "templates",
                            "macros",
                            "inventory"]
        # csv ファイルを取得し、辞書型で格納
        with open(file) as f:
            reader = csv.DictReader(f)
            hosts = [row for row in reader]
        for host in hosts:
            for param in list(host.keys()):
                # 該当ホストに存在しないパラメーターは削除
                if not host[param]:
                    del host[param]
                # オブジェクト型のパラメーターは辞書型で格納
                elif param in object_parameter:
                    host[param] = json.loads(host[param])
            print(self._request("host.create", host))

まず、CSV ファイルを読み込み、行ごとに辞書型で格納します。1 行目はパラメーター名はキー、2 行目以降は各ホストの値として格納されます。
ホスト毎に for 文で回し、値が存在しないパラメーターは削除、オブジェクト型のパラメーターは JSON の 2 重エンコードにならないよう辞書型として再度格納します。
その後、_request メソッドに渡すことで host.create を実行し、ホストを作成します。

まとめ

Zabbix API の host.create を使用し、CSV から読み込んだホスト情報からホストを作成する方法を紹介しました。Zabbix API を活用することで CSV ファイルで作成するホストの情報を管理し、一括作成することができます。
また、CSV ファイルに格納する内容や、スクリプトの内容を変更することで、ホスト以外の作成や更新、削除なども行うことができます。
最後に、サイバートラストでは Zabbix をベースに機能強化・修正を加えたエンタープライズ向けの統合システム監視ソフトウェアである MIRACLE ZBX を開発・提供しています。ホストやアイテムなど設定のバックアップを行うオプション製品なども提供しておりますので、ご興味がある方はお問い合わせフォームからお気軽にお問い合わせください。

免責事項

本記事は、Zabbix API 使用方法の一例として情報提供を目的としたものであり、本記事に基づいて構築された監視体制による運用結果、あるいは それに伴って発生したいかなる損害に関しても、当方は一切の責任を負いません。読者各位の判断と責任においてご活用ください。

本記事に関連するリンク
CentOS 7 延長サポートサービス
デジタルトランスフォーメーションのための電子認証基盤 iTrust
iTrust SSL/TLS サーバー証明書