Nel creare una soluzione per il cliente, si sono presentati 2 problemi che volevo risolvere in modo elegante e utilizzando le funzionalità standard di Zabbix.
Problema 1. Monitoraggio della versione attuale del firmware sui router Mikrotik.
Il problema è facilmente risolvibile — aggiungendo al template un agente HTTP. L'agente ottiene la versione attuale dal sito Mikrotik, e un trigger confronta la versione attuale con quella in uso e, in caso di discrepanza, genera un alert.
Quando hai 10 router, questo algoritmo non è critico, ma cosa fare con 3000 router? Inviare 3000 richieste al server? Certo, questa soluzione funzionerebbe, ma l'idea di 3000 richieste non mi soddisfaceva, volevo trovare un'altra soluzione. Inoltre, il difetto di un algoritmo del genere è che il lato opposto potrebbe considerare un tale numero di richieste da un solo IP come un attacco DoS e potrebbe semplicemente bannare l'IP.
Problema 2. Utilizzo della sessione di autorizzazione in diversi agenti HTTP.
Quando è necessario ricevere informazioni da pagine "chiuse" tramite un agente HTTP, è necessaria una cookie di autorizzazione. Di solito, esiste una forma standard di autorizzazione con una coppia "login/password" e l'ID della sessione viene impostato nel cookie.
Ma c'è un problema: non è possibile fare riferimento ai dati di un altro elemento dell'agente HTTP per inserire questo valore nell'intestazione.
Esiste anche uno "Script Web", ma ha un'altra limitazione: non consente di ottenere il contenuto per analisi e successivo salvataggio. Puoi solo controllare la presenza delle variabili necessarie sulle pagine o trasferire le variabili ottenute precedentemente tra i passaggi dello script web.
Dopo aver riflettuto su questi problemi, ho deciso di utilizzare i macro, che sono ben visibili in qualsiasi parte del sistema di monitoraggio: nei template, negli host, nei trigger o negli item. I macro possono essere aggiornati tramite l'API dell'interfaccia web.
Zabbix ha una buona e dettagliata documentazione sull'API. Per lo scambio di dati tramite API si utilizza il formato dati JSON. Puoi leggere i dettagli in .
La sequenza di azioni per ottenere i dati necessari e registrarli nei macro è illustrata nello schema sottostante.

Passo 1
Il primo passo può consistere in un'unica azione o in più azioni. Nei primi passi è contenuta tutta la logica principale, e i passaggi più importanti sono gli ultimi 3.
Nel mio esempio, al primo passo ottenevo la cookie di autorizzazione dalla centrale per il primo problema. Per il secondo problema ricevevo il numero della versione attuale del firmware Mikrotik.
URL delle versioni attuali del firmware Mikrotik
- — URL della versione Stable attuale
- — URL della versione LTS attuale
Questi indirizzi vengono utilizzati dall'hardware Mikrotik per ottenere l'ultima versione disponibile del firmware.
Il primo passo è completamente individuale per ogni caso e la sua logica di lavoro può variare. Tutto dipende dalle tue necessità.
Quando lavori con script web, presta attenzione al metodo necessario per ricevere la risposta. Intestazioni Risposta HTTP o il corpo della risposta senza intestazioni?
Se hai bisogno di cookie di autorizzazione, imposta il metodo di risposta Intestazioni come nel caso di Asterisk.Se hai bisogno di dati, come nel caso della risposta del server Mikrotik, imposta Corpo la risposta senza intestazioni.
Passo 2
Passiamo al secondo passo. Ottenere la sessione di autorizzazione:
POST http://company.com/zabbix/api_jsonrpc.php HTTP/1.1
Content-Type: application/json-rpc
{
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": "Admin",
"password": "zabbix"
},
"id": 1,
"auth": null
}jsonrpc — versione del protocollo JSON-RPC utilizzato;
Zabbix implementa JSON-RPC versione 2.0;
- method — metodo che viene chiamato;
- params — parametri trasmessi dal metodo;
- id — identificatore arbitrario della richiesta;
- auth — chiave di autenticazione dell'utente; poiché non la possediamo ancora, la indichiamo come null.
Per lavorare con l'API ho creato un account separato con diritti limitati. In primo luogo, non è necessario dare accesso dove non serve. In secondo luogo, fino alla versione 5.0, la password impostata tramite macro era leggibile. Pertanto, usare la password dell'amministratore di Zabbix renderebbe facile rubare l'account dell'amministratore.
Questo sarà particolarmente rilevante quando lavori con l'API tramite script di terze parti e conservi le credenziali sul lato.
Dalla versione 5.0 è stata introdotta l'opzione per nascondere la password memorizzata nella macro.

Quando crei un account separato per aggiornare i dati tramite l'API, assicurati sempre che i dati necessari siano accessibili tramite l'interfaccia web e che possa essere effettuato l'aggiornamento. Non ho controllato e poi ho impiegato molto tempo a capire perché il macro di cui avevo bisogno non fosse visibile tramite API.

Dopo aver ottenuto l'autorizzazione nell'API, passiamo ad ottenere l'elenco dei macro.
Passo 3
L'interfaccia API non permette di aggiornare il macro host per nome; prima bisogna ottenere l'ID del macro. Inoltre, per ottenere un elenco dei macro di un particolare host, è necessario conoscere l'ID di quest'ultimo, il che comporta una richiesta aggiuntiva. Utilizzare il macro predefinito {HOST.ID} non è possibile. Ho deciso di aggirare la limitazione in questo modo:

Ho creato un macro locale con l'ID di questo host. È molto facile conoscere l'ID dell'host tramite l'interfaccia web.
La risposta con l'elenco di tutti i macro di questo host può essere filtrata secondo il modello:
regex:{"hostmacroid":"([0-9]+)"[A-z0-9,":]+"{$MIKROTIK_VERSION}" 
Così otteniamo l'ID del macro di nostro interesse, dove MIKROTIK_VERSION è il nome del macro che stiamo cercando. Nel mio caso stiamo cercando il macro MIKROTIK_VERSION, assegnato all'host.
La richiesta appare così:
POST http://company.com/zabbix/api_jsonrpc.php HTTP/1.1
Content-Type: application/json-rpc
{
"jsonrpc":"2.0",
"method":"usermacro.get",
"params":{
"output":"extend",
"hostids":"{$HOST_ID}"
},
"auth":"{sid}",
"id":1
}
Variabile {sid} ottenuto al secondo passaggio e sarà utilizzato costantemente, dove è necessario lavorare con l'interfaccia API.
L'ULTIMO PASSAGGIO — aggiornamento del macro
Ora conosciamo l'ID del macro da aggiornare, il cookie di autenticazione o la versione del firmware del router. Possiamo aggiornare il macro stesso.
POST http://company.com/zabbix/api_jsonrpc.php HTTP/1.1
Content-Type: application/json-rpc
{
"jsonrpc":"2.0",
"method":"usermacro.update",
"params":{
"hostmacroid":"{hostmacroid}",
"value":"{mikrotik_version}"
},
"auth":"{sid}",
"id":1
}
{mikrotik_version} è il valore ottenuto al primo passaggio. Nel mio esempio — la versione attuale del firmware Mikrotik
{hostmacroid} è il valore ottenuto nel terzo passaggio — l'ID del macro che aggiorniamo.
Conclusioni
Affrontare il problema utilizzando la funzionalità predefinita è notevolmente più complesso e richiede più tempo. Soprattutto se si conosce la programmazione e si può rapidamente implementare la logica necessaria in uno script.
Un chiaro vantaggio di questo approccio è la "portabilità" della soluzione tra diversi server.
Personalmente trovo strano che non ci sia la possibilità di accedere ai dati di un altro elemento nell'agente HTTP e di inserirli nel corpo della richiesta o negli header [ ].
Il template pronto può essere .
Fonte: habr.com
