01Les jetons d'API
L'API JSON-RPC de Zabbix s'authentifie par jeton, créé dans le profil d'un utilisateur. Nous créons un utilisateur technique par usage, avec un rôle limité à ce dont il a besoin, et un jeton à date d'expiration.
| Usage | Rôle | Droits sur les hôtes |
|---|---|---|
| Lecture pour Grafana et les rapports | Utilisateur, API en lecture | Lecture sur les groupes concernés |
| Scripts d'exploitation (maintenances) | Administrateur restreint aux méthodes utiles | Écriture sur les groupes concernés |
| Provisionnement Ansible | Administrateur | Écriture sur tout le périmètre géré |
Un rôle Zabbix peut limiter l'API à une liste de méthodes. Un jeton qui ne sert qu'à poser des maintenances n'a besoin que de host.get, maintenance.get, maintenance.create et maintenance.delete. S'il fuit, c'est tout ce qu'il permet.
02Premiers appels
export ZBX_URL=https://zabbix.exemple.fr/api_jsonrpc.php
export ZBX_TOKEN='jeton-de-lecture'
curl -s -X POST "$ZBX_URL" \
-H 'Content-Type: application/json-rpc' \
-H "Authorization: Bearer $ZBX_TOKEN" \
-d '{"jsonrpc":"2.0","method":"problem.get","id":1,
"params":{"severities":[4,5],"recent":true,
"output":["eventid","name","severity","clock"],
"sortfield":["eventid"],"sortorder":"DESC"}}' | jq
Le jeton passe dans l'en-tête Authorization, jamais dans le corps de la requête
ni dans l'URL : il finirait dans les journaux du proxy inverse.
03La bibliothèque Python officielle
Zabbix publie zabbix_utils, une bibliothèque Python qui couvre l'API, l'envoi de
valeurs et l'interrogation des agents. Elle remplace avantageusement les bibliothèques
communautaires plus anciennes.
python3 -m venv /opt/zbx-outils /opt/zbx-outils/bin/pip install zabbix_utils
04Une maintenance posée par le script
Le cas d'usage qui justifie à lui seul l'automatisation. Avant de redémarrer un noeud, le script d'intervention pose une maintenance sur l'hôte, fait son travail, puis la retire. Plus de fausse alerte pendant l'opération, et plus d'oubli de maintenance laissée ouverte.
#!/opt/zbx-outils/bin/python3
"""Pose ou retire une maintenance Zabbix sur un hote.
zbx_maintenance.py pose pve-02 60 # 60 minutes
zbx_maintenance.py retire pve-02
"""
import os
import sys
import time
from zabbix_utils import ZabbixAPI
PREFIXE = "intervention-"
def api():
a = ZabbixAPI(url=os.environ["ZBX_URL"])
a.login(token=os.environ["ZBX_TOKEN"])
return a
def hote(a, nom):
r = a.host.get(filter={"host": [nom]}, output=["hostid"])
if not r:
sys.exit("hote inconnu dans Zabbix : %s" % nom)
return r[0]["hostid"]
def poser(nom, minutes):
a = api()
debut = int(time.time())
a.maintenance.create(
name=PREFIXE + nom,
active_since=debut,
active_till=debut + minutes * 60,
maintenance_type=0, # collecte maintenue
hosts=[{"hostid": hote(a, nom)}],
timeperiods=[{"timeperiod_type": 0, "start_date": debut,
"period": minutes * 60}])
print("maintenance posee sur %s pour %d minutes" % (nom, minutes))
def retirer(nom):
a = api()
ids = [m["maintenanceid"] for m in
a.maintenance.get(filter={"name": PREFIXE + nom}, output=["maintenanceid"])]
if ids:
a.maintenance.delete(*ids)
print("maintenance retiree sur %s (%d)" % (nom, len(ids)))
if __name__ == "__main__":
action, nom = sys.argv[1], sys.argv[2]
if action == "pose":
poser(nom, int(sys.argv[3]) if len(sys.argv) > 3 else 60)
else:
retirer(nom)
Le script pose une maintenance qui expire seule, même si l'intervention s'interrompt avant l'étape de retrait. Une maintenance sans fin est la meilleure façon de découvrir, trois mois plus tard, qu'un hôte ne prévenait plus de rien.
05Pousser des valeurs depuis un script
Un élément de type trappeur attend qu'on lui envoie des valeurs. C'est l'équivalent, dans
Zabbix, de la sonde push d'Uptime Kuma : le script de sauvegarde envoie son résultat, un
déclencheur nodata() alerte si rien n'arrive.
#!/opt/zbx-outils/bin/python3 from zabbix_utils import Sender # envoye au proxy du site, ou a la grappe de serveurs envoi = Sender(server="10.10.0.61", port=10051) r = envoi.send_value("srv-fichiers", "metier.sauvegarde.resultat", 0) print(r)
06Ansible pour les agents et les hôtes
La collection community.zabbix fournit un rôle de déploiement de l'agent et des
modules pour gérer hôtes, groupes, macros et maintenances. Combinée à l'autoregistration du
chapitre 02, elle couvre tout le cycle de vie : le rôle installe l'agent avec ses métadonnées,
l'hôte s'inscrit seul, et le module le supprime au décommissionnement.
- hosts: serveurs_linux
become: true
roles:
- role: community.zabbix.zabbix_agent
vars:
zabbix_agent2: true
zabbix_agent_version: "8.0"
zabbix_agent_server: ""
zabbix_agent_serveractive: "10.10.0.61;10.10.0.62"
zabbix_agent_hostmetadata: "linux {{ role_metier }} client-{{ client }}"
zabbix_agent_tlsconnect: psk
zabbix_agent_tlsaccept: psk
zabbix_agent_tlspskidentity: "PSK-{{ client | upper }}"
zabbix_agent_tlspsk_secret: "{{ vault_psk[client] }}"
La collection évolue avec Zabbix et certains noms de variables ont changé d'une version à l'autre. Avant de déployer pour la 8.0, relisez la documentation du rôle dans la version de la collection que vous installez.
07Les modèles dans Git
Les modèles maison et les modèles de politique du chapitre 03 sont du code : ils se versionnent. L'API exporte un modèle au format YAML, lisible en différentiel. Nous exportons chaque nuit, et une modification faite dans l'interface apparaît le lendemain comme un changement dans Git, avec son auteur.
#!/opt/zbx-outils/bin/python3 import os from zabbix_utils import ZabbixAPI a = ZabbixAPI(url=os.environ["ZBX_URL"]) a.login(token=os.environ["ZBX_TOKEN"]) # les modeles maison sont ranges dans un groupe dedie groupe = a.templategroup.get(filter={"name": ["Modeles/Captain"]}, output=["groupid"]) modeles = a.template.get(groupids=[groupe[0]["groupid"]], output=["templateid", "host"]) os.makedirs("modeles", exist_ok=True) for m in modeles: yaml = a.configuration.export(format="yaml", options={"templates": [m["templateid"]]}) with open("modeles/%s.yaml" % m["host"].replace("/", "_"), "w") as f: f.write(yaml)
Le chemin inverse, l'import depuis Git vers Zabbix, se fait par
configuration.import. Nous le réservons aux modèles maison : les officiels
s'importent depuis les fichiers publiés par l'éditeur pour la version installée.
Une supervision qui veille pendant que vous dormez
Nous concevons, installons et exploitons des plateformes de supervision pour des PME, des hébergeurs et des collectivités : Zabbix, Prometheus et Grafana, ou plus léger quand le besoin l'est. Reprise d'une supervision existante, réglage des alertes qui sonnent pour rien, astreinte : nous intervenons au forfait comme au long cours.