Skip to content

Commit da1a4e9

Browse files
authored
[Fleet] Install the Fleet Server package during setup (#89224)
1 parent 0491351 commit da1a4e9

File tree

7 files changed

+80
-6
lines changed

7 files changed

+80
-6
lines changed

x-pack/plugins/fleet/common/constants/agent.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ export const AGENT_POLICY_ROLLOUT_RATE_LIMIT_INTERVAL_MS = 1000;
2424
export const AGENT_POLICY_ROLLOUT_RATE_LIMIT_REQUEST_PER_INTERVAL = 5;
2525

2626
export const AGENTS_INDEX = '.fleet-agents';
27+
export const AGENT_ACTIONS_INDEX = '.fleet-actions';

x-pack/plugins/fleet/common/constants/epm.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export const ASSETS_SAVED_OBJECT_TYPE = 'epm-packages-assets';
88
export const INDEX_PATTERN_SAVED_OBJECT_TYPE = 'index-pattern';
99
export const MAX_TIME_COMPLETE_INSTALL = 60000;
1010

11+
export const FLEET_SERVER_PACKAGE = 'fleet_server';
12+
1113
export const requiredPackages = {
1214
System: 'system',
1315
Endpoint: 'endpoint',

x-pack/plugins/fleet/common/constants/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,12 @@ export * from './settings';
1919
// for the actual setting to differ from the default. Can we retrieve the real
2020
// setting in the future?
2121
export const SO_SEARCH_LIMIT = 10000;
22+
23+
export const FLEET_SERVER_INDICES = [
24+
'.fleet-actions',
25+
'.fleet-agents',
26+
'.fleet-enrollment-api-keys',
27+
'.fleet-policies',
28+
'.fleet-policies-leader',
29+
'.fleet-servers',
30+
];

x-pack/plugins/fleet/server/collectors/agent_collectors.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import { ElasticsearchClient, SavedObjectsClient } from 'kibana/server';
88
import * as AgentService from '../services/agents';
9+
import { isFleetServerSetup } from '../services/fleet_server_migration';
910
export interface AgentUsage {
1011
total: number;
1112
online: number;
@@ -18,14 +19,15 @@ export const getAgentUsage = async (
1819
esClient?: ElasticsearchClient
1920
): Promise<AgentUsage> => {
2021
// TODO: unsure if this case is possible at all.
21-
if (!soClient || !esClient) {
22+
if (!soClient || !esClient || !(await isFleetServerSetup())) {
2223
return {
2324
total: 0,
2425
online: 0,
2526
error: 0,
2627
offline: 0,
2728
};
2829
}
30+
2931
const { total, online, error, offline } = await AgentService.getAgentStatusForAgentPolicy(
3032
soClient,
3133
esClient

x-pack/plugins/fleet/server/plugin.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ import { agentCheckinState } from './services/agents/checkin/state';
8181
import { registerFleetUsageCollector } from './collectors/register';
8282
import { getInstallation } from './services/epm/packages';
8383
import { makeRouterEnforcingSuperuser } from './routes/security';
84-
import { runFleetServerMigration } from './services/fleet_server_migration';
84+
import { isFleetServerSetup } from './services/fleet_server_migration';
8585

8686
export interface FleetSetupDeps {
8787
licensing: LicensingPluginSetup;
@@ -299,7 +299,14 @@ export class FleetPlugin
299299
if (fleetServerEnabled) {
300300
// We need licence to be initialized before using the SO service.
301301
await this.licensing$.pipe(first()).toPromise();
302-
await runFleetServerMigration();
302+
303+
const fleetSetup = await isFleetServerSetup();
304+
305+
if (!fleetSetup) {
306+
this.logger?.warn(
307+
'Extra setup is needed to be able to use central management for agent, please visit the Fleet app in Kibana.'
308+
);
309+
}
303310
}
304311

305312
return {

x-pack/plugins/fleet/server/services/fleet_server_migration.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,39 @@ import {
99
ENROLLMENT_API_KEYS_INDEX,
1010
ENROLLMENT_API_KEYS_SAVED_OBJECT_TYPE,
1111
FleetServerEnrollmentAPIKey,
12+
FLEET_SERVER_PACKAGE,
13+
FLEET_SERVER_INDICES,
1214
} from '../../common';
1315
import { listEnrollmentApiKeys, getEnrollmentAPIKey } from './api_keys/enrollment_api_key_so';
1416
import { appContextService } from './app_context';
17+
import { getInstallation } from './epm/packages';
18+
19+
export async function isFleetServerSetup() {
20+
const pkgInstall = await getInstallation({
21+
savedObjectsClient: getInternalUserSOClient(),
22+
pkgName: FLEET_SERVER_PACKAGE,
23+
});
24+
25+
if (!pkgInstall) {
26+
return false;
27+
}
28+
29+
const esClient = appContextService.getInternalUserESClient();
30+
31+
const exists = await Promise.all(
32+
FLEET_SERVER_INDICES.map(async (index) => {
33+
const res = await esClient.indices.exists({
34+
index,
35+
});
36+
return res.statusCode !== 404;
37+
})
38+
);
39+
40+
return exists.every((exist) => exist === true);
41+
}
1542

1643
export async function runFleetServerMigration() {
17-
const logger = appContextService.getLogger();
18-
logger.info('Starting fleet server migration');
1944
await migrateEnrollmentApiKeys();
20-
logger.info('Fleet server migration finished');
2145
}
2246

2347
function getInternalUserSOClient() {

x-pack/plugins/fleet/server/services/setup.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { agentPolicyService } from './agent_policy';
1111
import { outputService } from './output';
1212
import {
1313
ensureInstalledDefaultPackages,
14+
ensureInstalledPackage,
1415
ensurePackagesCompletedInstall,
1516
} from './epm/packages/install';
1617
import {
@@ -20,6 +21,8 @@ import {
2021
Installation,
2122
Output,
2223
DEFAULT_AGENT_POLICIES_PACKAGES,
24+
FLEET_SERVER_PACKAGE,
25+
FLEET_SERVER_INDICES,
2326
} from '../../common';
2427
import { SO_SEARCH_LIMIT } from '../constants';
2528
import { getPackageInfo } from './epm/packages';
@@ -29,6 +32,8 @@ import { settingsService } from '.';
2932
import { awaitIfPending } from './setup_utils';
3033
import { createDefaultSettings } from './settings';
3134
import { ensureAgentActionPolicyChangeExists } from './agents';
35+
import { appContextService } from './app_context';
36+
import { runFleetServerMigration } from './fleet_server_migration';
3237

3338
const FLEET_ENROLL_USERNAME = 'fleet_enroll';
3439
const FLEET_ENROLL_ROLE = 'fleet_enroll';
@@ -77,6 +82,15 @@ async function createSetupSideEffects(
7782
// By moving this outside of the Promise.all, the upgrade will occur first, and then we'll attempt to reinstall any
7883
// packages that are stuck in the installing state.
7984
await ensurePackagesCompletedInstall(soClient, callCluster);
85+
if (appContextService.getConfig()?.agents.fleetServerEnabled) {
86+
await ensureInstalledPackage({
87+
savedObjectsClient: soClient,
88+
pkgName: FLEET_SERVER_PACKAGE,
89+
callCluster,
90+
});
91+
await ensureFleetServerIndicesCreated(esClient);
92+
await runFleetServerMigration();
93+
}
8094

8195
// If we just created the default policy, ensure default packages are added to it
8296
if (defaultAgentPolicyCreated) {
@@ -144,6 +158,21 @@ async function updateFleetRoleIfExists(callCluster: CallESAsCurrentUser) {
144158
return putFleetRole(callCluster);
145159
}
146160

161+
async function ensureFleetServerIndicesCreated(esClient: ElasticsearchClient) {
162+
await Promise.all(
163+
FLEET_SERVER_INDICES.map(async (index) => {
164+
const res = await esClient.indices.exists({
165+
index,
166+
});
167+
if (res.statusCode === 404) {
168+
await esClient.indices.create({
169+
index,
170+
});
171+
}
172+
})
173+
);
174+
}
175+
147176
async function putFleetRole(callCluster: CallESAsCurrentUser) {
148177
return callCluster('transport.request', {
149178
method: 'PUT',

0 commit comments

Comments
 (0)