mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 17:08:53 +00:00
commit
567e93baee
13 changed files with 113 additions and 56 deletions
1
changes/feature_19010-ipad-ios-wipe
Normal file
1
changes/feature_19010-ipad-ios-wipe
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Added support to wipe iOS/iPadOS devices.
|
||||
|
|
@ -316,7 +316,6 @@ func hostMdmActionSetup(c *cli.Context, hostIdent string, actionType string) (cl
|
|||
if err != nil {
|
||||
var nfe service.NotFoundErr
|
||||
if errors.As(err, &nfe) {
|
||||
fmt.Println(hostIdent)
|
||||
return nil, nil, errors.New("The host doesn't exist. Please provide a valid host identifier.")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ func (svc *Service) LockHost(ctx context.Context, hostID uint) (unlockPIN string
|
|||
|
||||
// locking validations are based on the platform of the host
|
||||
switch host.FleetPlatform() {
|
||||
case "ios", "ipados":
|
||||
return "", ctxerr.Wrap(ctx, fleet.NewInvalidArgumentError("host_id", "Can't lock iOS or iPadOS hosts. Use wipe instead."))
|
||||
case "darwin":
|
||||
if err := svc.VerifyMDMAppleConfigured(ctx); err != nil {
|
||||
if errors.Is(err, fleet.ErrMDMNotConfigured) {
|
||||
|
|
@ -176,7 +178,7 @@ func (svc *Service) UnlockHost(ctx context.Context, hostID uint) (string, error)
|
|||
|
||||
// locking validations are based on the platform of the host
|
||||
switch host.FleetPlatform() {
|
||||
case "darwin":
|
||||
case "darwin", "ios", "ipados":
|
||||
// all good, no need to check if MDM enrolled, will validate later that it
|
||||
// is currently locked.
|
||||
|
||||
|
|
@ -267,7 +269,7 @@ func (svc *Service) WipeHost(ctx context.Context, hostID uint) error {
|
|||
// uses scripts, not MDM.
|
||||
var requireMDM bool
|
||||
switch host.FleetPlatform() {
|
||||
case "darwin":
|
||||
case "darwin", "ios", "ipados":
|
||||
if err := svc.VerifyMDMAppleConfigured(ctx); err != nil {
|
||||
if errors.Is(err, fleet.ErrMDMNotConfigured) {
|
||||
err = fleet.NewInvalidArgumentError("host_id", fleet.AppleMDMNotConfiguredMessage).WithStatus(http.StatusBadRequest)
|
||||
|
|
@ -471,7 +473,7 @@ func (svc *Service) enqueueWipeHostRequest(ctx context.Context, host *fleet.Host
|
|||
}
|
||||
|
||||
switch wipeStatus.HostFleetPlatform {
|
||||
case "darwin":
|
||||
case "darwin", "ios", "ipados":
|
||||
wipeCommandUUID := uuid.NewString()
|
||||
if err := svc.mdmAppleCommander.EraseDevice(ctx, host, wipeCommandUUID); err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "enqueuing wipe request for darwin")
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ export const HOST_LINUX_PLATFORMS = [
|
|||
"tuxedo",
|
||||
] as const;
|
||||
|
||||
export const HOST_APPLE_PLATFORMS = ["darwin", "ios", "ipados"] as const;
|
||||
|
||||
/**
|
||||
* Checks if the provided platform is a Linux-like OS. We can recieve many
|
||||
* different types of host platforms so we need a check that will cover all
|
||||
|
|
@ -78,3 +80,9 @@ export const isLinuxLike = (platform: string) => {
|
|||
platform as typeof HOST_LINUX_PLATFORMS[number]
|
||||
);
|
||||
};
|
||||
|
||||
export const isAppleDevice = (platform: string) => {
|
||||
return HOST_APPLE_PLATFORMS.includes(
|
||||
platform as typeof HOST_APPLE_PLATFORMS[number]
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export interface IScript {
|
|||
}
|
||||
|
||||
export const isScriptSupportedPlatform = (hostPlatform: string) =>
|
||||
["darwin", "windows", ...HOST_LINUX_PLATFORMS].includes(hostPlatform); // excludes chrome, see also https://github.com/fleetdm/fleet/blob/5a21e2cfb029053ddad0508869eb9f1f23997bf2/server/fleet/hosts.go#L775
|
||||
["darwin", "windows", ...HOST_LINUX_PLATFORMS].includes(hostPlatform); // excludes chrome, ios, ipados see also https://github.com/fleetdm/fleet/blob/5a21e2cfb029053ddad0508869eb9f1f23997bf2/server/fleet/hosts.go#L775
|
||||
|
||||
export type IScriptExecutionStatus = "ran" | "pending" | "error";
|
||||
|
||||
|
|
|
|||
|
|
@ -785,7 +785,7 @@ describe("Host Actions Dropdown", () => {
|
|||
expect(screen.queryByText("Unlock")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not renders when a mac host but does not have Fleet mac mdm enabled and configured", async () => {
|
||||
it("does not renders when a macOS host but does not have Fleet mac mdm enabled and configured", async () => {
|
||||
const render = createCustomRenderer({
|
||||
context: {
|
||||
app: {
|
||||
|
|
@ -921,7 +921,7 @@ describe("Host Actions Dropdown", () => {
|
|||
expect(screen.queryByText("Wipe")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not renders when a mac host but does not have Fleet mac mdm enabled and configured", async () => {
|
||||
it("does not renders when a macOS host but does not have Fleet macOS mdm enabled and configured", async () => {
|
||||
const render = createCustomRenderer({
|
||||
context: {
|
||||
app: {
|
||||
|
|
@ -1139,55 +1139,85 @@ describe("Host Actions Dropdown", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("Does not render dropdown for certain platforms", () => {
|
||||
it("does not render dropdown for iOS", async () => {
|
||||
describe("Render options only available for iOS and iPadOS", () => {
|
||||
it("renders only the transfer, wipe, and delete options for iOS", async () => {
|
||||
const render = createCustomRenderer({
|
||||
context: {
|
||||
app: {
|
||||
isPremiumTier: true,
|
||||
isGlobalAdmin: true,
|
||||
isMacMdmEnabledAndConfigured: true,
|
||||
currentUser: createMockUser(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
render(
|
||||
const { user } = render(
|
||||
<HostActionsDropdown
|
||||
hostTeamId={null}
|
||||
onSelect={noop}
|
||||
hostStatus="online"
|
||||
hostPlatform="ios"
|
||||
hostMdmEnrollmentStatus={null}
|
||||
hostMdmEnrollmentStatus="On (automatic)"
|
||||
mdmName="Fleet"
|
||||
hostMdmDeviceStatus={"unlocked"}
|
||||
hostScriptsEnabled={false}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.queryByText("Actions")).not.toBeInTheDocument();
|
||||
await user.click(screen.getByText("Actions"));
|
||||
|
||||
expect(screen.queryByText("Transfer")).toBeInTheDocument();
|
||||
expect(screen.queryByText("Wipe")).toBeInTheDocument();
|
||||
expect(screen.queryByText("Delete")).toBeInTheDocument();
|
||||
|
||||
expect(screen.queryByText("Query")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Run script")).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText("Show disk encryption key")
|
||||
).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Turn off MDM")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Lock")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("does not render dropdown for iPadOS", async () => {
|
||||
it("renders only the transfer, wipe, and delete options for iPadOS", async () => {
|
||||
const render = createCustomRenderer({
|
||||
context: {
|
||||
app: {
|
||||
isPremiumTier: true,
|
||||
isGlobalAdmin: true,
|
||||
isMacMdmEnabledAndConfigured: true,
|
||||
currentUser: createMockUser(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
render(
|
||||
const { user } = render(
|
||||
<HostActionsDropdown
|
||||
hostTeamId={null}
|
||||
onSelect={noop}
|
||||
hostStatus="online"
|
||||
hostPlatform="ipados"
|
||||
hostMdmEnrollmentStatus={null}
|
||||
hostMdmEnrollmentStatus="On (automatic)"
|
||||
mdmName="Fleet"
|
||||
hostMdmDeviceStatus={"unlocked"}
|
||||
hostScriptsEnabled={false}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.queryByText("Actions")).not.toBeInTheDocument();
|
||||
await user.click(screen.getByText("Actions"));
|
||||
|
||||
expect(screen.queryByText("Transfer")).toBeInTheDocument();
|
||||
expect(screen.queryByText("Wipe")).toBeInTheDocument();
|
||||
expect(screen.queryByText("Delete")).toBeInTheDocument();
|
||||
|
||||
expect(screen.queryByText("Query")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Run script")).not.toBeInTheDocument();
|
||||
expect(
|
||||
screen.queryByText("Show disk encryption key")
|
||||
).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Turn off MDM")).not.toBeInTheDocument();
|
||||
expect(screen.queryByText("Lock")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -79,10 +79,6 @@ const HostActionsDropdown = ({
|
|||
// No options to render. Exit early
|
||||
if (options.length === 0) return null;
|
||||
|
||||
if (hostPlatform === "ios" || hostPlatform === "ipados") {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<Dropdown
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React from "react";
|
|||
import { cloneDeep } from "lodash";
|
||||
|
||||
import { IDropdownOption } from "interfaces/dropdownOption";
|
||||
import { isLinuxLike } from "interfaces/platform";
|
||||
import { isLinuxLike, isAppleDevice } from "interfaces/platform";
|
||||
import { isScriptSupportedPlatform } from "interfaces/script";
|
||||
|
||||
import {
|
||||
|
|
@ -86,6 +86,7 @@ const canTransferTeam = (config: IHostActionConfigOptions) => {
|
|||
|
||||
const canEditMdm = (config: IHostActionConfigOptions) => {
|
||||
const {
|
||||
hostPlatform,
|
||||
isGlobalAdmin,
|
||||
isGlobalMaintainer,
|
||||
isTeamAdmin,
|
||||
|
|
@ -95,7 +96,7 @@ const canEditMdm = (config: IHostActionConfigOptions) => {
|
|||
isMacMdmEnabledAndConfigured,
|
||||
} = config;
|
||||
return (
|
||||
config.hostPlatform === "darwin" &&
|
||||
hostPlatform === "darwin" &&
|
||||
isMacMdmEnabledAndConfigured &&
|
||||
isEnrolledInMdm &&
|
||||
isFleetMdm &&
|
||||
|
|
@ -103,6 +104,13 @@ const canEditMdm = (config: IHostActionConfigOptions) => {
|
|||
);
|
||||
};
|
||||
|
||||
const canQueryHost = ({ hostPlatform }: IHostActionConfigOptions) => {
|
||||
// Currently we cannot query iOS or iPadOS
|
||||
const isIosOrIpadosHost = hostPlatform === "ios" || hostPlatform === "ipados";
|
||||
|
||||
return !isIosOrIpadosHost;
|
||||
};
|
||||
|
||||
const canLockHost = ({
|
||||
isPremiumTier,
|
||||
hostPlatform,
|
||||
|
|
@ -146,17 +154,18 @@ const canWipeHost = ({
|
|||
hostMdmDeviceStatus,
|
||||
}: IHostActionConfigOptions) => {
|
||||
const hostMdmEnabled =
|
||||
(hostPlatform === "darwin" && isMacMdmEnabledAndConfigured) ||
|
||||
(isAppleDevice(hostPlatform) && isMacMdmEnabledAndConfigured) ||
|
||||
(hostPlatform === "windows" && isWindowsMdmEnabledAndConfigured);
|
||||
|
||||
// macOS and Windows hosts have the same conditions and can be wiped if they
|
||||
// Windows and Apple devices (i.e. macOS, iOS, iPadOS) have the same conditions and can be wiped if they
|
||||
// are enrolled in MDM and the MDM is enabled.
|
||||
const canWipeMacOrWindows = hostMdmEnabled && isFleetMdm && isEnrolledInMdm;
|
||||
const canWipeWindowsOrAppleOS =
|
||||
hostMdmEnabled && isFleetMdm && isEnrolledInMdm;
|
||||
|
||||
return (
|
||||
isPremiumTier &&
|
||||
hostMdmDeviceStatus === "unlocked" &&
|
||||
(isLinuxLike(hostPlatform) || canWipeMacOrWindows) &&
|
||||
(isLinuxLike(hostPlatform) || canWipeWindowsOrAppleOS) &&
|
||||
(isGlobalAdmin || isGlobalMaintainer || isTeamAdmin || isTeamMaintainer)
|
||||
);
|
||||
};
|
||||
|
|
@ -205,8 +214,12 @@ const canDeleteHost = (config: IHostActionConfigOptions) => {
|
|||
};
|
||||
|
||||
const canShowDiskEncryption = (config: IHostActionConfigOptions) => {
|
||||
const { isPremiumTier, doesStoreEncryptionKey } = config;
|
||||
return isPremiumTier && doesStoreEncryptionKey;
|
||||
const { isPremiumTier, doesStoreEncryptionKey, hostPlatform } = config;
|
||||
|
||||
// Currently we cannot show disk encryption key for iOS or iPadOS
|
||||
const isIosOrIpadosHost = hostPlatform === "ios" || hostPlatform === "ipados";
|
||||
|
||||
return isPremiumTier && doesStoreEncryptionKey && !isIosOrIpadosHost;
|
||||
};
|
||||
|
||||
const canRunScript = ({
|
||||
|
|
@ -237,6 +250,10 @@ const removeUnavailableOptions = (
|
|||
options = options.filter((option) => option.value !== "transfer");
|
||||
}
|
||||
|
||||
if (!canQueryHost(config)) {
|
||||
options = options.filter((option) => option.value !== "query");
|
||||
}
|
||||
|
||||
if (!canShowDiskEncryption(config)) {
|
||||
options = options.filter((option) => option.value !== "diskEncryption");
|
||||
}
|
||||
|
|
@ -266,9 +283,8 @@ const removeUnavailableOptions = (
|
|||
}
|
||||
|
||||
// TODO: refactor to filter in one pass using predefined filters specified for each of the
|
||||
// DEFAULT_OPTIONS. Note that as currently, structured the default is to include all options. For
|
||||
// example, "Query" is implicitly included by default because there is no equivalent `canQuery`
|
||||
// filter being applied here. This is a bit confusing since
|
||||
// DEFAULT_OPTIONS. Note that as currently, structured the default is to include all options.
|
||||
// This is a bit confusing since we remove options instead of add options
|
||||
|
||||
return options;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ import TransferHostModal from "../../components/TransferHostModal";
|
|||
import DeleteHostModal from "../../components/DeleteHostModal";
|
||||
|
||||
import DiskEncryptionKeyModal from "./modals/DiskEncryptionKeyModal";
|
||||
import HostActionDropdown from "./HostActionsDropdown/HostActionsDropdown";
|
||||
import HostActionsDropdown from "./HostActionsDropdown/HostActionsDropdown";
|
||||
import OSSettingsModal from "../OSSettingsModal";
|
||||
import BootstrapPackageModal from "./modals/BootstrapPackageModal";
|
||||
import RunScriptModal from "./modals/RunScriptModal";
|
||||
|
|
@ -672,7 +672,7 @@ const HostDetailsPage = ({
|
|||
}
|
||||
|
||||
return (
|
||||
<HostActionDropdown
|
||||
<HostActionsDropdown
|
||||
hostTeamId={host.team_id}
|
||||
onSelect={onSelectHostAction}
|
||||
hostPlatform={host.platform}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import React from "react";
|
||||
import { isAppleDevice } from "interfaces/platform";
|
||||
import { HostMdmDeviceStatusUIState } from "../../helpers";
|
||||
|
||||
interface IDeviceStatusTag {
|
||||
|
|
@ -23,7 +24,7 @@ export const DEVICE_STATUS_TAGS: DeviceStatusTagConfig = {
|
|||
title: "LOCKED",
|
||||
tagType: "warning",
|
||||
generateTooltip: (platform) =>
|
||||
platform === "darwin"
|
||||
isAppleDevice(platform)
|
||||
? "Host is locked. The end user can’t use the host until the six-digit PIN has been entered."
|
||||
: "Host is locked. The end user can’t use the host until the host has been unlocked.",
|
||||
},
|
||||
|
|
@ -43,7 +44,7 @@ export const DEVICE_STATUS_TAGS: DeviceStatusTagConfig = {
|
|||
title: "WIPED",
|
||||
tagType: "error",
|
||||
generateTooltip: (platform) =>
|
||||
platform === "darwin"
|
||||
isAppleDevice(platform)
|
||||
? "Host is wiped. To prevent the host from automatically reenrolling to Fleet, first release the host from Apple Business Manager and then delete the host in Fleet."
|
||||
: "Host is wiped.",
|
||||
},
|
||||
|
|
|
|||
|
|
@ -303,8 +303,10 @@ const (
|
|||
)
|
||||
|
||||
// anchored, so that it matches to the end of the line
|
||||
var scriptHashbangValidation = regexp.MustCompile(`^#!\s*(:?/usr)?/bin/z?sh(?:\s*|\s+.*)$`)
|
||||
var ErrUnsupportedInterpreter = errors.New(`Interpreter not supported. Shell scripts must run in "#!/bin/sh" or "#!/bin/zsh."`)
|
||||
var (
|
||||
scriptHashbangValidation = regexp.MustCompile(`^#!\s*(:?/usr)?/bin/z?sh(?:\s*|\s+.*)$`)
|
||||
ErrUnsupportedInterpreter = errors.New(`Interpreter not supported. Shell scripts must run in "#!/bin/sh" or "#!/bin/zsh."`)
|
||||
)
|
||||
|
||||
// ValidateShebang validates if we support a script, and whether we
|
||||
// can execute it directly, or need to pass it to a shell interpreter.
|
||||
|
|
@ -402,7 +404,7 @@ type HostLockWipeStatus struct {
|
|||
}
|
||||
|
||||
func (s *HostLockWipeStatus) IsPendingLock() bool {
|
||||
if s.HostFleetPlatform == "darwin" {
|
||||
if s.HostFleetPlatform == "darwin" || s.HostFleetPlatform == "ios" || s.HostFleetPlatform == "ipados" {
|
||||
// pending lock if an MDM command is queued but no result received yet
|
||||
return s.LockMDMCommand != nil && s.LockMDMCommandResult == nil
|
||||
}
|
||||
|
|
@ -411,7 +413,7 @@ func (s *HostLockWipeStatus) IsPendingLock() bool {
|
|||
}
|
||||
|
||||
func (s HostLockWipeStatus) IsPendingUnlock() bool {
|
||||
if s.HostFleetPlatform == "darwin" {
|
||||
if s.HostFleetPlatform == "darwin" || s.HostFleetPlatform == "ios" || s.HostFleetPlatform == "ipados" {
|
||||
// Apple MDM does not have a concept of pending unlock.
|
||||
return false
|
||||
}
|
||||
|
|
@ -432,7 +434,7 @@ func (s HostLockWipeStatus) IsLocked() bool {
|
|||
// this state is regardless of pending unlock/wipe (it reports whether the
|
||||
// host is locked *now*).
|
||||
|
||||
if s.HostFleetPlatform == "darwin" {
|
||||
if s.HostFleetPlatform == "darwin" || s.HostFleetPlatform == "ios" || s.HostFleetPlatform == "ipados" {
|
||||
// locked if an MDM command was sent and succeeded
|
||||
return s.LockMDMCommand != nil && s.LockMDMCommandResult != nil &&
|
||||
s.LockMDMCommandResult.Status == MDMAppleStatusAcknowledged
|
||||
|
|
@ -458,7 +460,7 @@ func (s HostLockWipeStatus) IsWiped() bool {
|
|||
// wiped if an MDM command was sent and succeeded
|
||||
return s.WipeMDMCommand != nil && s.WipeMDMCommandResult != nil &&
|
||||
strings.HasPrefix(s.WipeMDMCommandResult.Status, "2")
|
||||
case "darwin":
|
||||
case "darwin", "ios", "ipados":
|
||||
// wiped if an MDM command was sent and succeeded
|
||||
return s.WipeMDMCommand != nil && s.WipeMDMCommandResult != nil &&
|
||||
s.WipeMDMCommandResult.Status == MDMAppleStatusAcknowledged
|
||||
|
|
|
|||
|
|
@ -1423,6 +1423,12 @@ func (svc *Service) EnqueueMDMAppleCommandRemoveEnrollmentProfile(ctx context.Co
|
|||
return ctxerr.Wrap(ctx, err, "getting host info for mdm apple remove profile command")
|
||||
}
|
||||
|
||||
if h.Platform == "ios" || h.Platform == "ipados" {
|
||||
return &fleet.BadRequestError{
|
||||
Message: "Can't turn off MDM for iOS or iPadOS hosts. Use wipe instead.",
|
||||
}
|
||||
}
|
||||
|
||||
info, err := svc.ds.GetHostMDMCheckinInfo(ctx, h.UUID)
|
||||
if err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "getting mdm checkin info for mdm apple remove profile command")
|
||||
|
|
|
|||
|
|
@ -19,31 +19,25 @@ import (
|
|||
"github.com/fleetdm/fleet/v4/server/config"
|
||||
"github.com/fleetdm/fleet/v4/server/datastore/mysql"
|
||||
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"
|
||||
kitlog "github.com/go-kit/kit/log"
|
||||
)
|
||||
|
||||
func main() {
|
||||
mysqlAddr := flag.String("mysql", "localhost:3306", "mysql address")
|
||||
appleBMToken := flag.String("apple-bm-token", "", "path to (decrypted) Apple BM token")
|
||||
serverPrivateKey := flag.String("server-private-key", "", "fleet server's private key (to decrypt MDM assets)")
|
||||
profileUUID := flag.String("profile-uuid", "", "the Apple profile UUID to retrieve")
|
||||
serialNum := flag.String("serial-number", "", "serial number of a device to get the device details")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if *appleBMToken == "" {
|
||||
log.Fatal("must provide Apple BM token")
|
||||
if *serverPrivateKey == "" {
|
||||
log.Fatal("must provide -server-private-key")
|
||||
}
|
||||
if *profileUUID != "" && *serialNum != "" {
|
||||
log.Fatal("only one of -profile-uuid or -serial-number must be provided")
|
||||
}
|
||||
|
||||
tok, err := os.ReadFile(*appleBMToken)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
cfg := config.MysqlConfig{
|
||||
Protocol: "tcp",
|
||||
Address: *mysqlAddr,
|
||||
|
|
@ -55,17 +49,19 @@ func main() {
|
|||
ConnMaxLifetime: 0,
|
||||
}
|
||||
logger := kitlog.NewLogfmtLogger(os.Stderr)
|
||||
opts := []mysql.DBOption{mysql.Logger(logger)}
|
||||
opts := []mysql.DBOption{
|
||||
mysql.Logger(logger),
|
||||
mysql.WithFleetConfig(&config.FleetConfig{
|
||||
Server: config.ServerConfig{
|
||||
PrivateKey: *serverPrivateKey,
|
||||
},
|
||||
}),
|
||||
}
|
||||
mds, err := mysql.New(cfg, clock.C, opts...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var jsonTok nanodep_client.OAuth1Tokens
|
||||
if err := json.Unmarshal(tok, &jsonTok); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
depStorage, err := mds.NewMDMAppleDEPStorage()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
|
|
|||
Loading…
Reference in a new issue