Fixed Windows config profile not deleted properly - #51005
Conversation
|
@coderabbitai full review |
|
/agentic_review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Warning
- Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.
Pull request overview
Fixes stale Windows configuration profile rows when LocURI protection suppresses all <Delete> commands.
Changes:
- Deletes fully protected host-profile rows and refreshes status rollups.
- Adds unit and integration coverage for deletion, team transfer, and batch replacement scenarios.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
server/service/microsoft_mdm.go |
Cleans up suppressed removal rows in bulk. |
server/service/microsoft_mdm_test.go |
Adds reconciler regression tests. |
server/service/integration_mdm_profiles_test.go |
Verifies database, API, and rollup behavior. |
changes/49002-50698-50907-windows-profile-shared-locuri-row-cleanup |
Content unavailable under the exclusion policy. |
Files excluded by content exclusion policy (1)
- changes/49002-50698-50907-windows-profile-shared-locuri-row-cleanup
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Code Review by Qodo
1. Invalid new(c.Verb) call
|
WalkthroughWindows MDM reconciliation now removes stale host-profile rows when all profile LocURIs remain enforced by another profile and no device delete command is generated. The cleanup uses one batched datastore operation. Tests cover profile replacement, empty profiles, mirrored-team transfers, command output, host/profile deletion keys, and host-detail cleanup. A changelog entry documents the fix. Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@server/service/integration_mdm_profiles_test.go`:
- Around line 5170-5192: Wrap the rollup query and status comparison currently
inside the mysqltest.ExecAdhocSQL callback in a require.Eventually predicate,
retrying until the asynchronous refresh makes rollupStatus equal
recomputedStatus. Preserve the existing SQL and error handling, and return
whether the comparison succeeds from the predicate.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 83365afd-c40c-48d4-ad63-cdd921e81ce1
📒 Files selected for processing (4)
changes/49002-50698-50907-windows-profile-shared-locuri-row-cleanupserver/service/integration_mdm_profiles_test.goserver/service/microsoft_mdm.goserver/service/microsoft_mdm_test.go
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #51005 +/- ##
=======================================
Coverage 68.56% 68.56%
=======================================
Files 3985 3985
Lines 256692 256703 +11
Branches 13793 13793
=======================================
+ Hits 175992 176006 +14
+ Misses 65045 65043 -2
+ Partials 15655 15654 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
server/service/integration_mdm_profiles_test.go (1)
5108-5116: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winAssert that the retained profile remains on the host.
The test only proves that profile A is absent. It also passes if cleanup deletes both A and B rows. Query profile B after the batch replacement, assert that its host row remains, and assert that host details contain only profile B.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@server/service/integration_mdm_profiles_test.go` around lines 5108 - 5116, Extend the batch-replacement assertions after the existing profile A checks to query profile B’s host row and require it remains present. Update the host details validation to assert that the MDM profile list contains only profile B, while still confirming deleted profile A is absent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@server/service/microsoft_mdm_test.go`:
- Around line 1283-1314: The test
TestReconcileWindowsProfilesDeletesRemoveRowsWithNoLocURIs must also verify that
no delete command is emitted for the removed profile. After asserting
deletedRows, call result.requireNoDeleteCommands while preserving the existing
deleted-pair assertion.
---
Outside diff comments:
In `@server/service/integration_mdm_profiles_test.go`:
- Around line 5108-5116: Extend the batch-replacement assertions after the
existing profile A checks to query profile B’s host row and require it remains
present. Update the host details validation to assert that the MDM profile list
contains only profile B, while still confirming deleted profile A is absent.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 0ca9fc7f-db80-4593-992d-798e4bf7b63c
📒 Files selected for processing (3)
server/service/integration_mdm_profiles_test.goserver/service/microsoft_mdm.goserver/service/microsoft_mdm_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
- server/service/microsoft_mdm.go
| // TestReconcileWindowsProfilesDeletesRemoveRowsWithNoLocURIs covers a removed profile whose content yields no LocURIs, so the | ||
| // command comes back nil for a reason other than LocURI protection. | ||
| func TestReconcileWindowsProfilesDeletesRemoveRowsWithNoLocURIs(t *testing.T) { | ||
| const ( | ||
| hostUUID = "host-a" | ||
| keptProfile = "kept-profile-uuid" | ||
| removedProfile = "removed-profile-uuid" | ||
| ) | ||
| teamID := uint(1) | ||
|
|
||
| // The kept profile shares no LocURI with the removed one, so protection plays no part: the only reason there is no <Delete> | ||
| // is that the removed profile has no LocURIs to target. | ||
| result := runWindowsReconcileOnce(t, windowsReconcileSnapshot{ | ||
| hosts: []*fleet.WindowsHostReconcileInfo{{HostID: 1, UUID: hostUUID, TeamID: &teamID}}, | ||
| profiles: []*fleet.WindowsProfileForReconcile{ | ||
| {ProfileUUID: keptProfile, ProfileName: "Kept", TeamID: teamID, Checksum: []byte(windowsReconcileTestChecksum)}, | ||
| }, | ||
| current: map[string][]*fleet.MDMWindowsProfilePayload{ | ||
| hostUUID: { | ||
| installedRow(keptProfile, "Kept", hostUUID), | ||
| installedRow(removedProfile, "Removed", hostUUID), | ||
| }, | ||
| }, | ||
| contents: map[string][]byte{ | ||
| keptProfile: windowsTestProfileSyncML("Camera/AllowCamera"), | ||
| removedProfile: []byte(""), // empty (no LocURIs) | ||
| }, | ||
| }) | ||
|
|
||
| require.Len(t, result.deletedRows, 1, "a profile with no LocURIs must not stay stuck on the host") | ||
| require.Contains(t, result.deletedPairs(), hostProfileKey{hostUUID: hostUUID, profileUUID: removedProfile}) | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Assert that no delete command is emitted.
The test states that the removed profile has no LocURIs and the delete command is nil. It only asserts row deletion. Add result.requireNoDeleteCommands so a regression that emits an unnecessary <Delete> cannot pass.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@server/service/microsoft_mdm_test.go` around lines 1283 - 1314, The test
TestReconcileWindowsProfilesDeletesRemoveRowsWithNoLocURIs must also verify that
no delete command is emitted for the removed profile. After asserting
deletedRows, call result.requireNoDeleteCommands while preserving the existing
deleted-pair assertion.
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #50907 Resolves #50698 Resolves #49002 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Bug Fixes - Fixed stale Windows configuration profiles remaining in Host details after profile deletion, renaming, or host fleet transfers. - Host OS settings now accurately reflect the profiles still enforcing each setting. - Host status summaries are recalculated correctly after profile changes. - Prevented unnecessary device delete commands when another profile still protects the same settings. - Removed obsolete profile entries even when no device command is required. <!-- end of auto-generated comment: release notes by coderabbit.ai --> (cherry picked from commit 244262c)
Related issue:
Resolves #50907
Resolves #50698
Resolves #49002
Checklist for submitter
If some of the following don't apply, delete the relevant line.
changes/,orbit/changes/oree/fleetd-chrome/changes.See Changes files for more information.
Testing
Added/updated automated tests
Where appropriate, automated tests simulate multiple hosts and test for host isolation (updates to one hosts's records do not affect another)
QA'd all new/changed functionality manually
Summary by CodeRabbit
Bug Fixes