Add English documentation
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
# Proxmox VE API
|
||||
|
||||
[Version francaise](../api-pve.md)
|
||||
|
||||
## Principles
|
||||
|
||||
The application must use the Proxmox VE REST API in read-only mode.
|
||||
|
||||
Current state: `pve_client.py` implements the reusable API connection and endpoint checks for `/nodes`, `/storage`, `/cluster` and the configured backup jobs endpoint.
|
||||
|
||||
Collection of PBS storages, backup jobs, VM/CT and pools is implemented. Coverage computation supports `vmid` values explicitly listed in active jobs, `all=1` jobs and `pool=<name>` jobs.
|
||||
|
||||
The base URL usually follows this format:
|
||||
|
||||
```text
|
||||
https://<pve-host>:8006/api2/json
|
||||
```
|
||||
|
||||
The script can query any available node in the cluster for global endpoints.
|
||||
|
||||
## Token Authentication
|
||||
|
||||
Recommended authentication uses the HTTP `Authorization` header.
|
||||
|
||||
Format:
|
||||
|
||||
```text
|
||||
Authorization: PVEAPIToken=<token-id>=<token-secret>
|
||||
```
|
||||
|
||||
The token secret must never be logged.
|
||||
|
||||
In `.env`, set:
|
||||
|
||||
```env
|
||||
PVE_API_TOKEN_ID=backup-report@pve!report
|
||||
PVE_API_TOKEN_SECRET=secret-provided-by-pve
|
||||
```
|
||||
|
||||
## Useful Endpoints
|
||||
|
||||
Exact endpoints must be checked against the target PVE version during implementation.
|
||||
|
||||
Commonly useful endpoints:
|
||||
|
||||
| Need | Indicative endpoint |
|
||||
| --- | --- |
|
||||
| PVE version | `/version` |
|
||||
| Cluster resources | `/cluster/resources` |
|
||||
| Storage configuration | `/storage` |
|
||||
| Cluster index | `/cluster` |
|
||||
| Backup jobs | `/cluster/backup` |
|
||||
| Pools | `/pools` and `/pools/{poolid}` |
|
||||
| Recent backup tasks | `/cluster/tasks` and `/nodes/{node}/tasks` |
|
||||
| QEMU VM configuration | `/nodes/{node}/qemu/{vmid}/config` |
|
||||
| LXC container configuration | `/nodes/{node}/lxc/{vmid}/config` |
|
||||
| Node status | `/nodes` |
|
||||
|
||||
The nominal value for backup jobs is:
|
||||
|
||||
```text
|
||||
/cluster/backup
|
||||
```
|
||||
|
||||
`PVE_BACKUP_JOBS_ENDPOINT` exists only as a technical override. The expected value remains `/cluster/backup`.
|
||||
|
||||
Observed privilege for backup jobs:
|
||||
|
||||
```text
|
||||
Sys.Audit on /
|
||||
```
|
||||
|
||||
If the token does not have this privilege, PVE typically returns `HTTP 403 - Permission check failed (/, Sys.Audit)`.
|
||||
|
||||
With separated-privilege tokens, seeing `PVEAuditor` in the UI is not always enough: check effective token permissions, not only parent user permissions.
|
||||
|
||||
Manual check:
|
||||
|
||||
```sh
|
||||
PYTHONPATH=src python3 -m pve_backup_report --check-api
|
||||
```
|
||||
|
||||
The command displays only status and returned item counts. It does not log the token secret.
|
||||
|
||||
Endpoints are tested independently. A failure on the backup jobs endpoint does not prevent displaying the result of `/nodes`, `/storage` and `/cluster`.
|
||||
|
||||
## PBS Storages
|
||||
|
||||
A PBS storage is usually identified by a type equivalent to `pbs`.
|
||||
|
||||
Expected fields to normalize:
|
||||
|
||||
- `storage` or equivalent ID;
|
||||
- `type`;
|
||||
- `server`;
|
||||
- `datastore`;
|
||||
- `namespace`;
|
||||
- `username`.
|
||||
|
||||
Not all fields are necessarily present depending on version or configuration.
|
||||
|
||||
The report must display an explicit value such as `not specified` when a non-critical field is missing. For active state, PVE usually exposes `disable=1` when a storage is disabled and omits the field when it is active. Missing `disable` must therefore be interpreted as active.
|
||||
|
||||
Current diagnostic command:
|
||||
|
||||
```sh
|
||||
PYTHONPATH=src python3 -m pve_backup_report --dump-inventory
|
||||
```
|
||||
|
||||
It displays normalized PBS storages without showing secrets.
|
||||
|
||||
## VM and CT Resources
|
||||
|
||||
Inventory can be built from `/cluster/resources`.
|
||||
|
||||
Filter useful types:
|
||||
|
||||
- `qemu` for VMs;
|
||||
- `lxc` for containers.
|
||||
|
||||
Useful fields:
|
||||
|
||||
- `vmid`;
|
||||
- `name`;
|
||||
- `type`;
|
||||
- `node`;
|
||||
- `status`.
|
||||
|
||||
VM/CT notes are collected from each guest configuration on its current node:
|
||||
|
||||
- QEMU VM: `/nodes/{node}/qemu/{vmid}/config`;
|
||||
- LXC container: `/nodes/{node}/lxc/{vmid}/config`.
|
||||
|
||||
The expected field is `description`. If a VM/CT configuration is unavailable, collection continues, a `guests` anomaly is added, and the note is displayed as `not specified` in the report.
|
||||
|
||||
Diagnostic command:
|
||||
|
||||
```sh
|
||||
PYTHONPATH=src python3 -m pve_backup_report --dump-coverage
|
||||
```
|
||||
|
||||
Final model preview command:
|
||||
|
||||
```sh
|
||||
PYTHONPATH=src python3 -m pve_backup_report --dump-report-data
|
||||
```
|
||||
|
||||
## Latest Completed Backup
|
||||
|
||||
Latest backup state is inferred from recent PVE tasks retrieved through `/cluster/tasks` and `/nodes/{node}/tasks` without parameters, then locally filtered on type `vzdump`.
|
||||
|
||||
The number of tasks inspected locally is controlled by `PVE_TASK_HISTORY_LIMIT`.
|
||||
The number of lines retrieved for each task log is controlled by `PVE_TASK_LOG_LIMIT`.
|
||||
|
||||
If task history is unavailable, report generation continues and an anomaly is added.
|
||||
|
||||
For jobs backing up multiple VM/CT, the per-VM/CT result is extracted from the task log through `/nodes/{node}/tasks/{upid}/log`.
|
||||
|
||||
Backup duration is primarily extracted from `Finished Backup of ... (HH:MM:SS)` lines, because this value corresponds to the specific VM/CT. As a fallback, for a simple task or a VM/CT explicitly started in the log, it can be computed from `starttime` and `endtime`.
|
||||
|
||||
The VMID is extracted from log lines `Starting Backup of ...`, `Finished Backup of ...` and `Backup of ... failed`. If the log is unavailable, the script falls back to fields `vmid`, `id`, `guest` or `upid`.
|
||||
|
||||
If a VM/CT has just been added to a job and has not yet had a completed backup in the available history, no latest backup result can be set.
|
||||
|
||||
## Backup Jobs
|
||||
|
||||
PVE backup jobs contain the information required to determine:
|
||||
|
||||
- whether the job is enabled or disabled;
|
||||
- target storage;
|
||||
- schedule;
|
||||
- VM/CT selection;
|
||||
- possible exclusions;
|
||||
- backup mode.
|
||||
|
||||
The implementation must distinguish:
|
||||
|
||||
- active jobs;
|
||||
- disabled jobs;
|
||||
- jobs targeting PBS;
|
||||
- jobs targeting another storage type.
|
||||
|
||||
Current state: jobs are normalized with ID, storage, schedule, enabled state, mode, raw selection and raw exclusions.
|
||||
|
||||
Coverage computation interprets explicit `vmid=...` lists, `all=1` jobs, `pool=<name>` jobs and simple exclusions.
|
||||
|
||||
If a job references a missing or uncollectable pool, the relevant coverage remains `indetermine`.
|
||||
|
||||
## Scheduling
|
||||
|
||||
PVE can express schedules using calendar syntax.
|
||||
|
||||
The report must display the raw value if complete parsing is not implemented.
|
||||
|
||||
If a readable interpretation is added, keep the source value too in case of ambiguity.
|
||||
|
||||
## Collection Anomalies
|
||||
|
||||
Add an anomaly when:
|
||||
|
||||
- an endpoint returns an error;
|
||||
- a response is incomplete;
|
||||
- a job references an unknown storage;
|
||||
- a VM selection type is not supported;
|
||||
- a field required for analysis is missing.
|
||||
|
||||
An anomaly must contain:
|
||||
|
||||
- severity;
|
||||
- affected component;
|
||||
- short message;
|
||||
- non-sensitive technical details.
|
||||
|
||||
## Client-Handled Errors
|
||||
|
||||
The client distinguishes:
|
||||
|
||||
- connection error or timeout;
|
||||
- HTTP error with endpoint and return code;
|
||||
- invalid JSON response;
|
||||
- JSON response without a `data` field.
|
||||
|
||||
Error messages must never include `PVE_API_TOKEN_SECRET`.
|
||||
|
||||
## TLS
|
||||
|
||||
The API connection can be run with `PVE_VERIFY_TLS=false` when the existing CA is incompatible with strict Python/OpenSSL validation and cannot be replaced.
|
||||
Reference in New Issue
Block a user