From b804a92a052eaf996a60891c8d06ba9b27387c36 Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Tue, 19 May 2026 16:53:48 -0700 Subject: [PATCH] Session log: GuruRMM 4-bug fix + MSP360 backup integration 2026-05-19 Co-Authored-By: Claude Sonnet 4.6 --- .claude/commands/syncro.md | 2 + .claude/settings.json | 2 +- .../remediation-tool/references/tenants.md | 4 ++ .../scripts/onboard-tenant.sh | 1 + projects/msp-tools/guru-rmm | 2 +- .../2026-05-19-gururmm-backup-fixes.md | 54 +++++++++++++++++++ 6 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 session-logs/2026-05-19-gururmm-backup-fixes.md diff --git a/.claude/commands/syncro.md b/.claude/commands/syncro.md index 56cd4c6..2c0ea65 100644 --- a/.claude/commands/syncro.md +++ b/.claude/commands/syncro.md @@ -46,6 +46,8 @@ Create, update, close, comment on, and bill tickets in Syncro PSA. **Line-item `price_retail` MUST be set explicitly:** Earlier guidance to "omit `price_retail` and let Syncro auto-calc from the product rate" was wrong — the rate does NOT populate automatically. Fetch it with `GET /products/` → `.product.price_retail` and pass it on `add_line_item`. Omitting it leaves the line at $0.00 and the invoice posts at $0.00 (verified 2026-04-23 on #32203). +**Always pass `"taxable": false` explicitly on labor line items.** Labor products are configured with `taxable: false` in Syncro, but `add_line_item` via API does not inherit the product's taxable setting — it posts the line item as `taxable: true` regardless. Always include `"taxable": false` in the payload to match the product's configured value. + ## Implementation When invoked, use the Syncro REST API via `curl`. All requests include `?api_key=` as query parameter (NOT in header — Syncro uses query param auth). diff --git a/.claude/settings.json b/.claude/settings.json index 77454a1..604c081 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -12,7 +12,7 @@ "hooks": [ { "type": "command", - "command": "bash .claude/scripts/check-messages.sh", + "command": "bash \"D:/claudetools/.claude/scripts/check-messages.sh\"", "timeout": 15 } ] diff --git a/.claude/skills/remediation-tool/references/tenants.md b/.claude/skills/remediation-tool/references/tenants.md index 537c119..2c078b9 100644 --- a/.claude/skills/remediation-tool/references/tenants.md +++ b/.claude/skills/remediation-tool/references/tenants.md @@ -19,6 +19,7 @@ After full onboarding, update the Onboarded column below. | Curtis Plumbing | cparizona.onmicrosoft.com | d2d7ea54-9146-42d1-b99e-0da098550bde | NO | | | cwconcretellc.com | NETORGFT11452752.onmicrosoft.com | dfee2224-93cd-4291-9b09-6c6ce9bb8711 | NO | | | Dataforth Corporation | dataforth.com | 7dfa3ce8-c496-4b51-ab8d-bd3dcd78b584 | YES | All apps consented; Sec Inv + Exch Op + User Mgr roles assigned 2026-04-23; Exch Op Exchange Admin role added manually | +| DPA Inc (Deere Park Development) | dpa-inc.com | 11de2fe0-4fa4-4b28-a430-40bc20c86fc2 | NO | Richard Glabman — pending Tenant Admin consent | | Feline Limited Cat Clinic | felineltd.onmicrosoft.com | 1b5f38ef-b6c8-4b6d-9bfb-9250ea7e7994 | NO | | | Glaz-Tech Industries | glaztech.com | 82931e3c-de7a-4f74-87f7-fe714be1f160 | NO | | | Grabblaw | grabblaw.com | 032b383e-96e4-491b-880d-3fd3295672c3 | YES | Sec Inv + User Mgr + Tenant Admin consented; all roles assigned 2026-04-20 | @@ -94,6 +95,9 @@ https://login.microsoftonline.com/dfee2224-93cd-4291-9b09-6c6ce9bb8711/admincons Dataforth Corporation: https://login.microsoftonline.com/7dfa3ce8-c496-4b51-ab8d-bd3dcd78b584/adminconsent?client_id=709e6eed-0711-4875-9c44-2d3518c47063&redirect_uri=https://azcomputerguru.com&prompt=consent +DPA Inc (Richard Glabman): +https://login.microsoftonline.com/11de2fe0-4fa4-4b28-a430-40bc20c86fc2/adminconsent?client_id=709e6eed-0711-4875-9c44-2d3518c47063&redirect_uri=https://azcomputerguru.com&prompt=consent + Feline Limited Cat Clinic: https://login.microsoftonline.com/1b5f38ef-b6c8-4b6d-9bfb-9250ea7e7994/adminconsent?client_id=709e6eed-0711-4875-9c44-2d3518c47063&redirect_uri=https://azcomputerguru.com&prompt=consent diff --git a/.claude/skills/remediation-tool/scripts/onboard-tenant.sh b/.claude/skills/remediation-tool/scripts/onboard-tenant.sh index 74e827d..ef2fab1 100755 --- a/.claude/skills/remediation-tool/scripts/onboard-tenant.sh +++ b/.claude/skills/remediation-tool/scripts/onboard-tenant.sh @@ -59,6 +59,7 @@ SEC_INV_GRAPH_ROLES=( "dc5007c0-2d7d-4c42-879c-2dab87571379" "246dd0d5-5bd0-4def-940b-0421030a5b68" "498476ce-e0fe-48b0-b801-37ba7e2685c6" + "57f1cf28-c0c4-4ec3-9a30-19a2eaaf2f6e" # BitLockerKey.Read.All ) # Security Investigator — Exchange Online SEC_INV_EXO_ROLES=( diff --git a/projects/msp-tools/guru-rmm b/projects/msp-tools/guru-rmm index 20e7429..15f5bb0 160000 --- a/projects/msp-tools/guru-rmm +++ b/projects/msp-tools/guru-rmm @@ -1 +1 @@ -Subproject commit 20e74291e755192ae6bcaa901c14388c966c2690 +Subproject commit 15f5bb07b08b89650217efff3b97418c5c0936c2 diff --git a/session-logs/2026-05-19-gururmm-backup-fixes.md b/session-logs/2026-05-19-gururmm-backup-fixes.md new file mode 100644 index 0000000..0e8c110 --- /dev/null +++ b/session-logs/2026-05-19-gururmm-backup-fixes.md @@ -0,0 +1,54 @@ +# Session Log: GuruRMM — Bug Fixes & MSP360 Backup Integration + +**Date:** 2026-05-19 +**Duration:** ~3 hours + +## User +- **User:** Mike Swanson (mike) +- **Machine:** DESKTOP-0O8A1RL +- **Role:** admin + +## Summary + +Two areas of work: fixed 4 agent/server bugs identified from AD2's crash loop, then diagnosed and fixed the MSP360 backup integration which had never been configured. + +## Part 1: 4-Bug Fix (v0.6.25) + +Investigated why AD2's RMM agent was crash-looping and why the watchdog never fired. Root cause: agent 0.6.22/0.6.23 sent `user_inventory_report` WS messages the server couldn't deserialize. Also found a 48-minute update gap where the 30s grace period was too short for a Windows Defender scan of the new binary. + +### Bugs fixed (commits 56723b1, 2a7b74b): +1. **Grace period too short during updates** — extended to poll `agent_updates` for up to 2 hours before marking agent offline +2. **AgentMessage unknown variant crash** — silently skips unknown WS message types (forward-compat); previously crashed the WS handler +3. **WatchdogEvent not persisted** — WatchdogEvent messages now written to `watchdog_events` DB table +4. **Watchdog never started** — `ensure_watchdog_running()` was implemented but never called from `run_agent()`; `agent-id.txt` sidecar (required by `post_watchdog_alert`) was never written after WS auth +5. **Reviewer notes** (commit 2a7b74b): `has_in_progress_update` NULL gap fixed; `warn!` on WatchdogEvent DB insert failure + +## Part 2: MSP360 Backup Integration + +Backup tab on AD2 showed nothing. Root cause chain: + +1. `mspbackups_config` was empty — API credentials never configured. Fixed: loaded credentials from vault (`msp-tools/msp360-api.sops.yaml`), configured via API. +2. `POST /api/mspbackups/config` failed with `partner_id` NOT NULL violation — handler was passing `None`. Fixed in commit `3b29acc`. +3. Build pipeline only builds agents, not server. Discovered `build-server.sh` at `/opt/gururmm/build-server.sh`. +4. SOPS vault file had unquoted YAML timestamp (`created: 2026-05-18T00:00:00Z`) causing `time.Time` walk error. Fixed by quoting it in the raw YAML. +5. MSP360 `/api/Monitoring` returns `null` for `LastStart`/`NextStart` on 14 records — struct had `String` not `Option`. Fixed in commit `91630cb`. +6. Hostname match picked offline phantom AD2 agent (f6a99fe7, crash-loop duplicate) instead of online agent (49c66d8b). Fixed in commit `86e7ade`: `find_agent_by_hostname_ci` now orders by `status='online'` first. +7. `last_backup_at`/`next_backup_at` stored as NULL — MSP360 dates lack timezone (`2026-05-19T07:00:04`, not RFC3339). Fixed in commit `f146bd9`: fallback parser treats naive timestamps as UTC. + +### Result +AD2 backup tab now shows: `status: success`, last backup `2026-05-19T07:00:04Z`, next `2026-05-20T07:00:00Z`, plan `AD2 Image`, 6 files, ~355 GB. Syncs every 15 minutes. + +## Server Builds (manual — not triggered by agent pipeline) +- `sudo /opt/gururmm/build-server.sh` — used for all server-only deploys +- Server binary at `/opt/gururmm/gururmm-server`, service: `gururmm-server` + +## Commits (gururmm repo) +- `56723b1` — fix: 4-bug fix (grace period, AgentMessage forward-compat, WatchdogEvent, watchdog start) +- `2a7b74b` — fix: reviewer notes (NULL gap, warn! on watchdog event) +- `3b29acc` — fix: mspbackups config partner_id lookup +- `91630cb` — fix: handle null LastStart/NextStart in MSP360 BackupPlan +- `86e7ade` — fix: prefer online agent in MSP360 hostname match +- `f146bd9` — fix: parse MSP360 no-timezone dates as UTC + +## Anti-Pattern Added +Build-server.sh is separate from build-agents.sh. Server code changes require manual `sudo /opt/gururmm/build-server.sh` after pushing to Gitea.