Files
fleet/server/mdm/apple/apple_bm.go
T
Victor Lyuboslavsky aaac4b1dfe Changes needed before gokit/log to slog transition. (#39527)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #38889

PLEASE READ BELOW before looking at file changes

Before converting individual files/packages to slog, we generally need
to make these 2 changes to make the conversion easier:
- Replace uses of `kitlog.With` since they are not fully compatible with
our kitlog adapter
- Directly use the kitlog adapter logger type instead of the kitlog
interface, which will let us have direct access to the underlying slog
logger: `*logging.Logger`

Note: that I did not replace absolutely all uses of `kitlog.Logger`, but
I did remove all uses of `kitlog.With` except for these due to
complexity:
- server/logging/filesystem.go and the other log writers (webhook,
firehose, kinesis, lambda, pubsub, nats)
- server/datastore/mysql/nanomdm_storage.go (adapter pattern)
- server/vulnerabilities/nvd/* (cascades to CLI tools)
- server/service/osquery_utils/queries.go (callback type signatures
cascade broadly)
- cmd/maintained-apps/ (standalone, so can be transitioned later all at
once)

Most of the changes in this PR follow these patterns:
- `kitlog.Logger` type → `*logging.Logger`
- `kitlog.With(logger, ...)` → `logger.With(...)`
- `kitlog.NewNopLogger() → logging.NewNopLogger()`, including similar
variations such as `logging.NewLogfmtLogger(w)` and
`logging.NewJSONLogger(w)`
- removed many now-unused kitlog imports

Unique changes that the PR review should focus on:
- server/platform/logging/kitlog_adapter.go: Core adapter changes
- server/platform/logging/logging.go: New convenience functions
- server/service/integration_logger_test.go: Test changes for slog

# Checklist for submitter

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

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
  - Was added in 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**
* Migrated the codebase to a unified internal structured logging system
for more consistent, reliable logs and observability.
* No user-facing functionality changed; runtime behavior and APIs remain
compatible.
* **Tests**
* Updated tests to use the new logging helpers to ensure consistent test
logging and validation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-02-11 10:08:33 -06:00

97 lines
3.3 KiB
Go

package apple_mdm
import (
"context"
"errors"
"net/http"
abmctx "github.com/fleetdm/fleet/v4/server/contexts/apple_bm"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/fleet"
"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
// metadata and use it to update the rest of the abmToken fields (org name,
// apple ID, renew date). It only sets the data on the struct, it does not
// save it in the DB.
func SetABMTokenMetadata(
ctx context.Context,
abmToken *fleet.ABMToken,
depStorage storage.AllDEPStorage,
ds fleet.Datastore,
logger *logging.Logger,
renewal bool,
) error {
decryptedToken, err := assets.ABMToken(ctx, ds, abmToken.OrganizationName)
if err != nil {
return ctxerr.Wrap(ctx, err, "getting ABM token")
}
return SetDecryptedABMTokenMetadata(ctx, abmToken, decryptedToken, depStorage, ds, logger, renewal)
}
const UnsavedABMTokenOrgName = "new_abm_token" //nolint:gosec
func SetDecryptedABMTokenMetadata(
ctx context.Context,
abmToken *fleet.ABMToken,
decryptedToken *depclient.OAuth1Tokens,
depStorage storage.AllDEPStorage,
ds fleet.Datastore,
logger *logging.Logger,
renewal bool,
) error {
depClient := NewDEPClient(depStorage, ds, logger)
orgName := abmToken.OrganizationName
if orgName == "" {
// Then this is a newly uploaded token (or one migrated from the
// single-token world), which will not be found in the datastore when
// RetrieveAuthTokens tries to find it. Set the token in the context so
// that downstream we know it's not in the datastore.
ctx = abmctx.NewContext(ctx, decryptedToken)
// We don't have an org name, but the depClient expects an org name, so we set this fake one.
orgName = UnsavedABMTokenOrgName
}
if renewal {
// If we're renewing the token, we need to ensure the new token included in the context.
ctx = abmctx.NewContext(ctx, decryptedToken)
}
res, err := depClient.AccountDetail(ctx, orgName)
if err != nil {
var authErr *depclient.AuthError
if errors.As(err, &authErr) {
// authentication failure with 401 unauthorized means that the configured
// Apple BM certificate and/or token are invalid. Fail with a 400 Bad
// Request.
msg := err.Error()
if authErr.StatusCode == http.StatusUnauthorized {
msg = "The Apple Business Manager certificate or server token is invalid. Restart Fleet with a valid certificate and token. See https://fleetdm.com/learn-more-about/setup-abm for help."
}
return ctxerr.Wrap(ctx, &fleet.BadRequestError{
Message: msg,
InternalErr: err,
}, "apple GET /account request failed with authentication error")
}
return ctxerr.Wrap(ctx, err, "apple GET /account request failed")
}
if res.AdminID == "" {
// fallback to facilitator ID, as this is the same information but for
// older versions of the Apple API.
// https://github.com/fleetdm/fleet/issues/7515#issuecomment-1346579398
res.AdminID = res.FacilitatorID
}
abmToken.OrganizationName = res.OrgName
abmToken.AppleID = res.AdminID
abmToken.RenewAt = decryptedToken.AccessTokenExpiry.UTC()
return nil
}