Aller au contenu

Blog ·

Quand NetBox est la source de vérité

Brancher un DCIM externe n’est pas une synchronisation. C’est une décision par champ sur qui tranche, plus une liste de ce que l’on refuse d’importer.

Par Provibr

Un client dont le NetBox fonctionne ne veut pas d’un second inventaire. Il veut que ses racks et ses machines apparaissent dans la plateforme depuis laquelle il opère, et il veut continuer à les modifier à l’endroit que son équipe connaît déjà.

Le mot qu’on y accole d’habitude est « synchronisation », et le mot est le problème. Une synchronisation suppose deux systèmes qui convergent vers une seule vérité. Ce que vous avez en réalité est une question par champ à laquelle il faut répondre à l’avance et par écrit : pour cette colonne, sur cet objet, qui tranche ? Répondez-y une fois d’un haussement d’épaules et vous avez construit un système qui écrase une modification locale délibérée à trois heures du matin, ou qui ignore silencieusement un changement que le client a fait il y a une heure et qu’il croit arrivé.

Voici comment nous y avons répondu, y compris pour les champs où la réponse est non.

Quatre valeurs, et ce ne sont pas des degrés de confiance

Chaque colonne de chaque objet lié porte l’une de quatre valeurs d’autorité, et elles disent quatre choses différentes sur qui tranche plutôt que quatre niveaux de confiance.

Externe. L’autre côté tranche. Le champ est en lecture seule ici et un import l’écrase sans demander. Ce n’est pas une perte de contrôle, c’est l’arrangement dans lequel l’administrateur est entré en connectant le système.

À nous. Nous tranchons, et un import n’y touche pas. C’est l’état de chaque champ d’un objet qui n’est pas lié du tout, et de chaque champ pour lequel le système externe n’a pas d’équivalent.

Verrouillé manuellement. L’autre côté a bien une valeur, et un administrateur l’a délibérément remplacée ici, avec une raison. Une différence est alors un conflit que l’on fait remonter, jamais un écrasement silencieux. C’est la seule des quatre qui ne peut pas apparaître par défaut : quelqu’un la pose.

Dérivé. Personne ne tranche. Cela découle d’autre chose : le fait qu’une machine soit en rack, qu’elle soit rattachée à un service, qu’elle soit prête, la capacité d’un rack, la tenue de compte de la ligne elle-même. Ces valeurs sont structurellement non importables, et un test affirme qu’elles n’apparaissent dans aucune correspondance.

Cette dernière mérite une note. Les champs de tenue de compte, qui a créé une ligne et quand, sont dérivés plutôt qu’à nous. Personne ne choisit ces valeurs, elles découlent de l’action. Un chemin d’import autorisé à écrire un horodatage de création est un chemin d’import qui peut réécrire l’histoire.

L’autorité tient au lien plutôt qu’à l’objet. Un objet sans lien est entièrement à nous, ce qui veut dire que délier est une simple suppression plutôt qu’une migration d’état sur chaque colonne.

Le registre est par colonne, et la liste des colonnes vient du schéma

Chaque colonne des quatre types d’objets pris en charge, les sites, les localisations, les racks et les machines, a une entrée dans un registre. Y compris celles qui n’ont absolument rien à voir avec le système externe.

Cette complétude est imposée et non simplement voulue. Un test dérive la liste des colonnes du schéma de la base de données et exige une décision pour chacune. Une nouvelle colonne ajoutée dans une ronde ultérieure est donc un test rouge plutôt qu’un trou silencieux, ce qui est la même construction que nous utilisons ailleurs : un test par cas ne peut pas, par nature, trouver un cas manquant.

Certaines des décisions sont la partie intéressante.

Le budget électrique d’un rack reste à nous. NetBox modélise l’électricité comme des arrivées, pas comme un chiffre de budget unique. Déduire un nombre de plusieurs arrivées serait une affirmation de capacité assemblée à partir de données incomplètes, ce qui est précisément ce que la conception de la capacité interdit. Le champ n’est donc pas importé, avec cette phrase consignée à côté comme raison.

L’état de processus d’une machine reste à nous. Le statut d’équipement de NetBox mélange cycle de vie et exploitation dans un seul champ. Un équipement marqué en panne pousserait, dans une correspondance naïve, une machine dans un état de maintenance et la sortirait du parc commercialisable. Ce sont deux vocabulaires différents qui se trouvent partager un nom.

Le type d’une machine reste à nous. Le rôle d’équipement de NetBox est du texte libre. Se tromper là ne produit pas une erreur cosmétique, cela change ce que la plateforme vous laissera faire d’une machine.

Chacune de ces décisions est stockée avec une raison écrite, dans la même structure que la décision. Une règle avec une raison attachée survit à la personne suivante ; une règle sans raison est assouplie par quelqu’un qui suppose qu’elle était arbitraire.

À la création seulement, parce qu’il y a des étiquettes dans une boîte

Deux champs sont importés une fois, à la création, et jamais mis à jour : le code d’un site, d’une localisation ou d’un rack, et le code d’inventaire d’une machine.

La raison est physique. Ces valeurs sont imprimées sur des étiquettes, et les étiquettes sont dans une boîte dans un placard. Un slug renommé dans NetBox au printemps prochain ne doit pas envoyer un scan au mauvais endroit. « À la création seulement » n’est pas une troisième valeur d’autorité, c’est une propriété de l’import : la prendre à l’ajout, ne plus y toucher ensuite.

Les mêmes champs sont ceux sur lesquels un objet non lié est apparié quand la connexion est établie pour la première fois : le code pour les trois autres, le code d’inventaire pour les machines. Délibérément pas le nom, parce qu’un code est stable et unique à la casse près, et qu’un nom n’est ni l’un ni l’autre.

L’implantation n’est jamais importée, et aucun champ n’y mène

NetBox connaît, pour chaque équipement, son rack, sa position et sa face. Ces trois-là sont refusés.

Pas ignorés. Refusés, nommément, avec un code de raison, et affichés dans l’aperçu.

Le raisonnement découle directement de la conception de l’occupation : la seule vraie limite à l’occupation d’un rack est un index unique partiel sur la table des emplacements, et cet index n’est jamais touché que par une seule fonction. Un chemin d’import qui écrit un rack et un numéro d’unité sur une machine est un second chemin d’écriture qui ne connaît pas cet index, et un jour une machine est enregistrée dans deux racks avec un système externe qui confirme que c’est correct.

La spécification de cette partie dit qu’une implantation locale ou une affectation active ne doit jamais être effacée par un import. Il y a deux façons de rendre cela vrai. L’une est d’écrire l’import de manière à ce qu’il laisse les affectations tranquilles. L’autre est de rendre impossible à l’import d’écrire une affectation tout court, et c’est celle que nous avons prise : aucun champ n’y mène.

Faire respecter cela est une garde sur l’arbre syntaxique abstrait plutôt qu’un cas de test. Elle lit la source du module d’import et exige que les quatre tables protégées, les affectations, les emplacements, les rattachements de service et les étiquettes, n’apparaissent qu’à l’intérieur d’un select. Un insert, un update ou un delete sur l’une d’elles est rouge même si aucun chemin de code ne l’atteint jamais, parce que la garantie doit tenir pour du code qui n’existe pas encore. Le parcours échoue bruyamment sur une forme qu’il ne reconnaît pas, ce qui est une leçon apprise à la dure dans une garde antérieure qui sautait silencieusement ce qu’elle ne savait pas analyser.

Les refus sont listés nommément dans l’aperçu. L’omission silencieuse est la version dangereuse ici : quelqu’un connecte son NetBox, lit « 142 machines mises à jour », et suppose que la disposition de son rack est venue avec.

Une suppression externe est un tombstone

Un objet lié que l’autre côté cesse de mentionner devient un tombstone avec une revue d’impact, pas une suppression.

Ce n’est pas seulement de la politesse. Une liste qui revient trop courte à cause d’une erreur de filtre, d’un changement de permissions ou d’une page à moitié récupérée viderait sinon l’inventaire d’un client. Le tombstone met l’objet devant une personne, avec ce qui en dépend : un objet qui a une affectation active ne peut pas être retiré du tout, et une fois l’affectation libérée l’issue est une mise hors service plutôt qu’une suppression.

Et si l’on sait que la récupération est tronquée, il ne se passe rien du tout. Aucun tombstone n’est proposé pour quoi que ce soit. Ce que vous n’avez pas vu, vous ne pouvez pas en conclure qu’il manque. C’est une condition de deux lignes et c’est la différence entre un connecteur et un incident.

Ce que nous écririons

  1. Décidez de l’autorité par colonne, pas par objet, et faites venir la liste des colonnes du schéma pour qu’une nouvelle ne puisse pas être oubliée.
  2. Stockez la raison avec la décision. Un champ qui n’est pas importé a besoin d’une phrase, sinon quelqu’un l’importera plus tard.
  3. Rendez l’import dangereux impossible plutôt que prudent. Aucun champ n’y mène, plus une garde qui lit la source.
  4. Nommez ce que vous refusez dans l’aperçu, parce qu’un nombre d’objets mis à jour se lit comme de la complétude.
  5. Traitez l’absence comme une question, jamais comme une suppression, et traitez une récupération tronquée comme aucune information du tout.

Sur notre propre état : ceci est derrière un indicateur de déploiement désactivé par défaut avec un réglage par organisation par-dessus, ce n’est donc pas quelque chose à acheter aujourd’hui, et cela n’a pas tourné contre un vrai NetBox. Ce qui est dit plus haut sur la façon dont NetBox modélise la puissance, les statuts et les rôles vient de sa documentation et de la forme de son interface, pas d’une instance en production. Tout ce qui précède a été mesuré contre un bouchon qui reproduit le comportement de pagination, l’en-tête de version et les objets imbriqués de l’interface réelle, épinglé sur la version d’API que le code de production envoie. Le bouchon offre bel et bien un rack, une position et une face dans ses charges utiles d’équipement, et zéro affectation n’est écrite : le refus est mesuré et non supposé. La question voisine de savoir pourquoi un système externe qui rapporte un succès n’est pas un résultat en soi est dans pourquoi un 200 de Proxmox n’est pas un résultat.

Issu du travail sur les datacenters chez Provibr. La frontière d’occupation dont cet import est tenu à l’écart est décrite dans la seule vraie limite à l’occupation d’un rack, et les étiquettes dont les codes doivent rester stables dans une étiquette qui survit au renommage d’hôte.

Commencez avec un hôte et un agent

Créez un compte, installez l’agent avec une seule commande et connectez votre premier hôte Proxmox. La période d’essai dure 14 jours et ne demande aucune coordonnée de paiement.