update apple query for profile verification with include all/any + exclude (#47079)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Follow up PR for the Include Any/All + Exclude label
story, since this was missed.

# Checklist for submitter

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

- [ ] 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/guides/committing-changes.md#changes-files)
for more information.

- [x] Input data is properly validated, `SELECT *` is avoided, SQL
injection is prevented (using placeholders for values in statements), JS
inline code is prevented especially for url redirects, and untrusted
data interpolated into shell scripts/commands is validated against shell
metacharacters.
- [x] Timeouts are implemented and retries are limited to avoid infinite
loops
- [x] If paths of existing endpoints are modified without backwards
compatibility, checked the frontend/CLI for any necessary changes

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved Apple MDM profile verification to more accurately determine
expected configuration profiles, including correct handling of mixed
include/exclude label combinations and exclusion edge cases.

* **Tests**
* Updated unit and integration tests to reflect the expanded Apple
include+exclude scenarios and to run Apple-only profile reconciliation
flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Magnus Jensen
2026-06-08 17:24:23 +02:00
committed by GitHub
parent 408764c953
commit 6a84d3a489
3 changed files with 150 additions and 703 deletions
+126 -132
View File
@@ -1281,134 +1281,12 @@ func (ds *Datastore) GetHostMDMProfilesExpectedForVerification(ctx context.Conte
switch host.Platform {
case "darwin", "ios", "ipados":
return ds.getHostMDMAppleProfilesExpectedForVerification(ctx, teamID, host)
case "windows":
return ds.getHostMDMWindowsProfilesExpectedForVerification(ctx, teamID, host.ID)
default:
return nil, fmt.Errorf("unsupported platform: %s", host.Platform)
}
}
func (ds *Datastore) getHostMDMWindowsProfilesExpectedForVerification(ctx context.Context, teamID, hostID uint) (map[string]*fleet.ExpectedMDMProfile, error) {
stmt := `
-- profiles without labels
SELECT
mwcp.profile_uuid AS profile_uuid,
name,
syncml AS raw_profile,
min(mwcp.uploaded_at) AS earliest_install_date,
0 AS count_profile_labels,
0 AS count_non_broken_labels,
0 AS count_host_labels
FROM
mdm_windows_configuration_profiles mwcp
WHERE
mwcp.team_id = ? AND
NOT EXISTS (
SELECT
1
FROM
mdm_configuration_profile_labels mcpl
WHERE
mcpl.windows_profile_uuid = mwcp.profile_uuid
)
GROUP BY profile_uuid, name, syncml
UNION
-- label-based profiles where the host is a member of all the labels (include-all).
-- by design, "include" labels cannot match if they are broken (the host cannot be
-- a member of a deleted label).
SELECT
mwcp.profile_uuid AS profile_uuid,
name,
syncml AS raw_profile,
min(mwcp.uploaded_at) AS earliest_install_date,
COUNT(*) AS count_profile_labels,
COUNT(mcpl.label_id) as count_non_broken_labels,
COUNT(lm.label_id) AS count_host_labels
FROM
mdm_windows_configuration_profiles mwcp
JOIN mdm_configuration_profile_labels mcpl
ON mcpl.windows_profile_uuid = mwcp.profile_uuid AND mcpl.exclude = 0 AND mcpl.require_all = 1
LEFT OUTER JOIN label_membership lm
ON lm.label_id = mcpl.label_id AND lm.host_id = ?
WHERE
mwcp.team_id = ?
GROUP BY
profile_uuid, name, syncml
HAVING
count_profile_labels > 0 AND
count_host_labels = count_profile_labels
UNION
-- label-based entities where the host is NOT a member of any of the labels (exclude-any).
-- explicitly ignore profiles with broken excluded labels so that they are never applied.
SELECT
mwcp.profile_uuid AS profile_uuid,
name,
syncml AS raw_profile,
min(mwcp.uploaded_at) AS earliest_install_date,
COUNT(*) AS count_profile_labels,
COUNT(mcpl.label_id) as count_non_broken_labels,
COUNT(lm.label_id) AS count_host_labels
FROM
mdm_windows_configuration_profiles mwcp
JOIN mdm_configuration_profile_labels mcpl
ON mcpl.windows_profile_uuid = mwcp.profile_uuid AND mcpl.exclude = 1
LEFT OUTER JOIN label_membership lm
ON lm.label_id = mcpl.label_id AND lm.host_id = ?
WHERE
mwcp.team_id = ?
GROUP BY
profile_uuid, name, syncml
HAVING
-- considers only the profiles with labels, without any broken label, and with the host not in any label
count_profile_labels > 0 AND
count_profile_labels = count_non_broken_labels AND
count_host_labels = 0
UNION
-- label-based profiles where the host is a member of at least one of the labels (include-any)
SELECT
mwcp.profile_uuid AS profile_uuid,
name,
syncml AS raw_profile,
min(mwcp.uploaded_at) AS earliest_install_date,
COUNT(*) AS count_profile_labels,
COUNT(mcpl.label_id) as count_non_broken_labels,
COUNT(lm.label_id) AS count_host_labels
FROM
mdm_windows_configuration_profiles mwcp
JOIN mdm_configuration_profile_labels mcpl
ON mcpl.windows_profile_uuid = mwcp.profile_uuid AND mcpl.exclude = 0 AND mcpl.require_all = 0
LEFT OUTER JOIN label_membership lm
ON lm.label_id = mcpl.label_id AND lm.host_id = ?
WHERE
mwcp.team_id = ?
GROUP BY
profile_uuid, name, syncml
HAVING
count_profile_labels > 0 AND
count_host_labels > 0
`
var profiles []*fleet.ExpectedMDMProfile
err := sqlx.SelectContext(ctx, ds.reader(ctx), &profiles, stmt, teamID, hostID, teamID, hostID, teamID, hostID, teamID)
if err != nil {
return nil, ctxerr.Wrap(ctx, err, "running query for windows profiles")
}
byName := make(map[string]*fleet.ExpectedMDMProfile, len(profiles))
for _, r := range profiles {
byName[r.Name] = r
}
return byName, nil
}
func (ds *Datastore) getHostMDMAppleProfilesExpectedForVerification(ctx context.Context, teamID uint, host *fleet.Host) (map[string]*fleet.ExpectedMDMProfile, error) {
// TODO This will need to be updated to support scopes
stmt := `
-- profiles without labels
SELECT
@@ -1441,9 +1319,8 @@ WHERE
UNION
-- label-based profiles where the host is a member of all the labels (include-all)
-- by design, "include" labels cannot match if they are broken (the host cannot be
-- a member of a deleted label).
-- include-all only (no exclude labels): host must be a member of every include label.
-- broken include labels disqualify the profile.
SELECT
macp.profile_uuid AS profile_uuid,
macp.identifier AS identifier,
@@ -1466,7 +1343,11 @@ FROM
LEFT OUTER JOIN label_membership lm
ON lm.label_id = mcpl.label_id AND lm.host_id = ?
WHERE
macp.team_id = ?
macp.team_id = ? AND
NOT EXISTS (
SELECT 1 FROM mdm_configuration_profile_labels
WHERE apple_profile_uuid = macp.profile_uuid AND exclude = 1
)
GROUP BY
profile_uuid, identifier
HAVING
@@ -1475,8 +1356,8 @@ HAVING
UNION
-- label-based entities where the host is NOT a member of any of the labels (exclude-any).
-- explicitly ignore profiles with broken excluded labels so that they are never applied.
-- exclude-any only (no include labels): host must NOT be a member of any exclude label.
-- broken or not-yet-scanned dynamic exclude labels disqualify the profile.
SELECT
macp.profile_uuid AS profile_uuid,
macp.identifier AS identifier,
@@ -1499,7 +1380,11 @@ FROM
LEFT OUTER JOIN label_membership lm
ON lm.label_id = mcpl.label_id AND lm.host_id = ?
WHERE
macp.team_id = ?
macp.team_id = ? AND
NOT EXISTS (
SELECT 1 FROM mdm_configuration_profile_labels
WHERE apple_profile_uuid = macp.profile_uuid AND exclude = 0
)
GROUP BY
profile_uuid, identifier
HAVING
@@ -1510,7 +1395,8 @@ HAVING
UNION
-- label-based profiles where the host is a member of at least one of the labels (include-any)
-- include-any only (no exclude labels): host must be a member of at least one include label.
-- broken include labels are skipped (host can't be a member of a deleted label).
SELECT
macp.profile_uuid AS profile_uuid,
macp.identifier AS identifier,
@@ -1533,16 +1419,124 @@ FROM
LEFT OUTER JOIN label_membership lm
ON lm.label_id = mcpl.label_id AND lm.host_id = ?
WHERE
macp.team_id = ?
macp.team_id = ? AND
NOT EXISTS (
SELECT 1 FROM mdm_configuration_profile_labels
WHERE apple_profile_uuid = macp.profile_uuid AND exclude = 1
)
GROUP BY
profile_uuid, identifier
HAVING
count_profile_labels > 0 AND
count_host_labels > 0
UNION
-- include-all + exclude-any: host must be in ALL include labels AND NOT in ANY exclude label.
-- broken include labels or broken/not-yet-scanned dynamic exclude labels disqualify the profile.
SELECT
macp.profile_uuid AS profile_uuid,
macp.identifier AS identifier,
SUM(CASE WHEN mcpl.exclude = 0 THEN 1 ELSE 0 END) as count_profile_labels,
SUM(CASE WHEN mcpl.exclude = 0 AND mcpl.label_id IS NOT NULL THEN 1 ELSE 0 END) as count_non_broken_labels,
SUM(CASE WHEN mcpl.exclude = 0 AND lm_inc.label_id IS NOT NULL THEN 1 ELSE 0 END) as count_host_labels,
min(earliest_install_date) AS earliest_install_date
FROM
mdm_apple_configuration_profiles macp
JOIN (
SELECT
checksum,
min(uploaded_at) AS earliest_install_date
FROM
mdm_apple_configuration_profiles
GROUP BY checksum
) cs ON macp.checksum = cs.checksum
JOIN mdm_configuration_profile_labels mcpl
ON mcpl.apple_profile_uuid = macp.profile_uuid
JOIN hosts h
ON h.id = ?
LEFT OUTER JOIN labels lbl
ON lbl.id = mcpl.label_id
LEFT OUTER JOIN label_membership lm_inc
ON lm_inc.label_id = mcpl.label_id AND lm_inc.host_id = ? AND mcpl.exclude = 0
LEFT OUTER JOIN label_membership lm_exc
ON lm_exc.label_id = mcpl.label_id AND lm_exc.host_id = ? AND mcpl.exclude = 1
WHERE
macp.team_id = ? AND
EXISTS (
SELECT 1 FROM mdm_configuration_profile_labels
WHERE apple_profile_uuid = macp.profile_uuid AND exclude = 0 AND require_all = 1
) AND
EXISTS (
SELECT 1 FROM mdm_configuration_profile_labels
WHERE apple_profile_uuid = macp.profile_uuid AND exclude = 1
)
GROUP BY
profile_uuid, identifier
HAVING
-- include gate: host in all include labels (no broken include labels)
count_profile_labels > 0 AND count_non_broken_labels = count_profile_labels AND count_host_labels = count_profile_labels AND
-- exclude gate: host not in any exclude label, no broken/unscanned exclude labels (reusing count_host_updated_after_labels)
SUM(CASE WHEN mcpl.exclude = 1 AND lm_exc.label_id IS NOT NULL THEN 1
WHEN mcpl.exclude = 1 AND (lbl.label_membership_type = 0 AND lbl.created_at IS NOT NULL AND h.label_updated_at < lbl.created_at) THEN 1
WHEN mcpl.exclude = 1 AND mcpl.label_id IS NULL THEN 1
ELSE 0 END) = 0
UNION
-- include-any + exclude-any: host must be in AT LEAST ONE include label AND NOT in ANY exclude label.
-- broken/not-yet-scanned dynamic exclude labels disqualify the profile.
SELECT
macp.profile_uuid AS profile_uuid,
macp.identifier AS identifier,
SUM(CASE WHEN mcpl.exclude = 0 THEN 1 ELSE 0 END) as count_profile_labels,
SUM(CASE WHEN mcpl.exclude = 0 AND mcpl.label_id IS NOT NULL THEN 1 ELSE 0 END) as count_non_broken_labels,
SUM(CASE WHEN mcpl.exclude = 0 AND lm_inc.label_id IS NOT NULL THEN 1 ELSE 0 END) as count_host_labels,
min(earliest_install_date) AS earliest_install_date
FROM
mdm_apple_configuration_profiles macp
JOIN (
SELECT
checksum,
min(uploaded_at) AS earliest_install_date
FROM
mdm_apple_configuration_profiles
GROUP BY checksum
) cs ON macp.checksum = cs.checksum
JOIN mdm_configuration_profile_labels mcpl
ON mcpl.apple_profile_uuid = macp.profile_uuid
JOIN hosts h
ON h.id = ?
LEFT OUTER JOIN labels lbl
ON lbl.id = mcpl.label_id
LEFT OUTER JOIN label_membership lm_inc
ON lm_inc.label_id = mcpl.label_id AND lm_inc.host_id = ? AND mcpl.exclude = 0
LEFT OUTER JOIN label_membership lm_exc
ON lm_exc.label_id = mcpl.label_id AND lm_exc.host_id = ? AND mcpl.exclude = 1
WHERE
macp.team_id = ? AND
EXISTS (
SELECT 1 FROM mdm_configuration_profile_labels
WHERE apple_profile_uuid = macp.profile_uuid AND exclude = 0 AND require_all = 0
) AND
EXISTS (
SELECT 1 FROM mdm_configuration_profile_labels
WHERE apple_profile_uuid = macp.profile_uuid AND exclude = 1
)
GROUP BY
profile_uuid, identifier
HAVING
-- include gate: host in at least one include label
count_host_labels >= 1 AND
-- exclude gate: host not in any exclude label, no broken/unscanned exclude labels
SUM(CASE WHEN mcpl.exclude = 1 AND lm_exc.label_id IS NOT NULL THEN 1
WHEN mcpl.exclude = 1 AND (lbl.label_membership_type = 0 AND lbl.created_at IS NOT NULL AND h.label_updated_at < lbl.created_at) THEN 1
WHEN mcpl.exclude = 1 AND mcpl.label_id IS NULL THEN 1
ELSE 0 END) = 0
`
var rows []*fleet.ExpectedMDMProfile
if err := sqlx.SelectContext(ctx, ds.reader(ctx), &rows, stmt, teamID, host.ID, teamID, host.ID, teamID, host.ID, teamID); err != nil {
if err := sqlx.SelectContext(ctx, ds.reader(ctx), &rows, stmt, teamID, host.ID, teamID, host.ID, teamID, host.ID, teamID, host.ID, host.ID, host.ID, teamID, host.ID, host.ID, host.ID, teamID); err != nil {
return nil, ctxerr.Wrap(ctx, err, fmt.Sprintf("getting expected profiles for host in team %d", teamID))
}
+23 -486
View File
@@ -2560,6 +2560,16 @@ func testGetHostMDMProfilesExpectedForVerification(t *testing.T, ds *Datastore)
configProfileForTest(t, "exclude_one_matches_prof", "exclude_one_matches_prof", "p", excludeMatchedLabel1, excludeUnmatchedLabel),
// This profile will use an "exclude" rule where the host has none of the labels, thus should be included
configProfileForTest(t, "exclude_none_match_prof", "exclude_none_match_prof", "q", excludeUnmatchedLabel),
// This profile will use both an "include all" and "exclude" rule where the host matches the include all rule but also matches the exclude rule, thus should be excluded
configProfileForTest(t, "include_all_and_exclude_match_prof", "include_all_and_exclude_match_prof", "r", includeAllMatchedLabel1, includeAllMatchedLabel2, excludeMatchedLabel1),
// This profile will use both an "include all" and "exclude" rule where the host matches the include all rule but does not match the exclude rule, thus should be included
configProfileForTest(t, "include_all_and_exclude_none_match_prof", "include_all_and_exclude_none_match_prof", "s", includeAllMatchedLabel1, includeAllMatchedLabel2, excludeUnmatchedLabel),
// This profile will use both an "include any" and "exclude" rule where the host matches the include any rule but also matches the exclude rule, thus should be excluded
configProfileForTest(t, "include_any_and_exclude_match_prof", "include_any_and_exclude_match_prof", "t", includeAnyMatchedLabel1, includeAnyUnmatchedLabel, excludeMatchedLabel1),
// This profile will use both an "include any" and "exclude" rule where the host matches the include any rule but does not match the exclude rule, thus should be included
configProfileForTest(t, "include_any_and_exclude_none_match_prof", "include_any_and_exclude_none_match_prof", "u", includeAnyMatchedLabel1, includeAnyUnmatchedLabel, excludeUnmatchedLabel),
}
updates, err := ds.BatchSetMDMProfiles(ctx, &team.ID, profiles, nil, nil, nil, nil)
@@ -2593,432 +2603,16 @@ func testGetHostMDMProfilesExpectedForVerification(t *testing.T, ds *Datastore)
profs, _, err := ds.ListMDMConfigProfiles(ctx, &team.ID, fleet.ListOptions{})
require.NoError(t, err)
require.Len(t, profs, 11)
return team.ID, host
}
// ===================================================
// Windows
// ===================================================
windowsBasicTeamProfNoLabelsSetup := func() (uint, *fleet.Host) {
host, err := ds.NewHost(ctx, &fleet.Host{
Hostname: "windows-test",
OsqueryHostID: ptr.String("osquery-windows"),
NodeKey: ptr.String("node-key-windows"),
UUID: uuid.NewString(),
Platform: "windows",
})
require.NoError(t, err)
windowsEnroll(t, ds, host)
// create a team
team, err := ds.NewTeam(ctx, &fleet.Team{Name: "windows team 1"})
require.NoError(t, err)
err = ds.AddHostsToTeam(ctx, fleet.NewAddHostsToTeamParams(&team.ID, []uint{host.ID}))
require.NoError(t, err)
// create profiles for team 1
profiles := []*fleet.MDMWindowsConfigProfile{
windowsConfigProfileForTest(t, "T1.1", "T1.1"),
windowsConfigProfileForTest(t, "T1.2", "T1.2"),
}
updates, err := ds.BatchSetMDMProfiles(ctx, &team.ID, nil, profiles, nil, nil, nil)
require.NoError(t, err)
assert.False(t, updates.AppleConfigProfile)
assert.True(t, updates.WindowsConfigProfile)
assert.False(t, updates.AppleDeclaration)
profs, _, err := ds.ListMDMConfigProfiles(ctx, &team.ID, fleet.ListOptions{})
require.NoError(t, err)
require.Len(t, profs, 2)
return team.ID, host
}
windowsLabeledTeamProfSetup := func() (uint, *fleet.Host) {
host, err := ds.NewHost(ctx, &fleet.Host{
Hostname: "windows-test-2",
OsqueryHostID: ptr.String("osquery-windows-2"),
NodeKey: ptr.String("node-key-windows-2"),
UUID: uuid.NewString(),
Platform: "windows",
})
require.NoError(t, err)
windowsEnroll(t, ds, host)
// create a team
team, err := ds.NewTeam(ctx, &fleet.Team{Name: "windows team 2"})
require.NoError(t, err)
err = ds.AddHostsToTeam(ctx, fleet.NewAddHostsToTeamParams(&team.ID, []uint{host.ID}))
require.NoError(t, err)
// create profiles for team 1
profiles := []*fleet.MDMWindowsConfigProfile{
windowsConfigProfileForTest(t, "T2.1", "T2.1"),
windowsConfigProfileForTest(t, "T2.2", "T2.2"),
windowsConfigProfileForTest(t, "labeled_prof", "labeled_prof"),
}
label, err := ds.NewLabel(ctx, &fleet.Label{Name: "test_label_6"})
require.NoError(t, err)
updates, err := ds.BatchSetMDMProfiles(ctx, &team.ID, nil, profiles, nil, nil, nil)
require.NoError(t, err)
assert.False(t, updates.AppleConfigProfile)
assert.True(t, updates.WindowsConfigProfile)
assert.False(t, updates.AppleDeclaration)
var uid string
ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error {
return sqlx.GetContext(
ctx,
q,
&uid,
`SELECT profile_uuid FROM mdm_windows_configuration_profiles WHERE name = ?`,
"labeled_prof",
)
})
// Update label with host membership
ExecAdhocSQL(
t, ds, func(db sqlx.ExtContext) error {
_, err := db.ExecContext(
context.Background(),
"INSERT IGNORE INTO label_membership (host_id, label_id) VALUES (?, ?)",
host.ID,
label.ID,
)
return err
},
)
// Update profile <-> label mapping
ExecAdhocSQL(
t, ds, func(db sqlx.ExtContext) error {
_, err := db.ExecContext(
context.Background(),
"INSERT INTO mdm_configuration_profile_labels (windows_profile_uuid, label_name, label_id) VALUES (?, ?, ?)",
uid,
label.Name,
label.ID,
)
return err
},
)
profs, _, err := ds.ListMDMConfigProfiles(ctx, &team.ID, fleet.ListOptions{})
require.NoError(t, err)
require.Len(t, profs, 3)
return team.ID, host
}
windowsLabeledTeamProfWithAdditionalLabeledProfSetup := func() (uint, *fleet.Host) {
host, err := ds.NewHost(ctx, &fleet.Host{
Hostname: "windows-test-3",
OsqueryHostID: ptr.String("osquery-windows-3"),
NodeKey: ptr.String("node-key-windows-3"),
UUID: uuid.NewString(),
Platform: "windows",
})
require.NoError(t, err)
windowsEnroll(t, ds, host)
// create a team
team, err := ds.NewTeam(ctx, &fleet.Team{Name: "windows team 3"})
require.NoError(t, err)
err = ds.AddHostsToTeam(ctx, fleet.NewAddHostsToTeamParams(&team.ID, []uint{host.ID}))
require.NoError(t, err)
// create profiles for team 1
profiles := []*fleet.MDMWindowsConfigProfile{
windowsConfigProfileForTest(t, "T3.1", "T3.1"),
windowsConfigProfileForTest(t, "T3.2", "T3.7"),
windowsConfigProfileForTest(t, "labeled_prof_2", "labeled_prof_2"),
}
testLabel2, err := ds.NewLabel(ctx, &fleet.Label{Name: uuid.NewString()})
require.NoError(t, err)
testLabel3, err := ds.NewLabel(ctx, &fleet.Label{Name: uuid.NewString()})
require.NoError(t, err)
updates, err := ds.BatchSetMDMProfiles(ctx, &team.ID, nil, profiles, nil, nil, nil)
require.NoError(t, err)
assert.False(t, updates.AppleConfigProfile)
assert.True(t, updates.WindowsConfigProfile)
assert.False(t, updates.AppleDeclaration)
var uid string
ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error {
return sqlx.GetContext(
ctx,
q,
&uid,
`SELECT profile_uuid FROM mdm_windows_configuration_profiles WHERE name = ?`,
"labeled_prof_2",
)
})
// Update label with host membership
ExecAdhocSQL(
t, ds, func(db sqlx.ExtContext) error {
_, err := db.ExecContext(
context.Background(),
"INSERT IGNORE INTO label_membership (host_id, label_id) VALUES (?, ?)",
host.ID,
testLabel2.ID,
)
return err
},
)
// Update profile <-> label mapping
ExecAdhocSQL(
t, ds, func(db sqlx.ExtContext) error {
_, err := db.ExecContext(
context.Background(),
"INSERT INTO mdm_configuration_profile_labels (windows_profile_uuid, label_name, label_id) VALUES (?, ?, ?)",
uid,
testLabel2.Name,
testLabel2.ID,
)
return err
},
)
// Also add mapping to test label 3
ExecAdhocSQL(
t, ds, func(db sqlx.ExtContext) error {
_, err := db.ExecContext(
context.Background(),
"INSERT INTO mdm_configuration_profile_labels (windows_profile_uuid, label_name, label_id) VALUES (?, ?, ?)",
uid,
testLabel3.Name,
testLabel3.ID,
)
return err
},
)
profs, _, err := ds.ListMDMConfigProfiles(ctx, &team.ID, fleet.ListOptions{})
require.NoError(t, err)
require.Len(t, profs, 3)
return team.ID, host
}
windowsProfWithBrokenLabelSetup := func() (uint, *fleet.Host) {
host, err := ds.NewHost(ctx, &fleet.Host{
Hostname: "windows-test-4",
OsqueryHostID: ptr.String("osquery-windows-4"),
NodeKey: ptr.String("node-key-windows-4"),
UUID: uuid.NewString(),
Platform: "windows",
})
require.NoError(t, err)
windowsEnroll(t, ds, host)
// create a team
team, err := ds.NewTeam(ctx, &fleet.Team{Name: "windows team 4"})
require.NoError(t, err)
err = ds.AddHostsToTeam(ctx, fleet.NewAddHostsToTeamParams(&team.ID, []uint{host.ID}))
require.NoError(t, err)
// create profiles for team
profiles := []*fleet.MDMWindowsConfigProfile{
windowsConfigProfileForTest(t, "T4.1", "T4.1"),
windowsConfigProfileForTest(t, "T4.2", "T4.2"),
windowsConfigProfileForTest(t, "broken_label_prof", "broken_label_prof"),
}
label, err := ds.NewLabel(ctx, &fleet.Label{Name: uuid.NewString()})
require.NoError(t, err)
updates, err := ds.BatchSetMDMProfiles(ctx, &team.ID, nil, profiles, nil, nil, nil)
require.NoError(t, err)
assert.False(t, updates.AppleConfigProfile)
assert.True(t, updates.WindowsConfigProfile)
assert.False(t, updates.AppleDeclaration)
var uid string
ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error {
return sqlx.GetContext(
ctx,
q,
&uid,
`SELECT profile_uuid FROM mdm_windows_configuration_profiles WHERE name = ?`,
"broken_label_prof",
)
})
// Update label with host membership
ExecAdhocSQL(
t, ds, func(db sqlx.ExtContext) error {
_, err := db.ExecContext(
context.Background(),
"INSERT IGNORE INTO label_membership (host_id, label_id) VALUES (?, ?)",
host.ID,
label.ID,
)
return err
},
)
// Update profile <-> label mapping
ExecAdhocSQL(
t, ds, func(db sqlx.ExtContext) error {
_, err := db.ExecContext(
context.Background(),
"INSERT INTO mdm_configuration_profile_labels (windows_profile_uuid, label_name, label_id) VALUES (?, ?, ?)",
uid,
label.Name,
label.ID,
)
return err
},
)
profs, _, err := ds.ListMDMConfigProfiles(ctx, &team.ID, fleet.ListOptions{})
require.NoError(t, err)
require.Len(t, profs, 3)
// Simulate the label being broken — direct DeleteLabel is now blocked when
// referenced by a profile, so we nullify label_id in the join tables instead.
ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error {
if _, err := q.ExecContext(ctx, `UPDATE mdm_configuration_profile_labels SET label_id = NULL WHERE label_id = ?`, label.ID); err != nil {
return err
}
_, err := q.ExecContext(ctx, `UPDATE mdm_declaration_labels SET label_id = NULL WHERE label_id = ?`, label.ID)
return err
})
return team.ID, host
}
windowsLabeledProfileRulesSetup := func() (uint, *fleet.Host) {
host, err := ds.NewHost(ctx, &fleet.Host{
Hostname: "windows-test-5",
OsqueryHostID: ptr.String("osquery-windows-5"),
NodeKey: ptr.String("node-key-windows-5"),
UUID: uuid.NewString(),
Platform: "windows",
})
require.NoError(t, err)
windowsEnroll(t, ds, host)
// create a team
team, err := ds.NewTeam(ctx, &fleet.Team{Name: "windows team 5"})
require.NoError(t, err)
err = ds.AddHostsToTeam(ctx, fleet.NewAddHostsToTeamParams(&team.ID, []uint{host.ID}))
require.NoError(t, err)
// Include any labels
includeAnyMatchedLabel1, err := ds.NewLabel(ctx, &fleet.Label{Name: "include-any-windows-matched-label-1"})
require.NoError(t, err)
includeAnyMatchedLabel2, err := ds.NewLabel(ctx, &fleet.Label{Name: "include-any-windows-matched-label-2"})
require.NoError(t, err)
includeAnyUnmatchedLabel, err := ds.NewLabel(ctx, &fleet.Label{Name: "include-any-windows-unmatched-label"})
require.NoError(t, err)
// Include all labels
includeAllMatchedLabel1, err := ds.NewLabel(ctx, &fleet.Label{Name: "include-all-windows-matched-label-1"})
require.NoError(t, err)
includeAllMatchedLabel2, err := ds.NewLabel(ctx, &fleet.Label{Name: "include-all-windows-matched-label-2"})
require.NoError(t, err)
includeAllUnmatchedLabel, err := ds.NewLabel(ctx, &fleet.Label{Name: "include-all-windows-unmatched-label"})
require.NoError(t, err)
// Exclude labels
excludeMatchedLabel1, err := ds.NewLabel(ctx, &fleet.Label{Name: "exclude-windows-matched-label-1"})
require.NoError(t, err)
excludeMatchedLabel2, err := ds.NewLabel(ctx, &fleet.Label{Name: "exclude-windows-matched-label-2"})
require.NoError(t, err)
excludeUnmatchedLabel, err := ds.NewLabel(ctx, &fleet.Label{Name: "exclude-windows-unmatched-label"})
require.NoError(t, err)
// create profiles for team
// include_any_all_match_prof
// include_any_one_matches_prof
// include_all_all_match_prof
// exclude_none_match_prof
profiles := []*fleet.MDMWindowsConfigProfile{
// Two profiles with no label rules, thus should always be included
windowsConfigProfileForTest(t, "T5.1", "T5.1"),
windowsConfigProfileForTest(t, "T5.2", "T5.2"),
// This profile will use an "include any" rule where the host has both of the labels, thus should be included
windowsConfigProfileForTest(t, "include_any_all_match_prof", "include_any_all_match_prof", includeAnyMatchedLabel1, includeAnyMatchedLabel2),
// This profile will use an "include any" rule where the host has one of the labels, thus should be included
windowsConfigProfileForTest(t, "include_any_one_matches_prof", "include_any_one_matches_prof", includeAnyMatchedLabel1, includeAnyUnmatchedLabel),
// This profile will use an "include any" rule where the host has none of the labels, thus should be excluded
windowsConfigProfileForTest(t, "include_any_none_match_prof", "include_any_none_match_prof", includeAnyUnmatchedLabel),
// This profile will use an "include all" rule where the host has all of the labels and thus should be included
windowsConfigProfileForTest(t, "include_all_all_match_prof", "include_all_all_match_prof", includeAllMatchedLabel1, includeAllMatchedLabel2),
// This profile will use an "include all" rule where the host has one of the labels and thus should be excluded
windowsConfigProfileForTest(t, "include_all_one_matches_prof", "include_all_one_matches_prof", includeAllMatchedLabel1, includeAllUnmatchedLabel),
// This profile will use an "include any" rule where the host has none of the labels and thus should be excluded
windowsConfigProfileForTest(t, "include_all_none_match_prof", "include_all_none_match_prof", includeAllUnmatchedLabel),
// This profile will use an "exclude" rule where the host has both of the labels, thus should be excluded
windowsConfigProfileForTest(t, "exclude_all_match_prof", "exclude_all_match_prof", excludeMatchedLabel1, excludeMatchedLabel2),
// This profile will use an "exclude" rule where the host has one of the labels, thus should be excluded
windowsConfigProfileForTest(t, "exclude_one_matches_prof", "exclude_one_matches_prof", excludeMatchedLabel1, excludeUnmatchedLabel),
// This profile will use an "exclude" rule where the host has none of the labels, thus should be included
windowsConfigProfileForTest(t, "exclude_none_match_prof", "exclude_none_match_prof", excludeUnmatchedLabel),
}
updates, err := ds.BatchSetMDMProfiles(ctx, &team.ID, nil, profiles, nil, nil, nil)
require.NoError(t, err)
assert.False(t, updates.AppleConfigProfile)
assert.True(t, updates.WindowsConfigProfile)
assert.False(t, updates.AppleDeclaration)
// Update labels with host membership
ExecAdhocSQL(
t, ds, func(db sqlx.ExtContext) error {
_, err := db.ExecContext(
context.Background(),
"INSERT IGNORE INTO label_membership (host_id, label_id) VALUES (?, ?), (?, ?), (?, ?), (?, ?), (?, ?), (?, ?)",
host.ID,
includeAnyMatchedLabel1.ID,
host.ID,
includeAnyMatchedLabel2.ID,
host.ID,
includeAllMatchedLabel1.ID,
host.ID,
includeAllMatchedLabel2.ID,
host.ID,
excludeMatchedLabel1.ID,
host.ID,
excludeMatchedLabel2.ID,
)
return err
},
)
profs, _, err := ds.ListMDMConfigProfiles(ctx, &team.ID, fleet.ListOptions{})
require.NoError(t, err)
require.Len(t, profs, 11)
require.Len(t, profs, 15)
return team.ID, host
}
tests := []struct {
name string
setupFunc func() (uint, *fleet.Host)
wantMac map[string]*fleet.ExpectedMDMProfile
wantWindows map[string]*fleet.ExpectedMDMProfile
os string
name string
setupFunc func() (uint, *fleet.Host)
wantMac map[string]*fleet.ExpectedMDMProfile
os string
}{
{
name: "macos basic team profiles no labels",
@@ -3070,61 +2664,14 @@ func testGetHostMDMProfilesExpectedForVerification(t *testing.T, ds *Datastore)
name: "macos labels include any/all and exclude rules",
setupFunc: macosLabeledProfileRulesSetup,
wantMac: map[string]*fleet.ExpectedMDMProfile{
"T6.1": {Identifier: "T6.1"},
"T6.2": {Identifier: "T6.2"},
"include_any_all_match_prof": {Identifier: "include_any_all_match_prof"},
"include_any_one_matches_prof": {Identifier: "include_any_one_matches_prof"},
"include_all_all_match_prof": {Identifier: "include_all_all_match_prof"},
"exclude_none_match_prof": {Identifier: "exclude_none_match_prof"},
},
},
{
name: "windows basic team profiles no labels",
setupFunc: windowsBasicTeamProfNoLabelsSetup,
wantWindows: map[string]*fleet.ExpectedMDMProfile{
"T1.1": {Name: "T1.1"},
"T1.2": {Name: "T1.2"},
},
},
{
name: "windows labeled team profile",
setupFunc: windowsLabeledTeamProfSetup,
wantWindows: map[string]*fleet.ExpectedMDMProfile{
"T2.1": {Name: "T2.1"},
"T2.2": {Name: "T2.2"},
"labeled_prof": {Name: "labeled_prof"},
},
},
{
name: "windows labeled team profile with additional labeled profile",
setupFunc: windowsLabeledTeamProfWithAdditionalLabeledProfSetup,
// Our expected profiles should not include the labeled profile, because it
// maps to a label that is not applied to the host.
wantWindows: map[string]*fleet.ExpectedMDMProfile{
"T3.1": {Name: "T3.1"},
"T3.2": {Name: "T3.2"},
},
},
{
name: "windows profile with broken label",
setupFunc: windowsProfWithBrokenLabelSetup,
// Our expected profiles should not include the labeled profile, because it is broken
// (the label was deleted)
wantWindows: map[string]*fleet.ExpectedMDMProfile{
"T4.1": {Name: "T4.1"},
"T4.2": {Name: "T4.2"},
},
},
{
name: "windows labels include any/all and exclude rules",
setupFunc: windowsLabeledProfileRulesSetup,
wantWindows: map[string]*fleet.ExpectedMDMProfile{
"T5.1": {Name: "T5.1"},
"T5.2": {Name: "T5.2"},
"include_any_all_match_prof": {Name: "include_any_all_match_prof"},
"include_any_one_matches_prof": {Name: "include_any_one_matches_prof"},
"include_all_all_match_prof": {Name: "include_all_all_match_prof"},
"exclude_none_match_prof": {Name: "exclude_none_match_prof"},
"T6.1": {Identifier: "T6.1"},
"T6.2": {Identifier: "T6.2"},
"include_any_all_match_prof": {Identifier: "include_any_all_match_prof"},
"include_any_one_matches_prof": {Identifier: "include_any_one_matches_prof"},
"include_all_all_match_prof": {Identifier: "include_all_all_match_prof"},
"exclude_none_match_prof": {Identifier: "exclude_none_match_prof"},
"include_all_and_exclude_none_match_prof": {Identifier: "include_all_and_exclude_none_match_prof"},
"include_any_and_exclude_none_match_prof": {Identifier: "include_any_and_exclude_none_match_prof"},
},
},
}
@@ -3144,16 +2691,6 @@ func testGetHostMDMProfilesExpectedForVerification(t *testing.T, ds *Datastore)
}
}
}
if len(tt.wantWindows) > 0 {
got, err := ds.getHostMDMWindowsProfilesExpectedForVerification(ctx, teamID, host.ID)
require.NoError(t, err)
for k, v := range tt.wantWindows {
require.Contains(t, got, k)
require.Equal(t, v.Name, got[k].Name)
// windows does not currently use or care about earliest install date
}
}
})
}
}
@@ -6132,9 +6132,6 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
if _, err := q.ExecContext(ctx, `UPDATE host_mdm_apple_declarations SET status = ? WHERE status = ?`, fleet.OSSettingsVerifying, fleet.OSSettingsPending); err != nil {
return err
}
if _, err := q.ExecContext(ctx, `UPDATE host_mdm_windows_profiles SET status = ? WHERE status = ?`, fleet.OSSettingsVerifying, fleet.OSSettingsPending); err != nil {
return err
}
return nil
})
}
@@ -6152,7 +6149,6 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
// create an Apple and a Windows host
appleHost, _ := createHostThenEnrollMDM(s.ds, s.server.URL, t)
windowsHost, _ := createWindowsHostThenEnrollMDM(s.ds, s.server.URL, t)
// create a few labels
labels := make([]*fleet.Label, 5)
@@ -6163,16 +6159,12 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
}
// simulate reporting label results for those hosts
appleHost.LabelUpdatedAt = time.Now()
windowsHost.LabelUpdatedAt = time.Now()
err := s.ds.UpdateHost(ctx, appleHost)
require.NoError(t, err)
err = s.ds.UpdateHost(ctx, windowsHost)
require.NoError(t, err)
// set an Apple profile and declaration and a Windows profile
s.Do("POST", "/api/v1/fleet/mdm/profiles/batch", batchSetMDMProfilesRequest{Profiles: []fleet.MDMProfileBatchPayload{
{Name: "A1", Contents: mobileconfigForTest("A1", "A1"), LabelsExcludeAny: []string{labels[0].Name, labels[1].Name}},
{Name: "W2", Contents: syncMLForTest("./Foo/W2"), LabelsExcludeAny: []string{labels[2].Name, labels[3].Name}},
{Name: "D3", Contents: declarationForTest("D3"), LabelsExcludeAny: []string{labels[4].Name}},
}}, http.StatusNoContent)
@@ -6188,11 +6180,6 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryPending},
},
})
s.assertHostWindowsConfigProfiles(map[*fleet.Host][]fleet.HostMDMWindowsProfile{
windowsHost: {
{Name: "W2", OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryPending},
},
})
err = s.keyValueStore.Delete(ctx, fleet.MDMProfileProcessingKeyPrefix+":"+appleHost.UUID)
require.NoError(t, err)
@@ -6207,21 +6194,12 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerifying},
},
})
s.assertHostWindowsConfigProfiles(map[*fleet.Host][]fleet.HostMDMWindowsProfile{
windowsHost: {
{Name: "W2", OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerifying},
},
})
// mark some profiles as verified (despite accepting a HostMacOSProfile struct, it supports Windows too)
err = apple_mdm.VerifyHostMDMProfiles(ctx, s.ds, appleHost, map[string]*fleet.HostMacOSProfile{
"A1": {Identifier: "A1", DisplayName: "A1", InstallDate: time.Now()},
})
require.NoError(t, err)
err = apple_mdm.VerifyHostMDMProfiles(ctx, s.ds, windowsHost, map[string]*fleet.HostMacOSProfile{
"W2": {Identifier: "W2", DisplayName: "W2", InstallDate: time.Now()},
})
require.NoError(t, err)
s.assertHostAppleConfigProfiles(map[*fleet.Host][]fleet.HostMDMAppleProfile{
appleHost: {
@@ -6231,11 +6209,6 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerifying},
},
})
s.assertHostWindowsConfigProfiles(map[*fleet.Host][]fleet.HostMDMWindowsProfile{
windowsHost: {
{Name: "W2", OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerified},
},
})
// make hosts members of labels [1], [2], [3] and [4], meaning that none of the profiles apply anymore
err = s.ds.AsyncBatchInsertLabelMembership(ctx, [][2]uint{
@@ -6243,10 +6216,6 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{labels[2].ID, appleHost.ID},
{labels[3].ID, appleHost.ID},
{labels[4].ID, appleHost.ID},
{labels[1].ID, windowsHost.ID},
{labels[2].ID, windowsHost.ID},
{labels[3].ID, windowsHost.ID},
{labels[4].ID, windowsHost.ID},
})
require.NoError(t, err)
@@ -6259,19 +6228,12 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerifying},
},
})
// windows profiles now get marked for removal with a pending delete command
s.assertHostWindowsConfigProfiles(map[*fleet.Host][]fleet.HostMDMWindowsProfile{
windowsHost: {
{Name: "W2", OperationType: fleet.MDMOperationTypeRemove, Status: &fleet.MDMDeliveryPending},
},
})
// remove membership of labels [2] for Windows, and [4] for Apple, meaning
// remove membership of [4] for Apple, meaning
// that only D3 will be installed on Apple (as the Windows host is still
// member of an excluded label)
err = s.ds.AsyncBatchDeleteLabelMembership(ctx, [][2]uint{
{labels[4].ID, appleHost.ID},
{labels[2].ID, windowsHost.ID},
})
require.NoError(t, err)
@@ -6284,11 +6246,6 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerifying},
},
})
s.assertHostWindowsConfigProfiles(map[*fleet.Host][]fleet.HostMDMWindowsProfile{
windowsHost: {
{Name: "W2", OperationType: fleet.MDMOperationTypeRemove, Status: &fleet.MDMDeliveryPending},
},
})
// remove label [3] as an excluded label for the Windows profile, meaning
// that the host now meets the requirement to install.
@@ -6307,22 +6264,9 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerifying},
},
})
// The batch set above removed label [3] as an exclude label for W2, so the
// host now meets the requirement and W2 is re-installed (the install query
// detects profiles in desired state with operation_type='remove' and flips
// them back to install).
s.assertHostWindowsConfigProfiles(map[*fleet.Host][]fleet.HostMDMWindowsProfile{
windowsHost: {
{Name: "W2", OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryPending},
},
})
// simulate the reconcile profiles deployment and mark as verified
triggerReconcileProfiles()
err = apple_mdm.VerifyHostMDMProfiles(ctx, s.ds, windowsHost, map[string]*fleet.HostMacOSProfile{
"W2": {Identifier: "W2", DisplayName: "W2", InstallDate: time.Now()},
})
require.NoError(t, err)
s.assertHostAppleConfigProfiles(map[*fleet.Host][]fleet.HostMDMAppleProfile{
appleHost: {
@@ -6331,13 +6275,6 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerifying},
},
})
// W2 was re-installed (flipped from remove to install) and is now
// install+pending after the reconciler sent the command.
s.assertHostWindowsConfigProfiles(map[*fleet.Host][]fleet.HostMDMWindowsProfile{
windowsHost: {
{Name: "W2", OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerified},
},
})
// simulate the A1 profile being broken by nullifying labels[1] in the join table
// (direct DeleteLabel is now blocked when a label is referenced by a profile)
@@ -6355,12 +6292,6 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerifying},
},
})
// W2 is still install+pending from the re-install triggered earlier.
s.assertHostWindowsConfigProfiles(map[*fleet.Host][]fleet.HostMDMWindowsProfile{
windowsHost: {
{Name: "W2", OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerified},
},
})
// it also doesn't get installed to a new host not a member of any labels
appleHost2, _ := createHostThenEnrollMDM(s.ds, s.server.URL, t)
@@ -6380,18 +6311,10 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerifying},
},
})
s.assertHostWindowsConfigProfiles(map[*fleet.Host][]fleet.HostMDMWindowsProfile{
windowsHost: {
{Name: "W2", OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerified},
},
})
// simulate D3 and W2 profiles being broken by nullifying labels[2] and [4]
// in the join table (DeleteLabel is now blocked when referenced by a profile).
mysqltest.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error {
if _, err := q.ExecContext(ctx, `UPDATE mdm_configuration_profile_labels SET label_id = NULL WHERE label_id = ?`, labels[2].ID); err != nil {
return err
}
_, err := q.ExecContext(ctx, `UPDATE mdm_configuration_profile_labels SET label_id = NULL WHERE label_id = ?`, labels[4].ID)
return err
})
@@ -6409,13 +6332,6 @@ func (s *integrationMDMTestSuite) TestHostMDMProfilesExcludeLabels() {
{Identifier: mobileconfig.FleetCARootConfigPayloadIdentifier, OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerifying},
},
})
// W2 references a deleted label, so the reconciler skips it entirely
// (it appears in neither the install nor the remove list).
s.assertHostWindowsConfigProfiles(map[*fleet.Host][]fleet.HostMDMWindowsProfile{
windowsHost: {
{Name: "W2", OperationType: fleet.MDMOperationTypeInstall, Status: &fleet.MDMDeliveryVerified},
},
})
}
func (s *integrationMDMTestSuite) TestMDMProfilesIncludeAnyLabels() {