From 4236363522f529e16e02bf1bb42998b58fdce33d Mon Sep 17 00:00:00 2001 From: Victor Lyuboslavsky <2685025+getvictor@users.noreply.github.com> Date: Thu, 19 Feb 2026 11:40:52 -0600 Subject: [PATCH] Next set of slog migration changes for MDM (#39981) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **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 ## 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. --- cmd/fleet/cron.go | 16 ++-- ee/server/service/mdm.go | 4 +- ee/server/service/service.go | 2 +- server/fleet/mdm_test.go | 2 +- server/mdm/apple/apple_bm.go | 6 +- server/mdm/apple/apple_mdm.go | 88 +++++++++---------- server/mdm/apple/apple_mdm_external_test.go | 4 +- server/mdm/apple/apple_mdm_test.go | 4 +- server/mdm/maintainedapps/sync.go | 4 +- server/mdm/maintainedapps/testing_utils.go | 10 +-- server/mdm/microsoft/profile_verifier.go | 19 ++-- server/mdm/microsoft/profile_verifier_test.go | 12 +-- server/mdm/profiles/profile_variables.go | 15 ++-- server/service/apple_mdm.go | 6 +- .../service/integration_mdm_lifecycle_test.go | 4 +- .../service/integration_mdm_profiles_test.go | 2 +- server/service/integration_mdm_test.go | 24 ++--- server/service/microsoft_mdm.go | 13 ++- server/service/microsoft_mdm_test.go | 8 +- server/service/osquery_utils/queries.go | 5 +- server/worker/macos_setup_assistant_test.go | 4 +- 21 files changed, 121 insertions(+), 131 deletions(-) diff --git a/cmd/fleet/cron.go b/cmd/fleet/cron.go index 0bef4cfae3..096c3d7aca 100644 --- a/cmd/fleet/cron.go +++ b/cmd/fleet/cron.go @@ -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()) }), ) diff --git a/ee/server/service/mdm.go b/ee/server/service/mdm.go index 3cf870e193..248a6d7f86 100644 --- a/ee/server/service/mdm.go +++ b/ee/server/service/mdm.go @@ -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") } diff --git a/ee/server/service/service.go b/ee/server/service/service.go index dc23a554d7..a4aeb75438 100644 --- a/ee/server/service/service.go +++ b/ee/server/service/service.go @@ -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, diff --git a/server/fleet/mdm_test.go b/server/fleet/mdm_test.go index 87aa18dd09..5c5eb355a7 100644 --- a/server/fleet/mdm_test.go +++ b/server/fleet/mdm_test.go @@ -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 diff --git a/server/mdm/apple/apple_bm.go b/server/mdm/apple/apple_bm.go index d39b261c5f..30d6b81111 100644 --- a/server/mdm/apple/apple_bm.go +++ b/server/mdm/apple/apple_bm.go @@ -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) diff --git a/server/mdm/apple/apple_mdm.go b/server/mdm/apple/apple_mdm.go index eca18c850e..77d6870893 100644 --- a/server/mdm/apple/apple_mdm.go +++ b/server/mdm/apple/apple_mdm.go @@ -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") diff --git a/server/mdm/apple/apple_mdm_external_test.go b/server/mdm/apple/apple_mdm_external_test.go index 5098f2a6e0..2d134db5f3 100644 --- a/server/mdm/apple/apple_mdm_external_test.go +++ b/server/mdm/apple/apple_mdm_external_test.go @@ -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) } diff --git a/server/mdm/apple/apple_mdm_test.go b/server/mdm/apple/apple_mdm_test.go index 1535c59456..8d1ef00541 100644 --- a/server/mdm/apple/apple_mdm_test.go +++ b/server/mdm/apple/apple_mdm_test.go @@ -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() diff --git a/server/mdm/maintainedapps/sync.go b/server/mdm/maintainedapps/sync.go index 69ad0d48b1..37447b9330 100644 --- a/server/mdm/maintainedapps/sync.go +++ b/server/mdm/maintainedapps/sync.go @@ -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 diff --git a/server/mdm/maintainedapps/testing_utils.go b/server/mdm/maintainedapps/testing_utils.go index 62daa49454..0036fb2738 100644 --- a/server/mdm/maintainedapps/testing_utils.go +++ b/server/mdm/maintainedapps/testing_utils.go @@ -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{}) diff --git a/server/mdm/microsoft/profile_verifier.go b/server/mdm/microsoft/profile_verifier.go index adcad6b16f..8d20edd711 100644 --- a/server/mdm/microsoft/profile_verifier.go +++ b/server/mdm/microsoft/profile_verifier.go @@ -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 values on all the profiles for a @@ -31,7 +30,7 @@ import ( // - The data (if any) of the first 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 } diff --git a/server/mdm/microsoft/profile_verifier_test.go b/server/mdm/microsoft/profile_verifier_test.go index 074211b419..0d4d46541d 100644 --- a/server/mdm/microsoft/profile_verifier_test.go +++ b/server/mdm/microsoft/profile_verifier_test.go @@ -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, }, diff --git a/server/mdm/profiles/profile_variables.go b/server/mdm/profiles/profile_variables.go index 5f4e04c2d3..168d5f77aa 100644 --- a/server/mdm/profiles/profile_variables.go +++ b/server/mdm/profiles/profile_variables.go @@ -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 diff --git a/server/service/apple_mdm.go b/server/service/apple_mdm.go index da4ec7c93d..5557dbddf2 100644 --- a/server/service/apple_mdm.go +++ b/server/service/apple_mdm.go @@ -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 { diff --git a/server/service/integration_mdm_lifecycle_test.go b/server/service/integration_mdm_lifecycle_test.go index 378602a686..6646a38db9 100644 --- a/server/service/integration_mdm_lifecycle_test.go +++ b/server/service/integration_mdm_lifecycle_test.go @@ -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)) diff --git a/server/service/integration_mdm_profiles_test.go b/server/service/integration_mdm_profiles_test.go index b720be461c..efbee56c97 100644 --- a/server/service/integration_mdm_profiles_test.go +++ b/server/service/integration_mdm_profiles_test.go @@ -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() { diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index fb97298727..8b0a903f3f 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -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) diff --git a/server/service/microsoft_mdm.go b/server/service/microsoft_mdm.go index b9c7df2d1a..2cf33c908c 100644 --- a/server/service/microsoft_mdm.go +++ b/server/service/microsoft_mdm.go @@ -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()) diff --git a/server/service/microsoft_mdm_test.go b/server/service/microsoft_mdm_test.go index b88dd8c9bd..631d440bc8 100644 --- a/server/service/microsoft_mdm_test.go +++ b/server/service/microsoft_mdm_test.go @@ -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" diff --git a/server/service/osquery_utils/queries.go b/server/service/osquery_utils/queries.go index f1927afa02..6de6bdf5c5 100644 --- a/server/service/osquery_utils/queries.go +++ b/server/service/osquery_utils/queries.go @@ -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("") 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 `` 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$`) diff --git a/server/worker/macos_setup_assistant_test.go b/server/worker/macos_setup_assistant_test.go index cf7e43fe11..b7eb21dec9 100644 --- a/server/worker/macos_setup_assistant_test.go +++ b/server/worker/macos_setup_assistant_test.go @@ -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"