Implémentation d'un gestionnaire d'événements sommaire.
This commit is contained in:
parent
6c97d6998f
commit
201377528c
12 changed files with 411 additions and 239 deletions
|
@ -1,11 +1,9 @@
|
|||
Auteur : PEB <becue@crans.org>
|
||||
Date : 14/07/2014
|
||||
Date : 09/03/2015
|
||||
Licence : GPLv3
|
||||
|
||||
Documentation succincte de trigger
|
||||
==================================
|
||||
|
||||
Tous les fichiers sont renseignés depuis /usr/scripts.
|
||||
What the fuck is happening?
|
||||
===========================
|
||||
|
||||
Trigger est une sorte de librairie de remplacement de generate et des services
|
||||
dans la base LDAP, qui fonctionnent avec bien trop de délai.
|
||||
|
@ -13,6 +11,18 @@ dans la base LDAP, qui fonctionnent avec bien trop de délai.
|
|||
Trigger est le fruit d'une longue et intelligente (quelle modestie) réflexion,
|
||||
et donc nous allons ici décrire son fonctionnement.
|
||||
|
||||
Mise à jour LDAP : the fuck is happening?
|
||||
=========================================
|
||||
|
||||
Le binding envoit un tuple contenant en première entrée un hash, en deuxième entrée
|
||||
un dico contenant les attributs avant modif par le binding, en troisième entrée un
|
||||
dico contenant les attributs après modif, en quatrième entrée des données additionnelles
|
||||
(inchangées durant tout le processing).
|
||||
|
||||
Documentation succincte de trigger
|
||||
==================================
|
||||
|
||||
Tous les fichiers sont renseignés depuis /usr/scripts.
|
||||
* gestion/trigger/trigger.py est un fichier python qui importe un consumer de
|
||||
la librairie cmb. Il marche de manière asynchrone, c'est-à-dire qu'il attend et
|
||||
traîte les messages un par un. Dans gestion/config/trigger.py, il y a la liste
|
||||
|
@ -21,10 +31,11 @@ et donc nous allons ici décrire son fonctionnement.
|
|||
qu'il doit importer. Par exemple, sur l'hôte dhcp, le seul service présent est
|
||||
dhcp, et donc trigger va aller chercher gestion/trigger/service/dhcp.py, et
|
||||
travailler avec.
|
||||
* gestion/trigger/trigger.py importe une méthode trigger depuis
|
||||
gestion/trigger/host.py. Cette méthode permet d'aller puiser dans une factory
|
||||
portant le nom TriggerFactory les références vers les services utiles. Cela
|
||||
permet ensuite de les régénérer à la volée.
|
||||
* gestion/trigger/trigger.py importe des services, qui sont dans le dossier
|
||||
services, et eux importent une méthode depuis gestion/trigger/host.py, qui leur
|
||||
permet d'enregistrer des triggers. Cette méthode permet d'aller puiser dans une
|
||||
factory portant le nom TriggerFactory les références vers les services utiles.
|
||||
Cela permet ensuite de les régénérer à la volée.
|
||||
|
||||
* Le dossier gestion/trigger/services contient la liste des services existants
|
||||
pour trigger. Le fonctionnement des services sera détaillé ci-après.
|
||||
|
@ -32,56 +43,56 @@ et donc nous allons ici décrire son fonctionnement.
|
|||
Fonctionnement des services
|
||||
===========================
|
||||
|
||||
"Un service est une classe qui ne sera jamais instanciée"
|
||||
Un service est un fichier dans le dossier gestion/trigger/services. Il contient
|
||||
une fonction décorée avec record_service. C'est une fonction qui sera appelée quand
|
||||
trigger recevra une demande sur un serveur fournissant ledit service.
|
||||
|
||||
Un service est la donnée dans un fichier d'une classe portant le nom du fichier
|
||||
(et donc du service). La casse dans le nom de la classe n'importe pas. Cette
|
||||
classe hérite de BasicService, une classe définie dans
|
||||
gestion/trigger/services/service.py. Cette classe s'appuie sur la métaclasse
|
||||
MetaService pour se construire, ce qui permet d'établir un certain nombre de
|
||||
liens entre les méthodes d'une classe représentant un service et des attributs
|
||||
de lc_ldap que l'on souhaite monitorer. La métaclasse et l'ensemble des liens
|
||||
susmentionnés n'ont d'intérêt que pour la partie "transcription des modifs de la
|
||||
base LDAP dans un langage compréhensible par les services".
|
||||
|
||||
Enfin, tout service contient une méthode regen prévue pour régénérer ledit
|
||||
service.
|
||||
|
||||
Les services peuvent ensuite contenir autant de méthodes que souhaitées, dans la
|
||||
mesure où se sont des méthodes de classe ou statiques.
|
||||
|
||||
La variable faisant le lien entre les attributs ldap à monitorer et les
|
||||
fonctions à appeler pour transcrire les changements s'appelle changes_trigger.
|
||||
C'est un dictionnaire dont les clefs sont le nom des attributs ldap à
|
||||
surveiller, et les valeurs des tuples contenant les noms des fonctions à
|
||||
appeler en cas de changement.
|
||||
|
||||
Ces fonctions devront toujours avoir le prototype suivant :
|
||||
@classmethod
|
||||
def toto(cls, body, diff):
|
||||
où body et diff sont gérés et fournis tels quels par le service event. body est
|
||||
un 3-tuple contenant le dn de l'objet ldap modifié, la liste des clefs avant
|
||||
modification, et celle après. diff est un dictionnaire de différences calculé
|
||||
entre body[1] et body[2].
|
||||
Pour que civet sache si un service doit être régénéré, et donc qu'il lui envoie
|
||||
un message, il faut définir un parser. Ces parsers sont contenus dans
|
||||
gestion/trigger/parsers/, et portent le nom du service associé. Ils contiennent
|
||||
au moins une fonction décorée avec record_parser (dont les arguments sont des
|
||||
attributs ldap à surveiller). Quand civet reçoit des modifs des bindings, il regarde
|
||||
pour chaque attribut ayant changé s'ils sont surveillés par des parsers, et le cas
|
||||
échéant demande la régénération des services associés.
|
||||
|
||||
Ajouter un nouveau service
|
||||
==========================
|
||||
|
||||
Pour ajouter un service, il faut créer un fichier adapté dans trigger/services/,
|
||||
puis, définir une classe héritant de BasicService, et respecter quelques règles
|
||||
primordiales.
|
||||
et un dans trigger/parsers/. Il faut écrire des fonctions adaptées (le nom est libre),
|
||||
par exemple, pour un parser :
|
||||
|
||||
Premièrement, ce service sera importé sur chaque machine où il est configuré
|
||||
pour fonctionner, et sur civet dans event.py. Pensez donc une fois le tout
|
||||
configuré à relancer trigger sur civet, et à vérifier que ça marche. La variable
|
||||
de configuration debug dans gestion/config/trigger.py est là pour aider. Parmi
|
||||
les choses importantes, l'idéal est d'avoir des dépendances les plus paresseuses
|
||||
possibles d'un point de vue évaluation. Ainsi, civet qui ne fait qu'importer le
|
||||
fichier et utiliser les fonctions d'analyse listées dans changes_trigger peut
|
||||
éviter de jouer avec ce qui ne le concerne pas.
|
||||
{{{
|
||||
@record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name)
|
||||
def send_mac_ip(body, diff):
|
||||
}}}
|
||||
|
||||
Ensuite, il faut absolument une méthode regen, et définir changes_trigger. (un
|
||||
dict vide convient)
|
||||
body est le message reçu par civet sans transformation. diff est le diff calculé
|
||||
à la volée. Le nom de la fonction n'est pas important. Le décorateur prend les
|
||||
noms d'attributs à surveiller en paramètre. La fonction doit retourner un tuple
|
||||
dont le premier élément est le nom du service à régénérer (par exemple, "dhcp"),
|
||||
et le second les choses que le service devra lire et gérer pour se régénérer.
|
||||
|
||||
Pour un service, voici un exemple :
|
||||
|
||||
{{{
|
||||
@record_service
|
||||
def dhcp(body=None):
|
||||
}}}
|
||||
|
||||
body contient le "body" construit dans un parseur. La fonction est décorée, et
|
||||
son nom est stocké dans la TriggerFactory. Comme souligné précédemment, le nom
|
||||
de la fonction est important, au même titre que le nom des fichiers dans
|
||||
trigger/parsers et triggers/services.
|
||||
|
||||
Il faut ensuite référencer le service dans config/trigger.py pour les serveurs
|
||||
où il est important, et relancer trigger sur ces machines. Lors des tests, il ne
|
||||
faut pas hésiter à passer trigger en debug dans le fichier config/trigger.py.
|
||||
|
||||
Parmi les choses importantes, l'idéal est d'avoir des dépendances les plus
|
||||
paresseuses possibles d'un point de vue évaluation. Ainsi, civet qui ne fait
|
||||
qu'importer le fichier et utiliser les fonctions d'analyse listées dans
|
||||
changes_trigger peut éviter de jouer avec ce qui ne le concerne pas.
|
||||
|
||||
Enfin, si vous avez des questions, posez-les avant, pas après.
|
||||
|
||||
|
@ -94,11 +105,10 @@ trigger-*-nomduservice.
|
|||
Un service spécial
|
||||
==================
|
||||
|
||||
civet est un hôte spécial, qui gère un service spécial : le transcripteur. Le
|
||||
transcripteur est le service event, dans gestion/trigger/services/event.py,
|
||||
qui reçoit des messages sur la queue trigger-civet-event. C'est lui qui,
|
||||
fonction des messages reçus, les répartis tous vers les autres queues avec
|
||||
clef de routage idoine.
|
||||
Le service event est celui qui utilise les parseurs pour savoir quels services
|
||||
doivent être régénérés. Quand il reçoit le body, il fait un calcul des différences
|
||||
entre body[1] et body[2] (les deux dicos), et fournit ces différences aux parseurs,
|
||||
qui lui rendent des messages à envoyer.
|
||||
|
||||
L'intérêt est d'assurer une indépendance maximale entre binding ldap et la
|
||||
librairie trigger : le binding doit juste envoyer avec clef de routage
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue