Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API design: #22075 Option to automatically migrate Windows workstations #22288

Closed
wants to merge 82 commits into from
Closed
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
518a4a1
Use previous package filename for activity if installer edit doesn't …
iansltx Sep 17, 2024
f135d5b
UI – 2 small unreleased bug fixes for software install policy automat…
jacobshandling Sep 17, 2024
2bfbf2f
Allow CA certificates with extendedKeyUsage attributes. (#22160)
roperzh Sep 17, 2024
b11edd9
Add CIS policy for tests (#22112)
sharon-fdm Sep 17, 2024
ddbdce4
Updated PS1 install/uninstall scripts to fail on error. (#22164)
getvictor Sep 17, 2024
1f1bc9c
Website: add default organization to Premium trial license keys. (#22…
eashaw Sep 17, 2024
ea2a978
Ensure edited scripts provided from the client with newline switches …
iansltx Sep 18, 2024
f7fab00
Pass through uninstall error messages from backend (#22208)
iansltx Sep 18, 2024
4ee79ae
UI: handle possibly 'null' 'storedPolicy.team_id' on update policy ca…
jacobshandling Sep 18, 2024
90959db
Fixes for no-team.yml GitOps (#22210)
lucasmrod Sep 18, 2024
36ea5cc
Update tooltip for mac minimum target OS version label (#22157)
ghernandez345 Sep 18, 2024
721ed30
Website: Add search and breadcrumbs to article template page (#22171)
eashaw Sep 18, 2024
9a1b376
show correct chrome software icon for chrome packages (#22233)
ghernandez345 Sep 19, 2024
ebb62af
Website: Deliver contact form messages to Slack (#22231)
eashaw Sep 19, 2024
246fa60
Iron out the nav -- Update layout.ejs (#22151)
mikermcneil Sep 19, 2024
6ab05de
Update link + CTA on pricing.ejs (#22229)
mikermcneil Sep 19, 2024
ad4c05e
Website: Update start CTA orb image (psyStage 4) (#22232)
eashaw Sep 19, 2024
90c04ee
fix: stop profiles that never reached the host from showing up as fai…
jahzielv Sep 19, 2024
e2ac27e
Document 0-day macOS major version support process beginning with mac…
lukeheath Sep 19, 2024
d52335e
Update link, clarify iOS (#22230)
mikermcneil Sep 19, 2024
f247e57
Add template response to hiring steps (#22255)
Sampfluger88 Sep 19, 2024
edec764
Remove AE position (#22256)
Sampfluger88 Sep 19, 2024
07a5826
fleetdm.com/start: suggested copy change for fleetctl install (#22251)
noahtalerman Sep 19, 2024
2a88d5a
Add Product Designer position (#22250)
noahtalerman Sep 20, 2024
e4b6fae
Update pricing-features-table.yml (#22235)
noahtalerman Sep 20, 2024
2708988
Fleet UI: Fix observer persisting host_id when querying host from hos…
RachelElysia Sep 20, 2024
8d664bd
Make software batch endpoint asynchronous (#22258)
lucasmrod Sep 20, 2024
92d3b70
Update discovering-chrome-ai-using-fleet.md (#22268)
nonpunctual Sep 20, 2024
eeb0579
Dogfood: remove "Explore data (fleetdm.com)" team (#22246)
noahtalerman Sep 20, 2024
1677783
GitOps & API design: Add multiple Apple Business Manager and Volume P…
noahtalerman Sep 20, 2024
84473c2
feat: update MDM migration guide with new UX (#22128)
jahzielv Sep 20, 2024
a17ab39
Update button name in deploy-fleet.md (#22271)
rebeccaui Sep 20, 2024
fc8b1d6
Remove placeholder text (#22274)
noahtalerman Sep 20, 2024
d7594d1
Fleet UI: Disable install/uninstall actions if scripts are disabled (…
RachelElysia Sep 20, 2024
ff62f98
Update rest-api.md
rachaelshaw Sep 20, 2024
b26c592
Handbook: Update drafting steps (#22286)
rachaelshaw Sep 22, 2024
2d90b7f
Update product-design.rituals.yml (#22285)
rachaelshaw Sep 22, 2024
85a8cb9
Clarify empty space formatting (#22294)
Sampfluger88 Sep 22, 2024
6d9eb8d
Clean up Product Design responsibilities (#22282)
noahtalerman Sep 23, 2024
b5fcaa7
Update story template (#22280)
noahtalerman Sep 23, 2024
66a9fb2
Update hiring steps (#22296)
Sampfluger88 Sep 23, 2024
2ce2b80
Update versions of fleetd components in Fleet's TUF [automated] (#22289)
github-actions[bot] Sep 23, 2024
cbf563f
Use sync.Map for stubbed key-value store to avoid data races in GitOp…
iansltx Sep 23, 2024
e861ae7
Release fleetd 1.33.0 (#22283)
lucasmrod Sep 23, 2024
f83260a
Fleet UI: Host details > about info uses less columns at small widths…
RachelElysia Sep 23, 2024
b14f7fa
Update versions of fleetd components in Fleet's TUF [automated] (#22305)
github-actions[bot] Sep 23, 2024
631dc60
add s3 installers to loadtest (#22306)
rfairburn Sep 23, 2024
3163314
Fixed self-service checkbox appearing when iOS or iPadOS app is selec…
lukeheath Sep 23, 2024
dd583f0
Update docs codeowners temporarily (#22320)
lukeheath Sep 23, 2024
adf19c4
Reference docs for v4.57.0 (#22319)
noahtalerman Sep 23, 2024
03c3c6c
Docs: OS updates page - unclear tooltip copy (#22272)
marko-lisica Sep 23, 2024
1fdd127
Add macOS policies for patching in workstations-canary.yml (#22323)
dherder Sep 23, 2024
dfc7289
Add missing docs for batch apply VPP apps (#22265)
lucasmrod Sep 23, 2024
21b3c46
Add doc API changes for the now async software batch (#22259)
lucasmrod Sep 23, 2024
d83ed46
Add batch app store apps documentation (#21912)
dantecatalfamo Sep 23, 2024
9c3ad8b
Article: Guide Enable Okta Verify on macOS (#22328)
spokanemac Sep 23, 2024
6fce24c
Article: Fleet 4.57.0 release (#22173)
spokanemac Sep 23, 2024
c06eb13
Article: Guide BYOD enroll iOS iPadOS (#22281)
spokanemac Sep 23, 2024
b9a5107
Article deploy software packages (#22245)
spokanemac Sep 23, 2024
c51c20a
Adding changes for Fleet v4.57.0 (#22109) (#22327)
lukeheath Sep 24, 2024
752c2c0
Remove weird format thing (#22333)
Sampfluger88 Sep 24, 2024
bd96663
Add Kendra to team table (#22334)
Sampfluger88 Sep 24, 2024
111b243
Add steps to enable email sync (#22335)
Sampfluger88 Sep 24, 2024
aa38b10
fix: #22297 re-enable Escrow Buddy in the auth-db (#22298)
F1Feng Sep 24, 2024
f0babb7
Permissions guide: Apple Business Manager and Volume Purchasing Progr…
noahtalerman Sep 24, 2024
f5a7587
update the help text of macOS min version input (#22337)
ghernandez345 Sep 24, 2024
3b001ea
Fleet UI: Host status dropdown styling fixes (#22314)
RachelElysia Sep 24, 2024
57abc0f
Fleet UI: Fix self-service icon from cutting off (#22310)
RachelElysia Sep 24, 2024
31ac408
Fleet UI: Hide redundant built in label filtering (#22308)
RachelElysia Sep 24, 2024
537da81
Update README.md (#22347)
Sampfluger88 Sep 24, 2024
db1c374
fix TestEscrowBuddy/TestEscrowBuddyRotatesKey test (#22345)
roperzh Sep 24, 2024
8428f19
Move settings to no-team.yml (#22343)
lucasmrod Sep 24, 2024
f0753cf
Add redirects for all security files (#22344)
Sampfluger88 Sep 24, 2024
8cbb28b
21056 auto install document (#21362)
sharon-fdm Sep 24, 2024
ea0175e
Improve MySQL queries that aggregate MDM profile statuses for Apple h…
gillespi314 Sep 24, 2024
839106c
Hotfix CVE test (#22349)
mostlikelee Sep 24, 2024
adf3ad6
allow to install VPP apps without scripts (#22365)
roperzh Sep 25, 2024
38ba6cc
fix: update docs with accurate response body (#22360)
jahzielv Sep 25, 2024
18026d5
Fleet UI: Improve select targets dropdown (#22348)
RachelElysia Sep 25, 2024
345d35c
New Product design responsibility (#22284)
noahtalerman Sep 25, 2024
692e0fc
Fleet UI: Surface duplicate label name error to users (#22389)
RachelElysia Sep 25, 2024
927b77a
Merge branch 'main' into 22075-api-design
rachaelshaw Sep 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ define HELP_TEXT
make generate-go - Generate and bundle required go code
make generate-js - Generate and bundle required js code
make generate-dev - Generate and bundle required code in a watch loop
make generate-doc - Generate updated API documentation for activities, osquery flags

make clean - Clean all build artifacts
make clean-assets - Clean assets only
Expand Down
2 changes: 1 addition & 1 deletion articles/discovering-chrome-ai-using-fleet.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ In this case, `jq` is used to locate and read the value of the `tab_organization

### Step 3: Query the JSON file with Fleet

To detect Chrome AI features in Fleet, use SQL query like the following:
To detect Chrome AI features in Fleet, use a SQL query like the following:

```
SELECT fullkey,path FROM parse_json WHERE path LIKE '/Users/%/Library/Application Support/Google/Chrome/Default/Preferences' AND fullkey='optimization_guide/tab_organization_setting_state';
Expand Down
199 changes: 52 additions & 147 deletions articles/mdm-migration.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions changes/20865-fix-chrome-icon
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- show proper software icon for chrome packages
1 change: 1 addition & 0 deletions changes/20959-query-host-flow-fix-observer
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Fix UI flow for observers to easily query hosts from the host details page
2 changes: 2 additions & 0 deletions changes/21891-mdm-profile-fails
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Fixes a bug where a profile wouldn't be removed from a host if it was deleted or if the host was
moved to another team before the profile was installed on the host.
1 change: 1 addition & 0 deletions changes/21976-update-macos-target-version-tooltip
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- update the macos target minimum version tooltip
1 change: 1 addition & 0 deletions changes/22069-gitops-async-software-batch
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Modified `POST /api/latest/fleet/software/batch` endpoint to be asynchronous and added a new endpoint `GET /api/latest/fleet/software/batch/{request_uuid}` to retrieve the result of the batch upload.
1 change: 1 addition & 0 deletions changes/22097-mdm-migration-guide
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Updates the guide for MDM migration to include the new UX in fleetd.
1 change: 1 addition & 0 deletions changes/22158-scep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Allow custom SCEP CA certificates with any kind of extendedKeyUsage attributes.
2 changes: 2 additions & 0 deletions cmd/fleet/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import (
"github.com/fleetdm/fleet/v4/server/pubsub"
"github.com/fleetdm/fleet/v4/server/service"
"github.com/fleetdm/fleet/v4/server/service/async"
"github.com/fleetdm/fleet/v4/server/service/redis_key_value"
"github.com/fleetdm/fleet/v4/server/service/redis_lock"
"github.com/fleetdm/fleet/v4/server/service/redis_policy_set"
"github.com/fleetdm/fleet/v4/server/sso"
Expand Down Expand Up @@ -798,6 +799,7 @@ the way that the Fleet server works.
softwareInstallStore,
bootstrapPackageStore,
distributedLock,
redis_key_value.New(redisPool),
)
if err != nil {
initFatal(err, "initial Fleet Premium service")
Expand Down
4 changes: 2 additions & 2 deletions cmd/fleetctl/get_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2320,8 +2320,8 @@ func TestGetTeamsYAMLAndApply(t *testing.T) {
declaration.DeclarationUUID = uuid.NewString()
return declaration, nil
}
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) {
return nil, nil
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
return nil
}

actualYaml := runAppForTest(t, []string{"get", "teams", "--yaml"})
Expand Down
16 changes: 11 additions & 5 deletions cmd/fleetctl/gitops.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,19 @@ func gitopsCommand() *cli.Command {
}

// We need to extract the controls from no-team.yml to be able to apply them when applying the global app config.
var noTeamControls spec.Controls
var (
noTeamControls spec.Controls
noTeamPresent bool
)
for _, flFilename := range flFilenames.Value() {
if filepath.Base(flFilename) == "no-team.yml" {
baseDir := filepath.Dir(flFilename)
config, err := spec.GitOpsFromFile(flFilename, baseDir, appConfig, logf)
config, err := spec.GitOpsFromFile(flFilename, baseDir, appConfig, func(format string, a ...interface{}) {})
if err != nil {
return err
}
noTeamControls = config.Controls
noTeamPresent = true
break
}
}
Expand Down Expand Up @@ -145,7 +149,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 {
if isGlobalConfig && totalFilenames > 1 && !(totalFilenames == 2 && noTeamPresent) {
abmTeams, hasMissingABMTeam, usesLegacyABMConfig, err = checkABMTeamAssignments(config, fleetClient)
if err != nil {
return err
Expand Down Expand Up @@ -192,6 +196,7 @@ func gitopsCommand() *cli.Command {
}
}
}

if flDryRun {
incomingSecrets := fleetClient.GetGitOpsSecrets(config)
for _, secret := range incomingSecrets {
Expand All @@ -201,6 +206,7 @@ func gitopsCommand() *cli.Command {
secrets[secret] = struct{}{}
}
}

assumptions, err := fleetClient.DoGitOps(c.Context, config, flFilename, logf, flDryRun, teamDryRunAssumptions, appConfig)
if err != nil {
return err
Expand Down Expand Up @@ -349,7 +355,7 @@ func applyABMTokenAssignmentIfNeeded(
if usesLegacyConfig {
appleBMDefaultTeam := abmTeamNames[0]
if !slices.Contains(teamNames, appleBMDefaultTeam) {
return fmt.Errorf("apple_bm_default_team %s not found in team configs", appleBMDefaultTeam)
return fmt.Errorf("apple_bm_default_team team %q not found in team configs", appleBMDefaultTeam)
}
appConfigUpdate = map[string]map[string]any{
"mdm": {
Expand All @@ -359,7 +365,7 @@ func applyABMTokenAssignmentIfNeeded(
} else {
for _, abmTeam := range abmTeamNames {
if !slices.Contains(teamNames, abmTeam) {
return fmt.Errorf("apple_business_manager team %s not found in team configs", abmTeam)
return fmt.Errorf("apple_business_manager team %q not found in team configs", abmTeam)
}
}

Expand Down
87 changes: 68 additions & 19 deletions cmd/fleetctl/gitops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ func TestGitOpsBasicGlobalPremium(t *testing.T) {
license := &fleet.LicenseInfo{Tier: fleet.TierPremium, Expiration: time.Now().Add(24 * time.Hour)}
_, ds := runServerWithMockedDS(
t, &service.TestServerOpts{
License: license,
License: license,
KeyValueStore: newMemKeyValueStore(),
},
)

Expand Down Expand Up @@ -229,7 +230,10 @@ func TestGitOpsBasicGlobalPremium(t *testing.T) {
ds.NewJobFunc = func(ctx context.Context, job *fleet.Job) (*fleet.Job, error) {
return &fleet.Job{}, nil
}
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) {
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
return nil
}
ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) {
return nil, nil
}

Expand Down Expand Up @@ -285,7 +289,8 @@ func TestGitOpsBasicTeam(t *testing.T) {
license := &fleet.LicenseInfo{Tier: fleet.TierPremium, Expiration: time.Now().Add(24 * time.Hour)}
_, ds := runServerWithMockedDS(
t, &service.TestServerOpts{
License: license,
License: license,
KeyValueStore: newMemKeyValueStore(),
},
)

Expand Down Expand Up @@ -373,7 +378,10 @@ func TestGitOpsBasicTeam(t *testing.T) {
ds.DeleteMDMAppleDeclarationByNameFunc = func(ctx context.Context, teamID *uint, name string) error {
return nil
}
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) {
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
return nil
}
ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) {
return nil, nil
}
ds.ApplyEnrollSecretsFunc = func(ctx context.Context, teamID *uint, secrets []*fleet.EnrollSecret) error {
Expand Down Expand Up @@ -644,6 +652,7 @@ func TestGitOpsFullTeam(t *testing.T) {
MDMPusher: mockPusher{},
FleetConfig: &fleetCfg,
NoCacheDatastore: true,
KeyValueStore: newMemKeyValueStore(),
},
)

Expand Down Expand Up @@ -804,8 +813,11 @@ func TestGitOpsFullTeam(t *testing.T) {
return nil
}
var appliedSoftwareInstallers []*fleet.UploadSoftwareInstallerPayload
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) {
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
appliedSoftwareInstallers = installers
return nil
}
ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) {
return nil, nil
}
ds.SetTeamVPPAppsFunc = func(ctx context.Context, teamID *uint, adamIDs []fleet.VPPAppTeam) error {
Expand Down Expand Up @@ -937,7 +949,8 @@ func TestGitOpsBasicGlobalAndTeam(t *testing.T) {
license := &fleet.LicenseInfo{Tier: fleet.TierPremium, Expiration: time.Now().Add(24 * time.Hour)}
_, ds := runServerWithMockedDS(
t, &service.TestServerOpts{
License: license,
License: license,
KeyValueStore: newMemKeyValueStore(),
},
)

Expand Down Expand Up @@ -1055,7 +1068,10 @@ func TestGitOpsBasicGlobalAndTeam(t *testing.T) {
savedTeam = team
return team, nil
}
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) {
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
return nil
}
ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) {
return nil, nil
}
ds.ListSoftwareTitlesFunc = func(ctx context.Context, opt fleet.SoftwareTitleListOptions, tmFilter fleet.TeamFilter) ([]fleet.SoftwareTitleListResult, int, *fleet.PaginationMetadata, error) {
Expand Down Expand Up @@ -1201,7 +1217,8 @@ func TestGitOpsBasicGlobalAndNoTeam(t *testing.T) {
license := &fleet.LicenseInfo{Tier: fleet.TierPremium, Expiration: time.Now().Add(24 * time.Hour)}
_, ds := runServerWithMockedDS(
t, &service.TestServerOpts{
License: license,
License: license,
KeyValueStore: newMemKeyValueStore(),
},
)
// Mock appConfig
Expand Down Expand Up @@ -1317,7 +1334,10 @@ func TestGitOpsBasicGlobalAndNoTeam(t *testing.T) {
savedTeam = team
return team, nil
}
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) {
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
return nil
}
ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) {
return nil, nil
}
ds.ListSoftwareTitlesFunc = func(ctx context.Context, opt fleet.SoftwareTitleListOptions, tmFilter fleet.TeamFilter) ([]fleet.SoftwareTitleListResult, int, *fleet.PaginationMetadata, error) {
Expand Down Expand Up @@ -1634,9 +1654,9 @@ func TestGitOpsTeamSofwareInstallers(t *testing.T) {
file string
wantErr string
}{
{"testdata/gitops/team_software_installer_not_found.yml", "Please make sure that URLs are publicy accessible to the internet."},
{"testdata/gitops/team_software_installer_not_found.yml", "Please make sure that URLs are reachable from your Fleet server."},
{"testdata/gitops/team_software_installer_unsupported.yml", "The file should be .pkg, .msi, .exe or .deb."},
{"testdata/gitops/team_software_installer_too_large.yml", "The maximum file size is 500 MB"},
{"testdata/gitops/team_software_installer_too_large.yml", "The maximum file size is 500 MiB"},
{"testdata/gitops/team_software_installer_valid.yml", ""},
{"testdata/gitops/team_software_installer_valid_apply.yml", ""},
{"testdata/gitops/team_software_installer_pre_condition_multiple_queries.yml", "should have only one query."},
Expand Down Expand Up @@ -1668,10 +1688,13 @@ func TestGitOpsTeamSoftwareInstallersQueryEnv(t *testing.T) {

t.Setenv("QUERY_VAR", "IT_WORKS")

ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) {
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, tmID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
if installers[0].PreInstallQuery != "select IT_WORKS" {
return nil, fmt.Errorf("Missing env var, got %s", installers[0].PreInstallQuery)
return fmt.Errorf("Missing env var, got %s", installers[0].PreInstallQuery)
}
return nil
}
ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) {
return nil, nil
}

Expand All @@ -1686,9 +1709,9 @@ func TestGitOpsNoTeamSoftwareInstallers(t *testing.T) {
noTeamFile string
wantErr string
}{
{"testdata/gitops/no_team_software_installer_not_found.yml", "Please make sure that URLs are publicy accessible to the internet."},
{"testdata/gitops/no_team_software_installer_not_found.yml", "Please make sure that URLs are reachable from your Fleet server."},
{"testdata/gitops/no_team_software_installer_unsupported.yml", "The file should be .pkg, .msi, .exe or .deb."},
{"testdata/gitops/no_team_software_installer_too_large.yml", "The maximum file size is 500 MB"},
{"testdata/gitops/no_team_software_installer_too_large.yml", "The maximum file size is 500 MiB"},
{"testdata/gitops/no_team_software_installer_valid.yml", ""},
{"testdata/gitops/no_team_software_installer_pre_condition_multiple_queries.yml", "should have only one query."},
{"testdata/gitops/no_team_software_installer_pre_condition_not_found.yml", "no such file or directory"},
Expand Down Expand Up @@ -2050,6 +2073,7 @@ func setupFullGitOpsPremiumServer(t *testing.T) (*mock.Store, **fleet.AppConfig,
FleetConfig: &fleetCfg,
License: license,
NoCacheDatastore: true,
KeyValueStore: newMemKeyValueStore(),
},
)

Expand Down Expand Up @@ -2181,7 +2205,10 @@ func setupFullGitOpsPremiumServer(t *testing.T) (*mock.Store, **fleet.AppConfig,
declaration.DeclarationUUID = uuid.NewString()
return declaration, nil
}
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) ([]fleet.SoftwarePackageResponse, error) {
ds.BatchSetSoftwareInstallersFunc = func(ctx context.Context, teamID *uint, installers []*fleet.UploadSoftwareInstallerPayload) error {
return nil
}
ds.GetSoftwareInstallersFunc = func(ctx context.Context, tmID uint) ([]fleet.SoftwarePackageResponse, error) {
return nil, nil
}

Expand Down Expand Up @@ -2399,7 +2426,6 @@ software:
ipadTeam,
},
dryRunAssertion: func(t *testing.T, appCfg *fleet.AppConfig, ds fleet.Datastore, out string, err error) {
t.Log(out)
require.ErrorContains(t, err, "mdm.apple_bm_default_team has been deprecated")
assert.NotContains(t, out, "[!] gitops dry run succeeded")
},
Expand All @@ -2420,10 +2446,10 @@ software:
workstations,
},
dryRunAssertion: func(t *testing.T, appCfg *fleet.AppConfig, ds fleet.Datastore, out string, err error) {
assert.ErrorContains(t, err, "apple_business_manager team 📱🏢 Company-owned iPhones not found in team configs")
assert.ErrorContains(t, err, "apple_business_manager team \"📱🏢 Company-owned iPhones\" not found in team configs")
},
realRunAssertion: func(t *testing.T, appCfg *fleet.AppConfig, ds fleet.Datastore, out string, err error) {
assert.ErrorContains(t, err, "apple_business_manager team 📱🏢 Company-owned iPhones not found in team configs")
assert.ErrorContains(t, err, "apple_business_manager team \"📱🏢 Company-owned iPhones\" not found in team configs")
},
},
{
Expand Down Expand Up @@ -2891,3 +2917,26 @@ software:
})
}
}

type memKeyValueStore struct {
m map[string]string
}

func newMemKeyValueStore() *memKeyValueStore {
return &memKeyValueStore{
m: make(map[string]string),
}
}

func (m *memKeyValueStore) Set(ctx context.Context, key string, value string, expireTime time.Duration) error {
m.m[key] = value
return nil
}

func (m *memKeyValueStore) Get(ctx context.Context, key string) (*string, error) {
v, ok := m.m[key]
if !ok {
return nil, nil
}
return &v, nil
}
34 changes: 31 additions & 3 deletions docs/Configuration/yaml-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -585,16 +585,44 @@ Can only be configured for all teams (`org_settings`).

#### mdm

The `mdm` section lets you enable MDM features in Fleet.
##### apple_business_manager

- `apple_bm_default_team` - is name of the team that macOS hosts in Apple Business Manager automatically enroll to when they're first set up. If empty, hosts will enroll to "No team" (default: `""`).
- `organization_name` is the organization name associated with the Apple Business Manager account.
- `macos_team` is the team where macOS hosts are automatically added when they appear in Apple Business Manager.
- `ios_team` is the the team where iOS hosts are automatically added when they appear in Apple Business Manager.
- `ipados_team` is the team where iPadOS hosts are automatically added when they appear in Apple Business Manager.

##### Example

```yaml
org_settings:
mdm:
apple_bm_default_team: "Workstations" # Available in Fleet Premium
apple_business_manager: # Available in Fleet Premium
- organization_name: Fleet Device Management Inc.
macos_team: "💻 Workstations"
ios_team: "📱🏢 Company-owned iPhones"
ipados_team: "🔳🏢 Company-owned iPads"
```

> Apple Business Manager settings can only be configured for all teams (`org_settings`).

##### volume_purchasing_program

- `location` is the name of the location in the Apple Business Manager account.
- `teams` is a list of team names. If you choose specific teams, App Store apps in this VPP account will only be available to install on hosts in these teams. If not specified, App Store apps are available to install on hosts in all teams.

##### Example

```yaml
org_settings:
mdm:
volume_purchasing_program: # Available in Fleet Premium
- location: Fleet Device Management Inc.
teams:
- "💻 Workstations"
- "💻🐣 Workstations (canary)"
- "📱🏢 Company-owned iPhones"
- "🔳🏢 Company-owned iPads"
```

Can only be configured for all teams (`org_settings`).
Expand Down
Loading
Loading