diff --git a/docs/settings/fleet-settings.asciidoc b/docs/settings/fleet-settings.asciidoc index 0960937564b7d..a222e4e5af578 100644 --- a/docs/settings/fleet-settings.asciidoc +++ b/docs/settings/fleet-settings.asciidoc @@ -95,6 +95,8 @@ List of agent policies that are configured when the {fleet} app starts. String identifying this policy's namespace. `monitoring_enabled`::: List of keywords that specify the monitoring data to collect. Valid values include `['logs']`, `['metrics']`, and `['logs', 'metrics']`. + `keep_monitoring_alive`::: + If `true`, monitoring will be enabled, but logs/metrics collection will be disabled. Use this if you want to keep agent's monitoring server alive even when logs/metrics aren't being collected. `is_managed`::: If `true`, this policy is not editable by the user and can only be changed by updating the {kib} config. `is_default`::: diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index 4ebb8065dbe1d..7fc18bb58a00b 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -1645,6 +1645,9 @@ "overrides": { "type": "flattened", "index": false + }, + "keep_monitoring_alive": { + "type": "boolean" } } }, @@ -2594,6 +2597,106 @@ "dynamic": false, "properties": {} }, + "infrastructure-ui-source": { + "dynamic": false, + "properties": {} + }, + "inventory-view": { + "dynamic": false, + "properties": {} + }, + "metrics-explorer-view": { + "dynamic": false, + "properties": {} + }, + "upgrade-assistant-reindex-operation": { + "dynamic": false, + "properties": { + "indexName": { + "type": "keyword" + }, + "status": { + "type": "integer" + } + } + }, + "upgrade-assistant-ml-upgrade-operation": { + "dynamic": false, + "properties": { + "snapshotId": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + } + } + }, + "monitoring-telemetry": { + "properties": { + "reportedClusterUuids": { + "type": "keyword" + } + } + }, + "apm-telemetry": { + "dynamic": false, + "properties": {} + }, + "apm-server-schema": { + "properties": { + "schemaJson": { + "type": "text", + "index": false + } + } + }, + "apm-service-group": { + "properties": { + "groupName": { + "type": "keyword" + }, + "kuery": { + "type": "text" + }, + "description": { + "type": "text" + }, + "color": { + "type": "text" + } + } + }, + "apm-custom-dashboards": { + "properties": { + "dashboardSavedObjectId": { + "type": "keyword" + }, + "kuery": { + "type": "text" + }, + "serviceEnvironmentFilterEnabled": { + "type": "boolean" + }, + "serviceNameFilterEnabled": { + "type": "boolean" + } + } + }, + "enterprise_search_telemetry": { + "dynamic": false, + "properties": {} + }, + "app_search_telemetry": { + "dynamic": false, + "properties": {} + }, + "workplace_search_telemetry": { + "dynamic": false, + "properties": {} + }, "siem-ui-timeline-note": { "properties": { "eventId": { @@ -3055,105 +3158,5 @@ "index": false } } - }, - "infrastructure-ui-source": { - "dynamic": false, - "properties": {} - }, - "inventory-view": { - "dynamic": false, - "properties": {} - }, - "metrics-explorer-view": { - "dynamic": false, - "properties": {} - }, - "upgrade-assistant-reindex-operation": { - "dynamic": false, - "properties": { - "indexName": { - "type": "keyword" - }, - "status": { - "type": "integer" - } - } - }, - "upgrade-assistant-ml-upgrade-operation": { - "dynamic": false, - "properties": { - "snapshotId": { - "type": "text", - "fields": { - "keyword": { - "type": "keyword", - "ignore_above": 256 - } - } - } - } - }, - "monitoring-telemetry": { - "properties": { - "reportedClusterUuids": { - "type": "keyword" - } - } - }, - "apm-telemetry": { - "dynamic": false, - "properties": {} - }, - "apm-server-schema": { - "properties": { - "schemaJson": { - "type": "text", - "index": false - } - } - }, - "apm-service-group": { - "properties": { - "groupName": { - "type": "keyword" - }, - "kuery": { - "type": "text" - }, - "description": { - "type": "text" - }, - "color": { - "type": "text" - } - } - }, - "apm-custom-dashboards": { - "properties": { - "dashboardSavedObjectId": { - "type": "keyword" - }, - "kuery": { - "type": "text" - }, - "serviceEnvironmentFilterEnabled": { - "type": "boolean" - }, - "serviceNameFilterEnabled": { - "type": "boolean" - } - } - }, - "enterprise_search_telemetry": { - "dynamic": false, - "properties": {} - }, - "app_search_telemetry": { - "dynamic": false, - "properties": {} - }, - "workplace_search_telemetry": { - "dynamic": false, - "properties": {} } } diff --git a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts index 01794d226e312..62780b66727ef 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts @@ -104,7 +104,7 @@ describe('checking migration metadata changes on all registered SO types', () => "index-pattern": "997108a9ea1e8076e22231e1c95517cdb192b9c5", "infrastructure-monitoring-log-view": "5f86709d3c27aed7a8379153b08ee5d3d90d77f5", "infrastructure-ui-source": "113182d6895764378dfe7fa9fa027244f3a457c4", - "ingest-agent-policies": "f11cc19275f4c3e4ee7c5cd6423b6706b21b989d", + "ingest-agent-policies": "7633e578f60c074f8267bc50ec4763845e431437", "ingest-download-sources": "279a68147e62e4d8858c09ad1cf03bd5551ce58d", "ingest-outputs": "b4e636b13a5d0f89f0400fb67811d4cca4736eb0", "ingest-package-policies": "a0c9fb48e04dcd638e593db55f1c6451523f90ea", diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index 509a598a62ad4..e260764d57de8 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -7036,6 +7036,11 @@ ] } }, + "keep_monitoring_alive": { + "description": "When set to true, monitoring will be enabled but logs/metrics collection will be disabled", + "type": "boolean", + "nullable": true + }, "data_output_id": { "type": "string", "nullable": true diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index 7f43bb2e3b710..9ed380d26726b 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -4491,6 +4491,12 @@ components: enum: - metrics - logs + keep_monitoring_alive: + description: >- + When set to true, monitoring will be enabled but logs/metrics + collection will be disabled + type: boolean + nullable: true data_output_id: type: string nullable: true diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/agent_policy.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/agent_policy.yaml index ac29a287b91c8..251f76fad966f 100644 --- a/x-pack/plugins/fleet/common/openapi/components/schemas/agent_policy.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/agent_policy.yaml @@ -16,6 +16,10 @@ properties: enum: - metrics - logs + keep_monitoring_alive: + description: When set to true, monitoring will be enabled but logs/metrics collection will be disabled + type: boolean + nullable: true data_output_id: type: string nullable: true 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 a653bbfb8b223..4e5d6250208a5 100644 --- a/x-pack/plugins/fleet/common/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/common/types/models/agent_policy.ts @@ -52,6 +52,7 @@ export interface AgentPolicy extends Omit { revision: number; agents?: number; is_protected: boolean; + keep_monitoring_alive?: boolean; } export interface FullAgentPolicyInputStream { @@ -87,6 +88,14 @@ export type FullAgentPolicyOutput = Pick [key: string]: any; }; +export interface FullAgentPolicyMonitoring { + namespace?: string; + use_output?: string; + enabled: boolean; + metrics: boolean; + logs: boolean; +} + export interface FullAgentPolicy { id: string; outputs: { @@ -103,13 +112,7 @@ export interface FullAgentPolicy { inputs: FullAgentPolicyInput[]; revision?: number; agent?: { - monitoring: { - namespace?: string; - use_output?: string; - enabled: boolean; - metrics: boolean; - logs: boolean; - }; + monitoring: FullAgentPolicyMonitoring; download: { sourceURI: string }; features: Record; protection?: { diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index 9bf37677ae905..8791d9871982b 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -147,6 +147,7 @@ const getSavedObjectTypes = (): { [key: string]: SavedObjectsType } => ({ }, is_protected: { type: 'boolean' }, overrides: { type: 'flattened', index: false }, + keep_monitoring_alive: { type: 'boolean' }, }, }, migrations: { diff --git a/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.test.ts b/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.test.ts index 050b5f983c794..d9bf271210bc9 100644 --- a/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.test.ts @@ -283,6 +283,20 @@ describe('getFullAgentPolicy', () => { }); }); + it('should return a policy with monitoring enabled but no logs/metrics if keep_monitoring_alive is true', async () => { + mockAgentPolicy({ + keep_monitoring_alive: true, + }); + + const agentPolicy = await getFullAgentPolicy(savedObjectsClientMock.create(), 'agent-policy'); + + expect(agentPolicy?.agent?.monitoring).toEqual({ + enabled: true, + logs: false, + metrics: false, + }); + }); + it('should get the permissions for monitoring', async () => { mockAgentPolicy({ namespace: 'testnamespace', diff --git a/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts index 2cdd04483e108..d15e7adb9bd7f 100644 --- a/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts @@ -18,7 +18,11 @@ import type { FleetProxy, FleetServerHost, } from '../../types'; -import type { FullAgentPolicyOutputPermissions, PackageInfo } from '../../../common/types'; +import type { + FullAgentPolicyMonitoring, + FullAgentPolicyOutputPermissions, + PackageInfo, +} from '../../../common/types'; import { agentPolicyService } from '../agent_policy'; import { dataTypes, kafkaCompressionType, outputType } from '../../../common/constants'; import { DEFAULT_OUTPUT } from '../../constants'; @@ -105,6 +109,35 @@ export async function getFullAgentPolicy( acc[name] = featureConfig; return acc; }, {} as NonNullable['features']); + + const defaultMonitoringConfig: FullAgentPolicyMonitoring = { + enabled: false, + logs: false, + metrics: false, + }; + + let monitoring: FullAgentPolicyMonitoring = { ...defaultMonitoringConfig }; + + // If the agent policy has monitoring enabled for at least one of "logs" or "metrics", generate + // a monitoring config for the resulting compiled agent policy + if (agentPolicy.monitoring_enabled && agentPolicy.monitoring_enabled.length > 0) { + monitoring = { + namespace: agentPolicy.namespace, + use_output: getOutputIdForAgentPolicy(monitoringOutput), + enabled: true, + logs: agentPolicy.monitoring_enabled.includes(dataTypes.Logs), + metrics: agentPolicy.monitoring_enabled.includes(dataTypes.Metrics), + }; + // If the `keep_monitoring_alive` flag is set, enable monitoring but don't enable logs or metrics. + // This allows cloud or other environments to keep the monitoring server alive without tearing it down. + } else if (agentPolicy.keep_monitoring_alive) { + monitoring = { + enabled: true, + logs: false, + metrics: false, + }; + } + const fullAgentPolicy: FullAgentPolicy = { id: agentPolicy.id, outputs: { @@ -128,16 +161,7 @@ export async function getFullAgentPolicy( sourceURI: downloadSourceUri, ...(downloadSourceProxyUri ? { proxy_url: downloadSourceProxyUri } : {}), }, - monitoring: - agentPolicy.monitoring_enabled && agentPolicy.monitoring_enabled.length > 0 - ? { - namespace: agentPolicy.namespace, - use_output: getOutputIdForAgentPolicy(monitoringOutput), - enabled: true, - logs: agentPolicy.monitoring_enabled.includes(dataTypes.Logs), - metrics: agentPolicy.monitoring_enabled.includes(dataTypes.Metrics), - } - : { enabled: false, logs: false, metrics: false }, + monitoring, features, protection: { enabled: agentPolicy.is_protected, diff --git a/x-pack/plugins/fleet/server/types/models/agent_policy.ts b/x-pack/plugins/fleet/server/types/models/agent_policy.ts index 0fb27475c0779..9b7e0d779cd9c 100644 --- a/x-pack/plugins/fleet/server/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/server/types/models/agent_policy.ts @@ -35,6 +35,7 @@ export const AgentPolicyBaseSchema = { schema.oneOf([schema.literal(dataTypes.Logs), schema.literal(dataTypes.Metrics)]) ) ), + keep_monitoring_alive: schema.maybe(schema.boolean({ defaultValue: false })), data_output_id: schema.maybe(schema.nullable(schema.string())), monitoring_output_id: schema.maybe(schema.nullable(schema.string())), download_source_id: schema.maybe(schema.nullable(schema.string())),