change before saturday

This commit is contained in:
mariano
2026-05-22 14:20:21 +02:00
parent ed29fbc62d
commit 9ef0a5dcf9
2 changed files with 723 additions and 0 deletions
+98
View File
@@ -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
+625
View File
@@ -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 <ins>/<del>
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! 🚀