remove no team gitops setting when no-team.yml is not supplied (#28082)

For #26148

remove gitops settings when deleting no-team.yml from the gitops repo.


- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
- [x] Added/updated automated tests
- [x] Manual QA for all new/changed functionality
This commit is contained in:
Gabriel Hernandez 2025-04-22 16:40:17 +01:00 committed by GitHub
parent 86c1a12471
commit de0b046453
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 125 additions and 5 deletions

View file

@ -0,0 +1 @@
- remove fleet config no team settings when the no-team.yml file is removed via gitops

View file

@ -9,6 +9,7 @@ import (
"github.com/fleetdm/fleet/v4/pkg/spec"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/fleetdm/fleet/v4/server/service"
"github.com/urfave/cli/v2"
"golang.org/x/text/unicode/norm"
@ -340,6 +341,19 @@ func gitopsCommand() *cli.Command {
}
}
// we only want to reset the no-team config if the global config was loaded.
// NOTE: noTeamPresent is refering to the "No Team" team. It does not
// mean that other teams are not present.
if globalConfigLoaded && !noTeamPresent {
defaultNoTeamConfig := new(spec.GitOps)
defaultNoTeamConfig.TeamName = ptr.String(fleet.TeamNameNoTeam)
_, err = fleetClient.DoGitOps(c.Context, defaultNoTeamConfig, "no-team.yml", logf, flDryRun, nil, appConfig,
map[string][]fleet.SoftwarePackageResponse{}, map[string][]fleet.VPPAppResponse{}, map[string][]fleet.ScriptResponse{})
if err != nil {
return err
}
}
if flDryRun {
_, _ = fmt.Fprintf(c.App.Writer, "[!] gitops dry run succeeded\n")
} else {

View file

@ -405,7 +405,6 @@ team_settings:
assert.Equal(t, 0, result)
return nil
})
}
// TestCAIntegrations enables DigiCert and Custom SCEP CAs via GitOps.
@ -542,7 +541,6 @@ queries:
require.NoError(t, err)
assert.Empty(t, appConfig.Integrations.DigiCert.Value)
assert.Empty(t, appConfig.Integrations.CustomSCEPProxy.Value)
}
// TestUnsetConfigurationProfileLabels tests the removal of labels associated with a
@ -814,3 +812,83 @@ team_settings:
require.Len(t, meta.LabelsExcludeAny, 0)
require.Len(t, meta.LabelsIncludeAny, 0)
}
func (s *enterpriseIntegrationGitopsTestSuite) TestDeletingNoTeamYAML() {
t := s.T()
ctx := context.Background()
user := s.createGitOpsUser(t)
fleetctlConfig := s.createFleetctlConfig(t, user)
// Set the required environment variables
t.Setenv("FLEET_URL", s.server.URL)
// global file setup
const (
globalTemplate = `
agent_options:
controls:
org_settings:
server_settings:
server_url: $FLEET_URL
org_info:
org_name: Fleet
secrets:
policies:
queries:
`
)
globalFile, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = globalFile.WriteString(globalTemplate)
require.NoError(t, err)
err = globalFile.Close()
require.NoError(t, err)
// setup script
const testScriptTemplate = `echo "Hello, world!"`
scriptFile, err := os.CreateTemp(t.TempDir(), "*.sh")
require.NoError(t, err)
_, err = scriptFile.WriteString(testScriptTemplate)
require.NoError(t, err)
err = scriptFile.Close()
require.NoError(t, err)
// no team file setup
const (
noTeamTemplate = `name: No team
policies:
controls:
macos_setup:
script: %s
software:
`
)
noTeamFile, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
_, err = noTeamFile.WriteString(fmt.Sprintf(noTeamTemplate, scriptFile.Name()))
require.NoError(t, err)
err = noTeamFile.Close()
require.NoError(t, err)
noTeamFilePath := filepath.Join(filepath.Dir(noTeamFile.Name()), "no-team.yml")
err = os.Rename(noTeamFile.Name(), noTeamFilePath)
require.NoError(t, err)
_ = runAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath, "--dry-run"})
_ = runAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "-f", noTeamFilePath})
// Check script existance
_, err = s.ds.GetSetupExperienceScript(ctx, nil)
require.NoError(t, err)
_ = runAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name(), "--dry-run"})
_ = runAppForTest(t, []string{"gitops", "--config", fleetctlConfig.Name(), "-f", globalFile.Name()})
// Check script does not exist
_, err = s.ds.GetSetupExperienceScript(ctx, nil)
var nfe fleet.NotFoundError
require.ErrorAs(t, err, &nfe)
}

View file

@ -115,6 +115,11 @@ func TestGitOpsBasicGlobalFree(t *testing.T) {
ds.ListQueriesFunc = func(ctx context.Context, opts fleet.ListQueryOptions) ([]*fleet.Query, int, *fleet.PaginationMetadata, error) {
return nil, 0, nil, nil
}
ds.ListTeamPoliciesFunc = func(
ctx context.Context, teamID uint, opts fleet.ListOptions, iopts fleet.ListOptions,
) (teamPolicies []*fleet.Policy, inheritedPolicies []*fleet.Policy, err error) {
return nil, nil, nil
}
// Mock appConfig
savedAppConfig := &fleet.AppConfig{}
@ -352,6 +357,18 @@ func TestGitOpsBasicGlobalPremium(t *testing.T) {
}
}
ds.DeleteSetupExperienceScriptFunc = func(ctx context.Context, teamID *uint) error {
return nil
}
ds.ListTeamPoliciesFunc = func(
ctx context.Context, teamID uint, opts fleet.ListOptions, iopts fleet.ListOptions,
) (teamPolicies []*fleet.Policy, inheritedPolicies []*fleet.Policy, err error) {
return nil, nil, nil
}
ds.SetTeamVPPAppsFunc = func(ctx context.Context, teamID *uint, adamIDs []fleet.VPPAppTeam) error {
return nil
}
tmpFile, err := os.CreateTemp(t.TempDir(), "*.yml")
require.NoError(t, err)
@ -720,6 +737,11 @@ func TestGitOpsFullGlobal(t *testing.T) {
policy.ID = 1
policy.Name = "Policy to delete"
policyDeleted := false
ds.ListTeamPoliciesFunc = func(
ctx context.Context, teamID uint, opts fleet.ListOptions, iopts fleet.ListOptions,
) (teamPolicies []*fleet.Policy, inheritedPolicies []*fleet.Policy, err error) {
return nil, nil, nil
}
ds.ListGlobalPoliciesFunc = func(ctx context.Context, opts fleet.ListOptions) ([]*fleet.Policy, error) {
return []*fleet.Policy{&policy}, nil
}
@ -1082,7 +1104,10 @@ func TestGitOpsFullTeam(t *testing.T) {
ds.ListTeamPoliciesFunc = func(
ctx context.Context, teamID uint, opts fleet.ListOptions, iopts fleet.ListOptions,
) (teamPolicies []*fleet.Policy, inheritedPolicies []*fleet.Policy, err error) {
return []*fleet.Policy{&policy}, nil, nil
if teamID != 0 {
return []*fleet.Policy{&policy}, nil, nil
}
return nil, nil, nil
}
ds.PoliciesByIDFunc = func(ctx context.Context, ids []uint) (map[uint]*fleet.Policy, error) {
if slices.Contains(ids, 1) {
@ -1140,7 +1165,9 @@ func TestGitOpsFullTeam(t *testing.T) {
var appliedSoftwareInstallers []*fleet.UploadSoftwareInstallerPayload
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
appliedSoftwareInstallers = installers
if teamID != nil && *teamID != 0 {
appliedSoftwareInstallers = installers
}
return nil
}
ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) {
@ -2420,7 +2447,7 @@ func TestGitOpsTeamSoftwareInstallersQueryEnv(t *testing.T) {
t.Setenv("QUERY_VAR", "IT_WORKS")
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
if installers[0].PreInstallQuery != "select IT_WORKS" {
if len(installers) != 0 && installers[0].PreInstallQuery != "select IT_WORKS" {
return fmt.Errorf("Missing env var, got %s", installers[0].PreInstallQuery)
}
return nil