# 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