fix: better UX when attempting to turn off MDM on an offline host (#21770)

> Related issue: #20868

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/Committing-Changes.md#changes-files)
for more information.
- [x] Manual QA for all new/changed functionality
This commit is contained in:
Jahziel Villasana-Espinoza 2024-09-05 10:07:44 -04:00 committed by GitHub
parent 74a9f50ba7
commit 3bebd7f347
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 19 additions and 44 deletions

View file

@ -0,0 +1 @@
- Improves the UX of turning off MDM on an offline host (endpoint doesn't error anymore)

View file

@ -25,11 +25,15 @@ const UnenrollMdmModal = ({ hostId, onClose }: IUnenrollMdmModalProps) => {
setRequestState("unenrolling");
try {
await mdmAPI.unenrollHostFromMdm(hostId, 5000);
renderFlash("success", "Successfully turned off MDM.");
renderFlash(
"success",
"Turning off MDM or will turn off when the host comes online."
);
onClose();
} catch (unenrollMdmError: unknown) {
renderFlash("error", "Couldn't turn off MDM. Please try again.");
console.log(unenrollMdmError);
setRequestState("error");
onClose();
}
};

View file

@ -1570,47 +1570,17 @@ func (svc *Service) EnqueueMDMAppleCommandRemoveEnrollmentProfile(ctx context.Co
return ctxerr.Wrap(ctx, err, "logging activity for mdm apple remove profile command")
}
return svc.pollResultMDMAppleCommandRemoveEnrollmentProfile(ctx, cmdUUID, h.UUID, info.Platform)
}
func (svc *Service) pollResultMDMAppleCommandRemoveEnrollmentProfile(ctx context.Context, cmdUUID string, deviceID string, platform string) error {
ctx, cancelFn := context.WithDeadline(ctx, time.Now().Add(5*time.Second))
ticker := time.NewTicker(300 * time.Millisecond)
defer func() {
ticker.Stop()
cancelFn()
}()
for {
select {
case <-ctx.Done():
// time out after 5 seconds
return fleet.MDMAppleCommandTimeoutError{}
case <-ticker.C:
nanoEnroll, err := svc.ds.GetNanoMDMEnrollment(ctx, deviceID)
if err != nil {
level.Error(svc.logger).Log("err", "get nanomdm enrollment status", "details", err, "id", deviceID, "command_uuid", cmdUUID)
return err
}
if nanoEnroll != nil && nanoEnroll.Enabled {
// check again on the next tick
continue
}
// success, mdm enrollment is no longer enabled for the device
level.Info(svc.logger).Log("msg", "mdm disabled for device", "id", deviceID, "command_uuid", cmdUUID)
mdmLifecycle := mdmlifecycle.New(svc.ds, svc.logger)
err = mdmLifecycle.Do(ctx, mdmlifecycle.HostOptions{
Action: mdmlifecycle.HostActionTurnOff,
Platform: platform,
UUID: deviceID,
})
if err != nil {
return err
}
return nil
}
mdmLifecycle := mdmlifecycle.New(svc.ds, svc.logger)
err = mdmLifecycle.Do(ctx, mdmlifecycle.HostOptions{
Action: mdmlifecycle.HostActionTurnOff,
Platform: info.Platform,
UUID: h.UUID,
})
if err != nil {
return ctxerr.Wrap(ctx, err, "running turn off action in mdm lifecycle")
}
return nil
}
type mdmAppleGetInstallerRequest struct {

View file

@ -1378,8 +1378,8 @@ func (s *integrationMDMTestSuite) TestMDMAppleUnenroll() {
// 3 profiles added + 1 profile with fleetd configuration + 1 root CA config
require.Len(t, *hostResp.Host.MDM.Profiles, 5)
// try to unenroll the host, fails since the host doesn't respond
s.Do("DELETE", fmt.Sprintf("/api/latest/fleet/hosts/%d/mdm", h.ID), nil, http.StatusGatewayTimeout)
// returns success, but this is effectively a no-op because the host isn't enrolled yet.
s.Do("DELETE", fmt.Sprintf("/api/latest/fleet/hosts/%d/mdm", h.ID), nil, http.StatusOK)
// we're going to modify this mock, make sure we restore its default
originalPushMock := s.pushProvider.PushFunc