218 lines
9.0 KiB
Markdown
218 lines
9.0 KiB
Markdown
# 📄 PVE Backup Report
|
|
|
|

|
|

|
|

|
|

|
|

|
|
|
|
Outil Python pour générer un rapport quotidien des sauvegardes Proxmox VE vers Proxmox Backup Server.
|
|
|
|
## Documentation
|
|
- 🇬🇧 [English version](README.md)
|
|
|
|
## ✨ Fonctionnalités
|
|
|
|
- 📄 Rapport PDF quotidien horodaté, sans écrasement des rapports précédents.
|
|
- 🧭 Inventaire des stockages PBS déclarés dans Proxmox VE.
|
|
- ✅ Analyse de couverture des VM QEMU et conteneurs LXC.
|
|
- 📝 Notes PVE des VM/CT intégrées au rapport.
|
|
- 🕒 Récupération des dernières sauvegardes connues via les tâches PVE et les logs `vzdump`.
|
|
- 🗄️ Collecte optionnelle des datastores, namespaces, prune jobs, snapshots et espaces PBS.
|
|
- 🔐 Audit des utilisateurs PBS et permissions effectives associées aux stockages PVE.
|
|
- 📊 Rétention PBS avec nombre attendu de versions, delta et état PVE des VM/CT.
|
|
- ⚠️ Section d'anomalies pour les erreurs ou données de collecte partielles.
|
|
- 🐳 Exécution recommandée avec Docker, ou exécution directe en CLI.
|
|
|
|
## 🔐 Prérequis
|
|
|
|
Créer des utilisateurs ou tokens API dédiés à cette application de rapport. Ils doivent être limités aux droits d'audit/lecture seule :
|
|
|
|
- Proxmox VE : attribuer uniquement le rôle `PVEAuditor` à l'utilisateur et au token API utilisé par `PVE_API_TOKEN_ID`.
|
|
- Proxmox Backup Server : attribuer uniquement le rôle `Audit` à l'utilisateur et au token API utilisé par chaque `PBS<number>_API_TOKEN_ID`.
|
|
|
|
Ne pas utiliser de compte administrateur ou de compte avec droits d'écriture. L'application a seulement besoin de lire l'inventaire, les jobs de sauvegarde, les tâches, les datastores, les namespaces, les snapshots et les données de rétention.
|
|
|
|
## 🐳 Utilisation avec Docker
|
|
|
|
Docker est le mode d'exécution recommandé. L'image contient les dépendances Python et les bibliothèques système nécessaires à WeasyPrint.
|
|
|
|
### 📦 Préparation
|
|
|
|
```sh
|
|
cp .env.example .env
|
|
mkdir -p reports
|
|
```
|
|
|
|
Adapter ensuite `.env` avec les informations du cluster PVE et des PBS à collecter.
|
|
|
|
Dans Docker, conserver :
|
|
|
|
```env
|
|
REPORT_OUTPUT_DIR=/reports
|
|
```
|
|
|
|
Le fichier `compose.yaml` monte le répertoire local `./reports` dans le conteneur sous `/reports`. Les PDF générés sont donc visibles sur l'hôte dans `./reports/`.
|
|
|
|
### ⚙️ Configuration minimale
|
|
|
|
```env
|
|
PVE_API_URL=https://pve.example.invalid:8006
|
|
PVE_API_TOKEN_ID=backup-report@pve!report
|
|
PVE_API_TOKEN_SECRET=change-me
|
|
REPORT_OUTPUT_DIR=/reports
|
|
REPORT_TIMEZONE=Europe/Paris
|
|
PVE_VERIFY_TLS=true
|
|
```
|
|
|
|
Pour activer la collecte PBS, renseigner l'URL, le token ID et le secret du PBS concerné. Une configuration partielle n'active pas la collecte du PBS.
|
|
|
|
Exemple avec un PBS :
|
|
|
|
```env
|
|
PBS01_NAME=nom-affiche
|
|
PBS01_API_URL=https://backup.example.invalid:8007
|
|
PBS01_API_TOKEN_ID=
|
|
PBS01_API_TOKEN_SECRET=
|
|
```
|
|
|
|
Il est possible de renseigner un ou plusieurs PBS. Pour ajouter un serveur, dupliquer le bloc en incrémentant le numéro du préfixe : `PBS02_*`, `PBS03_*`, `PBS04_*`, etc. L'application détecte automatiquement tous les blocs `PBS<number>_*` présents dans l'environnement.
|
|
|
|
### 🏗️ Construction
|
|
|
|
```sh
|
|
docker compose build
|
|
```
|
|
|
|
### ✅ Vérification
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --check-config
|
|
docker compose run --rm pve-backup-report --check-api
|
|
```
|
|
|
|
`--check-api` teste les endpoints PVE principaux. Si `/cluster/backup` retourne `HTTP 403 - Permission check failed (/, Sys.Audit)`, le token fonctionne mais il lui manque le privilège `Sys.Audit` sur `/`.
|
|
|
|
### 📄 Génération du rapport
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --generate-pdf
|
|
```
|
|
|
|
Le rapport PDF est écrit dans `./reports/` avec un nom horodaté et n'écrase jamais un rapport précédent.
|
|
|
|
### 🧪 Commandes de diagnostic Docker
|
|
|
|
```sh
|
|
docker compose run --rm pve-backup-report --dump-inventory
|
|
docker compose run --rm pve-backup-report --dump-coverage
|
|
docker compose run --rm pve-backup-report --dump-report-data
|
|
docker compose run --rm pve-backup-report --dump-pbs-storage-usages
|
|
docker compose run --rm pve-backup-report --dump-pbs-users
|
|
docker compose run --rm pve-backup-report --debug-last-backup-vmid <VMID>
|
|
```
|
|
|
|
Lancer le conteneur sans argument exécute seulement la commande par défaut `pve-backup-report`. Pour générer un PDF, utiliser explicitement `--generate-pdf`.
|
|
|
|
### 🕒 Planification avec cron et Docker
|
|
|
|
Exemple de crontab côté hôte pour lancer le rapport tous les jours à 02:00 :
|
|
|
|
```cron
|
|
SHELL=/bin/sh
|
|
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
|
|
0 2 * * * cd /srv/pve-backup-report && /usr/bin/flock -n /tmp/pve-backup-report.lock /usr/bin/docker compose run --rm pve-backup-report --generate-pdf >> /var/log/pve-backup-report.log 2>&1
|
|
```
|
|
|
|
Adapter `/srv/pve-backup-report` au chemin réel du dépôt. Le `cd` est important : Docker Compose y trouve `compose.yaml` et l'application y charge `.env`.
|
|
|
|
## 💻 Utilisation directe en ligne de commande
|
|
|
|
Ce mode est utile pour le développement ou le diagnostic hors conteneur. L'hôte doit disposer de Python, des dépendances Python du projet et des bibliothèques système requises par WeasyPrint.
|
|
|
|
### 📦 Installation locale
|
|
|
|
```sh
|
|
python3 -m venv .venv
|
|
. .venv/bin/activate
|
|
python -m ensurepip --upgrade
|
|
pip install -r requirements.txt
|
|
pip install -e .
|
|
```
|
|
|
|
Pour lancer les tests :
|
|
|
|
```sh
|
|
pip install -e ".[dev]"
|
|
pytest
|
|
```
|
|
|
|
### 🧰 Commandes installées
|
|
|
|
```sh
|
|
pve-backup-report --check-config
|
|
pve-backup-report --check-api
|
|
pve-backup-report --dump-inventory
|
|
pve-backup-report --dump-coverage
|
|
pve-backup-report --dump-report-data
|
|
pve-backup-report --dump-pbs-storage-usages
|
|
pve-backup-report --dump-pbs-users
|
|
pve-backup-report --generate-pdf
|
|
pve-backup-report --debug-last-backup-vmid <VMID>
|
|
```
|
|
|
|
Sans installation éditable, depuis le dépôt :
|
|
|
|
```sh
|
|
PYTHONPATH=src python3 -m pve_backup_report --check-config
|
|
PYTHONPATH=src python3 -m pve_backup_report --check-api
|
|
PYTHONPATH=src python3 -m pve_backup_report --dump-inventory
|
|
PYTHONPATH=src python3 -m pve_backup_report --dump-coverage
|
|
PYTHONPATH=src python3 -m pve_backup_report --dump-report-data
|
|
PYTHONPATH=src python3 -m pve_backup_report --dump-pbs-storage-usages
|
|
PYTHONPATH=src python3 -m pve_backup_report --dump-pbs-users
|
|
PYTHONPATH=src python3 -m pve_backup_report --generate-pdf
|
|
PYTHONPATH=src python3 -m pve_backup_report --debug-last-backup-vmid <VMID>
|
|
```
|
|
|
|
En exécution locale directe, `REPORT_OUTPUT_DIR` peut rester à `reports/` ou pointer vers un autre répertoire accessible par l'utilisateur courant.
|
|
|
|
Le même fichier `.env` peut être utilisé en Docker et en exécution locale. Si `REPORT_OUTPUT_DIR=/reports` est conservé hors Docker et que `/reports` n'est pas accessible, l'application utilise automatiquement le répertoire local `reports/` et l'indique dans les logs.
|
|
|
|
### 🕒 Planification avec cron sans Docker
|
|
|
|
Exemple avec l'environnement virtuel du projet :
|
|
|
|
```cron
|
|
SHELL=/bin/sh
|
|
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
|
|
|
0 2 * * * cd /srv/pve-backup-report && /usr/bin/flock -n /tmp/pve-backup-report.lock /srv/pve-backup-report/.venv/bin/pve-backup-report --generate-pdf >> /var/log/pve-backup-report.log 2>&1
|
|
```
|
|
|
|
L'utilisateur qui exécute la crontab doit avoir le droit de lire `.env` et d'écrire dans `REPORT_OUTPUT_DIR`.
|
|
|
|
## 🔧 Variables utiles
|
|
|
|
- 🌐 `PVE_API_URL` : URL d'un noeud PVE joignable, par exemple `https://pve.example.invalid:8006`.
|
|
- 🔑 `PVE_API_TOKEN_ID` : identifiant complet du token, par exemple `backup-report@pve!report`.
|
|
- 🔒 `PVE_API_TOKEN_SECRET` : secret du token.
|
|
- 🛡️ `PVE_VERIFY_TLS` : laisser `true` en production ; utiliser `PVE_CA_BUNDLE` pour une CA interne.
|
|
- 🕒 `PVE_TASK_HISTORY_LIMIT` : nombre de tâches PVE récentes inspectées pour retrouver la dernière sauvegarde.
|
|
- 📜 `PVE_TASK_LOG_LIMIT` : nombre de lignes récupérées par log `vzdump` pour extraire le détail par VM/CT.
|
|
- 🗺️ `PBS_HOSTNAMES` : mapping manuel optionnel des serveurs PBS sous la forme `adresse=nom-affiche,adresse2=nom-affiche2`.
|
|
- 🗄️ `PBS<number>_*` : configurations optionnelles des API PBS, par exemple `PBS01_*`, `PBS02_*`, `PBS10_*`.
|
|
- 🏷️ `REPORT_FILENAME_PREFIX` : préfixe du fichier PDF généré.
|
|
|
|
## 📄 Sortie PDF
|
|
|
|
`--generate-pdf` génère un PDF horodaté dans `REPORT_OUTPUT_DIR`. La colonne `Dernière sauvegarde` affiche l'état, la date, l'heure et la durée lorsque PVE fournit cette information. Les tableaux `Rétention des sauvegardes VM/CT <PBS>` sont séparés par namespace et affichent le datastore, le nombre de versions PBS, la plus ancienne et la plus récente sauvegarde visibles sur chaque PBS configuré.
|
|
|
|
## 🤖 Utilisation de l'IA
|
|
L'application a été entièrement codée avec Codex et Claude code. Je n'aurai jamais eu le temps de coder l'application tout seul en aussi peu de temps.
|
|
|
|
## ⚖️ Licence
|
|
|
|
Ce projet est distribué sous licence Apache License 2.0. Voir le fichier `LICENSE`.
|