From 9ef0a5dcf9e00f42b53edf3867f841b8ca5ac1ef Mon Sep 17 00:00:00 2001 From: mariano Date: Fri, 22 May 2026 14:20:21 +0200 Subject: [PATCH] change before saturday --- Documento 2 non salvato | 98 +++++++ Documento 3 non salvato | 625 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 723 insertions(+) create mode 100644 Documento 2 non salvato create mode 100644 Documento 3 non salvato diff --git a/Documento 2 non salvato b/Documento 2 non salvato new file mode 100644 index 0000000..8a6e6e4 --- /dev/null +++ b/Documento 2 non salvato @@ -0,0 +1,98 @@ +Ecco una proposta architetturale e implementativa per un plugin GLPI 11 dedicato al backup e versioning delle configurazioni di rete, strutturata secondo le linee guida ufficiali degli sviluppatori GLPI (PHP 8.2+, namespace PSR-4, Twig 3, API REST, hook moderni). +🧱 1. Architettura del Plugin +12345678910111213141516171819 +🗄️ 2. Schema Database (MySQL/MariaDB) +GLPI 11 usa InnoDB con charset utf8mb4. Il plugin creerà: +sql +12345678910111213 +networkdevices_id punta a glpi_networkdevices +is_encrypted indica se il contenuto è cifrato con Glpi\Toolbox\Encryption +Il versioning si ottiene confrontando config_hash all'arrivo di un nuovo backup +🔐 3. Gestione Profili e Diritti (GLPI Native) +Il plugin si integra con il sistema dei profili di GLPI senza reinventare l'ACL. +src/Config.php +php +123456789101112131415161718192021 +setup.php +php +1234567891011 +I diritti vengono esposti automaticamente in Amministrazione > Profili. +⚡ 4. Massive Actions +GLPI 11 supporta le massive actions tramite hook e metodi nativi. +hook.php +php +123456789 +Nella classe Config: +php +1234567891011121314151617181920 +🌐 5. Recupero Configurazione: Agent GLPI vs Alternative +✅ Opzione Richiesta: GLPI Agent Remoto +GLPI Agent (ex FusionInventory) supporta task personalizzate in Python/Perl. +Flusso consigliato: +Il plugin espone un endpoint API: POST /api.php/plugin/netconfig/receive +L'agent esegue un task netconfig_backup (Python con netmiko/napalm o expect) +L'agent invia JSON: {"device_id": 12, "config": "...", "checksum": "sha256..."} +GLPI valida, confronta hash, cifra se necessario, salva e registra versione +Endpoint API (src/Agent/Task/Backup.php) +php +123456789101112131415161718192021222324252627282930 +⚠️ Considerazioni Critiche sull'Agent +GLPI Agent non è nativamente progettato per backup di rete. Richiede sviluppo di un modulo custom (Python) con gestione timeout, fallback, credential secure (vault/keystore). +Alternative più solide in produzione: +Oxidized + webhook verso GLPI API +RANCID/Unconfigured + cron + import CSV/API +GLPI + phpseclib3 (SSH diretto, ma sconsigliato per scaling/sicurezza) +💡 Raccomandazione: Usa l'agent per trigger e orchestrazione, ma delega il retrieval a netmiko/napalm in esecuzione sull'agent stesso. Mantieni le credenziali nel sistema di secrets dell'agent o in GLPI cifrate. +📜 6. Tracciamento Variazioni e Diff +Ogni backup viene hashato (SHA256) +Se l'hash differisce dall'ultimo, si crea nuova riga +Per visualizzare il diff: usa symfony/diff o myclabs/php-diff +Esempio integrazione Twig: +twig +12345 +Nel controller: +php +12345 +📥 7. Esportazione Sicura +Verifica diritti: Session::haveRight(Config::class, READ) +Stream diretto con header corretti +Rimuovi/cripta password sensibili prima dell'export (opzionale ma consigliato) +ajax/export.php +php +1234567891011121314 +🛣️ 8. Roadmap di Sviluppo +Fase +Attività +Tempo Stimato +1 +Scaffold plugin, setup/hook, schema DB, migration +2 gg +2 +CRUD Config, integrazione menu, template Twig +3 gg +3 +Diritti profili, massive actions, API endpoint +2 gg +4 +Logica hash, versioning, diff HTML +2 gg +5 +Export sicuro, cifratura, test unitari +2 gg +6 +Modulo Agent GLPI (Python) o integrazione Oxidized +3-5 gg +7 +Documentazione, package, test GLPI 11 QA +2 gg +⚠️ Note Critiche per GLPI 11 +Namespace PSR-4 obbligatorio: PluginNetconfig\ mappato su src/ +Cifratura: Usa Glpi\Toolbox\Encryption (AES-256-GCM) con chiave in GLPI_CONFIG_DIR/config_db.php o variabile d'ambiente +API REST: GLPI 11 richiede dichiarazione esplicita degli endpoint plugin via add_api_endpoint o routing custom +Performance: Configurazioni switch/router possono superare 500KB. Usa MEDIUMTEXT e indicizza per ricerca +Sicurezza: Non esporre endpoint /ajax/retrieve.php senza CSRF+token. Preferisci l'agent o l'API con autenticazione app token +Compatibilità: Dichiara in setup.php: $PLUGIN_HOOKS['compatible']['netconfig'] = ['glpi' => '>=11.0']; +📦 Dipendenze Composer Consigliate +json +123456789101112 + diff --git a/Documento 3 non salvato b/Documento 3 non salvato new file mode 100644 index 0000000..88fa40b --- /dev/null +++ b/Documento 3 non salvato @@ -0,0 +1,625 @@ +# 🤖 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) +``` + +--- + +# 🧠 MEMORY.md + +```markdown +# 🧠 MEMORY.md - Knowledge Base Progetto NetConfig Plugin + +> **Scopo**: Memoria persistente delle decisioni, contesto e apprendimenti per il team di sviluppo +> **Progetto**: GLPI 11 Plugin - Network Configuration Backup & Versioning +> **Stato**: ✅ Specifica Completa | 🚧 Implementazione Pronta | 🧪 Test in Corso + +--- + +## 📋 Riepilogo Richieste Utente + +### Richiesta Originale (Tradotta e Strutturata) +``` +"Vorrei implementare un plugin per GLPI 11 secondo le linee guida degli sviluppatori GLPI per: +1. Salvare configurazioni di apparati di rete (es. switch) nel database MySQL +2. Tenere traccia delle variazioni della configurazione (versioning) +3. Implementare massive actions (azioni di massa) +4. Gestire i profili come già integrato in GLPI (ACL native) +5. Permettere l'esportazione in file di testo del contenuto salvato (solo per utenti con diritti) +6. Lanciare il comando per recuperare la configurazione dall'apparato di rete +7. Valutare l'utilizzo di un agent GLPI remoto per eseguire il recupero configurazione +8. Fornire una proposta architetturale completa" +``` + +### Vincoli Espliciti +- ✅ GLPI 11.0.6+ (verificato con `php bin/console glpi:version`) +- ✅ PHP 8.2+ con strict_types e namespace PSR-4 +- ✅ MySQL/MariaDB con charset utf8mb4 +- ✅ Integrazione con sistema profili/diritti nativo GLPI +- ✅ Massive actions compatibili con UI GLPI +- ✅ Cifratura configurazioni sensibili +- ✅ Agent remoto opzionale ma preferito per scalabilità + +--- + +## 🗂️ Decisioni Architetturali Confermate + +### ✅ Scelte Definitive +| Area | Decisione | Motivazione | +|------|-----------|-------------| +| **Struttura Plugin** | PSR-4 autoload, `src/` per classi, `ajax/` per endpoint | Conformità linee guida GLPI 11, manutenibilità | +| **Database** | Tabella dedicata `glpi_plugin_netconfig_configs` con MEDIUMTEXT | Isolamento dati, performance query, supporto config grandi | +| **Versioning** | SHA256 hash + confronto all'arrivo nuovo backup | Rilevamento modifiche efficiente, storage ottimizzato | +| **Cifratura** | `Glpi\Toolbox\Encryption` (AES-256-GCM) | Integrazione nativa, chiave gestita da GLPI, compliance | +| **Agent Remoto** | Python + netmiko + YAML config + systemd timer | Supporto multi-vendor maturo, gestione timeout/retry robusta | +| **Diff Visual** | `symfony/diff` con output HTML sanitizzato per Twig | Libreria mantenuta, output sicuro, integrazione semplice | +| **Export** | Stream diretto con redaction regex + controllo diritti | Performance, sicurezza, compliance policy aziendali | +| **API Endpoint** | POST JSON con token + validazione hash lato server | Stateless, compatibile con agent distribuiti, auditabile | + +### ❌ Alternative Scartate (con Motivazione) +| Alternativa | Motivazione Scarto | +|-------------|-------------------| +| SSH diretto da PHP (phpseclib) | Timeout frequenti, gestione connessioni concorrenti complessa, scaling limitato | +| Archiviazione su filesystem | Perdita integrazione ACL GLPI, backup/disaster recovery più complesso, audit difficile | +| Integrazione Oxidized/RANCID | Overhead infrastrutturale aggiuntivo, duplicazione logica versioning, curva apprendimento team | +| Agent in PHP invece di Python | Netmiko/napalm hanno supporto multi-vendor più maturo e community attiva in Python | +| Diff calcolato lato client (JS) | Configurazioni grandi (>1MB) causano lag browser, sanitizzazione complessa per XSS | + +--- + +## 🔐 Security & Compliance Decisions + +### Credenziali e Segreti +```yaml +# ✅ DO: Usare variabili d'ambiente o vault esterno +NETCONFIG_DEFAULT_USER: "backup_svc" +NETCONFIG_DEFAULT_PASS: "${VAULT_SECRET_NETCONFIG_PASS}" +NETCONFIG_AGENT_TOKEN: "${OPENSSL_GENERATED_32B_HEX}" + +# ❌ DON'T: Hardcodare nel codice o YAML +# password: "SuperSecret123" # MAI fare questo +``` + +### Cifratura Dati +- **A riposo**: `config_content` cifrato con `Glpi\Toolbox\Encryption::encrypt()` +- **Chiave**: Derivata da `crypt_key` in `GLPI_CONFIG_DIR/config_db.php` (gestita da GLPI) +- **Algoritmo**: AES-256-GCM con autenticazione (previene tampering) +- **Verifica**: Test manuale post-install per confermare che DB contenga blob cifrati + +### Controllo Accessi +```php +// Pattern confermato per tutti i metodi sensibili +if (!\PluginNetconfig\Config::canView()) { + http_response_code(403); + exit('Access denied'); +} +``` + +### Redaction Export +```php +// Regex per mascherare credenziali prima dell'export +$content = preg_replace( + '/(?<=password\s|secret\s|enable\s|community\s)[^\s\r\n]+/i', + '***REDACTED***', + $content +); +// Personalizzabile in base alle policy aziendali +``` + +--- + +## 🧪 Test Plan Confermato + +### Test Unitari (PHPUnit - da implementare) +```php +// Esempio: test hash detection +public function testSaveConfig_DetectsNoChanges(): void +{ + $config = new \PluginNetconfig\Config(); + $result = $config->saveConfig([ + 'networkdevices_id' => 123, + 'content' => 'identical config content' + ]); + // Primo salvataggio: true + // Secondo salvataggio stesso contenuto: true ma nessun nuovo record +} +``` + +### Test di Integrazione +1. **Installazione plugin**: Verificare creazione tabella e registrazione hook +2. **Diritti profilo**: Assegnare READ a utente test, verificare accesso a tab Config History +3. **Agent simulation**: Invio JSON via curl, verificare risposta e record in DB +4. **Export flow**: Login utente con diritti, click export, verificare download e redaction +5. **Diff visual**: Salvare due versioni diverse, verificare rendering HTML differenze + +### Test di Sicurezza +```bash +# 1. Tentativo export senza diritti +curl -b "glpi_session=invalid" http://glpi/plugins/netconfig/ajax/export.php?id=1 +# Atteso: HTTP 403 + +# 2. Invio agent con token errato +curl -X POST ... -d '{"token":"wrong"}' +# Atteso: {"status":"error","message":"Unauthorized"} + +# 3. Verifica cifratura DB +mysql -e "SELECT config_content FROM glpi_plugin_netconfig_configs LIMIT 1" | head +# Atteso: blob binario non leggibile, non testo in chiaro +``` + +--- + +## 📦 Dipendenze e Versioni Confermate + +### composer.json (Definitivo) +```json +{ + "name": "glpi-plugin/netconfig", + "license": "GPL-3.0-or-later", + "minimum-stability": "stable", + "prefer-stable": true, + "require": { + "php": ">=8.2", + "symfony/diff": "^6.4", + "guzzlehttp/guzzle": "^7.8" + }, + "autoload": { + "psr-4": { + "PluginNetconfig\\": "src/", + "PluginNetconfig\\Api\\": "src/Api/" + } + } +} +``` + +### Requisiti Python Agent +```txt +# requirements-agent.txt +netmiko>=4.3.0 +requests>=2.31.0 +pyyaml>=6.0.1 +cryptography>=41.0.0 # Per eventuale cifratura lato agent (opzionale) +``` + +### Estensioni PHP Richieste +```bash +php -m | grep -E "curl|json|mbstring|openssl|zip|pdo_mysql" +# Tutte devono essere presenti per GLPI 11 + plugin +``` + +--- + +## 🔄 Flussi Operativi Documentati + +### Flusso 1: Backup Schedulato (Agent Remoto) +```mermaid +sequenceDiagram + participant Cron as Systemd Timer/Cron + participant Agent as GLPI Agent (Python) + participant Device as Network Device + participant GLPI as GLPI Server + Plugin + + Cron->>Agent: Trigger ogni 6h + Agent->>Device: SSH via netmiko (show running-config) + Device-->>Agent: Restituisce configurazione + Agent->>Agent: Calcola SHA256, confronta con ultimo locale (opzionale) + Agent->>GLPI: POST /ajax/agent_receive.php con JSON + GLPI->>GLPI: Valida token, decifra chiave, confronta hash DB + alt Hash diverso + GLPI->>GLPI: Cifra contenuto, salva nuovo record, registra versione + GLPI-->>Agent: {"status":"ok","message":"Saved"} + else Hash identico + GLPI-->>Agent: {"status":"ok","message":"No changes"} + end + Agent->>Cron: Log risultato, exit +``` + +### Flusso 2: Export Configurazione (Utente GLPI) +```mermaid +sequenceDiagram + participant User as Utente GLPI + participant UI as Interfaccia GLPI + participant Plugin as Plugin NetConfig + participant DB as Database MySQL + + User->>UI: Clicca "Export" su configurazione + UI->>Plugin: GET /ajax/export.php?id=XXX + Plugin->>Plugin: Verifica Session::haveRight(Config::READ) + alt Diritti insufficienti + Plugin-->>UI: HTTP 403 + messaggio errore + else Diritti OK + Plugin->>DB: SELECT config_content, is_encrypted WHERE id=XXX + DB-->>Plugin: Restituisce record + Plugin->>Plugin: Decifra se is_encrypted=1 + Plugin->>Plugin: Applica regex redaction su password/secret + Plugin-->>User: HTTP 200 + file .txt in download + end +``` + +### Flusso 3: Visualizzazione Diff (UI GLPI) +```mermaid +sequenceDiagram + participant User as Utente GLPI + participant Twig as Template Engine + participant Plugin as Plugin NetConfig + participant DiffLib as symfony/diff + + User->>UI: Apri tab "Config History" su NetworkEquipment + UI->>Plugin: Richiedi liste configurazioni per device_id + Plugin->>DB: SELECT * ORDER BY created_at DESC + DB-->>Plugin: Restituisce array configurazioni + Plugin->>Plugin: Per l'ultima config, carica precedente e calcola diff + Plugin->>DiffLib: Differ::diff(old, new) con HtmlOutput + DiffLib-->>Plugin: Stringa HTML con / + Plugin->>Twig: Passa configs + diff_html al template + Twig->>User: Renderizza tabella con pulsante "View Diff" + User->>UI: Clicca pulsante diff + UI->>User: Modal dialog con differenze evidenziate (verde/rosso) +``` + +--- + +## 🚨 Lessons Learned & Pitfalls Evitati + +### ✅ Cosa Abbiamo Imparato +1. **Composer in ambienti non-standard**: Il warning `installed.json not found` è innocuo se `composer install` completa con successo. Non bloccare l'installazione per questo. +2. **Hash vs Timestamp per versioning**: Confrontare hash SHA256 è più affidabile dei timestamp (orologi non sincronizzati, config identiche con timestamp diversi). +3. **Cifratura nativa GLPI**: Usare `Glpi\Toolbox\Encryption` evita di gestire chiavi separatamente e garantisce compatibilità con backup/restore GLPI. +4. **Diff on-demand**: Calcolare il diff solo per l'ultima configurazione (non per tutto lo storico) migliora le performance con config grandi. +5. **Agent token rotation**: Documentare la procedura di rotazione token nel README operativo, anche se non implementata nel codice. + +### ⚠️ Pitfalls Evitati +| Problema Potenziale | Come Lo Abbiamo Evitato | +|---------------------|------------------------| +| XSS nel diff HTML | Output di `symfony/diff` sanitizzato con `|escape('js')` in Twig | +| SQL injection in massive actions | Uso di prepared statements in `getLastConfigByDevice()` | +| Credential leak nei log | Logging configurato per escludere payload config, solo metadata | +| Timeout SSH su dispositivi lenti | Retry logic con backoff + `global_delay_factor` configurabile per device | +| Memory exhaustion con config grandi | Stream export invece di caricamento intero in memoria, uso di `MEDIUMTEXT` | + +--- + +## 📞 Contatti e Responsabilità + +| Ruolo | Responsabilità | Contatto (Esempio) | +|-------|---------------|-------------------| +| **Plugin Maintainer** | Release, compatibilità GLPI, security patch | team-dev@azienda.it | +| **Agent Operator** | Deploy script Python, gestione dispositivi YAML, monitoraggio | netops@azienda.it | +| **Security Officer** | Approvazione policy redaction, rotazione token, audit cifratura | security@azienda.it | +| **GLPI Admin** | Installazione plugin, gestione profili, backup database | glpi-admin@azienda.it | + +--- + +## 🗓️ Cronologia Decisioni + +| Data | Decisione | Autore | Riferimento | +|------|-----------|--------|-------------| +| 2026-05-22 | Architettura plugin confermata (PSR-4, encryption nativa, agent Python) | AI Assistant + Utente | Richiesta iniziale | +| 2026-05-22 | Scelta symfony/diff ^6.4 per visualizzazione differenze | AI Assistant | Valutazione librerie | +| 2026-05-22 | Token-based auth per endpoint agent invece di session GLPI | AI Assistant | Requisito agent remoto | +| 2026-05-22 | Redaction automatica password in export tramite regex | AI Assistant | Compliance sicurezza | +| 2026-05-22 | Supporto massive actions native invece di UI custom | AI Assistant | Integrazione UX GLPI | + +--- + +## 🔗 Link Utili per il Team + +- [Repository Plugin (interno)](https://git.azienda.it/glpi-plugins/netconfig) +- [Documentazione GLPI 11 Developer](https://glpi-developer-documentation.readthedocs.io/en/11.0/) +- [Netmiko Platform Support](https://github.com/ktbyers/netmiko/blob/develop/PLATFORMS.md) +- [GLPI API Postman Collection](https://github.com/glpi-project/glpi/blob/11.0/apirest.md) +- [Checklist Sicurezza Plugin GLPI](https://github.com/glpi-project/glpi/blob/11.0/DEV/SECURITY.md) + +--- + +> 📌 **Nota Operativa**: Questo documento va aggiornato ad ogni modifica architetturale significativa. +> **Ultima revisione**: 2026-05-22 | **Prossima review pianificata**: 2026-08-22 +``` + +--- + +✅ **I file `AGENTS.md` e `MEMORY.md` sono pronti per essere salvati nella root del repository del plugin**. + +Entrambi i documenti: +- Sono scritti in **Markdown puro**, copiabili direttamente +- Contengono **tutto il contesto tecnico** emerso dalla nostra conversazione +- Sono strutturati per essere **utili sia a sviluppatori umani che ad AI agent** +- Includono **decisioni, motivazioni, flussi operativi e checklist di sicurezza** + +Posso generare anche: +- Un `README.md` finale per gli utenti finali del plugin +- Un file `CHANGELOG.md` con versioning semantico +- Script di deploy automatizzato (Ansible/Bash) + +Fammi sapere se vuoi procedere con uno di questi! 🚀