Skip to content

iOS/iPadOS device vitals: ack parsing + wiring (2/2) - #50047

Merged
nulmete merged 1 commit into
49984-ios-ipados-vitalsfrom
49984-vitals-ack-parsing
Aug 4, 2026
Merged

iOS/iPadOS device vitals: ack parsing + wiring (2/2)#50047
nulmete merged 1 commit into
49984-ios-ipados-vitalsfrom
49984-vitals-ack-parsing

Conversation

@nulmete

@nulmete nulmete commented Jul 28, 2026

Copy link
Copy Markdown
Member

Related issue: Relates to #49984

This is PR 2 of 2 for #49984, stacked on top of PR 1 (#50046) — diff here is scoped to just the ack-parsing/wiring work on top of that PR's storage and command changes. This PR parses the additional DeviceInformation ack fields requested by PR 1's command expansion and persists them via SetOrUpdateHostMDMAppleDeviceVitals. A persistence failure is logged rather than aborting the MDM check-in, since it's a non-critical write the next refetch will redo.

Checklist for submitter

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.
    See Changes files for more information.

It will be included in the feature branch.

Testing

  • Added/updated automated tests

  • QA'd all new/changed functionality manually

Enrolled my iPhone to Fleet (dual-SIM, physical + eSIM):

Screenshot 2026-07-28 at 10 57 00 AM

host_mdm_apple_device_vitals — populated as expected:

  • battery_level: 0.87, cellular_technology: 1, all is_* booleans, last_cloud_backup_date — parsed correctly
  • device_properties_attestation: JSON array of 2 base64 DER certs (leaf + "Apple Enterprise Attestation Sub CA" intermediate) — confirms it's a cert chain, not a boolean, per the deviation noted in the parent issue
  • mdm_options: {} — key present, no sub-options applicable → empty object, not NULL (expected omitempty behavior)
  • push_token: NULL — expected; Apple only returns this for user-channel enrollments, not device-channel
  • organization_info / accessibility_settings: NULL — expected, nothing configured/toggled
  • model_number, modem_firmware_version, supplemental_build_version, bluetooth_mac, wifi_mac, eas_device_identifier, itunes_store_account_hash — all populated

host_mdm_apple_service_subscriptions2 rows for one dual-SIM device, confirming the multi-slot replace logic works on real hardware:

  • CTSubscriptionSlotOne — fully populated (carrier, MCC/MNC, ICCID, phone number, etc.)
  • CTSubscriptionSlotTwo — only eid/imei populated, everything else NULL — an inactive/unprovisioned eSIM slot reporting a sparse row, exactly the shape the tests were built to mirror

Summary by CodeRabbit

  • New Features

    • Apple device management now captures and stores additional iPhone and iPad device vitals during device information refreshes.
    • Supports details such as Wi‑Fi MAC address, lost mode status, operating system information, accessibility settings, organization details, and service subscriptions.
  • Bug Fixes

    • Missing or unexpected device information no longer interrupts refresh processing.
    • Failures saving supplementary device vitals no longer prevent other device management actions from completing.

@nulmete

nulmete commented Jul 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Apple MDM refetch handling now parses device-vitals data from queryResponses and persists it through the datastore. New helpers support typed plist values, byte arrays, nested dictionaries, and service subscriptions, while specialized parsers map nested payloads into Fleet models. Persistence errors are logged without aborting refetch processing. Tests cover complete and sparse vitals, unexpected types, defensive paths, supplemental OS fields, and write failures.

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main change: parsing and wiring iOS/iPadOS device vitals acknowledgments.
Description check ✅ Passed The description identifies the related issue, explains the implementation, documents testing, and reports manual QA results with relevant details.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 49984-vitals-ack-parsing

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
server/service/apple_mdm_test.go (1)

7477-7493: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

require.False(t, ptr.ValOrZero(...)) passes when the field is nil.

For the keys the payload sets to <false/> (AwaitingConfiguration, DiagnosticSubmissionEnabled, IsDoNotDisturbInEffect, IsMDMLostModeEnabled, IsNetworkTethered, PersonalHotspotEnabled, AccessibilitySettings.ZoomEnabled), a regression that drops the value entirely would still satisfy these assertions. Assert non-nil first so "parsed false" is distinguished from "not parsed" — that's precisely the failure mode this test exists to catch.

💚 Example for one field (apply to the other false-valued bools)
-	require.False(t, ptr.ValOrZero(gotVitals.AwaitingConfiguration))
+	require.NotNil(t, gotVitals.AwaitingConfiguration)
+	require.False(t, *gotVitals.AwaitingConfiguration)
🤖 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/apple_mdm_test.go` around lines 7477 - 7493, Strengthen the
false-valued boolean assertions in the vitals parsing test by first requiring
each payload-set field to be non-nil, then asserting its value is false. Apply
this to AwaitingConfiguration, DiagnosticSubmissionEnabled,
IsDoNotDisturbInEffect, IsMDMLostModeEnabled, IsNetworkTethered,
PersonalHotspotEnabled, and AccessibilitySettings.ZoomEnabled, preserving the
existing true-valued assertions.
🤖 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.

Nitpick comments:
In `@server/service/apple_mdm_test.go`:
- Around line 7477-7493: Strengthen the false-valued boolean assertions in the
vitals parsing test by first requiring each payload-set field to be non-nil,
then asserting its value is false. Apply this to AwaitingConfiguration,
DiagnosticSubmissionEnabled, IsDoNotDisturbInEffect, IsMDMLostModeEnabled,
IsNetworkTethered, PersonalHotspotEnabled, and
AccessibilitySettings.ZoomEnabled, preserving the existing true-valued
assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1ade435f-e180-4804-891c-d2db64001c4c

📥 Commits

Reviewing files that changed from the base of the PR and between 51fb53d and c6bb9dd.

📒 Files selected for processing (3)
  • server/service/apple_mdm.go
  • server/service/apple_mdm_device_vitals.go
  • server/service/apple_mdm_test.go

@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.78082% with 12 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (49984-ios-ipados-vitals@0dec82b). Learn more about missing BASE report.

Files with missing lines Patch % Lines
server/service/apple_mdm_device_vitals.go 91.60% 8 Missing and 4 partials ⚠️
Additional details and impacted files
@@                    Coverage Diff                     @@
##             49984-ios-ipados-vitals   #50047   +/-   ##
==========================================================
  Coverage                           ?   68.11%           
==========================================================
  Files                              ?     3939           
  Lines                              ?   251064           
  Branches                           ?    13277           
==========================================================
  Hits                               ?   171009           
  Misses                             ?    64721           
  Partials                           ?    15334           
Flag Coverage Δ
backend 69.45% <91.78%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

nulmete added a commit that referenced this pull request Aug 4, 2026
…50046)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Relates to #49984

This is PR 1 of 2 for #49984, split for ease of review and stacked onto
a feature branch (`49984-ios-ipados-vitals`). This PR adds the MySQL
storage (`host_mdm_apple_device_vitals`,
`host_mdm_apple_service_subscriptions`) for the 29 additional iOS/iPadOS
vitals, and expands the `DeviceInformation` MDM command's `Queries`
array to request the corresponding Apple keys. It does not yet parse or
persist any new ack data — that's PR 2 (#50047), stacked on top of this
branch.

# Checklist for submitter

- [ ] 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.

It will be included in the feature branch.

- [x] 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

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually (see results on PR2)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added support for collecting and storing Apple MDM device vitals and
cellular service subscription details.
* Expanded Apple device information requests to include the full set of
supported query fields.
* Added database support for retaining device vitals and subscription
data.

* **Bug Fixes**
* Host deletion now also removes associated Apple MDM vitals and
subscription records.

* **Tests**
* Added coverage for vitals updates, nullable values, subscription
synchronization, database constraints, and device information requests.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Base automatically changed from 49984-vitals-storage-and-command to 49984-ios-ipados-vitals August 4, 2026 13:47
Parses the additional DeviceInformation ack fields requested by the
command expansion added in the prior PR and persists them via
SetOrUpdateHostMDMAppleDeviceVitals. A persistence failure is logged
rather than aborting the check-in, since it's a non-critical write the
next refetch will redo. Part of #49984.
@nulmete
nulmete force-pushed the 49984-vitals-ack-parsing branch from 140876b to 2d16ab0 Compare August 4, 2026 13:54
@nulmete
nulmete merged commit f9a18ff into 49984-ios-ipados-vitals Aug 4, 2026
24 checks passed
@nulmete
nulmete deleted the 49984-vitals-ack-parsing branch August 4, 2026 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants