Next set of slog migration changes for MDM (#39981)

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

Incremental set of slog migration changes for MDM packages.

# Checklist for submitter
- [ ] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
  - already added in a previous PR

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Standardized logging to Go's structured slog across MDM (Apple,
Windows), DEP/ABM flows, maintained app sync, and related
tests—improving log consistency and contextual diagnostics without
changing user-facing behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Victor Lyuboslavsky
2026-02-19 11:40:52 -06:00
committed by GitHub
parent ea5260e6e3
commit 4236363522
21 changed files with 121 additions and 131 deletions
+8 -8
View File
@@ -767,8 +767,8 @@ func newWorkerIntegrationsSchedule(
// we leave depSvc and deCli nil and macos setup assistants jobs will be
// no-ops.
if depStorage != nil {
depSvc = apple_mdm.NewDEPService(ds, depStorage, logger)
depCli = apple_mdm.NewDEPClient(depStorage, ds, logger)
depSvc = apple_mdm.NewDEPService(ds, depStorage, logger.SlogLogger())
depCli = apple_mdm.NewDEPClient(depStorage, ds, logger.SlogLogger())
}
macosSetupAsst := &worker.MacosSetupAssistant{
Datastore: ds,
@@ -1385,7 +1385,7 @@ func appleMDMDEPSyncerJob(
}
if incompleteToken != nil {
logger.Log("msg", "migrated ABM token found, updating its metadata")
if err := apple_mdm.SetABMTokenMetadata(ctx, incompleteToken, depStorage, ds, logger, false); err != nil {
if err := apple_mdm.SetABMTokenMetadata(ctx, incompleteToken, depStorage, ds, logger.SlogLogger(), false); err != nil {
return ctxerr.Wrap(ctx, err, "updating migrated ABM token metadata")
}
if err := ds.SaveABMToken(ctx, incompleteToken); err != nil {
@@ -1395,7 +1395,7 @@ func appleMDMDEPSyncerJob(
}
if fleetSyncer == nil {
fleetSyncer = apple_mdm.NewDEPService(ds, depStorage, logger)
fleetSyncer = apple_mdm.NewDEPService(ds, depStorage, logger.SlogLogger())
}
return fleetSyncer.RunAssigner(ctx)
@@ -1451,7 +1451,7 @@ func newWindowsMDMProfileManagerSchedule(
ctx, name, instanceID, defaultInterval, ds, ds,
schedule.WithLogger(logger),
schedule.WithJob("manage_windows_profiles", func(ctx context.Context) error {
return service.ReconcileWindowsProfiles(ctx, ds, logger)
return service.ReconcileWindowsProfiles(ctx, ds, logger.SlogLogger())
}),
)
@@ -1699,7 +1699,7 @@ func newIPhoneIPadRefetcher(
ctx, name, instanceID, periodicity, ds, ds,
schedule.WithLogger(logger),
schedule.WithJob("cron_iphone_ipad_refetcher", func(ctx context.Context) error {
return apple_mdm.IOSiPadOSRefetch(ctx, ds, commander, logger, newActivityFn)
return apple_mdm.IOSiPadOSRefetch(ctx, ds, commander, logger.SlogLogger(), newActivityFn)
}),
)
@@ -1778,7 +1778,7 @@ func newMaintainedAppSchedule(
// ensures it runs a few seconds after Fleet is started
schedule.WithDefaultPrevRunCreatedAt(time.Now().Add(priorJobDiff)),
schedule.WithJob("refresh_maintained_apps", func(ctx context.Context) error {
return maintained_apps.Refresh(ctx, ds, logger)
return maintained_apps.Refresh(ctx, ds, logger.SlogLogger())
}),
)
@@ -1826,7 +1826,7 @@ func newIPhoneIPadReviver(
ctx, name, instanceID, 1*time.Hour, ds, ds,
schedule.WithLogger(logger),
schedule.WithJob("cron_iphone_ipad_reviver", func(ctx context.Context) error {
return apple_mdm.IOSiPadOSRevive(ctx, ds, commander, logger)
return apple_mdm.IOSiPadOSRevive(ctx, ds, commander, logger.SlogLogger())
}),
)
+2 -2
View File
@@ -1415,7 +1415,7 @@ func (svc *Service) UploadABMToken(ctx context.Context, token io.Reader) (*fleet
EncryptedToken: encryptedToken,
}
if err := apple_mdm.SetDecryptedABMTokenMetadata(ctx, tok, decryptedToken, svc.depStorage, svc.ds, svc.logger, false); err != nil {
if err := apple_mdm.SetDecryptedABMTokenMetadata(ctx, tok, decryptedToken, svc.depStorage, svc.ds, svc.logger.SlogLogger(), false); err != nil {
return nil, ctxerr.Wrap(ctx, err, "setting ABM token metadata")
}
@@ -1576,7 +1576,7 @@ func (svc *Service) RenewABMToken(ctx context.Context, token io.Reader, tokenID
return nil, ctxerr.Wrap(ctx, err, "decrypting ABM token for renewal")
}
if err := apple_mdm.SetDecryptedABMTokenMetadata(ctx, oldTok, decryptedToken, svc.depStorage, svc.ds, svc.logger, true); err != nil {
if err := apple_mdm.SetDecryptedABMTokenMetadata(ctx, oldTok, decryptedToken, svc.depStorage, svc.ds, svc.logger.SlogLogger(), true); err != nil {
return nil, ctxerr.Wrap(ctx, err, "setting ABM token metadata")
}
+1 -1
View File
@@ -75,7 +75,7 @@ func NewService(
depStorage: depStorage,
mdmAppleCommander: mdmAppleCommander,
ssoSessionStore: sso,
depService: apple_mdm.NewDEPService(ds, depStorage, logger),
depService: apple_mdm.NewDEPService(ds, depStorage, logger.SlogLogger()),
profileMatcher: profileMatcher,
softwareInstallStore: softwareInstallStore,
bootstrapPackageStore: bootstrapPackageStore,
+1 -1
View File
@@ -241,7 +241,7 @@ func TestDEPClient(t *testing.T) {
return &nanodep_client.Config{BaseURL: srv.URL}, nil
}
dep := apple_mdm.NewDEPClient(store, ds, logger)
dep := apple_mdm.NewDEPClient(store, ds, logger.SlogLogger())
orgName := c.orgName
if orgName == "" {
// simulate using a new token, not yet saved in the DB, so we pass the
+3 -3
View File
@@ -3,6 +3,7 @@ package apple_mdm
import (
"context"
"errors"
"log/slog"
"net/http"
abmctx "github.com/fleetdm/fleet/v4/server/contexts/apple_bm"
@@ -11,7 +12,6 @@ import (
"github.com/fleetdm/fleet/v4/server/mdm/assets"
depclient "github.com/fleetdm/fleet/v4/server/mdm/nanodep/client"
"github.com/fleetdm/fleet/v4/server/mdm/nanodep/storage"
"github.com/fleetdm/fleet/v4/server/platform/logging"
)
// SetABMTokenMetadata uses the provided ABM token to fetch the associated
@@ -23,7 +23,7 @@ func SetABMTokenMetadata(
abmToken *fleet.ABMToken,
depStorage storage.AllDEPStorage,
ds fleet.Datastore,
logger *logging.Logger,
logger *slog.Logger,
renewal bool,
) error {
decryptedToken, err := assets.ABMToken(ctx, ds, abmToken.OrganizationName)
@@ -42,7 +42,7 @@ func SetDecryptedABMTokenMetadata(
decryptedToken *depclient.OAuth1Tokens,
depStorage storage.AllDEPStorage,
ds fleet.Datastore,
logger *logging.Logger,
logger *slog.Logger,
renewal bool,
) error {
depClient := NewDEPClient(depStorage, ds, logger)
+41 -47
View File
@@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"fmt"
"log/slog"
"net/url"
"slices"
"strings"
@@ -21,7 +22,6 @@ import (
"github.com/fleetdm/fleet/v4/server/mdm/internal/commonmdm"
"github.com/fleetdm/fleet/v4/server/mdm/nanodep/godep"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/go-kit/log/level"
"github.com/google/uuid"
"github.com/hashicorp/go-multierror"
@@ -92,7 +92,7 @@ type DEPService struct {
ds fleet.Datastore
depStorage nanodep_storage.AllDEPStorage
depClient *godep.Client
logger *platformlogging.Logger
logger *slog.Logger
}
// getDefaultProfile returns a godep.Profile with default values set.
@@ -267,7 +267,7 @@ func (d *DEPService) RegisterProfileWithAppleDEPServer(ctx context.Context, team
}
if len(orgNames) == 0 {
d.logger.Log("msg", "skipping defining profile for team with no relevant ABM token")
d.logger.InfoContext(ctx, "skipping defining profile for team with no relevant ABM token")
return "", time.Time{}, nil
}
@@ -396,7 +396,7 @@ func (d *DEPService) EnsureDefaultSetupAssistant(ctx context.Context, team *flee
return "", time.Time{}, ctxerr.Wrap(ctx, err, "get default setup assistant profile uuid")
}
if profUUID == "" {
d.logger.Log("msg", "default DEP profile not set, registering")
d.logger.InfoContext(ctx, "default DEP profile not set, registering")
profUUID, modTime, err = d.RegisterProfileWithAppleDEPServer(ctx, team, nil, abmTokenOrgName)
if err != nil {
return "", time.Time{}, ctxerr.Wrap(ctx, err, "register default setup assistant with Apple")
@@ -443,7 +443,7 @@ func (d *DEPService) EnsureCustomSetupAssistantIfExists(ctx context.Context, tea
}
func (d *DEPService) RunAssigner(ctx context.Context) error {
syncerLogger := logging.NewNanoDEPLogger(d.logger.With("component", "nanodep-syncer"))
syncerLogger := logging.NewNanoDEPLogger(platformlogging.NewLogger(d.logger.With("component", "nanodep-syncer")))
teams, err := d.ds.ListTeams(
ctx, fleet.TeamFilter{
User: &fleet.User{
@@ -512,7 +512,7 @@ func (d *DEPService) RunAssigner(ctx context.Context) error {
}
if cursor != "" && effectiveProfModTime.After(cursorModTime) {
d.logger.Log("msg", "clearing device syncer cursor", "org_name", token.OrganizationName)
d.logger.InfoContext(ctx, "clearing device syncer cursor", "org_name", token.OrganizationName)
if err := d.depStorage.StoreCursor(ctx, token.OrganizationName, ""); err != nil {
result = multierror.Append(result, err)
continue
@@ -572,7 +572,7 @@ func (d *DEPService) AssignMDMAppleServiceDiscoveryURL(ctx context.Context, toke
func NewDEPService(
ds fleet.Datastore,
depStorage nanodep_storage.AllDEPStorage,
logger *platformlogging.Logger,
logger *slog.Logger,
) *DEPService {
depSvc := &DEPService{
depStorage: depStorage,
@@ -626,8 +626,7 @@ func (d *DEPService) processDeviceResponse(
deadline = device.MDMMigrationDeadline.String()
}
// FIXME: Move this log back to debug level after we've added/improved functionality for accessing DEP status.
level.Info(d.logger).Log(
"msg", "process device response",
d.logger.InfoContext(ctx, "process device response",
"serial_number", device.SerialNumber,
"device_assigned_by", device.DeviceAssignedBy,
"device_assigned_date", device.DeviceAssignedDate,
@@ -651,8 +650,7 @@ func (d *DEPService) processDeviceResponse(
case "deleted":
keepRecent(device, deletedDevices)
default:
level.Warn(d.logger).Log(
"msg", "unrecognized op_type",
d.logger.WarnContext(ctx, "unrecognized op_type",
"op_type", device.OpType,
"serial_number", device.SerialNumber,
)
@@ -711,7 +709,7 @@ func (d *DEPService) processDeviceResponse(
// the wrong op_type.
for _, md := range modifiedDevices {
if _, ok := existingSerials[md.SerialNumber]; !ok {
level.Info(d.logger).Log("msg", "treating device with op_type modified as added device", "serial_number", md.SerialNumber)
d.logger.InfoContext(ctx, "treating device with op_type modified as added device", "serial_number", md.SerialNumber)
addedDevicesSlice = append(addedDevicesSlice, md)
}
// FIXME: addedDevicesSlice is used in part to determine if a profile assignment is needed.
@@ -747,15 +745,15 @@ func (d *DEPService) processDeviceResponse(
n, err := d.ds.IngestMDMAppleDevicesFromDEPSync(ctx, addedDevicesSlice, abmTokenID, macOSTeam, iosTeam, ipadTeam)
switch {
case err != nil:
level.Error(d.logger).Log("err", err)
d.logger.ErrorContext(ctx, "error ingesting DEP devices", "err", err)
ctxerr.Handle(ctx, err)
case n > 0:
level.Info(d.logger).Log("msg", fmt.Sprintf("added %d new mdm device(s) to pending hosts", n))
d.logger.InfoContext(ctx, fmt.Sprintf("added %d new mdm device(s) to pending hosts", n))
case n == 0:
level.Debug(d.logger).Log("msg", "no DEP hosts to add")
d.logger.DebugContext(ctx, "no DEP hosts to add")
}
level.Info(d.logger).Log("msg", "devices to assign DEP profiles",
d.logger.InfoContext(ctx, "devices to assign DEP profiles",
"to_add", strings.Join(addedSerials, ", "),
"to_remove", strings.Join(deletedSerials, ", "),
"to_modify", strings.Join(modifiedSerials, ", "),
@@ -798,10 +796,10 @@ func (d *DEPService) processDeviceResponse(
existingHosts := []fleet.Host{}
existingHostMigrationDeadlines := make(map[uint]time.Time)
for _, existingHost := range existingSerials {
level.Info(d.logger).Log("msg", "preparing to upsert DEP assignment for existing host", "serial", existingHost.HardwareSerial, "host_id", existingHost.ID)
d.logger.InfoContext(ctx, "preparing to upsert DEP assignment for existing host", "serial", existingHost.HardwareSerial, "host_id", existingHost.ID)
md, ok := modifiedDevices[existingHost.HardwareSerial]
if !ok {
level.Error(d.logger).Log("msg",
d.logger.ErrorContext(ctx,
"serial coming from ABM is in the database, but it's not in the list of modified devices", "serial",
existingHost.HardwareSerial)
continue
@@ -860,11 +858,11 @@ func (d *DEPService) processDeviceResponse(
if len(skipSerials) > 0 {
// NOTE: the `dep_cooldown` job of the `integrations`` cron picks up the assignments
// after the cooldown period is over
level.Info(logger).Log("msg", "process device response: skipping assign profile for devices on cooldown", "serials", fmt.Sprintf("%s",
logger.InfoContext(ctx, "process device response: skipping assign profile for devices on cooldown", "serials", fmt.Sprintf("%s",
skipSerials))
}
if len(assignSerials) == 0 {
level.Info(logger).Log("msg", "process device response: no devices to assign profile")
logger.InfoContext(ctx, "process device response: no devices to assign profile")
continue
}
@@ -874,8 +872,7 @@ func (d *DEPService) processDeviceResponse(
// only log the error so the failure can be recorded
// below in UpdateHostDEPAssignProfileResponses and
// the proper cooldowns are applied
level.Error(logger).Log(
"msg", "assign profile",
logger.ErrorContext(ctx, "assign profile",
"devices", len(serials),
"err", err,
)
@@ -896,18 +893,17 @@ func (d *DEPService) processDeviceResponse(
}
// We don't expect to see this but log here just in case
if err != nil && implicitlyFailedAssignments > 0 {
level.Error(logger).Log(
"msg", "assign profile: no error was returned but some devices were not assigned a status in the response",
logger.ErrorContext(ctx,
"assign profile: no error was returned but some devices were not assigned a status in the response",
"devices", implicitlyFailedAssignments,
)
}
logs := []interface{}{
"msg", "profile assigned",
attrs := []any{
"devices", len(serials),
}
logs = append(logs, logCountsForResults(apiResp.Devices)...)
level.Info(logger).Log(logs...)
attrs = append(attrs, logCountsForResults(apiResp.Devices)...)
logger.InfoContext(ctx, "profile assigned", attrs...)
if err := d.ds.UpdateHostDEPAssignProfileResponses(ctx, apiResp, abmTokenID); err != nil {
return ctxerr.Wrap(ctx, err, "update host dep assign profile responses")
@@ -916,7 +912,7 @@ func (d *DEPService) processDeviceResponse(
}
if len(skippedSerials) > 0 {
level.Info(d.logger).Log("msg", "found devices that already have the right profile, skipping assignment", "serials",
d.logger.InfoContext(ctx, "found devices that already have the right profile, skipping assignment", "serials",
fmt.Sprintf("%s", skippedSerials))
}
@@ -970,7 +966,7 @@ func logCountsForResults(deviceResults map[string]string) (out []interface{}) {
// storage that will flag the ABM token's terms expired field and the
// AppConfig's AppleBMTermsExpired field whenever the status of the terms
// changes.
func NewDEPClient(storage godep.ClientStorage, updater fleet.ABMTermsUpdater, logger *platformlogging.Logger) *godep.Client {
func NewDEPClient(storage godep.ClientStorage, updater fleet.ABMTermsUpdater, logger *slog.Logger) *godep.Client {
return godep.NewClient(storage, fleethttp.NewClient(), godep.WithAfterHook(func(ctx context.Context, reqErr error) error {
// to check for ABM terms expired, we must have an ABM token organization
// name and NOT a raw ABM token in the context (as the presence of a raw
@@ -990,14 +986,14 @@ func NewDEPClient(storage godep.ClientStorage, updater fleet.ABMTermsUpdater, lo
// get the count of tokens with the flag still set
count, err := updater.CountABMTokensWithTermsExpired(ctx)
if err != nil {
level.Error(logger).Log("msg", "Apple DEP client: failed to get count of tokens with terms expired", "err", err)
logger.ErrorContext(ctx, "Apple DEP client: failed to get count of tokens with terms expired", "err", err)
return reqErr
}
// get the appconfig for the global flag
appCfg, err := updater.AppConfig(ctx)
if err != nil {
level.Error(logger).Log("msg", "Apple DEP client: failed to get app config", "err", err)
logger.ErrorContext(ctx, "Apple DEP client: failed to get app config", "err", err)
return reqErr
}
@@ -1011,7 +1007,7 @@ func NewDEPClient(storage godep.ClientStorage, updater fleet.ABMTermsUpdater, lo
// otherwise, update the specific ABM token's flag
wasSet, err := updater.SetABMTokenTermsExpiredForOrgName(ctx, orgName, termsExpired)
if err != nil {
level.Error(logger).Log("msg", "Apple DEP client: failed to update terms expired of ABM token", "err", err)
logger.ErrorContext(ctx, "Apple DEP client: failed to update terms expired of ABM token", "err", err)
return reqErr
}
@@ -1037,9 +1033,9 @@ func NewDEPClient(storage godep.ClientStorage, updater fleet.ABMTermsUpdater, lo
if mustSaveAppCfg {
if err := updater.SaveAppConfig(ctx, appCfg); err != nil {
level.Error(logger).Log("msg", "Apple DEP client: failed to save app config", "err", err)
logger.ErrorContext(ctx, "Apple DEP client: failed to save app config", "err", err)
}
level.Info(logger).Log("msg", "Apple DEP client: updated app config Terms Expired flag",
logger.InfoContext(ctx, "Apple DEP client: updated app config Terms Expired flag",
"apple_bm_terms_expired", appCfg.MDM.AppleBMTermsExpired)
}
}
@@ -1400,16 +1396,15 @@ func (pb *ProfileBimap) add(wantedProfile, currentProfile *fleet.MDMAppleProfile
// NewActivityFunc is the function signature for creating a new activity.
type NewActivityFunc func(ctx context.Context, user *fleet.User, activity fleet.ActivityDetails) error
func IOSiPadOSRefetch(ctx context.Context, ds fleet.Datastore, commander *MDMAppleCommander, logger *platformlogging.Logger,
newActivityFn NewActivityFunc,
) error {
func IOSiPadOSRefetch(ctx context.Context, ds fleet.Datastore, commander *MDMAppleCommander, logger *slog.Logger,
newActivityFn NewActivityFunc) error {
appCfg, err := ds.AppConfig(ctx)
if err != nil {
return ctxerr.Wrap(ctx, err, "fetching app config")
}
if !appCfg.MDM.EnabledAndConfigured {
level.Debug(logger).Log("msg", "apple mdm is not configured, skipping run")
logger.DebugContext(ctx, "apple mdm is not configured, skipping run")
return nil
}
@@ -1421,7 +1416,7 @@ func IOSiPadOSRefetch(ctx context.Context, ds fleet.Datastore, commander *MDMApp
if len(devices) == 0 {
return nil
}
logger.Log("msg", "sending commands to refetch", "count", len(devices), "lookup-duration", time.Since(start))
logger.InfoContext(ctx, "sending commands to refetch", "count", len(devices), "lookup-duration", time.Since(start))
hostMDMCommands := make([]fleet.HostMDMCommand, 0, 3*len(devices))
installedAppsUUIDs := struct {
@@ -1515,9 +1510,8 @@ func IOSiPadOSRefetch(ctx context.Context, ds fleet.Datastore, commander *MDMApp
// turnOffMDMIfAPNSFailed checks if the error is an APNSDeliveryError and turns off MDM for the failed devices.
// Returns a boolean value to indicate whether or not MDM was turned off.
func turnOffMDMIfAPNSFailed(ctx context.Context, ds fleet.Datastore, err error, logger *platformlogging.Logger, newActivityFn NewActivityFunc) (bool,
error,
) {
func turnOffMDMIfAPNSFailed(ctx context.Context, ds fleet.Datastore, err error, logger *slog.Logger, newActivityFn NewActivityFunc) (bool,
error) {
var e *APNSDeliveryError
if !errors.As(err, &e) {
return false, nil
@@ -1525,7 +1519,7 @@ func turnOffMDMIfAPNSFailed(ctx context.Context, ds fleet.Datastore, err error,
for uuid, err := range e.errorsByUUID {
if strings.Contains(err.Error(), "device token is inactive") {
level.Info(logger).Log("msg", "turning off MDM for device with inactive device token", "uuid", uuid)
logger.InfoContext(ctx, "turning off MDM for device with inactive device token", "uuid", uuid)
users, activities, err := ds.MDMTurnOff(ctx, uuid)
if err != nil {
return false, ctxerr.Wrap(ctx, err, "turn off mdm for failed device")
@@ -1582,14 +1576,14 @@ func GenerateOTAEnrollmentProfileMobileconfig(orgName, fleetURL, enrollSecret, i
return profileBuf.Bytes(), nil
}
func IOSiPadOSRevive(ctx context.Context, ds fleet.Datastore, commander *MDMAppleCommander, logger *platformlogging.Logger) error {
func IOSiPadOSRevive(ctx context.Context, ds fleet.Datastore, commander *MDMAppleCommander, logger *slog.Logger) error {
appCfg, err := ds.AppConfig(ctx)
if err != nil {
return ctxerr.Wrap(ctx, err, "fetching app config")
}
if !appCfg.MDM.EnabledAndConfigured {
level.Debug(logger).Log("msg", "apple mdm is not configured, skipping run")
logger.DebugContext(ctx, "apple mdm is not configured, skipping run")
return nil
}
@@ -1604,7 +1598,7 @@ func IOSiPadOSRevive(ctx context.Context, ds fleet.Datastore, commander *MDMAppl
if err := commander.SendNotifications(ctx, ids); err != nil {
var apnsErr *APNSDeliveryError
if errors.As(err, &apnsErr) {
level.Info(logger).Log("msg", "failed to send APNs notification to some hosts", "error", apnsErr.Error())
logger.InfoContext(ctx, "failed to send APNs notification to some hosts", "error", apnsErr.Error())
return nil
}
return ctxerr.Wrap(ctx, err, "sending push notifications")
+2 -2
View File
@@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"net/http/httptest"
"testing"
@@ -16,7 +17,6 @@ import (
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
nanodep_client "github.com/fleetdm/fleet/v4/server/mdm/nanodep/client"
"github.com/fleetdm/fleet/v4/server/mdm/nanodep/godep"
"github.com/fleetdm/fleet/v4/server/platform/logging"
"github.com/fleetdm/fleet/v4/server/test"
"github.com/jmoiron/sqlx"
"github.com/stretchr/testify/require"
@@ -41,7 +41,7 @@ func TestDEPService_RunAssigner(t *testing.T) {
mysql.SetTestABMAssets(t, ds, abmTokenOrgName)
logger := logging.NewNopLogger()
logger := slog.New(slog.DiscardHandler)
return apple_mdm.NewDEPService(ds, depStorage, logger)
}
+2 -2
View File
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"io"
"log/slog"
"net/http"
"net/http/httptest"
"testing"
@@ -15,7 +16,6 @@ import (
"github.com/fleetdm/fleet/v4/server/mdm/nanodep/godep"
"github.com/fleetdm/fleet/v4/server/mock"
nanodep_mock "github.com/fleetdm/fleet/v4/server/mock/nanodep"
"github.com/fleetdm/fleet/v4/server/platform/logging"
"github.com/micromdm/plist"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -25,7 +25,7 @@ func TestDEPService(t *testing.T) {
t.Run("EnsureDefaultSetupAssistant", func(t *testing.T) {
ds := new(mock.Store)
ctx := context.Background()
logger := logging.NewNopLogger()
logger := slog.New(slog.DiscardHandler)
depStorage := new(nanodep_mock.Storage)
depSvc := NewDEPService(ds, depStorage, logger)
defaultProfile := depSvc.getDefaultProfile()
+2 -2
View File
@@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"time"
@@ -14,7 +15,6 @@ import (
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
kitlog "github.com/go-kit/log"
)
type appListing struct {
@@ -33,7 +33,7 @@ const fmaOutputsBase = "https://raw.githubusercontent.com/fleetdm/fleet/refs/hea
// Refresh fetches the latest information about maintained apps from FMA's
// apps list on GitHub and updates the Fleet database with the new information.
func Refresh(ctx context.Context, ds fleet.Datastore, logger kitlog.Logger) error {
func Refresh(ctx context.Context, ds fleet.Datastore, logger *slog.Logger) error {
appsList, err := FetchAppsList(ctx)
if err != nil {
return err
+5 -5
View File
@@ -3,6 +3,7 @@ package maintained_apps
import (
"context"
"encoding/json"
"log/slog"
"net/http"
"net/http/httptest"
"os"
@@ -12,7 +13,6 @@ import (
"github.com/fleetdm/fleet/v4/server/dev_mode"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/go-kit/log"
"github.com/stretchr/testify/require"
)
@@ -45,7 +45,7 @@ func SyncApps(t *testing.T, ds fleet.Datastore) []fleet.MaintainedApp {
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", srv.URL)
defer dev_mode.ClearOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
err := Refresh(context.Background(), ds, log.NewNopLogger())
err := Refresh(context.Background(), ds, slog.New(slog.DiscardHandler))
require.NoError(t, err)
apps, _, err := ds.ListAvailableFleetMaintainedApps(context.Background(), nil, fleet.ListOptions{
@@ -101,7 +101,7 @@ func SyncAndRemoveApps(t *testing.T, ds fleet.Datastore) {
dev_mode.SetOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL", srv.URL)
defer dev_mode.ClearOverride("FLEET_DEV_MAINTAINED_APPS_BASE_URL")
err = Refresh(context.Background(), ds, log.NewNopLogger())
err = Refresh(context.Background(), ds, slog.New(slog.DiscardHandler))
require.NoError(t, err)
originalApps, _, err := ds.ListAvailableFleetMaintainedApps(context.Background(), nil, fleet.ListOptions{})
@@ -113,7 +113,7 @@ func SyncAndRemoveApps(t *testing.T, ds fleet.Datastore) {
removedApp := appsFile.Apps[0]
appsFile.Apps = appsFile.Apps[1:]
err = Refresh(context.Background(), ds, log.NewNopLogger())
err = Refresh(context.Background(), ds, slog.New(slog.DiscardHandler))
require.NoError(t, err)
modifiedApps, _, err := ds.ListAvailableFleetMaintainedApps(context.Background(), nil, fleet.ListOptions{})
@@ -128,7 +128,7 @@ func SyncAndRemoveApps(t *testing.T, ds fleet.Datastore) {
// remove all apps from upstream.
appsFile.Apps = []appListing{}
err = Refresh(context.Background(), ds, log.NewNopLogger())
err = Refresh(context.Background(), ds, slog.New(slog.DiscardHandler))
require.NoError(t, err)
modifiedApps, _, err = ds.ListAvailableFleetMaintainedApps(context.Background(), nil, fleet.ListOptions{})
+9 -10
View File
@@ -7,6 +7,7 @@ import (
"fmt"
"hash/fnv"
"io"
"log/slog"
"maps"
"slices"
"strings"
@@ -18,8 +19,6 @@ import (
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/wlanxml"
"github.com/fleetdm/fleet/v4/server/mdm/profiles"
"github.com/fleetdm/fleet/v4/server/variables"
kitlog "github.com/go-kit/log"
"github.com/go-kit/log/level"
)
// LoopOverExpectedHostProfiles loops all the <LocURI> values on all the profiles for a
@@ -31,7 +30,7 @@ import (
// - The data (if any) of the first <Item> element of the current LocURI
func LoopOverExpectedHostProfiles(
ctx context.Context,
logger kitlog.Logger,
logger *slog.Logger,
ds fleet.Datastore,
host *fleet.Host,
fn func(profile *fleet.ExpectedMDMProfile, hash, locURI, data string),
@@ -115,7 +114,7 @@ func HashLocURI(profileName, locURI string) string {
// VerifyHostMDMProfiles performs the verification of the MDM profiles installed on a host and
// updates the verification status in the datastore. It is intended to be called by Fleet osquery
// service when the Fleet server ingests host details.
func VerifyHostMDMProfiles(ctx context.Context, logger kitlog.Logger, ds fleet.Datastore, host *fleet.Host,
func VerifyHostMDMProfiles(ctx context.Context, logger *slog.Logger, ds fleet.Datastore, host *fleet.Host,
rawProfileResultsSyncML []byte,
) error {
profileResults, err := transformProfileResults(rawProfileResultsSyncML)
@@ -180,7 +179,7 @@ func splitMissingProfilesIntoFailAndRetryBuckets(ctx context.Context, ds fleet.P
return toFail, toRetry, nil
}
func compareResultsToExpectedProfiles(ctx context.Context, logger kitlog.Logger, ds fleet.Datastore, host *fleet.Host,
func compareResultsToExpectedProfiles(ctx context.Context, logger *slog.Logger, ds fleet.Datastore, host *fleet.Host,
profileResults profileResultsTransform, existingProfiles []fleet.HostMDMWindowsProfile,
) (verified map[string]struct{}, missing map[string]struct{}, err error) {
missing = map[string]struct{}{}
@@ -258,7 +257,7 @@ func compareResultsToExpectedProfiles(ctx context.Context, logger kitlog.Logger,
if gotStatus == "404" && (IsADMXInstallConfigOperationCSP(locURI) || IsWin32OrDesktopBridgeADMXCSP(locURI)) {
if existingProfile, ok := windowsProfilesByID[profile.ProfileUUID]; ok && existingProfile.Status != nil &&
(*existingProfile.Status == fleet.MDMDeliveryVerified || *existingProfile.Status == fleet.MDMDeliveryVerifying) {
level.Debug(logger).Log("msg", "ADMX policy install operation or Win32/Desktop Bridge ADMX policy returned 404, marking as verified", "profile_uuid", profile.ProfileUUID, "host_id", host.ID, "locuri", locURI)
logger.DebugContext(ctx, "ADMX policy install operation or Win32/Desktop Bridge ADMX policy returned 404, marking as verified", "profile_uuid", profile.ProfileUUID, "host_id", host.ID, "locuri", locURI)
equal = true
}
}
@@ -278,7 +277,7 @@ func compareResultsToExpectedProfiles(ctx context.Context, logger kitlog.Logger,
}
}
if !equal {
level.Debug(logger).Log("msg", "Windows profile verification failed", "profile", profile.Name, "host_id", host.ID)
logger.DebugContext(ctx, "Windows profile verification failed", "profile", profile.Name, "host_id", host.ID)
withinGracePeriod := profile.IsWithinGracePeriod(host.DetailUpdatedAt)
if !withinGracePeriod {
missing[profile.Name] = struct{}{}
@@ -392,14 +391,14 @@ func (e *MicrosoftProfileProcessingError) Error() string {
type ProfilePreprocessDependencies interface {
GetContext() context.Context
GetLogger() kitlog.Logger
GetLogger() *slog.Logger
GetDS() fleet.Datastore
GetHostIdForUUIDCache() map[string]uint
}
type ProfilePreprocessDependenciesForVerify struct {
Context context.Context
Logger kitlog.Logger
Logger *slog.Logger
DataStore fleet.Datastore
HostIDForUUIDCache map[string]uint
}
@@ -408,7 +407,7 @@ func (p ProfilePreprocessDependenciesForVerify) GetContext() context.Context {
return p.Context
}
func (p ProfilePreprocessDependenciesForVerify) GetLogger() kitlog.Logger {
func (p ProfilePreprocessDependenciesForVerify) GetLogger() *slog.Logger {
return p.Logger
}
@@ -5,6 +5,7 @@ import (
"encoding/xml"
"fmt"
"io"
"log/slog"
"strings"
"testing"
"time"
@@ -15,7 +16,6 @@ import (
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/wlanxml"
"github.com/fleetdm/fleet/v4/server/mock"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/go-kit/log"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -68,7 +68,7 @@ func TestLoopHostMDMLocURIs(t *testing.T) {
uniqueHash string
}
got := []wantStruct{}
err := LoopOverExpectedHostProfiles(ctx, log.NewNopLogger(), ds, &fleet.Host{}, func(profile *fleet.ExpectedMDMProfile, hash, locURI, data string) {
err := LoopOverExpectedHostProfiles(ctx, slog.New(slog.DiscardHandler), ds, &fleet.Host{}, func(profile *fleet.ExpectedMDMProfile, hash, locURI, data string) {
got = append(got, wantStruct{
locURI: locURI,
data: data,
@@ -145,7 +145,7 @@ func TestVerifyHostMDMProfilesErrors(t *testing.T) {
ctx := context.Background()
host := &fleet.Host{}
err := VerifyHostMDMProfiles(ctx, log.NewNopLogger(), ds, host, []byte{})
err := VerifyHostMDMProfiles(ctx, slog.New(slog.DiscardHandler), ds, host, []byte{})
require.ErrorIs(t, err, io.EOF)
}
@@ -870,7 +870,7 @@ func TestVerifyHostMDMProfilesHappyPaths(t *testing.T) {
out, err := xml.Marshal(msg)
require.NoError(t, err)
require.NoError(t,
VerifyHostMDMProfiles(context.Background(), log.NewNopLogger(), ds, &fleet.Host{DetailUpdatedAt: time.Now()}, out))
VerifyHostMDMProfiles(context.Background(), slog.New(slog.DiscardHandler), ds, &fleet.Host{DetailUpdatedAt: time.Now()}, out))
require.True(t, ds.UpdateHostMDMProfilesVerificationFuncInvoked)
require.True(t, ds.GetHostMDMProfilesExpectedForVerificationFuncInvoked)
require.True(t, ds.GetHostMDMWindowsProfilesFuncInvoked)
@@ -1090,7 +1090,7 @@ func TestPreprocessWindowsProfileContentsForVerification(t *testing.T) {
deps := ProfilePreprocessDependenciesForVerify{
Context: t.Context(),
Logger: log.NewNopLogger(),
Logger: slog.New(slog.DiscardHandler),
DataStore: ds,
HostIDForUUIDCache: make(map[string]uint),
}
@@ -1414,7 +1414,7 @@ func TestPreprocessWindowsProfileContentsForDeployment(t *testing.T) {
deps := ProfilePreprocessDependenciesForDeploy{
ProfilePreprocessDependenciesForVerify: ProfilePreprocessDependenciesForVerify{
Context: ctx,
Logger: log.NewNopLogger(),
Logger: slog.New(slog.DiscardHandler),
DataStore: ds,
HostIDForUUIDCache: hostIDForUUIDCache,
},
+7 -8
View File
@@ -5,6 +5,7 @@ import (
"context"
"encoding/xml"
"fmt"
"log/slog"
"net/url"
"regexp"
"strings"
@@ -14,8 +15,6 @@ import (
"github.com/fleetdm/fleet/v4/server/fleet"
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
"github.com/fleetdm/fleet/v4/server/ptr"
kitlog "github.com/go-kit/log"
"github.com/go-kit/log/level"
)
/*
@@ -31,12 +30,12 @@ Once more is needed it should be placed here, and the main replacement logic can
under server/service folder. Inside the `preprocessProfileContents` under the `fleetVarLoop` loop.
*/
func ReplaceCustomSCEPChallengeVariable(ctx context.Context, logger kitlog.Logger, fleetVariable string, customSCEPCAs map[string]*fleet.CustomSCEPProxyCA, profileContents string) (contents string, replacedVariable bool, err error) {
func ReplaceCustomSCEPChallengeVariable(ctx context.Context, logger *slog.Logger, fleetVariable string, customSCEPCAs map[string]*fleet.CustomSCEPProxyCA, profileContents string) (contents string, replacedVariable bool, err error) {
caName := strings.TrimPrefix(fleetVariable, string(fleet.FleetVarCustomSCEPChallengePrefix))
ca, ok := customSCEPCAs[caName]
if !ok {
level.Error(logger).Log("msg", "Custom SCEP CA not found. "+
"This error should never happen since we validated/populated CAs earlier", "ca_name", caName)
logger.ErrorContext(ctx, "Custom SCEP CA not found. This error should never happen since we validated/populated CAs earlier",
"ca_name", caName)
return "", false, nil
}
contents, err = ReplaceExactFleetPrefixVariableInXML(string(fleet.FleetVarCustomSCEPChallengePrefix), ca.Name, profileContents, ca.Challenge)
@@ -46,15 +45,15 @@ func ReplaceCustomSCEPChallengeVariable(ctx context.Context, logger kitlog.Logge
return contents, true, nil
}
func ReplaceCustomSCEPProxyURLVariable(ctx context.Context, logger kitlog.Logger, ds fleet.Datastore, appConfig *fleet.AppConfig,
func ReplaceCustomSCEPProxyURLVariable(ctx context.Context, logger *slog.Logger, ds fleet.Datastore, appConfig *fleet.AppConfig,
fleetVar string, customSCEPCAs map[string]*fleet.CustomSCEPProxyCA, profileContents string,
hostUUID string, profUUID string,
) (contents string, managedCertificate *fleet.MDMManagedCertificate, replacedVariable bool, err error) {
caName := strings.TrimPrefix(fleetVar, string(fleet.FleetVarCustomSCEPProxyURLPrefix))
ca, ok := customSCEPCAs[caName]
if !ok {
level.Error(logger).Log("msg", "Custom SCEP CA not found. "+
"This error should never happen since we validated/populated CAs earlier", "ca_name", caName)
logger.ErrorContext(ctx, "Custom SCEP CA not found. This error should never happen since we validated/populated CAs earlier",
"ca_name", caName)
return "", nil, false, nil
}
// Generate a new SCEP challenge for the profile
+3 -3
View File
@@ -5634,7 +5634,7 @@ func preprocessProfileContents(
hostContents = profiles.ReplaceFleetVariableInXML(fleetVarSCEPRenewalIDRegexp, hostContents, fleetRenewalID)
case strings.HasPrefix(fleetVar, string(fleet.FleetVarCustomSCEPChallengePrefix)):
replacedContents, replacedVariable, err := profiles.ReplaceCustomSCEPChallengeVariable(ctx, logger, fleetVar, customSCEPCAs, hostContents)
replacedContents, replacedVariable, err := profiles.ReplaceCustomSCEPChallengeVariable(ctx, logger.SlogLogger(), fleetVar, customSCEPCAs, hostContents)
if err != nil {
return ctxerr.Wrap(ctx, err, "replacing custom SCEP challenge variable")
}
@@ -5644,7 +5644,7 @@ func preprocessProfileContents(
hostContents = replacedContents
case strings.HasPrefix(fleetVar, string(fleet.FleetVarCustomSCEPProxyURLPrefix)):
replacedContents, managedCertificate, replacedVariable, err := profiles.ReplaceCustomSCEPProxyURLVariable(ctx, logger, ds, appConfig, fleetVar, customSCEPCAs, hostContents, hostUUID, profUUID)
replacedContents, managedCertificate, replacedVariable, err := profiles.ReplaceCustomSCEPProxyURLVariable(ctx, logger.SlogLogger(), ds, appConfig, fleetVar, customSCEPCAs, hostContents, hostUUID, profUUID)
if err != nil {
return ctxerr.Wrap(ctx, err, "replacing custom SCEP proxy URL variable")
}
@@ -7271,7 +7271,7 @@ func (svc *Service) MDMAppleProcessOTAEnrollment(
// and assigns it if necessary.
func EnsureMDMAppleServiceDiscovery(ctx context.Context, ds fleet.Datastore, depStorage storage.AllDEPStorage, logger *platformlogging.Logger,
urlPrefix string) error {
depSvc := apple_mdm.NewDEPService(ds, depStorage, logger)
depSvc := apple_mdm.NewDEPService(ds, depStorage, logger.SlogLogger())
ac, err := ds.AppConfig(ctx)
if err != nil {
@@ -1116,7 +1116,7 @@ func (s *integrationMDMTestSuite) TestLifecycleSCEPCertExpiration() {
require.Empty(t, getEnrollRef(iPadMdmDevice.UUID))
// enqueue refetch commands and report results
require.NoError(t, apple_mdm.IOSiPadOSRefetch(ctx, s.ds, s.mdmCommander, s.logger, func(ctx context.Context, user *fleet.User, activity fleet.ActivityDetails) error {
require.NoError(t, apple_mdm.IOSiPadOSRefetch(ctx, s.ds, s.mdmCommander, s.logger.SlogLogger(), func(ctx context.Context, user *fleet.User, activity fleet.ActivityDetails) error {
return nil
}))
require.True(t, existsRefetchCmd(iPadMdmDevice.UUID))
@@ -1212,7 +1212,7 @@ func (s *integrationMDMTestSuite) TestLifecycleSCEPCertExpiration() {
})
// enqueue refetch commands and report results
require.NoError(t, apple_mdm.IOSiPadOSRefetch(ctx, s.ds, s.mdmCommander, s.logger, func(ctx context.Context, user *fleet.User, activity fleet.ActivityDetails) error {
require.NoError(t, apple_mdm.IOSiPadOSRefetch(ctx, s.ds, s.mdmCommander, s.logger.SlogLogger(), func(ctx context.Context, user *fleet.User, activity fleet.ActivityDetails) error {
return nil
}))
require.True(t, existsRefetchCmd(iPadMdmDevice.UUID))
@@ -934,7 +934,7 @@ func (s *integrationMDMTestSuite) reportWindowsOSQueryProfiles(ctx context.Conte
require.NoError(t, err)
out, err := xml.Marshal(msg)
require.NoError(t, err)
require.NoError(t, microsoft_mdm.VerifyHostMDMProfiles(ctx, s.logger, s.ds, host, out))
require.NoError(t, microsoft_mdm.VerifyHostMDMProfiles(ctx, s.logger.SlogLogger(), s.ds, host, out))
}
func (s *integrationMDMTestSuite) TestWindowsProfileRetries() {
+12 -12
View File
@@ -239,8 +239,8 @@ func (s *integrationMDMTestSuite) SetupSuite() {
macosJob := &worker.MacosSetupAssistant{
Datastore: s.ds,
Log: wlog,
DEPService: apple_mdm.NewDEPService(s.ds, depStorage, wlog),
DEPClient: apple_mdm.NewDEPClient(depStorage, s.ds, wlog),
DEPService: apple_mdm.NewDEPService(s.ds, depStorage, wlog.SlogLogger()),
DEPClient: apple_mdm.NewDEPClient(depStorage, s.ds, wlog.SlogLogger()),
}
appleMDMJob := &worker.AppleMDM{
Datastore: s.ds,
@@ -362,7 +362,7 @@ func (s *integrationMDMTestSuite) SetupSuite() {
s.onProfileJobDone()
}()
}
err := ReconcileWindowsProfiles(ctx, ds, logger)
err := ReconcileWindowsProfiles(ctx, ds, logger.SlogLogger())
require.NoError(s.T(), err)
return err
}),
@@ -452,7 +452,7 @@ func (s *integrationMDMTestSuite) SetupSuite() {
ctx, name, s.T().Name(), 1*time.Hour, ds, ds,
schedule.WithLogger(logger),
schedule.WithJob("cron_iphone_ipad_refetcher", func(ctx context.Context) error {
return apple_mdm.IOSiPadOSRefetch(ctx, ds, mdmCommander, logger, func(ctx context.Context, user *fleet.User, act fleet.ActivityDetails) error {
return apple_mdm.IOSiPadOSRefetch(ctx, ds, mdmCommander, logger.SlogLogger(), func(ctx context.Context, user *fleet.User, act fleet.ActivityDetails) error {
return newActivity(ctx, user, act, ds, logger)
})
}),
@@ -935,7 +935,7 @@ func (s *integrationMDMTestSuite) mockDEPResponse(orgName string, handler http.H
t := s.T()
srv := httptest.NewServer(handler)
err := s.depStorage.StoreConfig(context.Background(), orgName, &nanodep_client.Config{BaseURL: srv.URL})
depSvc := apple_mdm.NewDEPService(s.ds, s.depStorage, s.logger)
depSvc := apple_mdm.NewDEPService(s.ds, s.depStorage, s.logger.SlogLogger())
require.NoError(t, depSvc.CreateDefaultAutomaticProfile(context.Background()))
require.NoError(t, err)
t.Cleanup(func() {
@@ -1317,7 +1317,7 @@ func (s *integrationMDMTestSuite) TestABMExpiredToken() {
require.False(t, config.MDM.AppleBMTermsExpired)
ctx := context.Background()
fleetSyncer := apple_mdm.NewDEPService(s.ds, s.depStorage, s.logger)
fleetSyncer := apple_mdm.NewDEPService(s.ds, s.depStorage, s.logger.SlogLogger())
// not signed error flips the AppleBMTermsExpired flag
returnType = "not_signed"
@@ -10339,7 +10339,7 @@ func (s *integrationMDMTestSuite) runWorkerUntilDoneWithChecks(failIfFailedJobs
func (s *integrationMDMTestSuite) runDEPSchedule() {
ctx := context.Background()
fleetSyncer := apple_mdm.NewDEPService(s.ds, s.depStorage, s.logger)
fleetSyncer := apple_mdm.NewDEPService(s.ds, s.depStorage, s.logger.SlogLogger())
err := fleetSyncer.RunAssigner(ctx)
require.NoError(s.T(), err)
}
@@ -11425,7 +11425,7 @@ func (s *integrationMDMTestSuite) enableABM(orgName string) *fleet.ABMToken {
_, _ = w.Write([]byte(`{}`))
}
}))
depClient := apple_mdm.NewDEPClient(s.depStorage, s.ds, s.logger)
depClient := apple_mdm.NewDEPClient(s.depStorage, s.ds, s.logger.SlogLogger())
_, err = depClient.AccountDetail(ctx, orgName)
require.NoError(t, err)
return tok
@@ -18766,7 +18766,7 @@ func (s *integrationMDMTestSuite) TestRecreateDeletedIPhoneBYOD() {
pushMutex.Unlock()
return mockSuccessfulPush(ctx, pushes)
}
err := apple_mdm.IOSiPadOSRevive(context.Background(), s.ds, s.mdmCommander, s.logger)
err := apple_mdm.IOSiPadOSRevive(context.Background(), s.ds, s.mdmCommander, s.logger.SlogLogger())
require.NoError(t, err)
pushMutex.Lock()
require.Len(t, recordedPushes, 1)
@@ -19729,7 +19729,7 @@ func (s *integrationMDMTestSuite) TestIOSiPadOSRefetch() {
return nil, errors.New("unknown device")
}
err = apple_mdm.IOSiPadOSRefetch(ctx, s.ds, s.mdmCommander, s.logger, func(ctx context.Context, user *fleet.User, act fleet.ActivityDetails) error {
err = apple_mdm.IOSiPadOSRefetch(ctx, s.ds, s.mdmCommander, s.logger.SlogLogger(), func(ctx context.Context, user *fleet.User, act fleet.ActivityDetails) error {
return newActivity(ctx, user, act, s.ds, s.logger)
})
require.NoError(s.T(), err) // Verify it not longer throws an error
@@ -20745,7 +20745,7 @@ func (s *integrationMDMTestSuite) TestInstalledApplicationListCommandForBYODiDev
checkExpectedCommands(mdmClientDEP, false, 1)
// run the cron-based refetch, will not do anything as the devices were just refetched
err = apple_mdm.IOSiPadOSRefetch(ctx, s.ds, s.mdmCommander, s.logger, func(ctx context.Context, user *fleet.User, act fleet.ActivityDetails) error {
err = apple_mdm.IOSiPadOSRefetch(ctx, s.ds, s.mdmCommander, s.logger.SlogLogger(), func(ctx context.Context, user *fleet.User, act fleet.ActivityDetails) error {
return newActivity(ctx, user, act, s.ds, s.logger)
})
require.NoError(t, err)
@@ -20760,7 +20760,7 @@ func (s *integrationMDMTestSuite) TestInstalledApplicationListCommandForBYODiDev
require.NoError(t, s.ds.UpdateHost(ctx, hostDEP))
// run the cron-based refetch again, will enqueue the commands with the correct managed only flag
err = apple_mdm.IOSiPadOSRefetch(ctx, s.ds, s.mdmCommander, s.logger, func(ctx context.Context, user *fleet.User, act fleet.ActivityDetails) error {
err = apple_mdm.IOSiPadOSRefetch(ctx, s.ds, s.mdmCommander, s.logger.SlogLogger(), func(ctx context.Context, user *fleet.User, act fleet.ActivityDetails) error {
return newActivity(ctx, user, act, s.ds, s.logger)
})
require.NoError(t, err)
+6 -7
View File
@@ -33,7 +33,6 @@ import (
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/fleetdm/fleet/v4/server/variables"
kitlog "github.com/go-kit/log"
"github.com/go-kit/log/level"
mysql_driver "github.com/go-sql-driver/mysql"
@@ -2527,7 +2526,7 @@ func (svc *Service) GetMDMWindowsProfilesSummary(ctx context.Context, teamID *ui
return ps, nil
}
func ReconcileWindowsProfiles(ctx context.Context, ds fleet.Datastore, logger kitlog.Logger) error {
func ReconcileWindowsProfiles(ctx context.Context, ds fleet.Datastore, logger *slog.Logger) error {
appConfig, err := ds.AppConfig(ctx)
if err != nil {
return fmt.Errorf("reading app config: %w", err)
@@ -2595,7 +2594,7 @@ func ReconcileWindowsProfiles(ctx context.Context, ds fleet.Datastore, logger ki
hostProfilesToUpdate = append(hostProfilesToUpdate, hp)
// Add to map for fast lookup
hostProfilesMap[p.HostUUID+"|"+p.ProfileUUID] = hp
level.Debug(logger).Log("msg", "installing profile", "profile_uuid", p.ProfileUUID, "host_id", p.HostUUID, "name", p.ProfileName)
logger.DebugContext(ctx, "installing profile", "profile_uuid", p.ProfileUUID, "host_id", p.HostUUID, "name", p.ProfileName)
}
// Grab the contents of all the profiles we need to install
@@ -2637,7 +2636,7 @@ func ReconcileWindowsProfiles(ctx context.Context, ds fleet.Datastore, logger ki
// No Fleet variables, send the same command to all hosts
command, err := buildCommandFromProfileBytes(p.SyncML, target.cmdUUID)
if err != nil {
level.Info(logger).Log("err", err, "profile_uuid", profUUID)
logger.InfoContext(ctx, "error building command from profile", "err", err, "profile_uuid", profUUID)
continue
}
if err := ds.MDMWindowsInsertCommandForHosts(ctx, target.hostUUIDs, command); err != nil {
@@ -2650,7 +2649,7 @@ func ReconcileWindowsProfiles(ctx context.Context, ds fleet.Datastore, logger ki
hp := hostProfilesMap[mapKey]
if hp == nil {
// This should never happen, but handle gracefully
level.Error(logger).Log("msg", "host profile not found in map", "profile_uuid", profUUID, "host_uuid", hostUUID)
logger.ErrorContext(ctx, "host profile not found in map", "profile_uuid", profUUID, "host_uuid", hostUUID)
continue
}
@@ -2675,7 +2674,7 @@ func ReconcileWindowsProfiles(ctx context.Context, ds fleet.Datastore, logger ki
// Build the command with the processed content
command, err := buildCommandFromProfileBytes([]byte(processedContent), hostCmdUUID)
if err != nil {
level.Info(logger).Log("err", err, "profile_uuid", profUUID, "host_uuid", hostUUID)
logger.InfoContext(ctx, "error building command from profile", "err", err, "profile_uuid", profUUID, "host_uuid", hostUUID)
// Mark this host's profile as failed
hp.Status = &fleet.MDMDeliveryFailed
hp.Detail = fmt.Sprintf("Failed to build command from profile: %s", err.Error())
@@ -2684,7 +2683,7 @@ func ReconcileWindowsProfiles(ctx context.Context, ds fleet.Datastore, logger ki
// Insert the command for this specific host
if err := ds.MDMWindowsInsertCommandForHosts(ctx, []string{hostUUID}, command); err != nil {
level.Error(logger).Log("err", err, "msg", "inserting command for host", "host_uuid", hostUUID)
logger.ErrorContext(ctx, "inserting command for host", "err", err, "host_uuid", hostUUID)
// Mark this host's profile as failed
hp.Status = &fleet.MDMDeliveryFailed
hp.Detail = fmt.Sprintf("Failed to insert command for host: %s", err.Error())
+4 -4
View File
@@ -8,6 +8,7 @@ import (
"encoding/xml"
"errors"
"fmt"
"log/slog"
"strings"
"testing"
"time"
@@ -17,7 +18,6 @@ import (
microsoft_mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
"github.com/fleetdm/fleet/v4/server/mock"
"github.com/go-kit/log"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -711,7 +711,7 @@ func setupReconcilerTest(ds *mock.Store, hostToProfile map[string]*fleet.MDMWind
func TestReconcileWindowsProfilesWithFleetVariableError(t *testing.T) {
ctx := context.Background()
ds := new(mock.Store)
logger := log.NewNopLogger()
logger := slog.New(slog.DiscardHandler)
// Setup test data with a profile containing Fleet variable
testHostUUID := "test-host-uuid"
@@ -771,7 +771,7 @@ func TestReconcileWindowsProfileWithCertificateFailureDoesNotAddManagedCertifica
Tier: fleet.TierPremium,
})
ds := new(mock.Store)
logger := log.NewNopLogger()
logger := slog.New(slog.DiscardHandler)
// Setup test data with a profile containing a certificate that will fail processing
testHostUUID := "test-host-uuid"
@@ -836,7 +836,7 @@ func TestReconcileWindowsProfilesWithOneHostFailingStillAddsManagedCertificate(t
Tier: fleet.TierPremium,
})
ds := new(mock.Store)
logger := log.NewNopLogger()
logger := slog.New(slog.DiscardHandler)
// Setup test data with a profile containing a certificate that will fail processing
testHostUUID := "test-host-uuid"
+2 -3
View File
@@ -24,7 +24,6 @@ import (
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
"github.com/fleetdm/fleet/v4/server/mdm/apple/mobileconfig"
microsoft_mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
platformlogging "github.com/fleetdm/fleet/v4/server/platform/logging"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/fleetdm/fleet/v4/server/service/async"
@@ -3221,7 +3220,7 @@ func buildConfigProfilesWindowsQuery(
var sb strings.Builder
sb.WriteString("<SyncBody>")
gotProfiles := false
err := microsoft_mdm.LoopOverExpectedHostProfiles(ctx, platformlogging.NewLogger(logger), ds, host, func(profile *fleet.ExpectedMDMProfile, hash, locURI, data string) {
err := microsoft_mdm.LoopOverExpectedHostProfiles(ctx, logger, ds, host, func(profile *fleet.ExpectedMDMProfile, hash, locURI, data string) {
// Per the [docs][1], to `<Get>` configurations you must
// replace `/Policy/Config/` with `Policy/Result/`
// [1]: https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-configuration-service-provider
@@ -3272,7 +3271,7 @@ func directIngestWindowsProfiles(
if len(rawResponse) == 0 {
return ctxerr.Errorf(ctx, "directIngestWindowsProfiles host %s got an empty SyncML response", host.UUID)
}
return microsoft_mdm.VerifyHostMDMProfiles(ctx, platformlogging.NewLogger(logger), ds, host, rawResponse)
return microsoft_mdm.VerifyHostMDMProfiles(ctx, logger, ds, host, rawResponse)
}
var rxExtractUsernameFromHostCertPath = regexp.MustCompile(`^/Users/([^/]+)/Library/Keychains/login\.keychain\-db$`)
+2 -2
View File
@@ -79,8 +79,8 @@ func TestMacosSetupAssistant(t *testing.T) {
macosJob := &MacosSetupAssistant{
Datastore: ds,
Log: logger,
DEPService: apple_mdm.NewDEPService(ds, depStorage, logger),
DEPClient: apple_mdm.NewDEPClient(depStorage, ds, logger),
DEPService: apple_mdm.NewDEPService(ds, depStorage, logger.SlogLogger()),
DEPClient: apple_mdm.NewDEPClient(depStorage, ds, logger.SlogLogger()),
}
const defaultProfileName = "Fleet default enrollment profile"