diff --git a/server/datastore/mysql/android_test.go b/server/datastore/mysql/android_test.go index b322a47b8e..a6cc63cd20 100644 --- a/server/datastore/mysql/android_test.go +++ b/server/datastore/mysql/android_test.go @@ -182,7 +182,7 @@ func testAndroidMDMStats(t *testing.T, ds *Datastore) { }) require.NoError(t, err) nanoEnroll(t, ds, macHost, false) - err = ds.MDMAppleUpsertHost(testCtx(), macHost) + err = ds.MDMAppleUpsertHost(testCtx(), macHost, false) require.NoError(t, err) // create a non-mdm host diff --git a/server/datastore/mysql/apple_mdm.go b/server/datastore/mysql/apple_mdm.go index dbeffbce6a..e9ec426101 100644 --- a/server/datastore/mysql/apple_mdm.go +++ b/server/datastore/mysql/apple_mdm.go @@ -1320,13 +1320,13 @@ WHERE return devices, nil } -func (ds *Datastore) MDMAppleUpsertHost(ctx context.Context, mdmHost *fleet.Host) error { +func (ds *Datastore) MDMAppleUpsertHost(ctx context.Context, mdmHost *fleet.Host, fromPersonalEnrollment bool) error { appCfg, err := ds.AppConfig(ctx) if err != nil { return ctxerr.Wrap(ctx, err, "mdm apple upsert host get app config") } return ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error { - return ingestMDMAppleDeviceFromCheckinDB(ctx, tx, mdmHost, ds.logger, appCfg) + return ingestMDMAppleDeviceFromCheckinDB(ctx, tx, mdmHost, ds.logger, appCfg, fromPersonalEnrollment) }) } @@ -1336,6 +1336,7 @@ func ingestMDMAppleDeviceFromCheckinDB( mdmHost *fleet.Host, logger log.Logger, appCfg *fleet.AppConfig, + fromPersonalEnrollment bool, ) error { if mdmHost.HardwareSerial == "" { return ctxerr.New(ctx, "ingest mdm apple host from checkin expected device serial number but got empty string") @@ -1349,13 +1350,13 @@ func ingestMDMAppleDeviceFromCheckinDB( enrolledHostInfo, err := matchHostDuringEnrollment(ctx, tx, mdmEnroll, true, "", mdmHost.UUID, mdmHost.HardwareSerial) switch { case errors.Is(err, sql.ErrNoRows): - return insertMDMAppleHostDB(ctx, tx, mdmHost, logger, appCfg) + return insertMDMAppleHostDB(ctx, tx, mdmHost, logger, appCfg, fromPersonalEnrollment) case err != nil: return ctxerr.Wrap(ctx, err, "get mdm apple host by serial number or udid") default: - return updateMDMAppleHostDB(ctx, tx, enrolledHostInfo.ID, mdmHost, appCfg) + return updateMDMAppleHostDB(ctx, tx, enrolledHostInfo.ID, mdmHost, appCfg, fromPersonalEnrollment) } } @@ -1378,6 +1379,7 @@ func updateMDMAppleHostDB( hostID uint, mdmHost *fleet.Host, appCfg *fleet.AppConfig, + fromPersonalEnrollment bool, ) error { refetchRequested, lastEnrolledAt := mdmHostEnrollFields(mdmHost) @@ -1428,7 +1430,7 @@ func updateMDMAppleHostDB( return ctxerr.Wrap(ctx, err, "error clearing mdm apple host_mdm_actions") } - if err := upsertMDMAppleHostMDMInfoDB(ctx, tx, appCfg, false, hostID); err != nil { + if err := upsertMDMAppleHostMDMInfoDB(ctx, tx, appCfg, false, fromPersonalEnrollment, hostID); err != nil { return ctxerr.Wrap(ctx, err, "ingest mdm apple host upsert MDM info") } @@ -1441,6 +1443,7 @@ func insertMDMAppleHostDB( mdmHost *fleet.Host, logger log.Logger, appCfg *fleet.AppConfig, + fromPersonalEnrollment bool, ) error { refetchRequested, lastEnrolledAt := mdmHostEnrollFields(mdmHost) insertStmt := ` @@ -1489,7 +1492,7 @@ func insertMDMAppleHostDB( return ctxerr.Wrap(ctx, err, "ingest mdm apple host upsert label membership") } - if err := upsertMDMAppleHostMDMInfoDB(ctx, tx, appCfg, false, mdmHost.ID); err != nil { + if err := upsertMDMAppleHostMDMInfoDB(ctx, tx, appCfg, false, fromPersonalEnrollment, mdmHost.ID); err != nil { return ctxerr.Wrap(ctx, err, "ingest mdm apple host upsert MDM info") } return nil @@ -1626,6 +1629,7 @@ func createHostFromMDMDB( tx, appCfg, fromADE, + false, unmanagedHostIDs..., ); err != nil { return 0, nil, ctxerr.Wrap(ctx, err, "ingest mdm apple host upsert MDM info") @@ -1781,7 +1785,7 @@ func upsertHostDisplayNames(ctx context.Context, tx sqlx.ExtContext, hosts ...fl return nil } -func upsertMDMAppleHostMDMInfoDB(ctx context.Context, tx sqlx.ExtContext, appCfg *fleet.AppConfig, fromSync bool, hostIDs ...uint) error { +func upsertMDMAppleHostMDMInfoDB(ctx context.Context, tx sqlx.ExtContext, appCfg *fleet.AppConfig, fromSync, fromPersonalEnrollment bool, hostIDs ...uint) error { if len(hostIDs) == 0 { return nil } @@ -1816,12 +1820,12 @@ func upsertMDMAppleHostMDMInfoDB(ctx context.Context, tx sqlx.ExtContext, appCfg args := []interface{}{} parts := []string{} for _, id := range hostIDs { - args = append(args, enrolled, serverURL, fromSync, mdmID, false, id) - parts = append(parts, "(?, ?, ?, ?, ?, ?)") + args = append(args, enrolled, serverURL, fromSync, mdmID, false, id, fromPersonalEnrollment) + parts = append(parts, "(?, ?, ?, ?, ?, ?, ?)") } _, err = tx.ExecContext(ctx, fmt.Sprintf(` - INSERT INTO host_mdm (enrolled, server_url, installed_from_dep, mdm_id, is_server, host_id) VALUES %s + INSERT INTO host_mdm (enrolled, server_url, installed_from_dep, mdm_id, is_server, host_id, is_personal_enrollment) VALUES %s ON DUPLICATE KEY UPDATE enrolled = VALUES(enrolled)`, strings.Join(parts, ",")), args...) return ctxerr.Wrap(ctx, err, "upsert host mdm info") @@ -2163,7 +2167,7 @@ INSERT INTO hosts ( if err := upsertMDMAppleHostLabelMembershipDB(ctx, tx, ds.logger, *host); err != nil { return ctxerr.Wrap(ctx, err, "restore pending dep host label membership") } - if err := upsertMDMAppleHostMDMInfoDB(ctx, tx, ac, true, host.ID); err != nil { + if err := upsertMDMAppleHostMDMInfoDB(ctx, tx, ac, true, false, host.ID); err != nil { return ctxerr.Wrap(ctx, err, "ingest mdm apple host upsert MDM info") } diff --git a/server/datastore/mysql/apple_mdm_test.go b/server/datastore/mysql/apple_mdm_test.go index 3206e3f927..3027035848 100644 --- a/server/datastore/mysql/apple_mdm_test.go +++ b/server/datastore/mysql/apple_mdm_test.go @@ -888,7 +888,7 @@ func testIngestMDMAppleHostAlreadyExistsInFleet(t *testing.T, ds *Datastore) { Platform: "darwin", }) require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, host.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, host.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) hosts := listHostsCheckCount(t, ds, fleet.TeamFilter{User: test.UserAdmin}, fleet.HostListOptions{}, 1) require.Equal(t, testSerial, hosts[0].HardwareSerial) @@ -897,7 +897,7 @@ func testIngestMDMAppleHostAlreadyExistsInFleet(t *testing.T, ds *Datastore) { err = ds.MDMAppleUpsertHost(ctx, &fleet.Host{ UUID: testUUID, HardwareSerial: testSerial, - }) + }, false) require.NoError(t, err) hosts = listHostsCheckCount(t, ds, fleet.TeamFilter{User: test.UserAdmin}, fleet.HostListOptions{}, 1) @@ -926,7 +926,7 @@ func testIngestMDMNonDarwinHostAlreadyExistsInFleet(t *testing.T, ds *Datastore) Platform: "linux", }) require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, host.ID, false, false, "https://fleetdm.com", true, "Fleet MDM", "") + err = ds.SetOrUpdateMDMData(ctx, host.ID, false, false, "https://fleetdm.com", true, "Fleet MDM", "", false) require.NoError(t, err) hosts := listHostsCheckCount(t, ds, fleet.TeamFilter{User: test.UserAdmin}, fleet.HostListOptions{}, 1) require.Equal(t, testSerial, hosts[0].HardwareSerial) @@ -936,7 +936,7 @@ func testIngestMDMNonDarwinHostAlreadyExistsInFleet(t *testing.T, ds *Datastore) UUID: testUUID, HardwareSerial: testSerial, Platform: "darwin", - }) + }, false) require.NoError(t, err) hosts = listHostsCheckCount(t, ds, fleet.TeamFilter{User: test.UserAdmin}, fleet.HostListOptions{}, 2) @@ -981,7 +981,7 @@ func testIngestMDMAppleIngestAfterDEPSync(t *testing.T, ds *Datastore) { err = ds.MDMAppleUpsertHost(ctx, &fleet.Host{ UUID: testUUID, HardwareSerial: testSerial, - }) + }, false) require.NoError(t, err) hosts = listHostsCheckCount(t, ds, fleet.TeamFilter{User: test.UserAdmin}, fleet.HostListOptions{}, 1) @@ -1001,7 +1001,7 @@ func testIngestMDMAppleCheckinBeforeDEPSync(t *testing.T, ds *Datastore) { UUID: testUUID, HardwareSerial: testSerial, HardwareModel: testModel, - }) + }, false) require.NoError(t, err) hosts := listHostsCheckCount(t, ds, fleet.TeamFilter{User: test.UserAdmin}, fleet.HostListOptions{}, 1) @@ -1035,7 +1035,7 @@ func testIngestMDMAppleCheckinMultipleIngest(t *testing.T, ds *Datastore) { err := ds.MDMAppleUpsertHost(ctx, &fleet.Host{ UUID: testUUID, HardwareSerial: testSerial, - }) + }, false) require.NoError(t, err) hosts := listHostsCheckCount(t, ds, fleet.TeamFilter{User: test.UserAdmin}, fleet.HostListOptions{}, 1) @@ -1046,7 +1046,7 @@ func testIngestMDMAppleCheckinMultipleIngest(t *testing.T, ds *Datastore) { err = ds.MDMAppleUpsertHost(ctx, &fleet.Host{ UUID: testUUID, HardwareSerial: testSerial, - }) + }, false) require.NoError(t, err) hosts = listHostsCheckCount(t, ds, fleet.TeamFilter{User: test.UserAdmin}, fleet.HostListOptions{}, 1) @@ -1062,7 +1062,7 @@ func testUpdateHostTablesOnMDMUnenroll(t *testing.T, ds *Datastore) { UUID: testUUID, HardwareSerial: testSerial, Platform: "darwin", - }) + }, false) require.NoError(t, err) profiles := []*fleet.MDMAppleConfigProfile{ @@ -2048,7 +2048,7 @@ func nanoEnrollAndSetHostMDMData(t *testing.T, ds *Datastore, host *fleet.Host, expectedMDMServerURL, err := apple_mdm.ResolveAppleEnrollMDMURL(ac.ServerSettings.ServerURL) require.NoError(t, err) nanoEnroll(t, ds, host, withUser) - err = ds.SetOrUpdateMDMData(ctx, host.ID, false, true, expectedMDMServerURL, true, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, host.ID, false, true, expectedMDMServerURL, true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) } @@ -2059,7 +2059,7 @@ func nanoEnrollUserDeviceAndSetHostMDMData(t *testing.T, ds *Datastore, host *fl expectedMDMServerURL, err := apple_mdm.ResolveAppleEnrollMDMURL(ac.ServerSettings.ServerURL) require.NoError(t, err) nanoEnrollUserDevice(t, ds, host) - err = ds.SetOrUpdateMDMData(ctx, host.ID, false, true, expectedMDMServerURL, true, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, host.ID, false, true, expectedMDMServerURL, true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) } @@ -4778,7 +4778,7 @@ func TestHostDEPAssignments(t *testing.T) { require.True(t, *h.DEPAssignedToFleet) // simulate osquery report of MDM detail query - err = ds.SetOrUpdateMDMData(ctx, testHost.ID, false, true, expectedMDMServerURL, true, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, testHost.ID, false, true, expectedMDMServerURL, true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) // enrollment status changes to "On (automatic)" @@ -4821,7 +4821,7 @@ func TestHostDEPAssignments(t *testing.T) { require.True(t, *h.DEPAssignedToFleet) // simulate osquery report of MDM detail query reflecting re-enrollment to MDM - err = ds.SetOrUpdateMDMData(ctx, testHost.ID, false, true, expectedMDMServerURL, true, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, testHost.ID, false, true, expectedMDMServerURL, true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) // host MDM row is re-created when osquery reports MDM detail query @@ -4843,7 +4843,7 @@ func TestHostDEPAssignments(t *testing.T) { // simulate osquery report of MDM detail query with empty server URL (signals unenrollment // from MDM) - err = ds.SetOrUpdateMDMData(ctx, testHost.ID, false, false, "", false, "", "") + err = ds.SetOrUpdateMDMData(ctx, testHost.ID, false, false, "", false, "", "", false) require.NoError(t, err) // host MDM row is reset to defaults when osquery reports MDM detail query with empty server URL @@ -4879,7 +4879,7 @@ func TestHostDEPAssignments(t *testing.T) { manualOrbitNodeKey := "manual-orbit-node-key" manualDeviceToken := "manual-device-token" - err = ds.MDMAppleUpsertHost(ctx, &fleet.Host{HardwareSerial: manualSerial, UUID: manualUUID}) + err = ds.MDMAppleUpsertHost(ctx, &fleet.Host{HardwareSerial: manualSerial, UUID: manualUUID}, false) require.NoError(t, err) var manualHostID uint @@ -5072,7 +5072,7 @@ func testMDMAppleResetEnrollment(t *testing.T, ds *Datastore) { cmd, err := ds.GetHostBootstrapPackageCommand(ctx, host.UUID) require.NoError(t, err) require.Equal(t, "command-uuid", cmd) - err = ds.SetOrUpdateMDMData(ctx, host.ID, false, true, "foo.mdm.example.com", true, "", "") + err = ds.SetOrUpdateMDMData(ctx, host.ID, false, true, "foo.mdm.example.com", true, "", "", false) require.NoError(t, err) sum, err := ds.GetMDMAppleBootstrapPackageSummary(ctx, uint(0)) @@ -6067,7 +6067,7 @@ func TestRestorePendingDEPHost(t *testing.T) { require.Equal(t, depHostID, h.ID) // simulate osquery report of MDM detail query - err = ds.SetOrUpdateMDMData(ctx, depHostID, false, true, expectedMDMServerURL, true, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, depHostID, false, true, expectedMDMServerURL, true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) // enrollment status changes to "On (automatic)" @@ -6358,7 +6358,7 @@ func testListIOSAndIPadOSToRefetch(t *testing.T, ds *Datastore) { HardwareModel: "iPhone14,6", Platform: "ios", OsqueryHostID: ptr.String("iOS0_OSQUERY_HOST_ID"), - }) + }, false) require.NoError(t, err) iOS0, err := ds.HostByIdentifier(ctx, "iOS0_SERIAL") require.NoError(t, err) @@ -6369,7 +6369,7 @@ func testListIOSAndIPadOSToRefetch(t *testing.T, ds *Datastore) { HardwareModel: "iPad13,18", Platform: "ipados", OsqueryHostID: ptr.String("iPadOS0_OSQUERY_HOST_ID"), - }) + }, false) require.NoError(t, err) iPadOS0, err := ds.HostByIdentifier(ctx, "iPadOS0_SERIAL") require.NoError(t, err) @@ -6447,7 +6447,7 @@ func testMDMAppleUpsertHostIOSIPadOS(t *testing.T, ds *Datastore) { HardwareSerial: fmt.Sprintf("test-serial-%d", i), HardwareModel: "test-hw-model", Platform: platform, - }) + }, false) require.NoError(t, err) h, err := ds.HostByIdentifier(ctx, fmt.Sprintf("test-uuid-%d", i)) require.NoError(t, err) @@ -6474,7 +6474,7 @@ func testMDMAppleUpsertHostIOSIPadOS(t *testing.T, ds *Datastore) { HardwareSerial: fmt.Sprintf("test-serial-%d", i), HardwareModel: "test-hw-model-2", Platform: platform, - }) + }, false) require.NoError(t, err) h, err = ds.HostByIdentifier(ctx, fmt.Sprintf("test-uuid-%d", i)) require.NoError(t, err) @@ -6501,7 +6501,7 @@ func testMDMAppleUpsertHostIOSIPadOS(t *testing.T, ds *Datastore) { HardwareSerial: "test-serial-2", HardwareModel: "test-hw-model", Platform: "darwin", - }) + }, false) require.NoError(t, err) h, err := ds.HostByIdentifier(ctx, "test-uuid-2") require.NoError(t, err) @@ -6581,7 +6581,7 @@ func testMDMAppleProfilesOnIOSIPadOS(t *testing.T, ds *Datastore) { HardwareModel: "iPhone14,6", Platform: "ios", OsqueryHostID: ptr.String("iOS0_OSQUERY_HOST_ID"), - }) + }, false) require.NoError(t, err) iOS0, err := ds.HostByIdentifier(ctx, "iOS0_UUID") require.NoError(t, err) @@ -6592,7 +6592,7 @@ func testMDMAppleProfilesOnIOSIPadOS(t *testing.T, ds *Datastore) { HardwareModel: "iPad13,18", Platform: "ipados", OsqueryHostID: ptr.String("iPadOS0_OSQUERY_HOST_ID"), - }) + }, false) require.NoError(t, err) iPadOS0, err := ds.HostByIdentifier(ctx, "iPadOS0_UUID") require.NoError(t, err) diff --git a/server/datastore/mysql/hosts.go b/server/datastore/mysql/hosts.go index a7dd43cedf..1a1d7e2308 100644 --- a/server/datastore/mysql/hosts.go +++ b/server/datastore/mysql/hosts.go @@ -911,6 +911,7 @@ const hostMDMJoin = ` hm.enrolled, hm.installed_from_dep, hm.enrollment_status, + hm.is_personal_enrollment, hm.server_url, hm.mdm_id, hm.host_id, @@ -1333,7 +1334,9 @@ func filterHostsByMDM(sql string, opt fleet.HostListOptions, params []interface{ case fleet.MDMEnrollStatusAutomatic: sql += ` AND hmdm.enrolled = 1 AND hmdm.installed_from_dep = 1` case fleet.MDMEnrollStatusManual: - sql += ` AND hmdm.enrolled = 1 AND hmdm.installed_from_dep = 0` + sql += ` AND hmdm.enrolled = 1 AND hmdm.installed_from_dep = 0 AND hmdm.is_personal_enrollment = 0` + case fleet.MDMEnrollStatusPersonal: + sql += ` AND hmdm.enrolled = 1 AND hmdm.installed_from_dep = 0 AND hmdm.is_personal_enrollment = 1` case fleet.MDMEnrollStatusEnrolled: sql += ` AND hmdm.enrolled = 1` case fleet.MDMEnrollStatusPending: @@ -3972,6 +3975,7 @@ func (ds *Datastore) SetOrUpdateMDMData( installedFromDep bool, name string, fleetEnrollmentRef string, + isPersonalEnrollment bool, ) error { var mdmID *uint if serverURL != "" { @@ -3984,9 +3988,9 @@ func (ds *Datastore) SetOrUpdateMDMData( return ds.updateOrInsert( ctx, - `UPDATE host_mdm SET enrolled = ?, server_url = ?, installed_from_dep = ?, mdm_id = ?, is_server = ?, fleet_enroll_ref = ? WHERE host_id = ?`, - `INSERT INTO host_mdm (enrolled, server_url, installed_from_dep, mdm_id, is_server, fleet_enroll_ref, host_id) VALUES (?, ?, ?, ?, ?, ?, ?)`, - enrolled, serverURL, installedFromDep, mdmID, isServer, fleetEnrollmentRef, hostID, + `UPDATE host_mdm SET enrolled = ?, server_url = ?, installed_from_dep = ?, mdm_id = ?, is_server = ?, fleet_enroll_ref = ?, is_personal_enrollment = ? WHERE host_id = ?`, + `INSERT INTO host_mdm (enrolled, server_url, installed_from_dep, mdm_id, is_server, fleet_enroll_ref, is_personal_enrollment, host_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, + enrolled, serverURL, installedFromDep, mdmID, isServer, fleetEnrollmentRef, isPersonalEnrollment, hostID, ) } @@ -4224,6 +4228,7 @@ func (ds *Datastore) GetHostMDM(ctx context.Context, hostID uint) (*fleet.HostMD hm.server_url, hm.installed_from_dep, hm.mdm_id, + hm.is_personal_enrollment, COALESCE(hm.is_server, false) AS is_server, COALESCE(mdms.name, ?) AS name, hdep.assign_profile_response AS dep_profile_assign_status @@ -4634,7 +4639,8 @@ func (ds *Datastore) generateAggregatedMDMStatus(ctx context.Context, teamID *ui COALESCE(SUM(CASE WHEN NOT enrolled AND NOT installed_from_dep THEN 1 ELSE 0 END), 0) as unenrolled_hosts_count, COALESCE(SUM(CASE WHEN NOT enrolled AND installed_from_dep THEN 1 ELSE 0 END), 0) as pending_hosts_count, COALESCE(SUM(CASE WHEN enrolled AND installed_from_dep THEN 1 ELSE 0 END), 0) as enrolled_automated_hosts_count, - COALESCE(SUM(CASE WHEN enrolled AND NOT installed_from_dep THEN 1 ELSE 0 END), 0) as enrolled_manual_hosts_count + COALESCE(SUM(CASE WHEN enrolled AND NOT installed_from_dep AND NOT is_personal_enrollment THEN 1 ELSE 0 END), 0) as enrolled_manual_hosts_count, + COALESCE(SUM(CASE WHEN enrolled AND NOT installed_from_dep AND is_personal_enrollment THEN 1 ELSE 0 END), 0) as enrolled_personal_hosts_count FROM host_mdm hm ` args := []interface{}{} diff --git a/server/datastore/mysql/hosts_test.go b/server/datastore/mysql/hosts_test.go index 82dd8d1f69..49b202453e 100644 --- a/server/datastore/mysql/hosts_test.go +++ b/server/datastore/mysql/hosts_test.go @@ -1245,9 +1245,9 @@ func testHostsUnenrollFromMDM(t *testing.T, ds *Datastore) { // Set hosts to be enrolled to an MDM. const simpleMDM = "https://simplemdm.com" - err = ds.SetOrUpdateMDMData(ctx, h.ID, false, true, simpleMDM, true, "", "") + err = ds.SetOrUpdateMDMData(ctx, h.ID, false, true, simpleMDM, true, "", "", false) require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, h2.ID, false, true, simpleMDM, true, "", "") + err = ds.SetOrUpdateMDMData(ctx, h2.ID, false, true, simpleMDM, true, "", "", false) require.NoError(t, err) // force is_server to NULL for host 1 @@ -1281,7 +1281,7 @@ func testHostsUnenrollFromMDM(t *testing.T, ds *Datastore) { require.Equal(t, 2, solutions[0].HostsCount) // Host `h` unenrolls from MDM, so MDM query returns empty server_url. - err = ds.SetOrUpdateMDMData(ctx, h.ID, false, false, "", false, "", "") + err = ds.SetOrUpdateMDMData(ctx, h.ID, false, false, "", false, "", "", false) require.NoError(t, err) // host_mdm entry should still exist with empty values. @@ -1302,7 +1302,7 @@ func testHostsUnenrollFromMDM(t *testing.T, ds *Datastore) { require.Equal(t, 1, solutions[0].HostsCount) // Host `h2` unenrolls from MDM, so MDM query returns empty server_url. - err = ds.SetOrUpdateMDMData(ctx, h2.ID, false, false, "", false, "", "") + err = ds.SetOrUpdateMDMData(ctx, h2.ID, false, false, "", false, "", "", false) require.NoError(t, err) // host_mdm entry should not exist anymore. @@ -1360,13 +1360,13 @@ func testHostsListMDM(t *testing.T, ds *Datastore) { require.Equal(t, int64(1), n) const simpleMDM, kandji, unknown = "https://simplemdm.com", "https://kandji.io", "https://url.com" - err = ds.SetOrUpdateMDMData(ctx, hostIDs[0], false, true, simpleMDM, true, fleet.WellKnownMDMSimpleMDM, "") // enrollment: automatic + err = ds.SetOrUpdateMDMData(ctx, hostIDs[0], false, true, simpleMDM, true, fleet.WellKnownMDMSimpleMDM, "", false) // enrollment: automatic require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, hostIDs[1], false, true, kandji, true, fleet.WellKnownMDMKandji, "") // enrollment: automatic + err = ds.SetOrUpdateMDMData(ctx, hostIDs[1], false, true, kandji, true, fleet.WellKnownMDMKandji, "", false) // enrollment: automatic require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, hostIDs[2], false, true, unknown, false, fleet.UnknownMDMName, "") // enrollment: manual + err = ds.SetOrUpdateMDMData(ctx, hostIDs[2], false, true, unknown, false, fleet.UnknownMDMName, "", false) // enrollment: manual require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, hostIDs[3], false, false, simpleMDM, false, fleet.WellKnownMDMSimpleMDM, "") // enrollment: unenrolled + err = ds.SetOrUpdateMDMData(ctx, hostIDs[3], false, false, simpleMDM, false, fleet.WellKnownMDMSimpleMDM, "", false) // enrollment: unenrolled require.NoError(t, err) var simpleMDMID uint @@ -1438,9 +1438,9 @@ func testHostsListMDM(t *testing.T, ds *Datastore) { require.NoError(t, err) hostIDs = append(hostIDs, h.ID) } - err = ds.SetOrUpdateMDMData(ctx, hostIDs[10], false, true, "http://intuneexample.com", false, fleet.WellKnownMDMIntune, "") // enrolled in Intune + err = ds.SetOrUpdateMDMData(ctx, hostIDs[10], false, true, "http://intuneexample.com", false, fleet.WellKnownMDMIntune, "", false) // enrolled in Intune require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, hostIDs[11], false, true, "http://example.com", false, fleet.WellKnownMDMFleet, "") // enrolled in Fleet + err = ds.SetOrUpdateMDMData(ctx, hostIDs[11], false, true, "http://example.com", false, fleet.WellKnownMDMFleet, "", false) // enrolled in Fleet require.NoError(t, err) hosts = listHostsCheckCount(t, ds, filter, fleet.HostListOptions{MDMNameFilter: ptr.String(fleet.WellKnownMDMIntune)}, 1) @@ -1557,7 +1557,7 @@ func testHostMDMSelect(t *testing.T, ds *Datastore) { require.NoError(t, err) for _, c := range cases { - require.NoError(t, ds.SetOrUpdateMDMData(ctx, h.ID, c.host.IsServer, c.host.Enrolled, mdmServerURL, c.host.InstalledFromDep, "test", "")) + require.NoError(t, ds.SetOrUpdateMDMData(ctx, h.ID, c.host.IsServer, c.host.Enrolled, mdmServerURL, c.host.InstalledFromDep, "test", "", false)) hosts, err := ds.ListHosts(ctx, fleet.TeamFilter{User: test.UserAdmin}, fleet.HostListOptions{}) require.NoError(t, err) @@ -6075,7 +6075,7 @@ func testHostMDMAndMunki(t *testing.T, ds *Datastore) { _, err = ds.GetHostMDM(context.Background(), 432) require.True(t, fleet.IsNotFound(err), err) - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 432, false, true, "url", false, "", "")) + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 432, false, true, "url", false, "", "", false)) hmdm, err := ds.GetHostMDM(context.Background(), 432) require.NoError(t, err) @@ -6086,9 +6086,10 @@ func testHostMDMAndMunki(t *testing.T, ds *Datastore) { assert.NotZero(t, *hmdm.MDMID) urlMDMID := *hmdm.MDMID assert.Equal(t, fleet.UnknownMDMName, hmdm.Name) + assert.False(t, hmdm.IsPersonalEnrollment) - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, true, "https://kandji.io", true, fleet.WellKnownMDMKandji, "")) // kandji mdm name - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 432, false, false, "url3", true, "", "")) + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, true, "https://kandji.io", true, fleet.WellKnownMDMKandji, "", false)) // kandji mdm name + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 432, false, false, "url3", true, "", "", true)) hmdm, err = ds.GetHostMDM(context.Background(), 432) require.NoError(t, err) @@ -6099,6 +6100,7 @@ func testHostMDMAndMunki(t *testing.T, ds *Datastore) { assert.NotZero(t, *hmdm.MDMID) assert.NotEqual(t, urlMDMID, *hmdm.MDMID) assert.Equal(t, fleet.UnknownMDMName, hmdm.Name) + assert.True(t, hmdm.IsPersonalEnrollment) hmdm, err = ds.GetHostMDM(context.Background(), 455) require.NoError(t, err) @@ -6122,7 +6124,7 @@ func testHostMDMAndMunki(t *testing.T, ds *Datastore) { require.ErrorIs(t, err, sql.ErrNoRows) // switch to simplemdm in an update - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "")) // now simplemdm name + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", false)) // now simplemdm name hmdm, err = ds.GetHostMDM(context.Background(), 455) require.NoError(t, err) @@ -6134,7 +6136,7 @@ func testHostMDMAndMunki(t *testing.T, ds *Datastore) { assert.Equal(t, fleet.WellKnownMDMSimpleMDM, hmdm.Name) // switch back to "url" - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, false, "url", false, "", "")) + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, false, "url", false, "", "", false)) hmdm, err = ds.GetHostMDM(context.Background(), 455) require.NoError(t, err) @@ -6147,7 +6149,7 @@ func testHostMDMAndMunki(t *testing.T, ds *Datastore) { // switch to a different Kandji server URL, will have a different MDM ID as // even though this is another Kandji, the URL is different. - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, true, "https://kandji.io/2", false, fleet.WellKnownMDMKandji, "")) + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, true, "https://kandji.io/2", false, fleet.WellKnownMDMKandji, "", false)) hmdm, err = ds.GetHostMDM(context.Background(), 455) require.NoError(t, err) @@ -6333,23 +6335,25 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { }, }) - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 432, false, true, "url", false, "", "")) // manual enrollment - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 123, false, true, "url", false, "", "")) // manual enrollment - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 124, false, true, "url", false, "", "")) // manual enrollment - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, true, "https://simplemdm.com", true, fleet.WellKnownMDMSimpleMDM, "")) // automatic enrollment - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 999, false, false, "https://kandji.io", false, fleet.WellKnownMDMKandji, "")) // unenrolled - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 875, false, false, "https://kandji.io", true, fleet.WellKnownMDMKandji, "")) // pending enrollment - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 1337, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "")) // pending enrollment + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 432, false, true, "url", false, "", "", false)) // manual enrollment + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 123, false, true, "url", false, "", "", false)) // manual enrollment + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 124, false, true, "url", false, "", "", false)) // manual enrollment + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, true, "https://simplemdm.com", true, fleet.WellKnownMDMSimpleMDM, "", false)) // automatic enrollment + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 999, false, false, "https://kandji.io", false, fleet.WellKnownMDMKandji, "", false)) // unenrolled + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 875, false, false, "https://kandji.io", true, fleet.WellKnownMDMKandji, "", false)) // pending enrollment + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 1337, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "", false)) // pending enrollment + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 31337, false, true, "https://fleetdm.com", false, fleet.WellKnownMDMFleet, "", true)) // Personal enrollment require.NoError(t, ds.GenerateAggregatedMunkiAndMDM(context.Background())) status, _, err = ds.AggregatedMDMStatus(context.Background(), nil, "") require.NoError(t, err) - assert.Equal(t, 7, status.HostsCount) + assert.Equal(t, 8, status.HostsCount) assert.Equal(t, 1, status.UnenrolledHostsCount) assert.Equal(t, 2, status.PendingHostsCount) assert.Equal(t, 3, status.EnrolledManualHostsCount) assert.Equal(t, 1, status.EnrolledAutomatedHostsCount) + assert.Equal(t, 1, status.EnrolledPersonalHostsCount) solutions, _, err = ds.AggregatedMDMSolutions(context.Background(), nil, "") require.NoError(t, err) @@ -6366,7 +6370,7 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { assert.Equal(t, 2, sol.HostsCount) assert.Equal(t, fleet.WellKnownMDMKandji, sol.Name) case "https://fleetdm.com": - assert.Equal(t, 1, sol.HostsCount) + assert.Equal(t, 2, sol.HostsCount) assert.Equal(t, fleet.WellKnownMDMFleet, sol.Name) default: require.Fail(t, fmt.Sprintf("unknown MDM solutions URL: %s", sol.ServerURL)) @@ -6391,21 +6395,24 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { h4 := test.NewHost(t, ds, "h4"+t.Name(), "192.168.1.11", "4", "4", time.Now(), test.WithPlatform("windows")) h5 := test.NewHost(t, ds, "h5"+t.Name(), "192.168.1.12", "5", "5", time.Now(), test.WithPlatform("ios")) h6 := test.NewHost(t, ds, "h6"+t.Name(), "192.168.1.12", "6", "6", time.Now(), test.WithPlatform("ipados")) + h7 := test.NewHost(t, ds, "h7"+t.Name(), "192.168.1.17", "7", "7", time.Now(), test.WithPlatform("ios")) require.NoError(t, ds.AddHostsToTeam(context.Background(), fleet.NewAddHostsToTeamParams(&team1.ID, []uint{h1.ID}))) require.NoError(t, ds.AddHostsToTeam(context.Background(), fleet.NewAddHostsToTeamParams(&team2.ID, []uint{h2.ID}))) require.NoError(t, ds.AddHostsToTeam(context.Background(), fleet.NewAddHostsToTeamParams(&team1.ID, []uint{h3.ID}))) require.NoError(t, ds.AddHostsToTeam(context.Background(), fleet.NewAddHostsToTeamParams(&team1.ID, []uint{h4.ID}))) require.NoError(t, ds.AddHostsToTeam(context.Background(), fleet.NewAddHostsToTeamParams(&team1.ID, []uint{h6.ID}))) + require.NoError(t, ds.AddHostsToTeam(context.Background(), fleet.NewAddHostsToTeamParams(&team1.ID, []uint{h7.ID}))) - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h1.ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "")) - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h2.ID, false, true, "url", false, "", "")) + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h1.ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", false)) + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h2.ID, false, true, "url", false, "", "", false)) - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h5.ID, false, true, "https://fleet.example.com", true, fleet.WellKnownMDMFleet, "")) - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h6.ID, false, true, "https://fleet.example.com", true, fleet.WellKnownMDMFleet, "")) + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h5.ID, false, true, "https://fleet.example.com", true, fleet.WellKnownMDMFleet, "", false)) + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h6.ID, false, true, "https://fleet.example.com", true, fleet.WellKnownMDMFleet, "", false)) + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h7.ID, false, true, "https://fleet.example.com", false, fleet.WellKnownMDMFleet, "", true)) // Add a server, this will be ignored in lists and aggregated data. - require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h4.ID, true, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "")) + require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), h4.ID, true, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", false)) require.NoError(t, ds.SetOrUpdateMunkiInfo(context.Background(), h1.ID, "1.2.3", []string{"d"}, nil)) require.NoError(t, ds.SetOrUpdateMunkiInfo(context.Background(), h2.ID, "1.2.3", []string{"d"}, []string{"e"})) @@ -6455,17 +6462,19 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { status, _, err = ds.AggregatedMDMStatus(context.Background(), nil, "") require.NoError(t, err) - assert.Equal(t, 11, status.HostsCount) + assert.Equal(t, 13, status.HostsCount) assert.Equal(t, 1, status.UnenrolledHostsCount) assert.Equal(t, 5, status.EnrolledManualHostsCount) assert.Equal(t, 3, status.EnrolledAutomatedHostsCount) + assert.Equal(t, 2, status.EnrolledPersonalHostsCount) status, _, err = ds.AggregatedMDMStatus(context.Background(), &team1.ID, "") require.NoError(t, err) - assert.Equal(t, 2, status.HostsCount) + assert.Equal(t, 3, status.HostsCount) assert.Equal(t, 0, status.UnenrolledHostsCount) assert.Equal(t, 1, status.EnrolledManualHostsCount) assert.Equal(t, 1, status.EnrolledAutomatedHostsCount) + assert.Equal(t, 1, status.EnrolledPersonalHostsCount) solutions, updatedAt, err = ds.AggregatedMDMSolutions(context.Background(), nil, "") require.True(t, updatedAt.After(firstUpdatedAt)) @@ -6474,7 +6483,7 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { // Check the new MDM solution used by the iOS/iPadOS assert.Equal(t, "https://fleet.example.com", solutions[4].ServerURL) assert.Equal(t, fleet.WellKnownMDMFleet, solutions[4].Name) - assert.Equal(t, 2, solutions[4].HostsCount) + assert.Equal(t, 3, solutions[4].HostsCount) solutions, updatedAt, err = ds.AggregatedMDMSolutions(context.Background(), &team1.ID, "") require.True(t, updatedAt.After(firstUpdatedAt)) @@ -6485,7 +6494,7 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { assert.Equal(t, 1, solutions[0].HostsCount) assert.Equal(t, "https://fleet.example.com", solutions[1].ServerURL) assert.Equal(t, fleet.WellKnownMDMFleet, solutions[1].Name) - assert.Equal(t, 1, solutions[1].HostsCount) + assert.Equal(t, 2, solutions[1].HostsCount) status, _, err = ds.AggregatedMDMStatus(context.Background(), &team1.ID, "darwin") require.NoError(t, err) @@ -6493,6 +6502,7 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { assert.Equal(t, 0, status.UnenrolledHostsCount) assert.Equal(t, 0, status.EnrolledManualHostsCount) assert.Equal(t, 0, status.EnrolledAutomatedHostsCount) + assert.Equal(t, 0, status.EnrolledPersonalHostsCount) solutions, updatedAt, err = ds.AggregatedMDMSolutions(context.Background(), &team1.ID, "darwin") require.True(t, updatedAt.After(firstUpdatedAt)) @@ -6505,20 +6515,23 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { assert.Equal(t, 0, status.UnenrolledHostsCount) assert.Equal(t, 1, status.EnrolledManualHostsCount) assert.Equal(t, 0, status.EnrolledAutomatedHostsCount) + assert.Equal(t, 0, status.EnrolledPersonalHostsCount) status, _, err = ds.AggregatedMDMStatus(context.Background(), &team1.ID, "ios") require.NoError(t, err) - assert.Equal(t, 0, status.HostsCount) - assert.Equal(t, 0, status.UnenrolledHostsCount) - assert.Equal(t, 0, status.EnrolledManualHostsCount) - assert.Equal(t, 0, status.EnrolledAutomatedHostsCount) - - status, _, err = ds.AggregatedMDMStatus(context.Background(), nil, "ios") - require.NoError(t, err) assert.Equal(t, 1, status.HostsCount) assert.Equal(t, 0, status.UnenrolledHostsCount) assert.Equal(t, 0, status.EnrolledManualHostsCount) + assert.Equal(t, 0, status.EnrolledAutomatedHostsCount) + assert.Equal(t, 1, status.EnrolledPersonalHostsCount) + + status, _, err = ds.AggregatedMDMStatus(context.Background(), nil, "ios") + require.NoError(t, err) + assert.Equal(t, 2, status.HostsCount) + assert.Equal(t, 0, status.UnenrolledHostsCount) + assert.Equal(t, 0, status.EnrolledManualHostsCount) assert.Equal(t, 1, status.EnrolledAutomatedHostsCount) + assert.Equal(t, 1, status.EnrolledPersonalHostsCount) status, _, err = ds.AggregatedMDMStatus(context.Background(), &team1.ID, "ipados") require.NoError(t, err) @@ -6526,6 +6539,7 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { assert.Equal(t, 0, status.UnenrolledHostsCount) assert.Equal(t, 0, status.EnrolledManualHostsCount) assert.Equal(t, 1, status.EnrolledAutomatedHostsCount) + assert.Equal(t, 0, status.EnrolledPersonalHostsCount) status, _, err = ds.AggregatedMDMStatus(context.Background(), nil, "ipados") require.NoError(t, err) @@ -6533,6 +6547,7 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { assert.Equal(t, 0, status.UnenrolledHostsCount) assert.Equal(t, 0, status.EnrolledManualHostsCount) assert.Equal(t, 1, status.EnrolledAutomatedHostsCount) + assert.Equal(t, 0, status.EnrolledPersonalHostsCount) solutions, updatedAt, err = ds.AggregatedMDMSolutions(context.Background(), &team1.ID, "windows") require.True(t, updatedAt.After(firstUpdatedAt)) @@ -6548,12 +6563,12 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) { require.Len(t, solutions, 1) assert.Equal(t, "https://fleet.example.com", solutions[0].ServerURL) assert.Equal(t, fleet.WellKnownMDMFleet, solutions[0].Name) - assert.Equal(t, 1, solutions[0].HostsCount) + assert.Equal(t, 2, solutions[0].HostsCount) solutions, updatedAt, err = ds.AggregatedMDMSolutions(context.Background(), &team1.ID, "ios") require.True(t, updatedAt.After(firstUpdatedAt)) require.NoError(t, err) - require.Len(t, solutions, 0) + require.Len(t, solutions, 1) solutions, updatedAt, err = ds.AggregatedMDMSolutions(context.Background(), nil, "ipados") require.True(t, updatedAt.After(firstUpdatedAt)) @@ -6794,7 +6809,7 @@ func testHostsLoadHostByDeviceAuthToken(t *testing.T, ds *Datastore) { // create a host enrolled in Simple MDM hSimple := createHostWithDeviceToken("simple") - err = ds.SetOrUpdateMDMData(ctx, hSimple.ID, false, true, "https://simplemdm.com", true, fleet.WellKnownMDMSimpleMDM, "") + err = ds.SetOrUpdateMDMData(ctx, hSimple.ID, false, true, "https://simplemdm.com", true, fleet.WellKnownMDMSimpleMDM, "", false) require.NoError(t, err) loadSimple, err := ds.LoadHostByDeviceAuthToken(ctx, "simple", time.Second) @@ -6816,7 +6831,7 @@ func testHostsLoadHostByDeviceAuthToken(t *testing.T, ds *Datastore) { // create a host that will be pending enrollment in Fleet MDM hFleet := createHostWithDeviceToken("fleet") - err = ds.SetOrUpdateMDMData(ctx, hFleet.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, hFleet.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) loadFleet, err := ds.LoadHostByDeviceAuthToken(ctx, "fleet", time.Second) @@ -7302,7 +7317,7 @@ func testHostsDeleteHosts(t *testing.T, ds *Datastore) { require.NoError(t, ds.RecordPolicyQueryExecutions(context.Background(), host, map[uint]*bool{policy.ID: ptr.Bool(true)}, time.Now(), false)) // Update host_mdm. - err = ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, "foo.mdm.example.com", false, "", "") + err = ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, "foo.mdm.example.com", false, "", "", false) require.NoError(t, err) // Update host_munki_info. err = ds.SetOrUpdateMunkiInfo(context.Background(), host.ID, "42", []string{"a"}, []string{"b"}) @@ -8326,7 +8341,7 @@ func testHostsGetHostMDMCheckinInfo(t *testing.T, ds *Datastore) { Platform: "darwin", }) require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, host.ID, false, true, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, host.ID, false, true, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) info, err := ds.GetHostMDMCheckinInfo(ctx, host.UUID) @@ -8437,7 +8452,7 @@ func testHostsLoadHostByOrbitNodeKey(t *testing.T, ds *Datastore) { // create a host enrolled in Simple MDM hSimple := createOrbitHost("simple") - err = ds.SetOrUpdateMDMData(ctx, hSimple.ID, false, true, "https://simplemdm.com", true, fleet.WellKnownMDMSimpleMDM, "") + err = ds.SetOrUpdateMDMData(ctx, hSimple.ID, false, true, "https://simplemdm.com", true, fleet.WellKnownMDMSimpleMDM, "", false) require.NoError(t, err) loadSimple, err := ds.LoadHostByOrbitNodeKey(ctx, *hSimple.OrbitNodeKey) @@ -8448,7 +8463,7 @@ func testHostsLoadHostByOrbitNodeKey(t *testing.T, ds *Datastore) { // create a host that will be pending enrollment in Fleet MDM hFleet := createOrbitHost("fleet") - err = ds.SetOrUpdateMDMData(ctx, hFleet.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, hFleet.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) loadFleet, err := ds.LoadHostByOrbitNodeKey(ctx, *hFleet.OrbitNodeKey) diff --git a/server/datastore/mysql/labels_test.go b/server/datastore/mysql/labels_test.go index 1bef82b775..ff0b25e426 100644 --- a/server/datastore/mysql/labels_test.go +++ b/server/datastore/mysql/labels_test.go @@ -324,11 +324,11 @@ func testLabelsListHostsInLabel(t *testing.T, db *Datastore) { ctx := context.Background() const simpleMDM, kandji = "https://simplemdm.com", "https://kandji.io" - err = db.SetOrUpdateMDMData(ctx, h1.ID, false, true, simpleMDM, true, fleet.WellKnownMDMSimpleMDM, "") // enrollment: automatic + err = db.SetOrUpdateMDMData(ctx, h1.ID, false, true, simpleMDM, true, fleet.WellKnownMDMSimpleMDM, "", false) // enrollment: automatic require.NoError(t, err) - err = db.SetOrUpdateMDMData(ctx, h2.ID, false, true, kandji, true, fleet.WellKnownMDMKandji, "") // enrollment: automatic + err = db.SetOrUpdateMDMData(ctx, h2.ID, false, true, kandji, true, fleet.WellKnownMDMKandji, "", false) // enrollment: automatic require.NoError(t, err) - err = db.SetOrUpdateMDMData(ctx, h3.ID, false, false, simpleMDM, false, fleet.WellKnownMDMSimpleMDM, "") // enrollment: unenrolled + err = db.SetOrUpdateMDMData(ctx, h3.ID, false, false, simpleMDM, false, fleet.WellKnownMDMSimpleMDM, "", false) // enrollment: unenrolled require.NoError(t, err) var simpleMDMID uint @@ -1654,7 +1654,7 @@ func testLabelsListHostsInLabelOSSettings(t *testing.T, db *Datastore) { // add two hosts to MDM to enforce disk encryption, fleet doesn't enforce settings on centos so h3 is not included for _, h := range []*fleet.Host{h1, h2} { windowsEnroll(t, db, h) - require.NoError(t, db.SetOrUpdateMDMData(context.Background(), h.ID, false, true, "https://example.com", false, fleet.WellKnownMDMFleet, "")) + require.NoError(t, db.SetOrUpdateMDMData(context.Background(), h.ID, false, true, "https://example.com", false, fleet.WellKnownMDMFleet, "", false)) } // add disk encryption key for h1 require.NoError(t, db.SetOrUpdateHostDiskEncryptionKey(context.Background(), h1, "test-key", "", ptr.Bool(true))) diff --git a/server/datastore/mysql/mdm_test.go b/server/datastore/mysql/mdm_test.go index 25089042b0..fc2d99c2a7 100644 --- a/server/datastore/mysql/mdm_test.go +++ b/server/datastore/mysql/mdm_test.go @@ -7328,6 +7328,7 @@ func testMDMProfilesSummaryAndHostFilters(t *testing.T, ds *Datastore) { false, fleet.WellKnownMDMFleet, "", + false, ), ) } @@ -7528,7 +7529,7 @@ func testAreHostsConnectedToFleetMDM(t *testing.T, ds *Datastore) { }) require.NoError(t, err) nanoEnroll(t, ds, connectedMac, false) - err = ds.SetOrUpdateMDMData(ctx, connectedMac.ID, false, true, "http://foo.com", false, "foo", "") + err = ds.SetOrUpdateMDMData(ctx, connectedMac.ID, false, true, "http://foo.com", false, "foo", "", false) require.NoError(t, err) disconnectedWithoutCheckoutMac, err := ds.NewHost(ctx, &fleet.Host{ @@ -7540,7 +7541,7 @@ func testAreHostsConnectedToFleetMDM(t *testing.T, ds *Datastore) { }) require.NoError(t, err) nanoEnroll(t, ds, disconnectedWithoutCheckoutMac, false) - err = ds.SetOrUpdateMDMData(ctx, disconnectedWithoutCheckoutMac.ID, false, false, "", false, "", "") + err = ds.SetOrUpdateMDMData(ctx, disconnectedWithoutCheckoutMac.ID, false, false, "", false, "", "", false) require.NoError(t, err) notConnectedWin, err := ds.NewHost(ctx, &fleet.Host{ @@ -7576,7 +7577,7 @@ func testAreHostsConnectedToFleetMDM(t *testing.T, ds *Datastore) { } err = ds.MDMWindowsInsertEnrolledDevice(ctx, windowsEnrollment) require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, connectedWin.ID, false, true, "http://foo.com", false, "foo", "") + err = ds.SetOrUpdateMDMData(ctx, connectedWin.ID, false, true, "http://foo.com", false, "foo", "", false) require.NoError(t, err) disconnectedWithoutCheckoutWin, err := ds.NewHost(ctx, &fleet.Host{ @@ -7602,7 +7603,7 @@ func testAreHostsConnectedToFleetMDM(t *testing.T, ds *Datastore) { } err = ds.MDMWindowsInsertEnrolledDevice(ctx, windowsEnrollmentDisconnectedWithoutCheckout) require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, disconnectedWithoutCheckoutWin.ID, false, false, "", false, "", "") + err = ds.SetOrUpdateMDMData(ctx, disconnectedWithoutCheckoutWin.ID, false, false, "", false, "", "", false) require.NoError(t, err) connectedMap, err := ds.AreHostsConnectedToFleetMDM(ctx, []*fleet.Host{ @@ -7668,7 +7669,7 @@ func testIsHostConnectedToFleetMDM(t *testing.T, ds *Datastore) { require.False(t, connected) nanoEnroll(t, ds, macH, false) - err = ds.SetOrUpdateMDMData(ctx, macH.ID, false, true, "http://foo.com", false, "foo", "") + err = ds.SetOrUpdateMDMData(ctx, macH.ID, false, true, "http://foo.com", false, "foo", "", false) require.NoError(t, err) connected, err = ds.IsHostConnectedToFleetMDM(ctx, macH) @@ -7685,7 +7686,7 @@ func testIsHostConnectedToFleetMDM(t *testing.T, ds *Datastore) { require.NoError(t, err) nanoEnrollUserDevice(t, ds, byodIpadH) - err = ds.SetOrUpdateMDMData(ctx, byodIpadH.ID, false, true, "http://foo.com", false, "foo", "") + err = ds.SetOrUpdateMDMData(ctx, byodIpadH.ID, false, true, "http://foo.com", false, "foo", "", false) require.NoError(t, err) connected, err = ds.IsHostConnectedToFleetMDM(ctx, byodIpadH) @@ -7719,7 +7720,7 @@ func testIsHostConnectedToFleetMDM(t *testing.T, ds *Datastore) { } err = ds.MDMWindowsInsertEnrolledDevice(ctx, windowsEnrollment) require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, windowsH.ID, false, true, "http://foo.com", false, "foo", "") + err = ds.SetOrUpdateMDMData(ctx, windowsH.ID, false, true, "http://foo.com", false, "foo", "", false) require.NoError(t, err) connected, err = ds.IsHostConnectedToFleetMDM(ctx, windowsH) @@ -7727,9 +7728,9 @@ func testIsHostConnectedToFleetMDM(t *testing.T, ds *Datastore) { require.True(t, connected) // now simulate an un-enrollment without checkout, in this case, osquery reports the host as not-enrolled - err = ds.SetOrUpdateMDMData(ctx, macH.ID, false, false, "", false, "", "") + err = ds.SetOrUpdateMDMData(ctx, macH.ID, false, false, "", false, "", "", false) require.NoError(t, err) - err = ds.SetOrUpdateMDMData(ctx, windowsH.ID, false, false, "", false, "", "") + err = ds.SetOrUpdateMDMData(ctx, windowsH.ID, false, false, "", false, "", "", false) require.NoError(t, err) connected, err = ds.IsHostConnectedToFleetMDM(ctx, macH) @@ -8312,7 +8313,7 @@ func testGetMDMConfigProfileStatus(t *testing.T, ds *Datastore) { windowsEnroll(t, ds, host8) for _, h := range []*fleet.Host{host1, host2, host3, host4, host5, host6, host7, host8} { - err = ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "https://fleetdm.com", false, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "https://fleetdm.com", false, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) } @@ -8480,7 +8481,7 @@ func testDeleteMDMProfilesCancelsInstalls(t *testing.T, ds *Datastore) { windowsEnroll(t, ds, host4) for _, h := range []*fleet.Host{host1, host2, host3, host4} { - err = ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "https://fleetdm.com", false, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "https://fleetdm.com", false, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) } diff --git a/server/datastore/mysql/microsoft_mdm_test.go b/server/datastore/mysql/microsoft_mdm_test.go index 65e217e218..7dbbb42f02 100644 --- a/server/datastore/mysql/microsoft_mdm_test.go +++ b/server/datastore/mysql/microsoft_mdm_test.go @@ -298,7 +298,7 @@ func testMDMWindowsDiskEncryption(t *testing.T, ds *Datastore) { require.NotNil(t, h) hosts = append(hosts, h) - require.NoError(t, ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "https://example.com", false, fleet.WellKnownMDMFleet, "")) + require.NoError(t, ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "https://example.com", false, fleet.WellKnownMDMFleet, "", false)) if p == "darwin" { nanoEnroll(t, ds, h, false) @@ -526,7 +526,7 @@ func testMDMWindowsDiskEncryption(t *testing.T, ds *Datastore) { require.NoError(t, ds.SetOrUpdateMDMData(ctx, hosts[3].ID, true, // set is_server to true for hosts[3] - true, "https://example.com", false, fleet.WellKnownMDMFleet, "")) + true, "https://example.com", false, fleet.WellKnownMDMFleet, "", false)) // Check Windows servers not counted checkExpected(t, nil, hostIDsByDEStatus{ @@ -720,7 +720,7 @@ func testMDMWindowsProfilesSummary(t *testing.T, ds *Datastore) { require.NotNil(t, h) hosts = append(hosts, h) - require.NoError(t, ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "https://example.com", false, fleet.WellKnownMDMFleet, "")) + require.NoError(t, ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "https://example.com", false, fleet.WellKnownMDMFleet, "", false)) if p == "windows" { uuidToDeviceID[h.UUID] = windowsEnroll(t, ds, h) } @@ -1025,7 +1025,7 @@ func testMDMWindowsProfilesSummary(t *testing.T, ds *Datastore) { require.NotNil(t, h) otherHosts = append(otherHosts, h) - require.NoError(t, ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "https://example.com", false, fleet.WellKnownMDMFleet, "")) + require.NoError(t, ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "https://example.com", false, fleet.WellKnownMDMFleet, "", false)) windowsEnroll(t, ds, h) } checkExpected(t, nil, expected) @@ -1117,7 +1117,7 @@ func testMDMWindowsProfilesSummary(t *testing.T, ds *Datastore) { checkExpected(t, nil, expected) // report otherHosts[0] as a server - require.NoError(t, ds.SetOrUpdateMDMData(ctx, otherHosts[0].ID, true, true, "https://example.com", false, fleet.WellKnownMDMFleet, "")) + require.NoError(t, ds.SetOrUpdateMDMData(ctx, otherHosts[0].ID, true, true, "https://example.com", false, fleet.WellKnownMDMFleet, "", false)) // otherHosts[0] is no longer counted expected = hostIDsByProfileStatus{ fleet.MDMDeliveryPending: []uint{hosts[0].ID, hosts[3].ID, otherHosts[1].ID, otherHosts[2].ID, otherHosts[3].ID, otherHosts[4].ID}, @@ -1126,7 +1126,7 @@ func testMDMWindowsProfilesSummary(t *testing.T, ds *Datastore) { checkExpected(t, nil, expected) // report hosts[0] as a server - require.NoError(t, ds.SetOrUpdateMDMData(ctx, hosts[0].ID, true, true, "https://example.com", false, fleet.WellKnownMDMFleet, "")) + require.NoError(t, ds.SetOrUpdateMDMData(ctx, hosts[0].ID, true, true, "https://example.com", false, fleet.WellKnownMDMFleet, "", false)) // hosts[0] is no longer counted expected = hostIDsByProfileStatus{ fleet.MDMDeliveryPending: []uint{hosts[3].ID, otherHosts[1].ID, otherHosts[2].ID, otherHosts[3].ID, otherHosts[4].ID}, @@ -1144,7 +1144,7 @@ func testMDMWindowsProfilesSummary(t *testing.T, ds *Datastore) { checkExpected(t, nil, expected) // report hosts[4] as enrolled to a different MDM - require.NoError(t, ds.SetOrUpdateMDMData(ctx, hosts[4].ID, false, true, "https://some-other-mdm.example.com", false, "some-other-mdm", "")) + require.NoError(t, ds.SetOrUpdateMDMData(ctx, hosts[4].ID, false, true, "https://some-other-mdm.example.com", false, "some-other-mdm", "", false)) require.NoError(t, ds.MDMWindowsDeleteEnrolledDeviceWithDeviceID(ctx, uuidToDeviceID[hosts[4].UUID])) // hosts[4] is no longer counted expected = hostIDsByProfileStatus{ diff --git a/server/datastore/mysql/migrations/tables/20250718091828_AddPersonalEnrollmentStatus.go b/server/datastore/mysql/migrations/tables/20250718091828_AddPersonalEnrollmentStatus.go new file mode 100644 index 0000000000..77198aee06 --- /dev/null +++ b/server/datastore/mysql/migrations/tables/20250718091828_AddPersonalEnrollmentStatus.go @@ -0,0 +1,41 @@ +package tables + +import ( + "database/sql" + + "github.com/pkg/errors" +) + +func init() { + MigrationClient.AddMigration(Up_20250718091828, Down_20250718091828) +} + +func Up_20250718091828(tx *sql.Tx) error { + if _, err := tx.Exec(` +ALTER TABLE host_mdm + ADD COLUMN is_personal_enrollment TINYINT(1) NOT NULL DEFAULT '0', + CHANGE COLUMN enrollment_status enrollment_status ENUM('On (manual)', 'On (automatic)', 'Pending', 'Off', 'On (personal)') COLLATE utf8mb4_unicode_ci +GENERATED ALWAYS AS ( + CASE + WHEN is_server = 1 THEN NULL + WHEN enrolled = 1 AND installed_from_dep = 0 AND is_personal_enrollment = 1 THEN 'On (personal)' + WHEN enrolled = 1 AND installed_from_dep = 0 AND is_personal_enrollment = 0 THEN 'On (manual)' + WHEN enrolled = 1 AND installed_from_dep = 1 AND is_personal_enrollment = 0 THEN 'On (automatic)' + WHEN enrolled = 0 AND installed_from_dep = 1 THEN 'Pending' + WHEN enrolled = 0 AND installed_from_dep = 0 THEN 'Off' + ELSE NULL + END +) VIRTUAL NULL`); err != nil { + return errors.Wrap(err, "add is_personal_enrollment column and modify enrollment_status on host_mdm table") + } + + // Remove the old index and create a new one that includes is_personal_enrollment. + if _, err := tx.Exec(`ALTER TABLE host_mdm DROP INDEX host_mdm_enrolled_installed_from_dep_idx, ADD INDEX host_mdm_enrolled_installed_from_dep_is_personal_enrollment_idx (enrolled, installed_from_dep, is_personal_enrollment);`); err != nil { + return errors.Wrap(err, "create enrollment status index") + } + return nil +} + +func Down_20250718091828(tx *sql.Tx) error { + return nil +} diff --git a/server/datastore/mysql/migrations/tables/20250718091828_AddPersonalEnrollmentStatus_test.go b/server/datastore/mysql/migrations/tables/20250718091828_AddPersonalEnrollmentStatus_test.go new file mode 100644 index 0000000000..c7cde0dd1c --- /dev/null +++ b/server/datastore/mysql/migrations/tables/20250718091828_AddPersonalEnrollmentStatus_test.go @@ -0,0 +1,87 @@ +package tables + +import ( + "testing" + + "github.com/jmoiron/sqlx" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUp_20250718091828(t *testing.T) { + db := applyUpToPrev(t) + + // + // Insert data to test the migration + // + // ... + // host_id 1 is a + _, err := db.DB.Exec(`INSERT INTO host_mdm (host_id, enrolled, server_url, installed_from_dep, is_server, fleet_enroll_ref) + VALUES (1, 1, 'https://example.com', 0, 0, ''), -- manually enrolled + (2, 1, 'https://example.com', 1, 0, ''), -- automatically enrolled from DEP, no enroll ref + (3, 1, 'https://example.com', 1, 0, 'fleet-enroll-ref3'), -- automatically enrolled from DEP with enroll ref + (4, 0, 'https://example.com', 0, 1, ''), -- server with MDM off + (5, 0, 'https://example.com', 1, 0, ''), -- not yet enrolled device, but from DEP + (6, 0, 'https://example.com', 0, 0, '') -- not enrolled device, not from DEP + `) + require.NoError(t, err) + + // Apply current migration. + applyNext(t, db) + + type hostMDM struct { + HostID uint `db:"host_id"` + EnrollmentStatus *string `db:"enrollment_status"` + Enrolled bool `db:"enrolled"` + ServerURL string `db:"server_url"` + InstalledFromDEP bool `db:"installed_from_dep"` + IsServer bool `db:"is_server"` + FleetEnrollRef string `db:"fleet_enroll_ref"` + IsPersonalEnrollment bool `db:"is_personal_enrollment"` + } + + hostMDMEntries := []*hostMDM{} + err = sqlx.SelectContext(t.Context(), db, &hostMDMEntries, `SELECT host_id, enrollment_status, enrolled, server_url, installed_from_dep, is_server, fleet_enroll_ref, is_personal_enrollment FROM host_mdm`) + require.NoError(t, err) + require.Len(t, hostMDMEntries, 6) + for _, entry := range hostMDMEntries { + assert.False(t, entry.IsPersonalEnrollment, "is_personal_enrollment should be false on all rows from before migration") + } + + _, err = db.DB.Exec(`INSERT INTO host_mdm (host_id, enrolled, server_url, installed_from_dep, is_server, fleet_enroll_ref, is_personal_enrollment) + VALUES (7, 1, 'https://example.com', 0, 0, '', 1), + (8, 0, 'https://example.com', 0, 0, '', 1) -- personal enrollment turned off + `) + require.NoError(t, err) + + err = sqlx.SelectContext(t.Context(), db, &hostMDMEntries, `SELECT host_id, enrollment_status, enrolled, server_url, installed_from_dep, is_server, fleet_enroll_ref, is_personal_enrollment FROM host_mdm`) + require.NoError(t, err) + require.Len(t, hostMDMEntries, 8) + for _, entry := range hostMDMEntries { + if entry.HostID <= 6 { + assert.False(t, entry.IsPersonalEnrollment, "is_personal_enrollment should be false on all rows from before migration") + } + switch entry.HostID { + case 1: + assert.Equal(t, "On (manual)", *entry.EnrollmentStatus) + case 2: + assert.Equal(t, "On (automatic)", *entry.EnrollmentStatus) + case 3: + assert.Equal(t, "On (automatic)", *entry.EnrollmentStatus) + case 4: + assert.Equal(t, (*string)(nil), entry.EnrollmentStatus) + case 5: + assert.Equal(t, "Pending", *entry.EnrollmentStatus) + case 6: + assert.Equal(t, "Off", *entry.EnrollmentStatus) + case 7: + assert.Truef(t, entry.IsPersonalEnrollment, "is_personal_enrollment should be true for host_id %d", entry.HostID) + assert.Equal(t, "On (personal)", *entry.EnrollmentStatus) + case 8: + assert.Truef(t, entry.IsPersonalEnrollment, "is_personal_enrollment should be true for host_id %d", entry.HostID) + assert.Equal(t, "Off", *entry.EnrollmentStatus) + default: + t.Fatalf("unexpected host_id %d", entry.HostID) + } + } +} diff --git a/server/datastore/mysql/schema.sql b/server/datastore/mysql/schema.sql index 7b8e341002..75177eb363 100644 --- a/server/datastore/mysql/schema.sql +++ b/server/datastore/mysql/schema.sql @@ -547,12 +547,13 @@ CREATE TABLE `host_mdm` ( `mdm_id` int unsigned DEFAULT NULL, `is_server` tinyint(1) DEFAULT NULL, `fleet_enroll_ref` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `enrollment_status` enum('On (manual)','On (automatic)','Pending','Off') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci GENERATED ALWAYS AS ((case when (`is_server` = 1) then NULL when ((`enrolled` = 1) and (`installed_from_dep` = 0)) then _utf8mb4'On (manual)' when ((`enrolled` = 1) and (`installed_from_dep` = 1)) then _utf8mb4'On (automatic)' when ((`enrolled` = 0) and (`installed_from_dep` = 1)) then _utf8mb4'Pending' when ((`enrolled` = 0) and (`installed_from_dep` = 0)) then _utf8mb4'Off' else NULL end)) VIRTUAL, + `enrollment_status` enum('On (manual)','On (automatic)','Pending','Off','On (personal)') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci GENERATED ALWAYS AS ((case when (`is_server` = 1) then NULL when ((`enrolled` = 1) and (`installed_from_dep` = 0) and (`is_personal_enrollment` = 1)) then _utf8mb4'On (personal)' when ((`enrolled` = 1) and (`installed_from_dep` = 0) and (`is_personal_enrollment` = 0)) then _utf8mb4'On (manual)' when ((`enrolled` = 1) and (`installed_from_dep` = 1) and (`is_personal_enrollment` = 0)) then _utf8mb4'On (automatic)' when ((`enrolled` = 0) and (`installed_from_dep` = 1)) then _utf8mb4'Pending' when ((`enrolled` = 0) and (`installed_from_dep` = 0)) then _utf8mb4'Off' else NULL end)) VIRTUAL, `created_at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `updated_at` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), + `is_personal_enrollment` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`host_id`), KEY `host_mdm_mdm_id_idx` (`mdm_id`), - KEY `host_mdm_enrolled_installed_from_dep_idx` (`enrolled`,`installed_from_dep`) + KEY `host_mdm_enrolled_installed_from_dep_is_personal_enrollment_idx` (`enrolled`,`installed_from_dep`,`is_personal_enrollment`) ) /*!50100 TABLESPACE `innodb_system` */ ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; @@ -1409,9 +1410,9 @@ CREATE TABLE `migration_status_tables` ( `is_applied` tinyint(1) NOT NULL, `tstamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) -) /*!50100 TABLESPACE `innodb_system` */ ENGINE=InnoDB AUTO_INCREMENT=402 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) /*!50100 TABLESPACE `innodb_system` */ ENGINE=InnoDB AUTO_INCREMENT=403 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -INSERT INTO `migration_status_tables` VALUES (1,0,1,'2020-01-01 01:01:01'),(2,20161118193812,1,'2020-01-01 01:01:01'),(3,20161118211713,1,'2020-01-01 01:01:01'),(4,20161118212436,1,'2020-01-01 01:01:01'),(5,20161118212515,1,'2020-01-01 01:01:01'),(6,20161118212528,1,'2020-01-01 01:01:01'),(7,20161118212538,1,'2020-01-01 01:01:01'),(8,20161118212549,1,'2020-01-01 01:01:01'),(9,20161118212557,1,'2020-01-01 01:01:01'),(10,20161118212604,1,'2020-01-01 01:01:01'),(11,20161118212613,1,'2020-01-01 01:01:01'),(12,20161118212621,1,'2020-01-01 01:01:01'),(13,20161118212630,1,'2020-01-01 01:01:01'),(14,20161118212641,1,'2020-01-01 01:01:01'),(15,20161118212649,1,'2020-01-01 01:01:01'),(16,20161118212656,1,'2020-01-01 01:01:01'),(17,20161118212758,1,'2020-01-01 01:01:01'),(18,20161128234849,1,'2020-01-01 01:01:01'),(19,20161230162221,1,'2020-01-01 01:01:01'),(20,20170104113816,1,'2020-01-01 01:01:01'),(21,20170105151732,1,'2020-01-01 01:01:01'),(22,20170108191242,1,'2020-01-01 01:01:01'),(23,20170109094020,1,'2020-01-01 01:01:01'),(24,20170109130438,1,'2020-01-01 01:01:01'),(25,20170110202752,1,'2020-01-01 01:01:01'),(26,20170111133013,1,'2020-01-01 01:01:01'),(27,20170117025759,1,'2020-01-01 01:01:01'),(28,20170118191001,1,'2020-01-01 01:01:01'),(29,20170119234632,1,'2020-01-01 01:01:01'),(30,20170124230432,1,'2020-01-01 01:01:01'),(31,20170127014618,1,'2020-01-01 01:01:01'),(32,20170131232841,1,'2020-01-01 01:01:01'),(33,20170223094154,1,'2020-01-01 01:01:01'),(34,20170306075207,1,'2020-01-01 01:01:01'),(35,20170309100733,1,'2020-01-01 01:01:01'),(36,20170331111922,1,'2020-01-01 01:01:01'),(37,20170502143928,1,'2020-01-01 01:01:01'),(38,20170504130602,1,'2020-01-01 01:01:01'),(39,20170509132100,1,'2020-01-01 01:01:01'),(40,20170519105647,1,'2020-01-01 01:01:01'),(41,20170519105648,1,'2020-01-01 01:01:01'),(42,20170831234300,1,'2020-01-01 01:01:01'),(43,20170831234301,1,'2020-01-01 01:01:01'),(44,20170831234303,1,'2020-01-01 01:01:01'),(45,20171116163618,1,'2020-01-01 01:01:01'),(46,20171219164727,1,'2020-01-01 01:01:01'),(47,20180620164811,1,'2020-01-01 01:01:01'),(48,20180620175054,1,'2020-01-01 01:01:01'),(49,20180620175055,1,'2020-01-01 01:01:01'),(50,20191010101639,1,'2020-01-01 01:01:01'),(51,20191010155147,1,'2020-01-01 01:01:01'),(52,20191220130734,1,'2020-01-01 01:01:01'),(53,20200311140000,1,'2020-01-01 01:01:01'),(54,20200405120000,1,'2020-01-01 01:01:01'),(55,20200407120000,1,'2020-01-01 01:01:01'),(56,20200420120000,1,'2020-01-01 01:01:01'),(57,20200504120000,1,'2020-01-01 01:01:01'),(58,20200512120000,1,'2020-01-01 01:01:01'),(59,20200707120000,1,'2020-01-01 01:01:01'),(60,20201011162341,1,'2020-01-01 01:01:01'),(61,20201021104586,1,'2020-01-01 01:01:01'),(62,20201102112520,1,'2020-01-01 01:01:01'),(63,20201208121729,1,'2020-01-01 01:01:01'),(64,20201215091637,1,'2020-01-01 01:01:01'),(65,20210119174155,1,'2020-01-01 01:01:01'),(66,20210326182902,1,'2020-01-01 01:01:01'),(67,20210421112652,1,'2020-01-01 01:01:01'),(68,20210506095025,1,'2020-01-01 01:01:01'),(69,20210513115729,1,'2020-01-01 01:01:01'),(70,20210526113559,1,'2020-01-01 01:01:01'),(71,20210601000001,1,'2020-01-01 01:01:01'),(72,20210601000002,1,'2020-01-01 01:01:01'),(73,20210601000003,1,'2020-01-01 01:01:01'),(74,20210601000004,1,'2020-01-01 01:01:01'),(75,20210601000005,1,'2020-01-01 01:01:01'),(76,20210601000006,1,'2020-01-01 01:01:01'),(77,20210601000007,1,'2020-01-01 01:01:01'),(78,20210601000008,1,'2020-01-01 01:01:01'),(79,20210606151329,1,'2020-01-01 01:01:01'),(80,20210616163757,1,'2020-01-01 01:01:01'),(81,20210617174723,1,'2020-01-01 01:01:01'),(82,20210622160235,1,'2020-01-01 01:01:01'),(83,20210623100031,1,'2020-01-01 01:01:01'),(84,20210623133615,1,'2020-01-01 01:01:01'),(85,20210708143152,1,'2020-01-01 01:01:01'),(86,20210709124443,1,'2020-01-01 01:01:01'),(87,20210712155608,1,'2020-01-01 01:01:01'),(88,20210714102108,1,'2020-01-01 01:01:01'),(89,20210719153709,1,'2020-01-01 01:01:01'),(90,20210721171531,1,'2020-01-01 01:01:01'),(91,20210723135713,1,'2020-01-01 01:01:01'),(92,20210802135933,1,'2020-01-01 01:01:01'),(93,20210806112844,1,'2020-01-01 01:01:01'),(94,20210810095603,1,'2020-01-01 01:01:01'),(95,20210811150223,1,'2020-01-01 01:01:01'),(96,20210818151827,1,'2020-01-01 01:01:01'),(97,20210818151828,1,'2020-01-01 01:01:01'),(98,20210818182258,1,'2020-01-01 01:01:01'),(99,20210819131107,1,'2020-01-01 01:01:01'),(100,20210819143446,1,'2020-01-01 01:01:01'),(101,20210903132338,1,'2020-01-01 01:01:01'),(102,20210915144307,1,'2020-01-01 01:01:01'),(103,20210920155130,1,'2020-01-01 01:01:01'),(104,20210927143115,1,'2020-01-01 01:01:01'),(105,20210927143116,1,'2020-01-01 01:01:01'),(106,20211013133706,1,'2020-01-01 01:01:01'),(107,20211013133707,1,'2020-01-01 01:01:01'),(108,20211102135149,1,'2020-01-01 01:01:01'),(109,20211109121546,1,'2020-01-01 01:01:01'),(110,20211110163320,1,'2020-01-01 01:01:01'),(111,20211116184029,1,'2020-01-01 01:01:01'),(112,20211116184030,1,'2020-01-01 01:01:01'),(113,20211202092042,1,'2020-01-01 01:01:01'),(114,20211202181033,1,'2020-01-01 01:01:01'),(115,20211207161856,1,'2020-01-01 01:01:01'),(116,20211216131203,1,'2020-01-01 01:01:01'),(117,20211221110132,1,'2020-01-01 01:01:01'),(118,20220107155700,1,'2020-01-01 01:01:01'),(119,20220125105650,1,'2020-01-01 01:01:01'),(120,20220201084510,1,'2020-01-01 01:01:01'),(121,20220208144830,1,'2020-01-01 01:01:01'),(122,20220208144831,1,'2020-01-01 01:01:01'),(123,20220215152203,1,'2020-01-01 01:01:01'),(124,20220223113157,1,'2020-01-01 01:01:01'),(125,20220307104655,1,'2020-01-01 01:01:01'),(126,20220309133956,1,'2020-01-01 01:01:01'),(127,20220316155700,1,'2020-01-01 01:01:01'),(128,20220323152301,1,'2020-01-01 01:01:01'),(129,20220330100659,1,'2020-01-01 01:01:01'),(130,20220404091216,1,'2020-01-01 01:01:01'),(131,20220419140750,1,'2020-01-01 01:01:01'),(132,20220428140039,1,'2020-01-01 01:01:01'),(133,20220503134048,1,'2020-01-01 01:01:01'),(134,20220524102918,1,'2020-01-01 01:01:01'),(135,20220526123327,1,'2020-01-01 01:01:01'),(136,20220526123328,1,'2020-01-01 01:01:01'),(137,20220526123329,1,'2020-01-01 01:01:01'),(138,20220608113128,1,'2020-01-01 01:01:01'),(139,20220627104817,1,'2020-01-01 01:01:01'),(140,20220704101843,1,'2020-01-01 01:01:01'),(141,20220708095046,1,'2020-01-01 01:01:01'),(142,20220713091130,1,'2020-01-01 01:01:01'),(143,20220802135510,1,'2020-01-01 01:01:01'),(144,20220818101352,1,'2020-01-01 01:01:01'),(145,20220822161445,1,'2020-01-01 01:01:01'),(146,20220831100036,1,'2020-01-01 01:01:01'),(147,20220831100151,1,'2020-01-01 01:01:01'),(148,20220908181826,1,'2020-01-01 01:01:01'),(149,20220914154915,1,'2020-01-01 01:01:01'),(150,20220915165115,1,'2020-01-01 01:01:01'),(151,20220915165116,1,'2020-01-01 01:01:01'),(152,20220928100158,1,'2020-01-01 01:01:01'),(153,20221014084130,1,'2020-01-01 01:01:01'),(154,20221027085019,1,'2020-01-01 01:01:01'),(155,20221101103952,1,'2020-01-01 01:01:01'),(156,20221104144401,1,'2020-01-01 01:01:01'),(157,20221109100749,1,'2020-01-01 01:01:01'),(158,20221115104546,1,'2020-01-01 01:01:01'),(159,20221130114928,1,'2020-01-01 01:01:01'),(160,20221205112142,1,'2020-01-01 01:01:01'),(161,20221216115820,1,'2020-01-01 01:01:01'),(162,20221220195934,1,'2020-01-01 01:01:01'),(163,20221220195935,1,'2020-01-01 01:01:01'),(164,20221223174807,1,'2020-01-01 01:01:01'),(165,20221227163855,1,'2020-01-01 01:01:01'),(166,20221227163856,1,'2020-01-01 01:01:01'),(167,20230202224725,1,'2020-01-01 01:01:01'),(168,20230206163608,1,'2020-01-01 01:01:01'),(169,20230214131519,1,'2020-01-01 01:01:01'),(170,20230303135738,1,'2020-01-01 01:01:01'),(171,20230313135301,1,'2020-01-01 01:01:01'),(172,20230313141819,1,'2020-01-01 01:01:01'),(173,20230315104937,1,'2020-01-01 01:01:01'),(174,20230317173844,1,'2020-01-01 01:01:01'),(175,20230320133602,1,'2020-01-01 01:01:01'),(176,20230330100011,1,'2020-01-01 01:01:01'),(177,20230330134823,1,'2020-01-01 01:01:01'),(178,20230405232025,1,'2020-01-01 01:01:01'),(179,20230408084104,1,'2020-01-01 01:01:01'),(180,20230411102858,1,'2020-01-01 01:01:01'),(181,20230421155932,1,'2020-01-01 01:01:01'),(182,20230425082126,1,'2020-01-01 01:01:01'),(183,20230425105727,1,'2020-01-01 01:01:01'),(184,20230501154913,1,'2020-01-01 01:01:01'),(185,20230503101418,1,'2020-01-01 01:01:01'),(186,20230515144206,1,'2020-01-01 01:01:01'),(187,20230517140952,1,'2020-01-01 01:01:01'),(188,20230517152807,1,'2020-01-01 01:01:01'),(189,20230518114155,1,'2020-01-01 01:01:01'),(190,20230520153236,1,'2020-01-01 01:01:01'),(191,20230525151159,1,'2020-01-01 01:01:01'),(192,20230530122103,1,'2020-01-01 01:01:01'),(193,20230602111827,1,'2020-01-01 01:01:01'),(194,20230608103123,1,'2020-01-01 01:01:01'),(195,20230629140529,1,'2020-01-01 01:01:01'),(196,20230629140530,1,'2020-01-01 01:01:01'),(197,20230711144622,1,'2020-01-01 01:01:01'),(198,20230721135421,1,'2020-01-01 01:01:01'),(199,20230721161508,1,'2020-01-01 01:01:01'),(200,20230726115701,1,'2020-01-01 01:01:01'),(201,20230807100822,1,'2020-01-01 01:01:01'),(202,20230814150442,1,'2020-01-01 01:01:01'),(203,20230823122728,1,'2020-01-01 01:01:01'),(204,20230906152143,1,'2020-01-01 01:01:01'),(205,20230911163618,1,'2020-01-01 01:01:01'),(206,20230912101759,1,'2020-01-01 01:01:01'),(207,20230915101341,1,'2020-01-01 01:01:01'),(208,20230918132351,1,'2020-01-01 01:01:01'),(209,20231004144339,1,'2020-01-01 01:01:01'),(210,20231009094541,1,'2020-01-01 01:01:01'),(211,20231009094542,1,'2020-01-01 01:01:01'),(212,20231009094543,1,'2020-01-01 01:01:01'),(213,20231009094544,1,'2020-01-01 01:01:01'),(214,20231016091915,1,'2020-01-01 01:01:01'),(215,20231024174135,1,'2020-01-01 01:01:01'),(216,20231025120016,1,'2020-01-01 01:01:01'),(217,20231025160156,1,'2020-01-01 01:01:01'),(218,20231031165350,1,'2020-01-01 01:01:01'),(219,20231106144110,1,'2020-01-01 01:01:01'),(220,20231107130934,1,'2020-01-01 01:01:01'),(221,20231109115838,1,'2020-01-01 01:01:01'),(222,20231121054530,1,'2020-01-01 01:01:01'),(223,20231122101320,1,'2020-01-01 01:01:01'),(224,20231130132828,1,'2020-01-01 01:01:01'),(225,20231130132931,1,'2020-01-01 01:01:01'),(226,20231204155427,1,'2020-01-01 01:01:01'),(227,20231206142340,1,'2020-01-01 01:01:01'),(228,20231207102320,1,'2020-01-01 01:01:01'),(229,20231207102321,1,'2020-01-01 01:01:01'),(230,20231207133731,1,'2020-01-01 01:01:01'),(231,20231212094238,1,'2020-01-01 01:01:01'),(232,20231212095734,1,'2020-01-01 01:01:01'),(233,20231212161121,1,'2020-01-01 01:01:01'),(234,20231215122713,1,'2020-01-01 01:01:01'),(235,20231219143041,1,'2020-01-01 01:01:01'),(236,20231224070653,1,'2020-01-01 01:01:01'),(237,20240110134315,1,'2020-01-01 01:01:01'),(238,20240119091637,1,'2020-01-01 01:01:01'),(239,20240126020642,1,'2020-01-01 01:01:01'),(240,20240126020643,1,'2020-01-01 01:01:01'),(241,20240129162819,1,'2020-01-01 01:01:01'),(242,20240130115133,1,'2020-01-01 01:01:01'),(243,20240131083822,1,'2020-01-01 01:01:01'),(244,20240205095928,1,'2020-01-01 01:01:01'),(245,20240205121956,1,'2020-01-01 01:01:01'),(246,20240209110212,1,'2020-01-01 01:01:01'),(247,20240212111533,1,'2020-01-01 01:01:01'),(248,20240221112844,1,'2020-01-01 01:01:01'),(249,20240222073518,1,'2020-01-01 01:01:01'),(250,20240222135115,1,'2020-01-01 01:01:01'),(251,20240226082255,1,'2020-01-01 01:01:01'),(252,20240228082706,1,'2020-01-01 01:01:01'),(253,20240301173035,1,'2020-01-01 01:01:01'),(254,20240302111134,1,'2020-01-01 01:01:01'),(255,20240312103753,1,'2020-01-01 01:01:01'),(256,20240313143416,1,'2020-01-01 01:01:01'),(257,20240314085226,1,'2020-01-01 01:01:01'),(258,20240314151747,1,'2020-01-01 01:01:01'),(259,20240320145650,1,'2020-01-01 01:01:01'),(260,20240327115530,1,'2020-01-01 01:01:01'),(261,20240327115617,1,'2020-01-01 01:01:01'),(262,20240408085837,1,'2020-01-01 01:01:01'),(263,20240415104633,1,'2020-01-01 01:01:01'),(264,20240430111727,1,'2020-01-01 01:01:01'),(265,20240515200020,1,'2020-01-01 01:01:01'),(266,20240521143023,1,'2020-01-01 01:01:01'),(267,20240521143024,1,'2020-01-01 01:01:01'),(268,20240601174138,1,'2020-01-01 01:01:01'),(269,20240607133721,1,'2020-01-01 01:01:01'),(270,20240612150059,1,'2020-01-01 01:01:01'),(271,20240613162201,1,'2020-01-01 01:01:01'),(272,20240613172616,1,'2020-01-01 01:01:01'),(273,20240618142419,1,'2020-01-01 01:01:01'),(274,20240625093543,1,'2020-01-01 01:01:01'),(275,20240626195531,1,'2020-01-01 01:01:01'),(276,20240702123921,1,'2020-01-01 01:01:01'),(277,20240703154849,1,'2020-01-01 01:01:01'),(278,20240707134035,1,'2020-01-01 01:01:01'),(279,20240707134036,1,'2020-01-01 01:01:01'),(280,20240709124958,1,'2020-01-01 01:01:01'),(281,20240709132642,1,'2020-01-01 01:01:01'),(282,20240709183940,1,'2020-01-01 01:01:01'),(283,20240710155623,1,'2020-01-01 01:01:01'),(284,20240723102712,1,'2020-01-01 01:01:01'),(285,20240725152735,1,'2020-01-01 01:01:01'),(286,20240725182118,1,'2020-01-01 01:01:01'),(287,20240726100517,1,'2020-01-01 01:01:01'),(288,20240730171504,1,'2020-01-01 01:01:01'),(289,20240730174056,1,'2020-01-01 01:01:01'),(290,20240730215453,1,'2020-01-01 01:01:01'),(291,20240730374423,1,'2020-01-01 01:01:01'),(292,20240801115359,1,'2020-01-01 01:01:01'),(293,20240802101043,1,'2020-01-01 01:01:01'),(294,20240802113716,1,'2020-01-01 01:01:01'),(295,20240814135330,1,'2020-01-01 01:01:01'),(296,20240815000000,1,'2020-01-01 01:01:01'),(297,20240815000001,1,'2020-01-01 01:01:01'),(298,20240816103247,1,'2020-01-01 01:01:01'),(299,20240820091218,1,'2020-01-01 01:01:01'),(300,20240826111228,1,'2020-01-01 01:01:01'),(301,20240826160025,1,'2020-01-01 01:01:01'),(302,20240829165448,1,'2020-01-01 01:01:01'),(303,20240829165605,1,'2020-01-01 01:01:01'),(304,20240829165715,1,'2020-01-01 01:01:01'),(305,20240829165930,1,'2020-01-01 01:01:01'),(306,20240829170023,1,'2020-01-01 01:01:01'),(307,20240829170033,1,'2020-01-01 01:01:01'),(308,20240829170044,1,'2020-01-01 01:01:01'),(309,20240905105135,1,'2020-01-01 01:01:01'),(310,20240905140514,1,'2020-01-01 01:01:01'),(311,20240905200000,1,'2020-01-01 01:01:01'),(312,20240905200001,1,'2020-01-01 01:01:01'),(313,20241002104104,1,'2020-01-01 01:01:01'),(314,20241002104105,1,'2020-01-01 01:01:01'),(315,20241002104106,1,'2020-01-01 01:01:01'),(316,20241002210000,1,'2020-01-01 01:01:01'),(317,20241003145349,1,'2020-01-01 01:01:01'),(318,20241004005000,1,'2020-01-01 01:01:01'),(319,20241008083925,1,'2020-01-01 01:01:01'),(320,20241009090010,1,'2020-01-01 01:01:01'),(321,20241017163402,1,'2020-01-01 01:01:01'),(322,20241021224359,1,'2020-01-01 01:01:01'),(323,20241022140321,1,'2020-01-01 01:01:01'),(324,20241025111236,1,'2020-01-01 01:01:01'),(325,20241025112748,1,'2020-01-01 01:01:01'),(326,20241025141855,1,'2020-01-01 01:01:01'),(327,20241110152839,1,'2020-01-01 01:01:01'),(328,20241110152840,1,'2020-01-01 01:01:01'),(329,20241110152841,1,'2020-01-01 01:01:01'),(330,20241116233322,1,'2020-01-01 01:01:01'),(331,20241122171434,1,'2020-01-01 01:01:01'),(332,20241125150614,1,'2020-01-01 01:01:01'),(333,20241203125346,1,'2020-01-01 01:01:01'),(334,20241203130032,1,'2020-01-01 01:01:01'),(335,20241205122800,1,'2020-01-01 01:01:01'),(336,20241209164540,1,'2020-01-01 01:01:01'),(337,20241210140021,1,'2020-01-01 01:01:01'),(338,20241219180042,1,'2020-01-01 01:01:01'),(339,20241220100000,1,'2020-01-01 01:01:01'),(340,20241220114903,1,'2020-01-01 01:01:01'),(341,20241220114904,1,'2020-01-01 01:01:01'),(342,20241224000000,1,'2020-01-01 01:01:01'),(343,20241230000000,1,'2020-01-01 01:01:01'),(344,20241231112624,1,'2020-01-01 01:01:01'),(345,20250102121439,1,'2020-01-01 01:01:01'),(346,20250121094045,1,'2020-01-01 01:01:01'),(347,20250121094500,1,'2020-01-01 01:01:01'),(348,20250121094600,1,'2020-01-01 01:01:01'),(349,20250121094700,1,'2020-01-01 01:01:01'),(350,20250124194347,1,'2020-01-01 01:01:01'),(351,20250127162751,1,'2020-01-01 01:01:01'),(352,20250213104005,1,'2020-01-01 01:01:01'),(353,20250214205657,1,'2020-01-01 01:01:01'),(354,20250217093329,1,'2020-01-01 01:01:01'),(355,20250219090511,1,'2020-01-01 01:01:01'),(356,20250219100000,1,'2020-01-01 01:01:01'),(357,20250219142401,1,'2020-01-01 01:01:01'),(358,20250224184002,1,'2020-01-01 01:01:01'),(359,20250225085436,1,'2020-01-01 01:01:01'),(360,20250226000000,1,'2020-01-01 01:01:01'),(361,20250226153445,1,'2020-01-01 01:01:01'),(362,20250304162702,1,'2020-01-01 01:01:01'),(363,20250306144233,1,'2020-01-01 01:01:01'),(364,20250313163430,1,'2020-01-01 01:01:01'),(365,20250317130944,1,'2020-01-01 01:01:01'),(366,20250318165922,1,'2020-01-01 01:01:01'),(367,20250320132525,1,'2020-01-01 01:01:01'),(368,20250320200000,1,'2020-01-01 01:01:01'),(369,20250326161930,1,'2020-01-01 01:01:01'),(370,20250326161931,1,'2020-01-01 01:01:01'),(371,20250331042354,1,'2020-01-01 01:01:01'),(372,20250331154206,1,'2020-01-01 01:01:01'),(373,20250401155831,1,'2020-01-01 01:01:01'),(374,20250408133233,1,'2020-01-01 01:01:01'),(375,20250410104321,1,'2020-01-01 01:01:01'),(376,20250421085116,1,'2020-01-01 01:01:01'),(377,20250422095806,1,'2020-01-01 01:01:01'),(378,20250424153059,1,'2020-01-01 01:01:01'),(379,20250430103833,1,'2020-01-01 01:01:01'),(380,20250430112622,1,'2020-01-01 01:01:01'),(381,20250501162727,1,'2020-01-01 01:01:01'),(382,20250502154517,1,'2020-01-01 01:01:01'),(383,20250502222222,1,'2020-01-01 01:01:01'),(384,20250507170845,1,'2020-01-01 01:01:01'),(385,20250513162912,1,'2020-01-01 01:01:01'),(386,20250519161614,1,'2020-01-01 01:01:01'),(387,20250519170000,1,'2020-01-01 01:01:01'),(388,20250520153848,1,'2020-01-01 01:01:01'),(389,20250528115932,1,'2020-01-01 01:01:01'),(390,20250529102706,1,'2020-01-01 01:01:01'),(391,20250603105558,1,'2020-01-01 01:01:01'),(392,20250609102714,1,'2020-01-01 01:01:01'),(393,20250609112613,1,'2020-01-01 01:01:01'),(394,20250613103810,1,'2020-01-01 01:01:01'),(395,20250616193950,1,'2020-01-01 01:01:01'),(396,20250624140757,1,'2020-01-01 01:01:01'),(397,20250626130239,1,'2020-01-01 01:01:01'),(398,20250629131032,1,'2020-01-01 01:01:01'),(399,20250701155654,1,'2020-01-01 01:01:01'),(400,20250707095725,1,'2020-01-01 01:01:01'),(401,20250716152435,1,'2020-01-01 01:01:01'); +INSERT INTO `migration_status_tables` VALUES (1,0,1,'2020-01-01 01:01:01'),(2,20161118193812,1,'2020-01-01 01:01:01'),(3,20161118211713,1,'2020-01-01 01:01:01'),(4,20161118212436,1,'2020-01-01 01:01:01'),(5,20161118212515,1,'2020-01-01 01:01:01'),(6,20161118212528,1,'2020-01-01 01:01:01'),(7,20161118212538,1,'2020-01-01 01:01:01'),(8,20161118212549,1,'2020-01-01 01:01:01'),(9,20161118212557,1,'2020-01-01 01:01:01'),(10,20161118212604,1,'2020-01-01 01:01:01'),(11,20161118212613,1,'2020-01-01 01:01:01'),(12,20161118212621,1,'2020-01-01 01:01:01'),(13,20161118212630,1,'2020-01-01 01:01:01'),(14,20161118212641,1,'2020-01-01 01:01:01'),(15,20161118212649,1,'2020-01-01 01:01:01'),(16,20161118212656,1,'2020-01-01 01:01:01'),(17,20161118212758,1,'2020-01-01 01:01:01'),(18,20161128234849,1,'2020-01-01 01:01:01'),(19,20161230162221,1,'2020-01-01 01:01:01'),(20,20170104113816,1,'2020-01-01 01:01:01'),(21,20170105151732,1,'2020-01-01 01:01:01'),(22,20170108191242,1,'2020-01-01 01:01:01'),(23,20170109094020,1,'2020-01-01 01:01:01'),(24,20170109130438,1,'2020-01-01 01:01:01'),(25,20170110202752,1,'2020-01-01 01:01:01'),(26,20170111133013,1,'2020-01-01 01:01:01'),(27,20170117025759,1,'2020-01-01 01:01:01'),(28,20170118191001,1,'2020-01-01 01:01:01'),(29,20170119234632,1,'2020-01-01 01:01:01'),(30,20170124230432,1,'2020-01-01 01:01:01'),(31,20170127014618,1,'2020-01-01 01:01:01'),(32,20170131232841,1,'2020-01-01 01:01:01'),(33,20170223094154,1,'2020-01-01 01:01:01'),(34,20170306075207,1,'2020-01-01 01:01:01'),(35,20170309100733,1,'2020-01-01 01:01:01'),(36,20170331111922,1,'2020-01-01 01:01:01'),(37,20170502143928,1,'2020-01-01 01:01:01'),(38,20170504130602,1,'2020-01-01 01:01:01'),(39,20170509132100,1,'2020-01-01 01:01:01'),(40,20170519105647,1,'2020-01-01 01:01:01'),(41,20170519105648,1,'2020-01-01 01:01:01'),(42,20170831234300,1,'2020-01-01 01:01:01'),(43,20170831234301,1,'2020-01-01 01:01:01'),(44,20170831234303,1,'2020-01-01 01:01:01'),(45,20171116163618,1,'2020-01-01 01:01:01'),(46,20171219164727,1,'2020-01-01 01:01:01'),(47,20180620164811,1,'2020-01-01 01:01:01'),(48,20180620175054,1,'2020-01-01 01:01:01'),(49,20180620175055,1,'2020-01-01 01:01:01'),(50,20191010101639,1,'2020-01-01 01:01:01'),(51,20191010155147,1,'2020-01-01 01:01:01'),(52,20191220130734,1,'2020-01-01 01:01:01'),(53,20200311140000,1,'2020-01-01 01:01:01'),(54,20200405120000,1,'2020-01-01 01:01:01'),(55,20200407120000,1,'2020-01-01 01:01:01'),(56,20200420120000,1,'2020-01-01 01:01:01'),(57,20200504120000,1,'2020-01-01 01:01:01'),(58,20200512120000,1,'2020-01-01 01:01:01'),(59,20200707120000,1,'2020-01-01 01:01:01'),(60,20201011162341,1,'2020-01-01 01:01:01'),(61,20201021104586,1,'2020-01-01 01:01:01'),(62,20201102112520,1,'2020-01-01 01:01:01'),(63,20201208121729,1,'2020-01-01 01:01:01'),(64,20201215091637,1,'2020-01-01 01:01:01'),(65,20210119174155,1,'2020-01-01 01:01:01'),(66,20210326182902,1,'2020-01-01 01:01:01'),(67,20210421112652,1,'2020-01-01 01:01:01'),(68,20210506095025,1,'2020-01-01 01:01:01'),(69,20210513115729,1,'2020-01-01 01:01:01'),(70,20210526113559,1,'2020-01-01 01:01:01'),(71,20210601000001,1,'2020-01-01 01:01:01'),(72,20210601000002,1,'2020-01-01 01:01:01'),(73,20210601000003,1,'2020-01-01 01:01:01'),(74,20210601000004,1,'2020-01-01 01:01:01'),(75,20210601000005,1,'2020-01-01 01:01:01'),(76,20210601000006,1,'2020-01-01 01:01:01'),(77,20210601000007,1,'2020-01-01 01:01:01'),(78,20210601000008,1,'2020-01-01 01:01:01'),(79,20210606151329,1,'2020-01-01 01:01:01'),(80,20210616163757,1,'2020-01-01 01:01:01'),(81,20210617174723,1,'2020-01-01 01:01:01'),(82,20210622160235,1,'2020-01-01 01:01:01'),(83,20210623100031,1,'2020-01-01 01:01:01'),(84,20210623133615,1,'2020-01-01 01:01:01'),(85,20210708143152,1,'2020-01-01 01:01:01'),(86,20210709124443,1,'2020-01-01 01:01:01'),(87,20210712155608,1,'2020-01-01 01:01:01'),(88,20210714102108,1,'2020-01-01 01:01:01'),(89,20210719153709,1,'2020-01-01 01:01:01'),(90,20210721171531,1,'2020-01-01 01:01:01'),(91,20210723135713,1,'2020-01-01 01:01:01'),(92,20210802135933,1,'2020-01-01 01:01:01'),(93,20210806112844,1,'2020-01-01 01:01:01'),(94,20210810095603,1,'2020-01-01 01:01:01'),(95,20210811150223,1,'2020-01-01 01:01:01'),(96,20210818151827,1,'2020-01-01 01:01:01'),(97,20210818151828,1,'2020-01-01 01:01:01'),(98,20210818182258,1,'2020-01-01 01:01:01'),(99,20210819131107,1,'2020-01-01 01:01:01'),(100,20210819143446,1,'2020-01-01 01:01:01'),(101,20210903132338,1,'2020-01-01 01:01:01'),(102,20210915144307,1,'2020-01-01 01:01:01'),(103,20210920155130,1,'2020-01-01 01:01:01'),(104,20210927143115,1,'2020-01-01 01:01:01'),(105,20210927143116,1,'2020-01-01 01:01:01'),(106,20211013133706,1,'2020-01-01 01:01:01'),(107,20211013133707,1,'2020-01-01 01:01:01'),(108,20211102135149,1,'2020-01-01 01:01:01'),(109,20211109121546,1,'2020-01-01 01:01:01'),(110,20211110163320,1,'2020-01-01 01:01:01'),(111,20211116184029,1,'2020-01-01 01:01:01'),(112,20211116184030,1,'2020-01-01 01:01:01'),(113,20211202092042,1,'2020-01-01 01:01:01'),(114,20211202181033,1,'2020-01-01 01:01:01'),(115,20211207161856,1,'2020-01-01 01:01:01'),(116,20211216131203,1,'2020-01-01 01:01:01'),(117,20211221110132,1,'2020-01-01 01:01:01'),(118,20220107155700,1,'2020-01-01 01:01:01'),(119,20220125105650,1,'2020-01-01 01:01:01'),(120,20220201084510,1,'2020-01-01 01:01:01'),(121,20220208144830,1,'2020-01-01 01:01:01'),(122,20220208144831,1,'2020-01-01 01:01:01'),(123,20220215152203,1,'2020-01-01 01:01:01'),(124,20220223113157,1,'2020-01-01 01:01:01'),(125,20220307104655,1,'2020-01-01 01:01:01'),(126,20220309133956,1,'2020-01-01 01:01:01'),(127,20220316155700,1,'2020-01-01 01:01:01'),(128,20220323152301,1,'2020-01-01 01:01:01'),(129,20220330100659,1,'2020-01-01 01:01:01'),(130,20220404091216,1,'2020-01-01 01:01:01'),(131,20220419140750,1,'2020-01-01 01:01:01'),(132,20220428140039,1,'2020-01-01 01:01:01'),(133,20220503134048,1,'2020-01-01 01:01:01'),(134,20220524102918,1,'2020-01-01 01:01:01'),(135,20220526123327,1,'2020-01-01 01:01:01'),(136,20220526123328,1,'2020-01-01 01:01:01'),(137,20220526123329,1,'2020-01-01 01:01:01'),(138,20220608113128,1,'2020-01-01 01:01:01'),(139,20220627104817,1,'2020-01-01 01:01:01'),(140,20220704101843,1,'2020-01-01 01:01:01'),(141,20220708095046,1,'2020-01-01 01:01:01'),(142,20220713091130,1,'2020-01-01 01:01:01'),(143,20220802135510,1,'2020-01-01 01:01:01'),(144,20220818101352,1,'2020-01-01 01:01:01'),(145,20220822161445,1,'2020-01-01 01:01:01'),(146,20220831100036,1,'2020-01-01 01:01:01'),(147,20220831100151,1,'2020-01-01 01:01:01'),(148,20220908181826,1,'2020-01-01 01:01:01'),(149,20220914154915,1,'2020-01-01 01:01:01'),(150,20220915165115,1,'2020-01-01 01:01:01'),(151,20220915165116,1,'2020-01-01 01:01:01'),(152,20220928100158,1,'2020-01-01 01:01:01'),(153,20221014084130,1,'2020-01-01 01:01:01'),(154,20221027085019,1,'2020-01-01 01:01:01'),(155,20221101103952,1,'2020-01-01 01:01:01'),(156,20221104144401,1,'2020-01-01 01:01:01'),(157,20221109100749,1,'2020-01-01 01:01:01'),(158,20221115104546,1,'2020-01-01 01:01:01'),(159,20221130114928,1,'2020-01-01 01:01:01'),(160,20221205112142,1,'2020-01-01 01:01:01'),(161,20221216115820,1,'2020-01-01 01:01:01'),(162,20221220195934,1,'2020-01-01 01:01:01'),(163,20221220195935,1,'2020-01-01 01:01:01'),(164,20221223174807,1,'2020-01-01 01:01:01'),(165,20221227163855,1,'2020-01-01 01:01:01'),(166,20221227163856,1,'2020-01-01 01:01:01'),(167,20230202224725,1,'2020-01-01 01:01:01'),(168,20230206163608,1,'2020-01-01 01:01:01'),(169,20230214131519,1,'2020-01-01 01:01:01'),(170,20230303135738,1,'2020-01-01 01:01:01'),(171,20230313135301,1,'2020-01-01 01:01:01'),(172,20230313141819,1,'2020-01-01 01:01:01'),(173,20230315104937,1,'2020-01-01 01:01:01'),(174,20230317173844,1,'2020-01-01 01:01:01'),(175,20230320133602,1,'2020-01-01 01:01:01'),(176,20230330100011,1,'2020-01-01 01:01:01'),(177,20230330134823,1,'2020-01-01 01:01:01'),(178,20230405232025,1,'2020-01-01 01:01:01'),(179,20230408084104,1,'2020-01-01 01:01:01'),(180,20230411102858,1,'2020-01-01 01:01:01'),(181,20230421155932,1,'2020-01-01 01:01:01'),(182,20230425082126,1,'2020-01-01 01:01:01'),(183,20230425105727,1,'2020-01-01 01:01:01'),(184,20230501154913,1,'2020-01-01 01:01:01'),(185,20230503101418,1,'2020-01-01 01:01:01'),(186,20230515144206,1,'2020-01-01 01:01:01'),(187,20230517140952,1,'2020-01-01 01:01:01'),(188,20230517152807,1,'2020-01-01 01:01:01'),(189,20230518114155,1,'2020-01-01 01:01:01'),(190,20230520153236,1,'2020-01-01 01:01:01'),(191,20230525151159,1,'2020-01-01 01:01:01'),(192,20230530122103,1,'2020-01-01 01:01:01'),(193,20230602111827,1,'2020-01-01 01:01:01'),(194,20230608103123,1,'2020-01-01 01:01:01'),(195,20230629140529,1,'2020-01-01 01:01:01'),(196,20230629140530,1,'2020-01-01 01:01:01'),(197,20230711144622,1,'2020-01-01 01:01:01'),(198,20230721135421,1,'2020-01-01 01:01:01'),(199,20230721161508,1,'2020-01-01 01:01:01'),(200,20230726115701,1,'2020-01-01 01:01:01'),(201,20230807100822,1,'2020-01-01 01:01:01'),(202,20230814150442,1,'2020-01-01 01:01:01'),(203,20230823122728,1,'2020-01-01 01:01:01'),(204,20230906152143,1,'2020-01-01 01:01:01'),(205,20230911163618,1,'2020-01-01 01:01:01'),(206,20230912101759,1,'2020-01-01 01:01:01'),(207,20230915101341,1,'2020-01-01 01:01:01'),(208,20230918132351,1,'2020-01-01 01:01:01'),(209,20231004144339,1,'2020-01-01 01:01:01'),(210,20231009094541,1,'2020-01-01 01:01:01'),(211,20231009094542,1,'2020-01-01 01:01:01'),(212,20231009094543,1,'2020-01-01 01:01:01'),(213,20231009094544,1,'2020-01-01 01:01:01'),(214,20231016091915,1,'2020-01-01 01:01:01'),(215,20231024174135,1,'2020-01-01 01:01:01'),(216,20231025120016,1,'2020-01-01 01:01:01'),(217,20231025160156,1,'2020-01-01 01:01:01'),(218,20231031165350,1,'2020-01-01 01:01:01'),(219,20231106144110,1,'2020-01-01 01:01:01'),(220,20231107130934,1,'2020-01-01 01:01:01'),(221,20231109115838,1,'2020-01-01 01:01:01'),(222,20231121054530,1,'2020-01-01 01:01:01'),(223,20231122101320,1,'2020-01-01 01:01:01'),(224,20231130132828,1,'2020-01-01 01:01:01'),(225,20231130132931,1,'2020-01-01 01:01:01'),(226,20231204155427,1,'2020-01-01 01:01:01'),(227,20231206142340,1,'2020-01-01 01:01:01'),(228,20231207102320,1,'2020-01-01 01:01:01'),(229,20231207102321,1,'2020-01-01 01:01:01'),(230,20231207133731,1,'2020-01-01 01:01:01'),(231,20231212094238,1,'2020-01-01 01:01:01'),(232,20231212095734,1,'2020-01-01 01:01:01'),(233,20231212161121,1,'2020-01-01 01:01:01'),(234,20231215122713,1,'2020-01-01 01:01:01'),(235,20231219143041,1,'2020-01-01 01:01:01'),(236,20231224070653,1,'2020-01-01 01:01:01'),(237,20240110134315,1,'2020-01-01 01:01:01'),(238,20240119091637,1,'2020-01-01 01:01:01'),(239,20240126020642,1,'2020-01-01 01:01:01'),(240,20240126020643,1,'2020-01-01 01:01:01'),(241,20240129162819,1,'2020-01-01 01:01:01'),(242,20240130115133,1,'2020-01-01 01:01:01'),(243,20240131083822,1,'2020-01-01 01:01:01'),(244,20240205095928,1,'2020-01-01 01:01:01'),(245,20240205121956,1,'2020-01-01 01:01:01'),(246,20240209110212,1,'2020-01-01 01:01:01'),(247,20240212111533,1,'2020-01-01 01:01:01'),(248,20240221112844,1,'2020-01-01 01:01:01'),(249,20240222073518,1,'2020-01-01 01:01:01'),(250,20240222135115,1,'2020-01-01 01:01:01'),(251,20240226082255,1,'2020-01-01 01:01:01'),(252,20240228082706,1,'2020-01-01 01:01:01'),(253,20240301173035,1,'2020-01-01 01:01:01'),(254,20240302111134,1,'2020-01-01 01:01:01'),(255,20240312103753,1,'2020-01-01 01:01:01'),(256,20240313143416,1,'2020-01-01 01:01:01'),(257,20240314085226,1,'2020-01-01 01:01:01'),(258,20240314151747,1,'2020-01-01 01:01:01'),(259,20240320145650,1,'2020-01-01 01:01:01'),(260,20240327115530,1,'2020-01-01 01:01:01'),(261,20240327115617,1,'2020-01-01 01:01:01'),(262,20240408085837,1,'2020-01-01 01:01:01'),(263,20240415104633,1,'2020-01-01 01:01:01'),(264,20240430111727,1,'2020-01-01 01:01:01'),(265,20240515200020,1,'2020-01-01 01:01:01'),(266,20240521143023,1,'2020-01-01 01:01:01'),(267,20240521143024,1,'2020-01-01 01:01:01'),(268,20240601174138,1,'2020-01-01 01:01:01'),(269,20240607133721,1,'2020-01-01 01:01:01'),(270,20240612150059,1,'2020-01-01 01:01:01'),(271,20240613162201,1,'2020-01-01 01:01:01'),(272,20240613172616,1,'2020-01-01 01:01:01'),(273,20240618142419,1,'2020-01-01 01:01:01'),(274,20240625093543,1,'2020-01-01 01:01:01'),(275,20240626195531,1,'2020-01-01 01:01:01'),(276,20240702123921,1,'2020-01-01 01:01:01'),(277,20240703154849,1,'2020-01-01 01:01:01'),(278,20240707134035,1,'2020-01-01 01:01:01'),(279,20240707134036,1,'2020-01-01 01:01:01'),(280,20240709124958,1,'2020-01-01 01:01:01'),(281,20240709132642,1,'2020-01-01 01:01:01'),(282,20240709183940,1,'2020-01-01 01:01:01'),(283,20240710155623,1,'2020-01-01 01:01:01'),(284,20240723102712,1,'2020-01-01 01:01:01'),(285,20240725152735,1,'2020-01-01 01:01:01'),(286,20240725182118,1,'2020-01-01 01:01:01'),(287,20240726100517,1,'2020-01-01 01:01:01'),(288,20240730171504,1,'2020-01-01 01:01:01'),(289,20240730174056,1,'2020-01-01 01:01:01'),(290,20240730215453,1,'2020-01-01 01:01:01'),(291,20240730374423,1,'2020-01-01 01:01:01'),(292,20240801115359,1,'2020-01-01 01:01:01'),(293,20240802101043,1,'2020-01-01 01:01:01'),(294,20240802113716,1,'2020-01-01 01:01:01'),(295,20240814135330,1,'2020-01-01 01:01:01'),(296,20240815000000,1,'2020-01-01 01:01:01'),(297,20240815000001,1,'2020-01-01 01:01:01'),(298,20240816103247,1,'2020-01-01 01:01:01'),(299,20240820091218,1,'2020-01-01 01:01:01'),(300,20240826111228,1,'2020-01-01 01:01:01'),(301,20240826160025,1,'2020-01-01 01:01:01'),(302,20240829165448,1,'2020-01-01 01:01:01'),(303,20240829165605,1,'2020-01-01 01:01:01'),(304,20240829165715,1,'2020-01-01 01:01:01'),(305,20240829165930,1,'2020-01-01 01:01:01'),(306,20240829170023,1,'2020-01-01 01:01:01'),(307,20240829170033,1,'2020-01-01 01:01:01'),(308,20240829170044,1,'2020-01-01 01:01:01'),(309,20240905105135,1,'2020-01-01 01:01:01'),(310,20240905140514,1,'2020-01-01 01:01:01'),(311,20240905200000,1,'2020-01-01 01:01:01'),(312,20240905200001,1,'2020-01-01 01:01:01'),(313,20241002104104,1,'2020-01-01 01:01:01'),(314,20241002104105,1,'2020-01-01 01:01:01'),(315,20241002104106,1,'2020-01-01 01:01:01'),(316,20241002210000,1,'2020-01-01 01:01:01'),(317,20241003145349,1,'2020-01-01 01:01:01'),(318,20241004005000,1,'2020-01-01 01:01:01'),(319,20241008083925,1,'2020-01-01 01:01:01'),(320,20241009090010,1,'2020-01-01 01:01:01'),(321,20241017163402,1,'2020-01-01 01:01:01'),(322,20241021224359,1,'2020-01-01 01:01:01'),(323,20241022140321,1,'2020-01-01 01:01:01'),(324,20241025111236,1,'2020-01-01 01:01:01'),(325,20241025112748,1,'2020-01-01 01:01:01'),(326,20241025141855,1,'2020-01-01 01:01:01'),(327,20241110152839,1,'2020-01-01 01:01:01'),(328,20241110152840,1,'2020-01-01 01:01:01'),(329,20241110152841,1,'2020-01-01 01:01:01'),(330,20241116233322,1,'2020-01-01 01:01:01'),(331,20241122171434,1,'2020-01-01 01:01:01'),(332,20241125150614,1,'2020-01-01 01:01:01'),(333,20241203125346,1,'2020-01-01 01:01:01'),(334,20241203130032,1,'2020-01-01 01:01:01'),(335,20241205122800,1,'2020-01-01 01:01:01'),(336,20241209164540,1,'2020-01-01 01:01:01'),(337,20241210140021,1,'2020-01-01 01:01:01'),(338,20241219180042,1,'2020-01-01 01:01:01'),(339,20241220100000,1,'2020-01-01 01:01:01'),(340,20241220114903,1,'2020-01-01 01:01:01'),(341,20241220114904,1,'2020-01-01 01:01:01'),(342,20241224000000,1,'2020-01-01 01:01:01'),(343,20241230000000,1,'2020-01-01 01:01:01'),(344,20241231112624,1,'2020-01-01 01:01:01'),(345,20250102121439,1,'2020-01-01 01:01:01'),(346,20250121094045,1,'2020-01-01 01:01:01'),(347,20250121094500,1,'2020-01-01 01:01:01'),(348,20250121094600,1,'2020-01-01 01:01:01'),(349,20250121094700,1,'2020-01-01 01:01:01'),(350,20250124194347,1,'2020-01-01 01:01:01'),(351,20250127162751,1,'2020-01-01 01:01:01'),(352,20250213104005,1,'2020-01-01 01:01:01'),(353,20250214205657,1,'2020-01-01 01:01:01'),(354,20250217093329,1,'2020-01-01 01:01:01'),(355,20250219090511,1,'2020-01-01 01:01:01'),(356,20250219100000,1,'2020-01-01 01:01:01'),(357,20250219142401,1,'2020-01-01 01:01:01'),(358,20250224184002,1,'2020-01-01 01:01:01'),(359,20250225085436,1,'2020-01-01 01:01:01'),(360,20250226000000,1,'2020-01-01 01:01:01'),(361,20250226153445,1,'2020-01-01 01:01:01'),(362,20250304162702,1,'2020-01-01 01:01:01'),(363,20250306144233,1,'2020-01-01 01:01:01'),(364,20250313163430,1,'2020-01-01 01:01:01'),(365,20250317130944,1,'2020-01-01 01:01:01'),(366,20250318165922,1,'2020-01-01 01:01:01'),(367,20250320132525,1,'2020-01-01 01:01:01'),(368,20250320200000,1,'2020-01-01 01:01:01'),(369,20250326161930,1,'2020-01-01 01:01:01'),(370,20250326161931,1,'2020-01-01 01:01:01'),(371,20250331042354,1,'2020-01-01 01:01:01'),(372,20250331154206,1,'2020-01-01 01:01:01'),(373,20250401155831,1,'2020-01-01 01:01:01'),(374,20250408133233,1,'2020-01-01 01:01:01'),(375,20250410104321,1,'2020-01-01 01:01:01'),(376,20250421085116,1,'2020-01-01 01:01:01'),(377,20250422095806,1,'2020-01-01 01:01:01'),(378,20250424153059,1,'2020-01-01 01:01:01'),(379,20250430103833,1,'2020-01-01 01:01:01'),(380,20250430112622,1,'2020-01-01 01:01:01'),(381,20250501162727,1,'2020-01-01 01:01:01'),(382,20250502154517,1,'2020-01-01 01:01:01'),(383,20250502222222,1,'2020-01-01 01:01:01'),(384,20250507170845,1,'2020-01-01 01:01:01'),(385,20250513162912,1,'2020-01-01 01:01:01'),(386,20250519161614,1,'2020-01-01 01:01:01'),(387,20250519170000,1,'2020-01-01 01:01:01'),(388,20250520153848,1,'2020-01-01 01:01:01'),(389,20250528115932,1,'2020-01-01 01:01:01'),(390,20250529102706,1,'2020-01-01 01:01:01'),(391,20250603105558,1,'2020-01-01 01:01:01'),(392,20250609102714,1,'2020-01-01 01:01:01'),(393,20250609112613,1,'2020-01-01 01:01:01'),(394,20250613103810,1,'2020-01-01 01:01:01'),(395,20250616193950,1,'2020-01-01 01:01:01'),(396,20250624140757,1,'2020-01-01 01:01:01'),(397,20250626130239,1,'2020-01-01 01:01:01'),(398,20250629131032,1,'2020-01-01 01:01:01'),(399,20250701155654,1,'2020-01-01 01:01:01'),(400,20250707095725,1,'2020-01-01 01:01:01'),(401,20250716152435,1,'2020-01-01 01:01:01'),(402,20250718091828,1,'2020-01-01 01:01:01'); /*!40101 SET @saved_cs_client = @@character_set_client */; /*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `mobile_device_management_solutions` ( diff --git a/server/fleet/datastore.go b/server/fleet/datastore.go index 8115a31fc3..3b6e802576 100644 --- a/server/fleet/datastore.go +++ b/server/fleet/datastore.go @@ -961,7 +961,7 @@ type Datastore interface { SaveHostAdditional(ctx context.Context, hostID uint, additional *json.RawMessage) error SetOrUpdateMunkiInfo(ctx context.Context, hostID uint, version string, errors, warnings []string) error - SetOrUpdateMDMData(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollRef string) error + SetOrUpdateMDMData(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollRef string, isPersonalEnrollment bool) error // UpdateMDMData updates the `enrolled` field of the host with the given ID. UpdateMDMData(ctx context.Context, hostID uint, enrolled bool) error // GetHostEmails returns the emails associated with the provided host for a given source, such as "google_chrome_profiles" @@ -1234,7 +1234,7 @@ type Datastore interface { // MDMAppleUpsertHost creates or matches a Fleet host record for an // MDM-enrolled device. - MDMAppleUpsertHost(ctx context.Context, mdmHost *Host) error + MDMAppleUpsertHost(ctx context.Context, mdmHost *Host, fromPersonalEnrollment bool) error // RestoreMDMApplePendingDEPHost restores a host that was previously deleted from Fleet. RestoreMDMApplePendingDEPHost(ctx context.Context, host *Host) error diff --git a/server/fleet/hosts.go b/server/fleet/hosts.go index 7fe96db24a..c9a4b1b595 100644 --- a/server/fleet/hosts.go +++ b/server/fleet/hosts.go @@ -64,7 +64,8 @@ const ( MDMEnrollStatusAutomatic = MDMEnrollStatus("automatic") MDMEnrollStatusPending = MDMEnrollStatus("pending") MDMEnrollStatusUnenrolled = MDMEnrollStatus("unenrolled") - MDMEnrollStatusEnrolled = MDMEnrollStatus("enrolled") // combination of "manual" and "automatic" + MDMEnrollStatusEnrolled = MDMEnrollStatus("enrolled") // combination of "manual", "automatic" and "personal" + MDMEnrollStatusPersonal = MDMEnrollStatus("personal") ) // OSSettingsStatus defines the possible statuses of the host's OS settings, which is derived from the @@ -1104,6 +1105,7 @@ type HostMDM struct { ServerURL string `db:"server_url" json:"-" csv:"-"` InstalledFromDep bool `db:"installed_from_dep" json:"-" csv:"-"` IsServer bool `db:"is_server" json:"-" csv:"-"` + IsPersonalEnrollment bool `db:"is_personal_enrollment" json:"-" csv:"-"` MDMID *uint `db:"mdm_id" json:"-" csv:"-"` Name string `db:"name" json:"-" csv:"-"` DEPProfileAssignStatus *string `db:"dep_profile_assign_status" json:"-" csv:"-"` @@ -1167,7 +1169,9 @@ func MDMNameFromServerURL(serverURL string) string { func (h *HostMDM) EnrollmentStatus() string { switch { - case h.Enrolled && !h.InstalledFromDep: + case h.Enrolled && !h.InstalledFromDep && h.IsPersonalEnrollment: + return "On (personal)" + case h.Enrolled && !h.InstalledFromDep && !h.IsPersonalEnrollment: return "On (manual)" case h.Enrolled && h.InstalledFromDep: return "On (automatic)" @@ -1243,6 +1247,7 @@ type AggregatedMunkiIssue struct { type AggregatedMDMStatus struct { EnrolledManualHostsCount int `json:"enrolled_manual_hosts_count" db:"enrolled_manual_hosts_count"` EnrolledAutomatedHostsCount int `json:"enrolled_automated_hosts_count" db:"enrolled_automated_hosts_count"` + EnrolledPersonalHostsCount int `json:"enrolled_personal_hosts_count" db:"enrolled_personal_hosts_count"` PendingHostsCount int `json:"pending_hosts_count" db:"pending_hosts_count"` UnenrolledHostsCount int `json:"unenrolled_hosts_count" db:"unenrolled_hosts_count"` HostsCount int `json:"hosts_count" db:"hosts_count"` diff --git a/server/fleet/hosts_test.go b/server/fleet/hosts_test.go index f82d4f5037..9597939d14 100644 --- a/server/fleet/hosts_test.go +++ b/server/fleet/hosts_test.go @@ -207,13 +207,17 @@ func TestMDMEnrollmentStatus(t *testing.T) { expected string }{ { - hostMDM: HostMDM{Enrolled: true, InstalledFromDep: true}, + hostMDM: HostMDM{Enrolled: true, InstalledFromDep: true, IsPersonalEnrollment: false}, expected: "On (automatic)", }, { - hostMDM: HostMDM{Enrolled: true, InstalledFromDep: false}, + hostMDM: HostMDM{Enrolled: true, InstalledFromDep: false, IsPersonalEnrollment: false}, expected: "On (manual)", }, + { + hostMDM: HostMDM{Enrolled: true, InstalledFromDep: false, IsPersonalEnrollment: true}, + expected: "On (personal)", + }, { hostMDM: HostMDM{Enrolled: false, InstalledFromDep: true}, expected: "Pending", diff --git a/server/mdm/lifecycle/lifecycle.go b/server/mdm/lifecycle/lifecycle.go index 37346a8bda..6fa3941847 100644 --- a/server/mdm/lifecycle/lifecycle.go +++ b/server/mdm/lifecycle/lifecycle.go @@ -130,10 +130,12 @@ func (t *HostLifecycle) resetWindows(ctx context.Context, opts HostOptions) erro } func (t *HostLifecycle) resetApple(ctx context.Context, opts HostOptions) error { + isPersonalEnrollment := false if opts.UUID == "" && opts.HardwareSerial == "" && opts.UserEnrollmentID != "" { // We are doing user enrollment, where we don't have access to device hardware details opts.UUID = opts.UserEnrollmentID opts.HardwareSerial = opts.UserEnrollmentID + isPersonalEnrollment = true } if opts.UUID == "" || opts.HardwareSerial == "" || opts.HardwareModel == "" { return ctxerr.New(ctx, "UUID, HardwareSerial and HardwareModel options are required for this action") @@ -152,7 +154,7 @@ func (t *HostLifecycle) resetApple(ctx context.Context, opts HostOptions) error // to centralize the flow control in the lifecycle methods. if !opts.SCEPRenewalInProgress { // upsert the host to ensure we have the latest information - if err := t.ds.MDMAppleUpsertHost(ctx, host); err != nil { + if err := t.ds.MDMAppleUpsertHost(ctx, host, isPersonalEnrollment); err != nil { return ctxerr.Wrap(ctx, err, "upserting mdm host") } } diff --git a/server/mock/datastore_mock.go b/server/mock/datastore_mock.go index d6fe670625..b83568f23a 100644 --- a/server/mock/datastore_mock.go +++ b/server/mock/datastore_mock.go @@ -689,7 +689,7 @@ type SaveHostAdditionalFunc func(ctx context.Context, hostID uint, additional *j type SetOrUpdateMunkiInfoFunc func(ctx context.Context, hostID uint, version string, errors []string, warnings []string) error -type SetOrUpdateMDMDataFunc func(ctx context.Context, hostID uint, isServer bool, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollRef string) error +type SetOrUpdateMDMDataFunc func(ctx context.Context, hostID uint, isServer bool, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollRef string, isPersonalEnrollment bool) error type UpdateMDMDataFunc func(ctx context.Context, hostID uint, enrolled bool) error @@ -861,7 +861,7 @@ type IngestMDMAppleDevicesFromDEPSyncFunc func(ctx context.Context, devices []go type IngestMDMAppleDeviceFromOTAEnrollmentFunc func(ctx context.Context, teamID *uint, deviceInfo fleet.MDMAppleMachineInfo) error -type MDMAppleUpsertHostFunc func(ctx context.Context, mdmHost *fleet.Host) error +type MDMAppleUpsertHostFunc func(ctx context.Context, mdmHost *fleet.Host, fromPersonalEnrollment bool) error type RestoreMDMApplePendingDEPHostFunc func(ctx context.Context, host *fleet.Host) error @@ -5873,11 +5873,11 @@ func (s *DataStore) SetOrUpdateMunkiInfo(ctx context.Context, hostID uint, versi return s.SetOrUpdateMunkiInfoFunc(ctx, hostID, version, errors, warnings) } -func (s *DataStore) SetOrUpdateMDMData(ctx context.Context, hostID uint, isServer bool, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollRef string) error { +func (s *DataStore) SetOrUpdateMDMData(ctx context.Context, hostID uint, isServer bool, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollRef string, isPersonalEnrollment bool) error { s.mu.Lock() s.SetOrUpdateMDMDataFuncInvoked = true s.mu.Unlock() - return s.SetOrUpdateMDMDataFunc(ctx, hostID, isServer, enrolled, serverURL, installedFromDep, name, fleetEnrollRef) + return s.SetOrUpdateMDMDataFunc(ctx, hostID, isServer, enrolled, serverURL, installedFromDep, name, fleetEnrollRef, isPersonalEnrollment) } func (s *DataStore) UpdateMDMData(ctx context.Context, hostID uint, enrolled bool) error { @@ -6475,11 +6475,11 @@ func (s *DataStore) IngestMDMAppleDeviceFromOTAEnrollment(ctx context.Context, t return s.IngestMDMAppleDeviceFromOTAEnrollmentFunc(ctx, teamID, deviceInfo) } -func (s *DataStore) MDMAppleUpsertHost(ctx context.Context, mdmHost *fleet.Host) error { +func (s *DataStore) MDMAppleUpsertHost(ctx context.Context, mdmHost *fleet.Host, fromPersonalEnrollment bool) error { s.mu.Lock() s.MDMAppleUpsertHostFuncInvoked = true s.mu.Unlock() - return s.MDMAppleUpsertHostFunc(ctx, mdmHost) + return s.MDMAppleUpsertHostFunc(ctx, mdmHost, fromPersonalEnrollment) } func (s *DataStore) RestoreMDMApplePendingDEPHost(ctx context.Context, host *fleet.Host) error { diff --git a/server/service/apple_mdm.go b/server/service/apple_mdm.go index ac4b162c89..55888e262f 100644 --- a/server/service/apple_mdm.go +++ b/server/service/apple_mdm.go @@ -3408,13 +3408,15 @@ func (svc *MDMAppleCheckinAndCommandService) Authenticate(r *mdm.Request, m *mdm if err != nil { return ctxerr.Wrap(r.Context, err, "getting checkin info in Authenticate message") } + // TODO BMAA Update for activity changes + mdmEnrolledActivity := &fleet.ActivityTypeMDMEnrolled{ + HostDisplayName: updatedInfo.DisplayName, + InstalledFromDEP: updatedInfo.DEPAssignedToFleet, + MDMPlatform: fleet.MDMPlatformApple, + HostSerial: updatedInfo.HardwareSerial, + } return newActivity( - r.Context, nil, &fleet.ActivityTypeMDMEnrolled{ - HostSerial: updatedInfo.HardwareSerial, - HostDisplayName: updatedInfo.DisplayName, - InstalledFromDEP: updatedInfo.DEPAssignedToFleet, - MDMPlatform: fleet.MDMPlatformApple, - }, svc.ds, svc.logger, + r.Context, nil, mdmEnrolledActivity, svc.ds, svc.logger, ) } diff --git a/server/service/apple_mdm_test.go b/server/service/apple_mdm_test.go index 06b4952ecd..601fa0dea4 100644 --- a/server/service/apple_mdm_test.go +++ b/server/service/apple_mdm_test.go @@ -1147,10 +1147,11 @@ func TestMDMAuthenticateManualEnrollment(t *testing.T) { ctx := context.Background() uuid, serial, model := "ABC-DEF-GHI", "XYZABC", "MacBookPro 16,1" - ds.MDMAppleUpsertHostFunc = func(ctx context.Context, mdmHost *fleet.Host) error { + ds.MDMAppleUpsertHostFunc = func(ctx context.Context, mdmHost *fleet.Host, fromPersonalEnrollment bool) error { require.Equal(t, uuid, mdmHost.UUID) require.Equal(t, serial, mdmHost.HardwareSerial) require.Equal(t, model, mdmHost.HardwareModel) + require.False(t, fromPersonalEnrollment) return nil } @@ -1173,6 +1174,7 @@ func TestMDMAuthenticateManualEnrollment(t *testing.T) { require.True(t, ok) require.Nil(t, user) require.Equal(t, "mdm_enrolled", activity.ActivityName()) + require.NotNil(t, a.HostSerial) require.Equal(t, serial, a.HostSerial) require.Equal(t, a.HostDisplayName, fmt.Sprintf("%s (%s)", model, serial)) require.False(t, a.InstalledFromDEP) @@ -1212,10 +1214,11 @@ func TestMDMAuthenticateADE(t *testing.T) { ctx := context.Background() uuid, serial, model := "ABC-DEF-GHI", "XYZABC", "MacBookPro 16,1" - ds.MDMAppleUpsertHostFunc = func(ctx context.Context, mdmHost *fleet.Host) error { + ds.MDMAppleUpsertHostFunc = func(ctx context.Context, mdmHost *fleet.Host, fromPersonalEnrollment bool) error { require.Equal(t, uuid, mdmHost.UUID) require.Equal(t, serial, mdmHost.HardwareSerial) require.Equal(t, model, mdmHost.HardwareModel) + require.False(t, fromPersonalEnrollment) return nil } @@ -1238,6 +1241,7 @@ func TestMDMAuthenticateADE(t *testing.T) { require.True(t, ok) require.Nil(t, user) require.Equal(t, "mdm_enrolled", activity.ActivityName()) + require.NotNil(t, a.HostSerial) require.Equal(t, serial, a.HostSerial) require.Equal(t, a.HostDisplayName, fmt.Sprintf("%s (%s)", model, serial)) require.True(t, a.InstalledFromDEP) @@ -1297,7 +1301,11 @@ func TestMDMAuthenticateSCEPRenewal(t *testing.T) { require.True(t, scepRenewalInProgress) return nil } - ds.MDMAppleUpsertHostFunc = func(ctx context.Context, mdmHost *fleet.Host) error { + ds.MDMAppleUpsertHostFunc = func(ctx context.Context, mdmHost *fleet.Host, fromPersonalEnrollment bool) error { + require.Equal(t, uuid, mdmHost.UUID) + require.Equal(t, serial, mdmHost.HardwareSerial) + require.Equal(t, model, mdmHost.HardwareModel) + require.False(t, fromPersonalEnrollment) return nil } diff --git a/server/service/integration_core_test.go b/server/service/integration_core_test.go index 60a41a641a..724c5f38c4 100644 --- a/server/service/integration_core_test.go +++ b/server/service/integration_core_test.go @@ -1381,9 +1381,9 @@ func (s *integrationTestSuite) TestHostsCount() { require.Equal(t, 0, resp.Count) // set MDM information on a host - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), hosts[1].ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), hosts[1].ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", false)) // also create server with MDM information, which is ignored. - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), hosts[2].ID, true, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), hosts[2].ID, true, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", false)) var mdmID uint mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { return sqlx.GetContext(context.Background(), q, &mdmID, @@ -1397,7 +1397,7 @@ func (s *integrationTestSuite) TestHostsCount() { HardwareModel: "MacBook Pro", }) require.NoError(t, err) - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), pendingMDMHost.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), pendingMDMHost.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "", false)) s.DoJSON("GET", "/api/latest/fleet/hosts/count", nil, http.StatusOK, &resp, "mdm_id", fmt.Sprint(mdmID)) require.Equal(t, 1, resp.Count) @@ -1712,7 +1712,7 @@ func (s *integrationTestSuite) TestListHosts() { assert.Nil(t, resp.MunkiIssue) // set MDM information on a host - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), host2.ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), host2.ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", false)) var mdmID uint mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { return sqlx.GetContext(context.Background(), q, &mdmID, @@ -1733,7 +1733,7 @@ func (s *integrationTestSuite) TestListHosts() { require.NoError(t, err) return err }) - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), pendingMDMHost.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), pendingMDMHost.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "", false)) // generate aggregated stats require.NoError(t, s.ds.GenerateAggregatedMunkiAndMDM(context.Background())) @@ -4015,7 +4015,7 @@ func (s *integrationTestSuite) TestGetMacadminsData() { return err }) - require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, hostAll.ID, false, true, "url", false, "", "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, hostAll.ID, false, true, "url", false, "", "", false)) require.NoError(t, s.ds.SetOrUpdateMunkiInfo(ctx, hostAll.ID, "1.3.0", []string{"error1"}, []string{"warning1"})) macadminsData := macadminsDataResponse{} @@ -4042,7 +4042,7 @@ func (s *integrationTestSuite) TestGetMacadminsData() { assert.False(t, macadminsData.Macadmins.MunkiIssues[1].HostIssueCreatedAt.IsZero()) assert.Equal(t, "warning", macadminsData.Macadmins.MunkiIssues[1].IssueType) - require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, hostAll.ID, false, true, "https://simplemdm.com", true, fleet.WellKnownMDMSimpleMDM, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, hostAll.ID, false, true, "https://simplemdm.com", true, fleet.WellKnownMDMSimpleMDM, "", false)) require.NoError(t, s.ds.SetOrUpdateMunkiInfo(ctx, hostAll.ID, "1.5.0", []string{"error1"}, nil)) macadminsData = macadminsDataResponse{} @@ -4058,7 +4058,7 @@ func (s *integrationTestSuite) TestGetMacadminsData() { require.Len(t, macadminsData.Macadmins.MunkiIssues, 1) assert.Equal(t, "error1", macadminsData.Macadmins.MunkiIssues[0].Name) - require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, hostAll.ID, false, false, "url2", false, "", "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, hostAll.ID, false, false, "url2", false, "", "", false)) macadminsData = macadminsDataResponse{} s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d/macadmins", hostAll.ID), nil, http.StatusOK, &macadminsData) @@ -4086,7 +4086,7 @@ func (s *integrationTestSuite) TestGetMacadminsData() { assert.Equal(t, "warning1", macadminsData.Macadmins.MunkiIssues[0].Name) // only mdm returns null on munki info - require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, hostOnlyMDM.ID, false, true, "https://kandji.io", true, fleet.WellKnownMDMKandji, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, hostOnlyMDM.ID, false, true, "https://kandji.io", true, fleet.WellKnownMDMKandji, "", false)) macadminsData = macadminsDataResponse{} s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d/macadmins", hostOnlyMDM.ID), nil, http.StatusOK, &macadminsData) require.NotNil(t, macadminsData.Macadmins) @@ -4536,7 +4536,7 @@ func (s *integrationTestSuite) TestLabels() { assert.Len(t, listHostsResp.Hosts, 0) // set MDM information on a host - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), lbl2Hosts[0].ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), lbl2Hosts[0].ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", false)) var mdmID uint mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { return sqlx.GetContext(context.Background(), q, &mdmID, @@ -4943,7 +4943,7 @@ func (s *integrationTestSuite) TestListHostsByLabel() { require.NoError( t, s.ds.SetOrUpdateMDMData( - context.Background(), host.ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", + context.Background(), host.ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", false, ), ) @@ -10097,7 +10097,7 @@ func (s *integrationTestSuite) TestOrbitConfigNotifications() { require.False(t, resp.Notifications.RenewEnrollmentProfile) hSimpleMDM := createOrbitEnrolledHost(t, "darwin", "simplemdm", s.ds) - err = s.ds.SetOrUpdateMDMData(context.Background(), hSimpleMDM.ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "") + err = s.ds.SetOrUpdateMDMData(context.Background(), hSimpleMDM.ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", false) require.NoError(t, err) resp = orbitGetConfigResponse{} s.DoJSON("POST", "/api/fleet/orbit/config", json.RawMessage(fmt.Sprintf(`{"orbit_node_key": %q}`, *hSimpleMDM.OrbitNodeKey)), http.StatusOK, &resp) @@ -10105,7 +10105,7 @@ func (s *integrationTestSuite) TestOrbitConfigNotifications() { // not yet assigned in ABM hFleetMDM := createOrbitEnrolledHost(t, "darwin", "fleetmdm", s.ds) - err = s.ds.SetOrUpdateMDMData(context.Background(), hFleetMDM.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "") + err = s.ds.SetOrUpdateMDMData(context.Background(), hFleetMDM.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) resp = orbitGetConfigResponse{} @@ -10119,14 +10119,14 @@ func (s *integrationTestSuite) TestOrbitConfigNotifications() { require.NotEmpty(t, abmToken.ID) err = s.ds.UpsertMDMAppleHostDEPAssignments(ctx, []fleet.Host{*hFleetMDM}, abmToken.ID) require.NoError(t, err) - err = s.ds.SetOrUpdateMDMData(context.Background(), hSimpleMDM.ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "") + err = s.ds.SetOrUpdateMDMData(context.Background(), hSimpleMDM.ID, false, true, "https://simplemdm.com", false, fleet.WellKnownMDMSimpleMDM, "", false) require.NoError(t, err) resp = orbitGetConfigResponse{} s.DoJSON("POST", "/api/fleet/orbit/config", json.RawMessage(fmt.Sprintf(`{"orbit_node_key": %q}`, *hFleetMDM.OrbitNodeKey)), http.StatusOK, &resp) require.True(t, resp.Notifications.RenewEnrollmentProfile) // if the fleet mdm host is fully enrolled (not pending anymore), then the notification is false - err = s.ds.SetOrUpdateMDMData(context.Background(), hFleetMDM.ID, false, true, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "") + err = s.ds.SetOrUpdateMDMData(context.Background(), hFleetMDM.ID, false, true, "https://fleetdm.com", true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) resp = orbitGetConfigResponse{} s.DoJSON("POST", "/api/fleet/orbit/config", json.RawMessage(fmt.Sprintf(`{"orbit_node_key": %q}`, *hFleetMDM.OrbitNodeKey)), http.StatusOK, &resp) diff --git a/server/service/integration_desktop_test.go b/server/service/integration_desktop_test.go index 2377b84bb2..41a21b07e7 100644 --- a/server/service/integration_desktop_test.go +++ b/server/service/integration_desktop_test.go @@ -36,7 +36,7 @@ func (s *integrationTestSuite) TestDeviceAuthenticatedEndpoints() { }, fleet.DeviceMappingGoogleChromeProfiles)) _, err = s.ds.SetOrUpdateCustomHostDeviceMapping(context.Background(), hosts[0].ID, "c@b.c", fleet.DeviceMappingCustomInstaller) require.NoError(t, err) - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), hosts[0].ID, false, true, "url", false, "", "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), hosts[0].ID, false, true, "url", false, "", "", false)) require.NoError(t, s.ds.SetOrUpdateMunkiInfo(context.Background(), hosts[0].ID, "1.3.0", nil, nil)) // create a battery for hosts[0] require.NoError(t, s.ds.ReplaceHostBatteries(context.Background(), hosts[0].ID, []*fleet.HostBattery{ @@ -286,7 +286,6 @@ func (s *integrationTestSuite) TestRateLimitOfEndpoints() { require.NoError(s.T(), err) config.SMTPSettings.SMTPConfigured = false require.NoError(s.T(), s.ds.SaveAppConfig(context.Background(), config)) - } func (s *integrationTestSuite) TestErrorReporting() { @@ -453,5 +452,4 @@ func (s *integrationTestSuite) TestErrorReporting() { s.DoJSON("GET", "/debug/errors", nil, http.StatusOK, &errors) require.Len(t, errors, 2) - } diff --git a/server/service/integration_enterprise_test.go b/server/service/integration_enterprise_test.go index 45e19e450b..af8109f40d 100644 --- a/server/service/integration_enterprise_test.go +++ b/server/service/integration_enterprise_test.go @@ -18323,7 +18323,7 @@ func (s *integrationEnterpriseTestSuite) TestConditionalAccessPolicies() { // Enroll to MDM to update managed status. err = s.ds.SetOrUpdateMDMData(ctx, h1.ID, false, true /* enrolled */, s.server.URL, false, /* installedFromDEP */ - "Fleet" /* MDM name */, "", /* fleetEnrollmentRef */ + "Fleet" /* MDM name */, "" /* fleetEnrollmentRef */, false, /* isPersonalEnrollment */ ) require.NoError(t, err) @@ -18447,7 +18447,7 @@ func (s *integrationEnterpriseTestSuite) TestConditionalAccessPolicies() { // Enroll to MDM to update managed status. err = s.ds.SetOrUpdateMDMData(ctx, h2.ID, false, true /* enrolled */, s.server.URL, false, /* installedFromDEP */ - "Fleet" /* MDM name */, "", /* fleetEnrollmentRef */ + "Fleet" /* MDM name */, "" /* fleetEnrollmentRef */, false, /* isPersonalEnrollment */ ) require.NoError(t, err) diff --git a/server/service/integration_mdm_dep_test.go b/server/service/integration_mdm_dep_test.go index cef5881607..fd4fc61702 100644 --- a/server/service/integration_mdm_dep_test.go +++ b/server/service/integration_mdm_dep_test.go @@ -1330,7 +1330,7 @@ func (s *integrationMDMTestSuite) TestDEPProfileAssignment() { checkHostDEPAssignProfileResponses(profileAssignmentReqs[0].Devices, profileAssignmentReqs[0].ProfileUUID, fleet.DEPAssignProfileResponseSuccess) // report MDM info via osquery - require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, eHost.ID, false, true, s.server.URL, true, fleet.WellKnownMDMFleet, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, eHost.ID, false, true, s.server.URL, true, fleet.WellKnownMDMFleet, "", false)) checkListHostDEPError(eHost.HardwareSerial, "On (automatic)", false) // transfer to "no team", we assign a DEP profile to the device @@ -3866,11 +3866,12 @@ func (s *integrationMDMTestSuite) TestSetupExperienceWithLotsOfVPPApps() { s.appleITunesSrvData["9"] = `{"bundleId": "i-9", "artworkUrl512": "https://example.com/images/9", "version": "9.0.0", "trackName": "App 9", "TrackID": 9}` s.appleITunesSrvData["10"] = `{"bundleId": "j-10", "artworkUrl512": "https://example.com/images/10", "version": "10.0.0", "trackName": "App 10", "TrackID": 10}` - s.appleVPPConfigSrvConfig.Assets = append(s.appleVPPConfigSrvConfig.Assets, []vpp.Asset{{ - AdamID: "6", - PricingParam: "STDQ", - AvailableCount: 1, - }, + s.appleVPPConfigSrvConfig.Assets = append(s.appleVPPConfigSrvConfig.Assets, []vpp.Asset{ + { + AdamID: "6", + PricingParam: "STDQ", + AvailableCount: 1, + }, { AdamID: "7", PricingParam: "STDQ", @@ -3890,7 +3891,8 @@ func (s *integrationMDMTestSuite) TestSetupExperienceWithLotsOfVPPApps() { AdamID: "10", PricingParam: "STDQ", AvailableCount: 1, - }}...) + }, + }...) t.Cleanup(func() { delete(s.appleITunesSrvData, "6") @@ -4305,5 +4307,4 @@ func (s *integrationMDMTestSuite) TestSetupExperienceWithLotsOfVPPApps() { } } - } diff --git a/server/service/integration_mdm_lifecycle_test.go b/server/service/integration_mdm_lifecycle_test.go index 1d2c0e13da..ae98dad786 100644 --- a/server/service/integration_mdm_lifecycle_test.go +++ b/server/service/integration_mdm_lifecycle_test.go @@ -421,7 +421,7 @@ func (s *integrationMDMTestSuite) TestTurnOnLifecycleEventsWindows() { t.Run(tt.Name, func(t *testing.T) { t.Run("programmatic enrollment", func(t *testing.T) { host, device := createWindowsHostThenEnrollMDM(s.ds, s.server.URL, t) - err := s.ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "") + err := s.ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) assertAction(t, host, device, tt.Action) }) @@ -442,7 +442,7 @@ func (s *integrationMDMTestSuite) TestTurnOnLifecycleEventsWindows() { device.DeviceID = host.UUID require.NoError(t, device.Enroll()) - err = s.ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "") + err = s.ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) assertAction(t, host, device, tt.Action) @@ -692,6 +692,7 @@ func (s *integrationMDMTestSuite) TestLifecycleSCEPCertExpiration() { true, fleet.WellKnownMDMFleet, "foo", + false, ), ) require.NoError(t, err) diff --git a/server/service/integration_mdm_profiles_test.go b/server/service/integration_mdm_profiles_test.go index e0c3c72ecb..ea6a48ef04 100644 --- a/server/service/integration_mdm_profiles_test.go +++ b/server/service/integration_mdm_profiles_test.go @@ -4029,7 +4029,7 @@ func (s *integrationMDMTestSuite) TestWindowsProfileManagement() { // simulate osquery reporting host mdm details (host_mdm.enrolled = 1 is condition for // hosts filtering by os settings status and generating mdm profiles summaries) - require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "", false)) checkHostsFilteredByOSSettingsStatus(t, []string{host.Hostname}, fleet.MDMDeliveryVerifying, nil, label) s.checkMDMProfilesSummaries(t, nil, fleet.MDMProfilesSummary{ Verifying: 1, diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index 2538844e27..fc3fc00730 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -1238,7 +1238,7 @@ func enrollWindowsHostInMDM(t *testing.T, host *fleet.Host, ds fleet.Datastore, require.NoError(t, err) err = ds.UpdateMDMWindowsEnrollmentsHostUUID(context.Background(), host.UUID, mdmDevice.DeviceID) require.NoError(t, err) - err = ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, fleetServerURL, false, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, fleetServerURL, false, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) return mdmDevice } @@ -2202,7 +2202,7 @@ func (s *integrationMDMTestSuite) TestWindowsMDMGetEncryptionKey() { // create a host and enroll it in Fleet host := createOrbitEnrolledHost(t, "windows", "h1", s.ds) - err := s.ds.SetOrUpdateMDMData(ctx, host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "") + err := s.ds.SetOrUpdateMDMData(ctx, host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) // request encryption key with no auth token @@ -3448,7 +3448,7 @@ func (s *integrationMDMTestSuite) TestBootstrapPackageStatus() { }) require.NoError(t, err) - err = s.ds.SetOrUpdateMDMData(context.Background(), winHost.ID, false, true, s.server.URL+apple_mdm.MDMPath, true, fleet.WellKnownMDMFleet, "") + err = s.ds.SetOrUpdateMDMData(context.Background(), winHost.ID, false, true, s.server.URL+apple_mdm.MDMPath, true, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) // create a host that's not enrolled into MDM @@ -3783,17 +3783,17 @@ func (s *integrationMDMTestSuite) TestMigrateMDMDeviceWebhook() { mdmURL := "https://mdm.example.com" // host is a server so migration is not allowed - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, isServer, enrolled, mdmURL, installedFromDEP, mdmName, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, isServer, enrolled, mdmURL, installedFromDEP, mdmName, "", false)) s.Do("POST", fmt.Sprintf("/api/v1/fleet/device/%s/migrate_mdm", "good-token"), nil, http.StatusBadRequest) require.False(t, webhookCalled) // host is not enrolled to MDM so migration is not allowed - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, !isServer, !enrolled, mdmURL, installedFromDEP, mdmName, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, !isServer, !enrolled, mdmURL, installedFromDEP, mdmName, "", false)) s.Do("POST", fmt.Sprintf("/api/v1/fleet/device/%s/migrate_mdm", "good-token"), nil, http.StatusBadRequest) require.False(t, webhookCalled) // host is already enrolled to Fleet MDM so migration is not allowed - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, !isServer, enrolled, mdmURL, installedFromDEP, fleet.WellKnownMDMFleet, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, !isServer, enrolled, mdmURL, installedFromDEP, fleet.WellKnownMDMFleet, "", false)) s.Do("POST", fmt.Sprintf("/api/v1/fleet/device/%s/migrate_mdm", "good-token"), nil, http.StatusBadRequest) require.False(t, webhookCalled) @@ -3805,7 +3805,7 @@ func (s *integrationMDMTestSuite) TestMigrateMDMDeviceWebhook() { // host is enrolled to a third-party MDM but hasn't been assigned in // ABM yet, so migration is not allowed - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, !isServer, enrolled, mdmURL, installedFromDEP, mdmName, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, !isServer, enrolled, mdmURL, installedFromDEP, mdmName, "", false)) s.Do("POST", fmt.Sprintf("/api/v1/fleet/device/%s/migrate_mdm", "good-token"), nil, http.StatusBadRequest) require.False(t, webhookCalled) @@ -3881,7 +3881,7 @@ func (s *integrationMDMTestSuite) TestMigrateMDMDeviceWebhook() { err = s.ds.UpdateHost(context.Background(), h) require.NoError(t, err) - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, !isServer, enrolled, mdmURL, !installedFromDEP, mdmName, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, !isServer, enrolled, mdmURL, !installedFromDEP, mdmName, "", false)) s.Do("POST", fmt.Sprintf("/api/v1/fleet/device/%s/migrate_mdm", "good-token"), nil, http.StatusNoContent) require.True(t, webhookCalled) webhookCalled = false @@ -3946,7 +3946,7 @@ func (s *integrationMDMTestSuite) TestMigrateMDMDeviceWebhookErrors() { // host is enrolled to a third-party MDM but hasn't been assigned in // ABM yet, so migration is not allowed - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, !isServer, enrolled, mdmURL, installedFromDEP, mdmName, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), h.ID, !isServer, enrolled, mdmURL, installedFromDEP, mdmName, "", false)) s.Do("POST", fmt.Sprintf("/api/v1/fleet/device/%s/migrate_mdm", "good-token"), nil, http.StatusBadRequest) require.False(t, webhookCalled) @@ -6471,6 +6471,7 @@ func (s *integrationMDMTestSuite) TestMDMMigration() { true, fleet.WellKnownMDMSimpleMDM, "", + false, ) require.NoError(t, err) @@ -6548,6 +6549,7 @@ func (s *integrationMDMTestSuite) TestMDMMigration() { true, fleet.WellKnownMDMFleet, "", + false, ) require.NoError(t, err) @@ -6580,6 +6582,7 @@ func (s *integrationMDMTestSuite) TestMDMMigration() { false, fleet.WellKnownMDMFleet, "", + false, ) require.NoError(t, err) mdmDevice := mdmtest.NewTestMDMClientAppleDirect(mdmtest.AppleEnrollInfo{ @@ -6621,6 +6624,7 @@ func (s *integrationMDMTestSuite) TestMDMMigration() { false, fleet.WellKnownMDMSimpleMDM, "", + false, ) require.NoError(t, err) getDesktopResp = fleetDesktopResponse{} @@ -6652,6 +6656,7 @@ func (s *integrationMDMTestSuite) TestMDMMigration() { false, fleet.WellKnownMDMSimpleMDM, "", + false, ) require.NoError(t, err) getDesktopResp = fleetDesktopResponse{} @@ -6766,14 +6771,14 @@ func (s *integrationMDMTestSuite) TestAppConfigWindowsMDM() { require.NoError(t, err) err = s.ds.UpdateMDMWindowsEnrollmentsHostUUID(ctx, host.UUID, mdmDevice.DeviceID) require.NoError(t, err) - err = s.ds.SetOrUpdateMDMData(ctx, host.ID, meta.isServer, true, s.server.URL, false, fleet.WellKnownMDMFleet, "") + err = s.ds.SetOrUpdateMDMData(ctx, host.ID, meta.isServer, true, s.server.URL, false, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) } else { host = createOrbitEnrolledHost(t, meta.os, meta.suffix, s.ds) createDeviceTokenForHost(t, s.ds, host.ID, meta.suffix) serverURL := "https://example.com" - err := s.ds.SetOrUpdateMDMData(ctx, host.ID, meta.isServer, meta.enrolledName != "", serverURL, false, meta.enrolledName, "") + err := s.ds.SetOrUpdateMDMData(ctx, host.ID, meta.isServer, meta.enrolledName != "", serverURL, false, meta.enrolledName, "", false) require.NoError(t, err) } @@ -8206,7 +8211,7 @@ func (s *integrationMDMTestSuite) TestBitLockerEnforcementNotifications() { // simulate osquery checking in and updating this info // TODO: should we automatically fill these fields on MDM enrollment? - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), windowsHost.ID, false, true, "https://example.com", true, fleet.WellKnownMDMFleet, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), windowsHost.ID, false, true, "https://example.com", true, fleet.WellKnownMDMFleet, "", false)) // notification is still false checkNotification(false) @@ -8315,7 +8320,7 @@ func (s *integrationMDMTestSuite) TestHostDiskEncryptionKey() { mdmDevice := mdmtest.NewTestMDMClientWindowsProgramatic(s.server.URL, *host.OrbitNodeKey) err := mdmDevice.Enroll() require.NoError(t, err) - err = s.ds.SetOrUpdateMDMData(ctx, host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "") + err = s.ds.SetOrUpdateMDMData(ctx, host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) // set its encryption key @@ -8330,7 +8335,7 @@ func (s *integrationMDMTestSuite) TestHostDiskEncryptionKey() { require.True(t, *hdek.Decryptable) // mark it as non-server - err = s.ds.SetOrUpdateMDMData(ctx, host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "") + err = s.ds.SetOrUpdateMDMData(ctx, host.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) var hostResp getHostResponse @@ -9522,7 +9527,7 @@ func (s *integrationMDMTestSuite) TestLockUnlockWipeWindowsLinux() { // create an MDM-enrolled Windows host winHost, winMDMClient := createWindowsHostThenEnrollMDM(s.ds, s.server.URL, t) // set its MDM data so it shows as MDM-enrolled in the backend - err := s.ds.SetOrUpdateMDMData(ctx, winHost.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "") + err := s.ds.SetOrUpdateMDMData(ctx, winHost.ID, false, true, s.server.URL, false, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) linuxHost := createOrbitEnrolledHost(t, "linux", "lock_unlock_linux", s.ds) @@ -10314,7 +10319,7 @@ func (s *integrationMDMTestSuite) TestIsServerBitlockerStatus() { // create a server host that is not enrolled in MDM host := createOrbitEnrolledHost(t, "windows", "server-host", s.ds) - require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, host.ID, true, false, "", false, "", "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, host.ID, true, false, "", false, "", "", false)) acResp := appConfigResponse{} s.DoJSON("PATCH", "/api/latest/fleet/config", json.RawMessage(`{ @@ -10328,7 +10333,7 @@ func (s *integrationMDMTestSuite) TestIsServerBitlockerStatus() { // create a non-server host that is enrolled in MDM host2 := createOrbitEnrolledHost(t, "windows", "non-server-host", s.ds) - require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, host2.ID, false, true, "http://example.com", false, fleet.WellKnownMDMFleet, "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(ctx, host2.ID, false, true, "http://example.com", false, fleet.WellKnownMDMFleet, "", false)) hr = getHostResponse{} s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", host2.ID), nil, http.StatusOK, &hr) @@ -10708,7 +10713,7 @@ func (s *integrationMDMTestSuite) TestSilentMigrationGotchas() { host := createOrbitEnrolledHost(t, "darwin", t.Name(), s.ds) // set the host as enrolled in a third-party MDM - err := s.ds.SetOrUpdateMDMData(ctx, host.ID, true, true, "https://foo.com", false, fleet.WellKnownMDMSimpleMDM, "") + err := s.ds.SetOrUpdateMDMData(ctx, host.ID, true, true, "https://foo.com", false, fleet.WellKnownMDMSimpleMDM, "", false) require.NoError(t, err) var hostResp getHostResponse @@ -10849,7 +10854,7 @@ func (s *integrationMDMTestSuite) TestSilentMigrationGotchas() { require.Nil(t, cmd) // set the host as completely unenrolled - err = s.ds.SetOrUpdateMDMData(ctx, host.ID, false, false, "", false, "", "") + err = s.ds.SetOrUpdateMDMData(ctx, host.ID, false, false, "", false, "", "", false) require.NoError(t, err) // orbit config asks to renew the enrollment profile, migration is not needed anymore so it's false resp = orbitGetConfigResponse{} @@ -11096,7 +11101,7 @@ func (s *integrationMDMTestSuite) TestConnectedToFleetWithoutCheckout() { require.NoError(t, err) // but, set the host as enrolled in a third-party MDM - err = s.ds.SetOrUpdateMDMData(ctx, host.ID, true, true, "https://foo.com", false, fleet.WellKnownMDMSimpleMDM, "") + err = s.ds.SetOrUpdateMDMData(ctx, host.ID, true, true, "https://foo.com", false, fleet.WellKnownMDMSimpleMDM, "", false) require.NoError(t, err) // host is connected to Fleet @@ -11107,7 +11112,7 @@ func (s *integrationMDMTestSuite) TestConnectedToFleetWithoutCheckout() { require.True(t, *hostResp.Host.MDM.ConnectedToFleet) // now simulate an un-enrollment without checkout, in this case, osquery reports the host as not-enrolled - err = s.ds.SetOrUpdateMDMData(ctx, host.ID, false, false, "", false, "", "") + err = s.ds.SetOrUpdateMDMData(ctx, host.ID, false, false, "", false, "", "", false) require.NoError(t, err) // host is not connected to Fleet anymore @@ -11400,7 +11405,7 @@ func (s *integrationMDMTestSuite) TestRefetchIOSIPadOS() { // Enroll host host, mdmClient := s.createAppleMobileHostThenEnrollMDM("ios") - require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, "https://foo.com", true, "", "")) + require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, "https://foo.com", true, "", "", false)) // Refetch host _ = s.Do("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/refetch", host.ID), nil, http.StatusOK) @@ -13868,6 +13873,10 @@ func (s *integrationMDMTestSuite) TestAppleMDMAccountDrivenUserEnrollment() { require.NoError(t, iPhoneMdmDevice.Enroll()) assert.Equal(t, iPhoneMdmDevice.EnrollInfo.AssignedManagedAppleID, "sso_user@example.com") + // TODO BMAA Update for activity changes + s.lastActivityOfTypeMatches(fleet.ActivityTypeMDMEnrolled{}.ActivityName(), + fmt.Sprintf(`{"host_serial": "%s", "host_display_name": "%s (%s)", "installed_from_dep": false, "mdm_platform": "apple"}`, iPhoneMdmDevice.EnrollmentID(), iPhoneMdmDevice.Model, iPhoneMdmDevice.EnrollmentID()), 0) + linkedIDPAccount, err := s.ds.GetMDMIdPAccountByHostUUID(context.Background(), iPhoneMdmDevice.EnrollmentID()) require.NoError(t, err) require.NotNil(t, linkedIDPAccount) @@ -13889,6 +13898,10 @@ func (s *integrationMDMTestSuite) TestAppleMDMAccountDrivenUserEnrollment() { require.NoError(t, iPadMdmDevice.Enroll()) assert.Equal(t, iPadMdmDevice.EnrollInfo.AssignedManagedAppleID, "sso_user2@example.com") + // TODO BMAA Update for activity changes + s.lastActivityOfTypeMatches(fleet.ActivityTypeMDMEnrolled{}.ActivityName(), + fmt.Sprintf(`{"host_serial": "%s", "host_display_name": "%s (%s)", "installed_from_dep": false, "mdm_platform": "apple"}`, iPadMdmDevice.EnrollmentID(), iPadMdmDevice.Model, iPadMdmDevice.EnrollmentID()), 0) + linkedIDPAccount, err = s.ds.GetMDMIdPAccountByHostUUID(context.Background(), iPadMdmDevice.EnrollmentID()) require.NoError(t, err) require.NotNil(t, linkedIDPAccount) @@ -13914,6 +13927,69 @@ func (s *integrationMDMTestSuite) TestAppleMDMAccountDrivenUserEnrollment() { iPadAccessToken, // Using iPad's access token. It doesn't matter because it should fail before checking it ) require.ErrorContains(t, macbookMdmDevice.Enroll(), "400 Bad Request") + + // Fetch the hosts we enrolled and check their details. Specifically we want to verify that MDM + // shows a personal enrollment via all 3 endpoints(list hosts, host details and host MDM + // details) since they query for the information slightly differently + listHostsRes := listHostsResponse{} + var iPhoneHostID *uint + var iPadHostID *uint + s.DoJSON("GET", "/api/latest/fleet/hosts", nil, http.StatusOK, &listHostsRes) + require.Len(t, listHostsRes.Hosts, 2) + for _, host := range listHostsRes.Hosts { + if host.UUID == iPhoneMdmDevice.EnrollmentID() { + assert.Equal(t, iPhoneHwModel, host.HardwareModel) + assert.Equal(t, iPhoneMdmDevice.EnrollmentID(), host.UUID) + assert.Equal(t, iPhoneMdmDevice.EnrollmentID(), host.HardwareSerial) + require.NotNil(t, host.MDM.EnrollmentStatus) + assert.Equal(t, "On (personal)", *host.MDM.EnrollmentStatus) + assert.True(t, *host.MDM.ConnectedToFleet) + iPhoneHostID = ptr.Uint(host.ID) + } else if host.UUID == iPadMdmDevice.EnrollmentID() { + assert.Equal(t, "ipados", host.Platform) + assert.Equal(t, iPadMdmDevice.EnrollmentID(), host.UUID) + assert.Equal(t, iPadMdmDevice.EnrollmentID(), host.HardwareSerial) + assert.Equal(t, iPadHwModel, host.HardwareModel) + require.NotNil(t, host.MDM.EnrollmentStatus) + assert.Equal(t, "On (personal)", *host.MDM.EnrollmentStatus) + assert.True(t, *host.MDM.ConnectedToFleet) + iPadHostID = ptr.Uint(host.ID) + } + } + + require.NotNil(t, iPhoneHostID, "iPhone host not found in the list of hosts") + require.NotNil(t, iPadHostID, "iPad host not found in the list of hosts") + + // Confirm that host details endpoint contains the expected values for the iPhone + getHostResp := getDeviceHostResponse{} + s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", *iPhoneHostID), nil, http.StatusOK, &getHostResp) + require.NotNil(t, getHostResp.Host.MDM.EnrollmentStatus) + assert.Equal(t, "On (personal)", *getHostResp.Host.MDM.EnrollmentStatus) + assert.True(t, *getHostResp.Host.MDM.ConnectedToFleet) + assert.Equal(t, iPhoneHwModel, getHostResp.Host.HardwareModel) + + // Confirm that the host MDM endpoint contains the expected values for the iPhone + // using an inline struct because the definition of fleet.HostMDM makes it unusable here + getHostMDMResponse := struct { + EnrollmentStatus string `json:"enrollment_status"` + ServerURL string `json:"server_url"` + Name string `json:"name"` + ID uint `json:"id"` + }{} + s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d/mdm", *iPhoneHostID), nil, http.StatusOK, &getHostMDMResponse) + assert.Equal(t, "On (personal)", getHostMDMResponse.EnrollmentStatus) + assert.Equal(t, fleet.WellKnownMDMFleet, getHostMDMResponse.Name) + + // Confirm that host details endpoint contains the expected values for the iPad + s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", *iPadHostID), nil, http.StatusOK, &getHostResp) + require.NotNil(t, getHostResp.Host.MDM.EnrollmentStatus) + assert.Equal(t, "On (personal)", *getHostResp.Host.MDM.EnrollmentStatus) + assert.True(t, *getHostResp.Host.MDM.ConnectedToFleet) + + // Confirm that the host MDM endpoint contains the expected values for the iPad + s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d/mdm", *iPadHostID), nil, http.StatusOK, &getHostMDMResponse) + assert.Equal(t, "On (personal)", getHostMDMResponse.EnrollmentStatus) + assert.Equal(t, fleet.WellKnownMDMFleet, getHostMDMResponse.Name) } func (s *integrationMDMTestSuite) TestSCEPProxy() { @@ -16250,9 +16326,9 @@ func (s *integrationMDMTestSuite) TestNonMDWindowsHostsIgnoredInDiskEncryptionSt // create a couple Windows non-MDM-enrolled hosts winHost1 := createOrbitEnrolledHost(t, "windows", "h1", s.ds) winHost2 := createOrbitEnrolledHost(t, "windows", "h2", s.ds) - err = s.ds.SetOrUpdateMDMData(ctx, winHost1.ID, false, false, "", false, "", "") + err = s.ds.SetOrUpdateMDMData(ctx, winHost1.ID, false, false, "", false, "", "", false) require.NoError(t, err) - err = s.ds.SetOrUpdateMDMData(ctx, winHost2.ID, false, false, "", false, "", "") + err = s.ds.SetOrUpdateMDMData(ctx, winHost2.ID, false, false, "", false, "", "", false) require.NoError(t, err) err = s.ds.AddLabelsToHost(ctx, winHost1.ID, []uint{allHostsLblID}) require.NoError(t, err) @@ -16311,7 +16387,7 @@ func (s *integrationMDMTestSuite) TestNonMDWindowsHostsIgnoredInDiskEncryptionSt s.checkListHostsFilter(t, allHostsLblID, "os_settings_disk_encryption", string(fleet.DiskEncryptionEnforcing), winHost1.ID) // enroll the other Windows host in a third-party MDM - err = s.ds.SetOrUpdateMDMData(ctx, winHost2.ID, false, true, "https://simplemdm.com", true, fleet.WellKnownMDMSimpleMDM, "") + err = s.ds.SetOrUpdateMDMData(ctx, winHost2.ID, false, true, "https://simplemdm.com", true, fleet.WellKnownMDMSimpleMDM, "", false) require.NoError(t, err) // stats should NOT count winHost2 (not in Fleet MDM) diff --git a/server/service/microsoft_mdm.go b/server/service/microsoft_mdm.go index b0118e01b0..60fd0889d3 100644 --- a/server/service/microsoft_mdm.go +++ b/server/service/microsoft_mdm.go @@ -63,8 +63,10 @@ func (req *SoapRequestContainer) DecodeBody(ctx context.Context, r io.Reader, u err = xml.Unmarshal(reqBytes, &req.Data) if err != nil { // We log the request body for debug by using an error implementing ErrWithInternal interface. - return ctxerr.Wrap(ctx, &fleet.BadRequestError{Message: "unmarshalling soap mdm request: " + err.Error(), - InternalErr: fmt.Errorf("request: %s", truncateString(string(reqBytes), maxRequestLogSize))}) + return ctxerr.Wrap(ctx, &fleet.BadRequestError{ + Message: "unmarshalling soap mdm request: " + err.Error(), + InternalErr: fmt.Errorf("request: %s", truncateString(string(reqBytes), maxRequestLogSize)), + }) } } diff --git a/server/service/osquery_test.go b/server/service/osquery_test.go index 97def378c5..e231798aee 100644 --- a/server/service/osquery_test.go +++ b/server/service/osquery_test.go @@ -1809,11 +1809,13 @@ func TestDetailQueries(t *testing.T) { return map[string]string{}, nil } ds.SetOrUpdateMDMDataFunc = func(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, - fleetEnrollmentRef string) error { + fleetEnrollmentRef string, isPersonalEnrollment bool, + ) error { require.True(t, enrolled) require.False(t, installedFromDep) require.Equal(t, "hi.com", serverURL) require.Empty(t, fleetEnrollmentRef) + require.False(t, isPersonalEnrollment) return nil } ds.SetOrUpdateMunkiInfoFunc = func(ctx context.Context, hostID uint, version string, errs, warns []string) error { @@ -2036,7 +2038,8 @@ func TestDetailQueries(t *testing.T) { } ds.UpdateHostSoftwareInstalledPathsFunc = func(ctx context.Context, hostID uint, paths map[string]struct{}, - result *fleet.UpdateHostSoftwareDBResult) error { + result *fleet.UpdateHostSoftwareDBResult, + ) error { return nil } @@ -2238,13 +2241,15 @@ func TestNewDistributedQueryCampaign(t *testing.T) { } var gotTargets []*fleet.DistributedQueryCampaignTarget ds.NewDistributedQueryCampaignTargetFunc = func(ctx context.Context, - target *fleet.DistributedQueryCampaignTarget) (*fleet.DistributedQueryCampaignTarget, error) { + target *fleet.DistributedQueryCampaignTarget, + ) (*fleet.DistributedQueryCampaignTarget, error) { gotTargets = append(gotTargets, target) return target, nil } ds.CountHostsInTargetsFunc = func(ctx context.Context, filter fleet.TeamFilter, targets fleet.HostTargets, now time.Time) (fleet.TargetMetrics, - error) { + error, + ) { return fleet.TargetMetrics{}, nil } ds.HostIDsInTargetsFunc = func(ctx context.Context, filter fleet.TeamFilter, targets fleet.HostTargets) ([]uint, error) { @@ -3077,11 +3082,13 @@ func TestObserversCanOnlyRunDistributedCampaigns(t *testing.T) { return camp, nil } ds.NewDistributedQueryCampaignTargetFunc = func(ctx context.Context, - target *fleet.DistributedQueryCampaignTarget) (*fleet.DistributedQueryCampaignTarget, error) { + target *fleet.DistributedQueryCampaignTarget, + ) (*fleet.DistributedQueryCampaignTarget, error) { return target, nil } ds.CountHostsInTargetsFunc = func(ctx context.Context, filter fleet.TeamFilter, targets fleet.HostTargets, now time.Time) (fleet.TargetMetrics, - error) { + error, + ) { return fleet.TargetMetrics{}, nil } ds.HostIDsInTargetsFunc = func(ctx context.Context, filter fleet.TeamFilter, targets fleet.HostTargets) ([]uint, error) { @@ -3141,11 +3148,13 @@ func TestTeamMaintainerCanRunNewDistributedCampaigns(t *testing.T) { return query, nil } ds.NewDistributedQueryCampaignTargetFunc = func(ctx context.Context, - target *fleet.DistributedQueryCampaignTarget) (*fleet.DistributedQueryCampaignTarget, error) { + target *fleet.DistributedQueryCampaignTarget, + ) (*fleet.DistributedQueryCampaignTarget, error) { return target, nil } ds.CountHostsInTargetsFunc = func(ctx context.Context, filter fleet.TeamFilter, targets fleet.HostTargets, now time.Time) (fleet.TargetMetrics, - error) { + error, + ) { return fleet.TargetMetrics{}, nil } ds.HostIDsInTargetsFunc = func(ctx context.Context, filter fleet.TeamFilter, targets fleet.HostTargets) ([]uint, error) { @@ -3198,13 +3207,15 @@ func TestPolicyQueries(t *testing.T) { } recordedResults := make(map[uint]*bool) ds.RecordPolicyQueryExecutionsFunc = func(ctx context.Context, gotHost *fleet.Host, results map[uint]*bool, updated time.Time, - deferred bool) error { + deferred bool, + ) error { recordedResults = results host = gotHost return nil } ds.FlippingPoliciesForHostFunc = func(ctx context.Context, hostID uint, incomingResults map[uint]*bool) (newFailing []uint, newPassing []uint, - err error) { + err error, + ) { return nil, nil, nil } @@ -3486,7 +3497,8 @@ func TestPolicyWebhooks(t *testing.T) { } recordedResults := make(map[uint]*bool) ds.RecordPolicyQueryExecutionsFunc = func(ctx context.Context, gotHost *fleet.Host, results map[uint]*bool, updated time.Time, - deferred bool) error { + deferred bool, + ) error { recordedResults = results host = gotHost return nil @@ -3521,7 +3533,8 @@ func TestPolicyWebhooks(t *testing.T) { checkPolicyResults(queries) ds.FlippingPoliciesForHostFunc = func(ctx context.Context, hostID uint, incomingResults map[uint]*bool) (newFailing []uint, newPassing []uint, - err error) { + err error, + ) { return []uint{3}, nil, nil } @@ -3626,7 +3639,8 @@ func TestPolicyWebhooks(t *testing.T) { checkPolicyResults(queries) ds.FlippingPoliciesForHostFunc = func(ctx context.Context, hostID uint, incomingResults map[uint]*bool) (newFailing []uint, newPassing []uint, - err error) { + err error, + ) { return []uint{1}, []uint{3}, nil } @@ -3674,7 +3688,8 @@ func TestPolicyWebhooks(t *testing.T) { require.NoError(t, err) ds.FlippingPoliciesForHostFunc = func(ctx context.Context, hostID uint, incomingResults map[uint]*bool) (newFailing []uint, newPassing []uint, - err error) { + err error, + ) { return []uint{}, []uint{2}, nil } diff --git a/server/service/osquery_utils/queries.go b/server/service/osquery_utils/queries.go index 8c29812bf3..eef2f60ec8 100644 --- a/server/service/osquery_utils/queries.go +++ b/server/service/osquery_utils/queries.go @@ -1907,6 +1907,11 @@ func directIngestMDMMac(ctx context.Context, logger log.Logger, host *fleet.Host } } + // isPersonalEnrollment is always false for macOS hosts as our current account driven user + // enrollment flow does not support macOS however we will need to detect it here if that ever + // changes. + isPersonalEnrollment := false + // strip any query parameters from the URL serverURL.RawQuery = "" @@ -1918,6 +1923,7 @@ func directIngestMDMMac(ctx context.Context, logger log.Logger, host *fleet.Host installedFromDep, mdmSolutionName, fleetEnrollRef, + isPersonalEnrollment, ) } @@ -1946,7 +1952,7 @@ func deduceMDMNameWindows(data map[string]string) string { func directIngestMDMWindows(ctx context.Context, logger log.Logger, host *fleet.Host, ds fleet.Datastore, rows []map[string]string) error { if len(rows) == 0 { // no mdm information in the registry - return ds.SetOrUpdateMDMData(ctx, host.ID, false, false, "", false, "", "") + return ds.SetOrUpdateMDMData(ctx, host.ID, false, false, "", false, "", "", false) } if len(rows) > 1 { logger.Log("component", "service", "method", "directIngestMDMWindows", "warn", @@ -1990,6 +1996,7 @@ func directIngestMDMWindows(ctx context.Context, logger log.Logger, host *fleet. automatic, mdmSolutionName, "", + false, // isPersonalEnrollment is always false for Windows hosts ) } diff --git a/server/service/osquery_utils/queries_test.go b/server/service/osquery_utils/queries_test.go index 92c0c71789..be87f0da2e 100644 --- a/server/service/osquery_utils/queries_test.go +++ b/server/service/osquery_utils/queries_test.go @@ -602,13 +602,14 @@ func TestDirectIngestMDMMac(t *testing.T) { }, }, nil } - ds.SetOrUpdateMDMDataFunc = func(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollmentRef string) error { + ds.SetOrUpdateMDMDataFunc = func(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollmentRef string, isPersonalEnrollment bool) error { require.Equal(t, isServer, c.wantParams[0]) require.Equal(t, enrolled, c.wantParams[1]) require.Equal(t, serverURL, c.wantParams[2]) require.Equal(t, installedFromDep, c.wantParams[3]) require.Equal(t, name, c.wantParams[4]) require.Equal(t, fleetEnrollmentRef, c.enrollRef) + require.False(t, isPersonalEnrollment) return nil } @@ -680,10 +681,11 @@ func TestDirectIngestMDMFleetEnrollRef(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - ds.SetOrUpdateMDMDataFunc = func(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollmentRef string) error { + ds.SetOrUpdateMDMDataFunc = func(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollmentRef string, isPersonalEnrollment bool) error { require.False(t, isServer) require.True(t, enrolled) require.True(t, installedFromDep) + require.False(t, isPersonalEnrollment) require.Equal(t, tc.wantServerURL, serverURL) require.Equal(t, tc.wantEnrollRef, fleetEnrollmentRef) @@ -726,13 +728,14 @@ func TestDirectIngestMDMFleetEnrollRef(t *testing.T) { }, }, nil } - ds.SetOrUpdateMDMDataFunc = func(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollmentRef string) error { + ds.SetOrUpdateMDMDataFunc = func(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollmentRef string, isPersonalEnrollment bool) error { require.False(t, isServer) require.True(t, enrolled) require.True(t, installedFromDep) require.Equal(t, "https://test.example.com", serverURL) require.Equal(t, "test-reference", fleetEnrollmentRef) require.Equal(t, fleet.WellKnownMDMFleet, name) + require.False(t, isPersonalEnrollment) return nil } @@ -964,13 +967,14 @@ func TestDirectIngestMDMWindows(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { - ds.SetOrUpdateMDMDataFunc = func(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollmentRef string) error { + ds.SetOrUpdateMDMDataFunc = func(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollmentRef string, isPersonalEnrollment bool) error { require.Equal(t, c.wantEnrolled, enrolled) require.Equal(t, c.wantInstalledFromDep, installedFromDep) require.Equal(t, c.wantIsServer, isServer) require.Equal(t, c.wantServerURL, serverURL) require.Equal(t, c.wantMDMSolName, name) require.Empty(t, fleetEnrollmentRef) + require.False(t, isPersonalEnrollment) return nil } }) diff --git a/server/service/transport.go b/server/service/transport.go index 55744d8210..238c89a21c 100644 --- a/server/service/transport.go +++ b/server/service/transport.go @@ -357,7 +357,7 @@ func hostListOptionsFromRequest(r *http.Request) (fleet.HostListOptions, error) enrollmentStatus := r.URL.Query().Get("mdm_enrollment_status") switch fleet.MDMEnrollStatus(enrollmentStatus) { - case fleet.MDMEnrollStatusManual, fleet.MDMEnrollStatusAutomatic, + case fleet.MDMEnrollStatusManual, fleet.MDMEnrollStatusAutomatic, fleet.MDMEnrollStatusPersonal, fleet.MDMEnrollStatusPending, fleet.MDMEnrollStatusUnenrolled, fleet.MDMEnrollStatusEnrolled: hopt.MDMEnrollmentStatusFilter = fleet.MDMEnrollStatus(enrollmentStatus) case "": diff --git a/server/worker/apple_mdm_test.go b/server/worker/apple_mdm_test.go index c61855942c..8fb2d2b0f6 100644 --- a/server/worker/apple_mdm_test.go +++ b/server/worker/apple_mdm_test.go @@ -94,7 +94,7 @@ func TestAppleMDM(t *testing.T) { err := ds.UpsertMDMAppleHostDEPAssignments(ctx, []fleet.Host{*h}, abmTokenID) require.NoError(t, err) } - err = ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "http://example.com", depAssignedToFleet, fleet.WellKnownMDMFleet, "") + err = ds.SetOrUpdateMDMData(ctx, h.ID, false, true, "http://example.com", depAssignedToFleet, fleet.WellKnownMDMFleet, "", false) require.NoError(t, err) return h } @@ -816,5 +816,4 @@ func TestGetSignedURL(t *testing.T) { assert.Contains(t, buf.String(), "test error") assert.True(t, mockStore.SignFuncInvoked) assert.False(t, mockStore.ExistsFuncInvoked) - }