don't allow manual_agent_install without bootstrap package (#40812)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #38432

# Checklist for submitter

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

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

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
This commit is contained in:
Magnus Jensen
2026-03-02 15:25:46 -05:00
committed by GitHub
parent 22d5498f2e
commit 861d0ee122
9 changed files with 103 additions and 14 deletions
@@ -693,9 +693,21 @@ func (s *enterpriseIntegrationGitopsTestSuite) TestMacOSSetupDeprecated() {
ctx := context.Background()
originalAppConfig, err := s.DS.AppConfig(ctx)
require.NoError(t, err)
t.Cleanup(func() {
err := s.DS.SaveAppConfig(ctx, originalAppConfig)
require.NoError(t, err)
})
user := s.createGitOpsUser(t)
fleetctlConfig := s.createFleetctlConfig(t, user)
bootstrapServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "testdata/signed.pkg")
}))
defer bootstrapServer.Close()
const (
globalConfig = `
agent_options:
@@ -713,6 +725,7 @@ queries:
agent_options:
controls:
macos_setup:
bootstrap_package: %s
manual_agent_install: %t
org_settings:
server_settings:
@@ -727,6 +740,7 @@ queries:
noTeamConfig = `name: No team
controls:
macos_setup:
bootstrap_package: %s
manual_agent_install: true
policies:
software:
@@ -735,6 +749,7 @@ software:
teamConfig = `
controls:
macos_setup:
bootstrap_package: %s
manual_agent_install: %t
software:
queries:
@@ -755,7 +770,7 @@ team_settings:
noTeamFile, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = noTeamFile.WriteString(noTeamConfig)
_, err = noTeamFile.WriteString(fmt.Sprintf(noTeamConfig, bootstrapServer.URL))
require.NoError(t, err)
err = noTeamFile.Close()
require.NoError(t, err)
@@ -766,26 +781,26 @@ team_settings:
teamName := uuid.NewString()
teamFile, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = teamFile.WriteString(fmt.Sprintf(teamConfig, true, teamName))
_, err = teamFile.WriteString(fmt.Sprintf(teamConfig, bootstrapServer.URL, true, teamName))
require.NoError(t, err)
err = teamFile.Close()
require.NoError(t, err)
teamFileClear, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = teamFileClear.WriteString(fmt.Sprintf(teamConfig, false, teamName))
_, err = teamFileClear.WriteString(fmt.Sprintf(teamConfig, bootstrapServer.URL, false, teamName))
require.NoError(t, err)
err = teamFileClear.Close()
require.NoError(t, err)
globalFileOnlySet, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = globalFileOnlySet.WriteString(fmt.Sprintf(globalConfigOnly, true))
_, err = globalFileOnlySet.WriteString(fmt.Sprintf(globalConfigOnly, bootstrapServer.URL, true))
require.NoError(t, err)
err = globalFileOnlySet.Close()
require.NoError(t, err)
globalFileOnlyClear, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = globalFileOnlyClear.WriteString(fmt.Sprintf(globalConfigOnly, false))
_, err = globalFileOnlyClear.WriteString(fmt.Sprintf(globalConfigOnly, bootstrapServer.URL, false))
require.NoError(t, err)
err = globalFileOnlyClear.Close()
require.NoError(t, err)
@@ -344,7 +344,7 @@ settings:
// Check that all the teams exist
teamsJSON := fleetctl.RunAppForTest(t, []string{"get", "teams", "--config", fleetctlConfig.Name(), "--json"})
assert.Equal(t, 12, strings.Count(teamsJSON, "fleet_id"))
assert.Equal(t, 6, strings.Count(teamsJSON, "fleet_id"))
// Real run with all the files, and delete other teams
args = []string{"gitops", "--config", fleetctlConfig.Name(), "--delete-other-teams", "-f", globalFile}
@@ -355,7 +355,7 @@ settings:
// Check that only the right teams exist
teamsJSON = fleetctl.RunAppForTest(t, []string{"get", "teams", "--config", fleetctlConfig.Name(), "--json"})
assert.Equal(t, 10, strings.Count(teamsJSON, "fleet_id"))
assert.Equal(t, 4, strings.Count(teamsJSON, "fleet_id"))
assert.NotContains(t, teamsJSON, deletedTeamName)
// Real run with one file at a time
@@ -1472,9 +1472,21 @@ func (s *enterpriseIntegrationGitopsTestSuite) TestMacOSSetup() {
t := s.T()
ctx := context.Background()
originalAppConfig, err := s.DS.AppConfig(ctx)
require.NoError(t, err)
t.Cleanup(func() {
err := s.DS.SaveAppConfig(ctx, originalAppConfig)
require.NoError(t, err)
})
user := s.createGitOpsUser(t)
fleetctlConfig := s.createFleetctlConfig(t, user)
bootstrapServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "testdata/signed.pkg")
}))
defer bootstrapServer.Close()
const (
globalConfig = `
agent_options:
@@ -1492,6 +1504,7 @@ reports:
agent_options:
controls:
macos_setup:
bootstrap_package: %s
manual_agent_install: %t
org_settings:
server_settings:
@@ -1506,6 +1519,7 @@ reports:
noTeamConfig = `name: No team
controls:
macos_setup:
bootstrap_package: %s
manual_agent_install: true
policies:
software:
@@ -1514,6 +1528,7 @@ software:
teamConfig = `
controls:
macos_setup:
bootstrap_package: %s
manual_agent_install: %t
software:
reports:
@@ -1534,7 +1549,7 @@ settings:
noTeamFile, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = noTeamFile.WriteString(noTeamConfig)
_, err = noTeamFile.WriteString(fmt.Sprintf(noTeamConfig, bootstrapServer.URL))
require.NoError(t, err)
err = noTeamFile.Close()
require.NoError(t, err)
@@ -1545,26 +1560,26 @@ settings:
teamName := uuid.NewString()
teamFile, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = teamFile.WriteString(fmt.Sprintf(teamConfig, true, teamName))
_, err = teamFile.WriteString(fmt.Sprintf(teamConfig, bootstrapServer.URL, true, teamName))
require.NoError(t, err)
err = teamFile.Close()
require.NoError(t, err)
teamFileClear, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = teamFileClear.WriteString(fmt.Sprintf(teamConfig, false, teamName))
_, err = teamFileClear.WriteString(fmt.Sprintf(teamConfig, bootstrapServer.URL, false, teamName))
require.NoError(t, err)
err = teamFileClear.Close()
require.NoError(t, err)
globalFileOnlySet, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = globalFileOnlySet.WriteString(fmt.Sprintf(globalConfigOnly, true))
_, err = globalFileOnlySet.WriteString(fmt.Sprintf(globalConfigOnly, bootstrapServer.URL, true))
require.NoError(t, err)
err = globalFileOnlySet.Close()
require.NoError(t, err)
globalFileOnlyClear, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = globalFileOnlyClear.WriteString(fmt.Sprintf(globalConfigOnly, false))
_, err = globalFileOnlyClear.WriteString(fmt.Sprintf(globalConfigOnly, bootstrapServer.URL, false))
require.NoError(t, err)
err = globalFileOnlyClear.Close()
require.NoError(t, err)
@@ -3363,12 +3378,25 @@ settings:
func (s *enterpriseIntegrationGitopsTestSuite) TestDisallowSoftwareSetupExperience() {
t := s.T()
ctx := context.Background()
originalAppConfig, err := s.DS.AppConfig(ctx)
require.NoError(t, err)
t.Cleanup(func() {
err = s.DS.SaveAppConfig(ctx, originalAppConfig)
require.NoError(t, err)
})
user := s.createGitOpsUser(t)
fleetctlConfig := s.createFleetctlConfig(t, user)
test.CreateInsertGlobalVPPToken(t, s.DS)
teamName := uuid.NewString()
bootstrapServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "testdata/signed.pkg")
}))
defer bootstrapServer.Close()
// The global template includes VPP token assignment to the team
// The location "Jungle" comes from test.CreateInsertGlobalVPPToken
globalTemplate := `agent_options:
@@ -3392,6 +3420,7 @@ queries:
testVPP := `
controls:
macos_setup:
bootstrap_package: %s
manual_agent_install: true
software:
app_store_apps:
@@ -3416,6 +3445,7 @@ team_settings:
testPackages := `
controls:
macos_setup:
bootstrap_package: %s
manual_agent_install: true
software:
app_store_apps:
@@ -3481,7 +3511,7 @@ team_settings:
require.NoError(t, err)
teamFile, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = fmt.Fprintf(teamFile, tc.teamTemplate, tc.teamName, tc.teamSettings)
_, err = fmt.Fprintf(teamFile, tc.teamTemplate, bootstrapServer.URL, tc.teamName, tc.teamSettings)
require.NoError(t, err)
err = teamFile.Close()
require.NoError(t, err)
@@ -3507,7 +3537,6 @@ team_settings:
} else {
require.NoError(t, err)
}
})
}
}
Binary file not shown.