mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 08:55:24 +00:00
Support deletion host-referencing tables that use UUID instead of ID when deleting a host (#11017)
This commit is contained in:
parent
242716c905
commit
231b8e4153
1
changes/issue-10673-delete-additional-host-table-refs
Normal file
1
changes/issue-10673-delete-additional-host-table-refs
Normal file
@ -0,0 +1 @@
|
||||
* Added missing tables to be cleared on host deletion (those that reference the host by UUID instead of ID).
|
@ -2502,6 +2502,27 @@ func testGetMDMAppleCommandResults(t *testing.T, ds *Datastore) {
|
||||
Result: []byte(rawCmd2),
|
||||
},
|
||||
})
|
||||
|
||||
// delete host [0] and verify that it did delete its command results
|
||||
err = ds.DeleteHost(ctx, enrolledHosts[0].ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// command now has only the hosts[1] result
|
||||
res, err = ds.GetMDMAppleCommandResults(ctx, uuid2)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, res, 1)
|
||||
|
||||
require.NotZero(t, res[0].UpdatedAt)
|
||||
res[0].UpdatedAt = time.Time{}
|
||||
require.ElementsMatch(t, res, []*fleet.MDMAppleCommandResult{
|
||||
{
|
||||
DeviceID: enrolledHosts[1].UUID,
|
||||
CommandUUID: uuid2,
|
||||
Status: "Error",
|
||||
RequestType: "ProfileList",
|
||||
Result: []byte(rawCmd2),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func createMDMAppleCommanderAndStorage(t *testing.T, ds *Datastore) (*apple_mdm.MDMAppleCommander, *NanoMDMStorage) {
|
||||
|
@ -333,6 +333,17 @@ var hostRefs = []string{
|
||||
"host_disk_encryption_keys",
|
||||
}
|
||||
|
||||
// those host refs cannot be deleted using the host.id like the hostRefs above,
|
||||
// they use the host.uuid instead. Additionally, the column name that refers to
|
||||
// the host.uuid is not always named the same, so the map key is the table name
|
||||
// and the map value is the column name to match to the host.uuid.
|
||||
var additionalHostRefsByUUID = map[string]string{
|
||||
"host_mdm_apple_profiles": "host_uuid",
|
||||
// deleting from nano_devices causes cascading deletes to nano_enrollments and
|
||||
// any other tables that reference nano_devices.
|
||||
"nano_devices": "id",
|
||||
}
|
||||
|
||||
func (ds *Datastore) DeleteHost(ctx context.Context, hid uint) error {
|
||||
delHostRef := func(tx sqlx.ExtContext, table string) error {
|
||||
_, err := tx.ExecContext(ctx, fmt.Sprintf(`DELETE FROM %s WHERE host_id=?`, table), hid)
|
||||
@ -342,6 +353,12 @@ func (ds *Datastore) DeleteHost(ctx context.Context, hid uint) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// load just the host uuid for the MDM tables that rely on this to be cleared.
|
||||
var hostUUID string
|
||||
if err := ds.writer.GetContext(ctx, &hostUUID, `SELECT uuid FROM hosts WHERE id = ?`, hid); err != nil {
|
||||
return ctxerr.Wrapf(ctx, err, "get uuid for host %d", hid)
|
||||
}
|
||||
|
||||
return ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error {
|
||||
_, err := tx.ExecContext(ctx, `DELETE FROM hosts WHERE id = ?`, hid)
|
||||
if err != nil {
|
||||
@ -360,6 +377,15 @@ func (ds *Datastore) DeleteHost(ctx context.Context, hid uint) error {
|
||||
return ctxerr.Wrapf(ctx, err, "deleting pack_targets for host %d", hid)
|
||||
}
|
||||
|
||||
// no point trying the uuid-based tables if the host's uuid is missing
|
||||
if hostUUID != "" {
|
||||
for table, col := range additionalHostRefsByUUID {
|
||||
if _, err := tx.ExecContext(ctx, fmt.Sprintf("DELETE FROM `%s` WHERE `%s`=?", table, col), hostUUID); err != nil {
|
||||
return ctxerr.Wrapf(ctx, err, "deleting %s for host uuid %s", table, hostUUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
@ -5396,6 +5396,10 @@ func testHostsDeleteHosts(t *testing.T, ds *Datastore) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, host)
|
||||
|
||||
// enroll in Fleet MDM
|
||||
nanoEnroll(t, ds, host, false)
|
||||
|
||||
// Updates host_software.
|
||||
software := []fleet.Software{
|
||||
{Name: "foo", Version: "0.0.1", Source: "chrome_extensions"},
|
||||
@ -5488,7 +5492,7 @@ func testHostsDeleteHosts(t *testing.T, ds *Datastore) {
|
||||
require.NoError(t, err)
|
||||
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, false, "foo.mdm.example.com", false, "")
|
||||
err = ds.SetOrUpdateMDMData(context.Background(), host.ID, false, true, "foo.mdm.example.com", false, "")
|
||||
require.NoError(t, err)
|
||||
// Update host_munki_info.
|
||||
err = ds.SetOrUpdateMunkiInfo(context.Background(), host.ID, "42", []string{"a"}, []string{"b"})
|
||||
@ -5515,6 +5519,13 @@ func testHostsDeleteHosts(t *testing.T, ds *Datastore) {
|
||||
// set an encryption key
|
||||
err = ds.SetOrUpdateHostDiskEncryptionKey(context.Background(), host.ID, "TESTKEY")
|
||||
require.NoError(t, err)
|
||||
// set an mdm profile
|
||||
prof, err := ds.NewMDMAppleConfigProfile(context.Background(), *configProfileForTest(t, "N1", "I1", "U1"))
|
||||
require.NoError(t, err)
|
||||
err = ds.BulkUpsertMDMAppleHostProfiles(context.Background(), []*fleet.MDMAppleBulkUpsertHostProfilePayload{
|
||||
{ProfileID: prof.ProfileID, ProfileIdentifier: prof.Identifier, ProfileName: prof.Name, HostUUID: host.UUID, OperationType: fleet.MDMAppleOperationTypeInstall},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Operating system vulnerabilities
|
||||
_, err = ds.writer.Exec(
|
||||
@ -5527,9 +5538,15 @@ func testHostsDeleteHosts(t *testing.T, ds *Datastore) {
|
||||
for _, hostRef := range hostRefs {
|
||||
var ok bool
|
||||
err = ds.writer.Get(&ok, fmt.Sprintf("SELECT 1 FROM %s WHERE host_id = ?", hostRef), host.ID)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, err, hostRef)
|
||||
require.True(t, ok, "table: %s", hostRef)
|
||||
}
|
||||
for tbl, col := range additionalHostRefsByUUID {
|
||||
var ok bool
|
||||
err = ds.writer.Get(&ok, fmt.Sprintf("SELECT 1 FROM %s WHERE %s = ?", tbl, col), host.UUID)
|
||||
require.NoError(t, err, tbl)
|
||||
require.True(t, ok, "table: %s", tbl)
|
||||
}
|
||||
|
||||
err = ds.DeleteHosts(context.Background(), []uint{host.ID})
|
||||
require.NoError(t, err)
|
||||
@ -5541,6 +5558,12 @@ func testHostsDeleteHosts(t *testing.T, ds *Datastore) {
|
||||
require.True(t, err == nil || errors.Is(err, sql.ErrNoRows), "table: %s", hostRef)
|
||||
require.False(t, ok, "table: %s", hostRef)
|
||||
}
|
||||
for tbl, col := range additionalHostRefsByUUID {
|
||||
var ok bool
|
||||
err = ds.writer.Get(&ok, fmt.Sprintf("SELECT 1 FROM %s WHERE %s = ?", tbl, col), host.UUID)
|
||||
require.True(t, err == nil || errors.Is(err, sql.ErrNoRows), "table: %s", tbl)
|
||||
require.False(t, ok, "table: %s", tbl)
|
||||
}
|
||||
}
|
||||
|
||||
func testHostIDsByOSVersion(t *testing.T, ds *Datastore) {
|
||||
|
Loading…
Reference in New Issue
Block a user