Return an error when refetching an Android host - #51119
Conversation
The refetch host API endpoint accepted refetch requests for Android hosts and returned 200, but Android hosts report their data through AMAPI and never run osquery or Apple MDM. Since refetch_requested is only cleared by the osquery detail query path and by the Apple MDM DeviceInformation response, the flag stayed true on the host forever, so the API reported a refetch as pending indefinitely on a host that will never perform one. The Host details page already hides the Refetch button for Android hosts and explains why, so return the same explanation to API callers instead of a success response that never refetches anything. Fixes fleetdm#50882
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Walkthrough
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 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 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #51119 +/- ##
==========================================
- Coverage 68.65% 68.64% -0.01%
==========================================
Files 3995 3995
Lines 257616 257620 +4
Branches 13802 13802
==========================================
- Hits 176855 176851 -4
- Misses 65028 65036 +8
Partials 15733 15733
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:
|
nilaway flagged the bre.Message access because it cannot see that require.ErrorAs guarantees a non-nil result. BadRequestError.Error() returns Message, so assert on the error text instead, which keeps the same assertion and matches how other tests in this package check typed errors.
Related issue: Resolves #50882
POST /api/v1/fleet/hosts/:id/refetchreturned200for Android hosts and flagged them for refetch, even though an Android host will never act on that flag.Android hosts report their data through AMAPI and run neither osquery nor Apple MDM.
refetch_requestedis only cleared in two places — the osquery detail query path (server/service/osquery.go) and the Apple MDMDeviceInformationresponse (server/service/apple_mdm.go) — so once set on an Android host it stayedtruepermanently. The API therefore reported a refetch as pending indefinitely on a host that will never perform one.The Host details page already disables the Refetch button for Android hosts and explains why (#50001), so this returns the same explanation to API callers:
Changes
server/service/hosts.go— reject refetch for Android hosts inRefetchHost, after the authorization check and before therefetch_requestedwrite, so the flag is never set.server/service/hosts_test.go— regression test asserting the error and thatUpdateHostRefetchRequestedis not called.docs/REST API/rest-api.md— document the Android behavior on the "Refetch host" endpoint.Notes for the reviewer
I used
fleet.BadRequestError(400) to matchfleet.ValidateAndroidWipeRequest, the closest existing precedent for an action that isn't supported on a given platform. Happy to switch toNewInvalidArgumentError(422) or adjust the wording if the group prefers something else.The device-authenticated route (
POST /device/{token}/refetch) is left alone, because none of its three authentication modes can be reached by an Android host:AuthnDeviceURL—AuthenticateIDeviceByURLexplicitly rejects any platform that isn't iOS or iPadOS.AuthnDeviceToken— device auth tokens are only issued by orbit/fleetd and conditional access, and Android hosts run neither.AuthnDeviceCertificate— resolves the host from an MDM SCEP certificate serial, which is part of Apple MDM enrollment.Guarding that path would add a host lookup to a route an Android host can't reach.
The background callers of
refetch_requested(calendar cron,apple_mdm.go,orbit.go) write through the datastore directly rather thanRefetchHost, so they are unaffected.Checklist for submitter
Changes file added for user-visible changes in
changes/,orbit/changes/oree/fleetd-chrome/changes.See Changes files for more information.
Input data is properly validated,
SELECT *is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters.Testing
Added/updated automated tests
QA'd all new/changed functionality manually
On the manual QA box: I verified this with automated tests rather than against a live Android host, since I don't have an Android Enterprise environment to enroll one.
TestRefetchHostAndroidNotSupportedfails with the fix reverted (returnsnilinstead of an error, i.e. the reported200), so it reproduces the reported behavior. I also checked that no existing integration test refetches an Android host — the refetch tests that assert200use Linux hosts (createHostsdefaults todebian/rhel/linux) or iOS/iPadOS hosts. Confirmation against a real enrolled Android device from someone with that setup would be welcome.Summary by CodeRabbit