URL: https://linuxfr.org/users/linkdd/journaux/code-python-en-bdd-avec-canopsis Title: Code Python en BDD avec Canopsis Authors: David Delassus Date: 2016年01月27日T17:07:40+01:00 License: CC By-SA Tags: canopsis, python et mongodb Score: 6 # 1. Introduction Avant de rentrer dans le vif du sujet, une petite présentation de Canopsis s'impose. ![Canopsis Logo](http://www.canopsis.com/wp-content/uploads/2015/01/canopsis-300x113.png) Il s'agit d'une solution d'hypervision sous licence AGPL3, capable d'agréger de nombreuses sources de données afin de les présenter à l'utilisateur, et de lui permettre d'interagir avec de manière standardisée et cohérente. L'architecture du projet, grossièrement simplifiée, se compose des éléments suivants : * des connecteurs récupèrent les données depuis différentes sources (Nagios/Shinken/Icinga/..., jMeter, Sikuli, BDD type SQL, API REST, ...), et les envoient sur un bus de données sous forme d'événement standardisé * des moteurs consomment les événements afin de les traiter et de les stocker de manière cohérente en base de données * une API REST fournit un accès à ces données * un application web complètement personnalisable permet à l'utilisateur de construire ses vues et de décider comment afficher, valoriser et interagir avec ces données Les parties moteurs et API REST sont développées en Python, et c'est ce qui va nous intéresser dans cet article. # 2. Charger le code dynamiquement Du travail est en cours sur ce projet afin de généraliser la modularité du projet. Actuellement, un moteur se présente comme un daemon, et s'implémente en surclassant une classe de base abstraite afin d'implémenter certaines méthodes. C'est certes simple, mais pas suffisamment souple car cela ne permet pas de bien découper le projet quand les fonctionnalités s'additionnent, on se retrouve ainsi avec un paquet python ``engines`` qui fait un peu fourre tout. L'idée était donc de rentre tout cela plus modulaire. Et la solution adoptée fut donc de spécifier dans le fichier de configuration l'implémentation des méthodes. La classe de base (que l'on n'a plus besoin de toucher) va charger le code tel qu'il est spécifié dans la configuration. Un exemple vaut mieux qu'un long discours. Avec ce fichier de configuration : ```ini [engine:myengine] event_processing=canopsis.myfeature.process.event_processing ``` Le moteur saura aller chercher la fonction ``event_processing`` dans le paquet python ``canopsis.myfeature.process``, et l'implémentation se résume à ceci : ```python def event_processing(event, **_): # do something with event ``` Ce système permet donc de mieux découper le code, chaque fonctionnalité apporte ses propres implémentations pour chaque aspect du projet. Cela repose notamment sur un petit utilitaire : ```python from canopsis.common.utils import lookup event_processing = lookup('canopsis.myfeature.process.event_processing') ``` Nous visons a démocratiser dans le projet ce genre d'usage, toujours pour une meilleure découpe, et une meilleure maintenabilité. # 3. Le vif du sujet (enfin) En parcourant un peu le web, je tombe sur un [article](https://nvbn.github.io/2016/01/04/import-from-github/) en particulier. TL;DR: cela présente le mécanisme qui permet d'agrémenter le système d'import de Python avec de nouvelles fonctionnalités (ici un import depuis un dépôt Github). Bon, fonctionnalité un peu risquée dans le cas où le code dépend du bon vouloir d'un inconnu à ne pas supprimer/casser son code. MAIS, le mécanisme présenté peut avoir d'autres usages, c'est donc notre cas. Ici, il est utilisé afin de stocker du code dans une base de données : * document MongoDB * entrée dans une table SQL * ... (avec le système de ``storage``, nous sommes capable de développer un driver pour n'importe quelle base de données) Ce qui permet ainsi de stocker le code des moteurs (et autres à l'avenir) dans MongoDB actuellement : ```json { "_id": "myfeature", "src": "def event_processing(event, **_):\n # do something with event\n" } ``` Et de le référencer dans la configuration : ```ini [engine:myengine] event_processing=canopsis.pyloader.myfeature.event_processing ``` Après cela, nous serons en mesure d'écrire un schéma JSON décrivant le document en base, et ce dernier sera utilisé par l'application web pour générer automatiquement un modèle, utilisable pour faire un listing des morceaux de code présent en base. L'édition du code pourra ainsi se faire depuis l'application web de Canopsis, même si ce n'est pas l'objectif premier, cela permettra de modifier à l'exécution le traitement des données, par le biais de l'API REST. On peut même imaginer une sorte de *pastebin* contenant diverses implémentations, qu'il suffira d'injecter pour tester avant de considérer un merge. # 4. Conclusion Cette fonctionnalité, simple mais efficace, est intégrée à un plus gros chantier (de migration du code utilisant l'ancienne API pour les moteurs, à la nouvelle API plus dynamique), et ne sera donc pas disponible tout de suite. En attendant, on peut toujours suivre l'avancée du projet sur notre [Gitlab](https://git.canopsis.net/explore).

AltStyle によって変換されたページ (->オリジナル) /