Fix issue preventing "Install Fleet's agent (fleetd) manually" from saving (#34418)

<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #34410

# Checklist for submitter

## Testing

- [X] Added/updated automated tests
There was already a test for this but it was mocking the wrong thing;
now it mocks the return from the "get bootstrap metadata" method.
- [X] QA'd all new/changed functionality manually
- "Install Fleet's agent (fleetd) manually" still disabled if there's no
bootstrap or if software/scripts exists in setup experience
- Verified that if there's just a bootstrap and no software or scripts,
"Install Fleet's agent (fleetd) manually" can be checked and saved on No
Team
  - Verified the same on a tesm.

For unreleased bug fixes in a release candidate, one of:

- [X] Confirmed that the fix is not expected to adversely impact load
test results
This commit is contained in:
Scott Gress
2025-10-16 20:38:57 -05:00
committed by GitHub
parent 004e473887
commit 911feb74b2
3 changed files with 50 additions and 3 deletions
+8 -1
View File
@@ -225,7 +225,14 @@ func (svc *Service) updateAppConfigMDMAppleSetup(ctx context.Context, payload fl
if payload.ManualAgentInstall != nil {
if ac.MDM.MacOSSetup.ManualAgentInstall.Value != *payload.ManualAgentInstall {
if *payload.ManualAgentInstall && (!ac.MDM.MacOSSetup.BootstrapPackage.Set || ac.MDM.MacOSSetup.BootstrapPackage.Value == "") {
// Try to load the bootstrap package to verify it exists.
_, err := svc.GetMDMAppleBootstrapPackageMetadata(ctx, 0, false)
// If we got an error other than not found, return it.
if err != nil && !fleet.IsNotFound(err) {
return ctxerr.Wrap(ctx, err, "checking bootstrap package")
}
// Otherwise if we got a not found error, we can't enable manual agent install.
if *payload.ManualAgentInstall && err != nil {
return fleet.NewUserMessageError(errors.New("Couldnt enable manual_agent_install. To use this option, first specify a bootstrap_package."), http.StatusUnprocessableEntity)
}
sec, err := svc.ds.GetSetupExperienceCount(ctx, string(fleet.MacOSPlatform), nil)
+8 -1
View File
@@ -1790,7 +1790,14 @@ func (svc *Service) updateTeamMDMAppleSetup(ctx context.Context, tm *fleet.Team,
if payload.ManualAgentInstall != nil {
if tm.Config.MDM.MacOSSetup.ManualAgentInstall.Value != *payload.ManualAgentInstall {
if *payload.ManualAgentInstall && (!tm.Config.MDM.MacOSSetup.BootstrapPackage.Set || tm.Config.MDM.MacOSSetup.BootstrapPackage.Value == "") {
// Try to load the bootstrap package to verify it exists.
_, err := svc.GetMDMAppleBootstrapPackageMetadata(ctx, tm.ID, false)
// If we got an error other than not found, return it.
if err != nil && !fleet.IsNotFound(err) {
return ctxerr.Wrap(ctx, err, "checking bootstrap package")
}
// Otherwise if we got a not found error, we can't enable manual agent install.
if *payload.ManualAgentInstall && err != nil {
return fleet.NewUserMessageError(errors.New("Couldnt enable manual_agent_install. To use this option, first specify a bootstrap_package."), http.StatusUnprocessableEntity)
}
sec, err := svc.ds.GetSetupExperienceCount(ctx, string(fleet.MacOSPlatform), &tm.ID)
+34 -1
View File
@@ -6,10 +6,12 @@ import (
"testing"
"github.com/fleetdm/fleet/v4/pkg/optjson"
"github.com/fleetdm/fleet/v4/server/authz"
"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mock"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/fleetdm/fleet/v4/server/test"
"github.com/stretchr/testify/require"
)
@@ -179,6 +181,18 @@ func TestObfuscateSecrets(t *testing.T) {
})
}
type bootstrapNotFoundError struct {
msg string
}
func (e *bootstrapNotFoundError) Error() string {
return e.msg
}
func (e *bootstrapNotFoundError) IsNotFound() bool {
return true
}
func TestUpdateTeamMDMAppleSetupManualAgent(t *testing.T) {
cases := []struct {
Name string
@@ -246,6 +260,9 @@ func TestUpdateTeamMDMAppleSetupManualAgent(t *testing.T) {
return &fleet.Team{}, nil
}
authorizer, err := authz.NewAuthorizer()
require.NoError(t, err)
svc := &Service{
ds: ds,
config: config.FleetConfig{
@@ -253,12 +270,28 @@ func TestUpdateTeamMDMAppleSetupManualAgent(t *testing.T) {
PrivateKey: "something",
},
},
authz: authorizer,
}
ctx := context.Background()
// Add admin user to context
adminUser := &fleet.User{
ID: 2,
GlobalRole: ptr.String(fleet.RoleAdmin),
Email: "useradmin@example.com",
}
ctx := test.UserContext(context.Background(), adminUser)
for _, tc := range cases {
t.Run(tc.Name, func(t *testing.T) {
ds.GetMDMAppleBootstrapPackageMetaFunc = func(ctx context.Context, teamID uint) (*fleet.MDMAppleBootstrapPackage, error) {
if tc.MacOSSetup.BootstrapPackage.Value == "" {
return nil, &bootstrapNotFoundError{msg: "bootstrap package not found"}
}
return &fleet.MDMAppleBootstrapPackage{
Name: tc.MacOSSetup.BootstrapPackage.Value,
}, nil
}
ds.GetSetupExperienceCountFunc = func(ctx context.Context, platform string, teamID *uint) (*fleet.SetupExperienceCount, error) {
return &tc.Count, nil
}