44 * you may not use this file except in compliance with the Elastic License.
55 */
66
7- import { IRouter , RequestHandlerContext } from 'kibana/server' ;
7+ import { IRouter , Logger , RequestHandlerContext } from 'kibana/server' ;
88import { SearchResponse } from 'elasticsearch' ;
99import { schema } from '@kbn/config-schema' ;
1010
11- import { kibanaRequestToMetadataListESQuery , getESQueryHostMetadataByID } from './query_builders' ;
11+ import { getESQueryHostMetadataByID , kibanaRequestToMetadataListESQuery } from './query_builders' ;
1212import { HostInfo , HostMetadata , HostResultList , HostStatus } from '../../../common/types' ;
1313import { EndpointAppContext } from '../../types' ;
14+ import { AgentStatus } from '../../../../ingest_manager/common/types/models' ;
1415
1516interface HitSource {
1617 _source : HostMetadata ;
1718}
1819
20+ interface MetadataRequestContext {
21+ requestHandlerContext : RequestHandlerContext ;
22+ endpointAppContext : EndpointAppContext ;
23+ }
24+
25+ const HOST_STATUS_MAPPING = new Map < AgentStatus , HostStatus > ( [
26+ [ 'online' , HostStatus . ONLINE ] ,
27+ [ 'offline' , HostStatus . OFFLINE ] ,
28+ ] ) ;
29+
1930export function registerEndpointRoutes ( router : IRouter , endpointAppContext : EndpointAppContext ) {
2031 router . post (
2132 {
@@ -62,7 +73,12 @@ export function registerEndpointRoutes(router: IRouter, endpointAppContext: Endp
6273 'search' ,
6374 queryParams
6475 ) ) as SearchResponse < HostMetadata > ;
65- return res . ok ( { body : mapToHostResultList ( queryParams , response ) } ) ;
76+ return res . ok ( {
77+ body : await mapToHostResultList ( queryParams , response , {
78+ endpointAppContext,
79+ requestHandlerContext : context ,
80+ } ) ,
81+ } ) ;
6682 } catch ( err ) {
6783 return res . internalError ( { body : err } ) ;
6884 }
@@ -79,11 +95,13 @@ export function registerEndpointRoutes(router: IRouter, endpointAppContext: Endp
7995 } ,
8096 async ( context , req , res ) => {
8197 try {
82- const index = await endpointAppContext . indexPatternRetriever . getMetadataIndexPattern (
83- context
98+ const doc = await getHostData (
99+ {
100+ endpointAppContext,
101+ requestHandlerContext : context ,
102+ } ,
103+ req . params . id
84104 ) ;
85-
86- const doc = await getHostData ( context , req . params . id , index ) ;
87105 if ( doc ) {
88106 return res . ok ( { body : doc } ) ;
89107 }
@@ -96,12 +114,14 @@ export function registerEndpointRoutes(router: IRouter, endpointAppContext: Endp
96114}
97115
98116export async function getHostData (
99- context : RequestHandlerContext ,
100- id : string ,
101- index : string
117+ metadataRequestContext : MetadataRequestContext ,
118+ id : string
102119) : Promise < HostInfo | undefined > {
120+ const index = await metadataRequestContext . endpointAppContext . indexPatternRetriever . getMetadataIndexPattern (
121+ metadataRequestContext . requestHandlerContext
122+ ) ;
103123 const query = getESQueryHostMetadataByID ( id , index ) ;
104- const response = ( await context . core . elasticsearch . dataClient . callAsCurrentUser (
124+ const response = ( await metadataRequestContext . requestHandlerContext . core . elasticsearch . dataClient . callAsCurrentUser (
105125 'search' ,
106126 query
107127 ) ) as SearchResponse < HostMetadata > ;
@@ -110,22 +130,25 @@ export async function getHostData(
110130 return undefined ;
111131 }
112132
113- return enrichHostMetadata ( response . hits . hits [ 0 ] . _source ) ;
133+ return await enrichHostMetadata ( response . hits . hits [ 0 ] . _source , metadataRequestContext ) ;
114134}
115135
116- function mapToHostResultList (
136+ async function mapToHostResultList (
117137 queryParams : Record < string , any > ,
118- searchResponse : SearchResponse < HostMetadata >
119- ) : HostResultList {
138+ searchResponse : SearchResponse < HostMetadata > ,
139+ metadataRequestContext : MetadataRequestContext
140+ ) : Promise < HostResultList > {
120141 const totalNumberOfHosts = searchResponse ?. aggregations ?. total ?. value || 0 ;
121142 if ( searchResponse . hits . hits . length > 0 ) {
122143 return {
123144 request_page_size : queryParams . size ,
124145 request_page_index : queryParams . from ,
125- hosts : searchResponse . hits . hits
126- . map ( response => response . inner_hits . most_recent . hits . hits )
127- . flatMap ( data => data as HitSource )
128- . map ( entry => enrichHostMetadata ( entry . _source ) ) ,
146+ hosts : await Promise . all (
147+ searchResponse . hits . hits
148+ . map ( response => response . inner_hits . most_recent . hits . hits )
149+ . flatMap ( data => data as HitSource )
150+ . map ( async entry => enrichHostMetadata ( entry . _source , metadataRequestContext ) )
151+ ) ,
129152 total : totalNumberOfHosts ,
130153 } ;
131154 } else {
@@ -138,9 +161,43 @@ function mapToHostResultList(
138161 }
139162}
140163
141- function enrichHostMetadata ( hostMetadata : HostMetadata ) : HostInfo {
164+ async function enrichHostMetadata (
165+ hostMetadata : HostMetadata ,
166+ metadataRequestContext : MetadataRequestContext
167+ ) : Promise < HostInfo > {
168+ let hostStatus = HostStatus . ERROR ;
169+ let elasticAgentId = hostMetadata ?. elastic ?. agent ?. id ;
170+ const log = logger ( metadataRequestContext . endpointAppContext ) ;
171+ try {
172+ /**
173+ * Get agent status by elastic agent id if available or use the host id.
174+ * https://github.com/elastic/endpoint-app-team/issues/354
175+ */
176+
177+ if ( ! elasticAgentId ) {
178+ elasticAgentId = hostMetadata . host . id ;
179+ log . warn ( `Missing elastic agent id, using host id instead ${ elasticAgentId } ` ) ;
180+ }
181+
182+ const status = await metadataRequestContext . endpointAppContext . agentService . getAgentStatusById (
183+ metadataRequestContext . requestHandlerContext . core . savedObjects . client ,
184+ elasticAgentId
185+ ) ;
186+ hostStatus = HOST_STATUS_MAPPING . get ( status ) || HostStatus . ERROR ;
187+ } catch ( e ) {
188+ if ( e . isBoom && e . output . statusCode === 404 ) {
189+ log . warn ( `agent with id ${ elasticAgentId } not found` ) ;
190+ } else {
191+ log . error ( e ) ;
192+ throw e ;
193+ }
194+ }
142195 return {
143196 metadata : hostMetadata ,
144- host_status : HostStatus . ERROR ,
197+ host_status : hostStatus ,
145198 } ;
146199}
200+
201+ const logger = ( endpointAppContext : EndpointAppContext ) : Logger => {
202+ return endpointAppContext . logFactory . get ( 'metadata' ) ;
203+ } ;
0 commit comments