Lors de la création d'une solution pour le client, deux tâches se sont présentées, que je voulais résoudre de manière élégante avec les fonctionnalités standard de Zabbix.
Tâche 1. Suivi de la version actuelle du firmware sur les routeurs Mikrotik.
La tâche se résout facilement en ajoutant au modèle un agent HTTP. L'agent récupère la version actuelle depuis le site de Mikrotik, et le déclencheur compare la version actuelle avec la version en cours et en cas de divergence, il émet une alerte.
Lorsque vous avez 10 routeurs, cet algorithme n'est pas critique, mais que faire avec 3000 routeurs ? Envoyer 3000 requêtes au serveur ? Cela fonctionnerait, mais l'idée d'envoyer 3000 requêtes ne me convenait pas, je voulais trouver une autre solution. De plus, il y avait un inconvénient avec cet algorithme : l'autre partie pourrait considérer un tel nombre de requêtes provenant d'une seule IP comme une attaque par déni de service (DoS) et pourrait tout simplement bloquer.
Tâche 2. Utilisation de session d'authentification dans différents agents HTTP.
Lorsque vous devez obtenir des informations à partir de pages « fermées » via un agent HTTP, un cookie d'authentification est nécessaire. Pour cela, il existe généralement un formulaire standard d'authentification avec une paire « identifiant / mot de passe » et l'établissement de l'ID de session dans le cookie.
Mais il y a un problème, il n'est pas possible d'accéder aux données d'un autre élément de l'agent HTTP pour insérer cette valeur dans l'en-tête.
Il existe aussi le « Scénario Web », qui a une autre limitation, il ne permet pas d'obtenir le contenu pour analyse et sauvegarde ultérieure. On peut uniquement vérifier la présence de variables nécessaires sur les pages ou transmettre les variables précédemment obtenues entre les étapes du scénario Web.
Après avoir réfléchi à ces tâches, j'ai décidé d'utiliser des macros, qui sont visibles dans n'importe quelle partie du système de surveillance : dans les modèles, hôtes, déclencheurs ou éléments. Et les macros peuvent être mises à jour via l'API de l'interface Web.
Zabbix dispose d'une bonne documentation détaillée sur l'API. Pour échanger des données par API, le format de données JSON est utilisé. Vous pouvez lire plus en détail dans .
La séquence d'actions pour obtenir les données nécessaires et les enregistrer dans une macro est présentée dans le schéma ci-dessous.

Étape 1
La toute première étape peut consister en une seule action ou en de nombreuses actions. Dans les premières étapes, toute la logique principale est posée, et les trois dernières étapes sont les plus importantes.
Dans mon exemple, lors de la première étape, j'ai récupéré le cookie d'authentification sur la centrale pour la première tâche. Pour la deuxième tâche, j'ai obtenu le numéro de la version actuelle du firmware Mikrotik.
URL des versions de firmware Mikrotik actuelles
- — URL de la version Stable actuelle
- — URL de la version LTS actuelle
Ces adresses sont utilisées par le matériel Mikrotik pour récupérer la dernière version disponible du firmware.
La première étape est entièrement individuelle pour chaque cas et sa logique peut varier. Tout dépend de votre tâche.
Lors de l'utilisation de scénarios Web, surveillez le type de méthode de réponse dont vous avez besoin. En-têtes Réponse HTTP ou le corps de la réponse sans en-têtes ?
Si des cookies d'authentification sont nécessaires, utilisez la méthode de réponse En-têtes comme dans le cas de Asterisk.Si vous avez besoin de données, comme dans le cas de la réponse du serveur Mikrotik, indiquez le corps de la réponse sans en-têtes.
Étape 2
Passons à la deuxième étape. Obtention de la session d'authentification :
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 — version du protocole JSON-RPC utilisée ;
Zabbix implémente la version 2.0 de JSON-RPC ;
- method — méthode qui est appelée ;
- params — paramètres passés par la méthode ;
- id — identifiant arbitraire de la requête ;
- auth — clé d'authentification de l'utilisateur ; comme nous ne l'avons pas encore, nous l'indiquerons comme nul.
Pour travailler avec l'API, j'ai créé un compte distinct avec des droits restreints. Tout d'abord, il n'est pas nécessaire d'accorder un accès là où cela n'est pas nécessaire. Deuxièmement, jusqu'à la version 5.0, le mot de passe défini par le macro pouvait être lu. Par conséquent, si l'on utilise le mot de passe de l'administrateur Zabbix, le compte admin peut être facilement volé.
Cela sera particulièrement pertinent lorsque vous travaillez avec l'API via des scripts tiers et que vous stockez les identifiants côté.
Depuis la version 5.0, une option a été ajoutée pour cacher le mot de passe stocké dans le macro.

Lorsque vous créez un compte séparé pour mettre à jour les données via l'API, assurez-vous que les données dont vous avez besoin sont accessibles via l'interface Web et qu'il est possible de les mettre à jour. Je n'ai pas vérifié et j'ai ensuite longtemps eu du mal à comprendre pourquoi le macro dont j'avais besoin n'était pas visible via l'API.

Après avoir obtenu l'autorisation dans l'API, nous passons à l'obtention de la liste des macros.
Étape 3
L'interface API ne permet pas de mettre à jour le macro hôte par son nom, il faut d'abord obtenir l'ID du macro. De plus, pour obtenir la liste des macros d'un hôte spécifique, il faut connaître l'ID de cet hôte, ce qui entraîne une requête supplémentaire. Utilisez le macro par défaut {HOST.ID} dans la requête ci-dessous. J'ai contourné cette limitation de la manière suivante :

J'ai créé un macro local avec l'ID de cet hôte. Il est très facile de connaître l'ID de l'hôte à partir de l'interface web.
La réponse contenant la liste de tous les macros de cet hôte peut être filtrée par modèle :
regex:{"hostmacroid":"([0-9]+)"[A-z0-9,":]+"{$MIKROTIK_VERSION}" 
Ainsi, nous obtenons l'ID du macro dont nous avons besoin, où MIKROTIK_VERSION est le nom du macro que nous recherchons. Dans mon cas, le macro recherché est MIKROTIK_VERSION, qui a été assigné à l'hôte.
La requête elle-même ressemble à ceci :
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
}
Variable {sid} obtenu à l'étape deux et sera utilisé en permanence lorsque nous devrons travailler avec l'interface API.
L'ÉTAPE 4 FINALE — mise à jour du macro
Maintenant que nous connaissons l'ID du macro que nous devons mettre à jour, le cookie d'authentification ou la version du firmware du routeur. Nous pouvons mettre à jour le macro lui-même.
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} est la valeur obtenue à la première étape. Dans mon exemple, c'est la version du firmware actuel de Mikrotik.
{hostmacroid} est la valeur que nous avons obtenue à l'étape trois — l'ID du macro que nous mettons à jour.
Conclusions
La solution du problème par le biais des fonctionnalités standard est de loin plus complexe et prend plus de temps. Surtout si vous connaissez la programmation et pouvez rapidement élaborer la logique nécessaire dans le script.
L'un des avantages évidents de cette approche est la "portabilité" de la solution entre différents serveurs.
Il me semble étrange de ne pas pouvoir accéder aux données d'un autre élément dans l'agent HTTP et de les insérer dans le corps de la requête ou dans les en-têtes [ ].
Le modèle prêt à l'emploi peut être .
Source : habr.com
