Entidades e Localizações no GLPI: Guia Completo

Guia técnico de entidades e localizações no GLPI: a diferença entre segmentar dados e mapear o espaço físico, como o GLPI guarda a árvore (glpi_entities, sons_cache, is_recursive), SQL de diagnóstico e as armadilhas de terreno que só aparecem em ambiente multi-entidade.

Neste artigo7 secções

Entidades e localizações parecem a mesma "árvore" no GLPI, mas resolvem problemas opostos: a entidade segmenta dados e permissões; a localização é apenas referência física. Confundir as duas - ou desenhar a hierarquia de entidades depois de os dados já terem entrado - é a origem de retrabalho que custa dias. Este guia mostra como o GLPI guarda essas árvores no fundo de dados, um passo a passo para a estrutura e as armadilhas que só aparecem na sustentação de ambientes multi-entidade.

Entidade, localização e grupo: quem faz o quê

Antes de criar qualquer nó, fixe a fronteira. Os três mecanismos organizam o GLPI, mas por eixos diferentes - e a escolha errada gera fuga de dados ou burocracia sem função.

MecanismoSegmenta permissão?Hierárquico?O que o utilizador passa a verUso típico
EntidadeSim (dados e acesso)SimApenas os dados da sua entidadeFilial, cliente MSP, departamento isolado
LocalizaçãoNãoSimNada muda - é só um rótulo físicoEdifício, piso, sala, bastidor, centro de dados
GrupoParcial (pedidos)SimPedidos atribuídos ao seu grupoEquipa de suporte, squad, piquete

Regra prática de terreno: entidade é fronteira de confidencialidade, localização é o mapa físico do ativo, grupo é a fila de trabalho. Se a pergunta é "quem pode ver isto", a resposta é quase sempre entidade - uma localização nunca esconde nada de ninguém.

Como o GLPI guarda a árvore de entidades

O ecrã Administração > Entidades é apenas uma casca sobre a tabela glpi_entities. Cada linha aponta para o pai pela coluna entities_id, guarda o caminho inteiro em completename e a profundidade em level. Duas colunas silenciosas - sons_cache e ancestors_cache - guardam a árvore pré-calculada em forma serializada; é delas que os filtros de visibilidade leem, não de um JOIN recursivo em tempo de consulta.

-- Arvore de entidades: pai, nivel e caminho completo
SELECT e.id,
       e.name         AS entidade,
       e.completename AS caminho,
       e.level        AS nivel,
       pai.name       AS entidade_pai
FROM   glpi_entities e
LEFT   JOIN glpi_entities pai ON pai.id = e.entities_id
ORDER  BY e.completename;

O completename ("Sede > TI > Suporte") é o que aparece nos seletores e relatórios; o level acelera as consultas de visibilidade. Guarde esses dois nomes: é por completename que audita a árvore e por level que o GLPI decide o âmbito sem percorrer a tabela toda.

Herança: o que desce para as filhas (e o que não desce)

Uma entidade filha não herda dados da mãe automaticamente - herda configuração marcada como recursiva. Categorias, SLA, regras de negócio, modelos de notificação e localizações carregam o par (entities_id, is_recursive): para valer em toda a árvore, o item tem de estar na entidade-raiz (entities_id = 0) com is_recursive = 1. Criar uma categoria dentro de uma filha prende-a ali, e as irmãs não a veem.

-- Categorias ITIL que NAO estao partilhadas para toda a arvore
-- (um item global correto tem entities_id = 0 e is_recursive = 1)
SELECT id, name, entities_id, is_recursive
FROM   glpi_itilcategories
WHERE  NOT (entities_id = 0 AND is_recursive = 1);

O erro comum é criar uma categoria ITIL "só para aquele cliente" e depois descobrir que metade da operação não a vê. Na sustentação, corremos esta verificação antes de qualquer entrada em produção multi-entidade: um item que deveria ser global e não está em (0, recursivo) é um bug à espera do primeiro pedido.

Passo a passo: desenhar a estrutura antes dos dados

  1. Liste as fronteiras de confidencialidade reais (quem NÃO pode ver o quê). Cada fronteira dura torna-se uma entidade; o resto é localização ou grupo.
  2. Desenhe a árvore no papel com no máximo três níveis. A profundidade cobra portagem em cada seletor e relatório.
  3. Crie as entidades pela interface, de cima para baixo - nunca por SQL (ver armadilhas).
  4. Configure na raiz o que é comum (categorias, SLA, notificações) assinalando is_recursive; só desça para a filha o que lhe for exclusivo.
  5. Só então registe utilizadores, ativos e pedidos. Mover dados entre entidades depois é caro e arrasta os anexos.

Localizações: hierarquia física e o campo que todos esquecem

A tabela glpi_locations é hierárquica pelo próprio locations_id (pai), mas cada localização também pertence a uma entidade (entities_id) e tem is_recursive. Uma localização criada dentro de uma filha não aparece nas outras entidades a menos que seja recursiva - o mesmo mecanismo das categorias. E o valor 0 em locations_id não é nulo: é o sentinela "nenhuma localização".

-- Computadores sem localizacao definida, por entidade
SELECT e.completename AS entidade,
       COUNT(*)       AS sem_localizacao
FROM   glpi_computers c
JOIN   glpi_entities  e ON e.id = c.entities_id
WHERE  c.locations_id = 0   -- 0 = nenhuma (sentinela), nao NULL
  AND  c.is_deleted   = 0
GROUP  BY e.completename
ORDER  BY sem_localizacao DESC;

Inventário sem localização é o padrão silencioso que rebenta no primeiro incidente físico ("em que bastidor está?"). A consulta acima torna-se um indicador de higiene de CMDB que acompanhamos por entidade, não uma surpresa a meio da madrugada.

Armadilhas de terreno

A pior de todas: criar uma entidade diretamente no fundo de dados por SQL. A linha entra, mas sons_cache e ancestors_cache da mãe não são recalculados - e como os filtros de visibilidade leem dessas caches, a entidade fica invisível para o getSonsOf(). O sintoma é cruel: a entidade existe na tabela, aparece num SELECT, mas some dos seletores e da árvore da interface. Aprendemos à força a nunca criar entidade por INSERT: é a criação pelo ecrã que recalcula as caches. Se uma importação legada já entrou por SQL, a correção é reabrir e gravar cada entidade pela interface para forçar a reconstrução da árvore.

  • Tratar a entidade 0 como vazia - a entidade-raiz tem id = 0, que é um id VÁLIDO. Código e integrações que testam if (!entities_id) descartam a raiz sem querer; em componentes select2, o valor da raiz é "" (cadeia vazia), nunca "0".
  • Um documento que desaparece ao mover o pedido - o anexo (Document_Item) exige que o documento esteja na mesma entidade do pedido. Mover o pedido para outra entidade sem levar o documento quebra o acesso ao anexo.
  • Uma localização partilhada sem recursão - criar um bastidor ou sala numa filha à espera de que a sede a veja: sem is_recursive, cada entidade só vê as suas localizações.
  • Entidades a mais - cada entidade multiplica a configuração (categorias, SLA, notificações, atribuição de perfil por entidade). Dez entidades quase iguais custam dez vezes a manutenção. Se a única diferença entre duas áreas é um relatório, use um grupo ou uma localização, não uma entidade.

Checklist de estrutura organizacional

  1. Mapeie as fronteiras de confidencialidade antes de tocar no GLPI; só essas se tornam entidades.
  2. Limite a árvore de entidades a três níveis de profundidade.
  3. Crie entidades pela interface, nunca por SQL.
  4. Configure o que é comum na raiz com is_recursive = 1; desça só o exclusivo.
  5. Trate id e locations_id iguais a 0 como valor válido, não como vazio.
  6. Corra as verificações de item global não partilhado e de ativo sem localização antes de cada entrada em produção.

Precisa de desenhar (ou resgatar) uma estrutura multi-entidade sem retrabalho, ou georreferenciar as localizações num mapa? A NexTool implanta e sustenta ambientes GLPI multi-entidade com a árvore revista de ponta a ponta, e o módulo Geolocation coloca as suas localizações no mapa. Fale com a nossa equipa de implementação e sustentação.


Revisto pela equipa NexTool Solutions.

Perguntas Frequentes

A entidade segmenta dados e permissões: define quem vê o quê (pedidos, ativos, utilizadores) e é a base de instalações multicliente e multifilial. A localização é apenas referência física (edifício, piso, sala, bastidor) e não esconde nada de ninguém. Uma entidade pode ter várias localizações; a localização nunca controla o acesso.

Porque a tabela glpi_entities mantém a árvore pré-calculada nas colunas sons_cache e ancestors_cache, e os filtros de visibilidade leem dessas caches. Um INSERT direto não as recalcula, por isso a entidade fica invisível para o getSonsOf(): existe na tabela, aparece num SELECT, mas some dos seletores e da árvore da interface. Crie-a sempre pelo ecrã Administração > Entidades, que recalcula as caches.

Só se o código tratar 0 como vazio. O id 0 é a entidade-raiz e é um valor VÁLIDO. Integrações que fazem if (!entities_id) descartam a raiz por engano. Em componentes select2 o valor da raiz é cadeia vazia (""), nunca "0". A mesma lógica vale para locations_id = 0, que significa 'nenhuma localização', não nulo.

O item tem de estar na entidade-raiz (entities_id = 0) com is_recursive = 1. Esse par (entities_id, is_recursive) é o que faz a configuração descer para as filhas. Criar a categoria dentro de uma filha prende-a ali e as irmãs não a veem. Antes de uma entrada em produção multi-entidade, corra um SELECT que liste os itens globais que não estão em (0, recursivo).

Não. Assinale is_recursive apenas quando a localização for partilhada entre entidades (ex.: um centro de dados central usado por várias filiais). Uma localização específica de uma entidade fica sem recursão, para não poluir as outras. Sem is_recursive, cada entidade só vê as suas próprias localizações.

Precisa de ajuda?