diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts index 77c78c4dba28d..0d2fca197e74d 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts @@ -14,13 +14,15 @@ import { LIST_TRUSTED_APPLICATION, } from './constants'; import { + extractEndpointPolicyConfig, getPreviousDiagTaskTimestamp, getPreviousDailyTaskTimestamp, batchTelemetryRecords, isPackagePolicyList, templateExceptionList, } from './helpers'; -import { ExceptionListItem } from './types'; +import type { ExceptionListItem } from './types'; +import { PolicyData } from '../../../common/endpoint/types'; describe('test diagnostic telemetry scheduled task timing helper', () => { test('test -5 mins is returned when there is no previous task run', async () => { @@ -220,3 +222,39 @@ describe('list telemetry schema', () => { expect(templatedItems[0]?.trusted_application).toBeUndefined(); }); }); + +describe('test endpoint policy data config extraction', () => { + const stubPolicyData = { + id: '872de8c5-85cf-4e1b-a504-9fd39b38570c', + version: 'WzU4MjkwLDFd', + name: 'Test Policy Data', + namespace: 'default', + description: '', + package: { + name: 'endpoint', + title: 'Endpoint Security', + version: '1.4.1', + }, + enabled: true, + policy_id: '499b5aa7-d214-5b5d-838b-3cd76469844e', + output_id: '', + inputs: [ + { + type: 'endpoint', + enabled: true, + streams: [], + config: null, + }, + ], + revision: 1, + created_at: '2022-01-18T14:52:17.385Z', + created_by: 'elastic', + updated_at: '2022-01-18T14:52:17.385Z', + updated_by: 'elastic', + } as unknown as PolicyData; + + test('can succeed when policy config is null or empty', async () => { + const endpointPolicyConfig = extractEndpointPolicyConfig(stubPolicyData); + expect(endpointPolicyConfig).toBeNull(); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts index 37f6debd50257..3abd17b47b73b 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts @@ -9,14 +9,14 @@ import moment from 'moment'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { PackagePolicy } from '../../../../fleet/common/types/models/package_policy'; import { copyAllowlistedFields, exceptionListEventFields } from './filters'; -import { ExceptionListItem, ListTemplate, TelemetryEvent } from './types'; +import type { ExceptionListItem, ListTemplate, TelemetryEvent } from './types'; import { LIST_DETECTION_RULE_EXCEPTION, LIST_ENDPOINT_EXCEPTION, LIST_ENDPOINT_EVENT_FILTER, LIST_TRUSTED_APPLICATION, } from './constants'; -import { TrustedApp } from '../../../common/endpoint/types'; +import { TrustedApp, PolicyData } from '../../../common/endpoint/types'; /** * Determines the when the last run was in order to execute to. @@ -200,6 +200,14 @@ export const templateExceptionList = (listData: ExceptionListItem[], listType: s * @param label_list the list of labels to create standardized UsageCounter from * @returns a string label for usage in the UsageCounter */ -export function createUsageCounterLabel(labelList: string[]): string { - return labelList.join('-'); -} +export const createUsageCounterLabel = (labelList: string[]): string => labelList.join('-'); + +/** + * Resiliantly handles an edge case where the endpoint config details are not present + * + * @returns the endpoint policy configuration + */ +export const extractEndpointPolicyConfig = (policyData: PolicyData | null) => { + const epPolicyConfig = policyData?.inputs[0]?.config?.policy; + return epPolicyConfig ? epPolicyConfig : null; +}; diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts index a06aac19d313b..fd57082cb0a38 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts @@ -16,6 +16,7 @@ import { TelemetryReceiver } from '../receiver'; import { TaskExecutionPeriod } from '../task'; import { batchTelemetryRecords, + extractEndpointPolicyConfig, getPreviousDailyTaskTimestamp, isPackagePolicyList, } from '../helpers'; @@ -129,11 +130,11 @@ export function createTelemetryEndpointTaskConfig(maxTelemetryBatch: number) { packagePolicies .map((pPolicy) => pPolicy as PolicyData) .forEach((pPolicy) => { - if (pPolicy.inputs[0].config !== undefined) { + if (pPolicy.inputs[0]?.config !== undefined && pPolicy.inputs[0]?.config !== null) { pPolicy.inputs.forEach((input) => { if ( input.type === FLEET_ENDPOINT_PACKAGE && - input.config !== undefined && + input?.config !== undefined && policyInfo !== undefined ) { endpointPolicyCache.set(policyInfo, pPolicy); @@ -196,6 +197,7 @@ export function createTelemetryEndpointTaskConfig(maxTelemetryBatch: number) { } const { cpu, memory, uptime } = endpoint.endpoint_metrics.Endpoint.metrics; + const endpointPolicyDetail = extractEndpointPolicyConfig(policyConfig); return { '@timestamp': taskExecutionPeriod.current, @@ -210,7 +212,7 @@ export function createTelemetryEndpointTaskConfig(maxTelemetryBatch: number) { endpoint_meta: { os: endpoint.endpoint_metrics.host.os, }, - policy_config: policyConfig !== null ? policyConfig?.inputs[0].config.policy : {}, + policy_config: endpointPolicyDetail !== null ? endpointPolicyDetail : {}, policy_response: failedPolicy !== null && failedPolicy !== undefined ? {