diff --git a/changes/21104-gitops-team-conflict b/changes/21104-gitops-team-conflict new file mode 100644 index 0000000000..6749b1b15a --- /dev/null +++ b/changes/21104-gitops-team-conflict @@ -0,0 +1 @@ +Improved fleetctl gitops error message when trying to change team name to a team that already exists. diff --git a/cmd/fleetctl/gitops_test.go b/cmd/fleetctl/gitops_test.go index 3b5470902b..0f6cee6406 100644 --- a/cmd/fleetctl/gitops_test.go +++ b/cmd/fleetctl/gitops_test.go @@ -665,6 +665,9 @@ func TestFullTeamGitOps(t *testing.T) { // Team var savedTeam *fleet.Team ds.TeamByNameFunc = func(ctx context.Context, name string) (*fleet.Team, error) { + if name == "Conflict" { + return &fleet.Team{}, nil + } if savedTeam != nil && savedTeam.Name == name { return savedTeam, nil } @@ -825,7 +828,15 @@ func TestFullTeamGitOps(t *testing.T) { assert.Equal(t, newTeamName, savedTeam.Name) assert.Equal(t, baseFilename, *savedTeam.Filename) + // Try to change team name again, but this time the new name conflicts with an existing team + t.Setenv("TEST_TEAM_NAME", "Conflict") + _, err = runAppNoChecks([]string{"gitops", "-f", file, "--dry-run"}) + assert.ErrorContains(t, err, "team name already exists") + _, err = runAppNoChecks([]string{"gitops", "-f", file}) + assert.ErrorContains(t, err, "team name already exists") + // Now clear the settings + t.Setenv("TEST_TEAM_NAME", newTeamName) tmpFile, err := os.CreateTemp(t.TempDir(), "*.yml") require.NoError(t, err) secret := "TestSecret" diff --git a/ee/server/service/teams.go b/ee/server/service/teams.go index 3d25abafe9..f7dcbec15d 100644 --- a/ee/server/service/teams.go +++ b/ee/server/service/teams.go @@ -868,6 +868,20 @@ func (svc *Service) ApplyTeamSpecs(ctx context.Context, specs []*fleet.TeamSpec, if err != nil && !fleet.IsNotFound(err) { return nil, err } + if team != nil && team.Name != spec.Name { + // If user is trying to change team name, check that the new name is not already taken. + _, err = svc.ds.TeamByName(ctx, spec.Name) + switch { + case err == nil: + return nil, fleet.NewInvalidArgumentError("name", + fmt.Sprintf("cannot change team name from '%s' (filename: %s) to '%s' because team name already exists", team.Name, + *spec.Filename, spec.Name)) + case fleet.IsNotFound(err): + // OK + default: + return nil, err + } + } } var create bool if team == nil {