Checkmk
to checkmk.com
Important

This is a machine translation based on the English version of the article. It might or might not have already been subject to text preparation. If you find errors, please file a GitHub issue that states the paragraph that has to be improved.

1. Introduction

Les plug-ins de vérification compatibles avec SNMP sont développés de manière similaire à leurs homologues basés sur des agents. La différence réside à la fois dans le processus de découverte des services et dans la vérification elle-même. Avec les plug-ins de vérification basés sur des agents, le plug-in agent sert à déterminer quelles données sont envoyées au site Checkmk, et un préfiltrage (mais aucune évaluation) a souvent déjà lieu sur l’hôte. En revanche, avec SNMP, vous devez spécifier exactement les champs de données dont vous avez besoin et les demander explicitement. Avec SNMP, ces zones (branches d’un arbre) ou champs de données individuels (feuilles) sont identifiés par des OID (identificateurs d’objet).

Un transfert complet de toutes les données serait théoriquement possible (à l'aide de ce qu'on appelle le « SNMP walk »), Cependant, même avec des appareils rapides, cela prend plusieurs minutes, et avec des commutateurs complexes, cela peut prendre plus d'une heure. Cela pose donc déjà un problème lors de la découverte et encore plus lors de la vérification elle-même. Checkmk adopte ici une approche plus ciblée. Néanmoins, les SNMP walks sont disponibles dans Checkmk pour le débogage des vérifications existantes et le développement de vos propres vérifications.

Si vous n'avez pas encore d'expérience avec SNMP, nous vous recommandons de lire l'article sur la surveillance via SNMP.

1.1. En quoi le fonctionnement de SNMP est-il différent ?

Par rapport à un plug-in de contrôle pour l'agent Checkmk, il existe certaines particularités à noter avec SNMP. Avec un plug-in de contrôle pour SNMP, la découverte d'un service se divise en deux phases.

Dans un premier temps, la fonction de détection SNMP est utilisée pour détecter le périphérique. Cela permet de déterminer si le plug-in de vérification présente un intérêt pour le périphérique concerné et s’effectue pour chaque périphérique surveillé via SNMP. À cette fin, quelques OID sont récupérés — individuellement, sans « SNMP walk ». Le plus important d’entre eux est l’« sysDescr » (OID : 1.3.6.1.2.1.1.1.0). Sous cet OID, chaque périphérique SNMP fournit une description de lui-même, par exemple Flintstones, Inc. Fred Router rev23.

Au cours de la deuxième étape, les données de surveillance nécessaires sont récupérées pour chacun de ces candidats à l’aide de SNMP walks. Celles-ci sont ensuite résumées dans un tableau et transmises à la fonction de découverte du plug-in de vérification dans l’argument « section », qui détermine alors les éléments à surveiller. Un service est ensuite généré pour chacun de ces éléments.

Au moment de la vérification, on sait donc déjà si le plug-in doit être exécuté pour le périphérique, ce qui rend inutile une nouvelle détection SNMP. Les données de surveillance actuelles requises pour le plug-in sont récupérées ici via des parcours SNMP.

Que devez-vous donc faire différemment avec un plug-in de vérification pour SNMP par rapport à un plug-in basé sur un agent ?

  1. Vous n'avez pas besoin d'un plug-in agent.

  2. Vous définissez les OID requis pour la détection SNMP et les textes qu’ils doivent contenir.

  3. Vous décidez quelles branches et feuilles de l'arborescence SNMP doivent être récupérées à des fins de surveillance.

1.2. N'ayez pas peur des MIB !

Dans cette brève introduction, nous aimerions aborder les fameuses MIB SNMP, qui font l’objet de nombreux préjugés. La bonne nouvelle : Checkmk n’a pas besoin de MIB ! Cependant, elles peuvent constituer une aide précieuse lors du développement d’un plug-in de vérification ou du dépannage de plug-ins existants.

Que sont les MIB ? MIB signifie littéralement « Management Information Base », ce qui ne donne guère plus d’informations que l’abréviation elle-même. Fondamentalement, une MIB est un fichier texte lisible par l’homme qui décrit les branches et les feuilles d’un arbre de données SNMP.

Les OID permettent d'identifier les branches ou les feuilles. La description de la branche contient des informations sur le système et les sous-systèmes fournis par la branche. Si un OID fait référence à une feuille, les informations contenues dans la MIB fournissent des détails sur le type de données (chaîne de caractères, nombre à virgule fixe, chaîne hexadécimale, …), la plage de valeurs et la représentation. Par exemple, les températures peuvent être stockées sous forme de nombre à virgule fixe avec un signe sur l’échelle Celsius avec une résolution de 0,1 °C, ou sans signe par paliers de 1,0 °C sur l’échelle Kelvin.

Checkmk fournit une série de fichiers MIB librement accessibles. Ceux-ci décrivent des champs très généraux de l’arborescence OID globale, mais ne contiennent aucun champ spécifique au fabricant. Ils ne sont donc pas d’une grande aide pour les plug-ins de vérification développés en interne.

Essayez donc de trouver les fichiers MIB pertinents pour votre appareil spécifique sur le site web du fabricant ou même sur l’interface de gestion de l’appareil. Installez ces fichiers sur le site Checkmk dans le répertoire ~/local/share/snmp/mibs/. Vous pouvez ensuite traduire les numéros OID en noms à l’aide de SNMP walks et ainsi trouver plus rapidement les données qui vous intéressent à des fins de surveillance. Comme déjà mentionné, les MIB bien entretenues contiennent également des informations intéressantes dans leurs commentaires. Vous pouvez facilement consulter un fichier MIB à l'aide d'un éditeur de texte ou de l'less de pagination.

2. Trouver les OID appropriés

La condition préalable essentielle au développement d’un plug-in de vérification basé sur SNMP est de savoir quels OID contiennent les informations pertinentes. Pour le scénario présenté en exemple, nous avons supposé que vous venez de mettre en service un lot de routeurs de type Flintstones, Inc. Fred Router rev23. Vous rencontrerez souvent cet appareil fictif dans la documentation du fabricant et les commentaires MIB. Cependant, vous avez oublié de saisir les coordonnées et les informations de localisation pour certains appareils. Un plug-in de vérification écrit par vos soins pour Checkmk devrait désormais vous aider à identifier ces appareils.

Tip

Le plug-in d'exemple que nous avons préparé est conçu de manière à ce que vous puissiez l'exécuter avec presque n'importe quel appareil compatible SNMP. Il vous suffit d'adapter la chaîne de caractères à comparer. Si vous ne disposez pas d'un appareil sous la main, vous trouverez diverses options de simulation dans le chapitre consacré au dépannage.

La première étape consiste à effectuer un SNMP walk complet. Cela implique de récupérer toutes les données disponibles via SNMP. Cette opération est très simple à réaliser avec Checkmk. Commencez par inclure dans la surveillance le périphérique pour lequel vous souhaitez développer un plug-in de vérification. Assurez-vous qu’il peut être surveillé dans les fonctions de base. Au minimum, les services SNMP Info et Uptime doivent être détectés, ainsi que probablement au moins un service Interface. Cela permettra de s'assurer que l'accès SNMP fonctionne correctement.

Passez ensuite à la ligne de commande du site Checkmk. Vous pouvez y exécuter une exploration complète à l'aide de la commande suivante — dans l'exemple ci-dessous pour le périphérique dont le nom d'hôte est mydevice01. Nous vous recommandons d'utiliser également l'option -v (pour un mode détaillé) :

OMD[mysite]:~$ cmk -v --snmpwalk mydevice01
mydevice01:
Walk on ".1.3.6.1.2.1"...3898 variables.
Walk on ".1.3.6.1.4.1"...6025 variables.
Wrote fetched data to /omd/sites/mysite/var/check_mk/snmpwalks/mydevice01.
Copier la ou les commandes dans le presse-papiers
Commande(s) copiée(s) avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Comme déjà mentionné, une exploration SNMP complète peut prendre plusieurs minutes, voire plusieurs heures (même si ce dernier cas est rare) ; ne vous inquiétez donc pas si cela prend un certain temps. Les résultats de l’exploration sont enregistrés dans le fichier ~/var/check_mk/snmpwalks/mydevice01. Il s’agit d’un fichier texte facile à lire qui commence ainsi :

~/var/check_mk/snmpwalks/mydevice01
.1.3.6.1.2.1.1.1.0 Flintstones, Inc. Fred Router rev23
.1.3.6.1.2.1.1.2.0 .1.3.6.1.4.1.424242.2.3
.1.3.6.1.2.1.1.3.0 546522419
.1.3.6.1.2.1.1.4.0 barney@example.com
.1.3.6.1.2.1.1.5.0 big-router-01
.1.3.6.1.2.1.1.6.0 Server room 23, Stonestreet 52, Munich
.1.3.6.1.2.1.1.7.0 72
.1.3.6.1.2.1.1.8.0 0

Chaque ligne contient un OID suivi de sa valeur. Vous trouverez le plus important d’entre eux dans la toute première ligne, à savoir sysDescr. Il s’agit d’un identifiant unique pour un modèle de matériel.

La deuxième ligne est également intéressante : Sous 1.3.6.1.4.1, il existe des branches que les fabricants de matériel peuvent attribuer eux-mêmes ; ici, Flintstones, Inc. dispose de l'identifiant de fabricant fictif 424242. En dessous, la société a attribué 2 pour les routeurs et 3 pour le même modèle. Vous trouverez ensuite des OID spécifiques aux appareils au sein de cette branche.

Ces OID n'ont toutefois pas beaucoup de sens. Si les MIB appropriées sont installées, vous pouvez les traduire en noms lors d'une deuxième étape. Il est préférable de rediriger vers un fichier la sortie de la commande suivante, qui s'afficherait autrement dans le terminal :

OMD[mysite]:~$ cmk --snmptranslate mydevice01 > /tmp/translated
Copier la ou les commandes dans le presse-papiers
Commande(s) copiée(s) avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Une fois ce fichier etranslated, il se lit comme la liste d'origine, mais affiche en outre le nom de l'OID dans chaque ligne après l'--> :

/tmp/translated
.1.3.6.1.2.1.1.1.0 Flintstones, Inc. Fred Router rev23 --> SNMPv2-MIB::sysDescr.0
.1.3.6.1.2.1.1.2.0 .1.3.6.1.4.1.424242.2.3 --> SNMPv2-MIB::sysObjectID.0
.1.3.6.1.2.1.1.3.0 546522419 --> DISMAN-EVENT-MIB::sysUpTimeInstance
.1.3.6.1.2.1.1.4.0 barney@example.com --> SNMPv2-MIB::sysContact.0
.1.3.6.1.2.1.1.5.0 big-router-01 --> SNMPv2-MIB::sysName.0
.1.3.6.1.2.1.1.6.0 Server room 23, Stonestreet 52, Munich --> SNMPv2-MIB::sysLocation.0
.1.3.6.1.2.1.1.7.0 42 --> SNMPv2-MIB::sysServices.0
.1.3.6.1.2.1.1.8.0 27 --> SNMPv2-MIB::sysORLastChange.0

Dans le résultat ci-dessus, par exemple, l'OID 1.3.6.1.2.1.1.4.0 a la valeur barney@example.com et le nom SNMPv2-MIB::sysContact.0. Les informations supplémentaires indiquant les noms des OID fournissent des renseignements importants pour identifier les OID qui vous intéressent. Pour l'exemple présenté, les OID 1.3.6.1.2.1.1.4.0 à 1.3.6.1.2.1.1.6.0 suffisent.

3. Création d'un simple module de vérification

Vous avez désormais terminé le travail préparatoire : Vous disposez désormais d'une liste des OID que vous souhaitez lire et évaluer. Il s'agit maintenant d'utiliser ces informations pour indiquer à Checkmk quels services sont générés et à quel moment ils doivent être envoyés vers WARN ou CRIT. La programmation d'un plugin de vérification en Python utilisé à cette fin présente de nombreuses similitudes avec celle d'un plugin de vérification basé sur un agent. Comme il y a quelques subtilités à prendre en compte, nous allons vous présenter la structure complète avec toutes les fonctions utilisées.

3.1. Préparation du fichier

Pour vos propres plug-ins de vérification, vous trouverez le répertoire de base déjà préparé dans la hiérarchie local du répertoire du site. Il s'agit de ~/local/lib/python3/cmk_addons/plugins/. Ce répertoire appartient à l'utilisateur du site et est donc accessible en écriture pour vous.

Dans ce répertoire, les plug-ins sont organisés en familles de plug-ins, dont les noms de répertoires peuvent être choisis librement. Par exemple, tous les plug-ins relatifs aux appareils Cisco sont stockés dans le dossier cisco — ou tous les plug-ins relatifs aux routeurs du fabricant Flintstones, Inc. sont stockés dans le dossier flintstone.

Dans ce sous-répertoire <plug-in_family>, d’autres sous-répertoires aux noms prédéfinis sont ensuite créés selon les besoins pour les différentes API, par exemple agent_based pour l’API Check des plug-ins basés sur des agents, y compris les plug-ins de vérification basés sur SNMP.

Créez les deux sous-répertoires pour le nouveau plug-in de vérification, puis accédez-y pour travailler :

OMD[mysite]:~$ mkdir -p ~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based
OMD[mysite]:~$ cd ~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based
Copier la ou les commandes dans le presse-papiers
Commande(s) copiée(s) avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Créez ici le fichier flintstone_setup_check.py pour le plug-in de vérification. La convention veut que le nom du fichier reflète le nom du plug-in de vérification tel qu’il est défini lors de la création du plug-in en tant qu’instance de la classe CheckPlugin. Il est obligatoire que le fichier se termine par .py, car à partir de la version 2.0.0 de Checkmk, les plug-ins de vérification sont toujours de véritables modules Python.

Un cadre de base exécutable (téléchargeable sur GitHub), que vous développerez étape par étape ci-après, se présente comme suit :

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
#!/usr/bin/env python3

from cmk.agent_based.v2 import (
    CheckPlugin,
    CheckResult,
    startswith,
    DiscoveryResult,
    Result,
    Service,
    SimpleSNMPSection,
    SNMPTree,
    State,
    StringTable,
)

def parse_flintstone(string_table):
    return {}

def discover_flintstone(section):
    yield Service()

def check_flintstone(section):
    yield Result(state=State.OK, summary="Everything is fine")

snmp_section_flintstone_setup = SimpleSNMPSection(
    name = "flintstone_base_config",
    parse_function = parse_flintstone,
    detect = startswith(".1.3.6.1.2.1.1.1.0", "Flintstone"),
    fetch = SNMPTree(base='.1.3.6.1.2.1.1', oids=['4.0']),
)

check_plugin_flintstone_setup = CheckPlugin(
    name = "flintstone_setup_check",
    sections = [ "flintstone_base_config" ],
    service_name = "Flintstone setup check",
    discovery_function = discover_flintstone,
    check_function = check_flintstone,
)
Copier le contenu du fichier dans le presse-papiers
Contenu du fichier copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Vous devrez d'abord importer les fonctions et les classes requises pour les plug-ins de vérification à partir des modules Python. Nous vous déconseillons d'utiliser l'import *, parfois employée, car elle consomme inutilement de la mémoire et rend difficile l'identification des espaces de noms réellement disponibles. Pour notre exemple, nous n'importerons que ce qui sera nécessaire ou susceptible d'être utile dans la suite de cet article :

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
from cmk.agent_based.v2 import (
    CheckPlugin,
    CheckResult,
    startswith,
    DiscoveryResult,
    Result,
    Service,
    SimpleSNMPSection,
    SNMPTree,
    State,
    StringTable,
)
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Par rapport au plug-in de vérification basé sur un agent, les nouvelles fonctions et classes spécifiques à SNMP se distinguent : SNMPTree, SimpleSNMPSection et startswith. SNMPTree est une classe qui sert à afficher les arborescences SNMP, ce qui est assez explicite. La classe SimpleSNMPSection est utilisée pour créer une section SNMP. La fonction startswith() compare le contenu d’une feuille SNMP à une chaîne de caractères. Nous y reviendrons plus tard.

3.2. Création de la section SNMP

Une fois que vous avez identifié les OID appropriés, il est temps de développer le plug-in de vérification. Lors de la création de la section SNMP, vous spécifiez deux éléments :

  1. Vous identifiez les périphériques pour lesquels le plug-in de vérification doit être exécuté.
    Dans l'exemple suivant, cela s'effectue à l'aide de la fonction `startswith()`, qui compare une chaîne de caractères avec le début du contenu d'une feuille OID. D'autres options d'affectation sont présentées ci-dessous.

  2. Vous déclarez quelles branches ou feuilles d'OID doivent être récupérées à des fins de surveillance.
    Cela s'effectue à l'aide du constructeur de la classe `SNMPTree`.

Modifiez le fichier d'exemple fourni de manière à ce que le plug-in ne s'exécute que pour un petit nombre de périphériques, en l'occurrence les modèles Flintstones, Inc. Fred Router. Les OID correspondant au contact, au nom du périphérique et à l'emplacement sont alors récupérés pour ces périphériques. Ces trois OID sont fournis par chaque périphérique. Si vous souhaitez tester l'exemple avec de véritables périphériques compatibles SNMP, il suffit donc de personnaliser le nom du modèle à reconnaître.

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
snmp_section_flintstone_setup_check = SimpleSNMPSection(
    name = "flintstone_base_config",
    parse_function = parse_flintstone,
    detect = startswith(
        ".1.3.6.1.2.1.1.1.0",
        "Flintstones, Inc. Fred Router",
    ),
    fetch = SNMPTree(
        base = '.1.3.6.1.2.1.1',
        oids = ['4.0', '5.0', '6.0'],
    ),
)
Copier le contenu du fichier dans le presse-papiers
Contenu du fichier copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

L'exemple contient également le paramètre « name », qui permet d'identifier la section SNMP générée, ainsi qu'une fonction d'analyse, dont nous parlerons plus tard.

La détection SNMP

Utilisez le paramètre detect pour spécifier les conditions dans lesquelles la fonction de découverte doit être exécutée. Dans notre exemple, c'est le cas si la valeur de l'OID 1.3.6.1.2.1.1.1.0 (c'est-à-dire l'sysDescr) commence par le texte Flintstones, Inc. Fred Router (sans distinction de casse). Outre startswith, il existe toute une gamme d'autres fonctions possibles pour l'identification. Il existe également une forme négative de chacune d'entre elles, qui commence par not_. Notez que chaque fonction doit être spécifiée séparément dans l'instruction import.

Attribut Fonction Négation

equals(oid, "needle")

La valeur de l'OID correspond au texte « needle ».

not_equals(oid, "needle")

contains(oid, "needle")

La valeur de l'OID contient le texte « needle » à un moment donné.

not_contains(oid, "needle")

startswith(oid, "needle")

La valeur de l'OID commence par le texte « needle ».

not_startswith(oid, "needle")

endswith(oid, "needle")

La valeur de l'OID se termine par le texte needle.

not_endswith(oid, "needle")

matches(oid, regex)

La valeur de l'OID correspond à l'expression régulière « regex », ancrée après et avant, c'est-à-dire avec une correspondance exacte. Si vous n'avez besoin que d'une sous-chaîne, ajoutez simplement un « .* » au début ou à la fin.

not_matches(oid, regex).

exists(oid)

L'OID est disponible sur l'appareil. Sa valeur peut être vide.

not_exists(oid)

Il est également possible de lier plusieurs attributs à all_of ou any_of.

all_of nécessite plusieurs vérifications réussies pour une reconnaissance positive. L'exemple suivant associe votre plug-in de vérification à un appareil si le texte de l'sysDescr commence par foo (ou FOO ou Foo) et si l'OID 1.3.6.1.2.1.1.2.0 contient le texte .4.1.11863. :

detect = all_of(
    startswith(".1.3.6.1.2.1.1.1.0", "foo"),
    contains(".1.3.6.1.2.1.1.2.0", ".4.1.11863.")
)
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

En revanche, la condition « any_of » est remplie si un seul des critères est satisfait. Voici un exemple dans lequel différentes valeurs sont autorisées pour l’sysDescr :

detect = any_of(
    startswith(".1.3.6.1.2.1.1.1.0", "foo version 3 system"),
    startswith(".1.3.6.1.2.1.1.1.0", "foo version 4 system"),
    startswith(".1.3.6.1.2.1.1.1.0", "foo version 4.1 system"),
)
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Au fait : connaissez-vous les expressions régulières ? Si oui, vous pourriez probablement simplifier cet exemple et vous en sortir avec une seule ligne :

detect = matches(".1.3.6.1.2.1.1.1.0", "FOO Version (3|4|4.1) .*")
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Autre remarque importante : Les OID que vous transmettez à la détection SNMP pour un plug-in de contrôle sont récupérés sur chaque appareil surveillé via SNMP. C'est le seul moyen pour Checkmk de déterminer à quels appareils le plug-in de contrôle doit s'appliquer.

Vous devez donc faire très attention lorsque vous utilisez des OID spécifiques à un fabricant. Essayez de concevoir votre détection SNMP de manière à donner la priorité à la vérification de l'sysDescr (1.3.6.1.2.1.1.1.0) et de l'sysObjectID (1.3.6.1.2.1.1.2.0).

Si vous avez tout de même besoin d'un OID différent pour une identification précise, utilisez all_of() et procédez comme suit :

  1. Vérifiez d'abord sysDescr ou sysObjectID.

  2. Dans les arguments suivants, vous pouvez ensuite restreindre davantage le groupe d'appareils pour lesquels votre plug-in doit être exécuté.

detect = all_of(
    startswith(".1.3.6.1.2.1.1.1.0", "Flintstone"),   # first check sysDescr
    contains(".1.3.6.1.4.1.424242.2.3.37.0", "foo"),  # fetch vendor specific OID
)
Copier le contenu du fichier dans le presse-papiers
Contenu du fichier copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Cela fonctionne grâce au principe d'évaluation paresseuse : Dès qu'une des vérifications précédentes échoue, aucune autre vérification n'est effectuée. Dans l'exemple ci-dessus, l'OID 1.3.6.1.4.1.424242.2.3.37.0 n'est récupéré que sur les appareils dont l'sysDescr contient également Flintstone.

3.3. Écriture de la fonction d'analyse

Comme pour les plug-ins basés sur des agents, la fonction d'analyse du plug-in de vérification SNMP a également pour tâche de convertir les données d'agent reçues en un format pouvant être traité facilement et, surtout, avec des performances élevées.

Ici aussi, vous recevez les données sous forme de liste. Il convient toutefois de tenir compte de quelques subtilités, car il y a une différence selon que vous interrogez des feuilles ou des branches. Pour rappel, dans notre exemple ci-dessus, ce sont des feuilles qui sont demandées :

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
    fetch = SNMPTree(
        base = '.1.3.6.1.2.1.1',
        oids = ['4.0', '5.0', '6.0'],
    )
Copier le contenu du fichier dans le presse-papiers
Contenu du fichier copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Si vous étendez temporairement la fonction parse avec la fonction print(), vous pouvez afficher les données fournies par Checkmk à partir de cette requête lors du test du plugin de vérification :

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def parse_flintstone(string_table):
    print(string_table)
    return {}
Copier le contenu du fichier dans le presse-papiers
Contenu du fichier copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Vous obtiendrez une liste imbriquée qui ne contient qu'un seul élément au premier niveau, à savoir une liste des valeurs récupérées :

[
    ['barney@example.com', 'big-router-01', 'Server room 23, Stonestreet 52, Munich']
]
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Le résultat est légèrement différent si vous récupérez des branches contenant plusieurs feuilles. Supposons que le routeur puisse être équipé d'un nombre variable de cartes réseau dont le nom, l'état de connexion et la vitesse peuvent être consultés à l'adresse 1.3.6.1.4.1.424242.2.3.23

    fetch = SNMPTree(
        base = '.1.3.6.1.4.1.424242.2.3.23',
        oids = [
            '6', # all names
            '7', # all states
            '8', # all speeds
        ],
    )
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

… alors la liste bidimensionnelle pourrait ressembler à ceci :

[
    # Name, State, Speed
    ['net0', '1', '1000'],
    ['net1', '0', '100'],
    ['net2', '1', '10000'],
    ['net3', '1', '1000'],
]
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Toutes les feuilles disponibles sous un OID sont écrites dans une colonne du tableau. Il devrait donc être évident que, pour l'affichage des données, seuls les OID correspondants peuvent être interrogés.

Tip

Le dernier exemple présenté pour la récupération des branches d'OID fait également partie de notre parcours SNMP disponible sur GitHub, que vous pouvez utiliser pour des simulations.

Mais revenons maintenant à l'exemple dans lequel les feuilles OID pour le contact, le nom de l'appareil et l'emplacement sont interrogées : La fonction d'analyse suivante copie simplement chaque élément de la liste interne dans une paire clé-valeur du dictionnaire renvoyé :

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def parse_flintstone(string_table):
    # print(string_table)
    result = {}
    result["contact"] = string_table[0][0]
    result["name"] = string_table[0][1]
    result["location"] = string_table[0][2]
    # print(result)
    return result
Copier le contenu du fichier dans le presse-papiers
Contenu du fichier copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Le résultat de la fonction d'analyse ressemblera alors à ceci :

{
    'contact': 'barney@example.com',
    'name': 'big-router-01',
    'location': 'Server room 23, Stonestreet 52, Munich'
}
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

3.4. Création du plug-in de vérification

Un plug-in de vérification est créé exactement comme décrit dans la section consacrée aux plug-ins de vérification basés sur un agent.

Étant donné que, dans la plupart des cas, vous interrogez plusieurs branches SNMP, ce qui entraîne la création de plusieurs sections SNMP, le paramètre `sections`, contenant la liste des sections à évaluer, est généralement requis :

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
check_plugin_flintstone_setup = CheckPlugin(
    name = "flintstone_setup_check",
    sections = [ "flintstone_base_config" ],
    service_name = "Flintstone setup check",
    discovery_function = discover_flintstone,
    check_function = check_flintstone,
)
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

3.5. Écriture de la fonction de découverte

La fonction de découverte correspond également à l'exemple des plug-ins de vérification basés sur des agents. Pour les plug-ins de vérification qui ne génèrent qu'un seul service par hôte, une seule fonction « yield() » suffit :

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def discover_flintstone(section):
    yield Service()
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

3.6. Écriture de la fonction de vérification

Dans cet exemple, nous souhaitons vérifier si les informations relatives au contact, au nom de l'appareil et à l'emplacement sont disponibles. Il suffit donc de vérifier, dans la fonction de vérification, quels champs sont vides et de définir le statut en conséquence : « CRIT » (si des informations manquent) ou « OK » (si toutes les informations sont disponibles) :

~/local/lib/python3/cmk_addons/plugins/flintstone/agent_based/flintstone_setup_check.py
def check_flintstone(section):
    missing = 0
    for e in ["contact", "name", "location"]:
        if section[e] == "":
            missing += 1
            yield Result(state=State.CRIT, summary=f"Missing information: {e}!")
    if missing > 0:
        yield Result(state=State.CRIT, summary=f"Missing fields: {missing}!")
    else:
        yield Result(state=State.OK, summary="All required information is available.")
Copier le contenu du fichier dans le presse-papiers
Le contenu du fichier a été copié avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Une fois la fonction de vérification créée, le plug-in de vérification sera prêt à l'emploi.

Nous avons mis ce plugin de vérification complet à disposition sur GitHub.

3.7. Test et activation du plug-in de vérification

Les tests et l'activation s'effectuent de la même manière que pour un plug-in de vérification basé sur un agent. Tout d'abord, assurez-vous que votre plug-in est syntaxiquement correct :

OMD[mysite]:~$ cmk-validate-plugins
Agent based plugins loading succeeded, Active checks loading succeeded, Special agents
loading succeeded, Rule specs loading succeeded, Rule specs forms creation succeeded,
Referenced rule specs validation succeeded, Loaded rule specs usage succeeded
Copier la ou les commandes dans le presse-papiers
Commande(s) copiée(s) avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

L'étape suivante consiste à détecter le service du plug-in :

OMD[mysite]:~$ cmk -vI --detect-plugins=flintstone_setup_check mydevice01
Discovering services and host labels on: mydevice01
mydevice01:
+ FETCHING DATA
No piggyback files for 'mydevice01'. Skip processing.
No piggyback files for '127.0.0.1'. Skip processing.
Get piggybacked data
+ ANALYSE DISCOVERED HOST LABELS
SUCCESS - Found no new host labels
+ ANALYSE DISCOVERED SERVICES
+ EXECUTING DISCOVERY PLUGINS (1)
  1 flintstone_setup_check
SUCCESS - Found 1 services
Copier la ou les commandes dans le presse-papiers
Commande(s) copiée(s) avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Comme prévu, la découverte du service a réussi. Vous pouvez désormais tester la vérification contenue dans le plug-in de vérification :

OMD[mysite]:~$ cmk -v --detect-plugins=flintstone_setup_check mydevice01
+ FETCHING DATA
No piggyback files for 'mydevice01'. Skip processing.
No piggyback files for '127.0.0.1'. Skip processing.
Get piggybacked data
Flintstone setup check All required information is available.
No piggyback files for 'mydevice01'. Skip processing.
No piggyback files for '127.0.0.1'. Skip processing.
[snmp] Success, [piggyback] Success ...
Copier la ou les commandes dans le presse-papiers
Commande(s) copiée(s) avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

Après le redémarrage du noyau de surveillance…

OMD[mysite]:~$ cmk -R
Generating configuration for core (type nagios)...
Precompiling host checks...OK
Validating Nagios configuration...OK
Restarting monitoring core...OK
Copier la ou les commandes dans le presse-papiers
Commande(s) copiée(s) avec succès dans le presse-papiers !
L'accès en écriture au presse-papiers a été refusé !

… le nouveau service sera alors visible dans la surveillance :

The new service created by the check plug-in in the monitoring.
Comme tous les champs des trois feuilles SNMP sont remplis, le service estOK

4. Dépannage

Étant donné que le dépannage des plug-ins de vérification basés sur des agents s'applique également, pour l'essentiel, aux plug-ins de vérification basés sur SNMP, nous n'aborderons ici que les spécificités de SNMP.

4.1. Options de simulation

Utilisation des parcours SNMP enregistrés dans Checkmk

Dans l'article consacré à la surveillance via SNMP, nous vous expliquons en détail comment créer des SNMP walks à partir de l'interface graphique et comment les utiliser à des fins de simulation. Cela permet également de développer des plug-ins de vérification sur des systèmes de test qui ne peuvent pas accéder aux hôtes SNMP pour lesquels vous développez un plug-in. Dans notre dépôt GitHub, vous trouverez un exemple de SNMP walk, que nous utilisons dans cet article et que vous pouvez utiliser pour développer et tester le plug-in de vérification.

Le démon SNMP factice

Si vous souhaitez vous assurer que des OID spécifiques changent en fonction les uns des autres, il peut être utile de programmer un démon SNMP factice qui fournit des données cohérentes. Le module Python snmp-agent peut vous aider à programmer un tel démon factice.

4.2. Matériel non coopératif

Avant qu'un périphérique puisse être surveillé à l'aide d'un nouveau plug-in de vérification basé sur SNMP, il doit d'abord pouvoir être surveillé via SNMP. Vous trouverez donc un aperçu des problèmes connus ainsi que des solutions suggérées dans l'article consacré à la surveillance via SNMP.

5. Fichiers et répertoires

Chemin d'accès au fichier Description

~/local/lib/python3/cmk_addons/plugins/

Répertoire de base pour le stockage des fichiers de plug-ins.

~/local/lib/python3/cmk_addons/plugins/<plug-in_family>/agent_based/

Emplacement de stockage des plug-ins de vérification écrits conformément à l'API Check V2.

~/local/share/snmp/mibs/

Stockez ici les fichiers MIB SNMP qui doivent être chargés automatiquement.


Last modified: Wed, 01 Apr 2026 14:25:53 GMT via commit 0903c1786
Sur cette page