Compare commits

..
12 Commits
Author SHA1 Message Date
hcornet c46836ab1c Dix-neuf packs applicatifs : JMX, API REST, SNMP
build / Garde-fou (push) Successful in 11m43s
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m57s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m29s
2026-09-12 11:31:25 +02:00
hcornet 9debdcdf9c Chaque pack apporte son propre calendrier de notification
build / Garde-fou (push) Successful in 10m45s
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m52s
build / Images Harbor (web, Dockerfile) (push) Successful in 10m0s
2026-09-12 11:02:02 +02:00
hcornet 032982cb28 Le calendrier livre par Centreon figure au projet sans etre recree
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m52s
build / Garde-fou (push) Successful in 10m45s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m18s
2026-09-12 10:04:11 +02:00
hcornet bc18f93196 Import d'un pack par la route de fusion, champs fermes, correction des champs vides
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m44s
build / Garde-fou (push) Successful in 10m44s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m25s
2026-09-11 21:15:23 +02:00
hcornet ec195cac8f Masquer les packs deja importes dans la fenetre d'import
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m52s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m15s
build / Garde-fou (push) Successful in 10m41s
2026-09-11 19:32:39 +02:00
hcornet 2187a1971e Groupes d'hotes : objet HG et suggestions dans le champ de l'hote
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m49s
build / Garde-fou (push) Successful in 10m37s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m15s
2026-09-11 19:06:36 +02:00
hcornet 23395779ee Catalogue range selon les categories des connecteurs Centreon
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m47s
build / Garde-fou (push) Successful in 10m40s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m13s
2026-09-11 17:56:54 +02:00
hcornet d2f11c3879 Treize packs materiel : baies de disques, commutateurs, wifi
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m47s
build / Garde-fou (push) Successful in 10m37s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m14s
2026-09-11 17:04:02 +02:00
hcornet 3879b63a88 Corps du message compose de blocs, macros Centreon en suggestion
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m50s
build / Garde-fou (push) Successful in 10m27s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m25s
2026-09-11 16:46:31 +02:00
hcornet cdfa377f46 Perimetres de notification et rattachement des modeles
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m58s
build / Garde-fou (push) Successful in 10m22s
build / Images Harbor (web, Dockerfile) (push) Successful in 13m11s
2026-09-11 15:59:40 +02:00
hcornet ac929c6878 Interface honnete sur l'acces aux comptes, fenetre de contribution
build / Garde-fou (push) Successful in 10m21s
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m48s
build / Images Harbor (web, Dockerfile) (push) Successful in 9m57s
2026-09-11 14:05:32 +02:00
hcornet 714470031d Message explicite quand le pack ou la branche existe deja
build / Garde-fou (push) Successful in 10m22s
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Canceled after 0s
build / Images Harbor (web, Dockerfile) (push) Canceled after 0s
2026-09-11 13:54:18 +02:00
101 changed files with 5964 additions and 132 deletions

No files matched your search

+4
View File
@@ -29,6 +29,10 @@ ENCLUME_PARTAGE_JOURS=90
ENCLUME_OIDC_METADATA=https://authentik.tips-of-mine.com/application/o/enclume/.well-known/openid-configuration
ENCLUME_OIDC_CLIENT_ID=
ENCLUME_OIDC_CLIENT_SECRET=
# Laisser a 0 tant que le fournisseur d'identite n'accepte pas les inscriptions :
# le site propose alors de contribuer par demande de fusion plutot qu'une
# connexion impossible a obtenir.
ENCLUME_INSCRIPTION_OUVERTE=0
ENCLUME_ADMIN_GROUPE=enclume-admins
# Depannage du premier demarrage, avant le mapping de portee "groups" :
ENCLUME_ADMIN_COMPTES=
+178
View File
@@ -3,6 +3,184 @@
Format : [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/).
Versionnement sémantique, comme décrit dans [docs/CONVENTIONS.md](docs/CONVENTIONS.md).
## 1.20.0
### Ajouté
- Dix-neuf packs applicatifs : Tomcat, JVM, Kafka, ActiveMQ et ZooKeeper en JMX ; Graylog,
Wazuh, HashiCorp Vault, Jenkins, Grafana, Prometheus, Veeam Enterprise Manager, Microsoft
IIS et Podman en API REST ; HAProxy, Keepalived, Squid et Microsoft DHCP en SNMP ; PHP-FPM
par sa page de statut
- Catalogue porté à 71 packs et 266 sondes, dont 22 en Applications
## 1.19.0
### Ajouté
- Un périmètre créé à la main reprend le dernier calendrier du projet, et propose d'en créer
un — en permanence ou en heures ouvrées — quand il n'y en a aucun
- Un périmètre sans calendrier est signalé dans son écran ; faute de choix, il vise `24x7`
sur le central, et la validation le rappelle
## 1.18.0
### Modifié
- Chaque pack apporte désormais **son propre** calendrier — `TP-App-Apache-24x7`,
`TP-App-Nginx-24x7`, `TP-HW-Printer-RFC3805-Heures-Ouvrees` — au lieu de pointer celui du
central : ajuster les plages d'une technologie ne modifie plus celles de tout le parc
## 1.17.0
### Modifié
- Le calendrier d'un pack figure désormais dans le projet même quand Centreon le livre :
il portait jusqu'ici une absence qui se lisait comme un oubli. Marqué « Centreon », il
montre ses plages, n'est pas recréé, et un bouton permet de forcer sa création si le
central l'a perdu
## 1.16.0
### Corrigé
- **L'import d'un pack n'apportait toujours que les commandes et les modèles.** La correction
annoncée en 1.11.1 n'avait jamais été appliquée : le remplacement dans l'éditeur avait
échoué en silence, et les tests ne couvraient que la route serveur. L'import passe
désormais par `/api/packs/<id>/fusionner`, et deux tests empruntent le chemin réel
- Les champs sans valeur affichaient le mot « undefined », notamment toutes les plages
horaires d'un calendrier neuf
- Un nouvel hôte rejoignait tous les groupes à chaque affichage : le groupe du dernier pack
importé est désormais pré-coché à la création seulement, et se décoche
### Modifié
- Version SNMP, criticité, calendrier d'un périmètre et commande de vérification deviennent
des listes fermées, avec une option « Autre valeur » qui révèle une saisie quand un objet
propre au central est nécessaire
- La couleur du bandeau se choisit dans un sélecteur de couleur
- Les groupes d'hôtes du projet se cochent ; un champ distinct reçoit ceux qui existent déjà
sur le central
- Un calendrier propose trois modèles de plages : en permanence, heures ouvrées, astreinte
## 1.15.0
### Modifié
- Les packs déjà présents dans le projet sont masqués de la fenêtre d'import, avec un
compteur et un lien pour les afficher : les reproposer n'avait aucun effet, l'import
les ignorait
## 1.14.1
### Modifié
- Le nom affiché dans l'interface devient « Forge Centreon », avec pour baseline
« Générateur de configuration pour Centreon avec CLAPI ». Le projet, le dépôt, les images
et le paquet Python restent « Enclume ».
## 1.14.0
### Ajouté
- Page d'aide « Installer SNMP » : configuration de départ sécurisée pour Debian, Ubuntu,
RHEL, Windows et les équipements réseau, avec la vérification depuis le collecteur
- Valeurs standards proposées pour les modèles parents, la version SNMP, le répertoire des
plugins, le collecteur et la criticité
### Modifié
- Moins de saisie libre : chaque champ qui a des valeurs connues les propose désormais
## 1.13.0
### Ajouté
- Chaque pack livre son groupe d'hôtes : importer un pack donne désormais les commandes,
les modèles, le groupe, le calendrier, le périmètre de notification et les prérequis
- La commande de vérification, ses arguments et le fuseau horaire sur l'hôte, où ils ont
leur place — ils n'existaient que sur le modèle d'hôte
- Un hôte créé après l'import d'un pack rejoint automatiquement son groupe
### Modifié
- Le fuseau horaire se choisit dans une liste fermée, alimentée par la base du système :
une faute de frappe ne se voyait qu'à l'exécution sur le central
- La commande de vérification propose celles livrées par Centreon et celles du projet
## 1.12.0
### Ajouté
- Groupes d'hôtes : objet `HG` créé par le projet, et suggestions dans le champ de l'hôte
- Un hôte peut appartenir à plusieurs groupes ; ceux qui ne sont pas dans le projet sont
signalés sans bloquer, ils peuvent exister sur le central
## 1.11.1
### Corrigé
- L'import d'un pack apportait seulement les commandes et les modèles : le calendrier, le
périmètre de notification, les hôtes et les prérequis étaient perdus en chemin. La fusion
est désormais faite par le serveur, qui connaît tous les objets d'un projet.
## 1.11.0
### Modifié
- Le catalogue adopte les catégories des connecteurs de supervision Centreon —
`operating-system`, `network`, `storage`, `database`, `virtualization`, `protocol`,
`ups-pdu`, `printer` et les autres — au lieu des trois familles maison. Les packs sont
reclassés et les répertoires renommés en conséquence.
## 1.10.0
### Ajouté
- Treize packs matériel : commutateurs Aruba, Extreme, Huawei, Alcatel OmniSwitch et Dell
PowerConnect ; wifi Cisco WLC, Aruba Instant et Ruckus ZoneDirector ; baies Dell EMC Unity,
Pure Storage, HPE MSA, IBM Storwize et NAS QNAP
- Catalogue porté à 52 packs et 224 sondes
## 1.9.0
### Ajouté
- Les 39 packs du catalogue livrent leur chaîne de notification : calendrier selon la
criticité, groupe de contacts dédié, impact métier, et rattachement des modèles d'hôte
et de service au périmètre
- Section `notification` dans le format de pack
### Corrigé
- Les calendriers livrés par Centreon (`24x7`, `workhours`…) sont référencés et non recréés :
`TP;ADD` aurait échoué sur un objet existant et interrompu le déploiement
## 1.8.0
### Ajouté
- Corps du message composé de blocs ordonnables : macro, lien, texte fixe, sortie du contrôle,
définis séparément pour l'hôte et pour le service
- Une quarantaine de macros Centreon proposées en suggestion, dont `$NOTIFICATIONAUTHOR$`,
`$NOTIFICATIONCOMMENT$`, les URL de notes et d'action, les données de performance
- Les macros personnalisées `$_HOSTXXX$` et `$_SERVICEXXX$` sont acceptées
### Modifié
- Une macro sans valeur à l'exécution n'affiche plus de ligne vide
## 1.7.0
### Ajouté
- Aperçu du message de notification dans l'éditeur, pour l'hôte et pour le service
- Gabarit HTML unique, partagé par l'aperçu et le script PHP généré
## 1.6.0
### Ajouté
- Périmètres de notification : calendrier, destinataires, états déclencheurs et contexte
métier — application, responsable, criticité, impact, procédure de reprise
- Calendriers de notification, objets `TP` avec leurs plages horaires
- Génération d'un script PHP par périmètre, avec le shebang `#!/usr/bin/php -c /etc/php.ini`,
et d'un script d'installation qui vérifie la syntaxe avant de déposer
- Paramétrage des contacts et création des groupes de contacts
- Rattachement d'un modèle d'hôte ou de service à un périmètre : calendrier, états
déclencheurs, intervalle et groupe de contacts posés directement sur le modèle
## 1.5.0
### Ajouté
- `ENCLUME_INSCRIPTION_OUVERTE` : tant que le fournisseur d'identité n'accepte pas les
inscriptions, le site propose « Contribuer » plutôt qu'une connexion impossible à obtenir
- Fenêtre expliquant comment proposer ou vérifier un pack sans compte
## 1.4.2
### Corrigé
- Un pack dont le fichier existe déjà dans le dépôt donne un message explicite, au lieu
d'un échec sans motif
- Même chose pour une branche de publication déjà présente
## 1.4.1
### Corrigé
+37 -1
View File
@@ -17,7 +17,7 @@ immédiatement, et une demande de fusion est ouverte après relecture.
```yaml
id: app-rabbitmq # minuscules, chiffres et tirets
name: RabbitMQ # nom lisible, affiché dans le catalogue
category: application # system | hardware | application
category: applications # une des catégories ci-dessous
status: to-verify # verified seulement si éprouvé sur un central réel
plugin: centreon_rabbitmq_restapi.pl
description: Supervision d'un broker RabbitMQ via son API de management.
@@ -37,6 +37,23 @@ prerequis: # facultatif mais précieux
notes: |
Activer le plugin de management et créer un compte en lecture seule.
groupe_hote: # le groupe dans lequel ranger les hôtes
name: HG-App-RabbitMQ
alias: RabbitMQ
notification: # la chaîne d'alerte livrée avec le pack
perimetre: RabbitMQ
calendrier: # le pack apporte le sien, il ne réutilise pas celui du central
name: TP-App-RabbitMQ-24x7
modele: 24x7 # 24x7 ou Heures-Ouvrees : le rythme copié
alias: RabbitMQ, en permanence
groupe: CG-App-RabbitMQ # CG-<Famille>-<Techno>
criticite: Majeure
impact: "Échanges entre applications interrompus"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Queues # donnera le modèle App-RabbitMQ-Queues
alias: Queues
@@ -47,6 +64,18 @@ services:
- {name: WARNING, value: "1000", description: "Seuil warning"}
```
### Les catégories
Ce sont celles des connecteurs de supervision Centreon, pour qu'un pack se range là où on
ira le chercher dans la documentation officielle :
`operating-system`, `network`, `hardware-server`, `storage`, `database`, `applications`,
`virtualization`, `protocol`, `ups-pdu`, `printer`, `sensor`, `cloud`, `toip-voip`,
`blockchain`, `centreon`.
Le fichier se dépose dans `catalog/<catégorie>/<id>.yml`, et le champ `category` porte la
même valeur.
### Les règles
- **Pas de point-virgule** dans une ligne de commande : c'est le séparateur CLAPI, il casserait
@@ -55,6 +84,13 @@ services:
- **Ce qui est commun à l'hôte va sur l'hôte** : ports, comptes, options du plugin. Ce qui est
propre à une sonde va sur la sonde : seuils, filtres.
- **Aucun mot de passe réel.** Valeur vide et `is_password: true`.
- **Un groupe d'hôtes.** Nommé `HG-<Famille>-<Techno>`. Un hôte sans groupe devient
introuvable dès que le parc grandit, et les droits comme les filtres s'appuient dessus.
- **Une chaîne de notification.** Un pack qui supervise sans prévenir personne n'a pas
d'intérêt : `calendrier`, `groupe` et `impact` sont attendus. Choisissez `24x7` pour ce
dont la panne réveille quelqu'un, `Heures-Ouvrees` sinon. Les calendriers livrés par
Centreon. Chaque pack apporte **son propre** calendrier, nommé `TP-<Famille>-<Techno>-<rythme>` :
ajuster les plages d'une technologie ne doit pas modifier celles de tout le central.
- **`status: verified`** uniquement si vous avez exécuté ces commandes sur un Centreon. Sinon
`to-verify`, c'est honnête et c'est utile.
- `$CENTREONPLUGINS$` est remplacé par le répertoire de plugins choisi par l'utilisateur.
+9 -1
View File
@@ -10,7 +10,7 @@ Projet indépendant, sans lien avec Centreon SAS.
- **Éditeur libre** : commandes, modèles de service, modèles d'hôte, hôtes. Héritage,
duplication, rattachement des services aux modèles d'hôte.
- **Catalogue de départ** : 39 packs, 177 sondes, importables puis modifiables.
- **Catalogue de départ** : 71 packs, 266 sondes, importables puis modifiables.
- **Validation** avant génération : noms en double, références manquantes, point-virgule
interdit, services rattachés à aucun modèle d'hôte, mots de passe en clair.
- **Quatre fichiers** : `deploy.sh` (avec `--dry-run`), `deploy.clapi` (import CLAPI),
@@ -20,6 +20,9 @@ Projet indépendant, sans lien avec Centreon SAS.
- **Prérequis d'installation** : un pack peut déclarer ses paquets et ses droits, générés
dans un `prerequis.sh` distinct du CLAPI.
- **Notifications par périmètre** : calendriers, destinataires, états déclencheurs et
message personnalisé par domaine applicatif ou système — voir
[docs/NOTIFICATIONS.md](docs/NOTIFICATIONS.md).
- **Partage par lien**, projets enregistrés et **soumission de packs** quand l'instance est
configurée pour — voir [docs/COMPTES-ET-MODERATION.md](docs/COMPTES-ET-MODERATION.md).
@@ -74,6 +77,11 @@ python3 -m enclume.cli --projet mon-projet.json --out ./sortie
|---|---|
| `GET /api/packs` | catalogue |
| `GET /api/packs/<id>/projet` | un pack converti en objets de projet |
| `POST /api/packs/<id>/fusionner` | ajoute un pack au projet en cours |
| `GET /api/fuseaux` | fuseaux horaires connus du système |
| `GET /api/valeurs-standards` | modèles parents, versions SNMP, criticités |
| `GET /aide/snmp` | installer et sécuriser SNMP, par système |
| `GET /api/commandes-usuelles` | commandes de vérification livrées par Centreon |
| `POST /api/valider` | validation seule |
| `POST /api/generer` | validation et génération des quatre fichiers |
| `POST /telecharger` | archive zip |
+62
View File
@@ -0,0 +1,62 @@
id: app-activemq-jmx
name: Apache ActiveMQ (JMX)
category: applications
status: to-verify
plugin: centreon_activemq_jmx.pl
description: Supervision d'un courtier ActiveMQ via JMX et l'agent Jolokia.
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
notes: |
Deployer l'agent Jolokia dans la JVM supervisee et exposer son point
d'acces au collecteur : les plugins JMX de Centreon passent par lui.
host_template:
name: App-ActiveMQ-JMX-custom
alias: Applicatif ActiveMQ JMX
parents: [generic-active-host-custom]
macros:
- {name: JMXURL, value: "http://localhost:8080/jolokia", description: "URL de l'agent Jolokia"}
- {name: JMXUSERNAME, value: "", description: "Compte Jolokia"}
- {name: JMXPASSWORD, value: "", description: "Mot de passe Jolokia", is_password: true}
- {name: JMXEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-ActiveMQ-JMX
alias: Apache ActiveMQ (JMX)
notification:
perimetre: Apache ActiveMQ (JMX)
calendrier:
name: TP-App-ActiveMQ-JMX-24x7
modele: 24x7
alias: Apache ActiveMQ (JMX), en permanence
groupe: CG-App-ActiveMQ-JMX
criticite: Majeure
impact: "Files de messages bloquees"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Queues
alias: Queues
description: Messages en attente dans les files
line: "$CENTREONPLUGINS$/centreon_activemq_jmx.pl --plugin=apps::activemq::jmx::plugin --mode=queues --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Topics
alias: Topics
description: Sujets et abonnes
line: "$CENTREONPLUGINS$/centreon_activemq_jmx.pl --plugin=apps::activemq::jmx::plugin --mode=topics --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Broker-Usage
alias: Broker-Usage
description: Memoire et stockage du courtier
line: "$CENTREONPLUGINS$/centreon_activemq_jmx.pl --plugin=apps::activemq::jmx::plugin --mode=broker-usage --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: app-apache
name: Apache HTTP Server
category: application
category: applications
status: verified
plugin: centreon_apache_serverstatus.pl
description: Supervision d'un serveur Apache via la page mod_status (charge CPU, requetes, slots, temps de reponse).
@@ -13,6 +13,21 @@ host_template:
- {name: APACHEPROTO, value: "http", description: "Protocole (http ou https)"}
- {name: APACHEURLPATH, value: "/server-status/?auto", description: "Chemin de la page mod_status"}
- {name: APACHEEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Apache
alias: Apache HTTP Server
notification:
perimetre: Apache HTTP Server
calendrier:
name: TP-App-Apache-24x7
modele: 24x7
alias: Apache HTTP Server, en permanence
groupe: CG-App-Apache
criticite: Majeure
impact: "Sites et applications web indisponibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu-Load
alias: Cpu-Load
+38
View File
@@ -0,0 +1,38 @@
id: app-dhcp-snmp
name: Microsoft DHCP (SNMP)
category: applications
status: to-verify
plugin: centreon_microsoft_dhcp_snmp.pl
description: Supervision d'un serveur DHCP Microsoft en SNMP (occupation des etendues).
host_template:
name: App-DHCP-SNMP-custom
alias: Applicatif Microsoft DHCP
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-DHCP-SNMP
alias: Microsoft DHCP (SNMP)
notification:
perimetre: Microsoft DHCP (SNMP)
calendrier:
name: TP-App-DHCP-SNMP-24x7
modele: 24x7
alias: Microsoft DHCP (SNMP), en permanence
groupe: CG-App-DHCP-SNMP
criticite: Critique
impact: "Attribution d'adresses interrompue, postes sans reseau"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Subnet-Usage
alias: Subnet-Usage
description: Occupation des etendues
line: "$CENTREONPLUGINS$/centreon_microsoft_dhcp_snmp.pl --plugin=apps::microsoft::dhcp::snmp::plugin --mode=subnet-usage --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: app-elasticsearch
name: Elasticsearch
category: application
category: applications
status: to-verify
plugin: centreon_elasticsearch_restapi.pl
description: Supervision d'un cluster Elasticsearch via son API REST (sante du cluster, noeuds, index).
@@ -20,6 +20,21 @@ host_template:
- {name: ESUSERNAME, value: "", description: "Compte de supervision"}
- {name: ESPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: ESEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Elasticsearch
alias: Elasticsearch
notification:
perimetre: Elasticsearch
calendrier:
name: TP-App-Elasticsearch-24x7
modele: 24x7
alias: Elasticsearch, en permanence
groupe: CG-App-Elasticsearch
criticite: Majeure
impact: "Recherche et journalisation degradees"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cluster-Status
alias: Cluster-Status
+41
View File
@@ -0,0 +1,41 @@
id: app-grafana
name: Grafana
category: applications
status: to-verify
plugin: centreon_grafana_restapi.pl
description: Supervision d'un serveur Grafana via son API REST (etat de fonctionnement).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
host_template:
name: App-Grafana-custom
alias: Applicatif Grafana
parents: [generic-active-host-custom]
macros:
- {name: APIPORT, value: "443", description: "Port de l'API"}
- {name: APIPROTO, value: "https", description: "Protocole d'acces"}
- {name: APITOKEN, value: "", description: "Jeton d'API", is_password: true}
- {name: APIEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Grafana
alias: Grafana
notification:
perimetre: Grafana
calendrier:
name: TP-App-Grafana-24x7
modele: 24x7
alias: Grafana, en permanence
groupe: CG-App-Grafana
criticite: Mineure
impact: "Tableaux de bord indisponibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Health
alias: Health
description: Etat de fonctionnement du serveur
line: "$CENTREONPLUGINS$/centreon_grafana_restapi.pl --plugin=apps::grafana::restapi::plugin --mode=health --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-token='$_HOSTAPITOKEN$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+50
View File
@@ -0,0 +1,50 @@
id: app-graylog
name: Graylog
category: applications
status: to-verify
plugin: centreon_graylog_restapi.pl
description: Supervision d'un serveur Graylog via son API REST (notifications, recherches).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
host_template:
name: App-Graylog-custom
alias: Applicatif Graylog
parents: [generic-active-host-custom]
macros:
- {name: APIPORT, value: "443", description: "Port de l'API"}
- {name: APIPROTO, value: "https", description: "Protocole d'acces"}
- {name: APIUSERNAME, value: "centreon", description: "Compte de supervision"}
- {name: APIPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: APIEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Graylog
alias: Graylog
notification:
perimetre: Graylog
calendrier:
name: TP-App-Graylog-24x7
modele: 24x7
alias: Graylog, en permanence
groupe: CG-App-Graylog
criticite: Majeure
impact: "Collecte et recherche de journaux interrompues"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Notifications
alias: Notifications
description: Notifications systeme du cluster
line: "$CENTREONPLUGINS$/centreon_graylog_restapi.pl --plugin=apps::graylog::restapi::plugin --mode=notifications --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-username='$_HOSTAPIUSERNAME$' --api-password='$_HOSTAPIPASSWORD$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Query
alias: Query
description: Nombre de messages correspondant a une recherche
line: "$CENTREONPLUGINS$/centreon_graylog_restapi.pl --plugin=apps::graylog::restapi::plugin --mode=query --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-username='$_HOSTAPIUSERNAME$' --api-password='$_HOSTAPIPASSWORD$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+46
View File
@@ -0,0 +1,46 @@
id: app-haproxy-snmp
name: HAProxy (SNMP)
category: applications
status: to-verify
plugin: centreon_haproxy_snmp.pl
description: Supervision d'un repartiteur HAProxy en SNMP (frontaux, arrieres, sessions).
host_template:
name: App-HAProxy-SNMP-custom
alias: Applicatif HAProxy SNMP
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-HAProxy-SNMP
alias: HAProxy (SNMP)
notification:
perimetre: HAProxy (SNMP)
calendrier:
name: TP-App-HAProxy-SNMP-24x7
modele: 24x7
alias: HAProxy (SNMP), en permanence
groupe: CG-App-HAProxy-SNMP
criticite: Critique
impact: "Repartition de charge degradee, services web inaccessibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Frontend-Usage
alias: Frontend-Usage
description: Sessions et trafic des frontaux
line: "$CENTREONPLUGINS$/centreon_haproxy_snmp.pl --plugin=apps::haproxy::snmp::plugin --mode=frontend-usage --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Backend-Usage
alias: Backend-Usage
description: Sessions et etat des arrieres
line: "$CENTREONPLUGINS$/centreon_haproxy_snmp.pl --plugin=apps::haproxy::snmp::plugin --mode=backend-usage --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -0,0 +1,49 @@
id: app-hashicorp-vault
name: HashiCorp Vault
category: applications
status: to-verify
plugin: centreon_hashicorp_vault_restapi.pl
description: Supervision d'un serveur HashiCorp Vault via son API REST (scellement, stockage Raft).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
host_template:
name: App-Vault-custom
alias: Applicatif HashiCorp Vault
parents: [generic-active-host-custom]
macros:
- {name: APIPORT, value: "443", description: "Port de l'API"}
- {name: APIPROTO, value: "https", description: "Protocole d'acces"}
- {name: APITOKEN, value: "", description: "Jeton d'API", is_password: true}
- {name: APIEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Vault
alias: HashiCorp Vault
notification:
perimetre: HashiCorp Vault
calendrier:
name: TP-App-Vault-24x7
modele: 24x7
alias: HashiCorp Vault, en permanence
groupe: CG-App-Vault
criticite: Critique
impact: "Secrets inaccessibles, applications dependantes bloquees"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Seal-Status
alias: Seal-Status
description: Etat de scellement du coffre
line: "$CENTREONPLUGINS$/centreon_hashicorp_vault_restapi.pl --plugin=apps::hashicorp::vault::restapi::plugin --mode=seal-status --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-token='$_HOSTAPITOKEN$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Raft-Storage
alias: Raft-Storage
description: Performances du stockage Raft
line: "$CENTREONPLUGINS$/centreon_hashicorp_vault_restapi.pl --plugin=apps::hashicorp::vault::restapi::plugin --mode=raft-storage --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-token='$_HOSTAPITOKEN$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+50
View File
@@ -0,0 +1,50 @@
id: app-iis-restapi
name: Microsoft IIS (API REST)
category: applications
status: to-verify
plugin: centreon_iis_restapi.pl
description: Supervision d'un serveur IIS via l'API REST de l'administration (pools, sites).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
host_template:
name: App-IIS-custom
alias: Applicatif Microsoft IIS
parents: [generic-active-host-custom]
macros:
- {name: APIPORT, value: "443", description: "Port de l'API"}
- {name: APIPROTO, value: "https", description: "Protocole d'acces"}
- {name: APIUSERNAME, value: "centreon", description: "Compte de supervision"}
- {name: APIPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: APIEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-IIS
alias: Microsoft IIS (API REST)
notification:
perimetre: Microsoft IIS (API REST)
calendrier:
name: TP-App-IIS-24x7
modele: 24x7
alias: Microsoft IIS (API REST), en permanence
groupe: CG-App-IIS
criticite: Majeure
impact: "Sites et applications web indisponibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Application-Pools
alias: Application-Pools
description: Etat des pools d'applications
line: "$CENTREONPLUGINS$/centreon_iis_restapi.pl --plugin=apps::microsoft::iis::restapi::plugin --mode=application-pools --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-username='$_HOSTAPIUSERNAME$' --api-password='$_HOSTAPIPASSWORD$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Web-Sites
alias: Web-Sites
description: Trafic et connexions des sites
line: "$CENTREONPLUGINS$/centreon_iis_restapi.pl --plugin=apps::microsoft::iis::restapi::plugin --mode=web-sites --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-username='$_HOSTAPIUSERNAME$' --api-password='$_HOSTAPIPASSWORD$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+49
View File
@@ -0,0 +1,49 @@
id: app-jenkins
name: Jenkins
category: applications
status: to-verify
plugin: centreon_jenkins_restapi.pl
description: Supervision d'un serveur Jenkins via son API REST (etat des travaux).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
host_template:
name: App-Jenkins-custom
alias: Applicatif Jenkins
parents: [generic-active-host-custom]
macros:
- {name: APIPORT, value: "443", description: "Port de l'API"}
- {name: APIPROTO, value: "https", description: "Protocole d'acces"}
- {name: APITOKEN, value: "", description: "Jeton d'API", is_password: true}
- {name: APIEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Jenkins
alias: Jenkins
notification:
perimetre: Jenkins
calendrier:
name: TP-App-Jenkins-24x7
modele: 24x7
alias: Jenkins, en permanence
groupe: CG-App-Jenkins
criticite: Mineure
impact: "Chaines d'integration continue a l'arret"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Jobs
alias: Jobs
description: Etat des travaux
line: "$CENTREONPLUGINS$/centreon_jenkins_restapi.pl --plugin=apps::jenkins::restapi::plugin --mode=jobs --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-token='$_HOSTAPITOKEN$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Nodes
alias: Nodes
description: Etat des agents de construction
line: "$CENTREONPLUGINS$/centreon_jenkins_restapi.pl --plugin=apps::jenkins::restapi::plugin --mode=nodes --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-token='$_HOSTAPITOKEN$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+70
View File
@@ -0,0 +1,70 @@
id: app-jvm-jmx
name: Machine virtuelle Java (JMX)
category: applications
status: to-verify
plugin: centreon_java_jvm.pl
description: Supervision d'une machine virtuelle Java via JMX et l'agent Jolokia.
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
notes: |
Deployer l'agent Jolokia dans la JVM supervisee et exposer son point
d'acces au collecteur : les plugins JMX de Centreon passent par lui.
host_template:
name: App-JVM-JMX-custom
alias: Applicatif JVM JMX
parents: [generic-active-host-custom]
macros:
- {name: JMXURL, value: "http://localhost:8080/jolokia", description: "URL de l'agent Jolokia"}
- {name: JMXUSERNAME, value: "", description: "Compte Jolokia"}
- {name: JMXPASSWORD, value: "", description: "Mot de passe Jolokia", is_password: true}
- {name: JMXEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-JVM-JMX
alias: Machine virtuelle Java (JMX)
notification:
perimetre: Machine virtuelle Java (JMX)
calendrier:
name: TP-App-JVM-JMX-24x7
modele: 24x7
alias: Machine virtuelle Java (JMX), en permanence
groupe: CG-App-JVM-JMX
criticite: Majeure
impact: "Application Java degradee ou arretee"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Memory
alias: Memory
description: Memoire utilisee par la JVM
line: "$CENTREONPLUGINS$/centreon_java_jvm.pl --plugin=apps::java::jvm::plugin --mode=memory --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Gc
alias: Gc
description: Ramasse-miettes
line: "$CENTREONPLUGINS$/centreon_java_jvm.pl --plugin=apps::java::jvm::plugin --mode=gcutil --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Threads
alias: Threads
description: Fils d'execution
line: "$CENTREONPLUGINS$/centreon_java_jvm.pl --plugin=apps::java::jvm::plugin --mode=threads --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Class-Count
alias: Class-Count
description: Classes chargees
line: "$CENTREONPLUGINS$/centreon_java_jvm.pl --plugin=apps::java::jvm::plugin --mode=class-count --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+62
View File
@@ -0,0 +1,62 @@
id: app-kafka-jmx
name: Apache Kafka (JMX)
category: applications
status: to-verify
plugin: centreon_kafka_jmx.pl
description: Supervision d'un courtier Kafka via JMX et l'agent Jolokia.
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
notes: |
Deployer l'agent Jolokia dans la JVM supervisee et exposer son point
d'acces au collecteur : les plugins JMX de Centreon passent par lui.
host_template:
name: App-Kafka-JMX-custom
alias: Applicatif Kafka JMX
parents: [generic-active-host-custom]
macros:
- {name: JMXURL, value: "http://localhost:8080/jolokia", description: "URL de l'agent Jolokia"}
- {name: JMXUSERNAME, value: "", description: "Compte Jolokia"}
- {name: JMXPASSWORD, value: "", description: "Mot de passe Jolokia", is_password: true}
- {name: JMXEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Kafka-JMX
alias: Apache Kafka (JMX)
notification:
perimetre: Apache Kafka (JMX)
calendrier:
name: TP-App-Kafka-JMX-24x7
modele: 24x7
alias: Apache Kafka (JMX), en permanence
groupe: CG-App-Kafka-JMX
criticite: Majeure
impact: "Echanges entre applications interrompus"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Broker-Status
alias: Broker-Status
description: Etat du courtier et partitions
line: "$CENTREONPLUGINS$/centreon_kafka_jmx.pl --plugin=apps::kafka::jmx::plugin --mode=brokers --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Topics
alias: Topics
description: Trafic par sujet
line: "$CENTREONPLUGINS$/centreon_kafka_jmx.pl --plugin=apps::kafka::jmx::plugin --mode=topics --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Global
alias: Global
description: Statistiques globales du cluster
line: "$CENTREONPLUGINS$/centreon_kafka_jmx.pl --plugin=apps::kafka::jmx::plugin --mode=global --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -0,0 +1,36 @@
id: app-keepalived-snmp
name: Keepalived (SNMP)
category: applications
status: to-verify
plugin: centreon_keepalived_snmp.pl
description: Supervision de l'etat VRRP d'un noeud Keepalived en SNMP.
host_template:
name: App-Keepalived-SNMP-custom
alias: Applicatif Keepalived SNMP
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Keepalived-SNMP
alias: Keepalived (SNMP)
notification:
perimetre: Keepalived (SNMP)
calendrier:
name: TP-App-Keepalived-SNMP-24x7
modele: 24x7
alias: Keepalived (SNMP), en permanence
groupe: CG-App-Keepalived-SNMP
criticite: Critique
impact: "Bascule d'adresse virtuelle compromise"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Vrrp-Status
alias: Vrrp-Status
description: Etat des instances VRRP
line: "$CENTREONPLUGINS$/centreon_keepalived_snmp.pl --plugin=apps::keepalived::snmp::plugin --mode=vrrp-status --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: app-nginx
name: Nginx
category: application
category: applications
status: verified
plugin: centreon_nginx_serverstatus.pl
description: Supervision d'un serveur Nginx via le module stub_status (connexions, requetes, temps de reponse).
@@ -13,6 +13,21 @@ host_template:
- {name: NGINXPROTO, value: "http", description: "Protocole (http ou https)"}
- {name: NGINXURLPATH, value: "/nginx_status", description: "Chemin de la page stub_status"}
- {name: NGINXEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Nginx
alias: Nginx
notification:
perimetre: Nginx
calendrier:
name: TP-App-Nginx-24x7
modele: 24x7
alias: Nginx, en permanence
groupe: CG-App-Nginx
criticite: Majeure
impact: "Sites et applications web indisponibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Connections
alias: Connections
+54
View File
@@ -0,0 +1,54 @@
id: app-php-fpm
name: PHP-FPM
category: applications
status: to-verify
plugin: centreon_php_fpm_web.pl
description: Supervision d'un pool PHP-FPM via sa page de statut (processus, file d'attente, requetes).
prerequis:
paquets:
debian: [libwww-perl]
rhel: [perl-libwww-perl]
notes: |
Activer pm.status_path dans la configuration du pool, et exposer ce chemin
au collecteur depuis le serveur web.
host_template:
name: App-PHP-FPM-custom
alias: Applicatif PHP-FPM
parents: [generic-active-host-custom]
macros:
- {name: FPMPORT, value: "80", description: "Port du serveur web"}
- {name: FPMPROTO, value: "http", description: "Protocole d'acces"}
- {name: FPMURLPATH, value: "/status", description: "Chemin de la page de statut"}
- {name: FPMEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-PHP-FPM
alias: PHP-FPM
notification:
perimetre: PHP-FPM
calendrier:
name: TP-App-PHP-FPM-24x7
modele: 24x7
alias: PHP-FPM, en permanence
groupe: CG-App-PHP-FPM
criticite: Majeure
impact: "Applications PHP indisponibles ou saturees"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Processes
alias: Processes
description: Processus actifs, inactifs et file d'attente
line: "$CENTREONPLUGINS$/centreon_php_fpm_web.pl --plugin=apps::php::fpm::web::plugin --mode=usage --hostname=$HOSTADDRESS$ --port='$_HOSTFPMPORT$' --proto='$_HOSTFPMPROTO$' --urlpath='$_HOSTFPMURLPATH$' --warning-active-processes='$_SERVICEWARNING$' --critical-active-processes='$_SERVICECRITICAL$' $_HOSTFPMEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning sur les processus actifs"}
- {name: CRITICAL, value: "", description: "Seuil critical sur les processus actifs"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Listen-Queue
alias: Listen-Queue
description: File d'attente des connexions
line: "$CENTREONPLUGINS$/centreon_php_fpm_web.pl --plugin=apps::php::fpm::web::plugin --mode=usage --hostname=$HOSTADDRESS$ --port='$_HOSTFPMPORT$' --proto='$_HOSTFPMPROTO$' --urlpath='$_HOSTFPMURLPATH$' --warning-listen-queue='$_SERVICEWARNING$' --critical-listen-queue='$_SERVICECRITICAL$' $_HOSTFPMEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "1", description: "Seuil warning sur la file d'attente"}
- {name: CRITICAL, value: "10", description: "Seuil critical sur la file d'attente"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+43
View File
@@ -0,0 +1,43 @@
id: app-prometheus
name: Prometheus
category: applications
status: to-verify
plugin: centreon_prometheus_api.pl
description: Supervision d'un serveur Prometheus via son API REST (cibles).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
host_template:
name: App-Prometheus-custom
alias: Applicatif Prometheus
parents: [generic-active-host-custom]
macros:
- {name: APIPORT, value: "443", description: "Port de l'API"}
- {name: APIPROTO, value: "https", description: "Protocole d'acces"}
- {name: APITOKEN, value: "", description: "Jeton d'API", is_password: true}
- {name: APIEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Prometheus
alias: Prometheus
notification:
perimetre: Prometheus
calendrier:
name: TP-App-Prometheus-24x7
modele: 24x7
alias: Prometheus, en permanence
groupe: CG-App-Prometheus
criticite: Mineure
impact: "Collecte de metriques interrompue"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Targets
alias: Targets
description: Etat des cibles de collecte
line: "$CENTREONPLUGINS$/centreon_prometheus_api.pl --plugin=cloud::prometheus::restapi::plugin --mode=targets --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-token='$_HOSTAPITOKEN$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: app-rabbitmq
name: RabbitMQ
category: application
category: applications
status: to-verify
plugin: centreon_rabbitmq_restapi.pl
description: Supervision d'un broker RabbitMQ via son API de management (files, noeuds, connexions).
@@ -21,6 +21,21 @@ host_template:
- {name: RABBITUSERNAME, value: "centreon", description: "Compte de supervision"}
- {name: RABBITPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: RABBITEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-RabbitMQ
alias: RabbitMQ
notification:
perimetre: RabbitMQ
calendrier:
name: TP-App-RabbitMQ-24x7
modele: 24x7
alias: RabbitMQ, en permanence
groupe: CG-App-RabbitMQ
criticite: Majeure
impact: "Echanges entre applications interrompus"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Node-Usage
alias: Node-Usage
+54
View File
@@ -0,0 +1,54 @@
id: app-squid-snmp
name: Squid (SNMP)
category: applications
status: to-verify
plugin: centreon_squid_snmp.pl
description: Supervision d'un mandataire Squid en SNMP (cache, trafic, ressources).
host_template:
name: App-Squid-SNMP-custom
alias: Applicatif Squid SNMP
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Squid-SNMP
alias: Squid (SNMP)
notification:
perimetre: Squid (SNMP)
calendrier:
name: TP-App-Squid-SNMP-24x7
modele: 24x7
alias: Squid (SNMP), en permanence
groupe: CG-App-Squid-SNMP
criticite: Majeure
impact: "Acces web des postes bloque ou ralenti"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cache-Usage
alias: Cache-Usage
description: Taux de succes et occupation du cache
line: "$CENTREONPLUGINS$/centreon_squid_snmp.pl --plugin=apps::squid::snmp::plugin --mode=cache-usage --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Traffic
alias: Traffic
description: Trafic HTTP et ICP
line: "$CENTREONPLUGINS$/centreon_squid_snmp.pl --plugin=apps::squid::snmp::plugin --mode=traffic --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: System
alias: System
description: Processeur et memoire du service
line: "$CENTREONPLUGINS$/centreon_squid_snmp.pl --plugin=apps::squid::snmp::plugin --mode=system --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+70
View File
@@ -0,0 +1,70 @@
id: app-tomcat-jmx
name: Apache Tomcat (JMX)
category: applications
status: to-verify
plugin: centreon_tomcat_jmx.pl
description: Supervision d'un serveur Tomcat via JMX et l'agent Jolokia.
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
notes: |
Deployer l'agent Jolokia dans la JVM supervisee et exposer son point
d'acces au collecteur : les plugins JMX de Centreon passent par lui.
host_template:
name: App-Tomcat-JMX-custom
alias: Applicatif Tomcat JMX
parents: [generic-active-host-custom]
macros:
- {name: JMXURL, value: "http://localhost:8080/jolokia", description: "URL de l'agent Jolokia"}
- {name: JMXUSERNAME, value: "", description: "Compte Jolokia"}
- {name: JMXPASSWORD, value: "", description: "Mot de passe Jolokia", is_password: true}
- {name: JMXEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Tomcat-JMX
alias: Apache Tomcat (JMX)
notification:
perimetre: Apache Tomcat (JMX)
calendrier:
name: TP-App-Tomcat-JMX-24x7
modele: 24x7
alias: Apache Tomcat (JMX), en permanence
groupe: CG-App-Tomcat-JMX
criticite: Majeure
impact: "Applications Java hebergees indisponibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Memory
alias: Memory
description: Memoire de la JVM
line: "$CENTREONPLUGINS$/centreon_tomcat_jmx.pl --plugin=apps::tomcat::jmx::plugin --mode=memory-detailed --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Threads
alias: Threads
description: Fils d'execution
line: "$CENTREONPLUGINS$/centreon_tomcat_jmx.pl --plugin=apps::tomcat::jmx::plugin --mode=threads --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Sessions
alias: Sessions
description: Sessions des applications web
line: "$CENTREONPLUGINS$/centreon_tomcat_jmx.pl --plugin=apps::tomcat::jmx::plugin --mode=sessions --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Requests
alias: Requests
description: Requetes traitees par les connecteurs
line: "$CENTREONPLUGINS$/centreon_tomcat_jmx.pl --plugin=apps::tomcat::jmx::plugin --mode=connector-usage --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+50
View File
@@ -0,0 +1,50 @@
id: app-veeam-vbem
name: Veeam Backup Enterprise Manager
category: applications
status: to-verify
plugin: centreon_veeam_vbem_restapi.pl
description: Supervision de Veeam Backup Enterprise Manager via son API REST (travaux, depots).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
host_template:
name: App-Veeam-VBEM-custom
alias: Applicatif Veeam Enterprise Manager
parents: [generic-active-host-custom]
macros:
- {name: APIPORT, value: "443", description: "Port de l'API"}
- {name: APIPROTO, value: "https", description: "Protocole d'acces"}
- {name: APIUSERNAME, value: "centreon", description: "Compte de supervision"}
- {name: APIPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: APIEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Veeam-VBEM
alias: Veeam Backup Enterprise Manager
notification:
perimetre: Veeam Backup Enterprise Manager
calendrier:
name: TP-App-Veeam-VBEM-24x7
modele: 24x7
alias: Veeam Backup Enterprise Manager, en permanence
groupe: CG-App-Veeam-VBEM
criticite: Critique
impact: "Sauvegardes non verifiees, restauration compromise"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Job-Status
alias: Job-Status
description: Etat des travaux de sauvegarde
line: "$CENTREONPLUGINS$/centreon_veeam_vbem_restapi.pl --plugin=apps::backup::veeam::vbem::restapi::plugin --mode=job-status --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-username='$_HOSTAPIUSERNAME$' --api-password='$_HOSTAPIPASSWORD$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Repository-Usage
alias: Repository-Usage
description: Occupation des depots
line: "$CENTREONPLUGINS$/centreon_veeam_vbem_restapi.pl --plugin=apps::backup::veeam::vbem::restapi::plugin --mode=repository-usage --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-username='$_HOSTAPIUSERNAME$' --api-password='$_HOSTAPIPASSWORD$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+50
View File
@@ -0,0 +1,50 @@
id: app-wazuh
name: Wazuh
category: applications
status: to-verify
plugin: centreon_wazuh_restapi.pl
description: Supervision d'un gestionnaire Wazuh via son API REST (agents, processus).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
host_template:
name: App-Wazuh-custom
alias: Applicatif Wazuh
parents: [generic-active-host-custom]
macros:
- {name: APIPORT, value: "443", description: "Port de l'API"}
- {name: APIPROTO, value: "https", description: "Protocole d'acces"}
- {name: APIUSERNAME, value: "centreon", description: "Compte de supervision"}
- {name: APIPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: APIEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Wazuh
alias: Wazuh
notification:
perimetre: Wazuh
calendrier:
name: TP-App-Wazuh-24x7
modele: 24x7
alias: Wazuh, en permanence
groupe: CG-App-Wazuh
criticite: Critique
impact: "Detection d'intrusion et conformite hors service"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Agents
alias: Agents
description: Etat de connexion des agents
line: "$CENTREONPLUGINS$/centreon_wazuh_restapi.pl --plugin=apps::wazuh::restapi::plugin --mode=agents --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-username='$_HOSTAPIUSERNAME$' --api-password='$_HOSTAPIPASSWORD$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Manager
alias: Manager
description: Processus du gestionnaire
line: "$CENTREONPLUGINS$/centreon_wazuh_restapi.pl --plugin=apps::wazuh::restapi::plugin --mode=manager --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-username='$_HOSTAPIUSERNAME$' --api-password='$_HOSTAPIPASSWORD$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -0,0 +1,62 @@
id: app-zookeeper-jmx
name: Apache ZooKeeper (JMX)
category: applications
status: to-verify
plugin: centreon_zookeeper_jmx.pl
description: Supervision d'un noeud ZooKeeper via JMX et l'agent Jolokia.
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
notes: |
Deployer l'agent Jolokia dans la JVM supervisee et exposer son point
d'acces au collecteur : les plugins JMX de Centreon passent par lui.
host_template:
name: App-ZooKeeper-JMX-custom
alias: Applicatif ZooKeeper JMX
parents: [generic-active-host-custom]
macros:
- {name: JMXURL, value: "http://localhost:8080/jolokia", description: "URL de l'agent Jolokia"}
- {name: JMXUSERNAME, value: "", description: "Compte Jolokia"}
- {name: JMXPASSWORD, value: "", description: "Mot de passe Jolokia", is_password: true}
- {name: JMXEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-ZooKeeper-JMX
alias: Apache ZooKeeper (JMX)
notification:
perimetre: Apache ZooKeeper (JMX)
calendrier:
name: TP-App-ZooKeeper-JMX-24x7
modele: 24x7
alias: Apache ZooKeeper (JMX), en permanence
groupe: CG-App-ZooKeeper-JMX
criticite: Majeure
impact: "Coordination du cluster perdue"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Connections
alias: Connections
description: Connexions clientes
line: "$CENTREONPLUGINS$/centreon_zookeeper_jmx.pl --plugin=apps::zookeeper::jmx::plugin --mode=connections --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Latency
alias: Latency
description: Latence des requetes
line: "$CENTREONPLUGINS$/centreon_zookeeper_jmx.pl --plugin=apps::zookeeper::jmx::plugin --mode=latency --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Packets
alias: Packets
description: Paquets emis et recus
line: "$CENTREONPLUGINS$/centreon_zookeeper_jmx.pl --plugin=apps::zookeeper::jmx::plugin --mode=packets --url='$_HOSTJMXURL$' --username='$_HOSTJMXUSERNAME$' --password='$_HOSTJMXPASSWORD$' $_HOSTJMXEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning"}
- {name: CRITICAL, value: "90", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: app-mongodb
name: MongoDB
category: application
category: database
status: to-verify
plugin: centreon_mongodb.pl
description: Supervision d'une instance MongoDB (connexion, operations, taille des bases, replication).
@@ -20,6 +20,21 @@ host_template:
- {name: MONGOUSERNAME, value: "centreon", description: "Compte de supervision"}
- {name: MONGOPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: MONGOEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-MongoDB
alias: MongoDB
notification:
perimetre: MongoDB
calendrier:
name: TP-App-MongoDB-24x7
modele: 24x7
alias: MongoDB, en permanence
groupe: CG-App-MongoDB
criticite: Majeure
impact: "Bases de donnees inaccessibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Connection-Time
alias: Connection-Time
@@ -1,6 +1,6 @@
id: app-mssql
name: Microsoft SQL Server
category: application
category: database
status: verified
plugin: centreon_mssql.pl
description: Supervision d'une instance SQL Server (connexion, taille des bases, sauvegardes, jobs, sessions, verrous).
@@ -22,6 +22,21 @@ prerequis:
droit VIEW SERVER STATE pour le compte de supervision.
verifications:
- "/usr/lib/centreon/plugins/centreon_mssql.pl --plugin=database::mssql::plugin --list-mode"
groupe_hote:
name: HG-App-DB-MSSQL
alias: Microsoft SQL Server
notification:
perimetre: Microsoft SQL Server
calendrier:
name: TP-App-DB-MSSQL-24x7
modele: 24x7
alias: Microsoft SQL Server, en permanence
groupe: CG-App-DB-MSSQL
criticite: Majeure
impact: "Bases de donnees inaccessibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Connection-Time
alias: Connection-Time
@@ -1,6 +1,6 @@
id: app-mysql
name: MySQL / MariaDB
category: application
category: database
status: verified
plugin: centreon_mysql.pl
description: Supervision d'une instance MySQL ou MariaDB (connexion, requetes, threads, replication, taille des bases).
@@ -23,6 +23,21 @@ prerequis:
GRANT REPLICATION CLIENT, PROCESS, SELECT ON *.* TO 'centreon'@'%';
verifications:
- "/usr/lib/centreon/plugins/centreon_mysql.pl --plugin=database::mysql::plugin --list-mode"
groupe_hote:
name: HG-App-DB-MySQL
alias: MySQL / MariaDB
notification:
perimetre: MySQL / MariaDB
calendrier:
name: TP-App-DB-MySQL-24x7
modele: 24x7
alias: MySQL / MariaDB, en permanence
groupe: CG-App-DB-MySQL
criticite: Majeure
impact: "Bases de donnees inaccessibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Connection-Time
alias: Connection-Time
@@ -1,6 +1,6 @@
id: app-oracle
name: Oracle Database
category: application
category: database
status: to-verify
plugin: centreon_oracle.pl
description: Supervision d'une instance Oracle (connexion, tablespaces, sessions, processus, sauvegardes RMAN). Necessite un client Oracle sur le collecteur.
@@ -21,6 +21,21 @@ prerequis:
definir ORACLE_HOME et LD_LIBRARY_PATH pour l'utilisateur centreon-engine.
verifications:
- "/usr/lib/centreon/plugins/centreon_oracle.pl --plugin=database::oracle::plugin --list-mode"
groupe_hote:
name: HG-App-DB-Oracle
alias: Oracle Database
notification:
perimetre: Oracle Database
calendrier:
name: TP-App-DB-Oracle-24x7
modele: 24x7
alias: Oracle Database, en permanence
groupe: CG-App-DB-Oracle
criticite: Majeure
impact: "Bases de donnees inaccessibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Connection-Time
alias: Connection-Time
@@ -1,6 +1,6 @@
id: app-postgresql
name: PostgreSQL
category: application
category: database
status: verified
plugin: centreon_postgres.pl
description: Supervision d'une instance PostgreSQL (connexion, sessions, taille des bases, verrous, temps de requete).
@@ -24,6 +24,21 @@ prerequis:
GRANT pg_monitor TO centreon;
verifications:
- "/usr/lib/centreon/plugins/centreon_postgres.pl --plugin=database::postgres::plugin --list-mode"
groupe_hote:
name: HG-App-DB-PostgreSQL
alias: PostgreSQL
notification:
perimetre: PostgreSQL
calendrier:
name: TP-App-DB-PostgreSQL-24x7
modele: 24x7
alias: PostgreSQL, en permanence
groupe: CG-App-DB-PostgreSQL
criticite: Majeure
impact: "Bases de donnees inaccessibles"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Connection-Time
alias: Connection-Time
@@ -1,6 +1,6 @@
id: app-redis
name: Redis
category: application
category: database
status: to-verify
plugin: centreon_redis_cli.pl
description: Supervision d'une instance Redis (clients, memoire, persistance, replication).
@@ -19,6 +19,21 @@ host_template:
- {name: REDISPORT, value: "6379", description: "Port d'ecoute"}
- {name: REDISPASSWORD, value: "", description: "Mot de passe", is_password: true}
- {name: REDISEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Redis
alias: Redis
notification:
perimetre: Redis
calendrier:
name: TP-App-Redis-24x7
modele: 24x7
alias: Redis, en permanence
groupe: CG-App-Redis
criticite: Majeure
impact: "Cache applicatif indisponible, degradation des temps de reponse"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Clients
alias: Clients
@@ -1,6 +1,6 @@
id: hw-dell-idrac-snmp
name: Serveur Dell (iDRAC SNMP)
category: hardware
category: hardware-server
status: verified
plugin: centreon_dell_idrac_snmp.pl
description: Etat materiel d'un serveur Dell PowerEdge via la carte iDRAC en SNMP (global, alimentations, ventilateurs, temperatures, disques, memoire).
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Dell-iDRAC-SNMP
alias: Serveur Dell (iDRAC SNMP)
notification:
perimetre: Serveur Dell (iDRAC SNMP)
calendrier:
name: TP-HW-Dell-iDRAC-SNMP-24x7
modele: 24x7
alias: Serveur Dell (iDRAC SNMP), en permanence
groupe: CG-HW-Dell-iDRAC-SNMP
criticite: Majeure
impact: "Materiel serveur en defaut"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Hardware
alias: Hardware
@@ -1,6 +1,6 @@
id: hw-hp-proliant-snmp
name: Serveur HP ProLiant (iLO SNMP)
category: hardware
category: hardware-server
status: verified
plugin: centreon_hp_proliant_snmp.pl
description: Etat materiel d'un serveur HP ProLiant via les agents Insight / iLO en SNMP.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-HP-Proliant-SNMP
alias: Serveur HP ProLiant (iLO SNMP)
notification:
perimetre: Serveur HP ProLiant (iLO SNMP)
calendrier:
name: TP-HW-HP-Proliant-SNMP-24x7
modele: 24x7
alias: Serveur HP ProLiant (iLO SNMP), en permanence
groupe: CG-HW-HP-Proliant-SNMP
criticite: Majeure
impact: "Materiel serveur en defaut"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Hardware
alias: Hardware
@@ -0,0 +1,71 @@
id: hw-alcatel-omniswitch-snmp
name: Switch Alcatel OmniSwitch (SNMP)
category: network
status: to-verify
plugin: centreon_alcatel_omniswitch_snmp.pl
description: Supervision d'un commutateur Alcatel-Lucent OmniSwitch en SNMP.
host_template:
name: HW-Alcatel-OmniSwitch-custom
alias: Materiel Alcatel OmniSwitch
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Alcatel-OmniSwitch
alias: Switch Alcatel OmniSwitch (SNMP)
notification:
perimetre: Switch Alcatel OmniSwitch (SNMP)
calendrier:
name: TP-HW-Alcatel-OmniSwitch-24x7
modele: 24x7
alias: Switch Alcatel OmniSwitch (SNMP), en permanence
groupe: CG-HW-Alcatel-OmniSwitch
criticite: Critique
impact: "Coupure reseau sur le perimetre desservi"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
description: Charge CPU de l'equipement
line: "$CENTREONPLUGINS$/centreon_alcatel_omniswitch_snmp.pl --plugin=network::alcatel::omniswitch::snmp::plugin --mode=cpu --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-average='$_SERVICEWARNING$' --critical-average='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Memory
alias: Memory
description: Utilisation de la memoire
line: "$CENTREONPLUGINS$/centreon_alcatel_omniswitch_snmp.pl --plugin=network::alcatel::omniswitch::snmp::plugin --mode=memory --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Hardware
alias: Hardware
description: Alimentations, ventilateurs et sondes de temperature
line: "$CENTREONPLUGINS$/centreon_alcatel_omniswitch_snmp.pl --plugin=network::alcatel::omniswitch::snmp::plugin --mode=hardware --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --component='$_SERVICECOMPONENT$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: COMPONENT, value: ".*", description: "Composants a verifier (regex)"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Interfaces
alias: Interfaces
description: Etat, trafic et erreurs des interfaces
line: "$CENTREONPLUGINS$/centreon_alcatel_omniswitch_snmp.pl --plugin=network::alcatel::omniswitch::snmp::plugin --mode=interfaces --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --interface='$_SERVICEINTERFACE$' --add-status --add-traffic --add-errors --warning-in-traffic='$_SERVICEWARNINGIN$' --critical-in-traffic='$_SERVICECRITICALIN$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: INTERFACE, value: "", description: "Filtre sur le nom de l'interface"}
- {name: WARNINGIN, value: "80", description: "Seuil warning trafic entrant (%)"}
- {name: CRITICALIN, value: "90", description: "Seuil critical trafic entrant (%)"}
- {name: EXTRAOPTIONS, value: "--interface-use-adminstatus --name", description: "Options supplementaires"}
- name: Uptime
alias: Uptime
description: Duree depuis le dernier redemarrage
default: false
line: "$CENTREONPLUGINS$/centreon_alcatel_omniswitch_snmp.pl --plugin=network::alcatel::omniswitch::snmp::plugin --mode=uptime --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-uptime='$_SERVICEWARNING$' --critical-uptime='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning (secondes)"}
- {name: CRITICAL, value: "@0:600", description: "Seuil critical (secondes)"}
- {name: EXTRAOPTIONS, value: "--unit=s", description: "Options supplementaires"}
+52
View File
@@ -0,0 +1,52 @@
id: hw-aruba-instant-snmp
name: Bornes wifi Aruba Instant (SNMP)
category: network
status: to-verify
plugin: centreon_aruba_instant_snmp.pl
description: Supervision d'un cluster de bornes wifi Aruba Instant en SNMP (bornes, clients, radios).
host_template:
name: HW-Aruba-Instant-custom
alias: Materiel Aruba Instant
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Aruba-Instant
alias: Bornes wifi Aruba Instant (SNMP)
notification:
perimetre: Bornes wifi Aruba Instant
calendrier:
name: TP-HW-Aruba-Instant-24x7
modele: 24x7
alias: Bornes wifi Aruba Instant (SNMP), en permanence
groupe: CG-HW-Aruba-Instant
criticite: Majeure
impact: "Couverture wifi degradee ou absente sur le site"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Ap-Status
alias: Ap-Status
description: Etat des bornes du cluster
line: "$CENTREONPLUGINS$/centreon_aruba_instant_snmp.pl --plugin=network::aruba::instant::snmp::plugin --mode=ap-status --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --filter-name='$_SERVICEFILTERNAME$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: FILTERNAME, value: "", description: "Filtre sur le nom de la borne"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Clients
alias: Clients
description: Nombre de clients associes
line: "$CENTREONPLUGINS$/centreon_aruba_instant_snmp.pl --plugin=network::aruba::instant::snmp::plugin --mode=clients --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning='$_SERVICEWARNING$' --critical='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning sur le nombre de clients"}
- {name: CRITICAL, value: "", description: "Seuil critical sur le nombre de clients"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Radios
alias: Radios
description: Etat et charge des radios
default: false
line: "$CENTREONPLUGINS$/centreon_aruba_instant_snmp.pl --plugin=network::aruba::instant::snmp::plugin --mode=radios --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+71
View File
@@ -0,0 +1,71 @@
id: hw-aruba-snmp
name: Switch Aruba (SNMP)
category: network
status: to-verify
plugin: centreon_aruba_snmp.pl
description: Supervision d'un commutateur Aruba en SNMP (CPU, memoire, materiel, interfaces).
host_template:
name: HW-Aruba-SNMP-custom
alias: Materiel Aruba SNMP
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Aruba-SNMP
alias: Switch Aruba (SNMP)
notification:
perimetre: Switch Aruba (SNMP)
calendrier:
name: TP-HW-Aruba-SNMP-24x7
modele: 24x7
alias: Switch Aruba (SNMP), en permanence
groupe: CG-HW-Aruba-SNMP
criticite: Critique
impact: "Coupure reseau sur le perimetre desservi"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
description: Charge CPU de l'equipement
line: "$CENTREONPLUGINS$/centreon_aruba_snmp.pl --plugin=network::aruba::standard::snmp::plugin --mode=cpu --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-average='$_SERVICEWARNING$' --critical-average='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Memory
alias: Memory
description: Utilisation de la memoire
line: "$CENTREONPLUGINS$/centreon_aruba_snmp.pl --plugin=network::aruba::standard::snmp::plugin --mode=memory --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Hardware
alias: Hardware
description: Alimentations, ventilateurs et sondes de temperature
line: "$CENTREONPLUGINS$/centreon_aruba_snmp.pl --plugin=network::aruba::standard::snmp::plugin --mode=hardware --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --component='$_SERVICECOMPONENT$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: COMPONENT, value: ".*", description: "Composants a verifier (regex)"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Interfaces
alias: Interfaces
description: Etat, trafic et erreurs des interfaces
line: "$CENTREONPLUGINS$/centreon_aruba_snmp.pl --plugin=network::aruba::standard::snmp::plugin --mode=interfaces --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --interface='$_SERVICEINTERFACE$' --add-status --add-traffic --add-errors --warning-in-traffic='$_SERVICEWARNINGIN$' --critical-in-traffic='$_SERVICECRITICALIN$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: INTERFACE, value: "", description: "Filtre sur le nom de l'interface"}
- {name: WARNINGIN, value: "80", description: "Seuil warning trafic entrant (%)"}
- {name: CRITICALIN, value: "90", description: "Seuil critical trafic entrant (%)"}
- {name: EXTRAOPTIONS, value: "--interface-use-adminstatus --name", description: "Options supplementaires"}
- name: Uptime
alias: Uptime
description: Duree depuis le dernier redemarrage
default: false
line: "$CENTREONPLUGINS$/centreon_aruba_snmp.pl --plugin=network::aruba::standard::snmp::plugin --mode=uptime --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-uptime='$_SERVICEWARNING$' --critical-uptime='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning (secondes)"}
- {name: CRITICAL, value: "@0:600", description: "Seuil critical (secondes)"}
- {name: EXTRAOPTIONS, value: "--unit=s", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: hw-cisco-snmp
name: Switch / routeur Cisco (SNMP)
category: hardware
category: network
status: verified
plugin: centreon_cisco_standard_snmp.pl
description: Supervision d'un equipement Cisco IOS / IOS-XE en SNMP (CPU, memoire, environnement materiel, interfaces).
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Cisco-SNMP
alias: Switch / routeur Cisco (SNMP)
notification:
perimetre: Switch / routeur Cisco (SNMP)
calendrier:
name: TP-HW-Cisco-SNMP-24x7
modele: 24x7
alias: Switch / routeur Cisco (SNMP), en permanence
groupe: CG-HW-Cisco-SNMP
criticite: Critique
impact: "Coupure reseau sur le perimetre desservi"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
+62
View File
@@ -0,0 +1,62 @@
id: hw-cisco-wlc-snmp
name: Controleur wifi Cisco WLC (SNMP)
category: network
status: to-verify
plugin: centreon_cisco_wlc_snmp.pl
description: Supervision d'un controleur wifi Cisco WLC en SNMP (bornes rattachees, clients, CPU, memoire).
host_template:
name: HW-Cisco-WLC-custom
alias: Materiel Cisco WLC
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Cisco-WLC
alias: Controleur wifi Cisco WLC (SNMP)
notification:
perimetre: Controleur wifi Cisco WLC
calendrier:
name: TP-HW-Cisco-WLC-24x7
modele: 24x7
alias: Controleur wifi Cisco WLC (SNMP), en permanence
groupe: CG-HW-Cisco-WLC
criticite: Majeure
impact: "Couverture wifi degradee ou absente sur le site"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Ap-Status
alias: Ap-Status
description: Etat des bornes rattachees au controleur
line: "$CENTREONPLUGINS$/centreon_cisco_wlc_snmp.pl --plugin=network::cisco::wlc::snmp::plugin --mode=ap-status --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --filter-name='$_SERVICEFILTERNAME$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: FILTERNAME, value: "", description: "Filtre sur le nom de la borne"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Ap-Usage
alias: Ap-Usage
description: Clients connectes et charge des bornes
line: "$CENTREONPLUGINS$/centreon_cisco_wlc_snmp.pl --plugin=network::cisco::wlc::snmp::plugin --mode=ap-usage --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --filter-name='$_SERVICEFILTERNAME$' --warning-clients='$_SERVICEWARNING$' --critical-clients='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: FILTERNAME, value: "", description: "Filtre sur le nom de la borne"}
- {name: WARNING, value: "", description: "Seuil warning sur le nombre de clients"}
- {name: CRITICAL, value: "", description: "Seuil critical sur le nombre de clients"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Cpu
alias: Cpu
description: Charge CPU du controleur
line: "$CENTREONPLUGINS$/centreon_cisco_wlc_snmp.pl --plugin=network::cisco::wlc::snmp::plugin --mode=cpu --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-average='$_SERVICEWARNING$' --critical-average='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Memory
alias: Memory
description: Utilisation memoire du controleur
line: "$CENTREONPLUGINS$/centreon_cisco_wlc_snmp.pl --plugin=network::cisco::wlc::snmp::plugin --mode=memory --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -0,0 +1,71 @@
id: hw-dell-powerconnect-snmp
name: Switch Dell PowerConnect et N-Series (SNMP)
category: network
status: to-verify
plugin: centreon_dell_powerconnect_snmp.pl
description: Supervision d'un commutateur Dell PowerConnect ou N-Series en SNMP.
host_template:
name: HW-Dell-PowerConnect-custom
alias: Materiel Dell PowerConnect
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Dell-PowerConnect
alias: Switch Dell PowerConnect et N-Series (SNMP)
notification:
perimetre: Switch Dell PowerConnect et N-Series (SNMP)
calendrier:
name: TP-HW-Dell-PowerConnect-24x7
modele: 24x7
alias: Switch Dell PowerConnect et N-Series (SNMP), en permanence
groupe: CG-HW-Dell-PowerConnect
criticite: Critique
impact: "Coupure reseau sur le perimetre desservi"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
description: Charge CPU de l'equipement
line: "$CENTREONPLUGINS$/centreon_dell_powerconnect_snmp.pl --plugin=network::dell::powerconnect::snmp::plugin --mode=cpu --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-average='$_SERVICEWARNING$' --critical-average='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Memory
alias: Memory
description: Utilisation de la memoire
line: "$CENTREONPLUGINS$/centreon_dell_powerconnect_snmp.pl --plugin=network::dell::powerconnect::snmp::plugin --mode=memory --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Hardware
alias: Hardware
description: Alimentations, ventilateurs et sondes de temperature
line: "$CENTREONPLUGINS$/centreon_dell_powerconnect_snmp.pl --plugin=network::dell::powerconnect::snmp::plugin --mode=hardware --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --component='$_SERVICECOMPONENT$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: COMPONENT, value: ".*", description: "Composants a verifier (regex)"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Interfaces
alias: Interfaces
description: Etat, trafic et erreurs des interfaces
line: "$CENTREONPLUGINS$/centreon_dell_powerconnect_snmp.pl --plugin=network::dell::powerconnect::snmp::plugin --mode=interfaces --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --interface='$_SERVICEINTERFACE$' --add-status --add-traffic --add-errors --warning-in-traffic='$_SERVICEWARNINGIN$' --critical-in-traffic='$_SERVICECRITICALIN$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: INTERFACE, value: "", description: "Filtre sur le nom de l'interface"}
- {name: WARNINGIN, value: "80", description: "Seuil warning trafic entrant (%)"}
- {name: CRITICALIN, value: "90", description: "Seuil critical trafic entrant (%)"}
- {name: EXTRAOPTIONS, value: "--interface-use-adminstatus --name", description: "Options supplementaires"}
- name: Uptime
alias: Uptime
description: Duree depuis le dernier redemarrage
default: false
line: "$CENTREONPLUGINS$/centreon_dell_powerconnect_snmp.pl --plugin=network::dell::powerconnect::snmp::plugin --mode=uptime --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-uptime='$_SERVICEWARNING$' --critical-uptime='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning (secondes)"}
- {name: CRITICAL, value: "@0:600", description: "Seuil critical (secondes)"}
- {name: EXTRAOPTIONS, value: "--unit=s", description: "Options supplementaires"}
+71
View File
@@ -0,0 +1,71 @@
id: hw-extreme-snmp
name: Switch Extreme Networks (SNMP)
category: network
status: to-verify
plugin: centreon_extreme_snmp.pl
description: Supervision d'un commutateur Extreme Networks en SNMP.
host_template:
name: HW-Extreme-SNMP-custom
alias: Materiel Extreme SNMP
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Extreme-SNMP
alias: Switch Extreme Networks (SNMP)
notification:
perimetre: Switch Extreme Networks (SNMP)
calendrier:
name: TP-HW-Extreme-SNMP-24x7
modele: 24x7
alias: Switch Extreme Networks (SNMP), en permanence
groupe: CG-HW-Extreme-SNMP
criticite: Critique
impact: "Coupure reseau sur le perimetre desservi"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
description: Charge CPU de l'equipement
line: "$CENTREONPLUGINS$/centreon_extreme_snmp.pl --plugin=network::extreme::snmp::plugin --mode=cpu --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-average='$_SERVICEWARNING$' --critical-average='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Memory
alias: Memory
description: Utilisation de la memoire
line: "$CENTREONPLUGINS$/centreon_extreme_snmp.pl --plugin=network::extreme::snmp::plugin --mode=memory --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Hardware
alias: Hardware
description: Alimentations, ventilateurs et sondes de temperature
line: "$CENTREONPLUGINS$/centreon_extreme_snmp.pl --plugin=network::extreme::snmp::plugin --mode=hardware --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --component='$_SERVICECOMPONENT$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: COMPONENT, value: ".*", description: "Composants a verifier (regex)"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Interfaces
alias: Interfaces
description: Etat, trafic et erreurs des interfaces
line: "$CENTREONPLUGINS$/centreon_extreme_snmp.pl --plugin=network::extreme::snmp::plugin --mode=interfaces --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --interface='$_SERVICEINTERFACE$' --add-status --add-traffic --add-errors --warning-in-traffic='$_SERVICEWARNINGIN$' --critical-in-traffic='$_SERVICECRITICALIN$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: INTERFACE, value: "", description: "Filtre sur le nom de l'interface"}
- {name: WARNINGIN, value: "80", description: "Seuil warning trafic entrant (%)"}
- {name: CRITICALIN, value: "90", description: "Seuil critical trafic entrant (%)"}
- {name: EXTRAOPTIONS, value: "--interface-use-adminstatus --name", description: "Options supplementaires"}
- name: Uptime
alias: Uptime
description: Duree depuis le dernier redemarrage
default: false
line: "$CENTREONPLUGINS$/centreon_extreme_snmp.pl --plugin=network::extreme::snmp::plugin --mode=uptime --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-uptime='$_SERVICEWARNING$' --critical-uptime='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning (secondes)"}
- {name: CRITICAL, value: "@0:600", description: "Seuil critical (secondes)"}
- {name: EXTRAOPTIONS, value: "--unit=s", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: hw-fortinet-fortigate-snmp
name: Firewall Fortinet FortiGate (SNMP)
category: hardware
category: network
status: verified
plugin: centreon_fortinet_fortigate.pl
description: Supervision d'un FortiGate en SNMP (CPU, memoire, disque, sessions, tunnels VPN, cluster HA, interfaces).
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Fortinet-FortiGate-SNMP
alias: Firewall Fortinet FortiGate (SNMP)
notification:
perimetre: Firewall Fortinet FortiGate (SNMP)
calendrier:
name: TP-HW-Fortinet-FortiGate-SNMP-24x7
modele: 24x7
alias: Firewall Fortinet FortiGate (SNMP), en permanence
groupe: CG-HW-Fortinet-FortiGate-SNMP
criticite: Critique
impact: "Pare-feu en defaut, acces reseau compromis"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: hw-hp-procurve-snmp
name: Switch HP ProCurve et Aruba (SNMP)
category: hardware
category: network
status: to-verify
plugin: centreon_hp_procurve_snmp.pl
description: Supervision d'un commutateur HP ProCurve ou Aruba en SNMP.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-HP-Procurve-SNMP
alias: Switch HP ProCurve et Aruba (SNMP)
notification:
perimetre: Switch HP ProCurve et Aruba (SNMP)
calendrier:
name: TP-HW-HP-Procurve-SNMP-24x7
modele: 24x7
alias: Switch HP ProCurve et Aruba (SNMP), en permanence
groupe: CG-HW-HP-Procurve-SNMP
criticite: Critique
impact: "Coupure reseau sur le perimetre desservi"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
+71
View File
@@ -0,0 +1,71 @@
id: hw-huawei-snmp
name: Switch et routeur Huawei (SNMP)
category: network
status: to-verify
plugin: centreon_huawei_snmp.pl
description: Supervision d'un equipement reseau Huawei en SNMP.
host_template:
name: HW-Huawei-SNMP-custom
alias: Materiel Huawei SNMP
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Huawei-SNMP
alias: Switch et routeur Huawei (SNMP)
notification:
perimetre: Switch et routeur Huawei (SNMP)
calendrier:
name: TP-HW-Huawei-SNMP-24x7
modele: 24x7
alias: Switch et routeur Huawei (SNMP), en permanence
groupe: CG-HW-Huawei-SNMP
criticite: Critique
impact: "Coupure reseau sur le perimetre desservi"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
description: Charge CPU de l'equipement
line: "$CENTREONPLUGINS$/centreon_huawei_snmp.pl --plugin=network::huawei::standard::snmp::plugin --mode=cpu --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-average='$_SERVICEWARNING$' --critical-average='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Memory
alias: Memory
description: Utilisation de la memoire
line: "$CENTREONPLUGINS$/centreon_huawei_snmp.pl --plugin=network::huawei::standard::snmp::plugin --mode=memory --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Hardware
alias: Hardware
description: Alimentations, ventilateurs et sondes de temperature
line: "$CENTREONPLUGINS$/centreon_huawei_snmp.pl --plugin=network::huawei::standard::snmp::plugin --mode=hardware --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --component='$_SERVICECOMPONENT$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: COMPONENT, value: ".*", description: "Composants a verifier (regex)"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Interfaces
alias: Interfaces
description: Etat, trafic et erreurs des interfaces
line: "$CENTREONPLUGINS$/centreon_huawei_snmp.pl --plugin=network::huawei::standard::snmp::plugin --mode=interfaces --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --interface='$_SERVICEINTERFACE$' --add-status --add-traffic --add-errors --warning-in-traffic='$_SERVICEWARNINGIN$' --critical-in-traffic='$_SERVICECRITICALIN$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: INTERFACE, value: "", description: "Filtre sur le nom de l'interface"}
- {name: WARNINGIN, value: "80", description: "Seuil warning trafic entrant (%)"}
- {name: CRITICALIN, value: "90", description: "Seuil critical trafic entrant (%)"}
- {name: EXTRAOPTIONS, value: "--interface-use-adminstatus --name", description: "Options supplementaires"}
- name: Uptime
alias: Uptime
description: Duree depuis le dernier redemarrage
default: false
line: "$CENTREONPLUGINS$/centreon_huawei_snmp.pl --plugin=network::huawei::standard::snmp::plugin --mode=uptime --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-uptime='$_SERVICEWARNING$' --critical-uptime='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning (secondes)"}
- {name: CRITICAL, value: "@0:600", description: "Seuil critical (secondes)"}
- {name: EXTRAOPTIONS, value: "--unit=s", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: hw-juniper-junos-snmp
name: Juniper JunOS (SNMP)
category: hardware
category: network
status: to-verify
plugin: centreon_juniper_junos_snmp.pl
description: Supervision d'un equipement Juniper sous JunOS en SNMP. Verifier le nom du script (centreon_juniper_junos_snmp.pl) sur l'installation cible.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Juniper-JunOS-SNMP
alias: Juniper JunOS (SNMP)
notification:
perimetre: Juniper JunOS (SNMP)
calendrier:
name: TP-HW-Juniper-JunOS-SNMP-24x7
modele: 24x7
alias: Juniper JunOS (SNMP), en permanence
groupe: CG-HW-Juniper-JunOS-SNMP
criticite: Critique
impact: "Coupure reseau sur le perimetre desservi"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: hw-mikrotik-snmp
name: MikroTik RouterOS (SNMP)
category: hardware
category: network
status: to-verify
plugin: centreon_mikrotik_snmp.pl
description: Supervision d'un equipement MikroTik sous RouterOS en SNMP.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-MikroTik-SNMP
alias: MikroTik RouterOS (SNMP)
notification:
perimetre: MikroTik RouterOS (SNMP)
calendrier:
name: TP-HW-MikroTik-SNMP-24x7
modele: 24x7
alias: MikroTik RouterOS (SNMP), en permanence
groupe: CG-HW-MikroTik-SNMP
criticite: Majeure
impact: "Coupure reseau sur le perimetre desservi"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: hw-paloalto-snmp
name: Pare-feu Palo Alto (SNMP)
category: hardware
category: network
status: to-verify
plugin: centreon_paloalto_snmp.pl
description: Supervision d'un pare-feu Palo Alto en SNMP.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-PaloAlto-SNMP
alias: Pare-feu Palo Alto (SNMP)
notification:
perimetre: Pare-feu Palo Alto (SNMP)
calendrier:
name: TP-HW-PaloAlto-SNMP-24x7
modele: 24x7
alias: Pare-feu Palo Alto (SNMP), en permanence
groupe: CG-HW-PaloAlto-SNMP
criticite: Critique
impact: "Pare-feu en defaut, acces reseau compromis"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: hw-pfsense-snmp
name: Pare-feu pfSense (SNMP)
category: hardware
category: network
status: to-verify
plugin: centreon_pfsense_snmp.pl
description: Supervision d'un pare-feu pfSense en SNMP (CPU, memoire, etat des regles, interfaces).
@@ -16,6 +16,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-pfSense-SNMP
alias: Pare-feu pfSense (SNMP)
notification:
perimetre: Pare-feu pfSense (SNMP)
calendrier:
name: TP-HW-pfSense-SNMP-24x7
modele: 24x7
alias: Pare-feu pfSense (SNMP), en permanence
groupe: CG-HW-pfSense-SNMP
criticite: Critique
impact: "Pare-feu en defaut, acces reseau compromis"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -0,0 +1,44 @@
id: hw-ruckus-zonedirector-snmp
name: Controleur wifi Ruckus ZoneDirector (SNMP)
category: network
status: to-verify
plugin: centreon_ruckus_zonedirector_snmp.pl
description: Supervision d'un controleur wifi Ruckus ZoneDirector en SNMP (bornes, clients, systeme).
host_template:
name: HW-Ruckus-ZoneDirector-custom
alias: Materiel Ruckus ZoneDirector
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Ruckus-ZoneDirector
alias: Controleur wifi Ruckus ZoneDirector (SNMP)
notification:
perimetre: Controleur wifi Ruckus
calendrier:
name: TP-HW-Ruckus-ZoneDirector-24x7
modele: 24x7
alias: Controleur wifi Ruckus ZoneDirector (SNMP), en permanence
groupe: CG-HW-Ruckus-ZoneDirector
criticite: Majeure
impact: "Couverture wifi degradee ou absente sur le site"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Ap-Status
alias: Ap-Status
description: Etat des bornes rattachees
line: "$CENTREONPLUGINS$/centreon_ruckus_zonedirector_snmp.pl --plugin=network::ruckus::zonedirector::snmp::plugin --mode=ap-status --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: System
alias: System
description: CPU, memoire et etat general du controleur
line: "$CENTREONPLUGINS$/centreon_ruckus_zonedirector_snmp.pl --plugin=network::ruckus::zonedirector::snmp::plugin --mode=system --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-cpu='$_SERVICEWARNING$' --critical-cpu='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning CPU en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical CPU en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: hw-stormshield-snmp
name: Pare-feu Stormshield (SNMP)
category: hardware
category: network
status: to-verify
plugin: centreon_stormshield_snmp.pl
description: Supervision d'un pare-feu Stormshield SNS en SNMP.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Stormshield-SNMP
alias: Pare-feu Stormshield (SNMP)
notification:
perimetre: Pare-feu Stormshield (SNMP)
calendrier:
name: TP-HW-Stormshield-SNMP-24x7
modele: 24x7
alias: Pare-feu Stormshield (SNMP), en permanence
groupe: CG-HW-Stormshield-SNMP
criticite: Critique
impact: "Pare-feu en defaut, acces reseau compromis"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: hw-ubiquiti-snmp
name: Ubiquiti UniFi et EdgeMax (SNMP)
category: hardware
category: network
status: to-verify
plugin: centreon_ubnt_snmp.pl
description: Supervision d'un equipement Ubiquiti en SNMP.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Ubiquiti-SNMP
alias: Ubiquiti UniFi et EdgeMax (SNMP)
notification:
perimetre: Ubiquiti UniFi et EdgeMax (SNMP)
calendrier:
name: TP-HW-Ubiquiti-SNMP-24x7
modele: 24x7
alias: Ubiquiti UniFi et EdgeMax (SNMP), en permanence
groupe: CG-HW-Ubiquiti-SNMP
criticite: Majeure
impact: "Coupure reseau ou wifi sur le perimetre desservi"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: os-aix-snmp
name: AIX (SNMP)
category: system
category: operating-system
status: to-verify
plugin: centreon_aix_snmp.pl
description: Supervision d'un serveur AIX via SNMP. Verifier le nom exact du plugin sur la version de centreon-plugins installee.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-OS-AIX-SNMP
alias: AIX (SNMP)
notification:
perimetre: AIX (SNMP)
calendrier:
name: TP-OS-AIX-SNMP-24x7
modele: 24x7
alias: AIX (SNMP), en permanence
groupe: CG-OS-AIX-SNMP
criticite: Majeure
impact: "Serveur indisponible ou degrade"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: os-freebsd-snmp
name: FreeBSD (SNMP)
category: system
category: operating-system
status: to-verify
plugin: centreon_freebsd_snmp.pl
description: Supervision d'un serveur FreeBSD via SNMP. Verifier le nom exact du plugin sur la version de centreon-plugins installee.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-OS-FreeBSD-SNMP
alias: FreeBSD (SNMP)
notification:
perimetre: FreeBSD (SNMP)
calendrier:
name: TP-OS-FreeBSD-SNMP-24x7
modele: 24x7
alias: FreeBSD (SNMP), en permanence
groupe: CG-OS-FreeBSD-SNMP
criticite: Majeure
impact: "Serveur indisponible ou degrade"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: os-linux-nrpe
name: Linux (NRPE)
category: system
category: operating-system
status: verified
plugin: check_centreon_nrpe
description: Supervision Linux par agent NRPE (commandes definies cote client dans nrpe.cfg).
@@ -19,6 +19,21 @@ prerequis:
notes: |
Cote client supervise : installer l'agent NRPE, declarer l'adresse du
collecteur dans allowed_hosts, et definir les commandes appelees.
groupe_hote:
name: HG-OS-Linux-NRPE
alias: Linux (NRPE)
notification:
perimetre: Linux (NRPE)
calendrier:
name: TP-OS-Linux-NRPE-24x7
modele: 24x7
alias: Linux (NRPE), en permanence
groupe: CG-OS-Linux-NRPE
criticite: Majeure
impact: "Serveur indisponible ou degrade"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: os-linux-snmp
name: Linux (SNMP)
category: system
category: operating-system
status: verified
plugin: centreon_linux_snmp.pl
description: Supervision d'un serveur Linux via SNMP avec centreon-plugins (CPU, memoire, swap, systemes de fichiers, charge, interfaces, uptime).
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-OS-Linux-SNMP
alias: Linux (SNMP)
notification:
perimetre: Linux (SNMP)
calendrier:
name: TP-OS-Linux-SNMP-24x7
modele: 24x7
alias: Linux (SNMP), en permanence
groupe: CG-OS-Linux-SNMP
criticite: Majeure
impact: "Serveur indisponible ou degrade"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: os-solaris-snmp
name: Solaris (SNMP)
category: system
category: operating-system
status: to-verify
plugin: centreon_solaris_snmp.pl
description: Supervision d'un serveur Solaris via SNMP. Verifier le nom exact du plugin sur la version de centreon-plugins installee.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-OS-Solaris-SNMP
alias: Solaris (SNMP)
notification:
perimetre: Solaris (SNMP)
calendrier:
name: TP-OS-Solaris-SNMP-24x7
modele: 24x7
alias: Solaris (SNMP), en permanence
groupe: CG-OS-Solaris-SNMP
criticite: Majeure
impact: "Serveur indisponible ou degrade"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: os-windows-nsclient
name: Windows (NSClient++ / check_nt)
category: system
category: operating-system
status: verified
plugin: check_nt
description: Supervision Windows par l'agent NSClient++ en protocole NSC (check_nt), utile quand SNMP n'est pas ouvert.
@@ -13,6 +13,21 @@ host_template:
macros:
- {name: NSCLIENTPORT, value: "12489", description: "Port d'ecoute NSClient++"}
- {name: NSCLIENTPASSWORD, value: "", description: "Mot de passe NSClient++", is_password: true}
groupe_hote:
name: HG-OS-Windows-NSClient
alias: Windows (NSClient++ / check_nt)
notification:
perimetre: Windows (NSClient++ / check_nt)
calendrier:
name: TP-OS-Windows-NSClient-24x7
modele: 24x7
alias: Windows (NSClient++ / check_nt), en permanence
groupe: CG-OS-Windows-NSClient
criticite: Majeure
impact: "Serveur indisponible ou degrade"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: os-windows-snmp
name: Windows (SNMP)
category: system
category: operating-system
status: verified
plugin: centreon_windows_snmp.pl
description: Supervision d'un serveur Windows via SNMP (CPU, memoire, disques, services, interfaces, uptime).
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-OS-Windows-SNMP
alias: Windows (SNMP)
notification:
perimetre: Windows (SNMP)
calendrier:
name: TP-OS-Windows-SNMP-24x7
modele: 24x7
alias: Windows (SNMP), en permanence
groupe: CG-OS-Windows-SNMP
criticite: Majeure
impact: "Serveur indisponible ou degrade"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
@@ -1,6 +1,6 @@
id: hw-printer-rfc3805
name: Imprimante reseau (RFC 3805)
category: hardware
category: printer
status: to-verify
plugin: centreon_printer_standard_rfc3805.pl
description: Supervision d'une imprimante compatible RFC 3805 (niveaux de consommables, bacs papier, etat general). Verifier les modes disponibles.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Printer-RFC3805
alias: Imprimante reseau (RFC 3805)
notification:
perimetre: Imprimante reseau (RFC 3805)
calendrier:
name: TP-HW-Printer-RFC3805-Heures-Ouvrees
modele: Heures-Ouvrees
alias: Imprimante reseau (RFC 3805), heures ouvrees
groupe: CG-HW-Printer-RFC3805
criticite: Mineure
impact: "Impression indisponible ou consommable epuise"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Marker-Supply
alias: Marker-Supply
@@ -1,6 +1,6 @@
id: app-ldap
name: Annuaire LDAP
category: application
category: protocol
status: to-verify
plugin: centreon_ldap.pl
description: Supervision d'un annuaire LDAP ou Active Directory (temps de reponse d'une recherche, disponibilite).
@@ -20,6 +20,21 @@ host_template:
- {name: LDAPBINDDN, value: "", description: "Compte de connexion (DN complet)"}
- {name: LDAPBINDPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: LDAPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-LDAP
alias: Annuaire LDAP
notification:
perimetre: Annuaire LDAP
calendrier:
name: TP-App-LDAP-24x7
modele: 24x7
alias: Annuaire LDAP, en permanence
groupe: CG-App-LDAP
criticite: Critique
impact: "Authentification et annuaire indisponibles, la plupart des applications s'arretent"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Search
alias: Search
@@ -1,6 +1,6 @@
id: app-protocols
name: Services reseau standards (HTTP, TCP, DNS, NTP, SSH)
category: application
category: protocol
status: verified
plugin: check_http
description: Sondes generiques basees sur les plugins Nagios livres avec Centreon. Utile pour tout service expose sans pack dedie.
@@ -9,6 +9,21 @@ host_template:
alias: Applicatif Protocoles reseau
parents: [generic-active-host-custom]
macros: []
groupe_hote:
name: HG-App-Protocols
alias: Services reseau standards (HTTP, TCP, DNS, NTP, SSH)
notification:
perimetre: Services reseau standards (HTTP, TCP, DNS, NTP, SSH)
calendrier:
name: TP-App-Protocols-24x7
modele: 24x7
alias: Services reseau standards (HTTP, TCP, DNS, NTP, SSH), en permanence
groupe: CG-App-Protocols
criticite: Majeure
impact: "Service reseau expose indisponible"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Http
alias: Http
@@ -1,6 +1,6 @@
id: os-generic-snmp
name: Equipement generique (SNMP standard)
category: system
category: protocol
status: verified
plugin: centreon_generic_snmp.pl
description: Supervision de tout equipement repondant aux MIB standard (HOST-RESOURCES, UCD, IF-MIB). Base de repli quand aucun pack constructeur ne correspond.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-OS-Generic-SNMP
alias: Equipement generique (SNMP standard)
notification:
perimetre: Equipement generique (SNMP standard)
calendrier:
name: TP-OS-Generic-SNMP-24x7
modele: 24x7
alias: Equipement generique (SNMP standard), en permanence
groupe: CG-OS-Generic-SNMP
criticite: Majeure
impact: "Serveur indisponible ou degrade"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cpu
alias: Cpu
+57
View File
@@ -0,0 +1,57 @@
id: hw-emc-unity-restapi
name: Baie Dell EMC Unity (API REST)
category: storage
status: to-verify
plugin: centreon_emc_unity_restapi.pl
description: Supervision d'une baie Dell EMC Unity via son API REST (materiel, pools, disques, alertes).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
notes: |
Creer un compte de supervision avec le role Operator sur la baie.
host_template:
name: HW-EMC-Unity-custom
alias: Materiel Dell EMC Unity
parents: [generic-active-host-custom]
macros:
- {name: UNITYPORT, value: "443", description: "Port de l'API"}
- {name: UNITYUSERNAME, value: "centreon", description: "Compte de supervision"}
- {name: UNITYPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: UNITYEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-EMC-Unity
alias: Baie Dell EMC Unity (API REST)
notification:
perimetre: Baie Dell EMC Unity
calendrier:
name: TP-HW-EMC-Unity-24x7
modele: 24x7
alias: Baie Dell EMC Unity (API REST), en permanence
groupe: CG-HW-EMC-Unity
criticite: Critique
impact: "Stockage partage en defaut, machines et applications menacees"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Hardware
alias: Hardware
description: Etat des composants materiels de la baie
line: "$CENTREONPLUGINS$/centreon_emc_unity_restapi.pl --plugin=storage::emc::unity::restapi::plugin --mode=hardware --hostname=$HOSTADDRESS$ --port='$_HOSTUNITYPORT$' --api-username='$_HOSTUNITYUSERNAME$' --api-password='$_HOSTUNITYPASSWORD$' $_HOSTUNITYEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Pool-Usage
alias: Pool-Usage
description: Occupation des pools de stockage
line: "$CENTREONPLUGINS$/centreon_emc_unity_restapi.pl --plugin=storage::emc::unity::restapi::plugin --mode=pool-usage --hostname=$HOSTADDRESS$ --port='$_HOSTUNITYPORT$' --api-username='$_HOSTUNITYUSERNAME$' --api-password='$_HOSTUNITYPASSWORD$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTUNITYEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Alerts
alias: Alerts
description: Alertes remontees par la baie
line: "$CENTREONPLUGINS$/centreon_emc_unity_restapi.pl --plugin=storage::emc::unity::restapi::plugin --mode=alerts --hostname=$HOSTADDRESS$ --port='$_HOSTUNITYPORT$' --api-username='$_HOSTUNITYUSERNAME$' --api-password='$_HOSTUNITYPASSWORD$' $_HOSTUNITYEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+51
View File
@@ -0,0 +1,51 @@
id: hw-hp-msa-xmlapi
name: Baie HPE MSA et P2000 (API XML)
category: storage
status: to-verify
plugin: centreon_hp_p2000_xmlapi.pl
description: Supervision d'une baie HPE MSA ou P2000 via son API XML (materiel, volumes, disques).
prerequis:
paquets:
debian: [libwww-perl, libxml-libxml-perl]
rhel: [perl-libwww-perl, perl-XML-LibXML]
notes: |
Un compte de supervision en lecture seule suffit. Verifier le nom du plugin
selon le modele : les generations MSA recentes exposent une API differente.
host_template:
name: HW-HP-MSA-custom
alias: Materiel HPE MSA
parents: [generic-active-host-custom]
macros:
- {name: MSAUSERNAME, value: "monitor", description: "Compte de supervision"}
- {name: MSAPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: MSAEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-HP-MSA
alias: Baie HPE MSA et P2000 (API XML)
notification:
perimetre: Baie HPE MSA
calendrier:
name: TP-HW-HP-MSA-24x7
modele: 24x7
alias: Baie HPE MSA et P2000 (API XML), en permanence
groupe: CG-HW-HP-MSA
criticite: Critique
impact: "Stockage partage en defaut, machines et applications menacees"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Hardware
alias: Hardware
description: Etat des composants de la baie
line: "$CENTREONPLUGINS$/centreon_hp_p2000_xmlapi.pl --plugin=storage::hp::p2000::xmlapi::plugin --mode=hardware --hostname=$HOSTADDRESS$ --hp-username='$_HOSTMSAUSERNAME$' --hp-password='$_HOSTMSAPASSWORD$' $_HOSTMSAEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Volume-Usage
alias: Volume-Usage
description: Occupation des volumes
line: "$CENTREONPLUGINS$/centreon_hp_p2000_xmlapi.pl --plugin=storage::hp::p2000::xmlapi::plugin --mode=volume-usage --hostname=$HOSTADDRESS$ --hp-username='$_HOSTMSAUSERNAME$' --hp-password='$_HOSTMSAPASSWORD$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTMSAEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+50
View File
@@ -0,0 +1,50 @@
id: hw-ibm-storwize-ssh
name: Baie IBM Storwize et FlashSystem (SSH)
category: storage
status: to-verify
plugin: centreon_ibm_storwize_ssh.pl
description: Supervision d'une baie IBM Storwize ou FlashSystem par SSH (materiel, pools, evenements).
prerequis:
paquets:
debian: [libssh-perl, openssh-client]
rhel: [perl-Net-SSH-Perl, openssh-clients]
notes: |
Deposer la cle publique de l'utilisateur du collecteur sur la baie, pour un
compte en lecture seule. Verifier la connexion SSH avant de deployer.
host_template:
name: HW-IBM-Storwize-custom
alias: Materiel IBM Storwize
parents: [generic-active-host-custom]
macros:
- {name: STORWIZEUSERNAME, value: "centreon", description: "Compte de supervision"}
- {name: STORWIZEEXTRAOPTIONS, value: "", description: "Options supplementaires, dont la cle SSH"}
groupe_hote:
name: HG-HW-IBM-Storwize
alias: Baie IBM Storwize et FlashSystem (SSH)
notification:
perimetre: Baie IBM Storwize
calendrier:
name: TP-HW-IBM-Storwize-24x7
modele: 24x7
alias: Baie IBM Storwize et FlashSystem (SSH), en permanence
groupe: CG-HW-IBM-Storwize
criticite: Critique
impact: "Stockage partage en defaut, machines et applications menacees"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Hardware
alias: Hardware
description: Etat des composants de la baie
line: "$CENTREONPLUGINS$/centreon_ibm_storwize_ssh.pl --plugin=storage::ibm::storwize::ssh::plugin --mode=hardware --hostname=$HOSTADDRESS$ --ssh-username='$_HOSTSTORWIZEUSERNAME$' $_HOSTSTORWIZEEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Pool-Usage
alias: Pool-Usage
description: Occupation des pools de stockage
line: "$CENTREONPLUGINS$/centreon_ibm_storwize_ssh.pl --plugin=storage::ibm::storwize::ssh::plugin --mode=pool-usage --hostname=$HOSTADDRESS$ --ssh-username='$_HOSTSTORWIZEUSERNAME$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTSTORWIZEEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: hw-netapp-ontap-snmp
name: Baie NetApp ONTAP (SNMP)
category: hardware
category: storage
status: to-verify
plugin: centreon_netapp_ontap_snmp.pl
description: Supervision d'une baie NetApp ONTAP en SNMP (etat global, volumes, disques, replication). Verifier les modes selon la version ONTAP.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-NetApp-ONTAP-SNMP
alias: Baie NetApp ONTAP (SNMP)
notification:
perimetre: Baie NetApp ONTAP (SNMP)
calendrier:
name: TP-HW-NetApp-ONTAP-SNMP-24x7
modele: 24x7
alias: Baie NetApp ONTAP (SNMP), en permanence
groupe: CG-HW-NetApp-ONTAP-SNMP
criticite: Critique
impact: "Stockage partage en defaut"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Global-Status
alias: Global-Status
@@ -0,0 +1,55 @@
id: hw-purestorage-restapi
name: Baie Pure Storage (API REST)
category: storage
status: to-verify
plugin: centreon_purestorage_restapi.pl
description: Supervision d'une baie Pure Storage via son API REST (materiel, occupation, alertes).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
notes: |
Generer un jeton d'API pour un compte en lecture seule sur la baie.
host_template:
name: HW-PureStorage-custom
alias: Materiel Pure Storage
parents: [generic-active-host-custom]
macros:
- {name: PURETOKEN, value: "", description: "Jeton d'API", is_password: true}
- {name: PUREEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-PureStorage
alias: Baie Pure Storage (API REST)
notification:
perimetre: Baie Pure Storage
calendrier:
name: TP-HW-PureStorage-24x7
modele: 24x7
alias: Baie Pure Storage (API REST), en permanence
groupe: CG-HW-PureStorage
criticite: Critique
impact: "Stockage partage en defaut, machines et applications menacees"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Hardware
alias: Hardware
description: Etat des composants materiels
line: "$CENTREONPLUGINS$/centreon_purestorage_restapi.pl --plugin=storage::purestorage::restapi::plugin --mode=hardware --hostname=$HOSTADDRESS$ --api-token='$_HOSTPURETOKEN$' $_HOSTPUREEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Volume-Usage
alias: Volume-Usage
description: Occupation des volumes
line: "$CENTREONPLUGINS$/centreon_purestorage_restapi.pl --plugin=storage::purestorage::restapi::plugin --mode=volume-usage --hostname=$HOSTADDRESS$ --api-token='$_HOSTPURETOKEN$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTPUREEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Alarms
alias: Alarms
description: Alarmes actives sur la baie
line: "$CENTREONPLUGINS$/centreon_purestorage_restapi.pl --plugin=storage::purestorage::restapi::plugin --mode=alarms --hostname=$HOSTADDRESS$ --api-token='$_HOSTPURETOKEN$' $_HOSTPUREEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
+54
View File
@@ -0,0 +1,54 @@
id: hw-qnap-snmp
name: NAS QNAP (SNMP)
category: storage
status: to-verify
plugin: centreon_qnap_snmp.pl
description: Supervision d'un NAS QNAP en SNMP (disques, volumes, ventilateurs, temperatures).
host_template:
name: HW-QNAP-SNMP-custom
alias: Materiel QNAP SNMP
parents: [generic-active-host-custom]
check_command: check_centreon_ping
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-QNAP-SNMP
alias: NAS QNAP (SNMP)
notification:
perimetre: NAS QNAP
calendrier:
name: TP-HW-QNAP-SNMP-24x7
modele: 24x7
alias: NAS QNAP (SNMP), en permanence
groupe: CG-HW-QNAP-SNMP
criticite: Majeure
impact: "Stockage et sauvegardes en defaut"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Hardware
alias: Hardware
description: Disques, ventilateurs et sondes de temperature
line: "$CENTREONPLUGINS$/centreon_qnap_snmp.pl --plugin=storage::qnap::snmp::plugin --mode=hardware --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --component='$_SERVICECOMPONENT$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: COMPONENT, value: ".*", description: "Composants a verifier (regex)"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Storage
alias: Storage
description: Occupation des volumes
line: "$CENTREONPLUGINS$/centreon_qnap_snmp.pl --plugin=storage::qnap::snmp::plugin --mode=storage --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-usage-prct='$_SERVICEWARNING$' --critical-usage-prct='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Cpu
alias: Cpu
description: Charge CPU du NAS
default: false
line: "$CENTREONPLUGINS$/centreon_qnap_snmp.pl --plugin=storage::qnap::snmp::plugin --mode=cpu --hostname=$HOSTADDRESS$ --snmp-version='$_HOSTSNMPVERSION$' --snmp-community='$_HOSTSNMPCOMMUNITY$' --warning-average='$_SERVICEWARNING$' --critical-average='$_SERVICECRITICAL$' $_HOSTSNMPEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "80", description: "Seuil warning en %"}
- {name: CRITICAL, value: "90", description: "Seuil critical en %"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: hw-synology-snmp
name: NAS Synology (SNMP)
category: hardware
category: storage
status: to-verify
plugin: centreon_synology_snmp.pl
description: Supervision d'un NAS Synology en SNMP (composants materiels, CPU, memoire, volumes). Verifier les modes selon la version DSM.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-Synology-SNMP
alias: NAS Synology (SNMP)
notification:
perimetre: NAS Synology (SNMP)
calendrier:
name: TP-HW-Synology-SNMP-24x7
modele: 24x7
alias: NAS Synology (SNMP), en permanence
groupe: CG-HW-Synology-SNMP
criticite: Majeure
impact: "Stockage et sauvegardes en defaut"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Hardware
alias: Hardware
@@ -1,6 +1,6 @@
id: hw-apc-ups-snmp
name: Onduleur APC (SNMP)
category: hardware
category: ups-pdu
status: to-verify
plugin: centreon_apc_ups_snmp.pl
description: Supervision d'un onduleur APC en SNMP (batterie, lignes d'entree et de sortie). Verifier les modes disponibles selon le modele.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-APC-UPS-SNMP
alias: Onduleur APC (SNMP)
notification:
perimetre: Onduleur APC (SNMP)
calendrier:
name: TP-HW-APC-UPS-SNMP-24x7
modele: 24x7
alias: Onduleur APC (SNMP), en permanence
groupe: CG-HW-APC-UPS-SNMP
criticite: Critique
impact: "Alimentation electrique menacee"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Battery-Status
alias: Battery-Status
@@ -1,6 +1,6 @@
id: hw-ups-rfc1628
name: Onduleur standard (RFC 1628)
category: hardware
category: ups-pdu
status: to-verify
plugin: centreon_ups_standard_rfc1628_snmp.pl
description: Supervision de tout onduleur respectant la MIB standard UPS-MIB. Repli utile quand aucun pack constructeur ne correspond.
@@ -12,6 +12,21 @@ host_template:
check_command_args: "!3!200,20%!400,50%"
macros:
- {name: SNMPEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-HW-UPS-RFC1628
alias: Onduleur standard (RFC 1628)
notification:
perimetre: Onduleur standard (RFC 1628)
calendrier:
name: TP-HW-UPS-RFC1628-24x7
modele: 24x7
alias: Onduleur standard (RFC 1628), en permanence
groupe: CG-HW-UPS-RFC1628
criticite: Critique
impact: "Alimentation electrique menacee"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Battery-Status
alias: Battery-Status
@@ -1,6 +1,6 @@
id: app-docker
name: Docker (API REST)
category: application
category: virtualization
status: to-verify
plugin: centreon_docker_restapi.pl
description: Supervision d'un hote Docker via son API REST (etat des conteneurs, consommation CPU et memoire). Verifier le nom du plugin selon la version installee.
@@ -12,6 +12,21 @@ host_template:
- {name: DOCKERPORT, value: "2376", description: "Port de l'API Docker"}
- {name: DOCKERPROTO, value: "https", description: "Protocole d'acces a l'API"}
- {name: DOCKEREXTRAOPTIONS, value: "", description: "Options supplementaires (certificats, api-version)"}
groupe_hote:
name: HG-App-Docker
alias: Docker (API REST)
notification:
perimetre: Docker (API REST)
calendrier:
name: TP-App-Docker-24x7
modele: 24x7
alias: Docker (API REST), en permanence
groupe: CG-App-Docker
criticite: Majeure
impact: "Conteneurs applicatifs arretes ou degrades"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Container-Status
alias: Container-Status
+50
View File
@@ -0,0 +1,50 @@
id: app-podman
name: Podman (API REST)
category: virtualization
status: to-verify
plugin: centreon_podman_restapi.pl
description: Supervision d'un hote Podman via son API REST (conteneurs, pods).
prerequis:
paquets:
debian: [libwww-perl, libjson-xs-perl]
rhel: [perl-libwww-perl, perl-JSON-XS]
host_template:
name: App-Podman-custom
alias: Applicatif Podman
parents: [generic-active-host-custom]
macros:
- {name: APIPORT, value: "443", description: "Port de l'API"}
- {name: APIPROTO, value: "https", description: "Protocole d'acces"}
- {name: APIUSERNAME, value: "centreon", description: "Compte de supervision"}
- {name: APIPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: APIEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Podman
alias: Podman (API REST)
notification:
perimetre: Podman (API REST)
calendrier:
name: TP-App-Podman-24x7
modele: 24x7
alias: Podman (API REST), en permanence
groupe: CG-App-Podman
criticite: Majeure
impact: "Conteneurs applicatifs arretes ou degrades"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Container-Usage
alias: Container-Usage
description: Consommation des conteneurs
line: "$CENTREONPLUGINS$/centreon_podman_restapi.pl --plugin=apps::podman::restapi::plugin --mode=container-usage --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-username='$_HOSTAPIUSERNAME$' --api-password='$_HOSTAPIPASSWORD$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: WARNING, value: "", description: "Seuil warning"}
- {name: CRITICAL, value: "", description: "Seuil critical"}
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
- name: Pod-Usage
alias: Pod-Usage
description: Etat des pods
line: "$CENTREONPLUGINS$/centreon_podman_restapi.pl --plugin=apps::podman::restapi::plugin --mode=pod-usage --hostname=$HOSTADDRESS$ --port='$_HOSTAPIPORT$' --proto='$_HOSTAPIPROTO$' --api-username='$_HOSTAPIUSERNAME$' --api-password='$_HOSTAPIPASSWORD$' $_HOSTAPIEXTRAOPTIONS$ $_SERVICEEXTRAOPTIONS$"
macros:
- {name: EXTRAOPTIONS, value: "", description: "Options supplementaires"}
@@ -1,6 +1,6 @@
id: app-proxmox
name: Proxmox VE (API REST)
category: application
category: virtualization
status: to-verify
plugin: centreon_proxmox_ve_api.pl
description: Supervision d'un cluster Proxmox VE via son API REST (noeuds, machines virtuelles, stockage, quorum).
@@ -21,6 +21,21 @@ host_template:
- {name: PVEUSERNAME, value: "centreon@pve", description: "Compte de supervision"}
- {name: PVEPASSWORD, value: "", description: "Mot de passe du compte", is_password: true}
- {name: PVEEXTRAOPTIONS, value: "", description: "Options supplementaires passees au plugin"}
groupe_hote:
name: HG-App-Proxmox
alias: Proxmox VE (API REST)
notification:
perimetre: Proxmox VE (API REST)
calendrier:
name: TP-App-Proxmox-24x7
modele: 24x7
alias: Proxmox VE (API REST), en permanence
groupe: CG-App-Proxmox
criticite: Critique
impact: "Hyperviseur en defaut, machines virtuelles menacees"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Cluster-Status
alias: Cluster-Status
@@ -1,6 +1,6 @@
id: app-vmware-esx
name: VMware ESXi (connecteur Centreon VMware)
category: application
category: virtualization
status: to-verify
plugin: centreon_vmware_connector_client.pl
description: Supervision d'un hote ESXi via le connecteur Centreon VMware. Le connecteur doit etre installe et configure avec l'acces vCenter.
@@ -21,6 +21,21 @@ prerequis:
notes: |
Le connecteur Centreon VMware doit tourner et declarer un container
pointant sur le vCenter, avec un compte en lecture seule.
groupe_hote:
name: HG-App-VMware-ESX
alias: VMware ESXi (connecteur Centreon VMware)
notification:
perimetre: VMware ESXi (connecteur Centreon VMware)
calendrier:
name: TP-App-VMware-ESX-24x7
modele: 24x7
alias: VMware ESXi (connecteur Centreon VMware), en permanence
groupe: CG-App-VMware-ESX
criticite: Critique
impact: "Hyperviseur en defaut, machines virtuelles menacees"
options_hote: d,u,r
options_service: w,c,r
intervalle: 30
services:
- name: Host-Status
alias: Host-Status
+1
View File
@@ -39,6 +39,7 @@ services:
ENCLUME_OIDC_METADATA: ${ENCLUME_OIDC_METADATA:-}
ENCLUME_OIDC_CLIENT_ID: ${ENCLUME_OIDC_CLIENT_ID:-}
ENCLUME_OIDC_CLIENT_SECRET: ${ENCLUME_OIDC_CLIENT_SECRET:-}
ENCLUME_INSCRIPTION_OUVERTE: ${ENCLUME_INSCRIPTION_OUVERTE:-0}
ENCLUME_ADMIN_GROUPE: ${ENCLUME_ADMIN_GROUPE:-enclume-admins}
ENCLUME_ADMIN_COMPTES: ${ENCLUME_ADMIN_COMPTES:-}
# Depot du catalogue : la moderation y ouvre des demandes de fusion.
+19
View File
@@ -75,6 +75,18 @@ Le nom du groupe se règle par `ENCLUME_ADMIN_GROUPE`, il n'a pas à s'appeler
Le temps de mettre ça en place, `[email protected]` donne l'accès
à la modération sur la seule foi de l'adresse. À vider ensuite.
## Qui peut obtenir un compte
Par défaut, `ENCLUME_INSCRIPTION_OUVERTE=0` : le site n'affiche aucun bouton de connexion
public, mais un bouton « Contribuer » qui explique que l'éditeur fonctionne sans compte et
que les packs se proposent par demande de fusion. Un lien discret « Se connecter (équipe) »
reste disponible dans cette fenêtre pour les mainteneurs.
Ce réglage existe parce que promettre une connexion à quelqu'un qui ne peut pas obtenir de
compte — annuaire sans source externe, inscription fermée — est une impasse silencieuse.
Passez-le à `1` une fois les sources et le flux d'enrôlement en place, ci-dessous.
## Ouvrir le site à d'autres que vous
Si Enclume doit accueillir des visiteurs extérieurs, deux points sont à traiter côté
@@ -103,6 +115,13 @@ Un jeton d'accès personnel sur le compte qui ouvrira les demandes de fusion, av
dépose le fichier YAML et ouvre une pull request — **jamais un push sur la branche
principale**. Tu relis dans Gitea avant de fusionner.
### Si la publication est refusée
Le dépôt du catalogue fait foi : publier crée un fichier, et Gitea refuse d'en créer un qui
existe déjà. Un pack proposé sous un identifiant déjà présent doit donc être refusé, avec
pour motif la mise à jour du pack existant — qui passe par une pull request ordinaire, pas
par la modération.
### Si la publication échoue en 403
Une protection placée devant Gitea — Cloudflare et son contrôle d'intégrité du navigateur,
+20
View File
@@ -38,11 +38,31 @@ Et enfin la revue humaine, qui ne s'automatise pas :
on l'insère ? Point-virgule pour le CLAPI, `@` et `:` pour une URL de connexion, guillemet
simple pour le shell, `%` pour un fichier ini lu par configparser. **Quatre** incidents sur
ce seul motif — c'est le premier endroit où regarder.
- une modification a-t-elle **réellement** été appliquée ? Une correction annoncée en 1.11.1
n'avait jamais pris : le texte recherché avait changé entre-temps. Relire le fichier après
l'édition, et faire passer un test par le chemin réel, pas seulement par la couche voisine.
- une valeur déjà encodée traverse-t-elle un second format qui réinterprète son encodage ?
C'est la variante du piège précédent : `%40` est correct dans une URL, et devient une
interpolation dans un ini.
- ce qui est écrit en base a-t-il traversé `strip_secrets` ?
## Un principe : le moins de saisie libre possible
Chaque champ de texte libre est une occasion de faute de frappe qui ne se verra qu'au
déploiement sur le central. Un champ nouveau doit donc, dans l'ordre de préférence :
1. **une liste fermée** quand les valeurs possibles sont connues et finies — un fuseau
horaire, un type de commande, une version SNMP ;
2. **une liste ouverte avec suggestions** quand des valeurs existent déjà sur le central que
nous ne connaissons pas — un modèle parent, un groupe d'hôtes, une commande de
vérification ;
3. **la saisie libre** seulement pour ce qui est propre à l'utilisateur : un nom, une
description, un seuil.
Et quand une valeur juste est majoritairement la même, elle est **préremplie**. Un projet
vide part avec `/usr/lib/centreon/plugins`, `generic-active-host-custom` et `Central` :
l'utilisateur corrige si son installation diffère, il ne devine pas.
## Nommage
| Objet | Règle | Exemple |
+152
View File
@@ -0,0 +1,152 @@
# Notifications par périmètre
Un modèle de service sans notification ne sert à rien en production. Enclume génère donc
aussi la chaîne de notification : le calendrier, la commande, les paramètres des contacts,
et le script PHP qui met en forme le message.
## Les packs livrent leur chaîne
Chaque pack du catalogue déclare son périmètre : le calendrier adapté à sa criticité, un
groupe de contacts nommé `CG-<Famille>-<Techno>`, et l'impact métier d'une panne. Importer le
pack LDAP crée donc le groupe `CG-App-LDAP`, rattache le modèle d'hôte et tous les modèles de
service à un périmètre en 24x7, et remplit le message avec « Authentification et annuaire
indisponibles ».
Il reste une chose à faire de votre côté : **mettre des contacts dans le groupe**. Enclume
crée le groupe vide, faute de connaître vos utilisateurs.
### Chaque pack apporte son calendrier
Un pack ne réutilise pas les calendriers du central : il crée le sien,
`TP-App-Apache-24x7`, `TP-HW-Printer-RFC3805-Heures-Ouvrees`. Ajuster les plages d'une
technologie ne touche alors qu'elle, et non tout ce qui pointait `24x7`.
Le rythme copié à la création est `24x7` pour ce dont la panne réveille quelqu'un,
`Heures-Ouvrees` sinon. Les plages restent modifiables ensuite, comme n'importe quel objet
du projet.
Si vous préférez viser un calendrier existant sur votre central — `24x7`, `workhours` —
saisissez-le dans le périmètre : il apparaîtra dans le projet marqué « Centreon » et ne sera
pas recréé, `TP;ADD` échouant sur un objet existant.
## Le principe
Un **périmètre** regroupe ce qui différencie réellement un domaine d'un autre :
| Élément | Rôle |
|---|---|
| Calendrier | quand la notification a le droit de partir (objet `TP` de Centreon) |
| Destinataires | contacts existants et groupe à créer |
| États déclencheurs | distincts pour l'hôte et le service |
| Contexte métier | application, responsable, criticité, impact, procédure de reprise |
| Sujets | pour l'hôte et pour le service, avec les macros de Centreon |
Un incident sur la chaîne de facturation et un disque plein sur un serveur de rebond
n'appellent ni le même destinataire, ni le même horaire, ni le même message. C'est
exactement ce que le périmètre permet de séparer.
## Ce qui est généré
Pour chaque périmètre :
- deux commandes de type `notif`, `<Périmètre>-Notify-Host` et `-Notify-Service` ;
- un script `notifications/notif-<périmètre>.php`, avec le shebang
`#!/usr/bin/php -c /etc/php.ini` ;
- les paramètres de notification de chaque contact : `hostnotifperiod`, `svcnotifperiod`,
`hostnotifopt`, `svcnotifopt`, `hostnotifcmd`, `svcnotifcmd` ;
- le groupe de contacts, s'il est demandé.
Et pour l'ensemble du projet, `notifications/installer.sh`, qui dépose les scripts sur le
serveur.
## Rattacher un modèle à un périmètre
C'est ce qui referme la boucle. Un modèle d'hôte ou de service porte un champ **périmètre de
notification** ; renseigné, la génération ajoute au modèle :
```
HTPL;setparam;App-Facturation-custom;notifications_enabled;1
HTPL;setparam;App-Facturation-custom;notification_period;Heures-Ouvrees
HTPL;setparam;App-Facturation-custom;notification_options;d,u,r
HTPL;setparam;App-Facturation-custom;notification_interval;15
HTPL;setcontactgroup;App-Facturation-custom;CG-Facturation
```
Le modèle de service reçoit le même traitement, avec ses propres états déclencheurs — un
service en alerte et un hôte indisponible ne se notifient pas selon les mêmes règles.
Conséquence pratique : un hôte qui hérite de `App-Facturation-custom` arrive dans Centreon
avec sa chaîne de notification complète. Rien à reprendre à la main dans l'interface.
## Installation
Les scripts ne s'installent pas tout seuls — comme le CLAPI, Enclume les écrit et vous les
jouez, après relecture :
```bash
cd notifications
./installer.sh # vérifie la syntaxe PHP, puis dépose dans le répertoire cible
```
Le script d'installation contrôle chaque fichier avec `php -l` avant de le copier, et
l'installe en `0750` pour l'utilisateur du moteur de supervision.
Un agent de transport de courrier doit être en place sur la machine : le script utilise la
fonction `mail()` de PHP, qui passe par `sendmail`. L'adresse d'expédition se règle par la
variable d'environnement `ENCLUME_EXPEDITEUR`, à défaut `centreon@<nom de la machine>`.
## Composer le corps du message
Le corps est une liste de **blocs**, dans l'ordre d'affichage. Quatre natures :
| Bloc | Ce qu'il affiche |
|---|---|
| Macro Centreon | la valeur d'une macro, `$NOTIFICATIONAUTHOR$`, `$SERVICEPERFDATA$`, ou une macro personnalisée `$_HOSTAPPLI$` |
| Lien cliquable | une macro contenant une URL, `$SERVICENOTESURL$` par exemple, rendue en lien |
| Texte fixe | une consigne qui ne dépend pas de l'événement, « Appeler le 3000 si non résolu en 30 minutes » |
| Sortie du contrôle | la sortie du plugin, mise en avant en police fixe |
Les blocs se définissent séparément pour l'hôte et pour le service. Tant qu'aucun n'est
défini, les blocs par défaut s'appliquent — et le bouton « Composer à partir des blocs par
défaut » les recopie pour servir de point de départ.
**Une macro vide à l'exécution ne produit aucune ligne.** Un message d'acquittement affichera
donc l'auteur et son commentaire ; une notification de problème, où ces macros sont vides,
n'affichera pas de lignes creuses.
### Les macros personnalisées
C'est le vrai gain par rapport à un message figé. `$_HOSTAPPLI$` ou `$_HOSTRESPONSABLE$`,
définies comme macros sur l'hôte, produisent un message qui nomme *l'application concernée*
et non celle du périmètre entier. L'éditeur propose une quarantaine de macros standard en
suggestion, et accepte toute macro saisie à la main.
## Voir le message avant de le déployer
Dans l'éditeur, un périmètre propose **Aperçu du message, service** et **Aperçu du message,
hôte**. Le message s'affiche tel qu'il partira, avec un incident d'exemple : sujet,
destinataire, mise en forme complète, plus la commande Centreon correspondante.
L'aperçu et le script PHP partagent le même gabarit HTML — celui-ci est écrit une seule fois
et embarqué dans le script généré. Ce qui est montré est donc ce qui sera envoyé, et un test
vérifie que les deux ne peuvent pas diverger.
## Le message produit
Un message HTML avec un bandeau coloré selon l'état — vert rétabli, orange alerte, rouge
critique —, un tableau des informations de l'événement, la sortie du plugin en police fixe,
les champs métier du périmètre, et un lien vers la procédure de reprise quand elle est
renseignée.
Toutes les valeurs passent par `htmlspecialchars` : la sortie d'un plugin peut contenir
n'importe quoi, y compris des caractères qui casseraient la mise en page.
## Ce qu'Enclume ne fait pas
**Créer les contacts.** Ils doivent exister sur le central, avec leur adresse de courriel.
Enclume règle leurs paramètres de notification, il ne les invente pas.
**Envoyer le message.** Le site n'exécute rien, ici comme ailleurs.
**Gérer les escalades.** Elles ne sont pas exposées par CLAPI et restent à définir dans
l'interface de Centreon.
+23 -4
View File
@@ -16,10 +16,25 @@ from typing import Any
import yaml
# Les categories sont celles des connecteurs de supervision Centreon : un pack
# Enclume se range la ou l'utilisateur ira le chercher dans la documentation
# officielle. L'ordre est celui de l'affichage.
CATEGORIES = {
"system": "Systemes d'exploitation",
"hardware": "Materiel",
"application": "Applications",
"operating-system": "Systemes d'exploitation",
"network": "Reseau",
"hardware-server": "Serveurs",
"storage": "Stockage",
"database": "Bases de donnees",
"applications": "Applications",
"virtualization": "Virtualisation",
"protocol": "Protocoles",
"ups-pdu": "Onduleurs et PDU",
"printer": "Imprimantes",
"sensor": "Capteurs",
"cloud": "Cloud",
"toip-voip": "ToIP et VoIP",
"blockchain": "Blockchain",
"centreon": "Centreon",
}
@@ -99,6 +114,8 @@ class Pack:
host_template: HostTemplate
services: list[Service]
prerequis: dict[str, Any] = field(default_factory=dict)
notification: dict[str, Any] = field(default_factory=dict)
groupe_hote: dict[str, Any] = field(default_factory=dict)
source_file: str = ""
@property
@@ -125,13 +142,15 @@ class Pack:
return cls(
id=str(raw["id"]).strip(),
name=str(raw["name"]).strip(),
category=str(raw.get("category", "system")).strip(),
category=str(raw.get("category", "applications")).strip(),
description=str(raw.get("description", "")),
plugin=str(raw.get("plugin", "")),
status=str(raw.get("status", "to-verify")),
host_template=HostTemplate.from_dict(raw["host_template"]),
services=[Service.from_dict(s) for s in raw.get("services") or []],
prerequis=raw.get("prerequis") or {},
notification=raw.get("notification") or {},
groupe_hote=raw.get("groupe_hote") or {},
source_file=source_file,
)
+4
View File
@@ -100,6 +100,10 @@ class Config:
# Le groupe qui donne acces a la moderation. Necessite que le fournisseur
# place la revendication "groups" dans le jeton (mapping de portee dedie
# cote Authentik).
# Les comptes sont-ils ouverts au public, ou reserves a l'equipe ?
# Tant que le fournisseur d'identite n'accepte pas les inscriptions, annoncer
# une connexion ouverte enverrait les visiteurs dans une impasse.
INSCRIPTION_OUVERTE = _bool("ENCLUME_INSCRIPTION_OUVERTE", False)
ADMIN_GROUPE = os.environ.get("ENCLUME_ADMIN_GROUPE", "enclume-admins")
ADMIN_COMPTES = [
c.strip().lower()
+111 -3
View File
@@ -10,7 +10,8 @@ from dataclasses import dataclass, field
from datetime import UTC, datetime
from typing import Any
from .model import Macro, Project, validate
from .model import JOURS, Macro, Project, validate
from .notifications import commande_notification, nom_script, rendre_installation, rendre_script
CLAPI_BIN = "/usr/share/centreon/bin/centreon"
@@ -46,6 +47,9 @@ class Plan:
"modeles de service": len(self.project.service_templates),
"modeles d'hote": len(self.project.host_templates),
"hotes": len(self.project.hosts),
"groupes d'hote": len(self.project.groupes_hotes),
"calendriers": len(self.project.calendriers),
"perimetres de notification": len(self.project.perimetres),
"operations": len([o for o in self.ops if o.obj != "#"]),
}
@@ -70,6 +74,7 @@ def build_plan(project: Project) -> Plan:
own_commands = {c.name for c in project.commands}
own_htpl = {h.name for h in project.host_templates}
own_tp = {c.name for c in project.calendriers if c.creer}
def ref_command(name: str) -> str:
"""Un objet du projet est prefixe ; un objet deja present sur le central ne l'est pas."""
@@ -79,6 +84,9 @@ def build_plan(project: Project) -> Plan:
return full(name) if name in own_htpl else name
del_cmd: list[Op] = []
del_tp: list[Op] = []
del_cg: list[Op] = []
del_hg: list[Op] = []
del_stpl: list[Op] = []
del_htpl: list[Op] = []
del_host: list[Op] = []
@@ -135,12 +143,101 @@ def build_plan(project: Project) -> Plan:
plan.ops.append(Op("HTPL", "setmacro", _macro_values(full(htpl.name), macro, fields)))
del_htpl.append(Op("HTPL", "DEL", [full(htpl.name)]))
# --- Notifications : calendriers, commandes, contacts -------------------
if any(c.creer for c in project.calendriers):
plan.ops.append(Op("#", "#", comment="Calendriers de notification"))
for calendrier in project.calendriers:
if not calendrier.creer:
# Livre par Centreon : on s'y refere, on ne le recree pas.
continue
plan.ops.append(Op("TP", "ADD", [full(calendrier.name), calendrier.alias or calendrier.name]))
for jour in JOURS:
plage = calendrier.jours.get(jour)
if plage:
plan.ops.append(Op("TP", "setparam", [full(calendrier.name), jour, plage]))
del_tp.append(Op("TP", "DEL", [full(calendrier.name)]))
if project.perimetres:
plan.ops.append(Op("#", "#", comment="Perimetres de notification"))
for perimetre in project.perimetres:
for pour, suffixe in (("host", "Host"), ("service", "Service")):
nom = full(f"{perimetre.name}-Notify-{suffixe}")
plan.ops.append(
Op("CMD", "ADD", [nom, "notif", commande_notification(project, perimetre, pour)])
)
del_cmd.append(Op("CMD", "DEL", [nom]))
if perimetre.groupe:
plan.ops.append(Op("CG", "ADD", [full(perimetre.groupe), perimetre.name]))
if perimetre.contacts:
plan.ops.append(
Op("CG", "setcontact", [full(perimetre.groupe), "|".join(perimetre.contacts)])
)
del_cg.append(Op("CG", "DEL", [full(perimetre.groupe)]))
calendrier = full(perimetre.calendrier) if perimetre.calendrier in own_tp else perimetre.calendrier
for contact in perimetre.contacts:
for parametre, valeur in (
("hostnotifperiod", calendrier),
("svcnotifperiod", calendrier),
("hostnotifopt", perimetre.options_hote),
("svcnotifopt", perimetre.options_service),
("hostnotifcmd", full(f"{perimetre.name}-Notify-Host")),
("svcnotifcmd", full(f"{perimetre.name}-Notify-Service")),
):
plan.ops.append(Op("CONTACT", "setparam", [contact, parametre, valeur]))
par_nom = {p.name: p for p in project.perimetres}
def cabler_notification(objet_clapi: str, nom: str, perimetre, pour_hote: bool) -> None:
"""Rattache un modele a son perimetre : calendrier, etats, destinataires.
Sans cela, un modele applicatif serait cree sans savoir qui prevenir ni
quand — et il faudrait le reprendre a la main dans l'interface.
"""
calendrier = (
full(perimetre.calendrier) if perimetre.calendrier in own_tp else perimetre.calendrier
)
options = perimetre.options_hote if pour_hote else perimetre.options_service
plan.ops.append(Op(objet_clapi, "setparam", [nom, "notifications_enabled", "1"]))
if calendrier:
plan.ops.append(Op(objet_clapi, "setparam", [nom, "notification_period", calendrier]))
if options:
plan.ops.append(Op(objet_clapi, "setparam", [nom, "notification_options", options]))
if perimetre.intervalle:
plan.ops.append(
Op(objet_clapi, "setparam", [nom, "notification_interval", str(perimetre.intervalle)])
)
if perimetre.groupe:
plan.ops.append(Op(objet_clapi, "setcontactgroup", [nom, full(perimetre.groupe)]))
rattachements = [
("HTPL", full(h.name), par_nom.get(h.perimetre), True)
for h in project.host_templates
if h.perimetre and h.perimetre in par_nom
] + [
("STPL", full(s.name), par_nom.get(s.perimetre), False)
for s in project.service_templates
if s.perimetre and s.perimetre in par_nom
]
if rattachements:
plan.ops.append(Op("#", "#", comment="Rattachement des modeles a leur perimetre"))
for objet_clapi, nom, perimetre, pour_hote in rattachements:
cabler_notification(objet_clapi, nom, perimetre, pour_hote)
links = [(s, h) for s in project.service_templates for h in s.host_templates]
if links:
plan.ops.append(Op("#", "#", comment="Rattachement des modeles de service aux modeles d'hote"))
for stpl, htpl_name in links:
plan.ops.append(Op("STPL", "addhosttemplate", [full(stpl.name), ref_htpl(htpl_name)]))
if project.groupes_hotes:
plan.ops.append(Op("#", "#", comment="Groupes d'hotes"))
own_hg = {g.name for g in project.groupes_hotes}
for groupe in project.groupes_hotes:
plan.ops.append(Op("HG", "ADD", [full(groupe.name), groupe.alias or groupe.name]))
del_hg.append(Op("HG", "DEL", [full(groupe.name)]))
if project.hosts:
plan.ops.append(Op("#", "#", comment="Hotes"))
for host in project.hosts:
@@ -154,16 +251,23 @@ def build_plan(project: Project) -> Plan:
host.address,
"|".join(ref_htpl(t) for t in host.templates),
host.poller or project.poller,
host.hostgroups,
"|".join(full(h) if h in own_hg else h for h in host.hostgroups),
],
)
)
for param, valeur in (
("check_command", ref_command(host.check_command) if host.check_command else ""),
("check_command_arguments", host.check_command_args),
("timezone", host.timezone),
):
if valeur:
plan.ops.append(Op("HOST", "setparam", [host.name, param, valeur]))
for macro in host.macros:
plan.ops.append(Op("HOST", "setmacro", _macro_values(host.name, macro, fields)))
plan.ops.append(Op("HOST", "applytpl", [host.name]))
del_host.append(Op("HOST", "DEL", [host.name]))
plan.rollback_ops = [*del_host, *del_stpl, *del_htpl, *del_cmd]
plan.rollback_ops = [*del_host, *del_hg, *del_stpl, *del_htpl, *del_cg, *del_cmd, *del_tp]
return plan
@@ -299,6 +403,10 @@ def render_bundle(plan: Plan) -> dict[str, str]:
}
if not plan.project.prerequis.vide:
fichiers["prerequis.sh"] = render_prerequis(plan)
for perimetre in plan.project.perimetres:
fichiers[f"notifications/{nom_script(perimetre)}"] = rendre_script(plan.project, perimetre)
if plan.project.perimetres:
fichiers["notifications/installer.sh"] = rendre_installation(plan.project)
return fichiers
+10
View File
@@ -39,6 +39,16 @@ def _appel(methode: str, chemin: str, corps: dict | None = None) -> dict:
return json.loads(charge) if charge else {}
except urllib.error.HTTPError as erreur:
detail = erreur.read().decode("utf-8", "replace")[:300].strip()
if erreur.code == 422 and "already exists" in detail.lower():
raise ErreurGitea(
"Un fichier portant cet identifiant existe deja dans le depot du catalogue. "
"Refuser la soumission, ou demander a l'auteur un identifiant distinct."
) from erreur
if erreur.code == 409:
raise ErreurGitea(
"Une branche portant ce nom existe deja dans le depot. "
"La supprimer dans Gitea, puis relancer la publication."
) from erreur
if "error code: 1010" in detail or "cloudflare" in detail.lower():
raise ErreurGitea(
f"HTTP {erreur.code} : la requete a ete bloquee avant d'atteindre Gitea, "
+257 -2
View File
@@ -56,6 +56,15 @@ def _clean(value: Any) -> str:
return "" if value is None else str(value).strip()
def _liste(valeur: Any) -> list[str]:
"""Accepte une liste, ou une chaine separee par | ou par virgule."""
if isinstance(valeur, list):
return [_clean(v) for v in valeur if _clean(v)]
if not _clean(valeur):
return []
return [morceau.strip() for morceau in re.split(r"[|,]", str(valeur)) if morceau.strip()]
@dataclass
class Macro:
name: str = ""
@@ -103,6 +112,7 @@ class ServiceTemplate:
active_checks: int = 1
passive_checks: int = 0
host_templates: list[str] = field(default_factory=list)
perimetre: str = ""
macros: list[Macro] = field(default_factory=list)
@classmethod
@@ -125,6 +135,7 @@ class ServiceTemplate:
active_checks=as_int("active_checks", 1),
passive_checks=as_int("passive_checks", 0),
host_templates=[_clean(h) for h in raw.get("host_templates") or [] if _clean(h)],
perimetre=_clean(raw.get("perimetre")),
macros=[Macro.from_dict(m) for m in raw.get("macros") or []],
)
@@ -139,6 +150,7 @@ class HostTemplate:
snmp_version: str = ""
snmp_community: str = ""
timezone: str = ""
perimetre: str = ""
macros: list[Macro] = field(default_factory=list)
@classmethod
@@ -152,10 +164,27 @@ class HostTemplate:
snmp_version=_clean(raw.get("snmp_version")),
snmp_community=_clean(raw.get("snmp_community")),
timezone=_clean(raw.get("timezone")),
perimetre=_clean(raw.get("perimetre")),
macros=[Macro.from_dict(m) for m in raw.get("macros") or []],
)
@dataclass
class GroupeHote:
"""Groupe d'hotes Centreon, objet HG.
Sert au classement dans l'interface, aux filtres et aux droits : un hote
sans groupe est difficile a retrouver des que le parc grandit.
"""
name: str = ""
alias: str = ""
@classmethod
def from_dict(cls, raw: dict[str, Any]) -> GroupeHote:
return cls(name=_clean(raw.get("name")), alias=_clean(raw.get("alias")))
@dataclass
class Host:
name: str = ""
@@ -163,7 +192,10 @@ class Host:
address: str = ""
templates: list[str] = field(default_factory=list)
poller: str = "Central"
hostgroups: str = ""
hostgroups: list[str] = field(default_factory=list)
check_command: str = ""
check_command_args: str = ""
timezone: str = ""
macros: list[Macro] = field(default_factory=list)
@classmethod
@@ -174,11 +206,149 @@ class Host:
address=_clean(raw.get("address")),
templates=[_clean(t) for t in raw.get("templates") or [] if _clean(t)],
poller=_clean(raw.get("poller")) or "Central",
hostgroups=_clean(raw.get("hostgroups")),
# Ancien format : une chaine unique separee par | ou par virgule.
hostgroups=_liste(raw.get("hostgroups")),
check_command=_clean(raw.get("check_command")),
check_command_args=_clean(raw.get("check_command_args")),
timezone=_clean(raw.get("timezone")),
macros=[Macro.from_dict(m) for m in raw.get("macros") or []],
)
JOURS = ("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday")
JOURS_FR = {
"monday": "lundi",
"tuesday": "mardi",
"wednesday": "mercredi",
"thursday": "jeudi",
"friday": "vendredi",
"saturday": "samedi",
"sunday": "dimanche",
}
# Etats qui declenchent une notification, tels que Centreon les nomme.
OPTIONS_HOTE = {"d": "Indisponible", "u": "Inatteignable", "r": "Retabli", "f": "Bascule", "s": "Maintenance"}
OPTIONS_SERVICE = {
"w": "Alerte",
"c": "Critique",
"u": "Inconnu",
"r": "Retabli",
"f": "Bascule",
"s": "Maintenance",
}
@dataclass
class Calendrier:
"""Periode temporelle Centreon : quand une notification a le droit de partir."""
name: str = ""
alias: str = ""
jours: dict[str, str] = field(default_factory=dict)
# Certains calendriers existent des l'installation de Centreon : les
# recreer ferait echouer le deploiement. Ils figurent quand meme dans le
# projet, pour qu'on voie a quoi les perimetres se referent.
creer: bool = True
@classmethod
def from_dict(cls, raw: dict[str, Any]) -> Calendrier:
jours = raw.get("jours") or {}
return cls(
name=_clean(raw.get("name")),
alias=_clean(raw.get("alias")),
jours={j: _clean(jours.get(j)) for j in JOURS if _clean(jours.get(j))},
creer=bool(raw.get("creer", True)),
)
@dataclass
class Bloc:
"""Un element du corps du message.
Quatre natures : une macro Centreon, un lien, un texte fixe, ou la sortie
du plugin mise en avant. L'ordre de la liste est l'ordre d'affichage.
"""
type: str = "macro"
libelle: str = ""
valeur: str = ""
TYPES = ("macro", "lien", "texte", "sortie")
@classmethod
def from_dict(cls, raw: dict[str, Any]) -> Bloc:
nature = _clean(raw.get("type")) or "macro"
return cls(
type=nature if nature in cls.TYPES else "macro",
libelle=_clean(raw.get("libelle")),
valeur=_clean(raw.get("valeur")),
)
@dataclass
class Perimetre:
"""Un perimetre de notification : qui est prevenu, quand, et avec quel message.
L'interet est de separer ce qui differe reellement d'un domaine a l'autre.
Un incident applicatif n'a pas le meme destinataire, le meme calendrier ni
le meme contenu qu'un incident systeme : le message doit porter le nom de
l'application, son responsable et la procedure de reprise.
"""
name: str = ""
description: str = ""
calendrier: str = "24x7"
contacts: list[str] = field(default_factory=list)
groupe: str = ""
options_hote: str = "d,u,r"
options_service: str = "w,c,u,r"
intervalle: int = 30
# Ce qui personnalise le message, au-dela des macros de Centreon.
application: str = ""
responsable: str = ""
procedure: str = ""
criticite: str = ""
impact: str = ""
couleur: str = "#2f6f9f"
sujet_hote: str = "[$NOTIFICATIONTYPE$] $HOSTNAME$ est $HOSTSTATE$"
sujet_service: str = "[$NOTIFICATIONTYPE$] $HOSTNAME$ / $SERVICEDESC$ est $SERVICESTATE$"
# Corps du message. Vides, les blocs par defaut s'appliquent.
blocs_hote: list[Bloc] = field(default_factory=list)
blocs_service: list[Bloc] = field(default_factory=list)
@property
def slug(self) -> str:
return re.sub(r"[^a-z0-9]+", "-", self.name.lower()).strip("-") or "perimetre"
@classmethod
def from_dict(cls, raw: dict[str, Any]) -> Perimetre:
defauts = cls()
try:
intervalle = int(raw.get("intervalle", defauts.intervalle))
except (TypeError, ValueError):
intervalle = defauts.intervalle
return cls(
name=_clean(raw.get("name")),
description=_clean(raw.get("description")),
calendrier=_clean(raw.get("calendrier")) or defauts.calendrier,
contacts=[_clean(c) for c in raw.get("contacts") or [] if _clean(c)],
groupe=_clean(raw.get("groupe")),
options_hote=_clean(raw.get("options_hote")) or defauts.options_hote,
options_service=_clean(raw.get("options_service")) or defauts.options_service,
intervalle=intervalle,
application=_clean(raw.get("application")),
responsable=_clean(raw.get("responsable")),
procedure=_clean(raw.get("procedure")),
criticite=_clean(raw.get("criticite")),
impact=_clean(raw.get("impact")),
couleur=_clean(raw.get("couleur")) or defauts.couleur,
sujet_hote=_clean(raw.get("sujet_hote")) or defauts.sujet_hote,
sujet_service=_clean(raw.get("sujet_service")) or defauts.sujet_service,
blocs_hote=[Bloc.from_dict(b) for b in raw.get("blocs_hote") or []],
blocs_service=[Bloc.from_dict(b) for b in raw.get("blocs_service") or []],
)
@dataclass
class Prerequis:
"""Ce qu'il faut installer sur le collecteur pour que les sondes tournent.
@@ -226,6 +396,9 @@ class Prerequis:
# soumission ne puisse y glisser autre chose.
MOTIF_PAQUET = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._+-]{0,80}$")
# Une macro Centreon : $NOM$, y compris les personnalisees $_HOSTXXX$.
MOTIF_MACRO = re.compile(r"^\$[A-Z_][A-Z0-9_]*\$$")
@dataclass
class Project:
@@ -239,6 +412,10 @@ class Project:
service_templates: list[ServiceTemplate] = field(default_factory=list)
host_templates: list[HostTemplate] = field(default_factory=list)
hosts: list[Host] = field(default_factory=list)
groupes_hotes: list[GroupeHote] = field(default_factory=list)
calendriers: list[Calendrier] = field(default_factory=list)
perimetres: list[Perimetre] = field(default_factory=list)
notif_dir: str = "/usr/share/centreon/notifications"
prerequis: Prerequis = field(default_factory=Prerequis)
schema: int = SCHEMA_VERSION
@@ -264,6 +441,10 @@ class Project:
service_templates=[ServiceTemplate.from_dict(s) for s in raw.get("service_templates") or []],
host_templates=[HostTemplate.from_dict(h) for h in raw.get("host_templates") or []],
hosts=[Host.from_dict(h) for h in raw.get("hosts") or []],
groupes_hotes=[GroupeHote.from_dict(g) for g in raw.get("groupes_hotes") or []],
calendriers=[Calendrier.from_dict(c) for c in raw.get("calendriers") or []],
perimetres=[Perimetre.from_dict(p) for p in raw.get("perimetres") or []],
notif_dir=_clean(raw.get("notif_dir")) or "/usr/share/centreon/notifications",
prerequis=Prerequis.from_dict(raw.get("prerequis")),
)
@@ -287,6 +468,9 @@ class Project:
add(self.service_templates, other.service_templates, "Modele de service")
add(self.host_templates, other.host_templates, "Modele d'hote")
add(self.hosts, other.hosts, "Hote")
add(self.groupes_hotes, other.groupes_hotes, "Groupe d'hotes")
add(self.calendriers, other.calendriers, "Calendrier")
add(self.perimetres, other.perimetres, "Perimetre")
self.prerequis.fusionner(other.prerequis)
return skipped
@@ -295,6 +479,16 @@ class Project:
# Validation
# --------------------------------------------------------------------------- #
def fuseaux_horaires() -> list[str]:
"""Fuseaux connus du systeme, au format attendu par Centreon."""
try:
import zoneinfo
return sorted(zoneinfo.available_timezones())
except Exception:
return []
def validate(project: Project) -> list[dict[str, str]]:
"""Retourne la liste des problemes, du bloquant au simple avertissement."""
@@ -322,6 +516,9 @@ def validate(project: Project) -> list[dict[str, str]]:
check_names(project.service_templates, "Modele de service")
check_names(project.host_templates, "Modele d'hote")
check_names(project.hosts, "Hote")
check_names(project.groupes_hotes, "Groupe d'hotes")
check_names(project.calendriers, "Calendrier")
check_names(project.perimetres, "Perimetre")
command_names = {c.name for c in project.commands}
htpl_names = {h.name for h in project.host_templates}
@@ -356,7 +553,19 @@ def validate(project: Project) -> list[dict[str, str]]:
for htpl in project.host_templates:
_check_macros(htpl.macros, f"Modele d'hote {htpl.name}", issues)
connus = set(fuseaux_horaires())
for objet in (*project.host_templates, *project.hosts):
if objet.timezone and connus and objet.timezone.lstrip(":") not in connus:
error(f"{objet.name} : fuseau horaire inconnu, {objet.timezone}")
groupes = {g.name for g in project.groupes_hotes}
for host in project.hosts:
for groupe in host.hostgroups:
if groupe not in groupes:
warn(
f"Hote {host.name} : le groupe {groupe} n'est pas dans le projet, "
"il devra exister sur le central."
)
if not host.address:
error(f"Hote {host.name} : l'adresse est vide.")
for template in host.templates:
@@ -364,6 +573,52 @@ def validate(project: Project) -> list[dict[str, str]]:
warn(f"Hote {host.name} : modele d'hote inconnu, {template}")
_check_macros(host.macros, f"Hote {host.name}", issues)
perimetres = {p.name for p in project.perimetres}
for modele in (*project.host_templates, *project.service_templates):
if modele.perimetre and modele.perimetre not in perimetres:
warn(
f"{modele.name} : le perimetre de notification {modele.perimetre} n'est pas "
"dans le projet."
)
calendriers = {c.name for c in project.calendriers}
for perimetre in project.perimetres:
# Un calendrier vide devient 24x7 a la lecture : le perimetre pointe
# alors le calendrier du central, ce que l'avertissement ci-dessous
# signale.
if perimetre.calendrier not in calendriers:
warn(
f"Perimetre {perimetre.name} : le calendrier {perimetre.calendrier} n'est pas "
"dans le projet, il devra exister sur le central."
)
if not perimetre.contacts and not perimetre.groupe:
warn(
f"Perimetre {perimetre.name} : ni contact ni groupe, personne ne sera prevenu."
)
for nom, blocs in (("hote", perimetre.blocs_hote), ("service", perimetre.blocs_service)):
for numero, bloc in enumerate(blocs, start=1):
if bloc.type in ("macro", "lien", "sortie") and not bloc.valeur:
error(
f"Perimetre {perimetre.name}, bloc {nom} n{chr(176)}{numero} : "
"aucune valeur, il n'affichera rien."
)
if bloc.type == "macro" and bloc.valeur and not MOTIF_MACRO.match(bloc.valeur):
error(
f"Perimetre {perimetre.name}, bloc {bloc.libelle or numero} : "
f"{bloc.valeur} n'a pas la forme d'une macro Centreon."
)
for lettre in perimetre.options_hote.replace(" ", "").split(","):
if lettre and lettre not in OPTIONS_HOTE:
error(f"Perimetre {perimetre.name} : option d'hote inconnue, {lettre}")
for lettre in perimetre.options_service.replace(" ", "").split(","):
if lettre and lettre not in OPTIONS_SERVICE:
error(f"Perimetre {perimetre.name} : option de service inconnue, {lettre}")
for calendrier in project.calendriers:
if calendrier.creer and not calendrier.jours:
warn(f"Calendrier {calendrier.name} : aucune plage horaire, il ne notifiera jamais.")
for paquet in (*project.prerequis.paquets_debian, *project.prerequis.paquets_rhel):
if not MOTIF_PAQUET.match(paquet):
error(f"Prerequis : nom de paquet invalide, {paquet}")
+546
View File
@@ -0,0 +1,546 @@
"""Scripts de notification PHP, un par perimetre.
Centreon appelle une commande de notification ; cette commande execute le
script genere ici, avec les macros de l'evenement en arguments. Le script met
en forme le message et le remet a sendmail.
Le corps du message est compose de blocs : une macro, un lien, un texte fixe,
ou la sortie du plugin. L'ordre des blocs est l'ordre d'affichage. Un gabarit
HTML unique sert au script comme a l'apercu, pour qu'ils ne divergent jamais.
Comme pour le reste d'Enclume, le site ecrit ces fichiers et ne les execute
jamais : ils sont deposes sur le collecteur par l'administrateur, apres
relecture.
"""
from __future__ import annotations
from html import escape
from .model import Bloc, Perimetre, Project
SHEBANG = "#!/usr/bin/php -c /etc/php.ini"
# Couleurs par etat, reprises du vocabulaire de la supervision.
COULEURS = {
"UP": "#3fb98a",
"OK": "#3fb98a",
"DOWN": "#e0575b",
"CRITICAL": "#e0575b",
"UNREACHABLE": "#b06ab3",
"WARNING": "#e7a93f",
"UNKNOWN": "#8ca0b6",
"PENDING": "#8ca0b6",
}
# --------------------------------------------------------------------------- #
# Macros proposees dans l'editeur
#
# Noms verifies dans la documentation Centreon. La liste ne cherche pas a etre
# exhaustive : l'editeur accepte toute macro saisie a la main, y compris les
# personnalisees $_HOSTXXX$ et $_SERVICEXXX$.
# --------------------------------------------------------------------------- #
MACROS: list[dict[str, str]] = [
# L'evenement
{"macro": "$NOTIFICATIONTYPE$", "libelle": "Type de notification", "portee": "les deux"},
{"macro": "$NOTIFICATIONAUTHOR$", "libelle": "Auteur de l'action", "portee": "les deux"},
{"macro": "$NOTIFICATIONAUTHORALIAS$", "libelle": "Auteur, nom complet", "portee": "les deux"},
{"macro": "$NOTIFICATIONCOMMENT$", "libelle": "Commentaire de l'auteur", "portee": "les deux"},
{"macro": "$LONGDATETIME$", "libelle": "Date et heure", "portee": "les deux"},
{"macro": "$SHORTDATETIME$", "libelle": "Date et heure, format court", "portee": "les deux"},
# L'hote
{"macro": "$HOSTNAME$", "libelle": "Nom de l'hote", "portee": "les deux"},
{"macro": "$HOSTALIAS$", "libelle": "Alias de l'hote", "portee": "les deux"},
{"macro": "$HOSTADDRESS$", "libelle": "Adresse de l'hote", "portee": "les deux"},
{"macro": "$HOSTSTATE$", "libelle": "Etat de l'hote", "portee": "les deux"},
{"macro": "$HOSTSTATETYPE$", "libelle": "Etat confirme ou en cours", "portee": "les deux"},
{"macro": "$HOSTOUTPUT$", "libelle": "Sortie du controle de l'hote", "portee": "hote"},
{"macro": "$LONGHOSTOUTPUT$", "libelle": "Sortie longue de l'hote", "portee": "hote"},
{"macro": "$HOSTDURATION$", "libelle": "Duree dans cet etat", "portee": "les deux"},
{"macro": "$HOSTATTEMPT$", "libelle": "Tentative en cours", "portee": "hote"},
{"macro": "$MAXHOSTATTEMPTS$", "libelle": "Tentatives maximales", "portee": "hote"},
{"macro": "$HOSTNOTES$", "libelle": "Notes de l'hote", "portee": "les deux"},
{"macro": "$HOSTNOTESURL$", "libelle": "URL des notes de l'hote", "portee": "les deux"},
{"macro": "$HOSTACTIONURL$", "libelle": "URL d'action de l'hote", "portee": "les deux"},
{"macro": "$HOSTGROUPNAMES$", "libelle": "Groupes de l'hote", "portee": "les deux"},
{"macro": "$HOSTPERFDATA$", "libelle": "Donnees de performance de l'hote", "portee": "hote"},
{"macro": "$HOSTID$", "libelle": "Identifiant de l'hote", "portee": "les deux"},
{
"macro": "$TOTALHOSTSERVICESCRITICAL$",
"libelle": "Services critiques sur l'hote",
"portee": "les deux",
},
# Le service
{"macro": "$SERVICEDESC$", "libelle": "Nom du service", "portee": "service"},
{"macro": "$SERVICESTATE$", "libelle": "Etat du service", "portee": "service"},
{"macro": "$SERVICESTATETYPE$", "libelle": "Etat confirme ou en cours", "portee": "service"},
{"macro": "$SERVICEOUTPUT$", "libelle": "Sortie du controle", "portee": "service"},
{"macro": "$LONGSERVICEOUTPUT$", "libelle": "Sortie longue du controle", "portee": "service"},
{"macro": "$SERVICEDURATION$", "libelle": "Duree dans cet etat", "portee": "service"},
{"macro": "$SERVICEATTEMPT$", "libelle": "Tentative en cours", "portee": "service"},
{"macro": "$MAXSERVICEATTEMPTS$", "libelle": "Tentatives maximales", "portee": "service"},
{"macro": "$SERVICENOTES$", "libelle": "Notes du service", "portee": "service"},
{"macro": "$SERVICENOTESURL$", "libelle": "URL des notes du service", "portee": "service"},
{"macro": "$SERVICEACTIONURL$", "libelle": "URL d'action du service", "portee": "service"},
{"macro": "$SERVICEGROUPNAMES$", "libelle": "Groupes du service", "portee": "service"},
{"macro": "$SERVICEPERFDATA$", "libelle": "Donnees de performance", "portee": "service"},
{"macro": "$SERVICEID$", "libelle": "Identifiant du service", "portee": "service"},
{
"macro": "$LASTSERVICESTATECHANGE$",
"libelle": "Dernier changement d'etat",
"portee": "service",
},
# Le destinataire
{"macro": "$CONTACTNAME$", "libelle": "Nom du destinataire", "portee": "les deux"},
{"macro": "$CONTACTALIAS$", "libelle": "Alias du destinataire", "portee": "les deux"},
{"macro": "$CONTACTEMAIL$", "libelle": "Courriel du destinataire", "portee": "les deux"},
]
# --------------------------------------------------------------------------- #
# Gabarits, partages par le script PHP et l'apercu
# --------------------------------------------------------------------------- #
GABARIT_HTML = """<html><body style="margin:0;padding:0;background:#f4f6f8;\
font-family:Segoe UI,Helvetica,Arial,sans-serif">\
<div style="max-width:640px;margin:24px auto;background:#fff;\
border:1px solid #dde2e8;border-radius:4px;overflow:hidden">\
<div style="background:__TEINTE__;color:#fff;padding:14px 18px;font-size:16px;\
font-weight:600">__ETAT__ &mdash; __PERIMETRE__</div>\
<div style="padding:18px">\
<table style="border-collapse:collapse;font-size:14px;width:100%">__LIGNES__</table>\
__BLOCS__\
__PROCEDURE__\
</div></div></body></html>"""
GABARIT_LIGNE = """<tr>\
<td style="padding:6px 14px 6px 0;color:#667;white-space:nowrap;vertical-align:top">__LIBELLE__</td>\
<td style="padding:6px 0;color:#111">__VALEUR__</td></tr>"""
GABARIT_SORTIE = """<div style="margin-top:16px;padding:12px;background:#f4f6f8;\
border-radius:3px;font-family:Consolas,monospace;font-size:13px;color:#222">__VALEUR__</div>"""
GABARIT_LIEN = """<tr>\
<td style="padding:6px 14px 6px 0;color:#667;white-space:nowrap;vertical-align:top">__LIBELLE__</td>\
<td style="padding:6px 0"><a href="__URL__" style="color:__TEINTE__">__URL__</a></td></tr>"""
GABARIT_PROCEDURE = """<p style="margin-top:18px;font-size:14px">\
<a href="__URL__" style="color:__TEINTE__;font-weight:600">Procedure de reprise</a></p>"""
def _php(valeur: str) -> str:
"""Litteral PHP entre guillemets simples."""
return "'" + str(valeur).replace("\\", "\\\\").replace("'", "\\'") + "'"
def nom_script(perimetre: Perimetre) -> str:
return f"notif-{perimetre.slug}.php"
# --------------------------------------------------------------------------- #
# Composition du corps
# --------------------------------------------------------------------------- #
def blocs_par_defaut(perimetre: Perimetre, pour: str) -> list[Bloc]:
"""Le message livre sans composition : l'essentiel d'un incident."""
est_service = pour == "service"
blocs = [
Bloc("macro", "Hote", "$HOSTNAME$"),
Bloc("macro", "Adresse", "$HOSTADDRESS$"),
]
if est_service:
blocs += [
Bloc("macro", "Service", "$SERVICEDESC$"),
Bloc("macro", "Etat", "$SERVICESTATE$"),
Bloc("macro", "Depuis", "$SERVICEDURATION$"),
Bloc("macro", "Tentative", "$SERVICEATTEMPT$"),
]
else:
blocs += [
Bloc("macro", "Etat", "$HOSTSTATE$"),
Bloc("macro", "Depuis", "$HOSTDURATION$"),
]
blocs += [
Bloc("macro", "Date", "$LONGDATETIME$"),
Bloc("macro", "Auteur", "$NOTIFICATIONAUTHOR$"),
Bloc("macro", "Commentaire", "$NOTIFICATIONCOMMENT$"),
]
for libelle, valeur in (
("Application", perimetre.application),
("Responsable", perimetre.responsable),
("Criticite", perimetre.criticite),
("Impact", perimetre.impact),
):
if valeur:
blocs.append(Bloc("texte", libelle, valeur))
blocs.append(
Bloc("sortie", "Sortie du controle", "$SERVICEOUTPUT$" if est_service else "$HOSTOUTPUT$")
)
return blocs
def blocs_effectifs(perimetre: Perimetre, pour: str) -> list[Bloc]:
choisis = perimetre.blocs_service if pour == "service" else perimetre.blocs_hote
return list(choisis) if choisis else blocs_par_defaut(perimetre, pour)
def _cle(index: int) -> str:
return f"b{index}"
def commande_notification(projet: Project, perimetre: Perimetre, pour: str) -> str:
"""Ligne de la commande Centreon : elle transporte les macros des blocs."""
chemin = f"{projet.notif_dir}/{nom_script(perimetre)}"
etat = "SERVICESTATE" if pour == "service" else "HOSTSTATE"
morceaux = [
chemin,
f"--type={pour}",
"--notification='$NOTIFICATIONTYPE$'",
"--destinataire='$CONTACTEMAIL$'",
"--hote='$HOSTNAME$'",
f"--etat='${etat}$'",
]
if pour == "service":
morceaux.append("--service='$SERVICEDESC$'")
for index, bloc in enumerate(blocs_effectifs(perimetre, pour), start=1):
if bloc.type in ("macro", "lien", "sortie"):
morceaux.append(f"--{_cle(index)}='{bloc.valeur}'")
return " ".join(morceaux)
def _blocs_php(perimetre: Perimetre, pour: str) -> str:
lignes = []
for index, bloc in enumerate(blocs_effectifs(perimetre, pour), start=1):
champs = [f"'type' => {_php(bloc.type)}", f"'libelle' => {_php(bloc.libelle)}"]
if bloc.type == "texte":
champs.append(f"'valeur' => {_php(bloc.valeur)}")
else:
champs.append(f"'cle' => {_php(_cle(index))}")
lignes.append(" [" + ", ".join(champs) + "],")
return "\n".join(lignes)
def rendre_script(projet: Project, perimetre: Perimetre) -> str:
"""Le script PHP d'un perimetre, hote et service dans le meme fichier."""
couleurs = "\n".join(f" {_php(k)} => {_php(v)}," for k, v in COULEURS.items())
return f"""{SHEBANG}
<?php
/**
* Notification Centreon — perimetre « {perimetre.name} »
* {perimetre.description}
*
* Genere par Enclume. A relire avant installation.
* Depose dans {projet.notif_dir}/ et rendu executable par l'utilisateur du
* moteur de supervision.
*
* Le corps du message est compose de blocs, dans l'ordre defini au moment de
* la generation. Chaque bloc de type macro, lien ou sortie recoit sa valeur
* par un argument de la ligne de commande.
*/
$perimetre = {_php(perimetre.name)};
$couleur = {_php(perimetre.couleur)};
$procedure = {_php(perimetre.procedure)};
$expediteur = getenv('ENCLUME_EXPEDITEUR') ?: 'centreon@' . php_uname('n');
$blocsHote = [
{_blocs_php(perimetre, "host")}
];
$blocsService = [
{_blocs_php(perimetre, "service")}
];
$couleurs = [
{couleurs}
];
$gabaritMessage = <<<'HTML'
{GABARIT_HTML}
HTML;
$gabaritLigne = <<<'HTML'
{GABARIT_LIGNE}
HTML;
$gabaritLien = <<<'HTML'
{GABARIT_LIEN}
HTML;
$gabaritSortie = <<<'HTML'
{GABARIT_SORTIE}
HTML;
$gabaritProcedure = <<<'HTML'
{GABARIT_PROCEDURE}
HTML;
// --- Lecture des arguments ------------------------------------------------
$type = getopt('', ['type:']);
$estService = (($type['type'] ?? '') === 'service');
$blocs = $estService ? $blocsService : $blocsHote;
$attendus = ['type:', 'notification::', 'destinataire:', 'hote:', 'etat:', 'service::'];
foreach ($blocs as $bloc) {{
if (isset($bloc['cle'])) {{
$attendus[] = $bloc['cle'] . '::';
}}
}}
$arguments = getopt('', $attendus);
foreach (['destinataire', 'hote', 'etat'] as $obligatoire) {{
if (empty($arguments[$obligatoire])) {{
fwrite(STDERR, "notification : argument manquant, --$obligatoire\\n");
exit(1);
}}
}}
$etat = strtoupper($arguments['etat']);
$teinte = $couleurs[$etat] ?? $couleur;
// --- Sujet ----------------------------------------------------------------
$sujet = $estService
? {_php(perimetre.sujet_service)}
: {_php(perimetre.sujet_hote)};
$sujet = strtr($sujet, [
'$NOTIFICATIONTYPE$' => $arguments['notification'] ?? '',
'$HOSTNAME$' => $arguments['hote'],
'$HOSTSTATE$' => $etat,
'$SERVICEDESC$' => $arguments['service'] ?? '',
'$SERVICESTATE$' => $etat,
]);
// --- Corps ----------------------------------------------------------------
$lignes = '';
$apres = '';
foreach ($blocs as $bloc) {{
$valeur = ($bloc['type'] === 'texte')
? ($bloc['valeur'] ?? '')
: ($arguments[$bloc['cle']] ?? '');
// Une macro sans valeur a l'execution ne doit pas laisser de ligne vide.
if ($valeur === '' || $valeur === null) {{
continue;
}}
if ($bloc['type'] === 'sortie') {{
$apres .= strtr($gabaritSortie, ['__VALEUR__' => htmlspecialchars($valeur)]);
continue;
}}
if ($bloc['type'] === 'lien') {{
$lignes .= strtr($gabaritLien, [
'__LIBELLE__' => htmlspecialchars($bloc['libelle']),
'__URL__' => htmlspecialchars($valeur),
'__TEINTE__' => $teinte,
]);
continue;
}}
$lignes .= strtr($gabaritLigne, [
'__LIBELLE__' => htmlspecialchars($bloc['libelle']),
'__VALEUR__' => htmlspecialchars($valeur),
]);
}}
$blocProcedure = ($procedure === '') ? '' : strtr($gabaritProcedure, [
'__URL__' => htmlspecialchars($procedure),
'__TEINTE__' => $teinte,
]);
$corps = strtr($gabaritMessage, [
'__TEINTE__' => $teinte,
'__ETAT__' => htmlspecialchars($etat),
'__PERIMETRE__' => htmlspecialchars($perimetre),
'__LIGNES__' => $lignes,
'__BLOCS__' => $apres,
'__PROCEDURE__' => $blocProcedure,
]);
// --- Envoi ----------------------------------------------------------------
$entetes = [
'MIME-Version: 1.0',
'Content-Type: text/html; charset=UTF-8',
'From: ' . $expediteur,
'X-Enclume-Perimetre: ' . $perimetre,
];
$envoye = mail($arguments['destinataire'], $sujet, $corps, implode("\\r\\n", $entetes));
if (!$envoye) {{
fwrite(STDERR, "notification : echec de l'envoi a " . $arguments['destinataire'] . "\\n");
exit(1);
}}
exit(0);
"""
def rendre_installation(projet: Project) -> str:
"""Script de depot des notifications sur le collecteur."""
lignes = [
"#!/usr/bin/env bash",
"#",
f"# Installation des scripts de notification - {projet.name}",
"# Genere par Enclume. A RELIRE AVANT EXECUTION.",
"#",
"# A executer sur le serveur qui porte le moteur de supervision, en root.",
"# Les scripts .php doivent se trouver a cote de ce fichier.",
"",
"set -euo pipefail",
"",
f'DESTINATION="{projet.notif_dir}"',
'UTILISATEUR="${UTILISATEUR:-centreon-engine}"',
"",
"if ! command -v php > /dev/null; then",
' echo "php est absent de cette machine." >&2',
" exit 1",
"fi",
"",
'mkdir -p "$DESTINATION"',
"",
]
for perimetre in projet.perimetres:
fichier = nom_script(perimetre)
lignes += [
f"# Perimetre : {perimetre.name}",
f'php -l "$(dirname "$0")/{fichier}"',
(
'install -m 0750 -o "$UTILISATEUR" -g "$UTILISATEUR" '
f'"$(dirname "$0")/{fichier}" "$DESTINATION/{fichier}"'
),
f'echo "installe : $DESTINATION/{fichier}"',
"",
]
lignes += [
"echo \"Termine. Verifier qu'un agent de transport de courrier est en place.\"",
"",
]
return "\n".join(lignes)
# --------------------------------------------------------------------------- #
# Apercu
# --------------------------------------------------------------------------- #
# Valeurs d'exemple pour les macros courantes. Une macro absente de cette table
# s'affiche sous forme de reperage, pour qu'on voie tout de meme la ligne
# qu'elle produira.
EXEMPLES_MACROS = {
"$NOTIFICATIONTYPE$": "PROBLEM",
"$NOTIFICATIONAUTHOR$": "hcornet",
"$NOTIFICATIONAUTHORALIAS$": "Hubert Cornet",
"$NOTIFICATIONCOMMENT$": "Prise en compte, intervention en cours",
"$LONGDATETIME$": "vendredi 11 septembre 2026 14:30:00",
"$SHORTDATETIME$": "11-09-2026 14:30:00",
"$HOSTNAME$": "srv-facturation-01",
"$HOSTALIAS$": "Serveur de facturation",
"$HOSTADDRESS$": "10.0.4.30",
"$HOSTSTATETYPE$": "HARD",
"$HOSTDURATION$": "0d 0h 4m 12s",
"$HOSTATTEMPT$": "3",
"$MAXHOSTATTEMPTS$": "3",
"$HOSTGROUPNAMES$": "Serveurs-Applicatifs",
"$HOSTNOTES$": "Serveur de la chaine de facturation",
"$HOSTNOTESURL$": "https://wiki.exemple.fr/srv-facturation-01",
"$HOSTACTIONURL$": "https://wiki.exemple.fr/actions/srv-facturation-01",
"$HOSTID$": "42",
"$TOTALHOSTSERVICESCRITICAL$": "2",
"$SERVICEDESC$": "App-DB-MySQL-Connection-Time",
"$SERVICESTATETYPE$": "HARD",
"$SERVICEDURATION$": "0d 0h 3m 45s",
"$SERVICEATTEMPT$": "3",
"$MAXSERVICEATTEMPTS$": "3",
"$SERVICEGROUPNAMES$": "Bases-de-donnees",
"$SERVICENOTES$": "Connexion a l'instance de facturation",
"$SERVICENOTESURL$": "https://wiki.exemple.fr/mysql-facturation",
"$SERVICEACTIONURL$": "https://wiki.exemple.fr/actions/mysql",
"$SERVICEPERFDATA$": "connection_time=0.004s;1;5;0;",
"$SERVICEID$": "317",
"$LASTSERVICESTATECHANGE$": "1789123456",
"$CONTACTNAME$": "hcornet",
"$CONTACTALIAS$": "Hubert Cornet",
"$CONTACTEMAIL$": "[email protected]",
}
ETATS_EXEMPLE = {"service": "CRITICAL", "host": "DOWN"}
SORTIES_EXEMPLE = {
"service": "CRITICAL: Cannot connect to MySQL server on '10.0.4.30' (111 Connection refused)",
"host": "CRITICAL - Host unreachable (rta nan, lost 100%)",
}
def _valeur_exemple(macro: str, pour: str) -> str:
if macro in ("$SERVICEOUTPUT$", "$HOSTOUTPUT$", "$LONGSERVICEOUTPUT$", "$LONGHOSTOUTPUT$"):
return SORTIES_EXEMPLE[pour]
if macro in ("$SERVICESTATE$", "$HOSTSTATE$"):
return ETATS_EXEMPLE[pour]
return EXEMPLES_MACROS.get(macro, f"[{macro}]")
def apercu(projet: Project, perimetre: Perimetre, pour: str = "service") -> dict[str, str]:
"""Le message tel qu'il partira, rempli de valeurs d'exemple.
Utilise exactement les gabarits embarques dans le script PHP : ce qui est
montre ici est ce qui sera envoye.
"""
etat = ETATS_EXEMPLE.get(pour, ETATS_EXEMPLE["service"])
teinte = COULEURS.get(etat, perimetre.couleur)
sujet = perimetre.sujet_service if pour == "service" else perimetre.sujet_hote
sujet = sujet.replace("$NOTIFICATIONTYPE$", "PROBLEM")
sujet = sujet.replace("$HOSTNAME$", EXEMPLES_MACROS["$HOSTNAME$"])
sujet = sujet.replace("$SERVICEDESC$", EXEMPLES_MACROS["$SERVICEDESC$"])
sujet = sujet.replace("$HOSTSTATE$", etat).replace("$SERVICESTATE$", etat)
lignes = ""
apres = ""
for bloc in blocs_effectifs(perimetre, pour):
valeur = bloc.valeur if bloc.type == "texte" else _valeur_exemple(bloc.valeur, pour)
if not valeur:
continue
if bloc.type == "sortie":
apres += GABARIT_SORTIE.replace("__VALEUR__", escape(valeur))
elif bloc.type == "lien":
lignes += (
GABARIT_LIEN.replace("__LIBELLE__", escape(bloc.libelle))
.replace("__URL__", escape(valeur))
.replace("__TEINTE__", teinte)
)
else:
lignes += GABARIT_LIGNE.replace("__LIBELLE__", escape(bloc.libelle)).replace(
"__VALEUR__", escape(valeur)
)
procedure = (
""
if not perimetre.procedure
else GABARIT_PROCEDURE.replace("__URL__", escape(perimetre.procedure)).replace(
"__TEINTE__", teinte
)
)
corps = (
GABARIT_HTML.replace("__TEINTE__", teinte)
.replace("__ETAT__", escape(etat))
.replace("__PERIMETRE__", escape(perimetre.name))
.replace("__LIGNES__", lignes)
.replace("__BLOCS__", apres)
.replace("__PROCEDURE__", procedure)
)
return {
"sujet": sujet,
"corps": corps,
"destinataire": EXEMPLES_MACROS["$CONTACTEMAIL$"],
"commande": commande_notification(projet, perimetre, pour),
"script": f"{projet.notif_dir}/{nom_script(perimetre)}",
}
+96 -1
View File
@@ -7,7 +7,40 @@ le projet de l'utilisateur, qui les modifie ensuite librement.
from __future__ import annotations
from .catalog import Pack
from .model import Command, HostTemplate, Macro, Prerequis, Project, ServiceTemplate
from .model import (
Calendrier,
Command,
GroupeHote,
HostTemplate,
Macro,
Perimetre,
Prerequis,
Project,
ServiceTemplate,
)
# Calendriers standards proposes par les packs. Les noms sont ceux que Centreon
# livre par defaut : un pack qui demande 24x7 tombera sur le calendrier existant
# du central si celui-ci le definit deja.
# Calendriers livres par Centreon a l'installation : un pack qui s'y refere ne
# doit pas tenter de les creer, TP;ADD echouerait sur un objet existant.
CALENDRIERS_CENTREON = {"24x7", "none", "workhours", "nonworkhours"}
CALENDRIERS_STANDARD = {
"24x7": {
"alias": "Tous les jours, toute la journee",
"jours": dict.fromkeys(
("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"),
"00:00-24:00",
),
},
"Heures-Ouvrees": {
"alias": "8h-18h du lundi au vendredi",
"jours": dict.fromkeys(
("monday", "tuesday", "wednesday", "thursday", "friday"), "08:00-18:00"
),
},
}
def _macro(macro) -> Macro:
@@ -44,6 +77,67 @@ def pack_to_project(
htpl.snmp_community = "public"
project.host_templates = [htpl]
# --- Groupe d'hotes livre avec le pack ----------------------------------
# Un hote sans groupe devient introuvable des que le parc grandit, et les
# droits comme les filtres s'appuient dessus. Le pack en propose donc un.
if pack.groupe_hote:
project.groupes_hotes = [
GroupeHote(
name=str(pack.groupe_hote.get("name") or ""),
alias=str(pack.groupe_hote.get("alias") or pack.name),
)
]
# --- Chaine de notification --------------------------------------------
notification = pack.notification or {}
perimetre_nom = ""
if notification:
calendrier = notification.get("calendrier")
if isinstance(calendrier, dict):
# Le pack apporte son propre calendrier : modifier les plages
# d'Apache ne doit pas toucher celles de tout le central.
calendrier_nom = str(calendrier.get("name") or "")
modele = CALENDRIERS_STANDARD.get(str(calendrier.get("modele") or "24x7"))
project.calendriers = [
Calendrier(
name=calendrier_nom,
alias=str(calendrier.get("alias") or modele["alias"]),
jours=dict(modele["jours"]),
creer=True,
)
]
else:
# Ancienne forme : une reference a un calendrier existant.
calendrier_nom = str(calendrier or "24x7")
modele = CALENDRIERS_STANDARD.get(calendrier_nom)
if modele:
project.calendriers = [
Calendrier(
name=calendrier_nom,
alias=str(modele["alias"]),
jours=dict(modele["jours"]),
creer=calendrier_nom not in CALENDRIERS_CENTREON,
)
]
perimetre_nom = str(notification.get("perimetre") or pack.name)
project.perimetres = [
Perimetre(
name=perimetre_nom,
description=str(notification.get("description") or pack.description),
calendrier=calendrier_nom,
groupe=str(notification.get("groupe") or ""),
options_hote=str(notification.get("options_hote") or "d,u,r"),
options_service=str(notification.get("options_service") or "w,c,r"),
intervalle=int(notification.get("intervalle") or 30),
criticite=str(notification.get("criticite") or ""),
impact=str(notification.get("impact") or ""),
responsable=str(notification.get("responsable") or ""),
)
]
htpl.perimetre = perimetre_nom
for svc in pack.services:
if only_defaults and not svc.enabled_by_default:
continue
@@ -59,6 +153,7 @@ def pack_to_project(
retry_interval=svc.retry_interval or 1,
max_attempts=svc.max_attempts or 3,
host_templates=[htpl.name],
perimetre=perimetre_nom,
macros=[_macro(m) for m in svc.macros],
)
)
+823 -44
View File
File diff suppressed because it is too large. Load diff
+51
View File
@@ -553,3 +553,54 @@ pre.code {
@media (max-width: 620px) {
#notifications { left: 16px; right: 16px; bottom: 16px; max-width: none; }
}
/* ----------------------------------------------------------- apercu du mail */
.apercu-entete {
border: 1px solid var(--line);
border-radius: var(--radius);
padding: 10px 12px;
margin-bottom: 14px;
}
.apercu-champ { display: flex; gap: 10px; font-size: 13px; margin-bottom: 4px; }
.apercu-champ span { color: var(--ink-dim); min-width: 96px; }
.apercu-champ b { font-weight: 500; }
/* Le message est en HTML de courriel : on lui rend un fond clair, sinon il
s'affiche sur le fond sombre de l'editeur et ne ressemble a rien. */
.apercu-corps {
background: #f4f6f8;
border: 1px solid var(--line);
border-radius: var(--radius);
max-height: 46vh;
overflow: auto;
}
.apercu-corps table { width: 100%; }
/* ------------------------------------------------------- blocs du message */
.blocs { margin-bottom: 18px; }
.bloc-ligne {
display: grid;
grid-template-columns: 150px 170px minmax(0, 1fr) 96px;
gap: 8px;
align-items: center;
margin-bottom: 6px;
}
.bloc-actions { display: flex; gap: 4px; }
.bloc-actions button { padding: 3px 7px; }
@media (max-width: 900px) {
.bloc-ligne { grid-template-columns: 1fr 1fr; }
}
/* Packs deja dans le projet : visibles a la demande, sans action possible. */
.note-masques {
display: flex;
align-items: center;
gap: 8px;
color: var(--ink-dim);
font-size: 12.5px;
margin-bottom: 10px;
}
.pack-ligne.importe { opacity: 0.55; }
+8 -2
View File
@@ -1,15 +1,16 @@
{% extends "base.html" %}
{% block title %}Enclume — Générateur de configuration CLAPI pour Centreon{% endblock %}
{% block title %}Forge Centreon — Générateur de configuration pour Centreon avec CLAPI{% endblock %}
{% block body %}
<div class="accueil">
<section class="manchette">
<h2>Créez votre configuration Centreon, repartez avec le CLAPI</h2>
<p>Commandes de contrôle, modèles de service, modèles d'hôte : construisez-les dans votre
navigateur, à partir de zéro ou d'un des {{ pack_count }} packs du catalogue. Enclume produit
navigateur, à partir de zéro ou d'un des {{ pack_count }} packs du catalogue. Forge Centreon produit
les fichiers à jouer sur votre central — que vous relisez avant de les exécuter.</p>
<div class="barre">
<a class="btn primaire" href="/editeur">Ouvrir l'éditeur</a>
<a class="btn" href="/aide/snmp">Installer SNMP</a>
<a class="btn" href="#fonctionnement">Comment ça marche</a>
</div>
<p class="petit">Sans inscription. Rien n'est installé. Projet indépendant de Centreon SAS.</p>
@@ -80,6 +81,11 @@
absente du catalogue, la proposer prend quelques minutes — et vérifier un pack existant
marqué « à valider » vaut tout autant. Le format et les règles sont dans le
<a href="{{ depot }}/src/branch/main/CONTRIBUTING.md">guide de contribution</a>.</p>
{% if not inscription_ouverte %}
<p class="petit">Les comptes du site sont pour l'instant réservés à l'équipe qui maintient
le catalogue : les contributions passent par une demande de fusion sur le dépôt. L'éditeur,
la génération et le partage, eux, ne demandent aucun compte.</p>
{% endif %}
<div class="barre">
<a class="btn" href="{{ depot }}">Code source</a>
<a class="btn" href="/editeur">Ouvrir l'éditeur</a>
+5 -4
View File
@@ -3,10 +3,10 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}Enclume — Générateur de configuration CLAPI pour Centreon{% endblock %}</title>
<title>{% block title %}Forge Centreon — Générateur de configuration pour Centreon avec CLAPI{% endblock %}</title>
<meta name="description" content="Créez vos commandes de contrôle, modèles de service et modèles d'hôte Centreon, et repartez avec le code CLAPI prêt à jouer sur votre central. Gratuit, sans inscription.">
<link rel="canonical" href="{{ request.url_root }}">
<meta property="og:title" content="Enclume — Générateur de configuration CLAPI pour Centreon">
<meta property="og:title" content="Forge Centreon — Générateur de configuration pour Centreon avec CLAPI">
<meta property="og:description" content="Créez vos commandes, modèles de service et modèles d'hôte, repartez avec le code CLAPI.">
<meta property="og:type" content="website">
<link rel="icon" href="{{ url_for('static', filename='enclume.svg') }}" type="image/svg+xml">
@@ -14,14 +14,15 @@
</head>
<body>
<header class="topbar">
<h1><a href="/">Enclume</a></h1>
<span class="meta">Générateur de configuration CLAPI pour Centreon</span>
<h1><a href="/">Forge Centreon</a></h1>
<span class="meta">Générateur de configuration pour Centreon avec CLAPI</span>
<span class="version">{{ version }}</span>
</header>
{% block body %}{% endblock %}
<footer class="pied">
<span>Projet indépendant, sans lien avec Centreon SAS. Centreon est une marque déposée de son propriétaire.</span>
<span class="grow"></span>
<a href="/aide/snmp">Installer SNMP</a>
<a href="/mentions">Mentions légales</a>
<a href="{{ depot }}">Code source</a>
<a href="{{ depot }}/src/branch/main/CONTRIBUTING.md">Contribuer</a>
+5 -1
View File
@@ -23,8 +23,10 @@
{% if utilisateur %}
<span class="compte">{{ utilisateur.affichage }}{% if utilisateur.administrateur %} <a href="/moderation">moderation</a>{% endif %}</span>
<button type="button" id="btn-deconnexion" class="small">Se deconnecter</button>
{% else %}
{% elif fonctions.comptes and inscription_ouverte %}
<a class="btn" href="/connexion">Se connecter</a>
{% elif fonctions.comptes %}
<button type="button" id="btn-contribuer">Contribuer</button>
{% endif %}
{% endif %}
<button type="button" id="btn-generer" class="primary">Generer le CLAPI</button>
@@ -62,6 +64,8 @@
"fonctions": fonctions,
"connecte": utilisateur is not none,
"partage": partage|default(none),
"inscription_ouverte": inscription_ouverte,
"depot": depot,
}|tojson }}</script>
<script src="{{ url_for('static', filename='editeur.js') }}"></script>
{% endblock %}
+143
View File
@@ -0,0 +1,143 @@
{% extends "base.html" %}
{% block title %}Installer et sécuriser SNMP — Forge Centreon{% endblock %}
{% block body %}
<div class="accueil texte">
<h2>Installer et sécuriser SNMP</h2>
<p>La plupart des packs du catalogue interrogent leurs équipements en SNMP. Cette page
donne, par système, une configuration de départ qui fonctionne et qui ne laisse pas votre
parc ouvert au premier venu.</p>
<div class="notice">
<b>Deux règles avant de commencer</b>
<p>SNMP v1 et v2c transportent la communauté <b>en clair</b> sur le réseau : quiconque
écoute peut la lire et interroger l'équipement. Préférez la <b>version 3</b> partout où
elle est disponible.</p>
<p style="margin-top:8px">Si vous restez en v2c — souvent le cas sur du matériel ancien —
restreignez au moins l'accès à l'adresse du collecteur et n'autorisez que la lecture.</p>
</div>
<h3>Debian et Ubuntu</h3>
<pre class="code">apt install snmpd</pre>
<p>Remplacez le contenu de <code>/etc/snmp/snmpd.conf</code> par ceci, en v3 :</p>
<pre class="code"># N'ecoute que sur l'interface d'administration, jamais sur toutes
agentaddress udp:10.0.4.20:161
# Ce que le compte a le droit de lire : tout l'arbre standard, rien d'autre
view lecture included .1.3.6.1.2.1
view lecture included .1.3.6.1.4.1
# Compte de supervision, lecture seule, sur la vue ci-dessus
rouser centreon authPriv -V lecture
# Informations d'inventaire, facultatives mais utiles
sysLocation Salle serveur, baie A3
sysContact [email protected]</pre>
<p>Le compte lui-même se crée service arrêté, la directive étant déplacée au démarrage
vers un fichier de persistance :</p>
<pre class="code">systemctl stop snmpd
echo 'createUser centreon SHA-256 "MotDePasseAuth" AES "MotDePasseChiffrement"' >> /etc/snmp/snmpd.conf
systemctl start snmpd</pre>
<div class="notice">
<b>Le piège classique</b>
<p>Après démarrage, la ligne <code>createUser</code> disparaît de
<code>/etc/snmp/snmpd.conf</code> : net-snmp la déplace dans
<code>/var/lib/snmp/snmpd.conf</code> sous forme chiffrée. C'est normal. Ne la remettez
pas, vous créeriez un doublon.</p>
</div>
<p>En v2c, si la version 3 n'est pas envisageable :</p>
<pre class="code">agentaddress udp:10.0.4.20:161
# Lecture seule, et uniquement depuis le collecteur
rocommunity UneChaineLongueEtAleatoire 10.0.4.10 -V lecture</pre>
<h3>RHEL, Alma et Rocky</h3>
<pre class="code">dnf install net-snmp net-snmp-utils</pre>
<p>Le fichier de configuration est au même endroit et la syntaxe identique. La différence
est le pare-feu :</p>
<pre class="code">firewall-cmd --permanent --add-rich-rule='rule family="ipv4" \
source address="10.0.4.10/32" port port="161" protocol="udp" accept'
firewall-cmd --reload
systemctl enable --now snmpd</pre>
<p>Sur Debian et Ubuntu, l'équivalent avec ufw :</p>
<pre class="code">ufw allow from 10.0.4.10 to any port 161 proto udp</pre>
<h3>Windows</h3>
<p>Le service SNMP de Windows ne connaît que la v2c, et Microsoft le considère comme
obsolète. Il reste utilisable, mais pour un parc Windows important, les packs
<b>NSClient++</b> du catalogue sont un meilleur choix.</p>
<pre class="code"># Windows 10, 11, Server 2019 et suivants
Add-WindowsCapability -Online -Name "SNMP.Client~~~~0.0.1.0"
# Serveurs plus anciens
Install-WindowsFeature SNMP-Service -IncludeManagementTools</pre>
<p>La configuration se fait dans la base de registre. Communauté en lecture seule, et
restriction au seul collecteur :</p>
<pre class="code">$base = "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters"
# 4 = lecture seule. Ne jamais utiliser 8, qui autorise l'ecriture.
New-ItemProperty -Path "$base\ValidCommunities" -Name "UneChaineLongueEtAleatoire" `
-Value 4 -PropertyType DWord -Force
# Seul le collecteur a le droit d'interroger
New-ItemProperty -Path "$base\PermittedManagers" -Name "1" `
-Value "10.0.4.10" -PropertyType String -Force
Restart-Service SNMP</pre>
<p>Puis le pare-feu :</p>
<pre class="code">New-NetFirewallRule -DisplayName "SNMP depuis le collecteur" -Direction Inbound `
-Protocol UDP -LocalPort 161 -RemoteAddress 10.0.4.10 -Action Allow</pre>
<h3>Équipements réseau</h3>
<p>La logique est la même partout : un compte ou une communauté en lecture seule, une
liste d'accès limitée au collecteur, et la version 3 quand le matériel la gère.</p>
<pre class="code"># Cisco IOS, en v3
snmp-server view lecture iso included
snmp-server group SUPERVISION v3 priv read lecture access 20
snmp-server user centreon SUPERVISION v3 auth sha MotDePasseAuth priv aes 128 MotDePasseChiffrement
access-list 20 permit 10.0.4.10</pre>
<pre class="code"># Cisco IOS, en v2c
access-list 20 permit 10.0.4.10
snmp-server community UneChaineLongueEtAleatoire RO 20</pre>
<p>Sur pfSense, OPNsense, FortiGate, Stormshield et la plupart des interfaces web,
l'écran SNMP propose les mêmes notions : communauté ou utilisateur v3, interface
d'écoute, et adresses autorisées. Renseignez toujours la dernière.</p>
<h3>Vérifier depuis le collecteur</h3>
<p>Avant de déployer quoi que ce soit, assurez-vous que le collecteur obtient une réponse.
Une configuration Centreon parfaite ne sert à rien si le port est fermé.</p>
<pre class="code"># v3
snmpwalk -v3 -l authPriv -u centreon -a SHA-256 -A "MotDePasseAuth" \
-x AES -X "MotDePasseChiffrement" 10.0.4.20 sysDescr
# v2c
snmpwalk -v2c -c UneChaineLongueEtAleatoire 10.0.4.20 sysDescr</pre>
<p>Une réponse contenant la description du système signifie que tout est en place. Un
silence vient du pare-feu ou de l'adresse d'écoute ; un refus d'authentification, du
compte ou de la communauté.</p>
<div class="notice">
<b>Ce que Forge Centreon attend de vous ensuite</b>
<p>Les packs SNMP posent la version et la communauté sur le modèle d'hôte, dans les
réglages du projet. En version 3, laissez la communauté vide et passez les options
d'authentification par la macro <code>SNMPEXTRAOPTIONS</code> du modèle d'hôte.</p>
</div>
<p style="margin-top:24px"><a class="btn" href="/editeur">Retour à l'éditeur</a></p>
</div>
{% endblock %}
+2 -2
View File
@@ -1,5 +1,5 @@
{% extends "base.html" %}
{% block title %}Mentions légales — Enclume{% endblock %}
{% block title %}Mentions légales — Forge Centreon{% endblock %}
{% block body %}
<div class="accueil texte">
@@ -13,7 +13,7 @@
<p>{{ hebergeur or "Non renseigné — définir ENCLUME_HEBERGEUR." }}</p>
<h3>Marques</h3>
<p>Centreon est une marque déposée de Centreon SAS. Enclume est un projet indépendant, sans
<p>Centreon est une marque déposée de Centreon SAS. Forge Centreon est un projet indépendant, sans
lien ni affiliation avec cette société. Les noms de constructeurs et d'éditeurs cités dans le
catalogue appartiennent à leurs propriétaires respectifs.</p>
+1 -1
View File
@@ -1,5 +1,5 @@
{% extends "base.html" %}
{% block title %}Moderation — Enclume{% endblock %}
{% block title %}Moderation — Forge Centreon{% endblock %}
{% block body %}
<div class="wrap-moderation">
{% if not connecte %}
+116
View File
@@ -108,6 +108,7 @@ def create_app() -> Flask:
"utilisateur": utilisateur,
"oidc_nom": Config.OIDC_NOM,
"depot": Config.DEPOT,
"inscription_ouverte": Config.INSCRIPTION_OUVERTE,
}
@app.get("/")
@@ -120,6 +121,11 @@ def create_app() -> Flask:
verifies=sum(1 for p in cat.packs.values() if p.status == "verified"),
)
@app.get("/aide/snmp")
def guide_snmp() -> str:
"""Installer et securiser SNMP, par systeme."""
return render_template("guide-snmp.html")
@app.get("/mentions")
def mentions() -> str:
return render_template(
@@ -222,6 +228,25 @@ def create_app() -> Flask:
only_defaults = request.args.get("tout") != "1"
return jsonify(pack_to_project(pack, only_defaults=only_defaults).to_dict())
@app.post("/api/packs/<pack_id>/fusionner")
def api_fusionner_pack(pack_id: str) -> Response:
"""Ajoute un pack au projet en cours.
La fusion est faite ici et non dans le navigateur : Project.merge
connait tous les objets d'un projet, y compris ceux ajoutes plus tard.
Une liste tenue a la main cote client finirait toujours par en oublier.
"""
pack = catalog().get(pack_id)
if pack is None:
return jsonify({"erreur": "pack inconnu"}), 404
payload = request.get_json(force=True, silent=True) or {}
projet = Project.from_dict(payload.get("project") or {})
fragment = pack_to_project(pack, only_defaults=not payload.get("tout"))
ignores = projet.merge(fragment)
return jsonify({"project": projet.to_dict(), "ignores": ignores})
@app.post("/api/valider")
def api_validate() -> Response:
plan = build_plan(project_from_request())
@@ -232,6 +257,97 @@ def create_app() -> Flask:
payload = request.get_json(force=True, silent=True) or {}
return jsonify(generate(payload.get("project", payload)))
@app.get("/api/fuseaux")
def api_fuseaux() -> Response:
"""Fuseaux horaires connus : la saisie libre menait a des erreurs muettes."""
from .model import fuseaux_horaires
return jsonify(fuseaux_horaires())
@app.get("/api/commandes-usuelles")
def api_commandes_usuelles() -> Response:
"""Commandes de verification livrees par Centreon."""
return jsonify(
[
{"nom": "check_centreon_ping", "description": "Ping, avec seuils de perte et de latence"},
{"nom": "check_host_alive", "description": "Ping simplifie, disponibilite de l'hote"},
{"nom": "check-host-alive", "description": "Variante historique de check_host_alive"},
{"nom": "check_centreon_dummy", "description": "Etat fixe, pour un hote passif"},
{"nom": "check_centreon_snmp_value", "description": "Valeur SNMP, pour un hote sans ping"},
]
)
@app.get("/api/valeurs-standards")
def api_valeurs_standards() -> Response:
"""Valeurs livrees par Centreon, proposees plutot que saisies.
Chaque champ libre est une occasion de faute de frappe qui ne se voit
qu'au moment du deploiement sur le central.
"""
return jsonify(
{
"modeles_hote": [
"generic-active-host-custom",
"generic-passive-host-custom",
"generic-active-host",
"generic-passive-host",
],
"modeles_service": [
"generic-active-service-custom",
"generic-passive-service-custom",
"generic-active-service",
"generic-passive-service",
],
"versions_snmp": ["1", "2c", "3"],
"repertoires_plugins": [
"/usr/lib/centreon/plugins",
"/usr/lib/nagios/plugins",
"/usr/local/centreon/plugins",
],
"criticites": ["Critique", "Majeure", "Mineure", "Information"],
"collecteurs": ["Central"],
}
)
@app.get("/api/macros-notification")
def api_macros_notification() -> Response:
"""Les macros proposees dans l'editeur de blocs."""
from .notifications import MACROS
return jsonify(MACROS)
@app.post("/api/blocs-defaut")
def api_blocs_defaut() -> Response:
"""Les blocs livres par defaut, point de depart d'une composition."""
from dataclasses import asdict
from .notifications import blocs_par_defaut
payload = request.get_json(force=True, silent=True) or {}
projet = Project.from_dict(payload.get("project") or {})
nom = str(payload.get("perimetre") or "")
pour = "host" if payload.get("pour") == "host" else "service"
perimetre = next((p for p in projet.perimetres if p.name == nom), None)
if perimetre is None:
return jsonify({"erreur": "perimetre introuvable"}), 404
return jsonify([asdict(b) for b in blocs_par_defaut(perimetre, pour)])
@app.post("/api/apercu-notification")
def api_apercu() -> Response:
"""Rend le message d'un perimetre avec des valeurs d'exemple."""
from .notifications import apercu
payload = request.get_json(force=True, silent=True) or {}
projet = Project.from_dict(payload.get("project") or {})
nom = str(payload.get("perimetre") or "")
pour = "host" if payload.get("pour") == "host" else "service"
perimetre = next((p for p in projet.perimetres if p.name == nom), None)
if perimetre is None:
return jsonify({"erreur": "perimetre introuvable"}), 404
return jsonify(apercu(projet, perimetre, pour))
@app.post("/api/macros")
def api_macros() -> Response:
payload = request.get_json(force=True, silent=True) or {}
+2
View File
@@ -8,3 +8,5 @@ Flask-SQLAlchemy>=3.1,<4.0
SQLAlchemy>=2.0,<3.0
alembic>=1.13,<2.0
psycopg[binary]>=3.1,<4.0
# Base des fuseaux horaires : absente des images slim, la liste serait vide.
tzdata>=2024.1
+36
View File
@@ -0,0 +1,36 @@
"""Fixtures communes aux tests."""
from __future__ import annotations
import importlib
import pytest
@pytest.fixture()
def app(tmp_path, monkeypatch):
"""Application avec une base SQLite temporaire."""
monkeypatch.setenv("ENCLUME_DATABASE_URL", f"sqlite:///{tmp_path/'essai.db'}")
monkeypatch.setenv("ENCLUME_CATALOG", "catalog")
monkeypatch.setenv("ENCLUME_SECRET_KEY", "cle-de-test")
monkeypatch.setenv("ENCLUME_COOKIE_SECURE", "0")
import enclume.auth
import enclume.config
import enclume.db
import enclume.routes_donnees
import enclume.webapp
for module in (
enclume.config,
enclume.db,
enclume.auth,
enclume.routes_donnees,
enclume.webapp,
):
importlib.reload(module)
application = enclume.webapp.create_app()
with application.app_context():
enclume.db.db.create_all()
return application
+130 -3
View File
@@ -29,10 +29,39 @@ const dom = new JSDOM(html, {
const { window } = dom;
// Reponses minimales mais de la bonne forme, comme celles du serveur.
// Ce que renverrait le serveur pour une fusion : le pack apporte bien plus que
// des commandes et des modeles.
const PROJET_FUSIONNE = {
name: 'Essai', centreon_version: '25.10', prefix: '', plugins_dir: '/usr/lib/centreon/plugins',
poller: 'Central', apply_config: true, notif_dir: '/usr/share/centreon/notifications',
commands: [{ name: 'App-Essai-Cpu', type: 'check', line: '$USER1$/check', comment: '' }],
service_templates: [], hosts: [],
host_templates: [{ name: 'App-Essai-custom', alias: 'Essai', parents: [], macros: [],
perimetre: 'Essai', check_command: '', check_command_args: '',
snmp_version: '', snmp_community: '', timezone: '' }],
groupes_hotes: [{ name: 'HG-App-Essai', alias: 'Essai' }],
calendriers: [{ name: 'Heures-Ouvrees', alias: '8h-18h', jours: { monday: '08:00-18:00' } }],
perimetres: [{ name: 'Essai', description: '', calendrier: 'Heures-Ouvrees', contacts: [],
groupe: 'CG-App-Essai', options_hote: 'd,u,r', options_service: 'w,c,r',
intervalle: 30, application: '', responsable: '', procedure: '',
criticite: 'Majeure', impact: 'Essai', couleur: '#2f6f9f',
sujet_hote: '', sujet_service: '', blocs_hote: [], blocs_service: [] }],
prerequis: { paquets_debian: ['libwww-perl'], paquets_rhel: [], verifications: [], notes: '' },
};
const reponses = {
'/api/packs': [],
'/api/packs': [
{ id: 'app-essai', name: 'Essai', category: 'applications', category_label: 'Applications',
status: 'verified', plugin: 'essai.pl', description: 'Pack d essai',
host_template: 'App-Essai-custom', services: [] },
],
'/api/generer': { summary: {}, issues: [], files: { 'deploy.clapi': '' } },
'/api/projets': [],
'/api/packs/app-essai/fusionner': { project: PROJET_FUSIONNE, ignores: [] },
'/api/valeurs-standards': {},
'/api/fuseaux': ['Europe/Paris'],
'/api/commandes-usuelles': [{ nom: 'check_centreon_ping', description: 'Ping' }],
'/api/macros-notification': [],
};
window.fetch = (url) => Promise.resolve({
ok: true,
@@ -60,7 +89,7 @@ if (!rail || !principal) {
}
// Chaque type d'objet doit se creer, s'afficher, et remplir la fenetre.
const types = ['command', 'stpl', 'htpl', 'host'];
const types = ['command', 'stpl', 'htpl', 'host', 'groupehote', 'calendrier', 'perimetre'];
if (erreurs.length === 0) {
for (const type of types) {
const ajouter = [...rail.querySelectorAll('button')].filter((b) => b.textContent === '+');
@@ -90,8 +119,106 @@ if (erreurs.length === 0) {
}
}
// L'import d'un pack doit apporter tout ce que le serveur renvoie, pas
// seulement les commandes et les modeles.
try {
document.getElementById('btn-pack').click();
await new Promise((r) => setTimeout(r, 30));
const importer = [...document.querySelectorAll('#modal-corps button')]
.find((b) => b.textContent === 'Sondes par defaut');
if (!importer) {
erreurs.push('aucun bouton d import dans le catalogue');
} else {
importer.click();
await new Promise((r) => setTimeout(r, 40));
const projet = window.projetCourant();
for (const [cle, libelle] of [
['groupes_hotes', "groupe d'hotes"],
['calendriers', 'calendrier'],
['perimetres', 'perimetre'],
]) {
if (!projet[cle] || projet[cle].length === 0) {
erreurs.push(`l import d un pack n apporte pas le ${libelle}`);
}
}
if (!projet.prerequis || !projet.prerequis.paquets_debian.length) {
erreurs.push('l import d un pack n apporte pas les prerequis');
}
}
} catch (erreur) {
erreurs.push('import d un pack : ' + erreur.message);
}
// Un pack deja dans le projet ne doit plus etre proposable a l'import.
try {
window.eval("projetCourant().host_templates.push({ name: 'App-Essai-custom', macros: [], parents: [] });");
document.getElementById('btn-pack').click();
await new Promise((r) => setTimeout(r, 30));
const corps = document.getElementById('modal-corps');
const boutons = [...corps.querySelectorAll('button')].map((b) => b.textContent);
if (boutons.includes('Sondes par defaut')) {
erreurs.push('un pack deja importe reste proposable');
}
if (!corps.textContent.includes('deja dans le projet')) {
erreurs.push('le masquage des packs importes n est pas signale');
}
// Affiches a la demande, ils restent sans action : les reimporter n'aurait
// aucun effet, et un bouton inerte ferait douter l'utilisateur.
const afficher = [...corps.querySelectorAll('button')]
.find((b) => b.textContent === 'Les afficher');
if (!afficher) {
erreurs.push('aucun moyen d afficher les packs masques');
} else {
afficher.click();
await new Promise((r) => setTimeout(r, 30));
const apres = [...corps.querySelectorAll('button')].map((b) => b.textContent);
if (apres.includes('Sondes par defaut')) {
erreurs.push('un pack deja importe redevient proposable une fois affiche');
}
if (!corps.textContent.includes('deja importe')) {
erreurs.push('un pack affiche n est pas signale comme deja importe');
}
}
document.querySelector('[data-fermer-modal]').click();
} catch (erreur) {
erreurs.push('catalogue de packs : ' + erreur.message);
}
// Un perimetre cree apres un import doit reprendre le calendrier du projet.
try {
const ajouts = [...rail.querySelectorAll('button')].filter((b) => b.textContent === '+');
ajouts[ajouts.length - 1].click(); // dernier groupe du rail : perimetres
await new Promise((r) => setTimeout(r, 20));
const projet = window.projetCourant();
const dernier = projet.perimetres[projet.perimetres.length - 1];
if (projet.calendriers.length && !dernier.calendrier) {
erreurs.push('un perimetre neuf ne reprend pas le calendrier du projet');
}
} catch (erreur) {
erreurs.push('creation d un perimetre : ' + erreur.message);
}
// Un champ sans valeur ne doit jamais afficher le mot « undefined ».
for (const entree of rail.querySelectorAll('.rail-item')) {
principal.innerHTML = '';
entree.click();
const champs = [...principal.querySelectorAll('input, textarea, select')];
const fautifs = champs.filter((c) => String(c.value).includes('undefined'));
if (fautifs.length) {
erreurs.push(
`${entree.textContent.trim()} : ${fautifs.length} champ(s) affichent undefined`
);
break;
}
}
// Les notifications doivent s'afficher, avec leur type.
try {
// Les actions precedentes ont pu en laisser : on part d'une zone vide.
const zoneExistante = document.getElementById('notifications');
if (zoneExistante) zoneExistante.innerHTML = '';
window.eval("notifier('essai de reussite', 'succes'); notifier('essai d erreur', 'erreur');");
const zone = document.getElementById('notifications');
if (!zone || zone.children.length !== 2) {
@@ -129,4 +256,4 @@ if (erreurs.length) {
process.exit(1);
}
console.log('interface : les quatre types d\'objets s\'affichent, les boutons repondent');
console.log('interface : les ' + types.length + ' types d\'objets s\'affichent, les boutons repondent');
+177
View File
@@ -136,3 +136,180 @@ def test_accueil_et_mentions():
assert b"Donn" in mentions.data # section donnees personnelles
assert client.get("/editeur").status_code == 200
def test_chaque_pack_produit_un_plan_valide():
"""Un pack du catalogue doit s'importer et se generer sans erreur bloquante."""
from enclume.packs import pack_to_project
catalogue = Catalog("catalog")
fautifs = {}
for pack in catalogue.packs.values():
plan = build_plan(pack_to_project(pack))
erreurs = [i["message"] for i in plan.issues if i["level"] == "error"]
if erreurs:
fautifs[pack.id] = erreurs
assert not fautifs, fautifs
def test_les_categories_sont_celles_de_centreon():
"""Un pack doit se ranger la ou on ira le chercher dans la documentation Centreon."""
from enclume.catalog import CATEGORIES
catalogue = Catalog("catalog")
inconnues = {p.id: p.category for p in catalogue.packs.values() if p.category not in CATEGORIES}
assert not inconnues, inconnues
def test_le_repertoire_correspond_a_la_categorie():
"""Les soumissions ecrivent dans catalog/<categorie>/ : l'arborescence doit suivre."""
import os
for pack in Catalog("catalog").packs.values():
repertoire = os.path.basename(os.path.dirname(pack.source_file))
assert repertoire == pack.category, f"{pack.id} : {repertoire} != {pack.category}"
def test_groupes_d_hotes_crees_et_rattaches():
"""Un hote sans groupe devient introuvable des que le parc grandit."""
projet = Project.from_dict(
{
"groupes_hotes": [{"name": "HG-Serveurs-Linux", "alias": "Serveurs Linux"}],
"hosts": [
{
"name": "srv-01",
"address": "10.0.4.1",
"templates": ["OS-Linux-SNMP-custom"],
"hostgroups": ["HG-Serveurs-Linux", "HG-Production"],
}
],
}
)
lignes = [o.import_line() for o in build_plan(projet).ops if o.obj != "#"]
assert "HG;ADD;HG-Serveurs-Linux;Serveurs Linux" in lignes
hote = next(ligne for ligne in lignes if ligne.startswith("HOST;ADD;"))
assert hote.endswith("HG-Serveurs-Linux|HG-Production")
# Un groupe absent du projet est signale, sans bloquer : il peut exister deja.
messages = [i["message"] for i in build_plan(projet).issues]
assert any("HG-Production" in m for m in messages)
def test_ancien_format_de_groupes_accepte():
"""Les projets enregistres avant la 1.12 portaient une chaine unique."""
projet = Project.from_dict(
{"hosts": [{"name": "srv", "address": "10.0.0.1", "hostgroups": "HG-A|HG-B"}]}
)
assert projet.hosts[0].hostgroups == ["HG-A", "HG-B"]
def test_rollback_supprime_les_groupes_d_hotes():
projet = Project.from_dict({"groupes_hotes": [{"name": "HG-Essai"}]})
lignes = [o.import_line() for o in build_plan(projet).rollback_ops]
assert "HG;DEL;HG-Essai" in lignes
def test_chaque_pack_livre_son_groupe_d_hotes():
"""Un utilisateur qui importe un pack doit recevoir une configuration complete."""
from enclume.packs import pack_to_project
catalogue = Catalog("catalog")
sans = [p.id for p in catalogue.packs.values() if not p.groupe_hote]
assert not sans, f"packs sans groupe d'hotes : {sans}"
projet = pack_to_project(catalogue.get("app-mysql"))
assert [g.name for g in projet.groupes_hotes] == ["HG-App-DB-MySQL"]
lignes = [o.import_line() for o in build_plan(projet).ops if o.obj == "HG"]
assert lignes == ["HG;ADD;HG-App-DB-MySQL;MySQL / MariaDB"]
def test_commande_et_fuseau_sur_l_hote():
"""La commande de verification et le fuseau appartiennent a l'hote."""
projet = Project.from_dict(
{
"hosts": [
{
"name": "srv-01",
"address": "10.0.4.1",
"check_command": "check_centreon_ping",
"check_command_args": "!3!200,20%!400,50%",
"timezone": "Europe/Paris",
}
]
}
)
lignes = [o.import_line() for o in build_plan(projet).ops if o.obj == "HOST"]
assert "HOST;setparam;srv-01;check_command;check_centreon_ping" in lignes
assert "HOST;setparam;srv-01;check_command_arguments;!3!200,20%!400,50%" in lignes
assert "HOST;setparam;srv-01;timezone;Europe/Paris" in lignes
def test_fuseau_horaire_errone_refuse():
"""Une faute de frappe sur un fuseau ne se verrait qu'a l'execution."""
from enclume.model import fuseaux_horaires, validate
if not fuseaux_horaires():
return # base de fuseaux absente de la machine
projet = Project.from_dict(
{"hosts": [{"name": "srv", "address": "10.0.0.1", "timezone": "Europe/Pariss"}]}
)
erreurs = [i["message"] for i in validate(projet) if i["level"] == "error"]
assert any("fuseau horaire inconnu" in m for m in erreurs)
def test_les_fuseaux_sont_exposes():
client = create_app().test_client()
fuseaux = client.get("/api/fuseaux").get_json()
assert "Europe/Paris" in fuseaux
commandes = [c["nom"] for c in client.get("/api/commandes-usuelles").get_json()]
assert "check_centreon_ping" in commandes
def test_guide_snmp_accessible_et_complet():
"""Une page d'aide qui n'aborde pas la securite ferait plus de mal que de bien."""
page = create_app().test_client().get("/aide/snmp").data.decode()
for systeme in ("Debian", "RHEL", "Windows", "Cisco"):
assert systeme in page, systeme
# Les points de securite qui distinguent une configuration tenable.
for notion in ("authPriv", "rocommunity", "PermittedManagers", "snmpwalk", "firewall-cmd"):
assert notion in page, notion
# La lecture seule, jamais l'ecriture.
assert "Ne jamais utiliser 8" in page
def test_valeurs_standards_exposees():
"""Les listes proposees remplacent la saisie libre : elles doivent exister."""
valeurs = create_app().test_client().get("/api/valeurs-standards").get_json()
assert "generic-active-host-custom" in valeurs["modeles_hote"]
assert "generic-active-service-custom" in valeurs["modeles_service"]
assert valeurs["versions_snmp"] == ["1", "2c", "3"]
assert "/usr/lib/centreon/plugins" in valeurs["repertoires_plugins"]
assert "Critique" in valeurs["criticites"]
def test_nom_affiche_et_baseline():
"""Le nom affiche est « Forge Centreon » ; le projet et les images restent « Enclume »."""
page = create_app().test_client().get("/").data.decode()
assert "Forge Centreon" in page
assert "Générateur de configuration pour Centreon avec CLAPI" in page
# La mention d'independance devient d'autant plus necessaire.
assert "Centreon SAS" in page
def test_l_editeur_utilise_la_route_de_fusion():
"""Garde-fou contre une correction qui n'a pas ete appliquee.
L'import d'un pack a laisse deux versions durant, une ancienne fonction qui
ne recopiait que trois listes : le remplacement avait echoue en silence, et
aucun test n'empruntait ce chemin.
"""
from pathlib import Path
script = Path("enclume/static/editeur.js").read_text(encoding="utf-8")
assert "/fusionner" in script, "l'import n'appelle pas la route de fusion"
assert "'service_templates', 'host_templates'" not in script, "l'ancien import subsiste"
+568
View File
@@ -0,0 +1,568 @@
"""Tests des perimetres de notification.
Ce que ces tests protegent : le CLAPI produit (calendriers, commandes de type
notif, parametres de contact) et le script PHP genere, dont la syntaxe est
verifiee par php lui-meme quand il est disponible.
"""
from __future__ import annotations
import shutil
import subprocess
import pytest
from enclume.generator import build_plan, render_bundle
from enclume.model import Project, validate
from enclume.notifications import SHEBANG
PROJET = {
"name": "Notifications",
"calendriers": [
{
"name": "Heures-Ouvrees",
"alias": "8h-18h du lundi au vendredi",
"jours": {
"monday": "08:00-18:00",
"tuesday": "08:00-18:00",
"wednesday": "08:00-18:00",
"thursday": "08:00-18:00",
"friday": "08:00-18:00",
},
}
],
"perimetres": [
{
"name": "Applicatif Facturation",
"description": "Chaine de facturation client",
"calendrier": "Heures-Ouvrees",
"contacts": ["hcornet", "astreinte"],
"groupe": "CG-Facturation",
"options_hote": "d,u,r",
"options_service": "w,c,r",
"application": "Facturation",
"responsable": "Equipe finance",
"procedure": "https://wiki.exemple.fr/reprise-facturation",
"criticite": "Majeure",
"impact": "Emission des factures bloquee",
}
],
}
def lignes_clapi(projet: Project) -> list[str]:
return [o.import_line() for o in build_plan(projet).ops if o.obj != "#"]
def test_calendrier_genere_ses_plages():
lignes = lignes_clapi(Project.from_dict(PROJET))
assert "TP;ADD;Heures-Ouvrees;8h-18h du lundi au vendredi" in lignes
assert "TP;setparam;Heures-Ouvrees;monday;08:00-18:00" in lignes
assert not any("saturday" in ligne for ligne in lignes), "un jour vide ne doit rien produire"
def test_deux_commandes_de_notification_par_perimetre():
lignes = lignes_clapi(Project.from_dict(PROJET))
commandes = [ligne for ligne in lignes if ligne.startswith("CMD;ADD;") and ";notif;" in ligne]
assert len(commandes) == 2
assert any("-Notify-Host;notif;" in c for c in commandes)
assert any("-Notify-Service;notif;" in c for c in commandes)
# La commande de service passe la description du service, pas celle de l'hote.
service = next(c for c in commandes if "-Notify-Service" in c)
assert "$SERVICEDESC$" in service and "$SERVICESTATE$" in service
def test_parametres_de_contact_pour_chaque_destinataire():
lignes = lignes_clapi(Project.from_dict(PROJET))
for contact in ("hcornet", "astreinte"):
assert f"CONTACT;setparam;{contact};hostnotifperiod;Heures-Ouvrees" in lignes
assert f"CONTACT;setparam;{contact};svcnotifopt;w,c,r" in lignes
assert any(
ligne.startswith(f"CONTACT;setparam;{contact};svcnotifcmd;") for ligne in lignes
)
def test_groupe_de_contacts_cree_et_peuple():
lignes = lignes_clapi(Project.from_dict(PROJET))
assert "CG;ADD;CG-Facturation;Applicatif Facturation" in lignes
assert "CG;setcontact;CG-Facturation;hcornet|astreinte" in lignes
def test_le_prefixe_s_applique_aux_objets_de_notification():
donnees = dict(PROJET, prefix="ACME-")
lignes = lignes_clapi(Project.from_dict(donnees))
assert "TP;ADD;ACME-Heures-Ouvrees;8h-18h du lundi au vendredi" in lignes
periode = next(ligne for ligne in lignes if "hostnotifperiod" in ligne)
assert periode.endswith("ACME-Heures-Ouvrees")
def test_option_de_notification_invalide_refusee():
donnees = dict(PROJET)
donnees["perimetres"] = [dict(PROJET["perimetres"][0], options_service="w,z")]
erreurs = [i for i in validate(Project.from_dict(donnees)) if i["level"] == "error"]
assert any("option de service inconnue" in e["message"] for e in erreurs)
def test_perimetre_sans_destinataire_signale():
donnees = dict(PROJET)
donnees["perimetres"] = [dict(PROJET["perimetres"][0], contacts=[], groupe="")]
messages = [i["message"] for i in validate(Project.from_dict(donnees))]
assert any("personne ne sera prevenu" in m for m in messages)
def test_le_script_php_est_genere_avec_son_shebang():
fichiers = render_bundle(build_plan(Project.from_dict(PROJET)))
chemin = "notifications/notif-applicatif-facturation.php"
assert chemin in fichiers
assert "notifications/installer.sh" in fichiers
script = fichiers[chemin]
assert script.startswith(SHEBANG)
assert script.splitlines()[1] == "<?php"
# Le contexte du perimetre doit se retrouver dans le message.
for attendu in ("Facturation", "Equipe finance", "Majeure", "reprise-facturation"):
assert attendu in script
def test_apostrophe_echappee_dans_le_script():
"""Un texte contenant une apostrophe casserait un litteral PHP mal echappe."""
donnees = dict(PROJET)
donnees["perimetres"] = [dict(PROJET["perimetres"][0], impact="L'emission des factures s'arrete")]
fichiers = render_bundle(build_plan(Project.from_dict(donnees)))
script = fichiers["notifications/notif-applicatif-facturation.php"]
assert "L\\'emission des factures s\\'arrete" in script
@pytest.mark.skipif(shutil.which("php") is None, reason="php absent de cette machine")
def test_le_script_php_est_syntaxiquement_valide(tmp_path):
fichiers = render_bundle(build_plan(Project.from_dict(PROJET)))
chemin = tmp_path / "notif.php"
chemin.write_text(fichiers["notifications/notif-applicatif-facturation.php"], encoding="utf-8")
resultat = subprocess.run(
["php", "-l", str(chemin)], capture_output=True, text=True, timeout=30
)
assert resultat.returncode == 0, resultat.stdout + resultat.stderr
@pytest.mark.skipif(shutil.which("php") is None, reason="php absent de cette machine")
def test_le_script_refuse_un_appel_incomplet(tmp_path):
"""Sans destinataire, le script doit sortir en erreur plutot que d'envoyer dans le vide."""
fichiers = render_bundle(build_plan(Project.from_dict(PROJET)))
chemin = tmp_path / "notif.php"
chemin.write_text(fichiers["notifications/notif-applicatif-facturation.php"], encoding="utf-8")
resultat = subprocess.run(
["php", str(chemin), "--type=host", "--hote=srv-01", "--etat=DOWN"],
capture_output=True,
text=True,
timeout=30,
)
assert resultat.returncode == 1
assert "destinataire" in resultat.stderr
def test_rollback_supprime_calendriers_et_groupes():
plan = build_plan(Project.from_dict(PROJET))
lignes = [o.import_line() for o in plan.rollback_ops]
assert "TP;DEL;Heures-Ouvrees" in lignes
assert "CG;DEL;CG-Facturation" in lignes
# Les commandes de notification partent aussi.
assert sum(1 for ligne in lignes if ligne.startswith("CMD;DEL;")) == 2
PROJET_RATTACHE = dict(
PROJET,
host_templates=[{"name": "App-Facturation-custom", "perimetre": "Applicatif Facturation"}],
service_templates=[
{
"name": "App-Facturation-Queue",
"perimetre": "Applicatif Facturation",
"host_templates": ["App-Facturation-custom"],
}
],
)
def test_un_modele_herite_du_cablage_de_son_perimetre():
"""Un modele applicatif doit arriver dans Centreon en sachant qui prevenir et quand."""
lignes = lignes_clapi(Project.from_dict(PROJET_RATTACHE))
assert "HTPL;setparam;App-Facturation-custom;notification_period;Heures-Ouvrees" in lignes
assert "HTPL;setparam;App-Facturation-custom;notification_options;d,u,r" in lignes
assert "HTPL;setcontactgroup;App-Facturation-custom;CG-Facturation" in lignes
# Le service prend ses propres etats declencheurs, pas ceux de l'hote.
assert "STPL;setparam;App-Facturation-Queue;notification_options;w,c,r" in lignes
assert "STPL;setcontactgroup;App-Facturation-Queue;CG-Facturation" in lignes
def test_le_prefixe_s_applique_au_groupe_rattache():
lignes = lignes_clapi(Project.from_dict(dict(PROJET_RATTACHE, prefix="ACME-")))
assert "HTPL;setcontactgroup;ACME-App-Facturation-custom;ACME-CG-Facturation" in lignes
def test_perimetre_inconnu_signale():
donnees = dict(PROJET_RATTACHE)
donnees["host_templates"] = [{"name": "App-X-custom", "perimetre": "Inexistant"}]
messages = [i["message"] for i in validate(Project.from_dict(donnees))]
assert any("perimetre de notification Inexistant" in m for m in messages)
def test_modele_sans_perimetre_ne_produit_aucun_cablage():
donnees = dict(PROJET_RATTACHE)
donnees["host_templates"] = [{"name": "App-Y-custom"}]
lignes = lignes_clapi(Project.from_dict(donnees))
assert not any("App-Y-custom" in ligne and "notification_period" in ligne for ligne in lignes)
def test_apercu_reprend_le_contexte_du_perimetre():
from enclume.notifications import apercu
projet = Project.from_dict(PROJET)
rendu = apercu(projet, projet.perimetres[0], "service")
assert "App-DB-MySQL-Connection-Time" in rendu["sujet"]
assert "CRITICAL" in rendu["sujet"]
for attendu in ("Facturation", "Equipe finance", "Majeure", "reprise-facturation"):
assert attendu in rendu["corps"]
assert rendu["script"].endswith("notif-applicatif-facturation.php")
def test_apercu_hote_n_affiche_pas_de_service():
from enclume.notifications import apercu
projet = Project.from_dict(PROJET)
rendu = apercu(projet, projet.perimetres[0], "host")
assert "Service" not in rendu["corps"].split("<table")[1].split("</table>")[0]
assert "DOWN" in rendu["sujet"]
def test_apercu_echappe_les_valeurs():
"""La sortie d'un plugin ou un champ metier ne doit pas pouvoir injecter du HTML."""
from enclume.notifications import apercu
donnees = dict(PROJET)
donnees["perimetres"] = [
dict(PROJET["perimetres"][0], impact="<script>alert(1)</script>")
]
projet = Project.from_dict(donnees)
rendu = apercu(projet, projet.perimetres[0], "service")
assert "<script>alert(1)</script>" not in rendu["corps"]
assert "&lt;script&gt;" in rendu["corps"]
def test_apercu_et_script_partagent_le_gabarit():
"""Les deux doivent montrer la meme chose : un gabarit unique le garantit."""
from enclume.notifications import GABARIT_HTML, GABARIT_LIGNE, rendre_script
projet = Project.from_dict(PROJET)
script = rendre_script(projet, projet.perimetres[0])
assert GABARIT_HTML in script
assert GABARIT_LIGNE in script
def test_route_d_apercu():
"""L'apercu ne demande ni base ni connexion : il ne conserve rien."""
from enclume.webapp import create_app
projet = Project.from_dict(PROJET).to_dict()
client = create_app().test_client()
reponse = client.post(
"/api/apercu-notification",
json={"project": projet, "perimetre": "Applicatif Facturation", "pour": "service"},
)
assert reponse.status_code == 200
assert "Emission des factures bloquee" in reponse.get_json()["corps"]
inconnu = client.post(
"/api/apercu-notification", json={"project": projet, "perimetre": "Inexistant"}
)
assert inconnu.status_code == 404
# --------------------------------------------------------------- composition
PROJET_COMPOSE = dict(
PROJET,
perimetres=[
dict(
PROJET["perimetres"][0],
blocs_service=[
{"type": "macro", "libelle": "Hote", "valeur": "$HOSTNAME$"},
{"type": "macro", "libelle": "Auteur", "valeur": "$NOTIFICATIONAUTHOR$"},
{"type": "macro", "libelle": "Commentaire", "valeur": "$NOTIFICATIONCOMMENT$"},
{"type": "lien", "libelle": "Documentation", "valeur": "$SERVICENOTESURL$"},
{"type": "texte", "libelle": "Astreinte", "valeur": "Appeler le 3000"},
{"type": "sortie", "libelle": "Sortie", "valeur": "$SERVICEOUTPUT$"},
],
)
],
)
def test_la_commande_transporte_les_macros_des_blocs():
lignes = lignes_clapi(Project.from_dict(PROJET_COMPOSE))
commande = next(ligne for ligne in lignes if "-Notify-Service" in ligne)
# Un argument par bloc qui porte une macro, le texte fixe reste dans le script.
assert "--b1='$HOSTNAME$'" in commande
assert "--b2='$NOTIFICATIONAUTHOR$'" in commande
assert "--b4='$SERVICENOTESURL$'" in commande
assert "--b5=" not in commande, "un bloc de texte fixe ne doit pas passer par la commande"
assert "--b6='$SERVICEOUTPUT$'" in commande
def test_les_blocs_par_defaut_couvrent_l_essentiel():
from enclume.notifications import blocs_par_defaut
projet = Project.from_dict(PROJET)
blocs = blocs_par_defaut(projet.perimetres[0], "service")
macros = [b.valeur for b in blocs if b.type == "macro"]
for attendue in ("$HOSTNAME$", "$SERVICEDESC$", "$NOTIFICATIONAUTHOR$", "$NOTIFICATIONCOMMENT$"):
assert attendue in macros
assert any(b.type == "sortie" for b in blocs)
# Le contexte du perimetre devient des blocs de texte.
assert any(b.type == "texte" and b.valeur == "Facturation" for b in blocs)
def test_l_apercu_suit_la_composition():
from enclume.notifications import apercu
projet = Project.from_dict(PROJET_COMPOSE)
rendu = apercu(projet, projet.perimetres[0], "service")
assert "Prise en compte" in rendu["corps"] # $NOTIFICATIONCOMMENT$
assert "Appeler le 3000" in rendu["corps"] # bloc de texte
assert "wiki.exemple.fr/mysql-facturation" in rendu["corps"] # bloc lien
assert "Criticite" not in rendu["corps"], "les blocs composes remplacent les defauts"
def test_macro_inconnue_affichee_en_reperage():
"""Une macro sans exemple doit tout de meme montrer la ligne qu'elle produira."""
from enclume.notifications import apercu
donnees = dict(PROJET)
donnees["perimetres"] = [
dict(
PROJET["perimetres"][0],
blocs_service=[{"type": "macro", "libelle": "Perso", "valeur": "$_SERVICEAPPLI$"}],
)
]
projet = Project.from_dict(donnees)
rendu = apercu(projet, projet.perimetres[0], "service")
assert "[$_SERVICEAPPLI$]" in rendu["corps"]
def test_liste_des_macros_exposee(app):
reponse = app.test_client().get("/api/macros-notification")
assert reponse.status_code == 200
macros = [m["macro"] for m in reponse.get_json()]
assert "$NOTIFICATIONAUTHOR$" in macros
assert "$SERVICENOTESURL$" in macros
def test_blocs_par_defaut_exposes(app):
projet = Project.from_dict(PROJET).to_dict()
reponse = app.test_client().post(
"/api/blocs-defaut",
json={"project": projet, "perimetre": "Applicatif Facturation", "pour": "host"},
)
assert reponse.status_code == 200
blocs = reponse.get_json()
assert any(b["valeur"] == "$HOSTOUTPUT$" for b in blocs)
assert not any(b["valeur"] == "$SERVICEDESC$" for b in blocs)
# ------------------------------------------------- chaine livree par les packs
def test_chaque_pack_declare_sa_chaine_de_notification():
"""Un pack qui superviserait sans prevenir personne n'a pas d'interet."""
from enclume.catalog import Catalog
catalogue = Catalog("catalog")
sans = [p.id for p in catalogue.packs.values() if not p.notification]
assert not sans, f"packs sans notification : {sans}"
for pack in catalogue.packs.values():
notification = pack.notification
assert notification.get("calendrier"), pack.id
assert notification.get("groupe", "").startswith("CG-"), pack.id
assert notification.get("impact"), pack.id
def test_import_d_un_pack_rattache_ses_modeles():
from enclume.catalog import Catalog
from enclume.packs import pack_to_project
projet = pack_to_project(Catalog("catalog").get("app-ldap"))
perimetre = projet.perimetres[0]
assert perimetre.calendrier == "TP-App-LDAP-24x7"
assert perimetre.groupe == "CG-App-LDAP"
assert perimetre.criticite == "Critique"
assert projet.host_templates[0].perimetre == perimetre.name
assert all(s.perimetre == perimetre.name for s in projet.service_templates)
def test_chaque_pack_apporte_son_propre_calendrier():
"""Modifier les plages d'un pack ne doit pas toucher celles de tout le central."""
from enclume.catalog import Catalog
from enclume.packs import pack_to_project
projet = pack_to_project(Catalog("catalog").get("app-ldap"))
calendrier = projet.calendriers[0]
assert calendrier.name == "TP-App-LDAP-24x7"
assert calendrier.creer is True
assert len(calendrier.jours) == 7
assert projet.perimetres[0].calendrier == calendrier.name
lignes = [o.import_line() for o in build_plan(projet).ops if o.obj == "TP"]
assert lignes[0].startswith("TP;ADD;TP-App-LDAP-24x7;")
assert any("monday;00:00-24:00" in ligne for ligne in lignes)
# Une imprimante ne reveille personne la nuit : cinq jours ouvres.
imprimante = pack_to_project(Catalog("catalog").get("hw-printer-rfc3805"))
assert imprimante.calendriers[0].name == "TP-HW-Printer-RFC3805-Heures-Ouvrees"
assert len(imprimante.calendriers[0].jours) == 5
def test_le_calendrier_d_un_pack_suit_le_prefixe():
"""Comme les autres objets du projet, il porte le prefixe demande."""
from enclume.catalog import Catalog
from enclume.packs import pack_to_project
projet = pack_to_project(Catalog("catalog").get("app-apache"))
projet.prefix = "ACME-"
lignes = [o.import_line() for o in build_plan(projet).ops]
assert any(ligne.startswith("TP;ADD;ACME-TP-App-Apache-24x7;") for ligne in lignes)
periode = next(ligne for ligne in lignes if "notification_period" in ligne)
assert periode.endswith(";ACME-TP-App-Apache-24x7")
def test_un_pack_importe_produit_le_cablage_complet():
from enclume.catalog import Catalog
from enclume.packs import pack_to_project
projet = pack_to_project(Catalog("catalog").get("app-mysql"))
lignes = lignes_clapi(projet)
assert any(ligne.startswith("CG;ADD;CG-App-DB-MySQL;") for ligne in lignes)
assert any(
ligne.startswith("HTPL;setcontactgroup;App-DB-MySQL-custom;CG-App-DB-MySQL")
for ligne in lignes
)
assert any("STPL;setcontactgroup;" in ligne for ligne in lignes)
assert any("notification_period;TP-App-DB-MySQL-24x7" in ligne for ligne in lignes)
def test_la_fusion_d_un_pack_apporte_tout(app):
"""L'import doit apporter le calendrier, le perimetre et les prerequis,
pas seulement les commandes et les modeles."""
client = app.test_client()
# Un projet vide, puis deux packs successifs.
reponse = client.post(
"/api/packs/app-mysql/fusionner", json={"project": {"name": "Essai"}}
)
assert reponse.status_code == 200
projet = reponse.get_json()["project"]
assert projet["perimetres"], "aucun perimetre importe"
assert projet["perimetres"][0]["groupe"] == "CG-App-DB-MySQL"
assert projet["prerequis"]["paquets_debian"], "les prerequis du pack sont perdus"
assert projet["host_templates"][0]["perimetre"] == projet["perimetres"][0]["name"]
# Le second pack apporte son propre calendrier sans ecraser le premier.
suite = client.post(
"/api/packs/hw-printer-rfc3805/fusionner", json={"project": projet}
).get_json()["project"]
assert len(suite["perimetres"]) == 2
# MySQL apporte 24x7, reference mais non recree ; l'imprimante son propre
# calendrier, qui sera cree.
assert [c["name"] for c in suite["calendriers"]] == [
"TP-App-DB-MySQL-24x7",
"TP-HW-Printer-RFC3805-Heures-Ouvrees",
]
assert len(suite["host_templates"]) == 2
def test_la_fusion_signale_les_doublons(app):
client = app.test_client()
projet = client.post(
"/api/packs/app-mysql/fusionner", json={"project": {"name": "Essai"}}
).get_json()["project"]
rejoue = client.post("/api/packs/app-mysql/fusionner", json={"project": projet}).get_json()
assert rejoue["ignores"], "un pack importe deux fois doit signaler les doublons"
assert len(rejoue["project"]["perimetres"]) == 1
def test_fusion_d_un_pack_inconnu(app):
reponse = app.test_client().post("/api/packs/inexistant/fusionner", json={"project": {}})
assert reponse.status_code == 404
def test_un_calendrier_du_central_est_reference_sans_etre_recree():
"""Quand l'utilisateur vise un calendrier existant, TP;ADD echouerait dessus."""
projet = Project.from_dict(
{
"calendriers": [
{
"name": "24x7",
"alias": "Livre par Centreon",
"jours": {"monday": "00:00-24:00"},
"creer": False,
}
],
"perimetres": [{"name": "Systeme", "calendrier": "24x7", "contacts": ["hcornet"]}],
"prefix": "ACME-",
}
)
plan = build_plan(projet)
assert not [o for o in plan.ops if o.obj == "TP"]
assert not [o for o in plan.rollback_ops if o.obj == "TP"]
# Il porte le nom du central, donc sans prefixe.
periode = next(
o.import_line() for o in plan.ops if "hostnotifperiod" in o.import_line()
)
assert periode.endswith(";24x7")
def test_un_calendrier_du_central_peut_etre_force():
"""Une installation peut avoir perdu ses calendriers par defaut."""
projet = Project.from_dict(
{"calendriers": [{"name": "24x7", "jours": {"monday": "00:00-24:00"}, "creer": True}]}
)
lignes = [o.import_line() for o in build_plan(projet).ops if o.obj == "TP"]
assert lignes[0].startswith("TP;ADD;24x7;")
assert "TP;setparam;24x7;monday;00:00-24:00" in lignes
def test_un_perimetre_sans_calendrier_retombe_sur_celui_du_central():
"""Plutot que de ne jamais notifier, il vise 24x7 — et l'avertissement le dit."""
projet = Project.from_dict(
{"perimetres": [{"name": "Sans calendrier", "calendrier": "", "contacts": ["hcornet"]}]}
)
assert projet.perimetres[0].calendrier == "24x7"
messages = [i["message"] for i in validate(projet)]
assert any("n'est pas dans le projet" in m for m in messages)
def test_chaque_perimetre_de_pack_a_son_calendrier():
"""Sur les 52 packs, aucun perimetre ne doit pointer dans le vide."""
from enclume.catalog import Catalog
from enclume.packs import pack_to_project
manquants = []
for pack in Catalog("catalog").packs.values():
projet = pack_to_project(pack)
connus = {c.name for c in projet.calendriers}
for perimetre in projet.perimetres:
if not perimetre.calendrier or perimetre.calendrier not in connus:
manquants.append((pack.id, perimetre.calendrier))
assert not manquants, manquants
Loaded 100 of 101 files, more files were not shown because too many files have changed in this diff. Show more