[PYTHON] Understand how Zabbix API works

Introduction

Zabbix can be operated through Zabbix API, but for each language [Zabbix API Library](https://www.zabbix. Since there are multiple types of org / wiki / Docs / api / libraries), it is difficult to know which one to use. In addition, Zabbix API has a huge number of methods (Method reference) and options, so any of the various libraries It will be very difficult to select if only the warranty range is used for maintenance.

This is my theory, but I think it's better to understand the book even if it takes time, rather than using a library that does not have a complete picture and no guarantee of maintenance. If you want to use Zabbix API, but you have a hard time with Zabbix API library, it's a mess.

Thankfully, the Zabbix API works very simply. In this article, after discussing Zabbix API, I would like to introduce an implementation that uses Zabbix API to a minimum. If there are any mistakes, I would appreciate it if you could point out kindly.

JSON-RPC 2.0

The Zabbix API uses JSON-RPC 2.0 as the request-response protocol. JSON-RPC is a lightweight Remote Procedure Call (RPC) protocol that does not retain the state of using JSON as the data format. The specs are so short that reading them will be the easiest and most accurate way to understand them. Therefore, only the parts necessary for the later explanation will be explained here.

A JSON-RPC 2.0 request consists of jsonrpc, method, params, and ʻid. jsonrpc is the JSON-RPC version number "2.0" , methodis the name of the procedure to call,params is the argument passed to the called procedure (optional), and ʻid is the request and response string. It is an identifier for attaching and is a value decided on the client side. It's very easy to understand, just send the procedure name and arguments in JSON format.

JSON-RPC2.0 request


{
    "jsonrpc": "2.0",
    "method": "hoge",
    "params": {
        "foo": "bar",
        "spam": "ham"
    },
    "id": 1
}

On the other hand, the JSON-RPC 2.0 response consists of jsonrpc, result or ʻerror, ʻid. jsonrpc is the JSON-RPC version number"2.0", result is the return value if the request succeeds, ʻerror is the error information if the request fails, and ʻid corresponds to the request. It will be the same value as the identifier to be used. Like the request, the result or error is just returned in JSON format, which is very easy to understand.

JSON on success-RPC2.0 response


{
    "jsonrpc": "2.0",
    "result": "hoge",
    "id": 1
}

JSON on failure-RPC2.0 response


{
    "jsonrpc": "2.0",
    "error": {
        "code": -32602,
        "message": "Invalid params",
        "data": "hogehoge"
    },
    "id": 1
}

Zabbix API

The only difference between the Zabbix API and the JSON-RPC 2.0 section is that the request contains ʻauth. ʻAuth is a token for user authentication, which can be obtained by hitting the ʻuser.login method in Zabbix API. When hitting the ʻuser.login method, ʻauth can be null`.

json:Request example in Zabbix API(www.zabbix.com/documentation/2.2/manual/From api)


{
    "jsonrpc": "2.0",
    "method": "user.login",
    "params": {
        "user": "Admin",
        "password": "zabbix"
    },
    "id": 1,
    "auth": null
}

json:Response example in Zabbix API(www.zabbix.com/documentation/2.2/manual/From api)


{
    "jsonrpc": "2.0",
    "result": "0424bd59b807674191e7d77572075f33",
    "id": 1
}

If you can get a token as the return value of the ʻuser.login method, all you have to do is put the token in ʻauth and interact with it according to the JSON-RPC 2.0 request-response mechanism.

json:Request example in Zabbix API when auth is specified(www.zabbix.com/documentation/2.2/manual/From api)


{
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
        "output": [
            "hostid",
            "host"
        ],
        "selectInterfaces": [
            "interfaceid",
            "ip"
        ]
    },
    "id": 2,
    "auth": "0424bd59b807674191e7d77572075f33"
}

json:Response example in Zabbix API when auth is specified(www.zabbix.com/documentation/2.2/manual/From api)


{
    "jsonrpc": "2.0",
    "result": [
        {
            "hostid": "10084",
            "host": "Zabbix server",
            "interfaces": [
                {
                    "interfaceid": "1",
                    "ip": "127.0.0.1"
                }
            ]
        }
    ],
    "id": 2
}

Implementation that uses Zabbix API to a minimum

If you want to use Zabbix API to the minimum, it is enough to create the following class. Authenticate at the time of instance creation, hold the token in the instance, and after that, give method and params appropriately and receive the response. The response should contain result on success and ʻerror` on failure, so branch and process.

Code snippets that use the Zabbix API to a minimum and examples of their use


# -*- coding: utf-8 -*-

import json
import urllib
import urllib2


class ZabbixApi(object):
    def __init__(self, host, user, password):
        """Returns Zabbix API instance

        :param host:IP address of Zabbix server
        :param user:Zabbix API access user
        :param password:Zabbix API access user password
        :return:
        """
        self.request_id = 1
        self.host = host
        self.auth_token = self.request('user.login', {'user': user, 'password': password})


    def request(self, method, params, auth_token=None):
        """Send a request to Zabbix API
Since id is not currently required, the incremented value is simply substituted.

        :param method:Zabbix API method name
        :param params:Zabbix API method arguments
        :param auth_token:Zabbix API authentication token
        :return: JSON-RPC2.0 format response
        """
        if hasattr(self, 'auth_token'):
            auth_token = self.auth_token
        headers = {"Content-Type": "application/json-rpc"}
        uri = "http://{0}/zabbix/api_jsonrpc.php".format(self.host)
        data = json.dumps({'jsonrpc': '2.0',
                           'method': method,
                           'params': params,
                           'auth': auth_token,
                           'id': self.request_id})
        request = urllib2.Request(uri, data, headers)
        self.request_id += 1
        return json.loads(urllib2.urlopen(request).read())


if __name__ == '__main__':
    api = ZabbixApi(192.168.0.2, 'Admin', 'zabbix')
    response = api.request('host.get', {'output': 'hostid', 'search': {'host': 'hoge'}})
    if 'result' in response:
        pass #Processing on success
    elif 'error' in response:
        pass #Processing at the time of failure
    else:
        pass #Processing at the time of failure

In fact, some Zabbix API libraries are just code with the above content. So, as long as you understand JSON-RPC 2.0 and ʻauth`, it may be easier later to implement the lightweight implementation you need, rather than deploying unnecessary libraries.

Summary

In this article, I briefly explained JSON-RPC 2.0 used by Zabbix API, touched on how Zabbix API works, and introduced the implementation to use Zabbix API to the minimum.

The Zabbix API documentation is so huge that you might be overwhelmed by the amount and think it's difficult, but when you sit down and look at it, it's really simple and easy to understand. It's difficult to know what kind of arguments should be passed to the method ...

We hope that this article will lower the hurdles to Zabbix API and lead to more secure operation.

Recommended Posts

Understand how Zabbix API works
Understand how Go's defer works
Hit Zabbix API (1.8, 2.0)
How Python module import works
Understand how to use django-filter
Get information with zabbix api
Zabbix API this and that
How to use OpenPose's Python API
Understanding how it works Twilio # 1-Introduction
How to use bing search api
[Python] How to use Typetalk API