Files
kyleandClaude Opus 5.5 d4e821799c Add an admin page for managing collector API keys
Admins (Microsoft 365 sign-in names in BACKUP_DASH_ADMINS) get an
Admin link to /admin.html, where they can create, list and revoke the
API keys collectors use, instead of running manage.py on the server.

Backend
- /api/v1/admin/keys (list, create, revoke), admins only (403
  otherwise); the user comes from the headers nginx sets after sign-in
- Changes need an X-Requested-By header, which another site's page
  can't add, so a signed-in admin's browser can't be used to forge them
- A new key is returned once; only its hash is stored. Names are unique
  for good, so revoked keys' history stays unambiguous
- Keys record who created/revoked them and the company they last
  reported for (schema v2; databases migrate automatically on start)
- /api/v1/me reports is_admin; manage.py shares the key code and
  records itself as creator/revoker

Frontend
- admin.html / admin.js: name validation shown after interaction
  (:user-invalid, aria-invalid kept in sync), the one-time key with a
  copy button (falls back to selecting it if clipboard access is
  refused), a key table flagging keys quiet for over 24 hours, and
  revoking confirmed in a <dialog>; results announced in a status region
- Shared el() and signed-in helpers moved to dom.js / signed-in.js
- Mock mode (?mock=1) includes sample keys

Tested: 15 new backend tests (access, forged requests, names,
duplicates, revoking, last-used company, v1 -> v2 upgrade); in the
browser, every admin flow in mock mode and at phone width; end to end
through the nginx config with the real API (a key created on the API
works for ingest; revoking it makes ingest 401; non-admins see an
explanation and no Admin link).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 13:52:29 -06:00

84 lines
4.5 KiB
Markdown

# Veeam Backup & Replication collector
A PowerShell script that runs on each client's VBR server and reports job results to the dashboard.
It covers jobs returned by `Get-VBRJob`: VM backup, replication and backup copy jobs.
## Install (on the VBR server, as an administrator)
Requires PowerShell 7 installed machine-wide (`winget install Microsoft.PowerShell` or the MSI),
which VBR 13's Veeam module expects. The Microsoft Store version won't work, because the SYSTEM
account can't run it. The installer checks for this before changing anything.
1. Create a key for this server on the dashboard's **Admin** page, or on the dashboard host:
```bash
python manage.py create-key veeam-acme
```
2. Copy the whole `collectors` folder to the VBR server (the installer needs `common`
as well as this folder), then from `collectors\veeam` run, from PowerShell 7 (`pwsh`):
```powershell
.\Install-VeeamCollector.ps1 -ApiUrl https://backups.example.com -Tenant "Acme Corp"
```
It prompts for the key, then:
- writes `C:\ProgramData\BackupDashboard\veeam-collector.json` (readable only by SYSTEM and Administrators)
- copies the script to `C:\Program Files\BackupDashboard\`
- registers the scheduled task **Backup Dashboard - Veeam collector** (SYSTEM, every 60 minutes,
run by `C:\Program Files\PowerShell\7\pwsh.exe`; use `-PwshPath` if it's installed elsewhere)
3. Preview the payloads, then backfill 30 days so the history view is populated straight away
(from `pwsh`):
```powershell
& 'C:\Program Files\BackupDashboard\Send-VeeamBackupStatus.ps1' -DryRun
& 'C:\Program Files\BackupDashboard\Send-VeeamBackupStatus.ps1' -LookbackHours 720
```
Re-run the installer to change settings or update the script. It also installs
`BackupDashboard.Collector.psm1`, the code shared by all collectors, next to the script. To remove the collector,
delete the scheduled task and both `BackupDashboard` folders.
## What it sends
| Dashboard | Veeam |
|---|---|
| Company | `Tenant` from the config |
| Job | Job name. The job's GUID is the ID, so renaming a job in Veeam doesn't duplicate it |
| Status | Session result (Success / Warning / Failed). Any state other than Stopped is **Running**. A session that stopped with no result (e.g. cancelled) is reported as **Warning** |
| Started / finished | Session `CreationTime` / `EndTime` |
| Next scheduled | Job's next run, from the live schedule (`GetScheduleOptions()`). Sent as empty, so never flagged Overdue, for disabled jobs, chained ("run after") jobs, and immediate-mode backup copy jobs, which run whenever their source does |
| Message | Session reason, each VM or object that didn't succeed, and warning/error lines from the session log |
| Size | `BackupStats.BackupSize` |
**Backup copy jobs (VBR 12+):** Veeam records their sessions under hidden per-source "worker" jobs.
The collector files each worker session under its copy job (via the worker's `PolicyJobId`), so a
copy job gets one run per source job it copies, with the source in `copied_from`.
Each run covers the last 48 hours (`LookbackHours`), so a few missed runs (server rebooting, API
down) fill in automatically. Sessions already delivered are recorded in
`veeam-collector.state.json`. Running sessions are re-sent until they finish.
## Troubleshooting
- Log: `C:\ProgramData\BackupDashboard\veeam-collector.log` (rotates at 5 MB).
- Exit codes: `0` OK, `1` some jobs failed to send (they're retried next run), `2` setup failed
(config, Veeam module, or Veeam connection).
- `API key rejected`: the key was revoked or mistyped. Re-run the installer with a new key.
- A job shows **Unknown** on the dashboard: the collector sent the job but matched no sessions to it.
Run `.\Get-VeeamCollectorDiagnostics.ps1` (read-only). It lists sessions whose job ID matches no
job, plus the type and link properties of the jobs left without sessions.
- `Get-VBRBackupSession` loads every session in the VBR database. On a server with years of history,
this can make each run take a minute or more. The task's 30-minute limit and "don't start if
already running" setting keep that safe.
## Testing without Veeam
`tests/MockVeeam.ps1` defines stand-in `Get-VBRJob` / `Get-VBRBackupSession` cmdlets with a mix of
success, warning, failed, running and disabled jobs:
```powershell
. ./tests/MockVeeam.ps1
./Send-VeeamBackupStatus.ps1 -ConfigPath ./my-test-config.json -DryRun
```
## Not covered yet
- Veeam Agent jobs managed by VBR (`Get-VBRComputerBackupJob`), tape jobs, and SureBackup.
- Veeam Backup for Microsoft 365, which has its own PowerShell module.