backupchecks/TODO-cove-data-protection.md

250 lines
8.1 KiB
Markdown

# TODO: Cove Data Protection Integration
**Date:** 2026-02-23
**Status:** Research COMPLETED — Ready for implementation
**Priority:** Medium
---
## 🎯 Goal
Integrate Cove Data Protection (formerly N-able Backup / SolarWinds Backup) into Backupchecks for backup status monitoring via scheduled API polling. The integration runs server-side within the Backupchecks web application.
**Challenge:** Cove does NOT work with email notifications like other backup systems (Veeam, Synology, NAKIVO). We use the JSON-RPC API instead.
---
## ✅ Research Phase — COMPLETED (2026-02-23)
### Confirmed findings
- **API endpoint:** `https://api.backup.management/jsonapi`
- **Protocol:** JSON-RPC 2.0, POST requests, `Content-Type: application/json`
- **Authentication:** Login method returns a `visa` token — include in all subsequent calls
- **PartnerId:** `139124` (MCC Automatisering) — required for all queries, partnernaam is NIET nodig
- **Alle benodigde data is beschikbaar** — eerdere blockers (D02/D03 errors) waren door gebruik van legacy column codes. Vervangen door D10/D11.
- **Geen MSP-level beperking** — elke API user heeft dezelfde toegang. Toegang tot alle sub-customers via top-level account.
- **Geen EnumerateAccounts nodig** — `EnumerateAccountStatistics` met juiste columns geeft alles wat we nodig hebben.
### Officiële documentatie (van N-able support, Andrew Robinson)
- **Getting Started:** https://developer.n-able.com/n-able-cove/docs/getting-started
- **Column Codes:** https://developer.n-able.com/n-able-cove/docs/column-codes
- **Construct a Call:** https://developer.n-able.com/n-able-cove/docs/construct-a-json-rpc-api-call
- **Authorization:** https://developer.n-able.com/n-able-cove/docs/authorization
---
## 📡 API — Vastgestelde werking
### Stap 1: Login
```json
POST https://api.backup.management/jsonapi
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": "jsonrpc",
"method": "Login",
"params": {
"username": "{{cove_api_username}}",
"password": "{{cove_api_password}}"
}
}
```
**Response bevat:**
- `visa` — sessie token (meegeven in alle vervolg calls)
- `result.PartnerId` — het partner ID (139124 voor MCC Automatisering)
### Stap 2: EnumerateAccountStatistics
```json
{
"jsonrpc": "2.0",
"visa": "{{visa}}",
"id": "jsonrpc",
"method": "EnumerateAccountStatistics",
"params": {
"query": {
"PartnerId": 139124,
"StartRecordNumber": 0,
"RecordsCount": 250,
"Columns": [
"I1", "I18", "I8", "I78",
"D09F00", "D09F09", "D09F15", "D09F08",
"D1F00", "D1F15",
"D10F00", "D10F15",
"D11F00", "D11F15",
"D19F00", "D19F15",
"D20F00", "D20F15",
"D5F00", "D5F15",
"D23F00", "D23F15"
]
}
}
}
```
---
## 📋 Column codes — wat ze betekenen
### Device info
| Column | Betekenis | Type |
|--------|-----------|------|
| `I1` | Device naam (intern, uniek) | String |
| `I18` | Computer naam (leesbaar) — leeg bij M365 | String |
| `I8` | Klant naam | String |
| `I78` | Actieve datasources, bijv. `D01D02D10` | String |
### Datasource status (per datasource herhaalbaar)
| Suffix | Betekenis | Type |
|--------|-----------|------|
| `F00` | Status van laatste sessie | Int (zie tabel) |
| `F09` | Tijdstip laatste **succesvolle** sessie | Unix timestamp |
| `F15` | Tijdstip laatste sessie (ongeacht status) | Unix timestamp |
| `F08` | Color bar laatste 28 dagen (28 cijfers) | String |
### Status waarden (F00)
| Waarde | Betekenis |
|--------|-----------|
| `1` | In process |
| `2` | Failed ❌ |
| `3` | Aborted |
| `5` | Completed ✅ |
| `6` | Interrupted |
| `8` | CompletedWithErrors ⚠️ |
| `9` | InProgressWithFaults |
| `10` | OverQuota |
| `11` | NoSelection (geconfigureerd maar niets geselecteerd) |
| `12` | Restarted |
### Datasources
| Code | Naam | Gebruik |
|-------|------|---------|
| `D09` | Total (alle datasources gecombineerd) | Altijd aanwezig, beste voor overall status |
| `D1` | Files & Folders | Servers/workstations |
| `D2` | System State | Servers/workstations |
| `D10` | VssMsSql (SQL Server) | Servers met SQL |
| `D11` | VssSharePoint | Servers met SharePoint |
| `D19` | Microsoft 365 Exchange | M365 tenants |
| `D20` | Microsoft 365 OneDrive | M365 tenants |
| `D5` | Microsoft 365 SharePoint | M365 tenants |
| `D23` | Microsoft 365 Teams | M365 tenants |
**Let op:** D02 en D03 zijn legacy codes — gebruik D10 en D11.
### Device types herkennen via I78
- `I78` bevat waarden zoals `D01D02`, `D01D02D10`, `D19D20D05D23`
- Leeg `I18` veld = Microsoft 365 tenant
- Gevuld `I18` veld = server of workstation
### D09F08 — Color bar decoderen
28 tekens, elk karakter = 1 dag (oudste eerst):
- `5` = Completed ✅
- `8` = CompletedWithErrors ⚠️
- `2` = Failed ❌
- `1` = In progress
- `0` = Geen backup
---
## 🏗️ Architectuur beslissing
**Gekozen: Option 2 — Parallel Import System**
```
API Poller → Cove API Parser → JobRun (direct, zonder MailMessage)
```
Rationale:
- Schone scheiding van email- en API-gebaseerde imports
- Geen misbruik van MailMessage model voor data zonder email context
- Toekomstbestendig voor andere API-gebaseerde backup systemen
### Database wijzigingen nodig
- `JobRun.source_type` — nieuw veld: `"email"` of `"api"`
- `JobRun.external_id` — Cove `AccountId` als externe referentie
- `JobRun.mail_message` — moet nullable worden (of aparte tabel)
---
## 🔧 Implementatie fases
### Phase 1: Database migratie
- [ ] `source_type` veld toevoegen aan JobRun (`email` / `api`)
- [ ] `external_id` veld toevoegen aan JobRun (voor Cove AccountId)
- [ ] `mail_message` FK nullable maken voor API-gebaseerde runs
- [ ] Migratie schrijven en testen
### Phase 2: Cove API client
- [ ] Nieuw bestand: `app/services/cove_client.py`
- [ ] Login methode (visa token ophalen)
- [ ] `enumerate_account_statistics()` methode
- [ ] Paginatie afhandelen (RecordsCount / StartRecordNumber)
- [ ] Token verloop afhandelen (opnieuw inloggen)
- [ ] Error handling & retry logic
### Phase 3: Data transformatie
- [ ] Nieuw bestand: `app/services/cove_importer.py`
- [ ] Settings lijst omzetten naar dict voor makkelijke lookup
- [ ] Unix timestamps omzetten naar datetime
- [ ] Datasource status mappen naar Backupchecks status (success/warning/failed)
- [ ] Device type bepalen (server vs M365) via `I18` en `I78`
- [ ] JobRun records aanmaken per device
### Phase 4: Scheduled polling
- [ ] Cronjob of scheduled task (elke 15-60 minuten?)
- [ ] Duplicate detectie op basis van `external_id` + tijdstip
- [ ] Logging & audit trail
- [ ] Rate limiting respecteren
### Phase 5: UI aanpassingen
- [ ] Job Details: geen "Download EML" knop voor API-gebaseerde runs
- [ ] Indicatie dat job afkomstig is van Cove API (niet email)
- [ ] 28-daagse color bar eventueel tonen
### Phase 6: Configuratie
- [ ] Cove API credentials opslaan in SystemSettings
- [ ] PartnerId configureerbaar maken
- [ ] Polling interval instelbaar
---
## 🔑 API Credentials
- **API User:** `backupchecks-cove-01`
- **User ID:** `1665555`
- **PartnerId:** `139124`
- **Role:** SuperUser + SecurityOfficer
- **Portal:** https://backup.management/#/api-users
**BELANGRIJK:** Token opslaan in password manager — kan niet opnieuw worden opgevraagd!
---
## ❓ Openstaande vragen voor implementatie
1. Hoe slaan we de Cove API credentials veilig op in Backupchecks? (SystemSettings? Environment variable?)
2. Wat is de gewenste polling frequentie? (15 min / 30 min / 1 uur?)
3. Willen we historische data importeren bij eerste run, of alleen nieuwe sessies?
4. Willen we de 28-daagse color bar (`D09F08`) tonen in de UI?
5. Ondersteunen we meerdere Cove accounts (meerdere MSPs)?
---
## 🎯 Success Criteria (MVP)
- [ ] Backup status (success/warning/failed) per device zichtbaar in Backupchecks
- [ ] Klant naam en device naam correct gekoppeld
- [ ] Tijdstip laatste backup beschikbaar
- [ ] Zichtbaar in Daily Jobs & Run Checks
- [ ] Servers én Microsoft 365 tenants worden ondersteund
- [ ] Geen duplicates bij herhaalde polling
### Nice to Have
- [ ] 28-daagse history grafiek
- [ ] Per-datasource status (SQL, Exchange, etc.)
- [ ] Polling frequentie instelbaar per klant