Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review. 📝 WalkthroughWalkthroughThe inbound delete path now handles applications already deleted on the agent. It records the deletion as expected, removes stale source-cache state, unmanages the application, and avoids recreation. Tests cover delete and UID-mismatch create races. ChangesApplication deletion race handling
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix · Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to Delete events for already-removed applications now complete without recreation while stale state is cleared. The supplied tests and checks indicate the change is ready to merge. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 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 |
|
Round 1 self-review.
Ready for review. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1101 +/- ##
==========================================
+ Coverage 48.31% 48.50% +0.18%
==========================================
Files 131 131
Lines 19659 19966 +307
==========================================
+ Hits 9499 9684 +185
- Misses 9307 9414 +107
- Partials 853 868 +15
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:
|
|
@jgwest @jannfis gentle ping on this one when you have a moment: fix for #1056, |
3932f74 to
7bd60e0
Compare
| // app can never be deleted again. | ||
| logCtx.Debug("application is not found, perhaps it is already deleted") | ||
| a.deletions.MarkExpected(sourceUIDForApp(app)) | ||
| if a.mode == types.AgentModeManaged { |
There was a problem hiding this comment.
There's one scenario where this can allow unauthorized deletion. The function deleteApplication is also invoked when there is a source UID mismatch between the incoming app and the existing app. The agent will then delete the existing app using deleteApplication and create the incoming app.
We are marking the deletion as expected using the source UID of the new app, thereby marking the deletion for the new app as legitimate instead of the old app. This allows the user to delete the app, and the agent will not recreate it because it was marked as expected.
There was a problem hiding this comment.
@chetan-rns you're right, thanks. In the mismatch path app is the incoming (new) application, so marking its source UID would have let a later user deletion of the recreated app go unreverted.
Done in 0c9e69b: deleteApplication returns NotFound from Get unchanged again, so the mismatch path behaves as on main (error, retry). The Delete event path now goes through deleteApplicationFromEvent, which handles NotFound by marking the event's source UID as expected, dropping the source cache entry and unmanaging. New test covers the mismatch case (Get NotFound after the identity check) and asserts the error is surfaced and the new UID is not marked expected. Could you take another look?
This comment was drafted with AI assistance and checked against the code.
When the principal sends a Delete event for an Application that no longer exists on the managed agent (for example because a user deleted it on the agent at the same time), deleteApplication returned the NotFound error from Get before marking the deletion as expected or dropping the source cache entry. The agent then treated the concurrent local deletion as unauthorized and recreated the Application, and every further deletion attempt was reverted as well, until the agent was restarted. Handle NotFound from Get in the Delete event path only. The new deleteApplicationFromEvent marks the deletion as expected for the source UID carried by the event, removes the stale source cache entry and unmanages the app. deleteApplication itself keeps returning NotFound: on a source UID mismatch the incoming app is the new one, and marking its source UID as expected would let a later user-initiated deletion of the recreated app go unreverted. The app is also unmanaged when Delete reports NotFound. Signed-off-by: KR Ravindra <42912207+KR-Ravindra@users.noreply.github.com>
7bd60e0 to
0c9e69b
Compare
|
Thanks @KR-Ravindra and thanks @chetan-rns! |
What does this PR do / why we need it:
Problem
When an Application is deleted on the principal and, at about the same time, by a user on the managed agent, the Delete event from the principal reaches the agent after the Application is already gone from the workload cluster. The agent fails to process that event, so it never learns that the deletion was legitimate. The concurrent local deletion is then treated as an unauthorized deletion and the Application is recreated; every further attempt to delete it is reverted the same way. The Application no longer exists on the principal, so nothing can ever remove it again until the agent is restarted.
Root cause
agent/inbound.go:875(deleteApplication): the lookup of the existing Application viaa.appManager.Getreturns the NotFound error straight to the caller. Everything that tells the agent the deletion is expected runs only after that lookup succeeds:a.deletions.MarkExpected(...)anda.sourceCache.Application.Delete(...). As a result the source UID of the deleted Application is never marked as an expected deletion and the stale source cache entry is kept, andaddAppDeletionToQueueinagent/outbound.gorecreates the Application throughRevertUserInitiatedDeletion.The NotFound case is already handled when
Deleteitself reports NotFound a few lines further down; only theGetpath was missing it.Fix
The Delete event path now goes through a new
deleteApplicationFromEvent. It callsdeleteApplicationand, if that returns NotFound fromGet, marks the deletion as expected for the source UID carried by the incoming event (sourceUIDForApp(app), which is the principal side UID and therefore the value of thesource-uidannotation on the agent side copy), drops the stale source cache entry in managed mode, unmanages the app, logs at debug level and returns nil. Errors other than NotFound are still returned unchanged.deleteApplicationitself keeps returning NotFound fromGet. It is also called on a source UID mismatch, where the incoming app is the new application; marking its source UID as expected there would let a later user-initiated deletion of the recreated app go unreverted (pointed out in review). That path therefore behaves as on main. Per review, the app is now also unmanaged in both NotFound cases.Which issue(s) this PR fixes:
Fixes #1056
How to test changes / Special notes to the reviewer:
How tested
Added the unit test
Delete: App already deleted on the agent must not be recreatedtoTest_ProcessIncomingAppWithUIDMismatchinagent/inbound_test.go. It seeds the source cache with the incoming UID, makes the backendGetreturn NotFound, sends a Delete event throughprocessIncomingApplication, and asserts that no error is returned, that noDelete/Createbackend call is made, that the source cache entry is gone and that the deletion is marked as expected.Added
Create: Old app gone before delete on UID mismatch must not mark the new UID as expectedto the same test: the identity check sees the old app, the secondGetreturns NotFound, and it asserts the error is surfaced, noDelete/Createis made and neither the new nor the old source UID is marked as an expected deletion.Before the fix:
After the fix:
go test ./agent/,go vet ./agent/andgo build ./...pass.Links
Checklist
This change was prepared with an AI agent operated by KR-Ravindra, who reviewed and tested it.
Summary by CodeRabbit