diff --git a/x-pack/plugins/fleet/server/plugin.ts b/x-pack/plugins/fleet/server/plugin.ts index 2e6fece83c7b3..5032c415fac13 100644 --- a/x-pack/plugins/fleet/server/plugin.ts +++ b/x-pack/plugins/fleet/server/plugin.ts @@ -81,6 +81,7 @@ import { agentCheckinState } from './services/agents/checkin/state'; import { registerFleetUsageCollector } from './collectors/register'; import { getInstallation } from './services/epm/packages'; import { makeRouterEnforcingSuperuser } from './routes/security'; +import { runFleetServerMigration } from './services/fleet_server_migration'; export interface FleetSetupDeps { licensing: LicensingPluginSetup; @@ -294,6 +295,12 @@ export class FleetPlugin licenseService.start(this.licensing$); agentCheckinState.start(); + const fleetServerEnabled = appContextService.getConfig()?.agents?.fleetServerEnabled; + if (fleetServerEnabled) { + await this.licensing$.pipe(first()).toPromise(); + await runFleetServerMigration(); + } + return { esIndexPatternService: new ESIndexPatternSavedObjectService(), packageService: { diff --git a/x-pack/plugins/fleet/server/services/fleet_server_migration.ts b/x-pack/plugins/fleet/server/services/fleet_server_migration.ts new file mode 100644 index 0000000000000..1a50b5c9df767 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/fleet_server_migration.ts @@ -0,0 +1,75 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { KibanaRequest } from 'src/core/server'; +import { + ENROLLMENT_API_KEYS_INDEX, + ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE, + FleetServerEnrollmentAPIKey, +} from '../../common'; +import { listEnrollmentApiKeys, getEnrollmentAPIKey } from './api_keys/enrollment_api_key_so'; +import { appContextService } from './app_context'; + +export async function runFleetServerMigration() { + const logger = appContextService.getLogger(); + logger.info('Starting fleet server migration'); + await migrateEnrollmentApiKeys(); + logger.info('Fleet server migration finished'); +} + +function getInternalUserSOClient() { + const fakeRequest = ({ + headers: {}, + getBasePath: () => '', + path: '/', + route: { settings: {} }, + url: { + href: '/', + }, + raw: { + req: { + url: '/', + }, + }, + } as unknown) as KibanaRequest; + + return appContextService.getInternalUserSOClient(fakeRequest); +} + +async function migrateEnrollmentApiKeys() { + const esClient = appContextService.getInternalUserESClient(); + const soClient = getInternalUserSOClient(); + let hasMore = true; + while (hasMore) { + const res = await listEnrollmentApiKeys(soClient, { + page: 1, + perPage: 100, + }); + if (res.total === 0) { + hasMore = false; + } + for (const item of res.items) { + const key = await getEnrollmentAPIKey(soClient, item.id); + + const body: FleetServerEnrollmentAPIKey = { + api_key: key.api_key, + api_key_id: key.api_key_id, + active: key.active, + created_at: key.created_at, + name: key.name, + policy_id: key.policy_id, + }; + await esClient.create({ + index: ENROLLMENT_API_KEYS_INDEX, + body, + id: key.id, + refresh: 'wait_for', + }); + + await soClient.delete(ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE, key.id); + } + } +}