gitops inconsistent language (#37538)

**Related issue:** Resolves #34351

Made language used in gitops more consistent.
This commit is contained in:
Juan Fernandez
2025-12-19 12:58:27 -04:00
committed by GitHub
parent 8ce6ea07da
commit ab8361735b
4 changed files with 158 additions and 102 deletions
+1
View File
@@ -0,0 +1 @@
* Made `gitops` output language consistent.
+1 -1
View File
@@ -423,7 +423,7 @@ func gitopsCommand() *cli.Command {
return fmt.Errorf("volume_purchasing_program team %s cannot be deleted", team.Name)
}
if flDryRun {
_, _ = fmt.Fprintf(c.App.Writer, "[!] would delete team %s\n", team.Name)
_, _ = fmt.Fprintf(c.App.Writer, "[!] would've deleted team %s\n", team.Name)
} else {
_, _ = fmt.Fprintf(c.App.Writer, "[-] deleting team %s\n", team.Name)
if err := fleetClient.DeleteTeam(team.ID); err != nil {
@@ -159,6 +159,44 @@ func (s *enterpriseIntegrationGitopsTestSuite) TearDownTest() {
}
}
func (s *enterpriseIntegrationGitopsTestSuite) assertDryRunOutput(t *testing.T, output string) {
allowedVerbs := []string{
"deleted",
"updated",
"applied",
"added",
"created",
"set",
}
pattern := fmt.Sprintf("\\[([+\\-!])] would've (%s)", strings.Join(allowedVerbs, "|"))
reg := regexp.MustCompile(pattern)
for line := range strings.SplitSeq(output, "\n") {
if line != "" && !strings.Contains(line, "succeeded") {
assert.Regexp(t, reg, line, "on dry run")
}
}
}
func (s *enterpriseIntegrationGitopsTestSuite) assertRealRunOutput(t *testing.T, output string) {
allowedVerbs := []string{
"deleted",
"updated",
"applied",
"added",
"created",
"set",
"applying", // this is used when doing groups operations before the operation starts, e.g. "Applying 10 policies"
"deleting", // ditto
}
pattern := fmt.Sprintf("\\[([+\\-!])] (%s)", strings.Join(allowedVerbs, "|"))
reg := regexp.MustCompile(pattern)
for line := range strings.SplitSeq(output, "\n") {
if line != "" && !strings.Contains(line, "succeeded") {
assert.Regexp(t, reg, line, "on real run")
}
}
}
// TestFleetGitops runs `fleetctl gitops` command on configs in https://github.com/fleetdm/fleet-gitops repo.
// Changes to that repo may cause this test to fail.
func (s *enterpriseIntegrationGitopsTestSuite) TestFleetGitops() {
@@ -221,16 +259,16 @@ team_settings:
test.CreateInsertGlobalVPPToken(t, s.DS)
// Apply the team to be deleted
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", deletedTeamFile.Name()})
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", deletedTeamFile.Name()}))
// Dry run
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile, "--dry-run"})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile, "--dry-run"}))
for _, fileName := range teamFileNames {
// When running no-teams, global config must also be provided ...
if strings.Contains(fileName, "no-team.yml") {
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", fileName, "-f", globalFile, "--dry-run"})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", fileName, "-f", globalFile, "--dry-run"}))
} else {
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", fileName, "--dry-run"})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", fileName, "--dry-run"}))
}
}
@@ -239,14 +277,14 @@ team_settings:
for _, fileName := range teamFileNames {
args = append(args, "-f", fileName)
}
_ = fleetctl.RunAppForTest(t, args)
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, args))
// Real run with all the files, but don't delete other teams
args = []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile}
for _, fileName := range teamFileNames {
args = append(args, "-f", fileName)
}
_ = fleetctl.RunAppForTest(t, args)
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, args))
// Check that all the teams exist
teamsJSON := fleetctl.RunAppForTest(t, []string{"get", "teams", "--config", fleetctlConfig.Name(), "--json"})
@@ -257,7 +295,7 @@ team_settings:
for _, fileName := range teamFileNames {
args = append(args, "-f", fileName)
}
_ = fleetctl.RunAppForTest(t, args)
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, args))
// Check that only the right teams exist
teamsJSON = fleetctl.RunAppForTest(t, []string{"get", "teams", "--config", fleetctlConfig.Name(), "--json"})
@@ -265,13 +303,13 @@ team_settings:
assert.NotContains(t, teamsJSON, deletedTeamName)
// Real run with one file at a time
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile})
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile}))
for _, fileName := range teamFileNames {
// When running no-teams, global config must also be provided ...
if strings.Contains(fileName, "no-team.yml") {
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", fileName, "-f", globalFile})
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", fileName, "-f", globalFile}))
} else {
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", fileName})
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", fileName}))
}
}
}
@@ -352,9 +390,8 @@ team_settings:
t.Setenv("FLEET_URL", s.Server.URL)
// Apply configs
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()}))
// Add bootstrap packages
require.NoError(t, s.DS.InsertMDMAppleBootstrapPackage(context.Background(), &fleet.MDMAppleBootstrapPackage{
@@ -406,9 +443,8 @@ team_settings:
})
// Re-apply configs and expect the macOS setup assets to be cleared
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()}))
mysql.ExecAdhocSQL(t, s.DS, func(q sqlx.ExtContext) error {
stmt := "SELECT COUNT(*) FROM mdm_apple_bootstrap_packages WHERE team_id IN (?, ?)"
@@ -540,8 +576,8 @@ queries:
t.Setenv("FLEET_URL", s.Server.URL)
// Apply configs
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()}))
groupedCAs, err := s.DS.GetGroupedCertificateAuthorities(t.Context(), false)
require.NoError(t, err)
@@ -608,8 +644,8 @@ queries:
require.NoError(t, err)
// Apply configs
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()}))
groupedCAs, err = s.DS.GetGroupedCertificateAuthorities(t.Context(), false)
require.NoError(t, err)
@@ -645,8 +681,8 @@ queries:
`)
require.NoError(t, err)
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()}))
groupedCAs, err = s.DS.GetGroupedCertificateAuthorities(t.Context(), true)
require.NoError(t, err)
@@ -736,9 +772,8 @@ team_settings:
t.Setenv("FLEET_URL", s.Server.URL)
// Apply configs
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()}))
// get the team ID
team, err := s.DS.TeamByName(ctx, teamName)
@@ -765,9 +800,8 @@ team_settings:
require.NoError(t, err)
// Apply configs
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()}))
// the custom setting is not scoped by label anymore
profs, _, err = s.DS.ListMDMConfigProfiles(ctx, nil, fleet.ListOptions{})
@@ -871,10 +905,8 @@ team_settings:
testing_utils.StartSoftwareInstallerServer(t)
// Apply configs
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name()}))
// get the team ID
team, err := s.DS.TeamByName(ctx, teamName)
@@ -910,10 +942,10 @@ team_settings:
require.NoError(t, err)
// Apply configs
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name()}))
// the installer is not scoped by label anymore
meta, err = s.DS.GetSoftwareInstallerMetadataByTeamAndTitleID(ctx, nil, noTeamTitleID, false)
@@ -995,9 +1027,9 @@ software:
err = os.Rename(noTeamFile.Name(), noTeamFilePath)
require.NoError(t, err)
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath}))
// Check script existance
_, err = s.DS.GetSetupExperienceScript(ctx, nil)
@@ -1101,14 +1133,15 @@ team_settings:
// Test dry-run first
output := fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "--dry-run"})
s.assertDryRunOutput(t, output)
// Check that webhook settings are mentioned in the output
require.Contains(t, output, "applying webhook settings for 'No team'")
require.Contains(t, output, "would've applied webhook settings for 'No team'")
// Apply the configuration (non-dry-run)
output = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath})
s.assertRealRunOutput(t, output)
// Verify the output mentions webhook settings were applied
require.Contains(t, output, "applying webhook settings for 'No team'")
@@ -1340,8 +1373,8 @@ queries:
err = globalFile.Close()
require.NoError(t, err)
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()}))
profiles, err := s.DS.ListMDMAppleConfigProfiles(ctx, nil)
require.NoError(t, err)
@@ -1370,8 +1403,8 @@ queries:
err = globalFile.Close()
require.NoError(t, err)
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()}))
// Check profile does not exist
profiles, err = s.DS.ListMDMAppleConfigProfiles(ctx, nil)
@@ -1484,10 +1517,10 @@ team_settings:
t.Setenv("FLEET_URL", s.Server.URL)
// Apply configs
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name()}))
appConfig, err := s.DS.AppConfig(ctx)
require.NoError(t, err)
@@ -1498,10 +1531,10 @@ team_settings:
assert.True(t, team.Config.MDM.MacOSSetup.ManualAgentInstall.Value)
// Apply global configs without no-team
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFileOnlyClear.Name(), "-f", teamFileClear.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFileOnlyClear.Name(), "-f", teamFileClear.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFileOnlyClear.Name(), "-f", teamFileClear.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFileOnlyClear.Name(), "-f", teamFileClear.Name()}))
appConfig, err = s.DS.AppConfig(ctx)
require.NoError(t, err)
assert.False(t, appConfig.MDM.MacOSSetup.ManualAgentInstall.Value)
@@ -1510,9 +1543,9 @@ team_settings:
assert.False(t, team.Config.MDM.MacOSSetup.ManualAgentInstall.Value)
// Apply global configs only
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFileOnlySet.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFileOnlySet.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFileOnlySet.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFileOnlySet.Name()}))
appConfig, err = s.DS.AppConfig(ctx)
require.NoError(t, err)
assert.True(t, appConfig.MDM.MacOSSetup.ManualAgentInstall.Value)
@@ -1632,8 +1665,8 @@ queries:
require.NoError(t, err)
// Apply the configs
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath}))
// Verify the script was saved
_, err = s.DS.GetSetupExperienceScript(ctx, nil)
@@ -1962,8 +1995,8 @@ labels:
require.NoError(t, err)
// Apply the configs
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()}))
// Verify the label was created and has the correct hosts
labels, err := s.DS.LabelsByName(ctx, []string{"my-label"})
@@ -2057,10 +2090,8 @@ team_settings:
t.Setenv("FLEET_URL", s.Server.URL)
testing_utils.StartSoftwareInstallerServer(t)
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "--dry-run"})
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath}))
// the ipa installer was created for no team
titles, _, _, err := s.DS.ListSoftwareTitles(ctx, fleet.SoftwareTitleListOptions{AvailableForInstall: true, TeamID: ptr.Uint(0)},
@@ -2112,10 +2143,8 @@ team_settings:
err = teamFile.Close()
require.NoError(t, err)
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()}))
// get the team ID
team, err := s.DS.TeamByName(ctx, teamName)
@@ -2156,10 +2185,8 @@ team_settings:
`, teamName)), 0o644)
require.NoError(t, err)
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()}))
// the ipa installer was created for the team
titles, _, _, err = s.DS.ListSoftwareTitles(ctx, fleet.SoftwareTitleListOptions{AvailableForInstall: true, TeamID: &team.ID},
@@ -2191,10 +2218,8 @@ team_settings:
err = os.WriteFile(teamFile.Name(), []byte(fmt.Sprintf(teamTemplate, "", teamName)), 0o644)
require.NoError(t, err)
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", teamFile.Name()}))
titles, _, _, err = s.DS.ListSoftwareTitles(ctx, fleet.SoftwareTitleListOptions{AvailableForInstall: true, TeamID: &team.ID},
fleet.TeamFilter{User: test.UserAdmin})
@@ -2279,10 +2304,8 @@ team_settings:
testing_utils.StartSoftwareInstallerServer(t)
// Apply configs
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name(), "--dry-run"})
_ = fleetctl.RunAppForTest(t,
[]string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name()})
s.assertDryRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name(), "--dry-run"}))
s.assertRealRunOutput(t, fleetctl.RunAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "-f", teamFile.Name()}))
// get the team ID
team, err := s.DS.TeamByName(ctx, teamName)
+54 -22
View File
@@ -513,9 +513,10 @@ func numberWithPluralization(n int, singular string, plural string) string {
}
const (
dryRunAppliedFormat = "[+] would've applied %s\n"
appliedFormat = "[+] applied %s\n"
applyingTeamFormat = "[+] applying %s for team %s\n"
dryRunAppliedFormat = "[+] would've applied %s\n"
appliedFormat = "[+] applied %s\n"
applyingTeamFormat = "[+] applying %s for team %s\n"
dryRunAppliedTeamFormat = "[+] would've applied %s for team %s\n"
)
// ApplyGroup applies the given spec group to Fleet.
@@ -956,7 +957,11 @@ func (c *Client) ApplyGroup(
if opts.DryRun && (teamID == 0 || !ok) {
logfn("[+] would've applied MDM profiles for new team %s\n", tmName)
} else {
logfn("[+] applying MDM profiles for team %s\n", tmName)
if opts.DryRun {
logfn("[+] would've applied MDM profiles for new team %s\n", tmName)
} else {
logfn("[+] applying MDM profiles for team %s\n", tmName)
}
if err := c.ApplyTeamProfiles(currentTeamName, profs, teamOpts); err != nil {
return nil, nil, nil, nil, fmt.Errorf("applying custom settings for team %q: %w", tmName, err)
}
@@ -1017,6 +1022,10 @@ func (c *Client) ApplyGroup(
}
}
}
format := applyingTeamFormat
if opts.DryRun {
format = dryRunAppliedTeamFormat
}
if len(tmScriptsPayloads) > 0 {
for tmName, scripts := range tmScriptsPayloads {
// For non-dry run, currentTeamName and tmName are the same
@@ -1032,7 +1041,7 @@ func (c *Client) ApplyGroup(
for tmName, software := range tmSoftwarePackagesPayloads {
// For non-dry run, currentTeamName and tmName are the same
currentTeamName := getTeamName(tmName)
logfn(applyingTeamFormat, numberWithPluralization(len(software), "software package", "software packages"), tmName)
logfn(format, numberWithPluralization(len(software), "software package", "software packages"), tmName)
installers, err := c.ApplyTeamSoftwareInstallers(currentTeamName, software, opts.ApplySpecOptions)
if err != nil {
return nil, nil, nil, nil, fmt.Errorf("applying software installers for team %q: %w", tmName, err)
@@ -1044,7 +1053,7 @@ func (c *Client) ApplyGroup(
for tmName, apps := range tmSoftwareAppsPayloads {
// For non-dry run, currentTeamName and tmName are the same
currentTeamName := getTeamName(tmName)
logfn(applyingTeamFormat, numberWithPluralization(len(apps), "app store app", "app store apps"), tmName)
logfn(format, numberWithPluralization(len(apps), "app store app", "app store apps"), tmName)
appsResponse, err := c.ApplyTeamAppStoreAppsAssociation(currentTeamName, apps, opts.ApplySpecOptions)
if err != nil {
return nil, nil, nil, nil, fmt.Errorf("applying app store apps for team: %q: %w", tmName, err)
@@ -2389,7 +2398,7 @@ func (c *Client) DoGitOps(
return nil, nil, err
}
logFn(
"[+] Set icons on %s and deleted icons on %s\n",
"[+] set icons on %s and deleted icons on %s\n",
numberWithPluralization(len(iconUpdates.IconsToUpdate)+len(iconUpdates.IconsToUpload), "software title", "software titles"),
numberWithPluralization(len(iconUpdates.TitleIDsToRemoveIconsFrom), "title", "titles"),
)
@@ -2569,20 +2578,24 @@ func (c *Client) doGitOpsNoTeamSetupAndSoftware(
}
}
logFn(applyingTeamFormat, numberWithPluralization(len(swPkgPayload), "software package", "software packages"), "'No team'")
format := applyingTeamFormat
if dryRun {
format = dryRunAppliedTeamFormat
}
logFn(format, numberWithPluralization(len(swPkgPayload), "software package", "software packages"), "'No team'")
softwareInstallers, err = c.ApplyNoTeamSoftwareInstallers(swPkgPayload, fleet.ApplySpecOptions{DryRun: dryRun})
if err != nil {
return nil, nil, fmt.Errorf("applying software installers: %w", err)
}
logFn(applyingTeamFormat, numberWithPluralization(len(appsPayload), "app store app", "app store apps"), "'No team'")
logFn(format, numberWithPluralization(len(appsPayload), "app store app", "app store apps"), "'No team'")
vppApps, err := c.ApplyNoTeamAppStoreAppsAssociation(appsPayload, fleet.ApplySpecOptions{DryRun: dryRun})
if err != nil {
return nil, nil, fmt.Errorf("applying app store apps: %w", err)
}
if dryRun {
logFn("[+] would've applied 'No Team' software packages\n")
} else {
if !dryRun {
logFn("[+] applied 'No Team' software packages\n")
}
return softwareInstallers, vppApps, nil
@@ -2636,9 +2649,8 @@ func (c *Client) doGitOpsNoTeamWebhookSettings(
}
}
logFn("[+] applying webhook settings for 'No team'\n")
if !dryRun {
logFn("[+] applying webhook settings for 'No team'\n")
// Apply the webhook settings to team ID 0 using the PATCH endpoint
var teamResp interface{}
err := c.authenticatedRequest(teamPayload, "PATCH", "/api/latest/fleet/teams/0", &teamResp)
@@ -2684,7 +2696,12 @@ func (c *Client) doGitOpsLabels(config *spec.GitOps, logFn func(format string, a
return nil, nil
}
logFn("[+] syncing %s (%d new and %d updated)\n", numberWithPluralization(len(config.Labels), "label", "labels"), len(config.Labels)-numUpdates, numUpdates)
if dryRun {
logFn("[+] would've applied %s (%d new and %d updated)\n", numberWithPluralization(len(config.Labels), "label", "labels"), len(config.Labels)-numUpdates, numUpdates)
} else {
logFn("[+] applying %s (%d new and %d updated)\n", numberWithPluralization(len(config.Labels), "label", "labels"), len(config.Labels)-numUpdates, numUpdates)
}
err = c.ApplyLabels(config.Labels)
if err != nil {
return nil, err
@@ -2807,7 +2824,12 @@ func (c *Client) doGitOpsPolicies(config *spec.GitOps, teamSoftwareInstallers []
if len(config.Policies) > 0 {
numPolicies := len(config.Policies)
logFn("[+] syncing %s\n", numberWithPluralization(numPolicies, "policy", "policies"))
if dryRun {
logFn("[+] would've applied %s\n", numberWithPluralization(numPolicies, "policy", "policies"))
} else {
logFn("[+] applying %s\n", numberWithPluralization(numPolicies, "policy", "policies"))
}
if !dryRun {
totalApplied := 0
for i := 0; i < len(config.Policies); i += batchSize {
@@ -2825,7 +2847,7 @@ func (c *Client) doGitOpsPolicies(config *spec.GitOps, teamSoftwareInstallers []
if err := c.ApplyPolicies(policiesSpec); err != nil {
return fmt.Errorf("error applying policies: %w", err)
}
logFn("[+] synced %s\n", numberWithPluralization(totalApplied, "policy", "policies"))
logFn("[+] applied %s\n", numberWithPluralization(totalApplied, "policy", "policies"))
}
}
}
@@ -2848,7 +2870,11 @@ func (c *Client) doGitOpsPolicies(config *spec.GitOps, teamSoftwareInstallers []
}
}
if len(policiesToDelete) > 0 {
logFn("[-] deleting %s\n", numberWithPluralization(len(policiesToDelete), "policy", "policies"))
if dryRun {
logFn("[-] would've deleted %s\n", numberWithPluralization(len(policiesToDelete), "policy", "policies"))
} else {
logFn("[-] deleting %s\n", numberWithPluralization(len(policiesToDelete), "policy", "policies"))
}
if !dryRun {
totalDeleted := 0
for i := 0; i < len(policiesToDelete); i += batchSize {
@@ -2885,7 +2911,11 @@ func (c *Client) doGitOpsQueries(config *spec.GitOps, logFn func(format string,
}
if len(config.Queries) > 0 {
numQueries := len(config.Queries)
logFn("[+] syncing %s\n", numberWithPluralization(numQueries, "query", "queries"))
if dryRun {
logFn("[+] would've applied %s\n", numberWithPluralization(numQueries, "query", "queries"))
} else {
logFn("[+] applying %s\n", numberWithPluralization(numQueries, "query", "queries"))
}
if !dryRun {
appliedCount := 0
for i := 0; i < len(config.Queries); i += batchSize {
@@ -2898,7 +2928,7 @@ func (c *Client) doGitOpsQueries(config *spec.GitOps, logFn func(format string,
if err := c.ApplyQueries(config.Queries[i:end]); err != nil {
return fmt.Errorf("error applying queries: %w", err)
}
logFn("[+] synced %s\n", numberWithPluralization(appliedCount, "query", "queries"))
logFn("[+] applied %s\n", numberWithPluralization(appliedCount, "query", "queries"))
}
}
}
@@ -2921,8 +2951,10 @@ func (c *Client) doGitOpsQueries(config *spec.GitOps, logFn func(format string,
}
}
if len(queriesToDelete) > 0 {
logFn("[-] deleting %s\n", numberWithPluralization(len(queriesToDelete), "query", "queries"))
if !dryRun {
if dryRun {
logFn("[-] would've deleted %s\n", numberWithPluralization(len(queriesToDelete), "query", "queries"))
} else {
logFn("[-] deleting %s\n", numberWithPluralization(len(queriesToDelete), "query", "queries"))
deleteCount := 0
for i := 0; i < len(queriesToDelete); i += batchSize {
end := i + batchSize