mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 08:55:24 +00:00
delete all host MDM profiles when is unenrolled programatically through the API (#10603)
https://github.com/fleetdm/fleet/issues/10507
This commit is contained in:
parent
d7fddb9c01
commit
09b6b8610f
@ -1060,6 +1060,14 @@ func (ds *Datastore) BulkUpsertMDMAppleHostProfiles(ctx context.Context, payload
|
||||
return err
|
||||
}
|
||||
|
||||
func (ds *Datastore) DeleteMDMAppleProfilesForHost(ctx context.Context, hostUUID string) error {
|
||||
_, err := ds.writer.ExecContext(ctx, `
|
||||
DELETE FROM host_mdm_apple_profiles
|
||||
WHERE host_uuid = ?
|
||||
`, hostUUID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (ds *Datastore) UpdateOrDeleteHostMDMAppleProfile(ctx context.Context, profile *fleet.HostMDMAppleProfile) error {
|
||||
if profile.OperationType == fleet.MDMAppleOperationTypeRemove &&
|
||||
profile.Status != nil && (*profile.Status == fleet.MDMAppleDeliveryApplied || profile.IgnoreMDMClientError()) {
|
||||
|
@ -37,6 +37,7 @@ func TestMDMAppleConfigProfile(t *testing.T) {
|
||||
{"TestMDMAppleHostsProfilesStatus", testMDMAppleHostsProfilesStatus},
|
||||
{"TestMDMAppleInsertIdPAccount", testMDMAppleInsertIdPAccount},
|
||||
{"TestIgnoreMDMClientError", testIgnoreMDMClientError},
|
||||
{"TestDeleteMDMAppleProfilesForHost", testDeleteMDMAppleProfilesForHost},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@ -1577,3 +1578,38 @@ func testIgnoreMDMClientError(t *testing.T, ds *Datastore) {
|
||||
require.Equal(t, fleet.MDMAppleDeliveryFailed, *cps[0].Status)
|
||||
require.Equal(t, "MDMClientError (96): Cannot replace profile 'p2' because it was not installed by the MDM server.", cps[0].Detail)
|
||||
}
|
||||
|
||||
func testDeleteMDMAppleProfilesForHost(t *testing.T, ds *Datastore) {
|
||||
ctx := context.Background()
|
||||
h, err := ds.NewHost(ctx, &fleet.Host{
|
||||
DetailUpdatedAt: time.Now(),
|
||||
LabelUpdatedAt: time.Now(),
|
||||
PolicyUpdatedAt: time.Now(),
|
||||
SeenTime: time.Now(),
|
||||
OsqueryHostID: ptr.String("host0-osquery-id"),
|
||||
NodeKey: ptr.String("host0-node-key"),
|
||||
UUID: "host0-test-mdm-profiles",
|
||||
Hostname: "hostname0",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, ds.BulkUpsertMDMAppleHostProfiles(ctx, []*fleet.MDMAppleBulkUpsertHostProfilePayload{{
|
||||
ProfileID: uint(1),
|
||||
ProfileIdentifier: "p1",
|
||||
ProfileName: "name1",
|
||||
HostUUID: h.UUID,
|
||||
CommandUUID: "c1",
|
||||
OperationType: fleet.MDMAppleOperationTypeRemove,
|
||||
Status: &fleet.MDMAppleDeliveryPending,
|
||||
}}))
|
||||
|
||||
gotProfs, err := ds.GetHostMDMProfiles(ctx, h.UUID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, gotProfs, 1)
|
||||
|
||||
err = ds.DeleteMDMAppleProfilesForHost(ctx, h.UUID)
|
||||
require.NoError(t, err)
|
||||
gotProfs, err = ds.GetHostMDMProfiles(ctx, h.UUID)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, gotProfs)
|
||||
}
|
||||
|
@ -817,6 +817,9 @@ type Datastore interface {
|
||||
// and the status is "applied" (i.e. successfully removed).
|
||||
UpdateOrDeleteHostMDMAppleProfile(ctx context.Context, profile *HostMDMAppleProfile) error
|
||||
|
||||
// DeleteMDMAppleProfilesForHost deletes all MDM profiles for a host
|
||||
DeleteMDMAppleProfilesForHost(ctx context.Context, hostUUID string) error
|
||||
|
||||
// GetMDMAppleCommandRequest type returns the request type for the given command
|
||||
GetMDMAppleCommandRequestType(ctx context.Context, commandUUID string) (string, error)
|
||||
|
||||
|
@ -566,6 +566,8 @@ type GetMDMAppleProfilesContentsFunc func(ctx context.Context, profileIDs []uint
|
||||
|
||||
type UpdateOrDeleteHostMDMAppleProfileFunc func(ctx context.Context, profile *fleet.HostMDMAppleProfile) error
|
||||
|
||||
type DeleteMDMAppleProfilesForHostFunc func(ctx context.Context, hostUUID string) error
|
||||
|
||||
type GetMDMAppleCommandRequestTypeFunc func(ctx context.Context, commandUUID string) (string, error)
|
||||
|
||||
type GetMDMAppleHostsProfilesSummaryFunc func(ctx context.Context, teamID *uint) (*fleet.MDMAppleHostsProfilesSummary, error)
|
||||
@ -1398,6 +1400,9 @@ type DataStore struct {
|
||||
UpdateOrDeleteHostMDMAppleProfileFunc UpdateOrDeleteHostMDMAppleProfileFunc
|
||||
UpdateOrDeleteHostMDMAppleProfileFuncInvoked bool
|
||||
|
||||
DeleteMDMAppleProfilesForHostFunc DeleteMDMAppleProfilesForHostFunc
|
||||
DeleteMDMAppleProfilesForHostFuncInvoked bool
|
||||
|
||||
GetMDMAppleCommandRequestTypeFunc GetMDMAppleCommandRequestTypeFunc
|
||||
GetMDMAppleCommandRequestTypeFuncInvoked bool
|
||||
|
||||
@ -3335,6 +3340,13 @@ func (s *DataStore) UpdateOrDeleteHostMDMAppleProfile(ctx context.Context, profi
|
||||
return s.UpdateOrDeleteHostMDMAppleProfileFunc(ctx, profile)
|
||||
}
|
||||
|
||||
func (s *DataStore) DeleteMDMAppleProfilesForHost(ctx context.Context, hostUUID string) error {
|
||||
s.mu.Lock()
|
||||
s.DeleteMDMAppleProfilesForHostFuncInvoked = true
|
||||
s.mu.Unlock()
|
||||
return s.DeleteMDMAppleProfilesForHostFunc(ctx, hostUUID)
|
||||
}
|
||||
|
||||
func (s *DataStore) GetMDMAppleCommandRequestType(ctx context.Context, commandUUID string) (string, error) {
|
||||
s.mu.Lock()
|
||||
s.GetMDMAppleCommandRequestTypeFuncInvoked = true
|
||||
|
@ -1103,6 +1103,14 @@ func (svc *Service) EnqueueMDMAppleCommandRemoveEnrollmentProfile(ctx context.Co
|
||||
return ctxerr.Wrap(ctx, err, "enqueuing mdm apple remove profile command")
|
||||
}
|
||||
|
||||
// Since the host is unenrolled, delete all profiles assigned to the
|
||||
// host manually, the device won't Acknowledge any more requests (eg:
|
||||
// to delete profiles) and profiles are automatically removed on
|
||||
// unenrollment.
|
||||
if err := svc.ds.DeleteMDMAppleProfilesForHost(ctx, h.UUID); err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "removing all profiles from host")
|
||||
}
|
||||
|
||||
if err := svc.ds.NewActivity(ctx, authz.UserFromContext(ctx), &fleet.ActivityTypeMDMUnenrolled{
|
||||
HostSerial: h.HardwareSerial,
|
||||
HostDisplayName: h.DisplayName(),
|
||||
|
@ -662,6 +662,10 @@ func TestMDMCommandAuthz(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
|
||||
ds.DeleteMDMAppleProfilesForHostFunc = func(ctx context.Context, hostUUID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var mdmEnabled atomic.Bool
|
||||
ds.GetNanoMDMEnrollmentStatusFunc = func(ctx context.Context, hostUUID string) (bool, error) {
|
||||
// This function is called twice during EnqueueMDMAppleCommandRemoveEnrollmentProfile.
|
||||
|
@ -778,6 +778,21 @@ func (s *integrationMDMTestSuite) TestMDMAppleUnenroll() {
|
||||
require.Len(t, listHostsRes.Hosts, 1)
|
||||
h := listHostsRes.Hosts[0]
|
||||
|
||||
// assign profiles to the host
|
||||
s.Do("POST", "/api/v1/fleet/mdm/apple/profiles/batch", batchSetMDMAppleProfilesRequest{Profiles: [][]byte{
|
||||
mobileconfigForTest("N1", "I1"),
|
||||
mobileconfigForTest("N2", "I2"),
|
||||
mobileconfigForTest("N3", "I3"),
|
||||
}}, http.StatusNoContent)
|
||||
|
||||
// trigger a sync and verify that there are profiles assigned to the host
|
||||
_, err = s.profileSchedule.Trigger()
|
||||
require.NoError(t, err)
|
||||
|
||||
var hostResp getHostResponse
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/hosts/%d", h.ID), getHostRequest{}, http.StatusOK, &hostResp)
|
||||
require.Len(t, *hostResp.Host.MDM.Profiles, 3)
|
||||
|
||||
// try to unenroll the host, fails since the host doesn't respond
|
||||
s.Do("PATCH", fmt.Sprintf("/api/latest/fleet/mdm/hosts/%d/unenroll", h.ID), nil, http.StatusGatewayTimeout)
|
||||
|
||||
@ -815,6 +830,12 @@ func (s *integrationMDMTestSuite) TestMDMAppleUnenroll() {
|
||||
return res, err
|
||||
}
|
||||
s.Do("PATCH", fmt.Sprintf("/api/latest/fleet/mdm/hosts/%d/unenroll", h.ID), nil, http.StatusOK)
|
||||
|
||||
// profiles are removed and the host is no longer enrolled
|
||||
hostResp = getHostResponse{}
|
||||
s.DoJSON("GET", fmt.Sprintf("/api/v1/fleet/hosts/%d", h.ID), getHostRequest{}, http.StatusOK, &hostResp)
|
||||
require.Nil(t, hostResp.Host.MDM.Profiles)
|
||||
require.Equal(t, "", hostResp.Host.MDM.Name)
|
||||
}
|
||||
|
||||
func (s *integrationMDMTestSuite) TestMDMAppleGetEncryptionKey() {
|
||||
|
Loading…
Reference in New Issue
Block a user