19. API

Przegląd

Zabbix API umożliwia programowe pobieranie i modyfikowanie konfiguracji Zabbix oraz zapewnia dostęp do danych historycznych. Jest szeroko stosowany do:

  • Tworzenia nowych aplikacji do pracy z Zabbix;
  • Zintegracji Zabbix z oprogramowaniem innych firm;
  • Automatyzacja rutynowych zadań.

API Zabbix jest interfejsem API opartym na sieci Web i jest dostarczany jako część interfejsu WWW. Wykorzystuje protokół JSON-RPC 2.0, co oznacza dwie rzeczy:

  • API składa się z zestawu oddzielnych metod;
  • Żądania i odpowiedzi między klientami a interfejsem API są kodowane przy użyciu formatu JSON.

Więcej informacji o protokole i JSON można znaleźć w specyfikacji JSON-RPC 2.0 i strony głównej formatowania JSON.

Aby uzyskać więcej informacji na temat integracji funkcjonalności Zabbix z aplikacjami w języku Python, zobacz bibliotekę Pythona zabbix_utils dla interfejsu API Zabbix.

Struktura

API składa się z wielu metod, które są nominalnie pogrupowane w oddzielne interfejsy API. Każda z metod wykonuje jedno określone zadanie. Na przykład metoda host.create należy do API host i jest używana do tworzenia nowych hostów. W przeszłości interfejsy API były czasami określane jako „klasy”.

Większość interfejsów API zawiera co najmniej cztery metody: get, create, update i delete do odpowiednio: pobierania, tworzenia, aktualizowania i usuwania danych, ale niektóre interfejsy API mogą zapewniać całkowicie inne zestawy metod.

Wykonywanie zapytań

Po skonfigurowaniu frontend możesz używać zdalnych żądań HTTP do wywołania API. Aby to zrobić musisz wysłać żądanie HTTP POST do pliku api_jsonrpc.php znajdującego się w katalogu frontendu. Na przykład, jeśli twój interfejs Zabbix jest zainstalowany pod adresem http://example.com/zabbix, żądanie HTTP wywołujące metodę apiinfo.version może wyglądać następująco:

POST http://example.com/zabbix/api_jsonrpc.php HTTP/1.1
       Content-Type: application/json-rpc
       
       {
        · "jsonrpc": "2.0",
        · "method": "apiinfo.version",
        · "id": 1,
        · "auth": null,
        · "params": {}
       }

Żądanie musi zawierać nagłówek Content-Type ustawiony na jedną z następujących wartości: application/json-rpc, application/json lub application/jsonrequest.

Przykładowy przepływ pracy

W poniższej sekcji znajdziesz więcej szczegółowych przykładów użycia.

Uwierzytelnianie

Aby uzyskać dostęp do jakichkolwiek danych w Zabbix, należy:

  • użyć istniejącego tokenu API (utworzonego w interfejsie Zabbix lub przy użyciu Token API);
  • użyć token uwierzytelniający uzyskanego za pomocą metodyuser.login.

Na przykład, jeśli chcesz uzyskać nowy token uwierzytelniający, logując się jako standardowy użytkownik Admin, zapytanie JSON będzie wyglądać następująco:

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

Przyjrzyjmy się bliżej obiektowi z zapytania. Posiada następujące właściwości:

  • jsonrpc - wersja protokołu JSON-RPC używana przez API; API Zabbix używa JSON-RPC w wersji 2.0;
  • method - wywoływana metoda API;
  • params - parametry, które zostaną przekazane do metody API;
  • id - dowolny identyfikator żądania;
  • auth - token uwierzytelniający użytkownika; jeżeli jeszcze nie istnieje, jest ustawiony na null.

Jeżeli poprawnie podano poświadczenia, odpowiedź zwrócona przez API będzie zawierać token uwierzytelniający użytkownika:

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

Obiekt w odpowiedzi z kolei zawiera następujące właściwości:

  • jsonrpc - ponownie, wersja protokołu JSON-RPC;
  • result - dane zwrócone przez metodę;
  • id - identyfikator odpowiedniego żądania.

Pobieranie hostów

Mamy teraz prawidłowy token uwierzytelniający użytkownika, który możemy użyć do dostępu do danych w Zabbix. Na przykład użyjmy metody host.get do pobrania identyfikatorów IDs, nazw hostów i interfejsów wszystkich skonfigurowanych hosts:

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

Zauważ, że własność auth jest teraz ustawiona na token uwierzytelniający, który uzyskaliśmy przez wywołanie user.login.

Obiekt odpowiedzi będzie zawierać żądane dane o hostach:

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

Ze względu na wydajność zalecamy zawsze wymieniać własności obiektu które chcesz pobrać aby uniknąć pobierania wszystkiego.

Tworzenie nowego elementu

Utwórzmy nowy element item na "serwerze Zabbix" używając danych uzyskanych z poprzedniego żądania host.get. Można to zrobić przy użyciu metody item.create:

{
           "jsonrpc": "2.0",
           "method": "item.create",
           "params": {
               "name": "Wolna przestrzen dyskowa w /home/joe/",
               "key_": "vfs.fs.size[/home/joe/,free]",
               "hostid": "10084",
               "type": 0,
               "value_type": 3,
               "interfaceid": "1",
               "delay": 30
           },
           "auth": "0424bd59b807674191e7d77572075f33",
           "id": 3
       }

Pomyślna odpowiedź będzie zawierała identyfikator ID nowo utworzonego elementu, który można użyć w odniesieniu do tego elementu w następujących żądaniach:

{
           "jsonrpc": "2.0",
           "result": {
               "itemids": [
                   "24759"
               ]
           },
           "id": 3
       }

Metoda item.create jak i inne medoty tworzenia mogą również akceptować tablice obiektów i tworzyć wiele elementów w pojedyńczym wywołaniu API.

Tworzenie wielu wyzwalaczy

Skoro metody tworzenia akceptują tablice, to możemy dodać wiele wyzwalacze tak:

{
           "jsonrpc": "2.0",
           "metoda": "wyzwalacz.utwórz",
           "parametry": [
               {
                   "description": "Obciążenie procesora jest zbyt wysokie na {HOST.NAME}",
                   "expression": "last(/Linux server/system.cpu.load[percpu,avg1])>5",
               },
               {
                   "description": "Zbyt wiele procesów na {HOST.NAME}",
                   "wyrażenie": "avg(/Linux server/proc.num[],5m)>300",
               }
           ],
           "auth": "0424bd59b807674191e7d77572075f33",
           „identyfikator”: 4
       }

Pomyślna odpowiedź będzie zawierać identyfikatory ID nowo utworzonych wyzwalaczy:

{
           "jsonrpc": "2.0",
           "wynik": {
               "wyzwalacze": [
                   "17369",
                   "17370"
               ]
           },
           „id”: 4
       }

Aktualizowanie elementu

Włącz element, czyli ustaw jego status na "0":

{
           "jsonrpc": "2.0",
           "method": "item.update",
           "params": {
               "itemid": "10092",
               "status": 0
           },
           "auth": "0424bd59b807674191e7d77572075f33",
           "id": 5
       }

Pomyślna odpowiedź będzie zawierać identyfikator ID zaktualizowanego elementu:

{
           "jsonrpc": "2.0",
           "result": {
               "itemids": [
                   "10092"
               ]
           },
           "id": 5
       }

Metoda item.update oraz inne metody aktualizacji może akceptować tablicę obiektów i aktualizować wiele elementów w jednym wywołaniu API.

Aktualizowanie wielu wyzwalaczy

Włącz wiele wyzwalaczy, czyli ustaw ich status na 0:

{
           "jsonrpc": "2.0",
           "method": "trigger.update",
           "params": [
               {
                   "triggerid": "13938",
                   "status": 0
               },
               {
                   "triggerid": "13939",
                   "status": 0
               }
           ],
           "auth": "0424bd59b807674191e7d77572075f33",
           "id": 6
       }

Pomyślna odpowiedź będzie zawierać identyfikatory ID zaktualizowanych wyzwalaczy:

{
           "jsonrpc": "2.0",
           "result": {
               "triggerids": [
                   "13938",
                   "13939"
               ]
           },
           "id": 6
       }

To jest preferowana metoda aktualizacji. Niektóre metody API takie jak host.massupdate pozwalają na zapis prostszego kodu, jednakże używanie tych metod nie jest rekomendowane, gdyż zostaną one usunięte w przyszłych wydaniach.

Obsługa błędów

Do tego momentu wszystko, czego próbowaliśmy, działało dobrze. Co się stanie jeśli spróbujemy wykonać nieprawidłowe wywołanie API? Spróbujmy kolejnego hosta wywołując host.create z pominięciem wymaganego parametru groups.

{
           "jsonrpc": "2.0",
           "method": "host.create",
           "params": {
               "host": "Linux server",
               "interfaces": [
                   {
                       "type": 1,
                       "main": 1,
                       "useip": 1,
                       "ip": "192.168.3.1",
                       "dns": "",
                       "port": "10050"
                   }
               ]
           },
           "id": 7,
           "auth": "0424bd59b807674191e7d77572075f33"
       }

Odpowiedź będzie zawierać komunikat o błędzie:

{
           "jsonrpc": "2.0",
           "error": {
               "code": -32602,
               "message": "Invalid params.",
               "data": "No groups for host \"Linux server\"."
           },
           "id": 7
       }

Jeśli wystąpił błąd, zamiast własności result obiekt odpowiedzi będzie zawierał własność error z następującymi danymi:

  • code - kod błędu;
  • message - krótkie podsumowanie błędu;
  • data - bardziej szczegółowy komunikat o błędzie.

Błedy mogą wystąpić w różnych przypadkach, takich jak nieprawidłowe wartości wejściowe, wygaśnięcie sesji lub próby uzyskania dostępu do nieistniejących obiektów. Twoja aplikacja powinna być w stanie płynnie obsłużyć tego rodzajuy błędy.

Wersje API

Aby uprościć wersjonowanie API, od wersji Zabbix 2.0.4, wersja API pasuje do wersji samego Zabbix. Możesz użyć metody apiinfo.version do sprawdzenia wersji interfejsu API, z którym pracujesz. Może być to przydatne przy dostosowaniu aplikacji do korzystania z funkcji specyficznych dla wersji.

Gwarantujemy kompatybilność wsteczną funkcji w głównej wersji. Dokonując zmian niekompatybilnych wstecz między głównymi wersjami, najczęściej pozostawiamy stare funkcje jako przestarzałe w następnej wersji i usuwamy je dopiero w kolejnym wydaniu. Niekiedy możemy usunąć funkcje pomiędzy głównymi wydaniami bez udostępniania wstecznej zgodności. Ważne jest, aby nigdy nie polegać na przestarzałych funkcjach i jak najszybciej migrować do nowszych alternatyw.

Możesz śledzić wszystkie zmiany wprowadzone w API w Dziennik zmian API.

Dalsza lektura

Wiesz już wystarczająco dużo, aby rozpocząć pracę z Zabbix API, ale nie przestawaj tutaj. Jako dalszą lekturę proponujemy spojrzeć na Lista dostępne interfejsów API.