Fix MDM last checkin and enrollment names to match API spec (#29073)

For #17710 

I focused too much on making sure we were returning the requested data
and got the actual property names wrong.

See https://github.com/fleetdm/fleet/pull/28940/files for proper names

- [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/Committing-Changes.md#changes-files)
for more information.
- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements)
- [x] Added/updated automated tests
- [x] Manual QA for all new/changed functionality
This commit is contained in:
Jordan Montgomery
2025-05-13 08:17:11 -04:00
committed by GitHub
parent ec9f6c3947
commit db3e3ff70b
7 changed files with 37 additions and 37 deletions
+1 -1
View File
@@ -1 +1 @@
Added mdm_last_enrolled_at and mdm_last_seen_at to host detail endpoints to return the last time a host enrolled, or re-enrolled in MDM and the last time a host checked in via MDM, respectively. This data is only returned for macOS, iOS and iPadOS hosts enrolled in Fleet MDM currently, other platforms will return null.
Added last_mdm_enrolled_at and last_mdm_checked_in_at to host detail endpoints to return the last time a host enrolled, or re-enrolled in MDM and the last time a host checked in via MDM, respectively. This data is only returned for macOS, iOS and iPadOS hosts enrolled in Fleet MDM currently, other platforms will return null.
@@ -53,8 +53,8 @@
"server_url": null,
"connected_to_fleet": null
},
"mdm_last_seen_at": null,
"mdm_last_enrolled_at": null,
"last_mdm_checked_in_at": null,
"last_mdm_enrolled_at": null,
"team_id": null,
"pack_stats": null,
"team_name": null,
@@ -30,6 +30,8 @@ spec:
label_updated_at: "0001-01-01T00:00:00Z"
labels: []
last_enrolled_at: "0001-01-01T00:00:00Z"
last_mdm_checked_in_at: null
last_mdm_enrolled_at: null
last_restarted_at: "0001-01-01T00:00:00Z"
logger_tls_period: 0
mdm:
@@ -41,8 +43,6 @@ spec:
pending_action: ""
server_url: null
connected_to_fleet: null
mdm_last_enrolled_at: null
mdm_last_seen_at: null
memory: 0
orbit_version: null
os_version: ""
+2 -2
View File
@@ -775,8 +775,8 @@ type HostDetail struct {
MaintenanceWindow *HostMaintenanceWindow `json:"maintenance_window,omitempty"`
EndUsers []HostEndUser `json:"end_users,omitempty"`
MDMLastEnrolledAt *time.Time `json:"mdm_last_enrolled_at"`
MDMLastSeenAt *time.Time `json:"mdm_last_seen_at"`
LastMDMEnrolledAt *time.Time `json:"last_mdm_enrolled_at"`
LastMDMCheckedInAt *time.Time `json:"last_mdm_checked_in_at"`
}
type HostEndUser struct {
+10 -10
View File
@@ -1210,7 +1210,7 @@ func (svc *Service) getHostDetails(ctx context.Context, host *fleet.Host, opts f
var profiles []fleet.HostMDMProfile
var mdmLastEnrollment *time.Time
var mdmLastSeen *time.Time
var mdmLastCheckedIn *time.Time
if ac.MDM.EnabledAndConfigured || ac.MDM.WindowsEnabledAndConfigured {
host.MDM.OSSettings = &fleet.HostMDMOSSettings{}
switch host.Platform {
@@ -1275,7 +1275,7 @@ func (svc *Service) getHostDetails(ctx context.Context, host *fleet.Host, opts f
// fetch host last seen at and last enrolled at times, currently only supported for
// Apple platforms
mdmLastEnrollment, mdmLastSeen, err = svc.ds.GetNanoMDMEnrollmentTimes(ctx, host.UUID)
mdmLastEnrollment, mdmLastCheckedIn, err = svc.ds.GetNanoMDMEnrollmentTimes(ctx, host.UUID)
if err != nil {
return nil, ctxerr.Wrap(ctx, err, "get host mdm enrollment times")
}
@@ -1335,14 +1335,14 @@ func (svc *Service) getHostDetails(ctx context.Context, host *fleet.Host, opts f
}
return &fleet.HostDetail{
Host: *host,
Labels: labels,
Packs: packs,
Batteries: &bats,
MaintenanceWindow: nextMw,
EndUsers: endUsers,
MDMLastEnrolledAt: mdmLastEnrollment,
MDMLastSeenAt: mdmLastSeen,
Host: *host,
Labels: labels,
Packs: packs,
Batteries: &bats,
MaintenanceWindow: nextMw,
EndUsers: endUsers,
LastMDMEnrolledAt: mdmLastEnrollment,
LastMDMCheckedInAt: mdmLastCheckedIn,
}, nil
}
+6 -6
View File
@@ -462,14 +462,14 @@ func TestHostDetailsMDMTimestamps(t *testing.T) {
require.NoError(t, err)
if testcase.platformIsApple {
assert.True(t, ds.GetNanoMDMEnrollmentTimesFuncInvoked)
require.NotNil(t, hostDetail.MDMLastEnrolledAt)
assert.Equal(t, *hostDetail.MDMLastEnrolledAt, ts1)
require.NotNil(t, hostDetail.MDMLastSeenAt)
assert.Equal(t, *hostDetail.MDMLastSeenAt, ts2)
require.NotNil(t, hostDetail.LastMDMEnrolledAt)
assert.Equal(t, *hostDetail.LastMDMEnrolledAt, ts1)
require.NotNil(t, hostDetail.LastMDMCheckedInAt)
assert.Equal(t, *hostDetail.LastMDMCheckedInAt, ts2)
} else {
assert.False(t, ds.GetNanoMDMEnrollmentTimesFuncInvoked)
assert.Nil(t, hostDetail.MDMLastEnrolledAt)
assert.Nil(t, hostDetail.MDMLastSeenAt)
assert.Nil(t, hostDetail.LastMDMEnrolledAt)
assert.Nil(t, hostDetail.LastMDMCheckedInAt)
}
})
}
+14 -14
View File
@@ -10839,8 +10839,8 @@ func (s *integrationMDMTestSuite) TestMDMEnrollDoesntClearLastEnrolledAtForMacOS
require.NotNil(t, hostResp.Host)
lastEnrolledAt := hostResp.Host.LastEnrolledAt
assert.Nil(t, hostResp.Host.MDMLastEnrolledAt)
assert.Nil(t, hostResp.Host.MDMLastSeenAt)
assert.Nil(t, hostResp.Host.LastMDMEnrolledAt)
assert.Nil(t, hostResp.Host.LastMDMCheckedInAt)
// Add the following here for debug: time.Sleep(2 * time.Second)
@@ -10853,10 +10853,10 @@ func (s *integrationMDMTestSuite) TestMDMEnrollDoesntClearLastEnrolledAtForMacOS
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", fleetHost.ID), nil, http.StatusOK, &hostResp)
require.NotNil(t, hostResp.Host)
assert.Equal(t, lastEnrolledAt, hostResp.Host.LastEnrolledAt)
assert.NotNil(t, hostResp.Host.MDMLastEnrolledAt)
assert.GreaterOrEqual(t, *hostResp.Host.MDMLastEnrolledAt, enrollTime)
assert.NotNil(t, hostResp.Host.MDMLastSeenAt)
assert.GreaterOrEqual(t, *hostResp.Host.MDMLastSeenAt, enrollTime)
assert.NotNil(t, hostResp.Host.LastMDMEnrolledAt)
assert.GreaterOrEqual(t, *hostResp.Host.LastMDMEnrolledAt, enrollTime)
assert.NotNil(t, hostResp.Host.LastMDMCheckedInAt)
assert.GreaterOrEqual(t, *hostResp.Host.LastMDMCheckedInAt, enrollTime)
}
func (s *integrationMDMTestSuite) TestConnectedToFleetWithoutCheckout() {
@@ -13408,10 +13408,10 @@ func (s *integrationMDMTestSuite) TestOTAEnrollment() {
require.Equal(t, hwModel, hostByIdentifierResp.Host.HardwareModel)
require.Equal(t, "darwin", hostByIdentifierResp.Host.Platform)
require.Nil(t, hostByIdentifierResp.Host.TeamID)
require.NotNil(t, hostByIdentifierResp.Host.MDMLastEnrolledAt)
assert.GreaterOrEqual(t, *hostByIdentifierResp.Host.MDMLastEnrolledAt, enrollTime)
require.NotNil(t, hostByIdentifierResp.Host.MDMLastSeenAt)
assert.GreaterOrEqual(t, *hostByIdentifierResp.Host.MDMLastSeenAt, enrollTime)
require.NotNil(t, hostByIdentifierResp.Host.LastMDMEnrolledAt)
assert.GreaterOrEqual(t, *hostByIdentifierResp.Host.LastMDMEnrolledAt, enrollTime)
require.NotNil(t, hostByIdentifierResp.Host.LastMDMCheckedInAt)
assert.GreaterOrEqual(t, *hostByIdentifierResp.Host.LastMDMCheckedInAt, enrollTime)
// create a team with a different enroll secret
var specResp applyTeamSpecsResponse
@@ -13436,10 +13436,10 @@ func (s *integrationMDMTestSuite) TestOTAEnrollment() {
require.Equal(t, "ipados", hostByIdentifierResp.Host.Platform)
require.NotNil(t, hostByIdentifierResp.Host.TeamID)
require.Equal(t, specResp.TeamIDsByName["newteam"], *hostByIdentifierResp.Host.TeamID)
require.NotNil(t, hostByIdentifierResp.Host.MDMLastEnrolledAt)
assert.GreaterOrEqual(t, *hostByIdentifierResp.Host.MDMLastEnrolledAt, enrollTime)
require.NotNil(t, hostByIdentifierResp.Host.MDMLastSeenAt)
assert.GreaterOrEqual(t, *hostByIdentifierResp.Host.MDMLastSeenAt, enrollTime)
require.NotNil(t, hostByIdentifierResp.Host.LastMDMEnrolledAt)
assert.GreaterOrEqual(t, *hostByIdentifierResp.Host.LastMDMEnrolledAt, enrollTime)
require.NotNil(t, hostByIdentifierResp.Host.LastMDMCheckedInAt)
assert.GreaterOrEqual(t, *hostByIdentifierResp.Host.LastMDMCheckedInAt, enrollTime)
}
func (s *integrationMDMTestSuite) TestSCEPProxy() {