mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Immediately ask for a host refetch when a host re-enrolls and reuses an existing host row (#29081)
This commit is contained in:
parent
7c88ed8a15
commit
7f5fc14f59
4 changed files with 99 additions and 6 deletions
|
|
@ -0,0 +1 @@
|
|||
* Fixed a bug where a host that was wiped and re-enrolled without deleting the corresponding host row in Fleet had its old Google Chrome profiles (and other osquery-based data) showing for about an hour.
|
||||
|
|
@ -1987,6 +1987,7 @@ func (ds *Datastore) EnrollOrbit(ctx context.Context, isMDMEnabled bool, hostInf
|
|||
"host_id", enrolledHostInfo.ID,
|
||||
)
|
||||
}
|
||||
refetchRequested := fleet.PlatformSupportsOsquery(enrolledHostInfo.Platform)
|
||||
|
||||
sqlUpdate := `
|
||||
UPDATE
|
||||
|
|
@ -1996,9 +1997,10 @@ func (ds *Datastore) EnrollOrbit(ctx context.Context, isMDMEnabled bool, hostInf
|
|||
uuid = COALESCE(NULLIF(uuid, ''), ?),
|
||||
osquery_host_id = COALESCE(NULLIF(osquery_host_id, ''), ?),
|
||||
hardware_serial = COALESCE(NULLIF(hardware_serial, ''), ?),
|
||||
computer_name = COALESCE(NULLIF(computer_name, ''), ?),
|
||||
hardware_model = COALESCE(NULLIF(hardware_model, ''), ?),
|
||||
team_id = ?
|
||||
computer_name = COALESCE(NULLIF(computer_name, ''), ?),
|
||||
hardware_model = COALESCE(NULLIF(hardware_model, ''), ?),
|
||||
team_id = ?,
|
||||
refetch_requested = ?
|
||||
WHERE id = ?`
|
||||
_, err := tx.ExecContext(ctx, sqlUpdate,
|
||||
orbitNodeKey,
|
||||
|
|
@ -2008,6 +2010,7 @@ func (ds *Datastore) EnrollOrbit(ctx context.Context, isMDMEnabled bool, hostInf
|
|||
hostInfo.ComputerName,
|
||||
hostInfo.HardwareModel,
|
||||
teamID,
|
||||
refetchRequested,
|
||||
enrolledHostInfo.ID,
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -2171,6 +2174,8 @@ func (ds *Datastore) EnrollHost(ctx context.Context, isMDMEnabled bool, osqueryH
|
|||
return ctxerr.Wrap(ctx, err, "error clearing host_mdm_actions")
|
||||
}
|
||||
|
||||
refetchRequested := fleet.PlatformSupportsOsquery(enrolledHostInfo.Platform)
|
||||
|
||||
// Update existing host record
|
||||
sqlUpdate := `
|
||||
UPDATE hosts
|
||||
|
|
@ -2179,10 +2184,11 @@ func (ds *Datastore) EnrollHost(ctx context.Context, isMDMEnabled bool, osqueryH
|
|||
last_enrolled_at = NOW(),
|
||||
osquery_host_id = ?,
|
||||
uuid = COALESCE(NULLIF(uuid, ''), ?),
|
||||
hardware_serial = COALESCE(NULLIF(hardware_serial, ''), ?)
|
||||
hardware_serial = COALESCE(NULLIF(hardware_serial, ''), ?),
|
||||
refetch_requested = ?
|
||||
WHERE id = ?
|
||||
`
|
||||
_, err := tx.ExecContext(ctx, sqlUpdate, nodeKey, teamID, osqueryHostID, hardwareUUID, hardwareSerial, enrolledHostInfo.ID)
|
||||
_, err := tx.ExecContext(ctx, sqlUpdate, nodeKey, teamID, osqueryHostID, hardwareUUID, hardwareSerial, refetchRequested, enrolledHostInfo.ID)
|
||||
if err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "update host")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -862,7 +862,12 @@ func (h *Host) FleetPlatform() string {
|
|||
|
||||
// SupportsOsquery returns whether the device runs osquery.
|
||||
func (h *Host) SupportsOsquery() bool {
|
||||
return h.Platform != "ios" && h.Platform != "ipados" && h.Platform != "android"
|
||||
return PlatformSupportsOsquery(h.Platform)
|
||||
}
|
||||
|
||||
// PlatformSupportsOsquery returns whether osquery is supported on this platform.
|
||||
func PlatformSupportsOsquery(platform string) bool {
|
||||
return platform != "ios" && platform != "ipados" && platform != "android"
|
||||
}
|
||||
|
||||
// HostLinuxOSs are the possible linux values for Host.Platform.
|
||||
|
|
|
|||
|
|
@ -13260,3 +13260,84 @@ func (s *integrationTestSuite) TestHostCertificates() {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *integrationTestSuite) TestHostReenrollWithSameHostRowRefetchOsquery() {
|
||||
t := s.T()
|
||||
|
||||
// create a mac, linux and windows host
|
||||
host1 := createOrbitEnrolledHost(t, "darwin", "host1", s.ds)
|
||||
host2 := createOrbitEnrolledHost(t, "linux", "host2", s.ds)
|
||||
host3 := createOrbitEnrolledHost(t, "windows", "host3", s.ds)
|
||||
|
||||
// set a chrome profile for each host
|
||||
for i, h := range []*fleet.Host{host1, host2, host3} {
|
||||
distributedReq := submitDistributedQueryResultsRequestShim{
|
||||
NodeKey: *h.NodeKey,
|
||||
Results: map[string]json.RawMessage{
|
||||
hostDetailQueryPrefix + "google_chrome_profiles": json.RawMessage(fmt.Sprintf(
|
||||
`[{"email": "%s"}]`, fmt.Sprintf("user%d@example.com", i))),
|
||||
},
|
||||
Statuses: map[string]interface{}{
|
||||
hostDistributedQueryPrefix + "google_chrome_profiles": 0,
|
||||
},
|
||||
Messages: map[string]string{},
|
||||
Stats: map[string]*fleet.Stats{},
|
||||
}
|
||||
distributedResp := submitDistributedQueryResultsResponse{}
|
||||
s.DoJSON("POST", "/api/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
}
|
||||
|
||||
oldHosts := make([]fleet.Host, 3)
|
||||
for i, h := range []*fleet.Host{host1, host2, host3} {
|
||||
var hostResponse getHostResponse
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", h.ID), nil, http.StatusOK, &hostResponse)
|
||||
require.False(t, hostResponse.Host.RefetchRequested)
|
||||
require.Len(t, hostResponse.Host.EndUsers, 1)
|
||||
require.Len(t, hostResponse.Host.EndUsers[0].OtherEmails, 1)
|
||||
require.Equal(t, hostResponse.Host.EndUsers[0].OtherEmails[0].Source, "google_chrome_profiles")
|
||||
oldHosts[i] = hostResponse.Host.Host
|
||||
}
|
||||
|
||||
// do an orbit re-enrollment of the hosts, should set refetch requested
|
||||
orbitKey := setOrbitEnrollment(t, host1, s.ds)
|
||||
host1.OrbitNodeKey = &orbitKey
|
||||
orbitKey = setOrbitEnrollment(t, host2, s.ds)
|
||||
host2.OrbitNodeKey = &orbitKey
|
||||
orbitKey = setOrbitEnrollment(t, host3, s.ds)
|
||||
host3.OrbitNodeKey = &orbitKey
|
||||
|
||||
for i, h := range []*fleet.Host{host1, host2, host3} {
|
||||
var hostResponse getHostResponse
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", h.ID), nil, http.StatusOK, &hostResponse)
|
||||
require.True(t, hostResponse.Host.RefetchRequested)
|
||||
require.Len(t, hostResponse.Host.EndUsers, 1)
|
||||
require.Len(t, hostResponse.Host.EndUsers[0].OtherEmails, 1)
|
||||
require.Equal(t, hostResponse.Host.EndUsers[0].OtherEmails[0].Source, "google_chrome_profiles")
|
||||
require.Equal(t, oldHosts[i].ID, h.ID)
|
||||
}
|
||||
|
||||
// send a response for the refetch request
|
||||
for _, h := range []*fleet.Host{host1, host2, host3} {
|
||||
distributedReq := submitDistributedQueryResultsRequestShim{
|
||||
NodeKey: *h.NodeKey,
|
||||
Results: map[string]json.RawMessage{
|
||||
hostDetailQueryPrefix + "google_chrome_profiles": json.RawMessage(`[]`),
|
||||
},
|
||||
Statuses: map[string]interface{}{
|
||||
hostDistributedQueryPrefix + "google_chrome_profiles": 0,
|
||||
},
|
||||
Messages: map[string]string{},
|
||||
Stats: map[string]*fleet.Stats{},
|
||||
}
|
||||
distributedResp := submitDistributedQueryResultsResponse{}
|
||||
s.DoJSON("POST", "/api/osquery/distributed/write", distributedReq, http.StatusOK, &distributedResp)
|
||||
}
|
||||
|
||||
for i, h := range []*fleet.Host{host1, host2, host3} {
|
||||
var hostResponse getHostResponse
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", h.ID), nil, http.StatusOK, &hostResponse)
|
||||
require.False(t, hostResponse.Host.RefetchRequested)
|
||||
require.Len(t, hostResponse.Host.EndUsers, 0)
|
||||
require.Equal(t, oldHosts[i].ID, h.ID)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue