diff --git a/changes/22359-gitops-mult-abm b/changes/22359-gitops-mult-abm new file mode 100644 index 0000000000..b7a7801edb --- /dev/null +++ b/changes/22359-gitops-mult-abm @@ -0,0 +1,2 @@ +- Updates GitOps to return an error if the deprecated `apple_bm_default_team` key is used and there + are more than 1 ABM tokens in Fleet. \ No newline at end of file diff --git a/cmd/fleetctl/gitops.go b/cmd/fleetctl/gitops.go index 04ca1469c0..30efe0a513 100644 --- a/cmd/fleetctl/gitops.go +++ b/cmd/fleetctl/gitops.go @@ -162,6 +162,7 @@ func gitopsCommand() *cli.Command { // name.) Because teams can be created/deleted during the same gitops run, we // grab some information to help us determine allowed/restricted actions and // when to perform the associations. + if isGlobalConfig && totalFilenames > 1 && !(totalFilenames == 2 && noTeamPresent) && isPremium { abmTeams, hasMissingABMTeam, usesLegacyABMConfig, err = checkABMTeamAssignments(config, fleetClient) if err != nil { @@ -298,6 +299,15 @@ func checkABMTeamAssignments(config *spec.GitOps, fleetClient *service.Client) ( return nil, false, false, errors.New(fleet.AppleABMDefaultTeamDeprecatedMessage) } + abmToks, err := fleetClient.ListABMTokens() + if err != nil { + return nil, false, false, err + } + + if hasLegacyConfig && len(abmToks) > 1 { + return nil, false, false, errors.New(fleet.AppleABMDefaultTeamDeprecatedMessage) + } + if !hasLegacyConfig && !hasNewConfig { return nil, false, false, nil } diff --git a/cmd/fleetctl/gitops_test.go b/cmd/fleetctl/gitops_test.go index 549788210e..e9d9670dff 100644 --- a/cmd/fleetctl/gitops_test.go +++ b/cmd/fleetctl/gitops_test.go @@ -2605,26 +2605,27 @@ software: assert.Contains(t, out, "[!] gitops succeeded") }, }, - // { - // name: "deprecated config with two tokens in the db fails", - // cfgs: []string{ - // global("apple_bm_default_team: 💻 Workstations"), - // workstations, - // }, - // tokens: []*fleet.ABMToken{{OrganizationName: "Fleet Device Management Inc."}, {OrganizationName: "Second Token LLC"}}, - // dryRunAssertion: func(t *testing.T, appCfg *fleet.AppConfig, ds fleet.Datastore, out string, err error) { - // require.ErrorContains(t, err, "mdm.apple_bm_default_team has been deprecated") - // assert.Empty(t, appCfg.MDM.AppleBussinessManager.Value) - // assert.Empty(t, appCfg.MDM.DeprecatedAppleBMDefaultTeam) - // assert.NotContains(t, out, "[!] gitops dry run succeeded") - // }, - // realRunAssertion: func(t *testing.T, appCfg *fleet.AppConfig, ds fleet.Datastore, out string, err error) { - // require.ErrorContains(t, err, "mdm.apple_bm_default_team has been deprecated") - // assert.Empty(t, appCfg.MDM.AppleBussinessManager.Value) - // assert.Empty(t, appCfg.MDM.DeprecatedAppleBMDefaultTeam) - // assert.NotContains(t, out, "[!] gitops dry run succeeded") - // }, - // }, + { + name: "deprecated config with two tokens in the db fails", + cfgs: []string{ + global("apple_bm_default_team: 💻 Workstations"), + workstations, + }, + tokens: []*fleet.ABMToken{{OrganizationName: "Fleet Device Management Inc."}, {OrganizationName: "Second Token LLC"}}, + dryRunAssertion: func(t *testing.T, appCfg *fleet.AppConfig, ds fleet.Datastore, out string, err error) { + t.Logf("got: %s", out) + require.ErrorContains(t, err, "mdm.apple_bm_default_team has been deprecated") + assert.Empty(t, appCfg.MDM.AppleBusinessManager.Value) + assert.Empty(t, appCfg.MDM.DeprecatedAppleBMDefaultTeam) + assert.NotContains(t, out, "[!] gitops dry run succeeded") + }, + realRunAssertion: func(t *testing.T, appCfg *fleet.AppConfig, ds fleet.Datastore, out string, err error) { + require.ErrorContains(t, err, "mdm.apple_bm_default_team has been deprecated") + assert.Empty(t, appCfg.MDM.AppleBusinessManager.Value) + assert.Empty(t, appCfg.MDM.DeprecatedAppleBMDefaultTeam) + assert.NotContains(t, out, "[!] gitops succeeded") + }, + }, { name: "new key all valid", cfgs: []string{ diff --git a/server/service/client_mdm.go b/server/service/client_mdm.go index a33028ba32..c41915b91a 100644 --- a/server/service/client_mdm.go +++ b/server/service/client_mdm.go @@ -40,6 +40,13 @@ func (c *Client) GetAppleBM() (*fleet.AppleBM, error) { return responseBody.AppleBM, err } +func (c *Client) ListABMTokens() ([]*fleet.ABMToken, error) { + verb, path := "GET", "/api/latest/fleet/abm_tokens" + var responseBody listABMTokensResponse + err := c.authenticatedRequestWithQuery(nil, verb, path, &responseBody, "") + return responseBody.Tokens, err +} + // RequestAppleCSR requests a signed CSR from the Fleet server and returns the // CSR bytes func (c *Client) RequestAppleCSR() ([]byte, error) {