12 KiB
🤖 AGENTS.md
# 🤖 AGENTS.md - Network Config Backup Plugin for GLPI 11
> **Documento di contesto per AI Agent / Assistente di sviluppo**
> **Progetto**: `glpi-plugin-netconfig`
> **Ultimo aggiornamento**: 2026-05-22
> **GLPI Target**: 11.0.6+ | **PHP**: 8.2+ | **Database**: MySQL/MariaDB
---
## 🎯 Obiettivo del Progetto
Sviluppare un plugin GLPI 11 che permetta di:
1. **Salvare configurazioni** di apparati di rete (switch, router, firewall) nel database MySQL di GLPI
2. **Tracciare le variazioni** delle configurazioni nel tempo (versioning con hash SHA256)
3. **Visualizzare differenze** (diff) tra versioni successive
4. **Esportare configurazioni** in file di testo (con controllo diritti e redaction credenziali)
5. **Lanciare il recupero configurazioni** tramite massive actions o trigger manuali
6. **Integrare GLPI Agent remoto** per l'esecuzione distribuita del backup via SSH (netmiko/napalm)
---
## 🧠 Contesto Tecnico Chiave
### Stack Tecnologico
| Componente | Versione/Nota |
|------------|--------------|
| GLPI | 11.0.6+ (CLI: `php bin/console glpi:version`) |
| PHP | 8.2+ con strict_types, namespace PSR-4 |
| Database | MySQL/MariaDB, InnoDB, utf8mb4_unicode_ci |
| Composer | 2.7.1+ (cache Packagist OK) |
| Template Engine | Twig 3 (nativo in GLPI 11) |
| Crittografia | `Glpi\Toolbox\Encryption` (AES-256-GCM) |
| Diff Engine | `symfony/diff` ^6.4 |
| HTTP Client | `guzzlehttp/guzzle` ^7.8 (opzionale per agent PHP) |
| Agent Script | Python 3 + netmiko + requests + pyyaml |
### Architettura Plugin
plugins/netconfig/ ├── setup.php # Hook init, versioning, diritti ├── hook.php # Install/uninstall DB ├── composer.json # Dipendenze + autoload PSR-4 ├── install/mysql/install.sql # Schema tabella configs ├── src/ │ ├── Config.php # CommonDBTM: CRUD, massive actions, diff │ ├── Agent/Receive.php # Endpoint API per agent │ └── Api/GlpiApiClient.php # Client REST API GLPI (opzionale) ├── ajax/ │ ├── export.php # Download sicuro configurazioni │ └── agent_receive.php # Fallback endpoint agent ├── templates/config_tab.html.twig # Vista tab GLPI con storico └── locales/ # Traduzioni it_IT/en_GB
### Flusso Dati Principale
[Apparato di Rete] │ ▼ (SSH via netmiko) [GLPI Agent Python] ──(POST JSON)──► [Plugin Endpoint] │ ▼ [Validazione Token + Hash] │ ▼ [Cifratura + Salvataggio DB] │ ▼ [Notifica UI GLPI + Diff]
---
## 🔑 Decisioni Architetturali Critiche
### ✅ Scelte Confermate
1. **Namespace PSR-4**: `PluginNetconfig\` mappato su `src/` (obbligatorio GLPI 11)
2. **Cifratura nativa**: Uso di `Glpi\Toolbox\Encryption` invece di soluzioni custom
3. **Versioning via hash**: SHA256 su contenuto config per rilevamento modifiche
4. **Massive actions native**: Integrazione con sistema GLPI invece di UI custom
5. **Agent remoto Python**: Netmiko per compatibilità multi-vendor (Cisco, HP, Juniper, etc.)
6. **Token-based auth**: `NETCONFIG_AGENT_TOKEN` per validazione richieste agent
7. **Diff lato server**: `symfony/diff` con output HTML sanitizzato per Twig
8. **Export con redaction**: Regex per mascherare password/secret prima del download
### ⚠️ Alternative Valutate e Scartate
| Alternativa | Motivo Scarto |
|-------------|--------------|
| Backup via SSH diretto da PHP (phpseclib) | Scaling problematico, timeout, gestione credenziali complessa |
| Integrazione Oxidized/RANCID via webhook | Overhead infrastrutturale, duplicazione logica versioning |
| Archiviazione config su filesystem invece di DB | Perdita integrazione con ACL/profile GLPI, backup/disaster recovery più complesso |
| Agent in PHP invece di Python | Netmiko/napalm hanno supporto multi-vendor più maturo in Python |
### 🔐 Security by Design
- **Credenziali di rete**: Mai hardcodate. Usare variabili d'ambiente o vault esterno
- **Token agente**: Generato con `openssl rand -hex 32`, rotazione periodica consigliata
- **Cifratura a riposo**: `config_content` cifrato con chiave GLPI (`crypt_key` in config_db.php)
- **Export sicuro**: Controllo `Session::haveRight()` + redaction automatica credenziali
- **API endpoint**: Validazione CSRF per chiamate browser, token per chiamate agent
- **Log sensibili**: Nessun dato di configurazione nei log di sistema
---
## 📡 Endpoint API del Plugin
### POST `/plugins/netconfig/ajax/agent_receive.php`
**Scopo**: Ricevere configurazioni da GLPI Agent remoto
**Request JSON**:
```json
{
"device_id": 123,
"config": "!\nhostname SW-TEST\n...\nend",
"token": "your_secure_agent_token",
"timestamp": "2026-05-22T10:30:00+00:00",
"agent_version": "1.0.0"
}
Response JSON:
{
"status": "ok",
"message": "Configuration saved and versioned"
}
Oppure:
{
"status": "ok",
"message": "No changes detected"
}
Codici HTTP:
200: Successo (controllarestatusnel JSON)400: Payload incompleto401: Token non valido405: Metodo HTTP non consentito500: Errore database/server
🐍 Script Agent Python: Punti Chiave
Configurazione Dispositivi (netconfig_devices.yaml)
devices:
- name: "SW-Core-01"
ip: "10.0.0.1"
platform: "cisco_ios" # Mappatura netmiko
glpi_id: 123 # ID in glpi_networkdevices
username: "${NETCONFIG_DEFAULT_USER}" # Variabile d'ambiente
enable_password: "${NETCONFIG_ENABLE_PASS}"
command: "show running-config"
delay_factor: 2
Gestione Errori Robusta
- Retry logic con backoff per timeout di rete
- Distinzione tra errori di autenticazione (no retry) e timeout (retry)
- Logging strutturato con livelli: INFO per successi, WARNING per retry, ERROR per fallimenti
Ottimizzazioni
- Invio a GLPI solo se hash diverso dall'ultimo salvato (controllo lato client opzionale)
- Pulizia output da caratteri di controllo prima dell'invio
- Supporto per piattaforme multiple tramite mapping
device_type
🔄 Massive Actions Supportate
| Action ID | Etichetta UI | Permesso Richiesto | Comportamento |
|---|---|---|---|
PluginNetconfig\Config:BackupNow |
"Force backup now" | CREATE | Triggera recupero configurazione immediato per dispositivi selezionati |
PluginNetconfig\Config:ExportSelected |
"Export selected" | READ | Genera download file .txt per configurazioni selezionate |
Implementazione: Override di getSpecificMassiveActions() e processMassiveActionsForOneItemtype() in Config.php
🗄️ Schema Database
Tabella: glpi_plugin_netconfig_configs
CREATE TABLE `glpi_plugin_netconfig_configs` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`networkdevices_id` int unsigned NOT NULL DEFAULT '0', -- FK a glpi_networkdevices
`config_content` mediumtext NOT NULL, -- Cifrato AES-256-GCM
`config_hash` char(64) NOT NULL, -- SHA256 hex
`is_encrypted` tinyint NOT NULL DEFAULT '1', -- Flag cifratura
`created_at` datetime NOT NULL, -- Timestamp salvataggio
`users_id` int unsigned NOT NULL DEFAULT '0', -- 0 = system/agent
PRIMARY KEY (`id`),
KEY `networkdevices_id` (`networkdevices_id`),
KEY `created_at` (`created_at`),
KEY `config_hash` (`config_hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Note:
MEDIUMTEXTsupporta config fino a ~16MB (sufficiente per switch/router enterprise)- Indici su
networkdevices_idecreated_atper query efficienti dello storico config_hashindicizzato per rilevamento rapido duplicati
🎨 Integrazione UI GLPI
Tab Personalizzato su NetworkEquipment
- Posizione: Scheda aggiuntiva "Config History" nel form di
NetworkEquipment - Contenuto: Tabella con data, hash abbreviato, utente, azioni (export, diff)
- Diff Visual: Modal dialog con output HTML di
symfony/diff(aggiunte in verde, rimozioni in rosso) - Pulsante Trigger: "Retrieve configuration now" visibile solo a utenti con diritto CREATE
Template Twig (config_tab.html.twig)
- Uso di helper GLPI:
path(),getUserName,__()per traduzioni - Sanitizzazione output diff con
|escape('js')per prevenzione XSS - Responsive design con classi Bootstrap native di GLPI 11
🛠️ Comandi Utili per Sviluppo & Debug
# Verifica ambiente GLPI
php /var/www/glpi/bin/console glpi:version
php /var/www/glpi/bin/console glpi:system:status
# Installazione plugin
cd /var/www/glpi/plugins/netconfig
composer install --no-dev -o
chown -R www-data:www-data .
# Poi: UI GLPI > Configurazione > Plugin > Installa
# Test endpoint agent
curl -X POST http://localhost/glpi/plugins/netconfig/ajax/agent_receive.php \
-H "Content-Type: application/json" \
-d '{"device_id":123,"config":"test","token":"CHANGE_ME"}'
# Log utili
tail -f /var/log/glpi/php-errors.log
tail -f /var/log/glpi_agent_netconfig.log
journalctl -u glpi-netconfig.service -f
# Verifica cifratura DB
mysql -e "SELECT config_content FROM glpi_plugin_netconfig_configs LIMIT 1" glpi_db
# Deve restituire blob cifrato, non testo in chiaro
🚨 Troubleshooting Ricorrenti
| Sintomo | Causa Probabile | Soluzione |
|---|---|---|
symfony/diff not found |
Cache Composer corrotta o minimum-stability mancante | composer clear-cache && composer install -vvv |
| Agent riceve 401 | Token non configurato o mismatch | Verificare NETCONFIG_AGENT_TOKEN in env e payload |
| Config non salvata ma nessun errore | Hash identico all'ultima versione (nessuna modifica) | Controllare log: messaggio "No changes detected" è normale |
| Diff non visualizzato | symfony/diff non installato o autoload non aggiornato |
composer dump-autoload -o |
| Export scarica file vuoto | Permessi insufficienti o config cifrata senza chiave valida | Verificare crypt_key in config_db.php e diritti profilo |
| Massive action non appare | Plugin non attivato o hook non registrato | Controllare setup.php e stato plugin in UI GLPI |
📈 Roadmap Futura (Opzionale)
- Supporto per backup multipli paralleli (queue RabbitMQ/Redis)
- Integrazione con GLPI Notifications per alert su config change
- Plugin settings UI per configurare token, timeout, piattaforme supportate
- Supporto per dispositivi via API REST (non solo SSH)
- Reportistica: grafico frequenza modifiche, compliance check
- Webhook outbound per integrazione con SIEM/ITSM esterni
📚 Riferimenti Ufficiali
- GLPI 11 Developer Documentation
- GLPI Plugin Development Guidelines
- Netmiko Documentation
- Symfony Diff Component
- GLPI REST API Reference
💡 Nota per l'Agent AI: Quando assisti nello sviluppo di questo plugin, priorizza:
- Conformità alle linee guida GLPI 11 (namespace, strict_types, DBConnection)
- Sicurezza (cifratura, validazione input, controllo diritti)
- Performance (query indicizzate, diff calcolato on-demand)
- Manutenibilità (codice commentato, log chiari, configurazione esterna)