Organize documentation by language

This commit is contained in:
2026-05-13 17:34:48 +02:00
parent e77d73d6dc
commit cf3bc421fa
14 changed files with 13 additions and 15 deletions
+135
View File
@@ -0,0 +1,135 @@
# API Proxmox Backup Server
[English version](../en/api-pbs.md)
Ce document decrit la collecte PBS utilisee par le rapport.
## Objectif
La collecte PBS sert a completer le rapport PVE avec les politiques de retention configurees et les versions de sauvegarde visibles sur les serveurs Proxmox Backup Server renseignes.
L'application peut interroger un ou plusieurs serveurs PBS. Chaque serveur est collecte uniquement si son URL API, son token ID et son token secret sont fournis.
Cette etape ne prouve pas les synchronisations entre serveurs PBS. Elle collecte les prune jobs et les snapshots visibles sur chaque PBS configure.
## Authentification
Le client PBS utilise un token API PBS.
Le header HTTP est :
```text
Authorization: PBSAPIToken=TOKENID:TOKENSECRET
```
Exemple de configuration d'un serveur PBS :
```env
PBS01_NAME=nom-affiche
PBS01_API_URL=https://backup.example.invalid:8007
PBS01_API_TOKEN_ID=
PBS01_API_TOKEN_SECRET=
```
Pour collecter plusieurs PBS, dupliquer ce bloc avec les prefixes `PBS02_*`, `PBS03_*`, `PBS04_*`, etc. Tous les blocs `PBS<number>_*` complets sont detectes automatiquement.
Le secret du token ne doit jamais etre journalise ni apparaitre dans le rapport.
## Endpoint utilise
| Donnee | Endpoint PBS |
| --- | --- |
| Prune jobs | `/config/prune` |
| Datastores PBS | `/config/datastore` |
| Statut d'un datastore | `/admin/datastore/{datastore}/status` |
| Statut garbage collector d'un datastore | `/admin/datastore/{datastore}/gc` |
| Namespaces d'un datastore | `/admin/datastore/{datastore}/namespace` |
| Snapshots d'un datastore/namespace | `/admin/datastore/{datastore}/snapshots?ns={namespace}` |
| Utilisateurs PBS | `/access/users` |
| Permissions effectives | `/access/permissions?auth-id={auth-id}&path={path}` |
Le client ajoute automatiquement `/api2/json` a l'URL PBS si ce suffixe n'est pas deja present.
## Donnees normalisees
Chaque prune job PBS est transforme en politique de retention avec les champs suivants :
- identifiant du job ;
- serveur PBS ;
- datastore ;
- namespace ;
- planification ;
- etat actif/inactif ;
- `keep-last` ;
- `keep-hourly` ;
- `keep-daily` ;
- `keep-weekly` ;
- `keep-monthly` ;
- `keep-yearly` ;
- `max-depth` ;
- commentaire.
Si le champ `ns` est absent, la namespace est consideree comme la racine `/`.
Le rapport calcule le nombre attendu de versions d'une VM/CT depuis la politique de retention active qui correspond au meme serveur PBS, datastore et namespace que les snapshots. Ce nombre est la somme des valeurs `keep-last`, `keep-hourly`, `keep-daily`, `keep-weekly`, `keep-monthly` et `keep-yearly` renseignees. Le delta affiche `nombre de snapshots visibles - nombre attendu`.
Chaque snapshot PBS est agrege par datastore, namespace, type de sauvegarde et VMID afin de produire :
- nombre de versions de sauvegarde ;
- date de la plus ancienne sauvegarde ;
- date de la plus recente sauvegarde ;
- taille de la sauvegarde la plus recente lorsque PBS expose cette information.
Les snapshots restant visibles sur PBS alors que la VM/CT n'existe plus dans l'inventaire PVE sont conserves pour le tableau de retention et marques `Non-active sur PVE`.
Les snapshots dont le namespace ne figure pas dans les namespaces declares sur PVE sont exclus de ces tableaux de retention.
Le statut de chaque datastore PBS configure est collecte afin d'afficher l'espace total, l'espace consomme et l'espace libre dans le rapport.
## Utilisateurs PBS declares cote PVE
La commande de diagnostic `--dump-pbs-users` collecte les stockages PBS declares dans PVE via `/storage`, puis rapproche leur champ `username` des utilisateurs visibles sur chaque PBS configure via `/access/users`.
Pour chaque stockage PBS PVE ayant un `username`, le diagnostic interroge les permissions effectives de cet auth-id sur le chemin PBS cible :
```text
/datastore/{datastore}
/datastore/{datastore}/{namespace}
```
Le second format est utilise lorsqu'une namespace non racine est declaree cote PVE.
Les informations collectees alimentent le tableau `Utilisateurs PBS - Audit des accès` du rapport et la commande de diagnostic. Elles servent a verifier quel compte PBS est utilise par PVE, si le compte est actif lorsque PBS expose cette information, et quels privileges effectifs sont disponibles sur le datastore/namespace cible.
Si le `username` PVE est un token PBS de type `user@realm!token`, le rapprochement avec `/access/users` se fait sur le user parent `user@realm`; les permissions sont demandees avec l'auth-id complet.
Les types PBS `vm` et `ct` sont rapproches des types PVE `qemu` et `lxc`.
La collecte des snapshots interroge les datastores exposes par chaque PBS configure.
Pour chaque datastore, elle ajoute aussi l'ensemble des namespaces declarees dans les stockages PBS de PVE, meme si le PBS concerne ne recoit pas directement les backups des VM/CT depuis PVE. Cela permet de retrouver des sauvegardes synchronisees sur un PBS secondaire, par exemple dans les namespaces `serveurs-internes` ou `Serveurs-PVELAB`.
Les namespaces retournees par l'API du PBS cible restent collectees egalement. Les snapshots sont ensuite rapproches des VM/CT par type et VMID.
Comme ces serveurs additionnels peuvent contenir des sauvegardes directes et synchronisees, certains appels `/snapshots` peuvent etre plus longs. Augmenter le timeout du bloc PBS concerne si le timeout par defaut est insuffisant.
## Gestion des erreurs
Si aucun PBS n'est configure, la collecte PBS est ignoree.
Si un PBS configure est indisponible, le rapport continue et une anomalie `pbs_retention` est ajoutee pour le serveur concerne.
Si un PBS configure est indisponible pour la collecte des snapshots, le rapport continue et une anomalie `pbs_snapshots` est ajoutee pour le serveur concerne.
Lorsqu'une namespace declaree dans PVE est testee sur un datastore PBS ou elle n'existe pas, PBS peut repondre `HTTP 400 - Bad Request` sur l'endpoint `/snapshots`. Pour une namespace non racine, cette reponse est interpretee comme une absence de namespace sur ce datastore et n'est pas remontee comme anomalie. Les autres erreurs, y compris un `400` sur la racine `/`, restent visibles.
Si la reponse `/config/prune` n'est pas une liste, le rapport continue et ajoute une anomalie.
Si `/config/prune` repond avec une liste vide alors qu'un PBS est configure, une anomalie `warning` est ajoutee afin de verifier soit l'absence reelle de prune jobs, soit les droits effectifs du token PBS.
## Limites
La collecte ne verifie pas encore :
- les synchronisations entre serveurs PBS ;
- l'etat d'execution des prune jobs ;
- le resultat effectif d'un prune sur les snapshots.
Ces points pourront etre ajoutes dans une etape dediee.
+228
View File
@@ -0,0 +1,228 @@
# API Proxmox VE
[English version](../en/api-pve.md)
## Principes
L'application doit utiliser l'API REST Proxmox VE en lecture seule.
Etat actuel : le module `pve_client.py` implemente la connexion API reutilisable et les tests des endpoints `/nodes`, `/storage`, `/cluster` et de l'endpoint configure pour les jobs de sauvegarde.
La collecte des stockages PBS, des jobs de sauvegarde, des VM/CT et des pools est implementee. Le calcul de couverture prend en charge les `vmid` explicitement listes dans les jobs actifs, les jobs `all=1` et les jobs `pool=<nom>`.
L'URL de base suit generalement ce format :
```text
https://<pve-host>:8006/api2/json
```
Le script peut interroger n'importe quel noeud disponible du cluster pour les endpoints globaux.
## Authentification par token
L'authentification recommandee utilise l'en-tete HTTP `Authorization`.
Format :
```text
Authorization: PVEAPIToken=<token-id>=<token-secret>
```
Le token secret ne doit jamais etre logue.
Dans `.env`, renseigner :
```env
PVE_API_TOKEN_ID=backup-report@pve!report
PVE_API_TOKEN_SECRET=secret-fourni-par-pve
```
## Endpoints utiles
Les endpoints exacts doivent etre verifies avec la version PVE cible pendant l'implementation.
Endpoints generalement utiles :
| Besoin | Endpoint indicatif |
| --- | --- |
| Version PVE | `/version` |
| Ressources cluster | `/cluster/resources` |
| Configuration des stockages | `/storage` |
| Index cluster | `/cluster` |
| Jobs de sauvegarde | `/cluster/backup` |
| Pools | `/pools` et `/pools/{poolid}` |
| Taches de sauvegarde recentes | `/cluster/tasks` et `/nodes/{node}/tasks` |
| Configuration VM QEMU | `/nodes/{node}/qemu/{vmid}/config` |
| Configuration conteneur LXC | `/nodes/{node}/lxc/{vmid}/config` |
| Statut des noeuds | `/nodes` |
La valeur nominale pour les jobs de sauvegarde est :
```text
/cluster/backup
```
`PVE_BACKUP_JOBS_ENDPOINT` existe seulement comme override technique. La valeur attendue reste `/cluster/backup`.
Privilege observe pour les jobs de sauvegarde :
```text
Sys.Audit sur /
```
Si le token ne possede pas ce privilege, PVE retourne typiquement `HTTP 403 - Permission check failed (/, Sys.Audit)`.
Avec les tokens en privileges separes, avoir `PVEAuditor` visible dans l'interface ne suffit pas toujours : il faut verifier les droits effectifs du token, pas seulement ceux de l'utilisateur parent.
Verification manuelle :
```sh
PYTHONPATH=src python3 -m pve_backup_report --check-api
```
La commande affiche uniquement le statut et le nombre d'elements retournes. Elle ne journalise pas le token secret.
Les endpoints sont testes independamment. Un echec sur l'endpoint des jobs de sauvegarde n'empeche pas d'afficher le resultat de `/nodes`, `/storage` et `/cluster`.
## Stockages PBS
Un stockage PBS est generalement identifie par un type equivalent a `pbs`.
Champs attendus a normaliser :
- `storage` ou ID equivalent ;
- `type` ;
- `server` ;
- `datastore` ;
- `namespace` ;
- `username`.
Tous les champs ne sont pas forcement presents selon la version ou la configuration.
Le rapport doit afficher une valeur explicite comme `non renseigne` lorsqu'un champ non critique est absent.
Pour l'etat actif, PVE expose generalement `disable=1` lorsqu'un storage est desactive et omet le champ lorsque le storage est actif. L'absence de `disable` doit donc etre interpretee comme actif.
La commande de diagnostic actuelle est :
```sh
PYTHONPATH=src python3 -m pve_backup_report --dump-inventory
```
Elle affiche les stockages PBS normalises sans afficher de secret.
## Ressources VM et CT
L'inventaire peut etre construit depuis `/cluster/resources`.
Filtrer les types utiles :
- `qemu` pour les VM ;
- `lxc` pour les conteneurs.
Champs utiles :
- `vmid` ;
- `name` ;
- `type` ;
- `node` ;
- `status`.
Les notes des VM/CT sont collectees depuis la configuration de chaque guest sur son noeud courant :
- VM QEMU : `/nodes/{node}/qemu/{vmid}/config` ;
- conteneurs LXC : `/nodes/{node}/lxc/{vmid}/config`.
Le champ attendu est `description`. Si la configuration d'une VM/CT est indisponible, la collecte continue, une anomalie `guests` est ajoutee, et la note est affichee comme `non renseigné` dans le rapport.
Commande de diagnostic :
```sh
PYTHONPATH=src python3 -m pve_backup_report --dump-coverage
```
Commande de previsualisation du modele final :
```sh
PYTHONPATH=src python3 -m pve_backup_report --dump-report-data
```
## Derniere sauvegarde realisee
L'etat de la derniere sauvegarde est deduit des taches PVE recentes recuperees via `/cluster/tasks` et `/nodes/{node}/tasks` sans parametre, puis filtrees localement sur le type `vzdump`.
Le nombre de taches inspectees localement est controle par `PVE_TASK_HISTORY_LIMIT`.
Le nombre de lignes recuperees pour chaque log de tache est controle par `PVE_TASK_LOG_LIMIT`.
Si l'historique des taches est indisponible, la generation du rapport continue et une anomalie est ajoutee.
Pour les jobs qui sauvegardent plusieurs VM/CT, le resultat par VM/CT est extrait du log de la tache via `/nodes/{node}/tasks/{upid}/log`.
La duree de sauvegarde est extraite en priorite des lignes `Finished Backup of ... (HH:MM:SS)`, car cette valeur correspond a la VM/CT concernee. En repli, pour une tache simple ou une VM/CT explicitement demarree dans le log, elle peut etre calculee depuis `starttime` et `endtime`.
Le VMID est extrait depuis les lignes de log `Starting Backup of ...`, `Finished Backup of ...` et `Backup of ... failed`. Si le log est indisponible, le script tente un repli depuis les champs `vmid`, `id`, `guest` ou `upid`.
Si une VM/CT vient d'etre ajoutee a un job et n'a pas encore eu de sauvegarde terminee dans l'historique disponible, aucun resultat de derniere sauvegarde ne peut etre renseigne.
## Jobs de sauvegarde
Les jobs de sauvegarde PVE contiennent les informations necessaires pour determiner :
- activation ou desactivation du job ;
- cible storage ;
- planification ;
- selection des VM/CT ;
- exclusions eventuelles ;
- mode de sauvegarde.
L'implementation doit distinguer :
- les jobs actifs ;
- les jobs desactives ;
- les jobs ciblant un PBS ;
- les jobs ciblant un autre type de storage.
Etat actuel : les jobs sont normalises avec ID, storage, schedule, activation, mode, selection brute et exclusions brutes.
Le calcul de couverture interprete les listes explicites `vmid=...`, les jobs `all=1`, les jobs `pool=<nom>`, et les exclusions simples.
Si un job reference un pool absent ou impossible a collecter, la couverture concernee reste `indetermine`.
## Planification
PVE peut exprimer les horaires avec une syntaxe de calendrier.
Le rapport doit afficher la valeur brute si le parsing complet n'est pas implemente.
Si une interpretation lisible est ajoutee, conserver aussi la valeur source en cas d'ambiguite.
## Anomalies de collecte
Ajouter une anomalie lorsque :
- un endpoint retourne une erreur ;
- une reponse est incomplete ;
- un job reference un storage inconnu ;
- un type de selection de VM n'est pas pris en charge ;
- un champ indispensable a l'analyse est absent.
Une anomalie doit contenir :
- une severite ;
- le composant concerne ;
- un message court ;
- des details techniques non sensibles.
## Erreurs gerees par le client
Le client distingue :
- erreur de connexion ou timeout ;
- erreur HTTP avec endpoint et code retour ;
- reponse JSON invalide ;
- reponse JSON sans champ `data`.
Les messages d'erreur ne doivent jamais inclure `PVE_API_TOKEN_SECRET`.
## TLS
La connexion API peut etre executee avec `PVE_VERIFY_TLS=false` lorsque la CA existante n'est pas compatible avec la validation stricte de Python/OpenSSL et ne peut pas etre remplacee.
+159
View File
@@ -0,0 +1,159 @@
# Architecture cible
[English version](../en/architecture.md)
## Vue d'ensemble
L'application est un outil batch lance une fois par jour. Elle collecte les donnees depuis l'API Proxmox VE, les transforme en objets internes, calcule la couverture de sauvegarde, puis genere un rapport PDF horodate.
Le conteneur Docker execute une commande unique et se termine avec un code de retour explicite.
Etat actuel du depot : la CLI, la configuration, le logging, la collecte PVE/PBS, l'analyse de couverture et la generation PDF WeasyPrint sont implementes. Le conteneur Docker integre les dependances systeme necessaires au rendu PDF.
## Composants
### CLI
La CLI est le point d'entree du script.
Responsabilites :
- charger la configuration ;
- initialiser les logs ;
- lancer la collecte ;
- lancer l'analyse ;
- generer le PDF ;
- retourner un code de sortie adapte.
### Configuration
Le module de configuration lit les variables d'environnement et valide les valeurs obligatoires.
Il ne doit pas contenir de logique d'appel API.
### Client PVE
Le client PVE encapsule les appels HTTP vers l'API Proxmox VE.
Le client utilise `requests` et une session reutilisable.
Il implemente :
- authentification par API token ;
- verification TLS configurable ;
- CA bundle optionnel ;
- timeout reseau ;
- erreurs dediees pour connexion, HTTP et reponse invalide ;
- methodes de verification pour `/nodes`, `/storage` et `/cluster/backup`.
Il gere :
- l'URL de base ;
- l'authentification par token ;
- la verification TLS ;
- les erreurs HTTP ;
- les timeouts ;
- la deserialisation JSON.
### Collecteurs
Les collecteurs recuperent les informations brutes :
- stockages ;
- jobs de sauvegarde ;
- ressources du cluster ;
- informations utiles sur les VM et CT.
- notes des VM/CT depuis leur configuration par noeud ;
- prune jobs PBS, si la collecte PBS est configuree ;
- snapshots PBS par datastore et namespace, si la collecte PBS correspondante est configuree.
Chaque collecteur doit retourner des donnees structurees, pas du JSON brut disperse dans l'application.
Etat actuel : la collecte des stockages PBS via `/storage`, des jobs de sauvegarde via `/cluster/backup`, des VM/CT via `/cluster/resources`, des pools via `/pools`, des dernieres taches `vzdump` via `/cluster/tasks` et `/nodes/{node}/tasks`, ainsi que des prune jobs et snapshots via l'API PBS, est implementee.
### Modeles
Les modeles representent les entites internes :
- `PbsStorage` ;
- `PbsRetentionPolicy` ;
- `PbsBackupSnapshotSummary` ;
- `Guest` ;
- `BackupJob` ;
- `BackupCoverage` ;
- `ReportData` ;
- `ReportSummary` ;
- `CollectionIssue`.
Les modeles peuvent etre implementes avec `dataclasses` ou Pydantic selon les choix du projet.
### Analyse de couverture
Le module d'analyse compare l'inventaire des VM/CT avec les jobs de sauvegarde actifs.
Il produit un statut par VM/CT :
- `sauvegarde_planifiee` ;
- `non_sauvegardee` ;
- `indetermine`.
Etat actuel : la couverture par `vmid` explicitement listes, `all=1` et `pool=<nom>` est calculee. Les exclusions simples sont prises en compte.
### Generation PDF
Le generateur PDF prend un objet `ReportData` complet et produit un fichier.
Il ne doit pas appeler l'API PVE.
Il ne doit pas relire la configuration globale sauf pour les options de rendu strictement necessaires.
Le rendu principal utilise `WeasyPrint` a partir d'un template HTML/CSS. Cette approche garde la logique metier separee de la presentation et rend les evolutions visuelles plus simples.
Le PDF contient actuellement le resume, les stockages PBS declares sur PVE, les espaces de stockage PBS, les politiques de retention PBS, les jobs de sauvegarde, les VM/CT non sauvegardees, la couverture VM/CT, les retentions de sauvegarde VM/CT par PBS avec nombre attendu de versions et delta, et les anomalies.
## Flux de donnees
1. Chargement de la configuration.
2. Connexion a l'API PVE.
3. Connexion optionnelle aux API PBS configurees.
4. Collecte des stockages.
5. Filtrage des stockages PBS.
6. Collecte des prune jobs et des snapshots PBS, si configures.
7. Collecte des jobs de sauvegarde.
8. Collecte des VM et CT.
9. Calcul de couverture.
10. Construction du modele de rapport.
11. Generation du PDF.
12. Log du resultat et code de sortie.
Une etape de preparation assemble un `ReportData` final avec un `ReportSummary` calcule. La commande `--dump-report-data` permet de previsualiser ce modele en JSON.
La commande `--generate-pdf` rend ce modele en PDF avec WeasyPrint. En Docker Compose, elle doit etre lancee explicitement :
```sh
docker compose run --rm pve-backup-report --generate-pdf
```
## Gestion des erreurs
Les erreurs bloquantes arretent l'execution :
- configuration invalide ;
- echec d'authentification ;
- API PVE totalement indisponible ;
- impossibilite d'ecrire le PDF.
Les erreurs partielles peuvent etre ajoutees au rapport :
- un noeud ne repond pas ;
- un champ attendu manque ;
- un job ne peut pas etre interprete ;
- un storage reference n'existe pas dans la collecte.
## Idempotence
L'execution quotidienne ne doit pas modifier l'etat PVE.
L'outil est en lecture seule vis-a-vis du cluster.
Le seul effet de bord attendu est la creation d'un nouveau rapport dans le repertoire de sortie.
+251
View File
@@ -0,0 +1,251 @@
# Configuration
[English version](../en/configuration.md)
## Variables d'environnement
Configuration minimale recommandee :
```env
PVE_API_URL=https://pve.example.invalid:8006
PVE_API_TOKEN_ID=
PVE_API_TOKEN_SECRET=
REPORT_OUTPUT_DIR=/reports
REPORT_TIMEZONE=Europe/Paris
REPORT_LANGUAGE=fr
```
Un fichier `.env.example` est fourni comme modele. Le fichier `.env` reel ne doit pas etre commite.
Configuration optionnelle :
```env
PVE_VERIFY_TLS=false
PVE_CA_BUNDLE=
PVE_TIMEOUT_SECONDS=30
PVE_BACKUP_JOBS_ENDPOINT=/cluster/backup
PVE_TASK_HISTORY_LIMIT=500
PBS_HOSTNAMES=backup.example.invalid=nom-affiche
LOG_LEVEL=INFO
REPORT_FILENAME_PREFIX=rapport-sauvegardes-pve
```
## Description des variables
| Variable | Obligatoire | Description |
| --- | --- | --- |
| `PVE_API_URL` | Oui | URL de l'API Proxmox VE, avec schema et port. |
| `PVE_API_TOKEN_ID` | Oui | Identifiant complet du token API PVE. |
| `PVE_API_TOKEN_SECRET` | Oui | Secret du token API PVE. |
| `REPORT_OUTPUT_DIR` | Non | Repertoire de sortie des rapports PDF. Defaut applicatif : `reports/`. En Docker Compose, utiliser `/reports`. |
| `REPORT_TIMEZONE` | Non | Fuseau horaire utilise pour les dates du rapport. Defaut : `Europe/Paris`. |
| `REPORT_LANGUAGE` | Non | Langue du rapport PDF. Valeurs supportees : `fr` ou `en`. Defaut : `fr`. |
| `PVE_VERIFY_TLS` | Non | Active la verification TLS. Defaut : `true`. |
| `PVE_CA_BUNDLE` | Non | Chemin vers une CA interne montee dans le conteneur. |
| `PVE_TIMEOUT_SECONDS` | Non | Timeout HTTP. Defaut : `30`. |
| `PVE_BACKUP_JOBS_ENDPOINT` | Non | Endpoint qui liste les jobs de sauvegarde planifies. Defaut : `/cluster/backup`. A conserver sauf cas particulier. |
| `PVE_TASK_HISTORY_LIMIT` | Non | Nombre de taches PVE recentes inspectees pour trouver la derniere sauvegarde. Defaut : `500`. |
| `PVE_TASK_LOG_LIMIT` | Non | Nombre de lignes recuperees par log de tache `vzdump`. Defaut : `5000`. |
| `PBS_HOSTNAMES` | Non | Mapping manuel IP/DNS PBS vers nom d'hote affiche dans le rapport. |
| `PBS<number>_NAME` | Non | Nom affiche du serveur PBS configure, par exemple `PBS01_NAME`. Defaut : le prefixe `PBS<number>`. |
| `PBS<number>_API_URL` | Non | URL API du serveur PBS, par exemple `https://backup.example.invalid:8007`. Active la collecte si le token est aussi renseigne. |
| `PBS<number>_API_TOKEN_ID` | Non | Identifiant complet du token API PBS. |
| `PBS<number>_API_TOKEN_SECRET` | Non | Secret du token API PBS. |
| `PBS<number>_VERIFY_TLS` | Non | Active la verification TLS pour ce serveur PBS. Defaut : valeur de `PVE_VERIFY_TLS`. |
| `PBS<number>_CA_BUNDLE` | Non | Chemin vers une CA interne pour ce serveur PBS. |
| `PBS<number>_TIMEOUT_SECONDS` | Non | Timeout HTTP pour ce serveur PBS. Defaut : valeur de `PVE_TIMEOUT_SECONDS` ou `30`. |
| `LOG_LEVEL` | Non | Niveau de log. Defaut : `INFO`. |
| `REPORT_FILENAME_PREFIX` | Non | Prefixe du fichier PDF. |
## Exemple Docker Compose
```yaml
services:
pve-backup-report:
build: .
env_file:
- .env
volumes:
- ./reports:/reports
restart: "no"
```
Avec ce montage, la configuration Docker doit contenir :
```env
REPORT_OUTPUT_DIR=/reports
```
Les rapports sont alors ecrits dans `./reports/` sur l'hote.
## Mapping des noms PBS
Le champ `PBS_HOSTNAMES` permet d'afficher le nom d'hote entre parentheses dans la colonne `Serveur PBS`.
Format :
```env
PBS_HOSTNAMES=backup.example.invalid=nom-affiche
```
Rendu dans le rapport :
```text
backup.example.invalid (nom-affiche)
```
## Collecte PBS
La collecte PBS est optionnelle. Pour chaque serveur PBS, elle est active uniquement si les trois variables API URL, token ID et token secret sont renseignees.
Un bloc PBS suit le motif `PBS<number>_*`. L'ordre de collecte et d'affichage suit l'ordre numerique des prefixes : `PBS01`, `PBS02`, `PBS10`, etc.
```env
PBS01_NAME=nom-affiche
PBS01_API_URL=https://backup.example.invalid:8007
PBS01_API_TOKEN_ID=
PBS01_API_TOKEN_SECRET=
```
Pour ajouter d'autres serveurs PBS, dupliquer le bloc et incrementer le numero du prefixe :
```env
PBS02_NAME=nom-affiche-secondaire
PBS02_API_URL=https://backup-secondary.example.invalid:8007
PBS02_API_TOKEN_ID=
PBS02_API_TOKEN_SECRET=
PBS10_NAME=nom-affiche-dixieme
PBS10_API_URL=https://backup-extra.example.invalid:8007
PBS10_API_TOKEN_ID=
PBS10_API_TOKEN_SECRET=
```
Le token PBS est transmis avec le schema d'authentification `PBSAPIToken` sous la forme `TOKENID:TOKENSECRET`.
La collecte d'un PBS est active uniquement lorsque l'URL, le token ID et le token secret sont tous renseignes. Une URL seule ne bloque pas le demarrage, mais aucune collecte n'est lancee pour ce PBS.
Le service Docker lance la commande `pve-backup-report`. Pour produire un rapport, passer explicitement l'argument `--generate-pdf`.
Pour tester la connexion API :
```sh
docker compose run --rm pve-backup-report --check-api
```
Pour generer le PDF :
```sh
docker compose run --rm pve-backup-report --generate-pdf
```
## Permissions du token PVE
Le token doit etre limite a la lecture.
Permissions attendues selon l'implementation :
- lecture de la configuration du cluster ;
- lecture des stockages ;
- lecture des ressources VM/CT ;
- lecture des jobs de sauvegarde.
Pour le test de l'endpoint des jobs de sauvegarde, PVE peut exiger le privilege `Sys.Audit` sur le chemin `/`.
Si `--check-api` retourne :
```text
<endpoint>: HTTP 403 - Permission check failed (/, Sys.Audit)
```
ajouter ce privilege au role du token utilise, ou utiliser un role de lecture existant qui le contient.
Dans l'etat observe du projet, `/cluster/backup` existe bien et l'erreur attendue en cas de droit insuffisant est un `403`, pas un `404`.
### Diagnostic des droits effectifs du token
Un token PVE peut etre en mode privileges separes. Dans ce mode, les droits effectifs du token sont l'intersection des droits de l'utilisateur et des ACL propres au token.
Verifier d'abord le token :
```sh
pveum user token permissions <user@realm> <tokenid> --path /
```
Exemple :
```sh
pveum user token permissions backup-report@pve report --path /
```
Verifier ensuite les ACL :
```sh
pveum acl list
```
Pour ajouter explicitement `PVEAuditor` au token sur `/` :
```sh
pveum acl modify / --tokens 'backup-report@pve!report' --roles PVEAuditor --propagate 1
```
Si le token est en privileges separes, l'utilisateur parent doit aussi avoir un droit compatible :
```sh
pveum acl modify / --users backup-report@pve --roles PVEAuditor --propagate 1
```
Autre option, moins restrictive : creer ou modifier le token en privileges complets (`privsep=0`). Dans ce cas, le token reprend les droits de son utilisateur parent. Cette option est moins fine et doit etre choisie volontairement.
Eviter les privileges d'administration globaux.
## TLS
La verification TLS peut etre desactivee explicitement pour les connexions locales :
```env
PVE_VERIFY_TLS=false
PVE_CA_BUNDLE=
```
Lorsque `PVE_VERIFY_TLS=false`, `PVE_CA_BUNDLE` est ignore meme s'il est renseigne.
Quand cette option est utilisee explicitement, l'application journalise un avertissement unique et masque les avertissements repetes de `urllib3` pour conserver des logs lisibles.
Si la CA interne n'est pas reconnue par le conteneur, preferer un volume monte et renseigner `PVE_CA_BUNDLE`.
Exemple :
```yaml
volumes:
- ./reports:/reports
- /etc/ssl/local/pve-ca.pem:/etc/ssl/local/pve-ca.pem:ro
```
Puis :
```env
PVE_CA_BUNDLE=/etc/ssl/local/pve-ca.pem
```
## Repertoire de sortie
Le repertoire de sortie doit etre persistant.
Dans Docker, monter un volume hote :
```yaml
volumes:
- /srv/pve-backup-report/reports:/reports
```
Et configurer :
```env
REPORT_OUTPUT_DIR=/reports
```
Le conteneur doit avoir le droit d'ecrire dans ce repertoire.
Les rapports ne doivent pas etre produits dans un chemin ephemere si leur conservation est requise pour l'audit.
+301
View File
@@ -0,0 +1,301 @@
# Exploitation
[English version](../en/exploitation.md)
## Execution avec Docker
Docker est le mode d'exploitation recommande. Le conteneur execute une commande ponctuelle, ecrit les logs sur stdout/stderr, genere le rapport PDF puis se termine.
### Preparation
```sh
cp .env.example .env
mkdir -p reports
```
Dans `.env`, adapter les acces PVE/PBS et conserver en execution Docker :
```env
REPORT_OUTPUT_DIR=/reports
```
Le service Docker Compose monte `./reports` vers `/reports`, ce qui rend les PDF disponibles sur l'hote dans le repertoire `reports/`.
### Construction de l'image
```sh
docker compose build
```
L'image installe les dependances Python et les bibliotheques systeme necessaires a WeasyPrint.
### Verification de la configuration
```sh
docker compose run --rm pve-backup-report --check-config
```
### Test de connexion API
```sh
docker compose run --rm pve-backup-report --check-api
```
Cette commande teste `/nodes`, `/storage`, `/cluster` et l'endpoint configure dans `PVE_BACKUP_JOBS_ENDPOINT`.
Si `/cluster/backup` retourne `HTTP 403 - Permission check failed (/, Sys.Audit)`, le token fonctionne mais il lui manque le privilege `Sys.Audit` sur `/`.
### Generation du rapport PDF
```sh
docker compose run --rm pve-backup-report --generate-pdf
```
Le rapport est cree dans `REPORT_OUTPUT_DIR`. Le nom contient un horodatage et n'ecrase pas les rapports precedents.
Exemple de fichier genere sur l'hote :
```text
reports/rapport-sauvegardes-pve-2026-05-09-020000.pdf
```
### Commandes de diagnostic Docker
Inventaire :
```sh
docker compose run --rm pve-backup-report --dump-inventory
```
Couverture :
```sh
docker compose run --rm pve-backup-report --dump-coverage
```
Donnees de rapport au format JSON :
```sh
docker compose run --rm pve-backup-report --dump-report-data
```
Cette sortie est une previsualisation technique du modele de rapport. Les champs bruts sensibles sont filtres, mais le JSON contient des informations d'exploitation comme les noms de VM/CT, VMID, notes PVE, serveurs, datastores, namespaces, utilisateurs PBS et metadonnees de sauvegarde. Il doit donc etre traite comme une donnee interne et ne pas etre partage hors du perimetre d'exploitation/audit autorise.
Espaces des datastores PBS :
```sh
docker compose run --rm pve-backup-report --dump-pbs-storage-usages
```
Utilisateurs PBS utilises par les stockages PVE :
```sh
docker compose run --rm pve-backup-report --dump-pbs-users
```
Diagnostic d'une derniere sauvegarde manquante :
```sh
docker compose run --rm pve-backup-report --debug-last-backup-vmid <VMID>
```
La commande `docker compose run --rm pve-backup-report` sans argument ne genere pas de PDF. Pour produire le rapport, utiliser explicitement `--generate-pdf`.
## Execution directe en ligne de commande
Ce mode est utile pour le developpement ou le diagnostic hors conteneur.
Installation locale :
```sh
python3 -m venv .venv
. .venv/bin/activate
python -m ensurepip --upgrade
pip install -r requirements.txt
pip install -e .
```
La generation PDF utilise WeasyPrint. Hors Docker, l'hote doit fournir les bibliotheques systeme requises par WeasyPrint.
Avec WeasyPrint 62.x, conserver la contrainte `pydyf>=0.10,<0.11` pour eviter les erreurs de generation PDF liees a l'API interne de `pydyf`.
Commandes installees :
```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
```
Sans installation editable :
```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
```
En execution locale directe, `REPORT_OUTPUT_DIR` peut rester a `reports/` ou pointer vers un autre repertoire accessible par l'utilisateur courant.
Le meme fichier `.env` peut etre utilise en Docker et en execution locale. La valeur Docker `REPORT_OUTPUT_DIR=/reports` reste valide dans le conteneur avec le montage `./reports:/reports`. Hors Docker, si `/reports` n'est pas accessible, l'application utilise automatiquement le repertoire local `reports/` et l'indique dans les logs.
Il reste possible de forcer explicitement un chemin local :
```env
REPORT_OUTPUT_DIR=reports
```
## Politique de retention PBS
Pour alimenter le tableau `Politique de retention` et les tableaux `Retention des sauvegardes VM/CT`, renseigner les variables API du PBS concerne :
```env
PBS01_NAME=nom-affiche
PBS01_API_URL=https://backup.example.invalid:8007
PBS01_API_TOKEN_ID=
PBS01_API_TOKEN_SECRET=
PBS01_VERIFY_TLS=true
```
Pour plusieurs PBS, dupliquer ce bloc avec les prefixes `PBS02_*`, `PBS03_*`, `PBS04_*`, etc. Le rapport cree les sections de retention pour chaque PBS configure.
La collecte lit les prune jobs des PBS configures via `/config/prune`. Si un PBS est indisponible, si son token n'a pas les droits suffisants, ou si aucune politique n'est retournee, le rapport continue et ajoute une anomalie `pbs_retention`.
La collecte lit aussi les snapshots des datastores de chaque PBS configure. Les namespaces declarees dans les stockages PBS de PVE sont interrogees sur chaque PBS, y compris sur un PBS secondaire qui ne recoit pas directement les backups depuis PVE mais contient des sauvegardes synchronisees. Ces donnees alimentent les tableaux `Retention des sauvegardes VM/CT <PBS>`, y compris les VM/CT encore visibles sur PBS mais absentes de l'inventaire PVE. Elles sont marquees `Non-active sur PVE` dans le rapport.
Si une namespace PVE n'existe pas sur un datastore PBS teste, l'eventuel `HTTP 400 - Bad Request` retourne par PBS est ignore pour cette namespace non racine afin d'eviter une anomalie attendue.
Les tableaux de retention sont separes par namespace et affichent aussi le datastore, car une meme namespace peut exister sur plusieurs datastores d'un meme PBS.
Ils affichent aussi le nombre attendu de versions et un delta par rapport au nombre de snapshots visibles. Ce calcul depend d'une politique de retention active correspondant au meme serveur PBS, datastore et namespace.
Le rapport collecte aussi le statut des datastores de chaque PBS configure afin d'afficher l'espace total, l'espace consomme et l'espace libre.
Le statut du garbage collector de chaque datastore PBS est aussi collecte. Si le garbage collector est en cours, un avertissement est affiche uniquement sous les tableaux de retention du PBS/datastore concerne.
## Planification quotidienne
La planification recommandee sur Debian 13 peut etre faite avec systemd timer ou cron. Le conteneur et la CLI sont concus pour une execution ponctuelle : la commande genere le rapport puis se termine.
### Cron avec Docker Compose
Exemple de crontab cote hote pour lancer le rapport tous les jours a 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
```
Points importants :
- adapter `/srv/pve-backup-report` au chemin reel du depot ;
- conserver `REPORT_OUTPUT_DIR=/reports` dans `.env` pour Docker ;
- verifier que le repertoire hote `reports/` existe et est accessible ;
- utiliser `flock` pour eviter deux generations simultanees si une execution dure plus longtemps que prevu ;
- rediriger stdout/stderr vers un fichier de log ou vers le systeme de supervision de l'hote.
Pour tester exactement la commande planifiee :
```sh
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
```
### Cron en appel direct du script
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
```
Dans ce mode :
- le `cd` vers le depot permet de charger le fichier `.env` par defaut ;
- `REPORT_OUTPUT_DIR` peut rester a `/reports`, a `reports/`, ou pointer vers un chemin absolu accessible par l'utilisateur cron ;
- l'utilisateur cron doit avoir les droits de lecture sur `.env` et d'ecriture dans le repertoire des rapports ;
- les bibliotheques systeme requises par WeasyPrint doivent etre installees sur l'hote.
Pour tester exactement la commande planifiee :
```sh
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
```
Adapter l'horaire pour eviter les periodes de forte charge ou les fenetres de maintenance.
## Verification quotidienne
Apres execution, verifier :
- la presence d'un nouveau PDF ;
- le code retour de la commande ;
- les logs du conteneur ;
- la section des anomalies ;
- la liste des VM/CT sans sauvegarde.
## Conservation des preuves
Pour un usage audit, conserver les rapports dans un emplacement sauvegarde.
Recommandations :
- stockage persistant hors conteneur ;
- droits d'ecriture limites ;
- lecture autorisee aux personnes habilitees ;
- retention alignee avec la politique interne ;
- horloge systeme synchronisee par NTP.
## Codes de sortie recommandes
| Code | Signification |
| --- | --- |
| `0` | Rapport genere sans erreur bloquante. |
| `1` | Erreur de configuration. |
| `2` | Authentification PVE impossible. |
| `3` | API PVE indisponible. |
| `4` | Erreur d'ecriture du PDF. |
| `5` | Erreur inattendue. |
Une execution avec anomalies non bloquantes peut retourner `0` si le rapport est genere et que les anomalies sont visibles dans le PDF.
## Supervision
Surveiller au minimum :
- absence de rapport du jour ;
- echec de commande ;
- augmentation du nombre de VM/CT non sauvegardes ;
- apparition d'anomalies recurrentes ;
- expiration ou revocation du token PVE.
## Rotation des logs
Les logs doivent rester sur stdout/stderr pour s'integrer a Docker.
La rotation est geree par Docker ou par la plateforme d'exploitation.
## Restauration et audit
Ce rapport prouve la configuration observee au moment de son execution.
Il ne prouve pas a lui seul qu'une restauration est possible.
Pour une preuve plus forte, completer ce projet avec :
- controle des dernieres executions de jobs ;
- verification des snapshots presents dans PBS ;
- tests periodiques de restauration ;
- signature ou stockage immuable des rapports.
+257
View File
@@ -0,0 +1,257 @@
# Rapport PDF
[English version](../en/rapport-pdf.md)
## Objectif
Le PDF doit etre lisible par une equipe d'exploitation et exploitable comme preuve de suivi lors d'un audit.
Il doit privilegier la clarte, la date de generation, la couverture de sauvegarde et les exceptions.
Etat actuel : la generation PDF est implementee avec `WeasyPrint` a partir d'un template HTML/CSS.
L'ancien rendu `reportlab` reste present dans le depot comme reference technique, mais la commande `--generate-pdf` utilise le rendu WeasyPrint.
La langue du rapport WeasyPrint est configurable avec `REPORT_LANGUAGE=fr` ou `REPORT_LANGUAGE=en`.
La valeur par defaut reste `fr`.
Etat du rendu WeasyPrint :
- Page de garde complete (break-after page) : barre de logo sur fond blanc en haut, titre principal en bleu `#1f4e79` 32pt centre, barre de metadonnees (Generation, Version) ancree en bas de page via un spacer flex.
- Pied de page present sur toutes les pages y compris la page de garde : libelle de document a gauche, date de generation au centre, version a droite, separes du contenu par un filet horizontal.
- En-tetes de pages (hors premiere page) : titre du rapport a gauche, numero de page sur le total a droite.
- Table des matieres avec numeros de page automatiques (CSS `target-counter`) et hierarchie visuelle : titres de groupe en gras bleu, sous-sections indentees.
- Icones SVG devant chaque titre de section (histogramme, serveur, cylindre, horloge, engrenage, triangle d'alerte, bouclier, archive, croix, cercle gris avec point d'interrogation pour la namespace non renseignee) pour identifier rapidement chaque partie.
- En-tetes de sections avec bordure gauche bleue et fond gris tres clair pour distinguer les titres du contenu.
- Section Resume affichee en grille de KPI cards (7 colonnes sur 2 lignes) plutot qu'en tableau ; les indicateurs "Non sauvegardees" et "Anomalies" apparaissent en orange si leur valeur est superieure a zero.
- Tableaux avec en-tetes fonces, lignes alternees, et classes CSS appliquees aux cellules selon leur valeur : vert pour "Active" et "Succes", rouge/gras pour "Non-active" et "Echec", ambre pour "Indetermine", gris italique pour "non renseigne".
- Messages d'avertissement (GC PBS en cours) et messages vides distincts visuellement des tableaux.
- Le rapport reste lisible en impression noir et blanc : le style repose sur le gras, l'italique et la bordure gauche en plus de la couleur.
Le modele de donnees final du futur rapport est previsualisable avec :
```sh
PYTHONPATH=src python3 -m pve_backup_report --dump-report-data
```
Cette commande produit un JSON contenant le resume calcule, les stockages PBS, les jobs de sauvegarde, la couverture VM/CT et les anomalies.
Les champs bruts sensibles sont filtres dans cette sortie, mais `--dump-report-data` reste une sortie d'audit technique : elle contient des noms de VM/CT, VMID, notes PVE, serveurs, datastores, namespaces, utilisateurs PBS et metadonnees d'infrastructure. Elle doit etre traitee comme une donnee interne.
Generation PDF :
```sh
PYTHONPATH=src python3 -m pve_backup_report --generate-pdf
```
Le fichier est ecrit dans `REPORT_OUTPUT_DIR` avec un nom horodate. Un rapport existant n'est jamais ecrase.
## Nom du fichier
Format recommande :
```text
rapport-sauvegardes-pve-YYYY-MM-DD-HHMMSS.pdf
```
Exemple :
```text
rapport-sauvegardes-pve-2026-05-07-020000.pdf
```
Le script doit refuser d'ecraser un fichier existant ou generer un nom alternatif unique.
## Structure du rapport
### Page de garde
Structure implementee (page entiere, break-after page) :
1. **Barre logo** : logo Proxmox VE (PNG base64) sur fond blanc, separee par un filet gris en bas.
2. **Zone titre** : titre `{{ title }}` en bleu `#1f4e79` 32pt centre, sur fond blanc.
3. **Spacer** : div `flex: 1` qui absorbe l'espace vide et pousse le cartouche en bas.
4. **Barre de metadonnees** : fond gris clair avec bordure bleue en haut, deux elements centres — Generation (`{{ generated_at }}`) et Version (`{{ version }}`), separes par un filet vertical.
### Table des matieres
La table des matieres est placee apres la page de garde.
Elle est alimentee automatiquement depuis les titres de sections du rapport afin de faciliter la navigation dans le PDF.
### Resume executif
Indicateurs minimaux :
- nombre total de VM ;
- nombre total de CT ;
- nombre de VM/CT avec sauvegarde planifiee ;
- nombre de VM/CT sans sauvegarde planifiee ;
- nombre de VM/CT indetermines ;
- nombre de stockages PBS ;
- nombre d'anomalies.
Le resume calcule dans `ReportSummary` contient aussi :
- nombre de jobs actifs ;
- nombre de jobs inactifs ;
- nombre de sauvegardes vers storage non PBS ;
- nombre de sauvegardes vers PBS desactive ;
### Stockages PBS déclarés sur PVE
Tableau attendu :
| ID | Username | Serveur PBS | Datastore | Namespace | Actif |
| --- | --- | --- | --- | --- | --- |
Les secrets ne doivent jamais apparaitre.
La colonne `Actif` affiche `oui` lorsque le stockage PBS est actif dans PVE. Si le champ PVE `disable` est absent, le stockage est considere actif ; `disable=1` est affiche `non`.
### Utilisateurs PBS - Audit des accès
Ce tableau est place juste apres `Stockages PBS déclarés sur PVE`.
Tableau attendu :
| Serveur PBS | Auth-id | Storage PVE | Datastore | Namespace | Actif | Expiration | Email | Permissions | Commentaire |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
Les donnees viennent des `username` des stockages PBS PVE, rapproches des utilisateurs et permissions effectives exposes par les PBS configures.
Si l'auth-id PVE est un token de type `user@realm!token`, la colonne `Auth-id` conserve la valeur complete et les metadonnees utilisateur sont rapprochees avec `user@realm`.
Les secrets ne doivent jamais apparaitre. Les permissions affichees sont uniquement les privileges effectifs actifs sur le datastore/namespace cible.
### Espaces de stockage PBS
Tableau attendu :
| Serveur PBS | Datastore | Espace total | Espace consomme | Espace libre |
| --- | --- | --- | --- | --- |
Les valeurs sont alimentees depuis le statut des datastores de chaque PBS configure.
Les tailles sont affichees en unites lisibles (`Kio`, `Mio`, `Gio`, `Tio`).
### Sauvegarde des VM/CT par namespace
Les tableaux de sauvegarde sont regroupes sous un titre de niveau 1 `Sauvegarde des VM/CT`.
Les VM/CT sont affichees dans plusieurs tableaux, un tableau par namespace.
Le titre de chaque tableau indique la namespace concernee.
Colonnes attendues :
| VMID | Nom | Notes | Type | Noeud | Etat de la VM | Sauvegarde | Serveur PBS | Storage | Mode | Frequence de sauvegarde | Derniere sauvegarde |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
La colonne `Notes` reprend les notes renseignees sur la VM ou le CT dans PVE. Si aucune note n'est renseignee ou si elle ne peut pas etre collectee, la valeur affichee est `non renseigné`.
La colonne `Sauvegarde` affiche `Active` lorsqu'une sauvegarde PBS active est planifiee, sinon `Non-active`.
La colonne `Frequence de sauvegarde` reprend l'horaire des jobs de sauvegarde associes, c'est-a-dire la valeur affichee dans la colonne `Horaire` du tableau `Jobs de sauvegarde`.
La colonne `Serveur PBS` est deduite du storage PBS associe lorsque le storage est connu. Si `PBS_HOSTNAMES` contient une correspondance, le rendu est `IP (nom-hote)`.
La namespace n'est pas affichee comme colonne dans ces tableaux, car elle est deja portee par le titre du tableau.
Les tableaux sont tries par ordre alphabetique de namespace, puis les lignes de chaque tableau sont triees par ordre alphabetique sur `Frequence de sauvegarde`. Le `VMID` ne sert plus de critere principal de tri.
La colonne `Mode` traduit le mode technique PVE du job :
- `snapshot` devient `Aucune interruption attendue` ;
- `suspend` devient `Suspension temporaire` ;
- `stop` devient `Arret pendant sauvegarde`.
La colonne `Derniere sauvegarde` affiche l'etat `Succes`, `Echec` ou `Indetermine`, suivi de la date, de l'heure de fin et de la duree de la derniere tache `vzdump` connue pour la VM/CT lorsque cette duree est disponible.
Pour les jobs multi-VM/CT, cette information est deduite du log de la tache `vzdump`, pas seulement de la tache globale du job.
La valeur `non renseigne` est attendue si aucune tache `vzdump` terminee n'est encore disponible dans l'historique PVE accessible, par exemple pour une VM/CT ajoutee recemment a un job avant sa premiere sauvegarde effective.
Les lignes sans sauvegarde doivent etre visuellement identifiables.
Les lignes indeterminees doivent etre distinctes des lignes non sauvegardees.
### Retention des sauvegardes VM/CT par PBS et namespace
Les tableaux de retention sont regroupes sous un titre de niveau 1 `Retention des sauvegardes VM/CT`.
Les donnees de retention sont affichees dans plusieurs tableaux, separes par serveur PBS puis par namespace.
Le titre de chaque tableau indique le PBS et la namespace concernes.
Colonnes attendues :
| VMID | Nom VM/CT | Datastore | Etat PVE | Nombre de versions | Nombre attendu de versions | Delta | Plus ancienne | Plus recente | Taille |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
La colonne `Datastore` permet de distinguer deux sauvegardes appartenant a la meme namespace sur un meme PBS mais stockees dans des datastores differents.
Les colonnes `Nombre de versions`, `Plus ancienne`, `Plus recente` et `Taille` sont alimentees depuis le PBS concerne via la liste des snapshots du datastore et de la namespace concernes.
La colonne `Nombre attendu de versions` est calculee depuis la politique de retention active du meme serveur PBS, datastore et namespace, en additionnant les valeurs `keep-last`, `keep-hourly`, `keep-daily`, `keep-weekly`, `keep-monthly` et `keep-yearly` renseignees.
La colonne `Delta` affiche l'ecart `Nombre de versions - Nombre attendu de versions` avec un signe `+` ou `-` sauf lorsque l'ecart vaut zero. Si aucune politique active correspondante n'est trouvee, les colonnes `Nombre attendu de versions` et `Delta` affichent `non renseigne`.
La colonne `Taille` correspond a la taille de la sauvegarde la plus recente visible sur le PBS concerne.
La colonne `Etat PVE` indique si la VM/CT existe encore dans l'inventaire PVE (`Active sur PVE`) ou si elle n'y est plus presente (`Non-active sur PVE`).
Chaque serveur PBS peut disposer de plusieurs tableaux :
- `Retention des sauvegardes VM/CT <serveur PBS> - <namespace>`.
La namespace n'est pas affichee comme colonne dans ces tableaux, car elle est deja portee par le titre du tableau.
Si le garbage collector du PBS/datastore concerne est en cours au moment de la generation du rapport, un avertissement est affiche juste sous le titre du tableau concerne. Cet avertissement precise que le nombre de versions des sauvegardes des VM/CT peut apparaitre superieur au nombre de versions declarees.
Chaque tableau ne liste que les VM/CT pour lesquelles au moins un snapshot correspondant est visible sur le PBS concerne.
Les VM/CT encore visibles sur PBS mais absentes de l'inventaire PVE restent affichees dans le tableau et sont marquees `Non-active sur PVE`.
Les snapshots dont le namespace n'existe pas dans les namespaces declares sur PVE sont exclus de ces tableaux.
Les tableaux de retention sont classes par namespace, puis par nom de VM/CT et VMID lorsque l'information est disponible.
### Politique de retention
Le tableau `Politique de retention` est alimente depuis les PBS configures lorsque leurs variables `*_API_URL`, `*_API_TOKEN_ID` et `*_API_TOKEN_SECRET` sont renseignees.
La collecte lit les prune jobs PBS via `/config/prune` et affiche :
- serveur PBS ;
- datastore ;
- namespace ;
- planification ;
- etat actif/inactif ;
- colonnes `Derniere`, `Horaire`, `Jour`, `Semaine`, `Mois`, `Annee` ;
- profondeur `max-depth`.
Une namespace absente dans PBS est affichee comme `/`, c'est-a-dire la namespace racine.
### VM/CT sans sauvegarde
Cette section doit reprendre uniquement les charges non couvertes.
Elle doit etre courte et directement exploitable.
### Anomalies
Cette section liste les problemes de collecte ou d'interpretation.
Elle peut etre vide, mais doit alors indiquer qu'aucune anomalie n'a ete detectee.
## Lisibilite
Le rapport doit rester lisible en impression noir et blanc.
Ne pas dependre uniquement de la couleur pour signaler un risque.
Utiliser des libelles explicites :
- `Sauvegarde planifiee` ;
- `Non sauvegardee` ;
- `Indetermine`.
## Horodatage
Toutes les dates affichees doivent utiliser le fuseau configure.
Le fuseau horaire doit apparaitre dans le rapport.
## Conservation
Le rapport quotidien doit etre conserve dans un repertoire persistant.
La politique de retention des rapports generes est distincte des politiques de retention PBS et doit etre documentee dans l'exploitation si elle est ajoutee.