Files
netconfig/AGENTS.md
T
2026-05-22 13:55:01 +02:00

296 lines
12 KiB
Markdown

# 🤖 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)
```