Add mdm enrollment pending filter to API endpoints (#9137)

This commit is contained in:
gillespi314 2023-01-03 11:26:23 -06:00 committed by GitHub
parent 75e8af2b2d
commit b990121fdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 82 additions and 18 deletions

View File

@ -0,0 +1,2 @@
- Added option to filter hosts by MDM enrollment status "pending" to surface devices ordered through Apple Business Manager that are still pending
enrollment in Fleet's MDM.

View File

@ -868,7 +868,7 @@ func newAppleMDMDEPProfileAssigner(
level.Error(kitlog.With(logger, "cron", name, "component", "nanodep-syncer")).Log("err", err) level.Error(kitlog.With(logger, "cron", name, "component", "nanodep-syncer")).Log("err", err)
sentry.CaptureException(err) sentry.CaptureException(err)
case n > 0: case n > 0:
level.Info(kitlog.With(logger, "cron", name, "component", "nanodep-syncer")).Log("msg", fmt.Sprintf("%d new mdm devices added to hosts", n)) level.Info(kitlog.With(logger, "cron", name, "component", "nanodep-syncer")).Log("msg", fmt.Sprintf("added %d new mdm device(s) to pending hosts", n))
default: default:
// ok // ok
} }

View File

@ -1707,7 +1707,7 @@ None.
| os_version | string | query | The version of the operating system to filter hosts by. `os_name` must also be specified with `os_version` | | os_version | string | query | The version of the operating system to filter hosts by. `os_name` must also be specified with `os_version` |
| device_mapping | boolean | query | Indicates whether `device_mapping` should be included for each host. See ["Get host's Google Chrome profiles](#get-host's-google-chrome-profiles) for more information about this feature. | | device_mapping | boolean | query | Indicates whether `device_mapping` should be included for each host. See ["Get host's Google Chrome profiles](#get-host's-google-chrome-profiles) for more information about this feature. |
| mdm_id | integer | query | The ID of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider and URL). | | mdm_id | integer | query | The ID of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider and URL). |
| mdm_enrollment_status | string | query | The _mobile device management_ (MDM) enrollment status to filter hosts by. Can be one of 'manual', 'automatic' or 'unenrolled'. | | mdm_enrollment_status | string | query | The _mobile device management_ (MDM) enrollment status to filter hosts by. Can be one of 'manual', 'automatic', 'pending', or 'unenrolled'. |
| munki_issue_id | integer | query | The ID of the _munki issue_ (a Munki-reported error or warning message) to filter hosts by (that is, filter hosts that are affected by that corresponding error or warning message). | | munki_issue_id | integer | query | The ID of the _munki issue_ (a Munki-reported error or warning message) to filter hosts by (that is, filter hosts that are affected by that corresponding error or warning message). |
| low_disk_space | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts with less GB of disk space available than this value. Must be a number between 1-100. | | low_disk_space | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts with less GB of disk space available than this value. Must be a number between 1-100. |
| disable_failing_policies| boolean | query | If "true", hosts will return failing policies as 0 regardless of whether there are any that failed for the host. This is meant to be used when increased performance is needed in exchange for the extra information. | | disable_failing_policies| boolean | query | If "true", hosts will return failing policies as 0 regardless of whether there are any that failed for the host. This is meant to be used when increased performance is needed in exchange for the extra information. |
@ -1852,7 +1852,7 @@ Response payload with the `munki_issue_id` filter provided:
| os_version | string | query | The version of the operating system to filter hosts by. `os_name` must also be specified with `os_version` | | os_version | string | query | The version of the operating system to filter hosts by. `os_name` must also be specified with `os_version` |
| label_id | integer | query | A valid label ID. Can only be used in combination with `order_key`, `order_direction`, `after`, `status`, `query` and `team_id`. | | label_id | integer | query | A valid label ID. Can only be used in combination with `order_key`, `order_direction`, `after`, `status`, `query` and `team_id`. |
| mdm_id | integer | query | The ID of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider and URL). | | mdm_id | integer | query | The ID of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider and URL). |
| mdm_enrollment_status | string | query | The _mobile device management_ (MDM) enrollment status to filter hosts by. Can be one of 'manual', 'automatic' or 'unenrolled'. | | mdm_enrollment_status | string | query | The _mobile device management_ (MDM) enrollment status to filter hosts by. Can be one of 'manual', 'automatic', 'pending', or 'unenrolled'. |
| munki_issue_id | integer | query | The ID of the _munki issue_ (a Munki-reported error or warning message) to filter hosts by (that is, filter hosts that are affected by that corresponding error or warning message). | | munki_issue_id | integer | query | The ID of the _munki issue_ (a Munki-reported error or warning message) to filter hosts by (that is, filter hosts that are affected by that corresponding error or warning message). |
| low_disk_space | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts with less GB of disk space available than this value. Must be a number between 1-100. | | low_disk_space | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts with less GB of disk space available than this value. Must be a number between 1-100. |
@ -2887,7 +2887,7 @@ requested by a web browser.
| os_name | string | query | The name of the operating system to filter hosts by. `os_version` must also be specified with `os_name` | | os_name | string | query | The name of the operating system to filter hosts by. `os_version` must also be specified with `os_name` |
| os_version | string | query | The version of the operating system to filter hosts by. `os_name` must also be specified with `os_version` | | os_version | string | query | The version of the operating system to filter hosts by. `os_name` must also be specified with `os_version` |
| mdm_id | integer | query | The ID of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider and URL). | | mdm_id | integer | query | The ID of the _mobile device management_ (MDM) solution to filter hosts by (that is, filter hosts that use a specific MDM provider and URL). |
| mdm_enrollment_status | string | query | The _mobile device management_ (MDM) enrollment status to filter hosts by. Can be one of 'manual', 'automatic' or 'unenrolled'. | | mdm_enrollment_status | string | query | The _mobile device management_ (MDM) enrollment status to filter hosts by. Can be one of 'manual', 'automatic', 'pending', or 'unenrolled'. |
| munki_issue_id | integer | query | The ID of the _munki issue_ (a Munki-reported error or warning message) to filter hosts by (that is, filter hosts that are affected by that corresponding error or warning message). | | munki_issue_id | integer | query | The ID of the _munki issue_ (a Munki-reported error or warning message) to filter hosts by (that is, filter hosts that are affected by that corresponding error or warning message). |
| low_disk_space | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts with less GB of disk space available than this value. Must be a number between 1-100. | | low_disk_space | integer | query | _Available in Fleet Premium_ Filters the hosts to only include hosts with less GB of disk space available than this value. Must be a number between 1-100. |
| label_id | integer | query | A valid label ID. Can only be used in combination with `order_key`, `order_direction`, `status`, `query` and `team_id`. | | label_id | integer | query | A valid label ID. Can only be used in combination with `order_key`, `order_direction`, `status`, `query` and `team_id`. |

View File

@ -704,8 +704,10 @@ func filterHostsByMDM(sql string, opt fleet.HostListOptions, params []interface{
sql += ` AND hmdm.enrolled = 1 AND hmdm.installed_from_dep = 1` sql += ` AND hmdm.enrolled = 1 AND hmdm.installed_from_dep = 1`
case fleet.MDMEnrollStatusManual: 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`
case fleet.MDMEnrollStatusPending:
sql += ` AND hmdm.enrolled = 0 AND hmdm.installed_from_dep = 1`
case fleet.MDMEnrollStatusUnenrolled: case fleet.MDMEnrollStatusUnenrolled:
sql += ` AND hmdm.enrolled = 0` sql += ` AND hmdm.enrolled = 0 AND hmdm.installed_from_dep = 0`
} }
} }
if opt.MDMIDFilter != nil || opt.MDMEnrollmentStatusFilter != "" { if opt.MDMIDFilter != nil || opt.MDMEnrollmentStatusFilter != "" {
@ -2579,7 +2581,8 @@ func (ds *Datastore) generateAggregatedMDMStatus(ctx context.Context, teamID *ui
query := `SELECT query := `SELECT
COUNT(DISTINCT host_id) as hosts_count, COUNT(DISTINCT host_id) as hosts_count,
COALESCE(SUM(CASE WHEN NOT enrolled THEN 1 ELSE 0 END), 0) as unenrolled_hosts_count, 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 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 THEN 1 ELSE 0 END), 0) as enrolled_manual_hosts_count
FROM host_mdm hm FROM host_mdm hm

View File

@ -23,6 +23,7 @@ import (
"github.com/fleetdm/fleet/v4/server/ptr" "github.com/fleetdm/fleet/v4/server/ptr"
"github.com/fleetdm/fleet/v4/server/test" "github.com/fleetdm/fleet/v4/server/test"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
"github.com/micromdm/nanodep/godep"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -891,8 +892,15 @@ func testHostsListMDM(t *testing.T, ds *Datastore) {
hostIDs = append(hostIDs, h.ID) hostIDs = append(hostIDs, h.ID)
} }
// enrollment: pending
n, err := ds.IngestMDMAppleDevicesFromDEPSync(ctx, []godep.Device{
{SerialNumber: "532141num832", Model: "MacBook Pro", OS: "OSX", OpType: "added"},
})
require.NoError(t, err)
require.Equal(t, int64(1), n)
const simpleMDM, kandji, unknown = "https://simplemdm.com", "https://kandji.io", "https://url.com" const simpleMDM, kandji, unknown = "https://simplemdm.com", "https://kandji.io", "https://url.com"
err := ds.SetOrUpdateMDMData(ctx, hostIDs[0], false, true, simpleMDM, true, "") // enrollment: automatic err = ds.SetOrUpdateMDMData(ctx, hostIDs[0], false, true, simpleMDM, true, "") // enrollment: automatic
require.NoError(t, err) require.NoError(t, err)
err = ds.SetOrUpdateMDMData(ctx, hostIDs[1], false, true, kandji, true, "") // enrollment: automatic err = ds.SetOrUpdateMDMData(ctx, hostIDs[1], false, true, kandji, true, "") // enrollment: automatic
require.NoError(t, err) require.NoError(t, err)
@ -929,6 +937,9 @@ func testHostsListMDM(t *testing.T, ds *Datastore) {
hosts = listHostsCheckCount(t, ds, filter, fleet.HostListOptions{MDMEnrollmentStatusFilter: fleet.MDMEnrollStatusAutomatic, MDMIDFilter: &kandjiID}, 1) hosts = listHostsCheckCount(t, ds, filter, fleet.HostListOptions{MDMEnrollmentStatusFilter: fleet.MDMEnrollStatusAutomatic, MDMIDFilter: &kandjiID}, 1)
assert.Equal(t, 1, len(hosts)) assert.Equal(t, 1, len(hosts))
hosts = listHostsCheckCount(t, ds, filter, fleet.HostListOptions{MDMEnrollmentStatusFilter: fleet.MDMEnrollStatusPending}, 1)
assert.Equal(t, 1, len(hosts))
} }
func testHostsListMunkiIssueID(t *testing.T, ds *Datastore) { func testHostsListMunkiIssueID(t *testing.T, ds *Datastore) {
@ -4172,25 +4183,27 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) {
}, },
}) })
require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 432, false, true, "url", false, "")) 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, "")) 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, "")) 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, "")) require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 455, false, true, "https://simplemdm.com", true, "")) // automatic enrollment
require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 999, false, false, "https://kandji.io", true, "")) require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 999, false, false, "https://kandji.io", false, "")) // unenrolled
require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 875, false, false, "https://kandji.io", true, "")) require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 875, false, false, "https://kandji.io", true, "")) // pending enrollment
require.NoError(t, ds.SetOrUpdateMDMData(context.Background(), 1337, false, false, "https://fleetdm.com", true, "")) // pending enrollment
require.NoError(t, ds.GenerateAggregatedMunkiAndMDM(context.Background())) require.NoError(t, ds.GenerateAggregatedMunkiAndMDM(context.Background()))
status, _, err = ds.AggregatedMDMStatus(context.Background(), nil, "") status, _, err = ds.AggregatedMDMStatus(context.Background(), nil, "")
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, 6, status.HostsCount) assert.Equal(t, 7, status.HostsCount)
assert.Equal(t, 2, status.UnenrolledHostsCount) assert.Equal(t, 1, status.UnenrolledHostsCount)
assert.Equal(t, 2, status.PendingHostsCount)
assert.Equal(t, 3, status.EnrolledManualHostsCount) assert.Equal(t, 3, status.EnrolledManualHostsCount)
assert.Equal(t, 1, status.EnrolledAutomatedHostsCount) assert.Equal(t, 1, status.EnrolledAutomatedHostsCount)
solutions, _, err = ds.AggregatedMDMSolutions(context.Background(), nil, "") solutions, _, err = ds.AggregatedMDMSolutions(context.Background(), nil, "")
require.NoError(t, err) require.NoError(t, err)
require.Len(t, solutions, 3) // 3 different urls require.Len(t, solutions, 4) // 4 different urls
for _, sol := range solutions { for _, sol := range solutions {
switch sol.ServerURL { switch sol.ServerURL {
case "url": case "url":
@ -4202,8 +4215,11 @@ func testAggregatedHostMDMAndMunki(t *testing.T, ds *Datastore) {
case "https://kandji.io": case "https://kandji.io":
assert.Equal(t, 2, sol.HostsCount) assert.Equal(t, 2, sol.HostsCount)
assert.Equal(t, fleet.WellKnownMDMKandji, sol.Name) assert.Equal(t, fleet.WellKnownMDMKandji, sol.Name)
case "https://fleetdm.com":
assert.Equal(t, 1, sol.HostsCount)
assert.Equal(t, fleet.WellKnownMDMFleet, sol.Name)
default: default:
require.Fail(t, "unknown MDM solutions URL: %s", sol.ServerURL) require.Fail(t, fmt.Sprintf("unknown MDM solutions URL: %s", sol.ServerURL))
} }
} }

View File

@ -44,6 +44,7 @@ type MDMEnrollStatus string
const ( const (
MDMEnrollStatusManual = MDMEnrollStatus("manual") MDMEnrollStatusManual = MDMEnrollStatus("manual")
MDMEnrollStatusAutomatic = MDMEnrollStatus("automatic") MDMEnrollStatusAutomatic = MDMEnrollStatus("automatic")
MDMEnrollStatusPending = MDMEnrollStatus("pending")
MDMEnrollStatusUnenrolled = MDMEnrollStatus("unenrolled") MDMEnrollStatusUnenrolled = MDMEnrollStatus("unenrolled")
) )
@ -407,6 +408,7 @@ var mdmNameFromServerURLChecks = map[string]string{
"airwatch": WellKnownMDMVMWare, "airwatch": WellKnownMDMVMWare,
"microsoft": WellKnownMDMIntune, "microsoft": WellKnownMDMIntune,
"simplemdm": WellKnownMDMSimpleMDM, "simplemdm": WellKnownMDMSimpleMDM,
"fleetdm": WellKnownMDMFleet,
} }
// MDMNameFromServerURL returns the MDM solution name corresponding to the // MDMNameFromServerURL returns the MDM solution name corresponding to the
@ -427,6 +429,8 @@ func (h *HostMDM) EnrollmentStatus() string {
return "Enrolled (manual)" return "Enrolled (manual)"
case h.Enrolled && h.InstalledFromDep: case h.Enrolled && h.InstalledFromDep:
return "Enrolled (automated)" return "Enrolled (automated)"
case !h.Enrolled && h.InstalledFromDep:
return "Pending"
default: default:
return "Unenrolled" return "Unenrolled"
} }
@ -493,6 +497,7 @@ type AggregatedMunkiIssue struct {
type AggregatedMDMStatus struct { type AggregatedMDMStatus struct {
EnrolledManualHostsCount int `json:"enrolled_manual_hosts_count" db:"enrolled_manual_hosts_count"` EnrolledManualHostsCount int `json:"enrolled_manual_hosts_count" db:"enrolled_manual_hosts_count"`
EnrolledAutomatedHostsCount int `json:"enrolled_automated_hosts_count" db:"enrolled_automated_hosts_count"` EnrolledAutomatedHostsCount int `json:"enrolled_automated_hosts_count" db:"enrolled_automated_hosts_count"`
PendingHostsCount int `json:"pending_hosts_count" db:"pending_hosts_count"`
UnenrolledHostsCount int `json:"unenrolled_hosts_count" db:"unenrolled_hosts_count"` UnenrolledHostsCount int `json:"unenrolled_hosts_count" db:"unenrolled_hosts_count"`
HostsCount int `json:"hosts_count" db:"hosts_count"` HostsCount int `json:"hosts_count" db:"hosts_count"`
} }

View File

@ -948,6 +948,15 @@ func (s *integrationTestSuite) TestHostsCount() {
`SELECT id FROM mobile_device_management_solutions WHERE name = ? AND server_url = ?`, fleet.WellKnownMDMSimpleMDM, "https://simplemdm.com") `SELECT id FROM mobile_device_management_solutions WHERE name = ? AND server_url = ?`, fleet.WellKnownMDMSimpleMDM, "https://simplemdm.com")
}) })
// set MDM information for another host installed from DEP and pending enrollment to Fleet MDM
pendingMDMHost, err := s.ds.NewHost(context.Background(), &fleet.Host{
Platform: "darwin",
HardwareSerial: "532141num832",
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))
s.DoJSON("GET", "/api/latest/fleet/hosts/count", nil, http.StatusOK, &resp, "mdm_id", fmt.Sprint(mdmID)) s.DoJSON("GET", "/api/latest/fleet/hosts/count", nil, http.StatusOK, &resp, "mdm_id", fmt.Sprint(mdmID))
require.Equal(t, 1, resp.Count) require.Equal(t, 1, resp.Count)
s.DoJSON("GET", "/api/latest/fleet/hosts/count", nil, http.StatusOK, &resp, "mdm_enrollment_status", "manual") s.DoJSON("GET", "/api/latest/fleet/hosts/count", nil, http.StatusOK, &resp, "mdm_enrollment_status", "manual")
@ -958,6 +967,8 @@ func (s *integrationTestSuite) TestHostsCount() {
require.Equal(t, 0, resp.Count) require.Equal(t, 0, resp.Count)
s.DoJSON("GET", "/api/latest/fleet/hosts/count", nil, http.StatusOK, &resp, "mdm_enrollment_status", "manual", "mdm_id", fmt.Sprint(mdmID)) s.DoJSON("GET", "/api/latest/fleet/hosts/count", nil, http.StatusOK, &resp, "mdm_enrollment_status", "manual", "mdm_id", fmt.Sprint(mdmID))
require.Equal(t, 1, resp.Count) require.Equal(t, 1, resp.Count)
s.DoJSON("GET", "/api/latest/fleet/hosts/count", nil, http.StatusOK, &resp, "mdm_enrollment_status", "pending")
require.Equal(t, 1, resp.Count)
} }
func (s *integrationTestSuite) TestPacks() { func (s *integrationTestSuite) TestPacks() {
@ -1134,9 +1145,36 @@ func (s *integrationTestSuite) TestListHosts() {
return sqlx.GetContext(context.Background(), q, &mdmID, return sqlx.GetContext(context.Background(), q, &mdmID,
`SELECT id FROM mobile_device_management_solutions WHERE name = ? AND server_url = ?`, fleet.WellKnownMDMSimpleMDM, "https://simplemdm.com") `SELECT id FROM mobile_device_management_solutions WHERE name = ? AND server_url = ?`, fleet.WellKnownMDMSimpleMDM, "https://simplemdm.com")
}) })
s.DoJSON("GET", "/api/latest/fleet/hosts", nil, http.StatusOK, &resp)
for _, h := range resp.Hosts {
fmt.Println("host", fmt.Sprintf("%+v", h.Host.HardwareSerial))
}
// set MDM information for another host installed from DEP and pending enrollment to Fleet MDM
pendingMDMHost, err := s.ds.NewHost(context.Background(), &fleet.Host{
Platform: "darwin",
HardwareSerial: "532141num832",
HardwareModel: "MacBook Pro",
})
require.NoError(t, err)
mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error {
_, err := q.ExecContext(context.Background(), "INSERT INTO mobile_device_management_solutions (name, server_url) VALUES ('https://fleetdm.com', 'Fleet')")
require.NoError(t, err)
return err
})
require.NoError(t, s.ds.SetOrUpdateMDMData(context.Background(), pendingMDMHost.ID, false, false, "https://fleetdm.com", true, fleet.WellKnownMDMFleet))
// generate aggregated stats // generate aggregated stats
require.NoError(t, s.ds.GenerateAggregatedMunkiAndMDM(context.Background())) require.NoError(t, s.ds.GenerateAggregatedMunkiAndMDM(context.Background()))
s.DoJSON("GET", "/api/latest/fleet/hosts", nil, http.StatusOK, &resp, "mdm_enrollment_status", "pending")
require.Len(t, resp.Hosts, 1)
require.Equal(t, "532141num832", resp.Hosts[0].HardwareSerial)
assert.Nil(t, resp.Software)
assert.Nil(t, resp.MunkiIssue)
require.Nil(t, resp.MDMSolution) // MDM solution is included only if `mdm_id` query param is specified`
resp = listHostsResponse{} resp = listHostsResponse{}
s.DoJSON("GET", "/api/latest/fleet/hosts", nil, http.StatusOK, &resp, "mdm_enrollment_status", "manual") s.DoJSON("GET", "/api/latest/fleet/hosts", nil, http.StatusOK, &resp, "mdm_enrollment_status", "manual")
require.Len(t, resp.Hosts, 1) require.Len(t, resp.Hosts, 1)

View File

@ -303,7 +303,7 @@ func hostListOptionsFromRequest(r *http.Request) (fleet.HostListOptions, error)
enrollmentStatus := r.URL.Query().Get("mdm_enrollment_status") enrollmentStatus := r.URL.Query().Get("mdm_enrollment_status")
switch fleet.MDMEnrollStatus(enrollmentStatus) { switch fleet.MDMEnrollStatus(enrollmentStatus) {
case fleet.MDMEnrollStatusManual, fleet.MDMEnrollStatusAutomatic, fleet.MDMEnrollStatusUnenrolled: case fleet.MDMEnrollStatusManual, fleet.MDMEnrollStatusAutomatic, fleet.MDMEnrollStatusPending, fleet.MDMEnrollStatusUnenrolled:
hopt.MDMEnrollmentStatusFilter = fleet.MDMEnrollStatus(enrollmentStatus) hopt.MDMEnrollmentStatusFilter = fleet.MDMEnrollStatus(enrollmentStatus)
case "": case "":
// No error when unset // No error when unset