Skip to content

BYOF: API & GitOps support - #47506

Merged
MagnusHJensen merged 13 commits into
mainfrom
45600-api-gitops-byof
Jun 17, 2026
Merged

BYOF: API & GitOps support#47506
MagnusHJensen merged 13 commits into
mainfrom
45600-api-gitops-byof

Conversation

@MagnusHJensen

@MagnusHJensen MagnusHJensen commented Jun 12, 2026

Copy link
Copy Markdown
Member

Related issue: Resolves #45600

I could see the contributor endpoint was not updated, so I just included it in this PR, and since it's a contributor one I think we are fine updating ahead of release.

Checklist for submitter

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

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.
    See Changes files for more information. (Part of previous PR)

  • Input data is properly validated, SELECT * is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters.

  • Timeouts are implemented and retries are limited to avoid infinite loops

  • If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for Apple Business Manager BYOD team assignments, including saving/loading BYOD default team selections and exposing BYOD team details via the API for personal mobile devices.
  • Refactor

    • Updated GitOps key handling for BYOD assignments to use byod_fleet, with migration/aliasing from the older byod_team key.
  • Tests

    • Expanded GitOps and ABM token tests/fixtures to cover BYOD team behavior, including defaults, clearing/reset behavior, and error/validation scenarios.

@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.77778% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.20%. Comparing base (76de4ad) to head (0251f11).
⚠️ Report is 25 commits behind head on main.

Files with missing lines Patch % Lines
ee/server/service/mdm.go 25.00% 8 Missing and 1 partial ⚠️
server/service/apple_mdm.go 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #47506      +/-   ##
==========================================
+ Coverage   67.19%   67.20%   +0.01%     
==========================================
  Files        3621     3622       +1     
  Lines      229299   229507     +208     
  Branches    11762    11762              
==========================================
+ Hits       154071   154245     +174     
- Misses      61372    61399      +27     
- Partials    13856    13863       +7     
Flag Coverage Δ
backend 68.84% <77.77%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

Adds BYOD fleet/team support to Apple Business Manager (ABM) token assignments across the Fleet API and GitOps, extending existing macOS/iOS/iPadOS assignment plumbing to include a BYOD default team and the associated config/key rename support.

Changes:

  • Extend ABM token/team models and update ABM token teams API endpoint to accept/return BYOD team assignments.
  • Persist and hydrate BYOD default team in MySQL datastore queries and update datastore tests accordingly.
  • Add GitOps support for byod_team/byod_fleet keys, updating fleetctl generate/apply fixtures and tests.

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tools/cloner-check/generated_files/appconfig.txt Updates generated appconfig type field list to include BYODTeam for ABM assignment info.
server/service/integration_mdm_test.go Adjusts service discovery integration test coverage for BYOD enrollment URLs (contains a duplicate block to remove).
server/service/apple_mdm.go Extends UpdateABMTokenTeams request/endpoint wiring to include byod_team_id.
server/service/appconfig.go Extends ABM assignment validation/application to include BYOD team (needs BYOD reset + normalization fix).
server/mock/service/service_mock.go Updates service mock interface to match new UpdateABMTokenTeams signature.
server/fleet/service.go Updates Service interface contract/docs for BYOD team support in UpdateABMTokenTeams.
server/fleet/mdm.go Extends ABMToken model with BYOD default team ID, DB join field, and API response field.
server/fleet/app.go Extends MDMAppleABMAssignmentInfo with BYODTeam for GitOps/API config.
server/datastore/mysql/apple_mdm.go Adds BYOD default team to ABM token insert/update/select queries and hydrates BYODTeam in responses.
server/datastore/mysql/apple_mdm_test.go Extends ABM token datastore tests to validate BYOD team persistence/hydration.
pkg/spec/gitops_deprecations.go Adds GitOps deprecated key mapping for byod_team -> byod_fleet.
ee/server/service/mdm.go Implements BYOD team handling in EE UpdateABMTokenTeams (validation + persistence).
cmd/fleetctl/fleetctl/testdata/generateGitops/test_dir_premium/default.yml Updates GitOps fixture to include byod_fleet.
cmd/fleetctl/fleetctl/testdata/generateGitops/expectedOrgSettings.yaml Updates expected GitOps output to include byod_fleet.
cmd/fleetctl/fleetctl/testdata/generateGitops/expectedOrgSettings-insecure.yaml Updates expected insecure GitOps output to include byod_fleet.
cmd/fleetctl/fleetctl/testdata/generateGitops/appConfig.json Updates app config JSON fixture to include byod_team.
cmd/fleetctl/fleetctl/gitops_test.go Extends GitOps tests to cover BYOD team assignment and renamed key support.
docs/Contributing/reference/api-for-contributors.md Updated contributor API reference (content excluded from review per policy).
Files excluded by content exclusion policy (1)
  • docs/Contributing/reference/api-for-contributors.md

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread server/service/appconfig.go
Comment thread server/service/appconfig.go
Comment thread server/service/integration_mdm_test.go Outdated
@MagnusHJensen

Copy link
Copy Markdown
Member Author

@coderabbitai review once

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

@MagnusHJensen Sure, I'll review the PR now!

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4025f7d9-ac8b-4a64-80de-ba78b67fd2e5

📥 Commits

Reviewing files that changed from the base of the PR and between b94f921 and 6cb9a86.

📒 Files selected for processing (1)
  • server/service/integration_mdm_dep_test.go

Walkthrough

This PR adds BYOD (Bring Your Own Device) team assignment support to Apple Business Manager (ABM) tokens. New BYODTeam and BYODTeamName fields are added to the ABMToken struct and BYODTeam to MDMAppleABMAssignmentInfo. The UpdateABMTokenTeams service interface gains a byodTeamID *uint parameter, propagated through the EE implementation, OSS stub, mock, and HTTP endpoint. MySQL persistence in SaveABMToken, InsertABMToken, ListABMTokens, and getABMToken is extended to read/write byod_default_team_id with a LEFT JOIN on teams. App config validation clears and reassigns BYODDefaultTeamID alongside macOS/iOS/iPadOS defaults. A GitOps deprecation mapping is added to rename byod_team to byod_fleet. Tests and fixtures are updated throughout.

Possibly related PRs

  • fleetdm/fleet#47407: The retrieved PR's ADUE flow assigns host team_id by deriving the ABM token's default BYOD team, which relies on this PR's newly persisted/exposed ABM token BYOD team/default-team support (e.g., byod_default_team_idBYODTeam/BYODDefaultTeamID).
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'BYOF: API & GitOps support' clearly and concisely describes the main change—enabling API and GitOps support for BYOD/BYOF fleet functionality.
Description check ✅ Passed The description provides the related issue (#45600), covers key security and compatibility checklist items, includes testing confirmations, and explains the contributor endpoint inclusion.
Linked Issues check ✅ Passed All changes implement BYOD fleet API/GitOps support per #45600 requirements: struct/method signature updates enable API integration, deprecation mappings and test fixtures support GitOps configuration, and database changes persist BYOD team assignments.
Out of Scope Changes check ✅ Passed All changes are directly related to BYOD fleet API/GitOps support. No out-of-scope modifications detected; the contributor endpoint update is justified as previously missed work.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 45600-api-gitops-byof

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
server/datastore/mysql/apple_mdm.go (1)

6167-6171: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Include BYOD defaults in ABM token team association lookups.

This helper now misses tokens where the team is associated only through byod_default_team_id, including the No Team case when only the BYOD default is unset.

Proposed fix
-	abmtFilter := `abmt.macos_default_team_id IS NULL OR abmt.ios_default_team_id IS NULL OR abmt.ipados_default_team_id IS NULL`
+	abmtFilter := `abmt.macos_default_team_id IS NULL OR abmt.ios_default_team_id IS NULL OR abmt.ipados_default_team_id IS NULL OR abmt.byod_default_team_id IS NULL`
 	if teamID != nil {
 		teamFilter = `h.team_id = ?`
-		abmtFilter = `abmt.macos_default_team_id = ? OR abmt.ios_default_team_id = ? OR abmt.ipados_default_team_id = ?`
-		args = append(args, *teamID, *teamID, *teamID, *teamID)
+		abmtFilter = `abmt.macos_default_team_id = ? OR abmt.ios_default_team_id = ? OR abmt.ipados_default_team_id = ? OR abmt.byod_default_team_id = ?`
+		args = append(args, *teamID, *teamID, *teamID, *teamID, *teamID)
 	}

As per coding guidelines, SQL queries intended to return data for a specific entity must apply precise filtering criteria.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/datastore/mysql/apple_mdm.go` around lines 6167 - 6171, The ABM token
team association filters in the helper are incomplete because they do not
account for the byod_default_team_id field. Add byod_default_team_id to both
filter conditions: in the first abmtFilter (when teamID is nil), include OR
abmt.byod_default_team_id IS NULL, and in the second abmtFilter (when teamID is
not nil), include OR abmt.byod_default_team_id = ?. Also update the args slice
to append *teamID one additional time to provide the parameter value for the
byod_default_team_id condition in the teamID case.

Source: Coding guidelines

server/service/appconfig.go (1)

2014-2031: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Normalize team-name keys consistently before assignment lookup.

Line 2015 validates using norm.NFC.String(tmName), but Lines 2027-2030 assign using raw team-name keys. This can pass validation and still resolve to nil on assignment when normalization forms differ, silently writing wrong default-team IDs (including BYOD).

Suggested fix
-		teamsByName := map[string]*uint{"": nil, "No team": nil}
+		teamsByName := map[string]*uint{
+			norm.NFC.String(""):      nil,
+			norm.NFC.String("No team"): nil,
+		}
 		for _, tm := range teams {
-			teamsByName[tm.Name] = &tm.ID
+			teamsByName[norm.NFC.String(tm.Name)] = &tm.ID
 		}
@@
-			tok := tokensByName[bm.OrganizationName]
-			tok.MacOSDefaultTeamID = teamsByName[bm.MacOSTeam]
-			tok.IOSDefaultTeamID = teamsByName[bm.IOSTeam]
-			tok.IPadOSDefaultTeamID = teamsByName[bm.IpadOSTeam]
-			tok.BYODDefaultTeamID = teamsByName[bm.BYODTeam]
+			tok := tokensByName[norm.NFC.String(bm.OrganizationName)]
+			tok.MacOSDefaultTeamID = teamsByName[norm.NFC.String(bm.MacOSTeam)]
+			tok.IOSDefaultTeamID = teamsByName[norm.NFC.String(bm.IOSTeam)]
+			tok.IPadOSDefaultTeamID = teamsByName[norm.NFC.String(bm.IpadOSTeam)]
+			tok.BYODDefaultTeamID = teamsByName[norm.NFC.String(bm.BYODTeam)]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@server/service/appconfig.go` around lines 2014 - 2031, The code validates
team names using normalized form `norm.NFC.String(tmName)` to check against the
`teamsByName` map, but then performs lookups using raw non-normalized team names
when assigning default team IDs to the token object. This inconsistency causes
validation to pass while assignment silently fails with nil values. Apply
`norm.NFC.String()` normalization to the team name keys when accessing
`teamsByName` during the assignment of `tok.MacOSDefaultTeamID`,
`tok.IOSDefaultTeamID`, `tok.IPadOSDefaultTeamID`, and `tok.BYODDefaultTeamID`
to ensure consistent normalization throughout.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@server/datastore/mysql/apple_mdm.go`:
- Around line 6167-6171: The ABM token team association filters in the helper
are incomplete because they do not account for the byod_default_team_id field.
Add byod_default_team_id to both filter conditions: in the first abmtFilter
(when teamID is nil), include OR abmt.byod_default_team_id IS NULL, and in the
second abmtFilter (when teamID is not nil), include OR abmt.byod_default_team_id
= ?. Also update the args slice to append *teamID one additional time to provide
the parameter value for the byod_default_team_id condition in the teamID case.

In `@server/service/appconfig.go`:
- Around line 2014-2031: The code validates team names using normalized form
`norm.NFC.String(tmName)` to check against the `teamsByName` map, but then
performs lookups using raw non-normalized team names when assigning default team
IDs to the token object. This inconsistency causes validation to pass while
assignment silently fails with nil values. Apply `norm.NFC.String()`
normalization to the team name keys when accessing `teamsByName` during the
assignment of `tok.MacOSDefaultTeamID`, `tok.IOSDefaultTeamID`,
`tok.IPadOSDefaultTeamID`, and `tok.BYODDefaultTeamID` to ensure consistent
normalization throughout.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f290a190-13c7-4ba5-8819-a056c1550b4c

📥 Commits

Reviewing files that changed from the base of the PR and between 76de4ad and 0d36d70.

⛔ Files ignored due to path filters (1)
  • docs/Contributing/reference/api-for-contributors.md is excluded by !**/*.md
📒 Files selected for processing (16)
  • cmd/fleetctl/fleetctl/gitops_test.go
  • cmd/fleetctl/fleetctl/testdata/generateGitops/appConfig.json
  • cmd/fleetctl/fleetctl/testdata/generateGitops/expectedOrgSettings-insecure.yaml
  • cmd/fleetctl/fleetctl/testdata/generateGitops/expectedOrgSettings.yaml
  • cmd/fleetctl/fleetctl/testdata/generateGitops/test_dir_premium/default.yml
  • ee/server/service/mdm.go
  • pkg/spec/gitops_deprecations.go
  • server/datastore/mysql/apple_mdm.go
  • server/datastore/mysql/apple_mdm_test.go
  • server/fleet/app.go
  • server/fleet/mdm.go
  • server/fleet/service.go
  • server/mock/service/service_mock.go
  • server/service/appconfig.go
  • server/service/apple_mdm.go
  • tools/cloner-check/generated_files/appconfig.txt

@MagnusHJensen
MagnusHJensen marked this pull request as ready for review June 16, 2026 13:51
@MagnusHJensen

Copy link
Copy Markdown
Member Author

@rachaelshaw
I could see the contributor endpoint was not updated, so I just included it in this PR, and since it's a contributor one I think we are fine updating ahead of release.

Let me know if we are not okay with this, and would rather pull it out and target for docs-v4.88.0

Comment thread docs/Contributing/reference/api-for-contributors.md Outdated
@MagnusHJensen
MagnusHJensen merged commit dcf5029 into main Jun 17, 2026
47 checks passed
@MagnusHJensen
MagnusHJensen deleted the 45600-api-gitops-byof branch June 17, 2026 11:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BYOF: API/Gitops changes for BYOD fleet

3 participants