d5f09dc91b
Instalador .bat generado en el navegador, casilla para ocultar actualizaciones/drivers/componentes en Software, buscador por pestaña en el detalle, GUIDs como componentes y tokens de ingesta cifrados (migraciones 024 y 025). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
82 lines
4.7 KiB
Markdown
82 lines
4.7 KiB
Markdown
# Arquitectura de inventario — menú "Equipos"
|
||
|
||
Diseño del módulo Equipos de Project. Se trajo de `linkedtrack.linkedcorp.net` (que sigue como
|
||
producto aparte, sin cambios) y se reescribió siguiendo las reglas de Project: mismo login, roles,
|
||
auditoría, UI Fluent y una sola base `project_linkedcorp`.
|
||
|
||
## Decisión de fondo
|
||
|
||
| Opción | Veredicto |
|
||
|---|---|
|
||
| Servidor GLPI completo | Descartado: demasiada administración para solo inventariar. |
|
||
| Agente 100% propio | Descartado: reescribir el sondeo de hardware (WMI, EDID, SNMP) es frágil y caro. |
|
||
| **Agente GLPI oficial + colector propio dentro de Project** | **Elegido.** El agente recolecta; Project recibe, guarda y muestra. |
|
||
|
||
## Flujo
|
||
|
||
```
|
||
GLPI Agent (cada PC/servidor) --POST inventario--> https://project.linkedcorp.net/api/inventory
|
||
(ingest.js: token -> inflar -> parsear JSON/XML
|
||
-> normalizer.js -> upsert por deviceid
|
||
-> diff en device_changes)
|
||
Navegador (superadmin/admin/it_manager) --JWT--> /api/devices -> menú "Equipos"
|
||
```
|
||
|
||
- **Handshake:** el agente primero manda un `contact` (JSON) o `PROLOG` (XML). Se responde sin
|
||
guardar nada (`{"status":"ok","expiration":"24"}` o `<REPLY><RESPONSE>SEND</RESPONSE>…`).
|
||
- **Ingesta autenticada por token**, no por JWT: tabla `inventory_tokens` (solo hash sha256). El
|
||
agente lo manda como contraseña Basic (`user`/`password` del `agent.cfg`), `Bearer`,
|
||
`X-Ingest-Token` o `?token=`. Sin token válido → `401`.
|
||
- **Rutas:** `POST /api/inventory` (propia; pasa por el Custom Location `/api` de NPM sin cambios)
|
||
y alias `POST /front/inventory.php` (ruta nativa de GLPI). Se montan ANTES de `express.json`
|
||
porque usan cuerpo crudo.
|
||
- **Límites:** cuerpo máx. 15 MB (`INVENTORY_MAX_BYTES`), inflado máx. 4× (anti zip-bomb).
|
||
- **Upsert por `deviceid`** (estable), nunca por hostname. Componentes se reemplazan completos en
|
||
una transacción; el diff (RAM, disco agregado/retirado, software instalado/desinstalado, SO,
|
||
hostname) queda en `device_changes`.
|
||
- **Baja lógica:** `status = retired`; un reporte nuevo NO reactiva un equipo dado de baja.
|
||
- **Crudo para depurar:** último reporte por equipo en `storage/inventories/<hash>.json|xml`
|
||
(se sobrescribe; descarga `GET /api/devices/:id/raw`).
|
||
|
||
## Normalización
|
||
|
||
`backend/src/modules/devices/normalizer.js`: el JSON nativo y el XML (en mayúsculas) comparten
|
||
nombres de campo, así que el XML se pasa a minúsculas y ambos usan el mismo mapeo. Todo campo
|
||
ausente queda `null` (el formato varía por versión del agente y SO). Tipo de equipo
|
||
(`desktop/laptop/server/virtual/printer/network/other`) se infiere de `chassis_type`, `vmsystem`,
|
||
nombre del SO e `itemtype`. Lo que no tiene columna (impresoras/red SNMP, antivirus, video,
|
||
batería) se guarda en `devices.extra_json`.
|
||
|
||
## Instalar el agente en un equipo
|
||
|
||
1. Superadmin/admin: menú **Equipos → Agentes → Generar token** (se muestra una sola vez).
|
||
2. En el equipo, instalar GLPI Agent (MSI en Windows; `.deb`/`.rpm`/tarball en Linux) con:
|
||
```
|
||
server = https://project.linkedcorp.net/api/inventory
|
||
user = project
|
||
password = <token>
|
||
tag = <opcional>
|
||
```
|
||
Windows (instalador): `SERVER=… USER=project PASSWORD=<token>`.
|
||
3. Forzar un envío: `glpi-agent --force` (Linux) / "Forzar inventario" en la página del agente
|
||
(`http://localhost:62354`) en Windows. El equipo aparece en **Equipos** al primer POST.
|
||
|
||
## Instalador con un clic (Windows)
|
||
|
||
Equipos → Agentes → "Instalador para Windows": genera `instalar-glpi-agent.bat` en el navegador con
|
||
`SERVER=<origen>/api/inventory`, `USER=project`, `PASSWORD=<token>` y `TAG` opcional. El .bat se
|
||
auto-eleva, descarga `GLPI-Agent-<ver>-x64.msi` de GitHub (versión fijada en
|
||
`frontend/src/pages/Equipos/agentInstaller.js#GLPI_AGENT_VERSION`; o usa el .msi que esté junto al
|
||
.bat), instala con `msiexec /qn` y `RUNNOW=1`, y verifica que el servicio `glpi-agent` corra. El
|
||
token solo se conoce al crearlo, por eso el .bat se genera en la pantalla y no en el servidor.
|
||
Linux: usar el instalador oficial `glpi-agent-<ver>-linux-installer.pl --server=… --user=… --password=…`.
|
||
|
||
## Pendientes / por verificar con un agente real
|
||
|
||
- Confirmar que el agente acepta la respuesta del handshake tal cual (si no, ajustar `ingest.js`).
|
||
- Capturar un JSON real (`glpi-agent --local=/tmp/inv --json`) y contrastar campos con
|
||
`normalizer.js` (hoy basado en el formato documentado del agente).
|
||
- Impresoras/red por SNMP (`netinventory`): solo se guarda lo básico + `extra_json`; falta una
|
||
vista propia cuando haya un caso real.
|
||
- Panel de impresoras con contador de páginas/tóner y export CSV: fase 2.
|