Entités et Lieux dans GLPI : Le Guide Complet

Guide technique des entités et des lieux dans GLPI : la différence entre segmenter les données et cartographier l'espace physique, comment GLPI stocke l'arbre (glpi_entities, sons_cache, is_recursive), le SQL de diagnostic et les pièges de terrain qui n'apparaissent qu'en environnement multi-entités.

Dans cet article7 sections

Les entités et les lieux ressemblent au même "arbre" dans GLPI, mais ils résolvent des problèmes opposés : l'entité segmente les données et les permissions ; le lieu n'est qu'une référence physique. Confondre les deux - ou concevoir la hiérarchie d'entités après que les données sont déjà entrées - est la source de reprises qui coûtent des jours. Ce guide montre comment GLPI stocke ces arbres dans la base, un plan pas à pas pour la structure et les pièges qui n'apparaissent qu'en maintenance d'environnements multi-entités.

Entité, lieu et groupe : qui fait quoi

Avant de créer le moindre nœud, fixez la frontière. Les trois mécanismes organisent GLPI, mais selon des axes différents - et le mauvais choix produit soit une fuite de données, soit une bureaucratie inutile.

MécanismeSegmente la permission ?Hiérarchique ?Ce que l'utilisateur voit désormaisUsage typique
EntitéOui (données et accès)OuiUniquement les données de son entitéFiliale, client MSP, service isolé
LieuNonOuiRien ne change - ce n'est qu'une étiquette physiqueBâtiment, étage, salle, baie, centre de données
GroupePartiel (tickets)OuiTickets attribués à son groupeÉquipe de support, squad, astreinte

Règle empirique de terrain : l'entité est une frontière de confidentialité, le lieu est la carte physique de l'actif, le groupe est la file de travail. Si la question est "qui a le droit de voir ceci", la réponse est presque toujours l'entité - un lieu ne cache jamais rien à personne.

Comment GLPI stocke l'arbre des entités

L'écran Administration > Entités n'est qu'une coquille au-dessus de la table glpi_entities. Chaque ligne pointe vers son parent par la colonne entities_id, garde le chemin complet dans completename et la profondeur dans level. Deux colonnes silencieuses - sons_cache et ancestors_cache - conservent l'arbre pré-calculé sous forme sérialisée ; c'est de là que lisent les filtres de visibilité, pas d'une jointure récursive au moment de la requête.

-- Arbre des entites : parent, niveau et chemin complet
SELECT e.id,
       e.name         AS entite,
       e.completename AS chemin,
       e.level        AS niveau,
       p.name         AS entite_parent
FROM   glpi_entities e
LEFT   JOIN glpi_entities p ON p.id = e.entities_id
ORDER  BY e.completename;

Le completename ("Siège > DSI > Support") est ce qui apparaît dans les sélecteurs et les rapports ; le level accélère les requêtes de visibilité. Retenez ces deux noms : vous auditez l'arbre par completename et GLPI décide la portée par level sans parcourir toute la table.

Héritage : ce qui descend vers les enfants (et ce qui ne descend pas)

Une entité enfant n'hérite pas automatiquement des données de la mère - elle hérite de la configuration marquée comme récursive. Catégories, SLA, règles métier, modèles de notification et lieux portent la paire (entities_id, is_recursive) : pour valoir sur tout l'arbre, l'élément doit se trouver sur l'entité racine (entities_id = 0) avec is_recursive = 1. Créer une catégorie à l'intérieur d'un enfant la piège là, et les sœurs ne la voient pas.

-- Categories ITIL NON partagees sur tout l'arbre
-- (un item global correct a entities_id = 0 et is_recursive = 1)
SELECT id, name, entities_id, is_recursive
FROM   glpi_itilcategories
WHERE  NOT (entities_id = 0 AND is_recursive = 1);

L'erreur courante est de créer une catégorie ITIL "juste pour ce client" et de découvrir ensuite que la moitié de l'exploitation ne la voit pas. En maintenance, nous exécutons cette vérification avant toute mise en production multi-entités : un élément qui devrait être global et n'est pas en (0, récursif) est un bug qui attend le premier ticket.

Pas à pas : concevoir la structure avant les données

  1. Listez les frontières de confidentialité réelles (qui ne DOIT PAS voir quoi). Chaque frontière dure devient une entité ; le reste est un lieu ou un groupe.
  2. Dessinez l'arbre sur papier avec au plus trois niveaux. La profondeur prélève un péage sur chaque sélecteur et rapport.
  3. Créez les entités par l'interface, de haut en bas - jamais par SQL (voir pièges).
  4. Configurez sur la racine ce qui est commun (catégories, SLA, notifications) en cochant is_recursive ; ne descendez vers un enfant que ce qui lui est exclusif.
  5. Ce n'est qu'alors que vous enregistrez utilisateurs, actifs et tickets. Déplacer des données entre entités ensuite coûte cher et entraîne les pièces jointes.

Lieux : la hiérarchie physique et le champ que tout le monde oublie

La table glpi_locations est hiérarchique par son propre locations_id (parent), mais chaque lieu appartient aussi à une entité (entities_id) et possède is_recursive. Un lieu créé dans un enfant n'apparaît pas dans les autres entités sauf s'il est récursif - le même mécanisme que les catégories. Et la valeur 0 dans locations_id n'est pas nulle : c'est la sentinelle "aucun lieu".

-- Ordinateurs sans lieu defini, par entite
SELECT e.completename AS entite,
       COUNT(*)       AS sans_lieu
FROM   glpi_computers c
JOIN   glpi_entities  e ON e.id = c.entities_id
WHERE  c.locations_id = 0   -- 0 = aucun (sentinelle), pas NULL
  AND  c.is_deleted   = 0
GROUP  BY e.completename
ORDER  BY sans_lieu DESC;

Un inventaire sans lieu est le schéma silencieux qui explose au premier incident physique ("dans quelle baie est-il ?"). La requête ci-dessus devient un indicateur d'hygiène de CMDB que nous suivons par entité, pas une surprise en pleine nuit.

Pièges de terrain

Le pire de tous : créer une entité directement dans la base par SQL. La ligne entre, mais sons_cache et ancestors_cache de la mère ne sont pas recalculés - et comme les filtres de visibilité lisent de ces caches, l'entité devient invisible pour getSonsOf(). Le symptôme est cruel : l'entité existe dans la table, apparaît dans un SELECT, mais disparaît des sélecteurs et de l'arbre de l'interface. Nous avons appris à la dure à ne jamais créer d'entité par INSERT : c'est la création par l'écran qui recalcule les caches. Si un import hérité est déjà entré par SQL, la correction consiste à rouvrir et enregistrer chaque entité par l'interface pour forcer la reconstruction de l'arbre.

  • Traiter l'entité 0 comme vide - l'entité racine a id = 0, qui est un id VALIDE. Le code et les intégrations qui testent if (!entities_id) écartent la racine par accident ; dans les composants select2, la valeur de la racine est "" (chaîne vide), jamais "0".
  • Un document qui disparaît quand on déplace un ticket - la pièce jointe (Document_Item) exige que le document soit dans la même entité que le ticket. Déplacer le ticket vers une autre entité sans emporter le document casse l'accès à la pièce jointe.
  • Un lieu partagé sans récursion - créer une baie ou une salle dans un enfant en attendant que le siège la voie : sans is_recursive, chaque entité ne voit que ses propres lieux.
  • Trop d'entités - chaque entité multiplie la configuration (catégories, SLA, notifications, attribution de profil par entité). Dix entités quasi identiques coûtent dix fois la maintenance. Si la seule différence entre deux domaines est un rapport, utilisez un groupe ou un lieu, pas une entité.

Checklist de structure organisationnelle

  1. Cartographiez les frontières de confidentialité avant de toucher à GLPI ; seules celles-ci deviennent des entités.
  2. Plafonnez l'arbre des entités à trois niveaux de profondeur.
  3. Créez les entités par l'interface, jamais par SQL.
  4. Configurez le commun sur la racine avec is_recursive = 1 ; ne descendez que l'exclusif.
  5. Traitez id et locations_id égaux à 0 comme une valeur valide, pas comme vide.
  6. Exécutez les vérifications d'élément global non partagé et d'actif sans lieu avant chaque mise en production.

Besoin de concevoir (ou de sauver) une structure multi-entités sans reprise, ou de géoréférencer vos lieux sur une carte ? NexTool déploie et maintient des environnements GLPI multi-entités avec l'arbre revu de bout en bout, et le module Geolocation place vos lieux sur la carte. Parlez à notre équipe de déploiement et de maintenance.


Révisé par l'équipe NexTool Solutions.

Questions fréquentes

L'entité segmente les données et les permissions : elle définit qui voit quoi (tickets, actifs, utilisateurs) et sert de base aux montages multi-clients et multi-sites. Le lieu n'est qu'une référence physique (bâtiment, étage, salle, baie) et ne cache rien à personne. Une entité peut contenir plusieurs lieux ; un lieu ne contrôle jamais l'accès.

Parce que la table glpi_entities garde l'arbre pré-calculé dans les colonnes sons_cache et ancestors_cache, et les filtres de visibilité lisent de ces caches. Un INSERT direct ne les recalcule pas, donc l'entité devient invisible pour getSonsOf() : elle existe dans la table, apparaît dans un SELECT, mais disparaît des sélecteurs et de l'arbre de l'interface. Créez-la toujours par l'écran Administration > Entités, qui recalcule les caches.

Seulement si le code traite 0 comme vide. L'id 0 est l'entité racine et c'est une valeur VALIDE. Les intégrations qui font if (!entities_id) écartent la racine par erreur. Dans les composants select2, la valeur de la racine est une chaîne vide (""), jamais "0". La même logique vaut pour locations_id = 0, qui signifie 'aucun lieu', pas null.

L'élément doit se trouver sur l'entité racine (entities_id = 0) avec is_recursive = 1. Cette paire (entities_id, is_recursive) est ce qui fait descendre la configuration vers les enfants. Créer la catégorie dans un enfant la piège là et les sœurs ne la voient pas. Avant une mise en production multi-entités, exécutez un SELECT qui liste les éléments globaux qui ne sont pas en (0, récursif).

Non. Cochez is_recursive uniquement quand le lieu est partagé entre entités (par ex. un centre de données central utilisé par plusieurs filiales). Un lieu propre à une entité reste non récursif, pour ne pas polluer les autres. Sans is_recursive, chaque entité ne voit que ses propres lieux.

Besoin d'aide ?