From 504da49cf5f1728eccbff9a896f9a653c53f3989 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 9 Oct 2024 10:34:02 +0200 Subject: [PATCH 01/17] delete unenrolled agents task --- .../fleet/common/types/models/settings.ts | 1 + x-pack/plugins/fleet/server/config.ts | 1 + x-pack/plugins/fleet/server/plugin.ts | 10 + .../fleet/server/routes/output/index.ts | 2 +- .../fleet/server/saved_objects/index.ts | 11 ++ .../delete_unenrolled_agent_setting.ts | 26 +++ .../plugins/fleet/server/services/settings.ts | 1 + x-pack/plugins/fleet/server/services/setup.ts | 10 + .../tasks/delete_unenrolled_agents_task.ts | 178 ++++++++++++++++++ .../fleet/server/types/rest_spec/settings.ts | 1 + .../fleet/server/types/so_attributes.ts | 1 + 11 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts create mode 100644 x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts diff --git a/x-pack/plugins/fleet/common/types/models/settings.ts b/x-pack/plugins/fleet/common/types/models/settings.ts index 9a5166e41df96..465f06f41f7f3 100644 --- a/x-pack/plugins/fleet/common/types/models/settings.ts +++ b/x-pack/plugins/fleet/common/types/models/settings.ts @@ -19,4 +19,5 @@ export interface Settings extends BaseSettings { output_secret_storage_requirements_met?: boolean; use_space_awareness_migration_status?: 'pending' | 'success' | 'error'; use_space_awareness_migration_started_at?: string | null; + delete_unenrolled_agents?: boolean; } diff --git a/x-pack/plugins/fleet/server/config.ts b/x-pack/plugins/fleet/server/config.ts index 6df693096f7c6..1797c30d15f4d 100644 --- a/x-pack/plugins/fleet/server/config.ts +++ b/x-pack/plugins/fleet/server/config.ts @@ -130,6 +130,7 @@ export const config: PluginConfigDescriptor = { schema: schema.object( { isAirGapped: schema.maybe(schema.boolean({ defaultValue: false })), + enableDeleteUnenrolledAgents: schema.maybe(schema.boolean({ defaultValue: false })), registryUrl: schema.maybe(schema.uri({ scheme: ['http', 'https'] })), registryProxyUrl: schema.maybe(schema.uri({ scheme: ['http', 'https'] })), agents: schema.object({ diff --git a/x-pack/plugins/fleet/server/plugin.ts b/x-pack/plugins/fleet/server/plugin.ts index c767424cef36a..ced8da63e9703 100644 --- a/x-pack/plugins/fleet/server/plugin.ts +++ b/x-pack/plugins/fleet/server/plugin.ts @@ -142,6 +142,7 @@ import { fetchAgentMetrics } from './services/metrics/fetch_agent_metrics'; import { registerIntegrationFieldsExtractor } from './services/register_integration_fields_extractor'; import { registerUpgradeManagedPackagePoliciesTask } from './services/setup/managed_package_policies'; import { registerDeployAgentPoliciesTask } from './services/agent_policies/deploy_agent_policies_task'; +import { DeleteUnenrolledAgentsTask } from './tasks/delete_unenrolled_agents_task'; export interface FleetSetupDeps { security: SecurityPluginSetup; @@ -192,6 +193,7 @@ export interface FleetAppContext { auditLogger?: AuditLogger; uninstallTokenService: UninstallTokenServiceInterface; unenrollInactiveAgentsTask: UnenrollInactiveAgentsTask; + deleteUnenrolledAgentsTask: DeleteUnenrolledAgentsTask; taskManagerStart?: TaskManagerStartContract; } @@ -284,6 +286,7 @@ export class FleetPlugin private checkDeletedFilesTask?: CheckDeletedFilesTask; private fleetMetricsTask?: FleetMetricsTask; private unenrollInactiveAgentsTask?: UnenrollInactiveAgentsTask; + private deleteUnenrolledAgentsTask?: DeleteUnenrolledAgentsTask; private agentService?: AgentService; private packageService?: PackageService; @@ -628,6 +631,11 @@ export class FleetPlugin taskManager: deps.taskManager, logFactory: this.initializerContext.logger, }); + this.deleteUnenrolledAgentsTask = new DeleteUnenrolledAgentsTask({ + core, + taskManager: deps.taskManager, + logFactory: this.initializerContext.logger, + }); // Register fields metadata extractor registerIntegrationFieldsExtractor({ core, fieldsMetadata: deps.fieldsMetadata }); @@ -674,6 +682,7 @@ export class FleetPlugin messageSigningService, uninstallTokenService, unenrollInactiveAgentsTask: this.unenrollInactiveAgentsTask!, + deleteUnenrolledAgentsTask: this.deleteUnenrolledAgentsTask!, taskManagerStart: plugins.taskManager, }); licenseService.start(plugins.licensing.license$); @@ -682,6 +691,7 @@ export class FleetPlugin this.fleetUsageSender?.start(plugins.taskManager).catch(() => {}); this.checkDeletedFilesTask?.start({ taskManager: plugins.taskManager }).catch(() => {}); this.unenrollInactiveAgentsTask?.start({ taskManager: plugins.taskManager }).catch(() => {}); + this.deleteUnenrolledAgentsTask?.start({ taskManager: plugins.taskManager }).catch(() => {}); startFleetUsageLogger(plugins.taskManager).catch(() => {}); this.fleetMetricsTask ?.start(plugins.taskManager, core.elasticsearch.client.asInternalUser) diff --git a/x-pack/plugins/fleet/server/routes/output/index.ts b/x-pack/plugins/fleet/server/routes/output/index.ts index b222f9f737d1d..f633713e4bbc5 100644 --- a/x-pack/plugins/fleet/server/routes/output/index.ts +++ b/x-pack/plugins/fleet/server/routes/output/index.ts @@ -189,7 +189,7 @@ export const registerRoutes = (router: FleetAuthzRouter) => { fleetAuthz: { fleet: { allSettings: true }, }, - description: 'Generate Logstash API keyy', + description: 'Generate Logstash API key', options: { tags: ['oas-tag:Fleet outputs'], }, diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index 0eb6c86df01e2..3a50720ae28a5 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -161,6 +161,7 @@ export const getSavedObjectTypes = ( output_secret_storage_requirements_met: { type: 'boolean' }, use_space_awareness_migration_status: { type: 'keyword', index: false }, use_space_awareness_migration_started_at: { type: 'date', index: false }, + delete_unenrolled_agents: { type: 'boolean', index: false }, }, }, migrations: { @@ -181,6 +182,16 @@ export const getSavedObjectTypes = ( }, ], }, + 3: { + changes: [ + { + type: 'mappings_addition', + addedMappings: { + delete_unenrolled_agents: { type: 'boolean', index: false }, + }, + }, + ], + }, }, }, [LEGACY_AGENT_POLICY_SAVED_OBJECT_TYPE]: { diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts b/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts new file mode 100644 index 0000000000000..61225063ce5d8 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server'; + +import { settingsService } from '..'; +import type { FleetConfigType } from '../../config'; + +export function getPreconfiguredDeleteUnenrolledAgentsSettingFromConfig(config?: FleetConfigType) { + return config.enableDeleteUnenrolledAgents ?? false; +} + +export async function ensureDeleteUnenrolledAgentsSetting( + soClient: SavedObjectsClientContract, + enableDeleteUnenrolledAgents: boolean +) { + if (enableDeleteUnenrolledAgents) { + await settingsService.saveSettings(soClient, { + delete_unenrolled_agents: true, + }); + } +} diff --git a/x-pack/plugins/fleet/server/services/settings.ts b/x-pack/plugins/fleet/server/services/settings.ts index 394a2365f3c03..ea883e1bf7de3 100644 --- a/x-pack/plugins/fleet/server/services/settings.ts +++ b/x-pack/plugins/fleet/server/services/settings.ts @@ -47,6 +47,7 @@ export async function getSettings(soClient: SavedObjectsClientContract): Promise settingsSo.attributes.use_space_awareness_migration_started_at, fleet_server_hosts: fleetServerHosts.items.flatMap((item) => item.host_urls), preconfigured_fields: getConfigFleetServerHosts() ? ['fleet_server_hosts'] : [], + delete_unenrolled_agents: settingsSo.attributes.delete_unenrolled_agents, }; } diff --git a/x-pack/plugins/fleet/server/services/setup.ts b/x-pack/plugins/fleet/server/services/setup.ts index c0b86d6394769..0d6ec183531a4 100644 --- a/x-pack/plugins/fleet/server/services/setup.ts +++ b/x-pack/plugins/fleet/server/services/setup.ts @@ -53,6 +53,10 @@ import { cleanUpOldFileIndices } from './setup/clean_old_fleet_indices'; import type { UninstallTokenInvalidError } from './security/uninstall_token_service'; import { ensureAgentPoliciesFleetServerKeysAndPolicies } from './setup/fleet_server_policies_enrollment_keys'; import { ensureSpaceSettings } from './preconfiguration/space_settings'; +import { + ensureDeleteUnenrolledAgentsSetting, + getPreconfiguredDeleteUnenrolledAgentsSettingFromConfig, +} from './preconfiguration/delete_unenrolled_agent_setting'; export interface SetupStatus { isInitialized: boolean; @@ -195,6 +199,12 @@ async function createSetupSideEffects( logger.debug('Setting up Space settings'); await ensureSpaceSettings(appContextService.getConfig()?.spaceSettings ?? []); + logger.debug('Setting up delete unenrolled agents setting'); + await ensureDeleteUnenrolledAgentsSetting( + soClient, + getPreconfiguredDeleteUnenrolledAgentsSettingFromConfig(appContextService.getConfig()) + ); + logger.debug('Setting up Fleet outputs'); await Promise.all([ ensurePreconfiguredOutputs( diff --git a/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts new file mode 100644 index 0000000000000..b8e222d5d1f98 --- /dev/null +++ b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts @@ -0,0 +1,178 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SavedObjectsClient } from '@kbn/core/server'; +import type { + CoreSetup, + ElasticsearchClient, + Logger, + SavedObjectsClientContract, +} from '@kbn/core/server'; +import type { + ConcreteTaskInstance, + TaskManagerSetupContract, + TaskManagerStartContract, +} from '@kbn/task-manager-plugin/server'; +import { getDeleteTaskRunResult } from '@kbn/task-manager-plugin/server/task'; +import type { LoggerFactory } from '@kbn/core/server'; +import { errors } from '@elastic/elasticsearch'; + +import { AGENTS_INDEX } from '../../common/constants'; + +import { settingsService } from '../services'; + +export const TYPE = 'fleet:delete-unenrolled-agents-task'; +export const VERSION = '1.0.0'; +const TITLE = 'Fleet Delete Unenrolled Agents Task'; +const SCOPE = ['fleet']; +const INTERVAL = '1h'; +const TIMEOUT = '1m'; + +interface DeleteUnenrolledAgentsTaskSetupContract { + core: CoreSetup; + taskManager: TaskManagerSetupContract; + logFactory: LoggerFactory; +} + +interface DeleteUnenrolledAgentsTaskStartContract { + taskManager: TaskManagerStartContract; +} + +export class DeleteUnenrolledAgentsTask { + private logger: Logger; + private wasStarted: boolean = false; + private abortController = new AbortController(); + + constructor(setupContract: DeleteUnenrolledAgentsTaskSetupContract) { + const { core, taskManager, logFactory } = setupContract; + this.logger = logFactory.get(this.taskId); + + taskManager.registerTaskDefinitions({ + [TYPE]: { + title: TITLE, + timeout: TIMEOUT, + createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { + return { + run: async () => { + return this.runTask(taskInstance, core); + }, + cancel: async () => { + this.abortController.abort('Task timed out'); + }, + }; + }, + }, + }); + } + + public start = async ({ taskManager }: DeleteUnenrolledAgentsTaskStartContract) => { + if (!taskManager) { + this.logger.error('[DeleteUnenrolledAgentsTask] Missing required service during start'); + return; + } + + this.wasStarted = true; + this.logger.info(`[DeleteUnenrolledAgentsTask] Started with interval of [${INTERVAL}]`); + + try { + await taskManager.ensureScheduled({ + id: this.taskId, + taskType: TYPE, + scope: SCOPE, + schedule: { + interval: INTERVAL, + }, + state: {}, + params: { version: VERSION }, + }); + } catch (e) { + this.logger.error(`Error scheduling task DeleteUnenrolledAgentsTask, error: ${e.message}`, e); + } + }; + + private get taskId(): string { + return `${TYPE}:${VERSION}`; + } + + private endRun(msg: string = '') { + this.logger.info(`[DeleteUnenrolledAgentsTask] runTask ended${msg ? ': ' + msg : ''}`); + } + + public async deleteUnenrolledAgents(esClient: ElasticsearchClient) { + this.logger.debug(`[DeleteUnenrolledAgentsTask] Fetching unenrolled agents`); + + const response = await esClient.deleteByQuery({ + index: AGENTS_INDEX, + body: { + query: { + bool: { + filter: [ + { + term: { + active: false, + }, + }, + { exists: { field: 'unenrolled_at' } }, + ], + }, + }, + }, + }); + + this.logger.debug( + `[DeleteUnenrolledAgentsTask] Executed deletion of ${response.deleted} unenrolled agents` + ); + } + + public async isDeleteUnenrolledAgentsEnabled( + soClient: SavedObjectsClientContract + ): Promise { + const settings = await settingsService.getSettingsOrUndefined(soClient); + return settings?.delete_unenrolled_agents ?? false; + } + + public runTask = async (taskInstance: ConcreteTaskInstance, core: CoreSetup) => { + if (!this.wasStarted) { + this.logger.debug('[DeleteUnenrolledAgentsTask] runTask Aborted. Task not started yet'); + return; + } + // Check that this task is current + if (taskInstance.id !== this.taskId) { + this.logger.debug( + `[DeleteUnenrolledAgentsTask] Outdated task version: Got [${taskInstance.id}] from task instance. Current version is [${this.taskId}]` + ); + return getDeleteTaskRunResult(); + } + + this.logger.info(`[runTask()] started`); + + const [coreStart] = await core.getStartServices(); + const esClient = coreStart.elasticsearch.client.asInternalUser; + const soClient = new SavedObjectsClient(coreStart.savedObjects.createInternalRepository()); + + try { + if (!(await this.isDeleteUnenrolledAgentsEnabled(soClient))) { + this.logger.debug( + '[DeleteUnenrolledAgentsTask] Delete unenrolled agents flag is disabled, returning.' + ); + this.endRun('Delete unenrolled agents is disabled'); + return; + } + await this.deleteUnenrolledAgents(esClient); + + this.endRun('success'); + } catch (err) { + if (err instanceof errors.RequestAbortedError) { + this.logger.warn(`[DeleteUnenrolledAgentsTask] request aborted due to timeout: ${err}`); + this.endRun(); + return; + } + this.logger.error(`[DeleteUnenrolledAgentsTask] error: ${err}`); + this.endRun('error'); + } + }; +} diff --git a/x-pack/plugins/fleet/server/types/rest_spec/settings.ts b/x-pack/plugins/fleet/server/types/rest_spec/settings.ts index 0adaa69f1d30a..e86299c117652 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/settings.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/settings.ts @@ -66,6 +66,7 @@ export const SettingsResponseSchema = schema.object({ schema.oneOf([schema.literal('pending'), schema.literal('success'), schema.literal('error')]) ), use_space_awareness_migration_started_at: schema.maybe(schema.string()), + delete_unenrolled_agents: schema.maybe(schema.boolean()), }), }); diff --git a/x-pack/plugins/fleet/server/types/so_attributes.ts b/x-pack/plugins/fleet/server/types/so_attributes.ts index 9be09fe4ee554..fd2666cb566bb 100644 --- a/x-pack/plugins/fleet/server/types/so_attributes.ts +++ b/x-pack/plugins/fleet/server/types/so_attributes.ts @@ -241,6 +241,7 @@ export interface SettingsSOAttributes { output_secret_storage_requirements_met?: boolean; use_space_awareness_migration_status?: 'pending' | 'success' | 'error'; use_space_awareness_migration_started_at?: string | null; + delete_unenrolled_agents?: boolean; } export interface SpaceSettingsSOAttributes { From 4191916f6b10675ddbde87139a39c79e61defb3e Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:21:17 +0000 Subject: [PATCH 02/17] [CI] Auto-commit changed files from 'node scripts/check_mappings_update --fix' --- packages/kbn-check-mappings-update-cli/current_fields.json | 1 + packages/kbn-check-mappings-update-cli/current_mappings.json | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/packages/kbn-check-mappings-update-cli/current_fields.json b/packages/kbn-check-mappings-update-cli/current_fields.json index 79c6216decb5a..3f4c3c8f3524e 100644 --- a/packages/kbn-check-mappings-update-cli/current_fields.json +++ b/packages/kbn-check-mappings-update-cli/current_fields.json @@ -717,6 +717,7 @@ "vars" ], "ingest_manager_settings": [ + "delete_unenrolled_agents", "fleet_server_hosts", "has_seen_add_data_notice", "output_secret_storage_requirements_met", diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index bfe5816a2f1b2..11abdffcc1c2f 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -2369,6 +2369,10 @@ }, "ingest_manager_settings": { "properties": { + "delete_unenrolled_agents": { + "index": false, + "type": "boolean" + }, "fleet_server_hosts": { "type": "keyword" }, From 0061716717d4d3f35d126452680c11e4c146907b Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 9 Oct 2024 11:47:59 +0200 Subject: [PATCH 03/17] added delete flag to settings UI --- .../settings_page/advanced_section.tsx | 126 ++++++++++++++++++ .../components/settings_page/index.tsx | 3 + .../fleet/server/types/rest_spec/settings.ts | 3 +- 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/advanced_section.tsx diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/advanced_section.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/advanced_section.tsx new file mode 100644 index 0000000000000..cee746f69371d --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/advanced_section.tsx @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useEffect } from 'react'; + +import { + EuiTitle, + EuiLink, + EuiSpacer, + EuiDescribedFormGroup, + EuiSwitch, + EuiForm, + EuiFormRow, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { i18n } from '@kbn/i18n'; + +import { + useAuthz, + useGetSettings, + usePutSettingsMutation, + useStartServices, +} from '../../../../hooks'; + +export const AdvancedSection: React.FunctionComponent<{}> = ({}) => { + const authz = useAuthz(); + const { docLinks, notifications } = useStartServices(); + const deleteUnenrolledAgents = useGetSettings().data?.item?.delete_unenrolled_agents ?? false; + const [deleteUnenrolledAgentsChecked, setDeleteUnenrolledAgentsChecked] = + React.useState(deleteUnenrolledAgents); + const { mutateAsync: mutateSettingsAsync } = usePutSettingsMutation(); + + useEffect(() => { + if (deleteUnenrolledAgents) { + setDeleteUnenrolledAgentsChecked(deleteUnenrolledAgents); + } + }, [deleteUnenrolledAgents]); + + const updateSettings = useCallback( + async (deleteFlag: boolean) => { + try { + setDeleteUnenrolledAgentsChecked(deleteFlag); + const res = await mutateSettingsAsync({ + delete_unenrolled_agents: deleteFlag, + }); + + if (res.error) { + throw res.error; + } + } catch (error) { + setDeleteUnenrolledAgentsChecked(!deleteFlag); + notifications.toasts.addError(error, { + title: i18n.translate('xpack.fleet.errorUpdatingSettings', { + defaultMessage: 'Error updating settings', + }), + }); + } + }, + [mutateSettingsAsync, notifications.toasts] + ); + + return ( + <> + +

+ +

+
+ + + + + + } + description={ +

+ + + + ), + }} + /> +

+ } + > + + + } + checked={deleteUnenrolledAgentsChecked} + onChange={(e) => updateSettings(e.target.checked)} + disabled={!authz.fleet.allSettings} + /> + +
+
+ + + + ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/index.tsx index 809639ecae692..cfeb76ba0d240 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/index.tsx @@ -14,6 +14,7 @@ import { FleetServerHostsSection } from './fleet_server_hosts_section'; import { OutputSection } from './output_section'; import { AgentBinarySection } from './agent_binary_section'; import { FleetProxiesSection } from './fleet_proxies_section'; +import { AdvancedSection } from './advanced_section'; export interface SettingsPageProps { outputs: Output[]; @@ -52,6 +53,8 @@ export const SettingsPage: React.FunctionComponent = ({ /> + + ); }; diff --git a/x-pack/plugins/fleet/server/types/rest_spec/settings.ts b/x-pack/plugins/fleet/server/types/rest_spec/settings.ts index e86299c117652..980a3b8d50f9f 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/settings.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/settings.ts @@ -40,6 +40,7 @@ export const PutSettingsRequestSchema = { ), kibana_ca_sha256: schema.maybe(schema.string()), prerelease_integrations_enabled: schema.maybe(schema.boolean()), + delete_unenrolled_agents: schema.maybe(schema.boolean()), }), }; @@ -56,7 +57,7 @@ export const SettingsResponseSchema = schema.object({ item: schema.object({ has_seen_add_data_notice: schema.maybe(schema.boolean()), fleet_server_hosts: schema.maybe(schema.arrayOf(schema.string())), - prerelease_integrations_enabled: schema.boolean(), + prerelease_integrations_enabled: schema.maybe(schema.boolean()), id: schema.string(), version: schema.maybe(schema.string()), preconfigured_fields: schema.maybe(schema.arrayOf(schema.literal('fleet_server_hosts'))), From 11148b0356c23d8583e69151876724d293893a4e Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:32:58 +0000 Subject: [PATCH 04/17] [CI] Auto-commit changed files from 'node scripts/jest_integration -u src/core/server/integration_tests/ci_checks' --- .../ci_checks/saved_objects/check_registered_types.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts index c8803a1fbd071..c482b80fdc78f 100644 --- a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts +++ b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts @@ -124,7 +124,7 @@ describe('checking migration metadata changes on all registered SO types', () => "ingest-download-sources": "279a68147e62e4d8858c09ad1cf03bd5551ce58d", "ingest-outputs": "daafff49255ab700e07491376fe89f04fc998b91", "ingest-package-policies": "53a94064674835fdb35e5186233bcd7052eabd22", - "ingest_manager_settings": "e794576a05d19dd5306a1e23cbb82c09bffabd65", + "ingest_manager_settings": "0a33c7789b98aecf5b9649b5b3986fcb7e84a6b7", "inventory-view": "b8683c8e352a286b4aca1ab21003115a4800af83", "kql-telemetry": "93c1d16c1a0dfca9c8842062cf5ef8f62ae401ad", "legacy-url-alias": "9b8cca3fbb2da46fd12823d3cd38fdf1c9f24bc8", From 553161cdb9b54b78f3764b8152aadec7604ec48c Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:13:07 +0000 Subject: [PATCH 05/17] [CI] Auto-commit changed files from 'node scripts/capture_oas_snapshot --include-path /api/status --include-path /api/alerting/rule/ --include-path /api/alerting/rules --include-path /api/actions --include-path /api/security/role --include-path /api/spaces --include-path /api/fleet --update' --- oas_docs/bundle.json | 13 ++++++++++--- oas_docs/bundle.serverless.json | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json index 6cc3990de1b51..46cd507b38348 100644 --- a/oas_docs/bundle.json +++ b/oas_docs/bundle.json @@ -26018,7 +26018,7 @@ }, "/api/fleet/logstash_api_keys": { "post": { - "description": "Generate Logstash API keyy", + "description": "Generate Logstash API key", "operationId": "%2Fapi%2Ffleet%2Flogstash_api_keys#0", "parameters": [ { @@ -40127,6 +40127,9 @@ "item": { "additionalProperties": false, "properties": { + "delete_unenrolled_agents": { + "type": "boolean" + }, "fleet_server_hosts": { "items": { "type": "string" @@ -40173,7 +40176,6 @@ } }, "required": [ - "prerelease_integrations_enabled", "id" ], "type": "object" @@ -40272,6 +40274,9 @@ "additional_yaml_config": { "type": "string" }, + "delete_unenrolled_agents": { + "type": "boolean" + }, "fleet_server_hosts": { "items": { "format": "uri", @@ -40311,6 +40316,9 @@ "item": { "additionalProperties": false, "properties": { + "delete_unenrolled_agents": { + "type": "boolean" + }, "fleet_server_hosts": { "items": { "type": "string" @@ -40357,7 +40365,6 @@ } }, "required": [ - "prerelease_integrations_enabled", "id" ], "type": "object" diff --git a/oas_docs/bundle.serverless.json b/oas_docs/bundle.serverless.json index 6fcc247e1fb22..5234a00095d9b 100644 --- a/oas_docs/bundle.serverless.json +++ b/oas_docs/bundle.serverless.json @@ -26018,7 +26018,7 @@ }, "/api/fleet/logstash_api_keys": { "post": { - "description": "Generate Logstash API keyy", + "description": "Generate Logstash API key", "operationId": "%2Fapi%2Ffleet%2Flogstash_api_keys#0", "parameters": [ { @@ -40127,6 +40127,9 @@ "item": { "additionalProperties": false, "properties": { + "delete_unenrolled_agents": { + "type": "boolean" + }, "fleet_server_hosts": { "items": { "type": "string" @@ -40173,7 +40176,6 @@ } }, "required": [ - "prerelease_integrations_enabled", "id" ], "type": "object" @@ -40272,6 +40274,9 @@ "additional_yaml_config": { "type": "string" }, + "delete_unenrolled_agents": { + "type": "boolean" + }, "fleet_server_hosts": { "items": { "format": "uri", @@ -40311,6 +40316,9 @@ "item": { "additionalProperties": false, "properties": { + "delete_unenrolled_agents": { + "type": "boolean" + }, "fleet_server_hosts": { "items": { "type": "string" @@ -40357,7 +40365,6 @@ } }, "required": [ - "prerelease_integrations_enabled", "id" ], "type": "object" From 76970c65dc6307e468f8a6d381f2bc76fcf480a8 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 9 Oct 2024 13:16:08 +0200 Subject: [PATCH 06/17] add test on task --- .../delete_unenrolled_agents_task.test.ts | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts diff --git a/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts new file mode 100644 index 0000000000000..2de81f2a90934 --- /dev/null +++ b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts @@ -0,0 +1,134 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ElasticsearchClientMock } from '@kbn/core/server/mocks'; +import { coreMock } from '@kbn/core/server/mocks'; +import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; +import type { TaskManagerSetupContract } from '@kbn/task-manager-plugin/server'; +import { TaskStatus } from '@kbn/task-manager-plugin/server'; +import { getDeleteTaskRunResult } from '@kbn/task-manager-plugin/server/task'; +import type { CoreSetup } from '@kbn/core/server'; +import { loggingSystemMock } from '@kbn/core/server/mocks'; + +import { settingsService } from '../services'; +import { createAppContextStartContractMock } from '../mocks'; + +import { appContextService } from '../services'; + +import { DeleteUnenrolledAgentsTask, TYPE, VERSION } from './delete_unenrolled_agents_task'; + +jest.mock('../services'); + +const MOCK_TASK_INSTANCE = { + id: `${TYPE}:${VERSION}`, + runAt: new Date(), + attempts: 0, + ownerId: '', + status: TaskStatus.Running, + startedAt: new Date(), + scheduledAt: new Date(), + retryAt: new Date(), + params: {}, + state: {}, + taskType: TYPE, +}; + +describe('DeleteUnenrolledAgentsTask', () => { + const { createSetup: coreSetupMock } = coreMock; + const { createSetup: tmSetupMock, createStart: tmStartMock } = taskManagerMock; + + let mockContract: ReturnType; + let mockTask: DeleteUnenrolledAgentsTask; + let mockCore: CoreSetup; + let mockTaskManagerSetup: jest.Mocked; + const mockSettingsService = settingsService as jest.Mocked; + + beforeEach(() => { + mockContract = createAppContextStartContractMock(); + appContextService.start(mockContract); + mockCore = coreSetupMock(); + mockTaskManagerSetup = tmSetupMock(); + mockTask = new DeleteUnenrolledAgentsTask({ + core: mockCore, + taskManager: mockTaskManagerSetup, + logFactory: loggingSystemMock.create(), + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('Task lifecycle', () => { + it('Should create task', () => { + expect(mockTask).toBeInstanceOf(DeleteUnenrolledAgentsTask); + }); + + it('Should register task', () => { + expect(mockTaskManagerSetup.registerTaskDefinitions).toHaveBeenCalled(); + }); + + it('Should schedule task', async () => { + const mockTaskManagerStart = tmStartMock(); + await mockTask.start({ taskManager: mockTaskManagerStart }); + expect(mockTaskManagerStart.ensureScheduled).toHaveBeenCalled(); + }); + }); + + describe('Task logic', () => { + let esClient: ElasticsearchClientMock; + const runTask = async (taskInstance = MOCK_TASK_INSTANCE) => { + const mockTaskManagerStart = tmStartMock(); + await mockTask.start({ taskManager: mockTaskManagerStart }); + const createTaskRunner = + mockTaskManagerSetup.registerTaskDefinitions.mock.calls[0][0][TYPE].createTaskRunner; + const taskRunner = createTaskRunner({ taskInstance }); + return taskRunner.run(); + }; + + beforeEach(async () => { + const [{ elasticsearch }] = await mockCore.getStartServices(); + esClient = elasticsearch.client.asInternalUser as ElasticsearchClientMock; + esClient.deleteByQuery.mockResolvedValue({ deleted: 10 }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('Should delete unenrolled agents', async () => { + mockSettingsService.getSettingsOrUndefined.mockResolvedValue({ + delete_unenrolled_agents: true, + id: '1', + prerelease_integrations_enabled: false, + }); + + await runTask(); + + expect(esClient.deleteByQuery).toHaveBeenCalled(); + }); + + it('Should not run if task is outdated', async () => { + const result = await runTask({ ...MOCK_TASK_INSTANCE, id: 'old-id' }); + + expect(esClient.deleteByQuery).not.toHaveBeenCalled(); + expect(result).toEqual(getDeleteTaskRunResult()); + }); + + it('Should exit if delete unenrolled agents flag is false', async () => { + mockSettingsService.getSettingsOrUndefined.mockResolvedValue({ + delete_unenrolled_agents: false, + id: '1', + prerelease_integrations_enabled: false, + }); + + await runTask(); + + expect(esClient.deleteByQuery).not.toHaveBeenCalled(); + }); + }); +}); From 22d2d859a9bd4a5de89d3f6b1d0c92cdadd26bce Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 9 Oct 2024 13:22:58 +0200 Subject: [PATCH 07/17] more tests, make prerelease_integrations_enabled optional --- x-pack/plugins/fleet/common/types/models/settings.ts | 2 +- .../fleet/server/routes/settings/settings_handler.test.ts | 2 ++ .../fleet/server/tasks/delete_unenrolled_agents_task.test.ts | 2 -- x-pack/plugins/fleet/server/types/so_attributes.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/fleet/common/types/models/settings.ts b/x-pack/plugins/fleet/common/types/models/settings.ts index 465f06f41f7f3..061b02c491014 100644 --- a/x-pack/plugins/fleet/common/types/models/settings.ts +++ b/x-pack/plugins/fleet/common/types/models/settings.ts @@ -8,7 +8,7 @@ export interface BaseSettings { has_seen_add_data_notice?: boolean; fleet_server_hosts?: string[]; - prerelease_integrations_enabled: boolean; + prerelease_integrations_enabled?: boolean; } export interface Settings extends BaseSettings { diff --git a/x-pack/plugins/fleet/server/routes/settings/settings_handler.test.ts b/x-pack/plugins/fleet/server/routes/settings/settings_handler.test.ts index 0b52c44cde269..c6e51309aee69 100644 --- a/x-pack/plugins/fleet/server/routes/settings/settings_handler.test.ts +++ b/x-pack/plugins/fleet/server/routes/settings/settings_handler.test.ts @@ -31,6 +31,7 @@ jest.mock('../../services', () => ({ has_seen_add_data_notice: true, fleet_server_hosts: ['http://localhost:8220'], prerelease_integrations_enabled: true, + delete_unenrolled_agents: true, }), }, appContextService: { @@ -74,6 +75,7 @@ describe('SettingsHandler', () => { has_seen_add_data_notice: true, fleet_server_hosts: ['http://localhost:8220'], prerelease_integrations_enabled: true, + delete_unenrolled_agents: true, }, }; expect(response.ok).toHaveBeenCalledWith({ diff --git a/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts index 2de81f2a90934..be463dc3795cf 100644 --- a/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts +++ b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts @@ -104,7 +104,6 @@ describe('DeleteUnenrolledAgentsTask', () => { mockSettingsService.getSettingsOrUndefined.mockResolvedValue({ delete_unenrolled_agents: true, id: '1', - prerelease_integrations_enabled: false, }); await runTask(); @@ -123,7 +122,6 @@ describe('DeleteUnenrolledAgentsTask', () => { mockSettingsService.getSettingsOrUndefined.mockResolvedValue({ delete_unenrolled_agents: false, id: '1', - prerelease_integrations_enabled: false, }); await runTask(); diff --git a/x-pack/plugins/fleet/server/types/so_attributes.ts b/x-pack/plugins/fleet/server/types/so_attributes.ts index fd2666cb566bb..bb544a8d4a335 100644 --- a/x-pack/plugins/fleet/server/types/so_attributes.ts +++ b/x-pack/plugins/fleet/server/types/so_attributes.ts @@ -234,7 +234,7 @@ export type OutputSOAttributes = | OutputSoKafkaAttributes; export interface SettingsSOAttributes { - prerelease_integrations_enabled: boolean; + prerelease_integrations_enabled?: boolean; has_seen_add_data_notice?: boolean; fleet_server_hosts?: string[]; secret_storage_requirements_met?: boolean; From 8f20bca4703b5933f1d10b64ef4662974a85b031 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 9 Oct 2024 14:17:31 +0200 Subject: [PATCH 08/17] fix types --- x-pack/plugins/fleet/server/mocks/index.ts | 1 + .../server/services/epm/packages/get_prerelease_setting.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/fleet/server/mocks/index.ts b/x-pack/plugins/fleet/server/mocks/index.ts index 17f85cd252c2b..43b113899072e 100644 --- a/x-pack/plugins/fleet/server/mocks/index.ts +++ b/x-pack/plugins/fleet/server/mocks/index.ts @@ -139,6 +139,7 @@ export const createAppContextStartContractMock = ( } : {}), unenrollInactiveAgentsTask: {} as any, + deleteUnenrolledAgentsTask: {} as any, }; }; diff --git a/x-pack/plugins/fleet/server/services/epm/packages/get_prerelease_setting.ts b/x-pack/plugins/fleet/server/services/epm/packages/get_prerelease_setting.ts index df4b47d13ef2f..48783fa7a6b54 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/get_prerelease_setting.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/get_prerelease_setting.ts @@ -13,7 +13,7 @@ import { getSettings } from '../../settings'; export async function getPrereleaseFromSettings( savedObjectsClient: SavedObjectsClientContract ): Promise { - let prerelease: boolean = false; + let prerelease: boolean | undefined = false; try { ({ prerelease_integrations_enabled: prerelease } = await getSettings(savedObjectsClient)); } catch (err) { @@ -21,5 +21,5 @@ export async function getPrereleaseFromSettings( .getLogger() .warn('Error while trying to load prerelease flag from settings, defaulting to false', err); } - return prerelease; + return prerelease ?? false; } From 8fe491a01b41ec1b10f852efccc9348fd695ee50 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 9 Oct 2024 13:04:04 +0000 Subject: [PATCH 09/17] [CI] Auto-commit changed files from 'make api-docs && make api-docs-staging' --- oas_docs/output/kibana.serverless.staging.yaml | 10 +++++++--- oas_docs/output/kibana.serverless.yaml | 10 +++++++--- oas_docs/output/kibana.staging.yaml | 10 +++++++--- oas_docs/output/kibana.yaml | 10 +++++++--- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/oas_docs/output/kibana.serverless.staging.yaml b/oas_docs/output/kibana.serverless.staging.yaml index 67e2f6844a6df..d74eca599bb27 100644 --- a/oas_docs/output/kibana.serverless.staging.yaml +++ b/oas_docs/output/kibana.serverless.staging.yaml @@ -23557,7 +23557,7 @@ paths: - Elastic Agent policies /api/fleet/logstash_api_keys: post: - description: Generate Logstash API keyy + description: Generate Logstash API key operationId: '%2Fapi%2Ffleet%2Flogstash_api_keys#0' parameters: - description: The version of the API to use @@ -33188,6 +33188,8 @@ paths: additionalProperties: false type: object properties: + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: type: string @@ -33219,7 +33221,6 @@ paths: version: type: string required: - - prerelease_integrations_enabled - id required: - item @@ -33281,6 +33282,8 @@ paths: properties: additional_yaml_config: type: string + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: format: uri @@ -33309,6 +33312,8 @@ paths: additionalProperties: false type: object properties: + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: type: string @@ -33340,7 +33345,6 @@ paths: version: type: string required: - - prerelease_integrations_enabled - id required: - item diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index 67e2f6844a6df..d74eca599bb27 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -23557,7 +23557,7 @@ paths: - Elastic Agent policies /api/fleet/logstash_api_keys: post: - description: Generate Logstash API keyy + description: Generate Logstash API key operationId: '%2Fapi%2Ffleet%2Flogstash_api_keys#0' parameters: - description: The version of the API to use @@ -33188,6 +33188,8 @@ paths: additionalProperties: false type: object properties: + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: type: string @@ -33219,7 +33221,6 @@ paths: version: type: string required: - - prerelease_integrations_enabled - id required: - item @@ -33281,6 +33282,8 @@ paths: properties: additional_yaml_config: type: string + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: format: uri @@ -33309,6 +33312,8 @@ paths: additionalProperties: false type: object properties: + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: type: string @@ -33340,7 +33345,6 @@ paths: version: type: string required: - - prerelease_integrations_enabled - id required: - item diff --git a/oas_docs/output/kibana.staging.yaml b/oas_docs/output/kibana.staging.yaml index 372569024e114..49ce5c42b6dab 100644 --- a/oas_docs/output/kibana.staging.yaml +++ b/oas_docs/output/kibana.staging.yaml @@ -26986,7 +26986,7 @@ paths: - Elastic Agent policies /api/fleet/logstash_api_keys: post: - description: Generate Logstash API keyy + description: Generate Logstash API key operationId: '%2Fapi%2Ffleet%2Flogstash_api_keys#0' parameters: - description: The version of the API to use @@ -36617,6 +36617,8 @@ paths: additionalProperties: false type: object properties: + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: type: string @@ -36648,7 +36650,6 @@ paths: version: type: string required: - - prerelease_integrations_enabled - id required: - item @@ -36710,6 +36711,8 @@ paths: properties: additional_yaml_config: type: string + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: format: uri @@ -36738,6 +36741,8 @@ paths: additionalProperties: false type: object properties: + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: type: string @@ -36769,7 +36774,6 @@ paths: version: type: string required: - - prerelease_integrations_enabled - id required: - item diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index 372569024e114..49ce5c42b6dab 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -26986,7 +26986,7 @@ paths: - Elastic Agent policies /api/fleet/logstash_api_keys: post: - description: Generate Logstash API keyy + description: Generate Logstash API key operationId: '%2Fapi%2Ffleet%2Flogstash_api_keys#0' parameters: - description: The version of the API to use @@ -36617,6 +36617,8 @@ paths: additionalProperties: false type: object properties: + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: type: string @@ -36648,7 +36650,6 @@ paths: version: type: string required: - - prerelease_integrations_enabled - id required: - item @@ -36710,6 +36711,8 @@ paths: properties: additional_yaml_config: type: string + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: format: uri @@ -36738,6 +36741,8 @@ paths: additionalProperties: false type: object properties: + delete_unenrolled_agents: + type: boolean fleet_server_hosts: items: type: string @@ -36769,7 +36774,6 @@ paths: version: type: string required: - - prerelease_integrations_enabled - id required: - item From 3c8409200c8b7ce1ce27db2bf41cda74b0efdecc Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 9 Oct 2024 16:21:01 +0200 Subject: [PATCH 10/17] fix test --- .../test_suites/task_manager/check_registered_task_types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/check_registered_task_types.ts b/x-pack/test/plugin_api_integration/test_suites/task_manager/check_registered_task_types.ts index fcb782b069dbf..1e617db9255de 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/check_registered_task_types.ts +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/check_registered_task_types.ts @@ -138,6 +138,7 @@ export default function ({ getService }: FtrProviderContext) { 'endpoint:metadata-check-transforms-task', 'endpoint:user-artifact-packager', 'fleet:check-deleted-files-task', + 'fleet:delete-unenrolled-agents-task', 'fleet:deploy_agent_policies', 'fleet:reassign_action:retry', 'fleet:request_diagnostics:retry', From 6fe1fc281c990778b28ff44dcd9030c668d7bc89 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Wed, 9 Oct 2024 16:35:29 +0200 Subject: [PATCH 11/17] fix moving delete flag from true to false, add abortController --- .../delete_unenrolled_agent_setting.ts | 4 +++ .../tasks/delete_unenrolled_agents_task.ts | 29 ++++++++++--------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts b/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts index 61225063ce5d8..308d0df346c1e 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts @@ -22,5 +22,9 @@ export async function ensureDeleteUnenrolledAgentsSetting( await settingsService.saveSettings(soClient, { delete_unenrolled_agents: true, }); + } else { + await settingsService.saveSettings(soClient, { + delete_unenrolled_agents: false, + }); } } diff --git a/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts index b8e222d5d1f98..c965111856f7b 100644 --- a/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts +++ b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts @@ -105,23 +105,26 @@ export class DeleteUnenrolledAgentsTask { public async deleteUnenrolledAgents(esClient: ElasticsearchClient) { this.logger.debug(`[DeleteUnenrolledAgentsTask] Fetching unenrolled agents`); - const response = await esClient.deleteByQuery({ - index: AGENTS_INDEX, - body: { - query: { - bool: { - filter: [ - { - term: { - active: false, + const response = await esClient.deleteByQuery( + { + index: AGENTS_INDEX, + body: { + query: { + bool: { + filter: [ + { + term: { + active: false, + }, }, - }, - { exists: { field: 'unenrolled_at' } }, - ], + { exists: { field: 'unenrolled_at' } }, + ], + }, }, }, }, - }); + { signal: this.abortController.signal } + ); this.logger.debug( `[DeleteUnenrolledAgentsTask] Executed deletion of ${response.deleted} unenrolled agents` From 147c2d4b2e8122dbca857751aa14b721225a3e75 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 10 Oct 2024 10:56:30 +0200 Subject: [PATCH 12/17] prevent delete flag to update from UI when preconfigured --- .../fleet/common/types/models/settings.ts | 5 +- .../settings_page/advanced_section.tsx | 41 ++++-- x-pack/plugins/fleet/server/errors/index.ts | 1 + .../routes/settings/settings_handler.test.ts | 10 +- .../fleet/server/saved_objects/index.ts | 14 ++- .../delete_unenrolled_agent_setting.test.ts | 71 +++++++++++ .../delete_unenrolled_agent_setting.ts | 31 +++-- .../fleet/server/services/settings.test.ts | 117 ++++++++++++++++++ .../plugins/fleet/server/services/settings.ts | 17 ++- .../delete_unenrolled_agents_task.test.ts | 10 +- .../tasks/delete_unenrolled_agents_task.ts | 2 +- .../fleet/server/types/rest_spec/settings.ts | 14 ++- .../fleet/server/types/so_attributes.ts | 5 +- 13 files changed, 303 insertions(+), 35 deletions(-) create mode 100644 x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.test.ts diff --git a/x-pack/plugins/fleet/common/types/models/settings.ts b/x-pack/plugins/fleet/common/types/models/settings.ts index 061b02c491014..a63211ef14c55 100644 --- a/x-pack/plugins/fleet/common/types/models/settings.ts +++ b/x-pack/plugins/fleet/common/types/models/settings.ts @@ -19,5 +19,8 @@ export interface Settings extends BaseSettings { output_secret_storage_requirements_met?: boolean; use_space_awareness_migration_status?: 'pending' | 'success' | 'error'; use_space_awareness_migration_started_at?: string | null; - delete_unenrolled_agents?: boolean; + delete_unenrolled_agents?: { + enabled: boolean; + is_preconfigured: boolean; + }; } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/advanced_section.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/advanced_section.tsx index cee746f69371d..c4e9478e0762e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/advanced_section.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/advanced_section.tsx @@ -15,6 +15,7 @@ import { EuiSwitch, EuiForm, EuiFormRow, + EuiToolTip, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -30,7 +31,10 @@ import { export const AdvancedSection: React.FunctionComponent<{}> = ({}) => { const authz = useAuthz(); const { docLinks, notifications } = useStartServices(); - const deleteUnenrolledAgents = useGetSettings().data?.item?.delete_unenrolled_agents ?? false; + const deleteUnenrolledAgents = + useGetSettings().data?.item?.delete_unenrolled_agents?.enabled ?? false; + const isPreconfigured = + useGetSettings().data?.item?.delete_unenrolled_agents?.is_preconfigured ?? false; const [deleteUnenrolledAgentsChecked, setDeleteUnenrolledAgentsChecked] = React.useState(deleteUnenrolledAgents); const { mutateAsync: mutateSettingsAsync } = usePutSettingsMutation(); @@ -46,7 +50,10 @@ export const AdvancedSection: React.FunctionComponent<{}> = ({}) => { try { setDeleteUnenrolledAgentsChecked(deleteFlag); const res = await mutateSettingsAsync({ - delete_unenrolled_agents: deleteFlag, + delete_unenrolled_agents: { + enabled: deleteFlag, + is_preconfigured: false, + }, }); if (res.error) { @@ -105,17 +112,27 @@ export const AdvancedSection: React.FunctionComponent<{}> = ({}) => { } > - + updateSettings(e.target.checked)} - disabled={!authz.fleet.allSettings} - /> + > + + } + checked={deleteUnenrolledAgentsChecked} + onChange={(e) => updateSettings(e.target.checked)} + disabled={!authz.fleet.allSettings || isPreconfigured} + /> + diff --git a/x-pack/plugins/fleet/server/errors/index.ts b/x-pack/plugins/fleet/server/errors/index.ts index 09b387e7a5cee..6782b8122a552 100644 --- a/x-pack/plugins/fleet/server/errors/index.ts +++ b/x-pack/plugins/fleet/server/errors/index.ts @@ -100,6 +100,7 @@ export class OutputUnauthorizedError extends FleetError {} export class OutputInvalidError extends FleetError {} export class OutputLicenceError extends FleetError {} export class DownloadSourceError extends FleetError {} +export class DeleteUnenrolledAgentsPreconfiguredError extends FleetError {} // Not found errors export class AgentNotFoundError extends FleetNotFoundError {} diff --git a/x-pack/plugins/fleet/server/routes/settings/settings_handler.test.ts b/x-pack/plugins/fleet/server/routes/settings/settings_handler.test.ts index c6e51309aee69..73641bfaed71a 100644 --- a/x-pack/plugins/fleet/server/routes/settings/settings_handler.test.ts +++ b/x-pack/plugins/fleet/server/routes/settings/settings_handler.test.ts @@ -31,7 +31,10 @@ jest.mock('../../services', () => ({ has_seen_add_data_notice: true, fleet_server_hosts: ['http://localhost:8220'], prerelease_integrations_enabled: true, - delete_unenrolled_agents: true, + delete_unenrolled_agents: { + enabled: true, + is_preconfigured: false, + }, }), }, appContextService: { @@ -75,7 +78,10 @@ describe('SettingsHandler', () => { has_seen_add_data_notice: true, fleet_server_hosts: ['http://localhost:8220'], prerelease_integrations_enabled: true, - delete_unenrolled_agents: true, + delete_unenrolled_agents: { + enabled: true, + is_preconfigured: false, + }, }, }; expect(response.ok).toHaveBeenCalledWith({ diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index 3a50720ae28a5..ffb9381f8b30c 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -161,7 +161,12 @@ export const getSavedObjectTypes = ( output_secret_storage_requirements_met: { type: 'boolean' }, use_space_awareness_migration_status: { type: 'keyword', index: false }, use_space_awareness_migration_started_at: { type: 'date', index: false }, - delete_unenrolled_agents: { type: 'boolean', index: false }, + delete_unenrolled_agents: { + properties: { + enabled: { type: 'boolean', index: false }, + is_preconfigured: { type: 'boolean', index: false }, + }, + }, }, }, migrations: { @@ -187,7 +192,12 @@ export const getSavedObjectTypes = ( { type: 'mappings_addition', addedMappings: { - delete_unenrolled_agents: { type: 'boolean', index: false }, + delete_unenrolled_agents: { + properties: { + enabled: { type: 'boolean', index: false }, + is_preconfigured: { type: 'boolean', index: false }, + }, + }, }, }, ], diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.test.ts new file mode 100644 index 0000000000000..aa1a7573f225b --- /dev/null +++ b/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.test.ts @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { settingsService } from '..'; + +import { ensureDeleteUnenrolledAgentsSetting } from './delete_unenrolled_agent_setting'; + +jest.mock('..', () => ({ + settingsService: { + getSettingsOrUndefined: jest.fn(), + saveSettings: jest.fn(), + }, +})); + +describe('delete_unenrolled_agent_setting', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should update settings with delete_unenrolled_agents enabled', async () => { + await ensureDeleteUnenrolledAgentsSetting({} as any, true); + + expect(settingsService.saveSettings).toHaveBeenCalledWith( + expect.anything(), + { delete_unenrolled_agents: { enabled: true, is_preconfigured: true } }, + { fromSetup: true } + ); + }); + + it('should update settings with delete_unenrolled_agents disabled', async () => { + await ensureDeleteUnenrolledAgentsSetting({} as any, false); + + expect(settingsService.saveSettings).toHaveBeenCalledWith( + expect.anything(), + { delete_unenrolled_agents: { enabled: false, is_preconfigured: true } }, + { fromSetup: true } + ); + }); + + it('should update settings when previously preconfigured', async () => { + (settingsService.getSettingsOrUndefined as jest.Mock).mockResolvedValue({ + delete_unenrolled_agents: { + enabled: false, + is_preconfigured: true, + }, + }); + await ensureDeleteUnenrolledAgentsSetting({} as any); + + expect(settingsService.saveSettings).toHaveBeenCalledWith( + expect.anything(), + { delete_unenrolled_agents: { enabled: false, is_preconfigured: false } }, + { fromSetup: true } + ); + }); + + it('should not update settings when previously not preconfigured', async () => { + (settingsService.getSettingsOrUndefined as jest.Mock).mockResolvedValue({ + delete_unenrolled_agents: { + enabled: false, + is_preconfigured: false, + }, + }); + await ensureDeleteUnenrolledAgentsSetting({} as any); + + expect(settingsService.saveSettings).not.toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts b/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts index 308d0df346c1e..ba54e1c5146b2 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/delete_unenrolled_agent_setting.ts @@ -10,21 +10,30 @@ import type { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-ser import { settingsService } from '..'; import type { FleetConfigType } from '../../config'; -export function getPreconfiguredDeleteUnenrolledAgentsSettingFromConfig(config?: FleetConfigType) { - return config.enableDeleteUnenrolledAgents ?? false; +export function getPreconfiguredDeleteUnenrolledAgentsSettingFromConfig( + config?: FleetConfigType +): boolean | undefined { + return config.enableDeleteUnenrolledAgents; } export async function ensureDeleteUnenrolledAgentsSetting( soClient: SavedObjectsClientContract, - enableDeleteUnenrolledAgents: boolean + enableDeleteUnenrolledAgents?: boolean ) { - if (enableDeleteUnenrolledAgents) { - await settingsService.saveSettings(soClient, { - delete_unenrolled_agents: true, - }); - } else { - await settingsService.saveSettings(soClient, { - delete_unenrolled_agents: false, - }); + if (enableDeleteUnenrolledAgents === undefined) { + const settings = await settingsService.getSettingsOrUndefined(soClient); + if (!settings?.delete_unenrolled_agents?.is_preconfigured) { + return; + } } + await settingsService.saveSettings( + soClient, + { + delete_unenrolled_agents: { + enabled: !!enableDeleteUnenrolledAgents, + is_preconfigured: enableDeleteUnenrolledAgents !== undefined, + }, + }, + { fromSetup: true } + ); } diff --git a/x-pack/plugins/fleet/server/services/settings.test.ts b/x-pack/plugins/fleet/server/services/settings.test.ts index 33926b0ec12f7..92fb85a335775 100644 --- a/x-pack/plugins/fleet/server/services/settings.test.ts +++ b/x-pack/plugins/fleet/server/services/settings.test.ts @@ -14,6 +14,8 @@ import { GLOBAL_SETTINGS_ID, GLOBAL_SETTINGS_SAVED_OBJECT_TYPE } from '../../com import type { Settings } from '../types'; +import { DeleteUnenrolledAgentsPreconfiguredError } from '../errors'; + import { appContextService } from './app_context'; import { getSettings, saveSettings, settingsSetup } from './settings'; import { auditLoggingService } from './audit_logging'; @@ -225,4 +227,119 @@ describe('saveSettings', () => { }); }); }); + + it('should allow updating preconfigured setting if called from setup', async () => { + const soClient = savedObjectsClientMock.create(); + + const newData: Partial> = { + delete_unenrolled_agents: { + enabled: true, + is_preconfigured: true, + }, + }; + + soClient.find.mockResolvedValueOnce({ + saved_objects: [ + { + id: GLOBAL_SETTINGS_ID, + attributes: { + delete_unenrolled_agents: { + enabled: false, + is_preconfigured: true, + }, + }, + references: [], + type: GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, + score: 0, + }, + ], + page: 1, + per_page: 10, + total: 1, + }); + mockListFleetServerHosts.mockResolvedValueOnce({ + items: [ + { + id: 'fleet-server-host', + name: 'Fleet Server Host', + is_default: true, + is_preconfigured: false, + host_urls: ['http://localhost:8220'], + }, + ], + page: 1, + perPage: 10, + total: 1, + }); + + soClient.update.mockResolvedValueOnce({ + id: GLOBAL_SETTINGS_ID, + attributes: {}, + references: [], + type: GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, + }); + + await saveSettings(soClient, newData, { fromSetup: true }); + + expect(soClient.update).toHaveBeenCalled(); + }); + + it('should not allow updating preconfigured setting if not called from setup', async () => { + const soClient = savedObjectsClientMock.create(); + + const newData: Partial> = { + delete_unenrolled_agents: { + enabled: true, + is_preconfigured: true, + }, + }; + + soClient.find.mockResolvedValueOnce({ + saved_objects: [ + { + id: GLOBAL_SETTINGS_ID, + attributes: { + delete_unenrolled_agents: { + enabled: false, + is_preconfigured: true, + }, + }, + references: [], + type: GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, + score: 0, + }, + ], + page: 1, + per_page: 10, + total: 1, + }); + mockListFleetServerHosts.mockResolvedValueOnce({ + items: [ + { + id: 'fleet-server-host', + name: 'Fleet Server Host', + is_default: true, + is_preconfigured: false, + host_urls: ['http://localhost:8220'], + }, + ], + page: 1, + perPage: 10, + total: 1, + }); + + soClient.update.mockResolvedValueOnce({ + id: GLOBAL_SETTINGS_ID, + attributes: {}, + references: [], + type: GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, + }); + + try { + await saveSettings(soClient, newData); + fail('Expected to throw'); + } catch (e) { + expect(e).toBeInstanceOf(DeleteUnenrolledAgentsPreconfiguredError); + } + }); }); diff --git a/x-pack/plugins/fleet/server/services/settings.ts b/x-pack/plugins/fleet/server/services/settings.ts index ea883e1bf7de3..5f7433403c4e6 100644 --- a/x-pack/plugins/fleet/server/services/settings.ts +++ b/x-pack/plugins/fleet/server/services/settings.ts @@ -13,6 +13,8 @@ import { GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, GLOBAL_SETTINGS_ID } from '../../com import type { Settings, BaseSettings } from '../../common/types'; import type { SettingsSOAttributes } from '../types'; +import { DeleteUnenrolledAgentsPreconfiguredError } from '../errors'; + import { appContextService } from './app_context'; import { listFleetServerHosts } from './fleet_server_host'; import { auditLoggingService } from './audit_logging'; @@ -81,7 +83,10 @@ export async function settingsSetup(soClient: SavedObjectsClientContract) { export async function saveSettings( soClient: SavedObjectsClientContract, newData: Partial>, - options?: SavedObjectsUpdateOptions & { createWithOverwrite?: boolean } + options?: SavedObjectsUpdateOptions & { + createWithOverwrite?: boolean; + fromSetup?: boolean; + } ): Promise & Pick> { const data = { ...newData }; if (data.fleet_server_hosts) { @@ -92,6 +97,16 @@ export async function saveSettings( try { const settings = await getSettings(soClient); + if ( + !options?.fromSetup && + settings.delete_unenrolled_agents?.is_preconfigured && + data.delete_unenrolled_agents + ) { + throw new DeleteUnenrolledAgentsPreconfiguredError( + `Setting delete_unenrolled_agents is preconfigured as 'enableDeleteUnenrolledAgents' and cannot be updated outside of kibana config file.` + ); + } + auditLoggingService.writeCustomSoAuditLog({ action: 'update', id: settings.id, diff --git a/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts index be463dc3795cf..54996c27975e3 100644 --- a/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts +++ b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.test.ts @@ -102,7 +102,10 @@ describe('DeleteUnenrolledAgentsTask', () => { it('Should delete unenrolled agents', async () => { mockSettingsService.getSettingsOrUndefined.mockResolvedValue({ - delete_unenrolled_agents: true, + delete_unenrolled_agents: { + enabled: true, + is_preconfigured: false, + }, id: '1', }); @@ -120,7 +123,10 @@ describe('DeleteUnenrolledAgentsTask', () => { it('Should exit if delete unenrolled agents flag is false', async () => { mockSettingsService.getSettingsOrUndefined.mockResolvedValue({ - delete_unenrolled_agents: false, + delete_unenrolled_agents: { + enabled: false, + is_preconfigured: false, + }, id: '1', }); diff --git a/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts index c965111856f7b..440567effac7d 100644 --- a/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts +++ b/x-pack/plugins/fleet/server/tasks/delete_unenrolled_agents_task.ts @@ -135,7 +135,7 @@ export class DeleteUnenrolledAgentsTask { soClient: SavedObjectsClientContract ): Promise { const settings = await settingsService.getSettingsOrUndefined(soClient); - return settings?.delete_unenrolled_agents ?? false; + return settings?.delete_unenrolled_agents?.enabled ?? false; } public runTask = async (taskInstance: ConcreteTaskInstance, core: CoreSetup) => { diff --git a/x-pack/plugins/fleet/server/types/rest_spec/settings.ts b/x-pack/plugins/fleet/server/types/rest_spec/settings.ts index 980a3b8d50f9f..459070fa9591a 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/settings.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/settings.ts @@ -40,7 +40,12 @@ export const PutSettingsRequestSchema = { ), kibana_ca_sha256: schema.maybe(schema.string()), prerelease_integrations_enabled: schema.maybe(schema.boolean()), - delete_unenrolled_agents: schema.maybe(schema.boolean()), + delete_unenrolled_agents: schema.maybe( + schema.object({ + enabled: schema.boolean(), + is_preconfigured: schema.boolean(), + }) + ), }), }; @@ -67,7 +72,12 @@ export const SettingsResponseSchema = schema.object({ schema.oneOf([schema.literal('pending'), schema.literal('success'), schema.literal('error')]) ), use_space_awareness_migration_started_at: schema.maybe(schema.string()), - delete_unenrolled_agents: schema.maybe(schema.boolean()), + delete_unenrolled_agents: schema.maybe( + schema.object({ + enabled: schema.boolean(), + is_preconfigured: schema.boolean(), + }) + ), }), }); diff --git a/x-pack/plugins/fleet/server/types/so_attributes.ts b/x-pack/plugins/fleet/server/types/so_attributes.ts index bb544a8d4a335..31207dda64bc8 100644 --- a/x-pack/plugins/fleet/server/types/so_attributes.ts +++ b/x-pack/plugins/fleet/server/types/so_attributes.ts @@ -241,7 +241,10 @@ export interface SettingsSOAttributes { output_secret_storage_requirements_met?: boolean; use_space_awareness_migration_status?: 'pending' | 'success' | 'error'; use_space_awareness_migration_started_at?: string | null; - delete_unenrolled_agents?: boolean; + delete_unenrolled_agents?: { + enabled: boolean; + is_preconfigured: boolean; + }; } export interface SpaceSettingsSOAttributes { From 8c25642e475c631861e8eac6fa82797f667fd5e1 Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 10 Oct 2024 13:23:07 +0200 Subject: [PATCH 13/17] fix checks --- packages/kbn-check-mappings-update-cli/current_fields.json | 6 +++--- .../ci_checks/saved_objects/check_registered_types.test.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/kbn-check-mappings-update-cli/current_fields.json b/packages/kbn-check-mappings-update-cli/current_fields.json index 3f4c3c8f3524e..c85747291281c 100644 --- a/packages/kbn-check-mappings-update-cli/current_fields.json +++ b/packages/kbn-check-mappings-update-cli/current_fields.json @@ -233,9 +233,7 @@ "payload.connector.type", "type" ], - "cloud-security-posture-settings": [ - "rules" - ], + "cloud-security-posture-settings": [], "config": [ "buildNum" ], @@ -718,6 +716,8 @@ ], "ingest_manager_settings": [ "delete_unenrolled_agents", + "delete_unenrolled_agents.enabled", + "delete_unenrolled_agents.is_preconfigured", "fleet_server_hosts", "has_seen_add_data_notice", "output_secret_storage_requirements_met", diff --git a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts index c482b80fdc78f..d3a0e80e93d29 100644 --- a/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts +++ b/src/core/server/integration_tests/ci_checks/saved_objects/check_registered_types.test.ts @@ -124,7 +124,7 @@ describe('checking migration metadata changes on all registered SO types', () => "ingest-download-sources": "279a68147e62e4d8858c09ad1cf03bd5551ce58d", "ingest-outputs": "daafff49255ab700e07491376fe89f04fc998b91", "ingest-package-policies": "53a94064674835fdb35e5186233bcd7052eabd22", - "ingest_manager_settings": "0a33c7789b98aecf5b9649b5b3986fcb7e84a6b7", + "ingest_manager_settings": "111a616eb72627c002029c19feb9e6c439a10505", "inventory-view": "b8683c8e352a286b4aca1ab21003115a4800af83", "kql-telemetry": "93c1d16c1a0dfca9c8842062cf5ef8f62ae401ad", "legacy-url-alias": "9b8cca3fbb2da46fd12823d3cd38fdf1c9f24bc8", From 3c604cc8513ce13a261bb94db178072ac0e2a4ec Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 10 Oct 2024 14:06:01 +0200 Subject: [PATCH 14/17] update current_mappings --- .../current_mappings.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index 11abdffcc1c2f..8ef6a2148262d 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -2370,8 +2370,16 @@ "ingest_manager_settings": { "properties": { "delete_unenrolled_agents": { - "index": false, - "type": "boolean" + "properties": { + "enabled": { + "index": false, + "type": "boolean" + }, + "is_preconfigured": { + "index": false, + "type": "boolean" + } + } }, "fleet_server_hosts": { "type": "keyword" From ebf978df5b6f37106af7f1e3ff674e54480c3301 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 10 Oct 2024 12:51:16 +0000 Subject: [PATCH 15/17] [CI] Auto-commit changed files from 'node scripts/capture_oas_snapshot --include-path /api/status --include-path /api/alerting/rule/ --include-path /api/alerting/rules --include-path /api/actions --include-path /api/security/role --include-path /api/spaces --include-path /api/fleet --update' --- oas_docs/bundle.json | 45 ++++++++++++++++++++++++++++++--- oas_docs/bundle.serverless.json | 45 ++++++++++++++++++++++++++++++--- 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json index 46cd507b38348..8a2eb526a09c0 100644 --- a/oas_docs/bundle.json +++ b/oas_docs/bundle.json @@ -40128,7 +40128,20 @@ "additionalProperties": false, "properties": { "delete_unenrolled_agents": { - "type": "boolean" + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "is_preconfigured" + ], + "type": "object" }, "fleet_server_hosts": { "items": { @@ -40275,7 +40288,20 @@ "type": "string" }, "delete_unenrolled_agents": { - "type": "boolean" + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "is_preconfigured" + ], + "type": "object" }, "fleet_server_hosts": { "items": { @@ -40317,7 +40343,20 @@ "additionalProperties": false, "properties": { "delete_unenrolled_agents": { - "type": "boolean" + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "is_preconfigured" + ], + "type": "object" }, "fleet_server_hosts": { "items": { diff --git a/oas_docs/bundle.serverless.json b/oas_docs/bundle.serverless.json index 5234a00095d9b..a1202965b5341 100644 --- a/oas_docs/bundle.serverless.json +++ b/oas_docs/bundle.serverless.json @@ -40128,7 +40128,20 @@ "additionalProperties": false, "properties": { "delete_unenrolled_agents": { - "type": "boolean" + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "is_preconfigured" + ], + "type": "object" }, "fleet_server_hosts": { "items": { @@ -40275,7 +40288,20 @@ "type": "string" }, "delete_unenrolled_agents": { - "type": "boolean" + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "is_preconfigured" + ], + "type": "object" }, "fleet_server_hosts": { "items": { @@ -40317,7 +40343,20 @@ "additionalProperties": false, "properties": { "delete_unenrolled_agents": { - "type": "boolean" + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean" + }, + "is_preconfigured": { + "type": "boolean" + } + }, + "required": [ + "enabled", + "is_preconfigured" + ], + "type": "object" }, "fleet_server_hosts": { "items": { From 42839cf0466aedf723f7c5eb9cffbc72adb2806c Mon Sep 17 00:00:00 2001 From: Julia Bardi Date: Thu, 10 Oct 2024 14:53:37 +0200 Subject: [PATCH 16/17] added finally block --- .../kbn-check-mappings-update-cli/current_mappings.json | 8 ++++---- .../src/compatibility/check_incompatible_mappings.ts | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index 8ef6a2148262d..01a3d016e594b 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -2371,13 +2371,13 @@ "properties": { "delete_unenrolled_agents": { "properties": { - "enabled": { + "enabled": { "index": false, - "type": "boolean" + "type": "boolean" }, - "is_preconfigured": { + "is_preconfigured": { "index": false, - "type": "boolean" + "type": "boolean" } } }, diff --git a/packages/kbn-check-mappings-update-cli/src/compatibility/check_incompatible_mappings.ts b/packages/kbn-check-mappings-update-cli/src/compatibility/check_incompatible_mappings.ts index 1355e8547250e..ce9e2acef8d4c 100644 --- a/packages/kbn-check-mappings-update-cli/src/compatibility/check_incompatible_mappings.ts +++ b/packages/kbn-check-mappings-update-cli/src/compatibility/check_incompatible_mappings.ts @@ -54,5 +54,7 @@ export async function checkIncompatibleMappings({ throw createFailError( `Only mappings changes that are compatible with current mappings are allowed. Consider reaching out to the Kibana core team if you are stuck.` ); + } finally { + await esClient.indices.delete({ index: TEST_INDEX_NAME }).catch(() => {}); } } From b7b7eecdab0fb3a8a7008c10bbba40ce1aa408a6 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 10 Oct 2024 13:48:48 +0000 Subject: [PATCH 17/17] [CI] Auto-commit changed files from 'make api-docs && make api-docs-staging' --- .../output/kibana.serverless.staging.yaml | 33 +++++++++++++++++-- oas_docs/output/kibana.serverless.yaml | 33 +++++++++++++++++-- oas_docs/output/kibana.staging.yaml | 33 +++++++++++++++++-- oas_docs/output/kibana.yaml | 33 +++++++++++++++++-- 4 files changed, 120 insertions(+), 12 deletions(-) diff --git a/oas_docs/output/kibana.serverless.staging.yaml b/oas_docs/output/kibana.serverless.staging.yaml index 6792cb898f11c..a4b3f37c5c2e8 100644 --- a/oas_docs/output/kibana.serverless.staging.yaml +++ b/oas_docs/output/kibana.serverless.staging.yaml @@ -33190,7 +33190,16 @@ paths: type: object properties: delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: type: string @@ -33284,7 +33293,16 @@ paths: additional_yaml_config: type: string delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: format: uri @@ -33314,7 +33332,16 @@ paths: type: object properties: delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: type: string diff --git a/oas_docs/output/kibana.serverless.yaml b/oas_docs/output/kibana.serverless.yaml index 6792cb898f11c..a4b3f37c5c2e8 100644 --- a/oas_docs/output/kibana.serverless.yaml +++ b/oas_docs/output/kibana.serverless.yaml @@ -33190,7 +33190,16 @@ paths: type: object properties: delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: type: string @@ -33284,7 +33293,16 @@ paths: additional_yaml_config: type: string delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: format: uri @@ -33314,7 +33332,16 @@ paths: type: object properties: delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: type: string diff --git a/oas_docs/output/kibana.staging.yaml b/oas_docs/output/kibana.staging.yaml index 9a35c01349d4b..809703d3887fa 100644 --- a/oas_docs/output/kibana.staging.yaml +++ b/oas_docs/output/kibana.staging.yaml @@ -36619,7 +36619,16 @@ paths: type: object properties: delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: type: string @@ -36713,7 +36722,16 @@ paths: additional_yaml_config: type: string delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: format: uri @@ -36743,7 +36761,16 @@ paths: type: object properties: delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: type: string diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index 9a35c01349d4b..809703d3887fa 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -36619,7 +36619,16 @@ paths: type: object properties: delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: type: string @@ -36713,7 +36722,16 @@ paths: additional_yaml_config: type: string delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: format: uri @@ -36743,7 +36761,16 @@ paths: type: object properties: delete_unenrolled_agents: - type: boolean + additionalProperties: false + type: object + properties: + enabled: + type: boolean + is_preconfigured: + type: boolean + required: + - enabled + - is_preconfigured fleet_server_hosts: items: type: string