@@ -14,15 +14,15 @@ export interface AgentOSMetadataTelemetry {
1414 version : string ;
1515 count : number ;
1616}
17-
18- export type PolicyTypes = 'malware' ;
1917export interface PolicyTelemetry {
20- success : number ;
21- warning : number ;
18+ active : number ;
19+ inactive : number ;
2220 failure : number ;
2321}
2422
25- export type PoliciesTelemetry = Record < PolicyTypes , PolicyTelemetry > ;
23+ export interface PoliciesTelemetry {
24+ malware : PolicyTelemetry ;
25+ }
2626
2727export interface EndpointUsage {
2828 total_installed : number ;
@@ -31,6 +31,8 @@ export interface EndpointUsage {
3131 policies : PoliciesTelemetry ;
3232}
3333
34+ type EndpointOSNames = 'Linux' | 'Windows' | 'macOs' ;
35+
3436export interface AgentLocalMetadata extends AgentMetadata {
3537 elastic : {
3638 agent : {
@@ -48,8 +50,8 @@ export interface AgentLocalMetadata extends AgentMetadata {
4850 } ;
4951}
5052
51- export type OSTracker = Record < string , AgentOSMetadataTelemetry > ;
52-
53+ type OSTracker = Record < string , AgentOSMetadataTelemetry > ;
54+ type AgentDailyActiveTracker = Map < string , boolean > ;
5355/**
5456 * @description returns an empty telemetry object to be incrmented and updated within the `getEndpointTelemetryFromFleet` fn
5557 */
@@ -59,13 +61,16 @@ export const getDefaultEndpointTelemetry = (): EndpointUsage => ({
5961 os : [ ] ,
6062 policies : {
6163 malware : {
62- success : 0 ,
63- warning : 0 ,
64+ active : 0 ,
65+ inactive : 0 ,
6466 failure : 0 ,
6567 } ,
6668 } ,
6769} ) ;
6870
71+ /**
72+ * @description this fun
73+ */
6974export const trackEndpointOSTelemetry = (
7075 os : AgentLocalMetadata [ 'os' ] ,
7176 osTracker : OSTracker
@@ -87,6 +92,80 @@ export const trackEndpointOSTelemetry = (
8792 return updatedOSTracker ;
8893} ;
8994
95+ /**
96+ * @description This iterates over all unique agents that currently track an endpoint package. It takes a list of agents who have checked in in the last 24 hours
97+ * and then checks whether those agents have endpoints whose latest status is 'RUNNING' to determine an active_within_last_24_hours. Since the policy information is also tracked in these events
98+ * we pull out the status of the current protection (malware) type. This must be done in a compound manner as the desired status is reflected in the config, and the successful application of that policy
99+ * is tracked in the policy.applied.response.configurations[protectionsType].status. Using these two we can determine whether the policy is toggled on, off, or failed to turn on.
100+ */
101+ export const addEndpointDailyActivityAndPolicyDetailsToTelemetry = async (
102+ agentDailyActiveTracker : AgentDailyActiveTracker ,
103+ savedObjectsClient : ISavedObjectsRepository ,
104+ endpointTelemetry : EndpointUsage
105+ ) : Promise < EndpointUsage > => {
106+ const updatedEndpointTelemetry = { ...endpointTelemetry } ;
107+
108+ const policyHostTypeToPolicyType = {
109+ Linux : 'linux' ,
110+ macOs : 'mac' ,
111+ Windows : 'windows' ,
112+ } ;
113+ const enabledMalwarePolicyTypes = [ 'prevent' , 'detect' ] ;
114+
115+ for ( const agentId of agentDailyActiveTracker . keys ( ) ) {
116+ const { saved_objects : agentEvents } = await getLatestFleetEndpointEvent (
117+ savedObjectsClient ,
118+ agentId
119+ ) ;
120+
121+ const latestEndpointEvent = agentEvents [ 0 ] ;
122+ if ( latestEndpointEvent ) {
123+ /*
124+ We can assume that if the last status of the endpoint is RUNNING and the agent has checked in within the last 24 hours
125+ then the endpoint has still been running within the last 24 hours.
126+ */
127+ const { subtype, payload } = latestEndpointEvent . attributes ;
128+ const endpointIsActive =
129+ subtype === 'RUNNING' && agentDailyActiveTracker . get ( agentId ) === true ;
130+
131+ if ( endpointIsActive ) {
132+ updatedEndpointTelemetry . active_within_last_24_hours += 1 ;
133+ }
134+
135+ // The policy details are sent as a string on the 'payload' attribute of the agent event
136+ const endpointPolicyDetails = payload ? JSON . parse ( payload ) : null ;
137+ if ( endpointPolicyDetails ) {
138+ // We get the setting the user desired to enable (treating prevent and detect as 'active' states) and then see if it succeded or failed.
139+ const hostType =
140+ policyHostTypeToPolicyType [
141+ endpointPolicyDetails [ 'endpoint-security' ] ?. host ?. os ?. name as EndpointOSNames
142+ ] ;
143+ const userDesiredMalwareState =
144+ endpointPolicyDetails [ 'endpoint-security' ] . Endpoint ?. configuration ?. inputs [ 0 ] ?. policy [
145+ hostType
146+ ] ?. malware ?. mode ;
147+
148+ const isAnActiveMalwareState = enabledMalwarePolicyTypes . includes ( userDesiredMalwareState ) ;
149+ const malwareStatus =
150+ endpointPolicyDetails [ 'endpoint-security' ] . Endpoint ?. policy ?. applied ?. response
151+ ?. configurations ?. malware ?. status ;
152+
153+ if ( isAnActiveMalwareState && malwareStatus !== 'failure' ) {
154+ updatedEndpointTelemetry . policies . malware . active += 1 ;
155+ }
156+ if ( ! isAnActiveMalwareState ) {
157+ updatedEndpointTelemetry . policies . malware . inactive += 1 ;
158+ }
159+ if ( isAnActiveMalwareState && malwareStatus === 'failure' ) {
160+ updatedEndpointTelemetry . policies . malware . failure += 1 ;
161+ }
162+ }
163+ }
164+ }
165+
166+ return updatedEndpointTelemetry ;
167+ } ;
168+
90169/**
91170 * @description This aggregates the telemetry details from the two fleet savedObject sources, `fleet-agents` and `fleet-agent-events` to populate
92171 * the telemetry details for endpoint. Since we cannot access our own indices due to `kibana_system` not having access, this is the best alternative.
@@ -106,7 +185,7 @@ export const getEndpointTelemetryFromFleet = async (
106185 // Use unique hosts to prevent any potential duplicates
107186 const uniqueHostIds : Set < string > = new Set ( ) ;
108187 // Need agents to get events data for those that have run in last 24 hours as well as policy details
109- const agentDailyActiveTracker : Map < string , boolean > = new Map ( ) ;
188+ const agentDailyActiveTracker : AgentDailyActiveTracker = new Map ( ) ;
110189
111190 const aDayAgo = new Date ( ) ;
112191 aDayAgo . setDate ( aDayAgo . getDate ( ) - 1 ) ;
@@ -131,48 +210,16 @@ export const getEndpointTelemetryFromFleet = async (
131210 endpointTelemetry
132211 ) ;
133212
134- // All unique agents with an endpoint installed. You can technically install a new agent on a host, so relying on most recently installed.
213+ // All unique hosts with an endpoint installed.
135214 endpointTelemetry . total_installed = uniqueHostIds . size ;
136215 // Get the objects to populate our OS Telemetry
137216 endpointMetadataTelemetry . os = Object . values ( osTracker ) ;
217+ // Populate endpoint telemetry with the finalized 24 hour count and policy details
218+ const finalizedEndpointTelemetryData = await addEndpointDailyActivityAndPolicyDetailsToTelemetry (
219+ agentDailyActiveTracker ,
220+ savedObjectsClient ,
221+ endpointMetadataTelemetry
222+ ) ;
138223
139- for ( const agentId of agentDailyActiveTracker . keys ( ) ) {
140- const { saved_objects : agentEvents } = await getLatestFleetEndpointEvent (
141- savedObjectsClient ,
142- agentId
143- ) ;
144-
145- const latestEndpointEvent = agentEvents [ 0 ] ;
146- if ( latestEndpointEvent ) {
147- /*
148- We can assume that if the last status of the endpoint is RUNNING and the agent has checked in within the last 24 hours
149- then the endpoint has still been running within the last 24 hours.
150- */
151- const { subtype, payload } = latestEndpointEvent . attributes ;
152- const endpointIsActive =
153- subtype === 'RUNNING' && agentDailyActiveTracker . get ( agentId ) === true ;
154-
155- if ( endpointIsActive ) {
156- endpointMetadataTelemetry . active_within_last_24_hours += 1 ;
157- }
158- const endpointPolicyDetails = payload ? JSON . parse ( payload ) : null ;
159- if ( endpointPolicyDetails ) {
160- const malwareStatus =
161- endpointPolicyDetails [ 'endpoint-security' ] . Endpoint ?. policy ?. applied ?. response
162- ?. configurations ?. malware ?. status ;
163-
164- if ( malwareStatus === 'success' ) {
165- endpointMetadataTelemetry . policies . malware . success += 1 ;
166- }
167- if ( malwareStatus === 'warning' ) {
168- endpointMetadataTelemetry . policies . malware . warning += 1 ;
169- }
170- if ( malwareStatus === 'failure' ) {
171- endpointMetadataTelemetry . policies . malware . failure += 1 ;
172- }
173- }
174- }
175- }
176-
177- return endpointMetadataTelemetry ;
224+ return finalizedEndpointTelemetryData ;
178225} ;
0 commit comments