commti after qwen start
This commit is contained in:
@@ -0,0 +1,295 @@
|
||||
# 🤖 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)
|
||||
```
|
||||
Reference in New Issue
Block a user