Auteur : PEB Date : 14/07/2014 Licence : GPLv3 Documentation succincte de trigger ================================== Tous les fichiers sont renseignés depuis /usr/scripts. 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. Trigger est le fruit d'une longue et intelligente (quelle modestie) réflexion, et donc nous allons ici décrire son fonctionnement. * 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 des services que chaque hôte gère. Ainsi, gestion/trigger/trigger.py sait, en fonction de l'hôte sur lequel il se trouve, comment il doit se comporter, et ce 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. * Le dossier gestion/trigger/services contient la liste des services existants pour trigger. Le fonctionnement des services sera détaillé ci-après. Fonctionnement des services =========================== "Un service est une classe qui ne sera jamais instanciée" 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]. 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. 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. Ensuite, il faut absolument une méthode regen, et définir changes_trigger. (un dict vide convient) Enfin, si vous avez des questions, posez-les avant, pas après. Pour chaque service, une "file d'attente" rabbitmq est créée ayant le nom trigger-nomdel'hôte-nomduservice, et une clef de routage du type trigger.nomduservice est mise en place pour que les messages envoyés vers trigger.nomduservice soient dispatchés sur l'ensemble des queues 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. 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 trigger.event les modifs qu'il fait, et c'est la librairie elle-même qui gère les envois en son sein. Cela permet aussi d'avoir des définitions de services précises d'un point de vue spécification, et une portabilité plus que correcte de trigger d'un binding vers un autre. (les seules données ldap qui l'intéressent sont les noms des attributs, définis dans le schéma de la base ldap, il faut donc que le binding fournisse ses données avec les mêmes noms)