# πŸ€– AGENTS.md ```markdown # πŸ€– 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**: ```json { "status": "ok", "message": "Configuration saved and versioned" } ``` Oppure: ```json { "status": "ok", "message": "No changes detected" } ``` **Codici HTTP**: - `200`: Successo (controllare `status` nel JSON) - `400`: Payload incompleto - `401`: Token non valido - `405`: Metodo HTTP non consentito - `500`: Errore database/server --- ## 🐍 Script Agent Python: Punti Chiave ### Configurazione Dispositivi (`netconfig_devices.yaml`) ```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` ```sql 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**: - `MEDIUMTEXT` supporta config fino a ~16MB (sufficiente per switch/router enterprise) - Indici su `networkdevices_id` e `created_at` per query efficienti dello storico - `config_hash` indicizzato 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 ```bash # 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](https://glpi-developer-documentation.readthedocs.io/en/11.0/) - [GLPI Plugin Development Guidelines](https://github.com/glpi-project/glpi/blob/11.0/DEV/PLUGIN.md) - [Netmiko Documentation](https://ktbyers.github.io/netmiko/) - [Symfony Diff Component](https://symfony.com/doc/current/components/diff.html) - [GLPI REST API Reference](https://github.com/glpi-project/glpi/blob/11.0/apirest.md) --- > πŸ’‘ **Nota per l'Agent AI**: Quando assisti nello sviluppo di questo plugin, priorizza: > 1. ConformitΓ  alle linee guida GLPI 11 (namespace, strict_types, DBConnection) > 2. Sicurezza (cifratura, validazione input, controllo diritti) > 3. Performance (query indicizzate, diff calcolato on-demand) > 4. ManutenibilitΓ  (codice commentato, log chiari, configurazione esterna) ```