diff --git a/x-pack/plugins/fleet/common/constants/agent_policy.ts b/x-pack/plugins/fleet/common/constants/agent_policy.ts index 96b6249585bfc..bed9b6e8390b8 100644 --- a/x-pack/plugins/fleet/common/constants/agent_policy.ts +++ b/x-pack/plugins/fleet/common/constants/agent_policy.ts @@ -28,4 +28,19 @@ export const DEFAULT_AGENT_POLICY: Omit< monitoring_enabled: ['logs', 'metrics'] as Array<'logs' | 'metrics'>, }; +export const DEFAULT_FLEET_SERVER_AGENT_POLICY: Omit< + AgentPolicy, + 'id' | 'updated_at' | 'updated_by' | 'revision' +> = { + name: 'Default Fleet Server policy', + namespace: 'default', + description: 'Default Fleet Server agent policy created by Kibana', + status: agentPolicyStatuses.Active, + package_policies: [], + is_default: false, + is_default_fleet_server: true, + is_managed: false, + monitoring_enabled: ['logs', 'metrics'] as Array<'logs' | 'metrics'>, +}; + export const DEFAULT_AGENT_POLICIES_PACKAGES = [defaultPackages.System]; diff --git a/x-pack/plugins/fleet/common/types/models/agent_policy.ts b/x-pack/plugins/fleet/common/types/models/agent_policy.ts index 5f41b0f70ca74..bc139537400cc 100644 --- a/x-pack/plugins/fleet/common/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/common/types/models/agent_policy.ts @@ -17,6 +17,7 @@ export interface NewAgentPolicy { namespace: string; description?: string; is_default?: boolean; + is_default_fleet_server?: boolean; // Optional when creating a policy is_managed?: boolean; // Optional when creating a policy monitoring_enabled?: Array>; } diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index f2eb8be5c030c..5b851c692ad3f 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -162,6 +162,7 @@ const getSavedObjectTypes = ( description: { type: 'text' }, namespace: { type: 'keyword' }, is_default: { type: 'boolean' }, + is_default_fleet_server: { type: 'boolean' }, is_managed: { type: 'boolean' }, status: { type: 'keyword' }, package_policies: { type: 'keyword' }, diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_12_0.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_12_0.ts index 49a0d6fc7737f..15e68ace987b9 100644 --- a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_12_0.ts +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v7_12_0.ts @@ -17,12 +17,11 @@ export const migrateAgentToV7120: SavedObjectMigrationFn, + Exclude, AgentPolicy > = (agentPolicyDoc) => { - const isV12 = 'is_managed' in agentPolicyDoc.attributes; - if (!isV12) { - agentPolicyDoc.attributes.is_managed = false; - } + agentPolicyDoc.attributes.is_managed = false; + agentPolicyDoc.attributes.is_default_fleet_server = false; + return agentPolicyDoc; }; diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index f31f38796055c..44962ea31c56c 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -35,6 +35,7 @@ import { dataTypes, FleetServerPolicy, AGENT_POLICY_INDEX, + DEFAULT_FLEET_SERVER_AGENT_POLICY, } from '../../common'; import { AgentPolicyNameExistsError, @@ -133,6 +134,39 @@ class AgentPolicyService { }; } + public async ensureDefaultFleetServerAgentPolicy( + soClient: SavedObjectsClientContract, + esClient: ElasticsearchClient + ): Promise<{ + created: boolean; + policy: AgentPolicy; + }> { + const agentPolicies = await soClient.find({ + type: AGENT_POLICY_SAVED_OBJECT_TYPE, + searchFields: ['is_default_fleet_server'], + search: 'true', + }); + + if (agentPolicies.total === 0) { + const newDefaultAgentPolicy: NewAgentPolicy = { + ...DEFAULT_FLEET_SERVER_AGENT_POLICY, + }; + + return { + created: true, + policy: await this.create(soClient, esClient, newDefaultAgentPolicy), + }; + } + + return { + created: false, + policy: { + id: agentPolicies.saved_objects[0].id, + ...agentPolicies.saved_objects[0].attributes, + }, + }; + } + public async create( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, @@ -569,18 +603,19 @@ class AgentPolicyService { if (!(await isAgentsSetup(soClient))) { return; } - const policy = await agentPolicyService.getFullAgentPolicy(soClient, agentPolicyId); - if (!policy || !policy.revision) { + const policy = await agentPolicyService.get(soClient, agentPolicyId); + const fullPolicy = await agentPolicyService.getFullAgentPolicy(soClient, agentPolicyId); + if (!policy || !fullPolicy || !fullPolicy.revision) { return; } const fleetServerPolicy: FleetServerPolicy = { '@timestamp': new Date().toISOString(), - revision_idx: policy.revision, + revision_idx: fullPolicy.revision, coordinator_idx: 0, - data: (policy as unknown) as FleetServerPolicy['data'], - policy_id: policy.id, - default_fleet_server: false, + data: (fullPolicy as unknown) as FleetServerPolicy['data'], + policy_id: fullPolicy.id, + default_fleet_server: policy.is_default_fleet_server === true, }; await esClient.create({ diff --git a/x-pack/plugins/fleet/server/services/setup.ts b/x-pack/plugins/fleet/server/services/setup.ts index 6c8f24e799574..94c3c606f9f8f 100644 --- a/x-pack/plugins/fleet/server/services/setup.ts +++ b/x-pack/plugins/fleet/server/services/setup.ts @@ -56,15 +56,20 @@ async function createSetupSideEffects( esClient: ElasticsearchClient, callCluster: CallESAsCurrentUser ): Promise { + const isFleetServerEnabled = appContextService.getConfig()?.agents.fleetServerEnabled; const [ installedPackages, defaultOutput, { created: defaultAgentPolicyCreated, defaultAgentPolicy }, + { created: defaultFleetServerPolicyCreated, policy: defaultFleetServerPolicy }, ] = await Promise.all([ // packages installed by default ensureInstalledDefaultPackages(soClient, callCluster), outputService.ensureDefaultOutput(soClient), agentPolicyService.ensureDefaultAgentPolicy(soClient, esClient), + isFleetServerEnabled + ? agentPolicyService.ensureDefaultFleetServerAgentPolicy(soClient, esClient) + : {}, updateFleetRoleIfExists(callCluster), settingsService.getSettings(soClient).catch((e: any) => { if (e.isBoom && e.output.statusCode === 404) { @@ -83,7 +88,7 @@ async function createSetupSideEffects( // By moving this outside of the Promise.all, the upgrade will occur first, and then we'll attempt to reinstall any // packages that are stuck in the installing state. await ensurePackagesCompletedInstall(soClient, callCluster); - if (appContextService.getConfig()?.agents.fleetServerEnabled) { + if (isFleetServerEnabled) { await ensureInstalledPackage({ savedObjectsClient: soClient, pkgName: FLEET_SERVER_PACKAGE, @@ -94,15 +99,28 @@ async function createSetupSideEffects( } if (appContextService.getConfig()?.agents?.fleetServerEnabled) { - await ensureInstalledPackage({ + const fleetServerPackage = await ensureInstalledPackage({ savedObjectsClient: soClient, pkgName: FLEET_SERVER_PACKAGE, callCluster, }); await ensureFleetServerIndicesCreated(esClient); await runFleetServerMigration(); + + if (defaultFleetServerPolicyCreated) { + await addPackageToAgentPolicy( + soClient, + esClient, + callCluster, + fleetServerPackage, + defaultFleetServerPolicy, + defaultOutput + ); + } } + // If we just created the default fleet server policy add the fleet server package + // If we just created the default policy, ensure default packages are added to it if (defaultAgentPolicyCreated) { const agentPolicyWithPackagePolicies = await agentPolicyService.get(