Deuxième partie : comment Combodo s’est organisé pour s’adapter au modèle STS-LTS
Dans l’article précédent, vous avez pu appréhender les nombreux avantages à combiner des versions Long-term et Short-term support : être flexible et évolutif tout en garantissant de la stabilité à nos clients, minimiser les coûts de support et de développement tout en garantissant la meilleure qualité de service.
Mais avant d’arriver à la mise à disposition de cette première version LTS, la 2.7, nous avons dû repenser un certain nombre de choses dans notre organisation interne. Ce projet a fait faire un pas en avant aux équipes de Combodo, et nous allons voir dans cet article comment nous nous sommes organisés pour relever le défi.
Un projet de développement ambitieux
Comment réaliser la première version LTS de l’histoire de Combodo ? Voilà un projet bien ambitieux, et comme nous l’expliquions dans le précédent volet, soumis à des contraintes contradictoires…
Ce projet s’est étalé sur un peu plus d’un an, mobilisant plusieurs équipes au sein de Combodo. Quelques chiffres résument bien cette année de développement :
- Début des développements : mars 2019
- Backlog : 275 demandes en mars 2019, et environ 400 en juillet 2019… pour finalement terminer à 240 demandes effectivement réalisées fin mars 2020… on peut dire qu’il a évolué très vite, et qu’il a fallu s’adapter.
- Date de sortie :
- Objectif initial de sortie de la LTS décembre 2019
- Date de sortie décalée une première fois à fin février 2020 (décidé en décembre 2019)
- Nouveau décalage à fin mars 2020 (décidé en janvier 2020)
- Sortie effective de la version 2.7.0 le 1er avril 2020
Changer l’organisation pour optimiser la qualité !
Face à nos ambitions, nous avons revu notre manière de travailler au fur et à mesure que le projet avançait.
Suivi de projet
Les rétrospectives effectuées sur les précédentes version d’iTop nous ont montré l’augmentation des demandes au cours du temps. Vu la dimension du projet, nous avons décidé de mettre en place un suivi hebdomadaire du backlog : cela nous a permis d’identifier rapidement les dérapages et d’agir en conséquence pour limiter les retards.
Confinement et Covid-19
Comme le monde entier au début de l’année 2020, nous avons subi l’épidémie de COVID-19 et du jour au lendemain, toute notre organisation a due être changée. Nous aimons faire de la programmation en paire et les revues de code, et nous avons découvert les avantages et inconvénients du télétravail :
- ➕ Nous étions moins soumis aux distractions de la vie de bureau donc nous pouvions nous concentrer sur le code.
- ➖ Passer de l’oral à l’écrit (et donc à l’asynchrone) a généré des tensions entre les équipes notamment entre l’équipe de développement et l’équipe produit : disponibilité, prise en compte des demandes, temps de réponse…
- ➖ A distance il est bien plus difficile de s’assurer de l’alignement de chacun sur la même compréhension… Quand tout le monde est dans les mêmes locaux, il suffit bien souvent de simplement se déplacer pour parler à l’ensemble des membres de l’autre équipe.
🤔 Ce changement de fonctionnement subi par les équipes, ajouté au retard par rapport au planning initial a nécessité de la souplesse, afin de trouver la meilleure façon de fonctionner.
Nous avons donc cherché les outils adaptés (chat et visio : à terme Combodo a adopté Rocket Chat) et échangé sur la manière de bien les utiliser, afin de garantir un fonctionnement validé par tous.
Pair programming
En vue d’améliorer la qualité du code de l’application, la programmation à deux personnes (pair programming ou peer programming) a été généralisée. Il y a plusieurs avantages à cette pratique :
- Comme les deux développeurs ont une vue différente, le code est de meilleure qualité (mieux structuré, plus maintenable) : l’un (celui qui est au clavier) a une vue tactique du code, et l’autre a une vue stratégique.
- La revue de code qui s’effectue au moment du codage est plus pertinente que celle effectuée à posteriori.
- Transfert de compétences : la maintenance est facilitée par le fait que deux développeurs connaitront bien cette partie du code qu’ils ont conçue et modifiée.
Cette pratique a aussi quelques inconvénients :
- Le démarrage est toujours un peu plus long, puisque les deux développeurs doivent s’accorder sur la marche à suivre pour le développement et apprendre le fonctionnement de la partie de code qu’ils ont à modifier.
- Il faut trouver des paires de développeurs qui se complètent bien et se font confiance (pas forcement facile dans les petites équipes)
- La mobilisation de deux développeurs sur le même sujet réduit la quantité de projets que l’équipe peut mener en parallèle.
Mais pour nous les bénéfices ont largement supplanté ces quelques inconvénients. Cette méthode a donc été définitivement adoptée.
Revues de code
Nous avons mis en place également des revues de code à postériori. C’est un exercice qui n’est pas forcément simple.
iTop étant une application vaste, il est difficile pour les développeurs de connaitre l’ensemble de la base de code, ou simplement d’évaluer l’impact d’une modification sur l’ensemble de l’application. Cependant, toute l’équipe travaillant sur cette version au même moment, l’émulation permet de trouver des connexions entre des sujets (fonctionnels comme techniques) connexes.
Cela a été l’occasion de commencer à créer des pull request internes afin de faciliter ce travail de revue, et de permettre une intégration meilleure de la fonctionnalité dans l’historique Git. Sur cette version 2.7.0 16 pull request internes ont ainsi été intégrées !
Tests automatisés
Avec le développement de la version 2.7, les tests PHPUnit qui étaient balbutiants chez Combodo ont connu un essor important puisque l’on est passé de quelques dizaines de tests à plusieurs milliers !
De plus les tests qui étaient seulement manuels jusque là ont été automatisés à l’aide de Jenkins et sont lancés à chaque commit pour une partie d’entre eux, et quotidiennement pour l’ensemble.
Pour compléter ces tests PHPUnit (qui couvrent essentiellement des fonctions du cœur d’iTop), des tests de l’interface graphique ont aussi été réalisés à l’aide de Behat et également exécutés quotidiennement.
Cette couche bien plus importante de tests a grandement facilité la vie et donné confiance à l’équipe qualité en charge de la validation du produit.
Prévoir le futur
Une fois cette organisation mise en place, il faut la pérenniser, et il faut également anticiper le futur et les évolutions notamment technologiques qui font partie des challenges importants d’une LTS.
Plage de compatibilité PHP
Le calendrier des versions supportées de PHP évoluant vite, il faut concilier des aspects contradictoires :
- Permettre à une majorité de clients de pouvoir basculer sur notre version LTS sans avoir à mettre à jour leur infrastructure, et donc supporter une version minimale assez basse
- Ne pas choisir une version minimale trop basse considérant que vu le rythme de développement de PHP, nombre de librairies que nous embarquons dans iTop allaient sans doute monter leur version minimale supportée rapidement
- Supporter la version la plus récente de PHP
En conséquence, nous avons retenu une plage allant de PHP 5.6 comme version minimale à 7.4 comme version maximale.
MySQL 8
La sortie de MySQL 8.0 a aussi fait planer un doute sur les performances d’iTop puisqu’une des modifications importantes de cette version était la suppression du cache de requêtes. Nous avons considéré qu’implémenter un cache de requêtes SQL dans iTop était en dehors du périmètre de l’application, mais nous avons malgré tout rendu iTop compatible avec cette version !
Nous avons ainsi dû intervenir sur plusieurs aspects :
- Les noms de colonnes toujours renvoyés en majuscule à partir de MySQL 8 (auparavant, c’était avec la casse utilisée dans la clause SELECT)
- Mauvaise détection de mysqldump : on contrôlait la version du programme pour valider le support de utf8mb4 (charset généralisé en iTop 2.5.0) et ce code n’était plus fonctionnel avec MySQL 8… Nous utilisons maintenant la version de la base de données plutôt que celle de l’outil
- Génération de valeurs en double dans Ticket.ref : le système s’appuyait sur la valeur d’incrémentation automatique, mais celle-ci est mise en cache dans MySQL8… Nous avons donc mis en place un nouveau système avec un compteur générique ItopCounter.
Les incompatibilités ayant été corrigées, nous avons mené des tests de performance qui ont confirmé l’impact très négatif de la disparition du cache de requêtes.
En conséquence une communication spécifique a été faite pour prévenir nos utilisateurs sur ces problèmes de performances avec MySQL 8, et leur conseiller de privilégier une version antérieure du serveur de base de données.
Gestion des dépendances
iTop embarque plusieurs librairies PHP. Ces librairies étaient auparavant gérées manuellement. La version LTS étant planifiée pour durer plus longtemps il nous a fallu un mécanisme efficace pour gérer les failles de sécurité et bug dans ces librairies. Nous avons naturellement choisi Composer, un outil très répandu dans le monde PHP et qui a fait ses preuves.
Nous avons ensuite mené un travail d’inventaire, puis pour chaque librairie vérifié s’il y avait lieu de la mettre à jour.
La présence du fichier composer.json dans notre dépôt nous apporte de l’efficacité grâce au support par notre outil de développement PHPStorm, et assure également de ne pas manquer d’informations importantes grâce à l’outil Dependabot intégré à GitHub.
Nous avons aussi adapté nos processus pour ajouter, avant chaque version majeure, une nouvelle phase « fondations » incluant en particulier la vérification des librairies et leur mise à jour.
Silex vers Symfony
Nous avons dû remplacer la librairie Silex (arrivée en fin de maintenance en juin 2018) par Symfony. Cette nouvelle librairie a aussi un calendrier de support calqué sur PHP. Nous étions donc limité sur la version Symfony utilisable dans iTop 2.7.0.
Silex a donc été remplacée par Symfony 3 tout en prévoyant le passage à Symfony 4 et 5.
Politique de dépréciation / suppression des API
Une bonne partie du code d’iTop est constitué d’API : effectivement, les créateurs d’extensions utilisent beaucoup de nos classes et méthodes ! Or si l’équipe de développement Combodo a besoin de pouvoir restructurer parfois le code de iTop, il faut aussi garantir de la stabilité à ces développeurs, et faciliter les migrations des extensions.
Nous avons donc mené plusieurs chantiers :
- clairement identifier les classes et méthodes qui sont des API (avec le tag phpdoc @api) et celles qui ne doivent pas être utilisées ailleurs que dans le code iTop (@internal)
- automatiser la documentation de ces API : cela a été fait avec quelques scripts, et publié sur le wiki
- lorsqu’une partie de l’API doit être modifiée, avoir une politique solide de dépréciation / suppression : l’ancien code reste présent dans la version N mais est marqué comme étant déprécié, et il sera supprimé dans une version ultérieure
Les méthodes dépréciées sont marquées avec le tag phpdoc @deprecated, avec l’indication de la version de iTop où cela a été fait et autant que possible une indication sur le code à utiliser à la place. Pour chacune des dépréciations, un ticket de suppression est saisi et planifié pour une des prochaines versions d’iTop. L’ensemble est documenté dans les notes de migration (exemple pour la 2.7.0 dans un chapitre du What’s new, et pour la 3.0.0 dans une page dédiée).
Par exemple la documentation de la méthode \DBObject::DBInsertTracked a été modifiée pour iTop 2.7.0 :
/** * @internal * * @deprecated 2.7.0 N°2361 simply use {@see DBObject::DBInsert()} instead, that will automatically create and persist a CMDBChange object. * If you need to persist your own, call {@see CMDBObject::SetCurrentChange()} before. * * @param CMDBChange $oChange * * @return int|null * @throws CoreException */ public function DBInsertTracked(CMDBChange $oChange)
Et cette méthode DBObject::DBInsertTracked a été supprimée en 3.0.0 (commit 80161b9).
Améliorer la sécurité, maintenant et demain !
Audit de sécurité
Plusieurs de nos clients avaient fait réaliser un audit de sécurité par un cabinet externe pour leur propre version d’iTop et nous avaient remonté quelques failles.
Nous avons pris la décision de faire réaliser un audit de sécurité sur la version beta de la 2.7.0 pour identifier et aider à la correction du maximum de failles avant la sortie officielle de iTop 3.0.0.
Public security policy
Afin que les failles soient remontées au plus vite et corrigées le mieux possible, nous avons aussi défini ensemble puis publié notre politique de sécurité sur nos dépôts GitHub (pas exemple ici sur iTop).
Les failles sont publiées 3 mois après la sortie de la première version contenant la correction afin de permettre à nos utilisateurs et clients de mettre à jour leurs instances. La publication est effectuée par le biais de GitHub security advisories et de CVE.
L’audit de sécurité et la remontée des failles grâce à la politique mise en œuvre ont permis de corriger 30 problèmes de sécurité sur la version 2.7.0.
Extension Brute force protection
Cette extension a été ajoutée aux packages souscription (iTop Professional et Essential) pour protéger l’application des attaques par force brute sur les mots de passe. C’est en effet une attaque connue sur les application web accessibles sur internet.
Une attaque par force brute est ainsi définie par Wikipedia :
L’attaque par force brute est une méthode utilisée en cryptanalyse pour trouver un mot de passe ou une clé. Il s’agit de tester, une à une, toutes les combinaisons possibles.
.Source https://fr.wikipedia.org/wiki/Attaque_par_force_brute
L’extension limite le nombre d’essais possibles pour la connexion, ce qui empêche ce type d’attaque. Elle propose aussi de nombreuses autres protections (filtrage par IP, captcha, …) comme l’indique sa documentation.
Password policy
Pour compliquer encore le travail des hackers, il ne faut pas autoriser les utilisateurs de l’application à avoir des mots de passe trop courts ou trop simples. L’authentification locale a été modifiée pour permettre de contrôler les mots de passe et éviter la validation de mots de passe trop simples et non sécurisés. Plus de détails dans le What’s new iTop 2.7.0 : Password Policy
Fonctionnalités
Certaines fonctionnalités devaient être réalisées absolument dans cette LTS. Effectivement il nous fallait :
- rendre la maintenance et le support les plus simples possible,
- assurer la meilleure des intégrations aux SI des utilisateurs,
- proposer toutes les API pour les auteurs d’extension.
Voici ci-dessous quelques exemples de fonctionnalités réalisées pour remplir ces objectifs :
Extensibilité login
Puisque cette version est prévue pour durer, il a fallu prévoir l’extensibilité de certaines parties. La page de connexion a fait parti des améliorations apportées à la version 2.7.0.
Nous avons ajouté les fonctionnalités suivantes :
- Passage de la page de connexion sous un format Twig ce qui permet d’en modifier l’aspect visuel.
- Restructuration de la logique de connexion pour permettre l’ajout de nouveaux types de connexion (SSO notamment avec OAuth)
- Permettre de nouveaux contrôles pour la sécurité (comme Brute Force Protection contre les attaques de force brute)
- Permettre d’ajouter plus tard des contrôles de connexion comme le 2FA ou les captchas
Supportabilité
Pour pouvoir assurer le support de la version LTS pendant un temps assez long, il faut que l’équipe support ait des outils intégrés à iTop pour leur permettre de gagner en efficacité. Un effort tout particulier a été fait dans ce domaine.
- Log management permet aux clients qui appellent le support d’accéder aux logs de l’application directement depuis iTop (et même de les envoyer à Combodo) sans avoir à se connecter au système comme dans les précédentes versions.
- System information permet d’accéder à l’état de l’application et aux paramètres importants du système, il est même possible de récupérer un rapport à envoyer à l’équipe support de Combodo.
- Database integrity permet de contrôler l’intégrité de la base de donnée pour éviter les dysfonctionnements de l’application.
- Application Upgrade permet de faire les mises à jour des versions mineures de manière contrôlée directement depuis l’application. Cela facilite l’adoption des versions mineures (de maintenance) de la LTS par les clients. Il est important pour Combodo que les clients soient le plus possible dans la version la plus récente de la LTS pour diminuer les demandes à l’équipe support.
Performance
Génération SQL
L’application iTop utilise, pour manipuler les données du client, un langage de requêtes propre à iTop, l’OQL (Object Query Language). Ce langage permet d’accéder au données en effectuant des requêtes sur les objets à la manière du langage SQL. Le cœur d’iTop convertit ensuite l’OQL en SQL pour effectuer les traitements attendus par l’utilisateur.
Avant iTop 2.7, le mécanisme utilisé pour la génération de ces requêtes SQL garantissait la cohérence des données remontées dans les résultats, ce qui était rassurant pour l’utilisateur, mais au prix de performances dégradées. Nous devions faire face aux questions de nos clients au moindre soucis de performance.
Cette partie de l’application a été revue avec comme objectifs d’améliorer la maintenabilité, grâce à une architecture plus explicite, et la performance de la génération des requêtes SQL, avec un gain en nombre de jointures (pouvant se monter à plusieurs dizaines sur les opérations de dénombrement).
Le choix de l’optimisation s’est fait au détriment de la garantie de cohérence des résultats, puisque les requêtes ne vont plus chercher exhaustivement dans toutes les tables composant les objets du modèle de données du client, mais seulement les tables nécessaires à la réponse. Malgré tout, même si les optimisations dépendent grandement de la complexité des requêtes OQL, un gain important sur l’exécution des requêtes en base a été constaté.
Ce compromis entre la performance et la cohérence des résultats, a été fait en sachant qu’un outil de contrôle de cohérence de la base « Database integrity » était fourni en standard dans l’application.
Ce changement a été rendu possible par l’ajout de tests unitaires qui ont permis de garantir que le comportement (le résultat des requêtes) était identique à la version 2.6.
Conclusion
En faisant ici la liste de toutes les évolutions à la fois sur notre organisation, nos méthodes, mais également les choix techniques concernant la solution réalisés pour la Long-term Support, nous réalisons facilement l’impact d’un tel projet sur les équipes Combodo et la solution iTop.
iTop 2.7 fonctionne donc depuis 2 ans désormais, seule LTS en parallèle des versions STS comme iTop 3.0 et utilisée par plus de la moitié de nos clients. Après tout ce temps, il nous a semblé utile de terminer cette série d’articles par un retour d’expérience sur le déploiement et le fonctionnement à postériori, en vue de préparer les prochaines versions d’iTop.
Le dernier article de cette série vous permettra de faire le point comme nous et de mettre en perspective les résultats de ce projet pour le futur.