Skip to content

Commit c3d784c

Browse files
[SECURITY SOLUTION] EMT-401: add policy data to metadata and fix tests (#68582)
[SECURITY SOLUTION] EMT-401: add policy data to metadata and fix tests
1 parent fef7ff8 commit c3d784c

File tree

9 files changed

+174
-279
lines changed

9 files changed

+174
-279
lines changed

x-pack/plugins/security_solution/common/endpoint/generate_data.ts

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,20 @@ const Mac: HostOS[] = [];
6161

6262
const OS: HostOS[] = [...Windows, ...Mac, ...Linux];
6363

64-
const POLICIES: Array<{ name: string; id: string }> = [
64+
const APPLIED_POLICIES: Array<{
65+
name: string;
66+
id: string;
67+
status: HostPolicyResponseActionStatus;
68+
}> = [
6569
{
6670
name: 'Default',
6771
id: '00000000-0000-0000-0000-000000000000',
72+
status: HostPolicyResponseActionStatus.success,
6873
},
6974
{
7075
name: 'With Eventing',
7176
id: 'C2A9093E-E289-4C0A-AA44-8C32A414FA7A',
77+
status: HostPolicyResponseActionStatus.success,
7278
},
7379
];
7480

@@ -181,7 +187,11 @@ interface HostInfo {
181187
host: Host;
182188
endpoint: {
183189
policy: {
184-
id: string;
190+
applied: {
191+
id: string;
192+
status: HostPolicyResponseActionStatus;
193+
name: string;
194+
};
185195
};
186196
};
187197
}
@@ -271,7 +281,12 @@ export class EndpointDocGenerator {
271281
* Creates new random policy id for the host to simulate new policy application
272282
*/
273283
public updatePolicyId() {
274-
this.commonInfo.endpoint.policy.id = this.randomChoice(POLICIES).id;
284+
this.commonInfo.endpoint.policy.applied.id = this.randomChoice(APPLIED_POLICIES).id;
285+
this.commonInfo.endpoint.policy.applied.status = this.randomChoice([
286+
HostPolicyResponseActionStatus.success,
287+
HostPolicyResponseActionStatus.failure,
288+
HostPolicyResponseActionStatus.warning,
289+
]);
275290
}
276291

277292
private createHostData(): HostInfo {
@@ -293,7 +308,9 @@ export class EndpointDocGenerator {
293308
os: this.randomChoice(OS),
294309
},
295310
endpoint: {
296-
policy: this.randomChoice(POLICIES),
311+
policy: {
312+
applied: this.randomChoice(APPLIED_POLICIES),
313+
},
297314
},
298315
};
299316
}
@@ -974,7 +991,7 @@ export class EndpointDocGenerator {
974991
status: HostPolicyResponseActionStatus.success,
975992
},
976993
],
977-
id: this.commonInfo.endpoint.policy.id,
994+
id: this.commonInfo.endpoint.policy.applied.id,
978995
response: {
979996
configurations: {
980997
events: {
@@ -1015,8 +1032,9 @@ export class EndpointDocGenerator {
10151032
],
10161033
},
10171034
},
1018-
status: this.randomHostPolicyResponseActionStatus(),
1035+
status: this.commonInfo.endpoint.policy.applied.status,
10191036
version: policyVersion,
1037+
name: this.commonInfo.endpoint.policy.applied.name,
10201038
},
10211039
},
10221040
},

x-pack/plugins/security_solution/common/endpoint/types.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,11 @@ export type AlertEvent = Immutable<{
253253
};
254254
endpoint: {
255255
policy: {
256-
id: string;
256+
applied: {
257+
id: string;
258+
status: HostPolicyResponseActionStatus;
259+
name: string;
260+
};
257261
};
258262
};
259263
process: {
@@ -357,7 +361,11 @@ export type HostMetadata = Immutable<{
357361
};
358362
endpoint: {
359363
policy: {
360-
id: string;
364+
applied: {
365+
id: string;
366+
status: HostPolicyResponseActionStatus;
367+
name: string;
368+
};
361369
};
362370
};
363371
agent: {
@@ -700,6 +708,7 @@ export interface HostPolicyResponse {
700708
applied: {
701709
version: string;
702710
id: string;
711+
name: string;
703712
status: HostPolicyResponseActionStatus;
704713
actions: HostPolicyResponseAppliedAction[];
705714
response: {

x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/host_details.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
8686
title: i18n.translate('xpack.securitySolution.endpoint.host.details.policy', {
8787
defaultMessage: 'Policy',
8888
}),
89-
description: details.endpoint.policy.id,
89+
description: details.endpoint.policy.applied.id,
9090
},
9191
{
9292
title: i18n.translate('xpack.securitySolution.endpoint.host.details.policyStatus', {
@@ -138,10 +138,10 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
138138
},
139139
];
140140
}, [
141-
details.endpoint.policy.id,
142-
details.host.ip,
143-
details.host.hostname,
144141
details.agent.version,
142+
details.endpoint.policy.applied.id,
143+
details.host.hostname,
144+
details.host.ip,
145145
policyStatus,
146146
policyResponseUri,
147147
policyStatusClickHandler,

x-pack/plugins/security_solution/server/endpoint/routes/metadata/metadata.test.ts

Lines changed: 72 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
} from '../../../../common/endpoint/types';
2828
import { SearchResponse } from 'elasticsearch';
2929
import { registerEndpointRoutes } from './index';
30-
import * as data from '../../test_data/all_metadata_data.json';
3130
import {
3231
createMockAgentService,
3332
createMockMetadataIndexPatternRetriever,
@@ -37,6 +36,7 @@ import { AgentService } from '../../../../../ingest_manager/server';
3736
import Boom from 'boom';
3837
import { EndpointAppContextService } from '../../endpoint_app_context_services';
3938
import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__';
39+
import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data';
4040

4141
describe('test endpoint route', () => {
4242
let routerMock: jest.Mocked<IRouter>;
@@ -78,10 +78,7 @@ describe('test endpoint route', () => {
7878

7979
it('test find the latest of all endpoints', async () => {
8080
const mockRequest = httpServerMock.createKibanaRequest({});
81-
82-
const response: SearchResponse<HostMetadata> = (data as unknown) as SearchResponse<
83-
HostMetadata
84-
>;
81+
const response = createSearchResponse(new EndpointDocGenerator().generateHostMetadata());
8582
mockScopedClient.callAsCurrentUser.mockImplementationOnce(() => Promise.resolve(response));
8683
[routeConfig, routeHandler] = routerMock.post.mock.calls.find(([{ path }]) =>
8784
path.startsWith('/api/endpoint/metadata')
@@ -97,8 +94,8 @@ describe('test endpoint route', () => {
9794
expect(routeConfig.options).toEqual({ authRequired: true });
9895
expect(mockResponse.ok).toBeCalled();
9996
const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as HostResultList;
100-
expect(endpointResultList.hosts.length).toEqual(2);
101-
expect(endpointResultList.total).toEqual(2);
97+
expect(endpointResultList.hosts.length).toEqual(1);
98+
expect(endpointResultList.total).toEqual(1);
10299
expect(endpointResultList.request_page_index).toEqual(0);
103100
expect(endpointResultList.request_page_size).toEqual(10);
104101
});
@@ -119,7 +116,7 @@ describe('test endpoint route', () => {
119116

120117
mockAgentService.getAgentStatusById = jest.fn().mockReturnValue('error');
121118
mockScopedClient.callAsCurrentUser.mockImplementationOnce(() =>
122-
Promise.resolve((data as unknown) as SearchResponse<HostMetadata>)
119+
Promise.resolve(createSearchResponse(new EndpointDocGenerator().generateHostMetadata()))
123120
);
124121
[routeConfig, routeHandler] = routerMock.post.mock.calls.find(([{ path }]) =>
125122
path.startsWith('/api/endpoint/metadata')
@@ -138,8 +135,8 @@ describe('test endpoint route', () => {
138135
expect(routeConfig.options).toEqual({ authRequired: true });
139136
expect(mockResponse.ok).toBeCalled();
140137
const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as HostResultList;
141-
expect(endpointResultList.hosts.length).toEqual(2);
142-
expect(endpointResultList.total).toEqual(2);
138+
expect(endpointResultList.hosts.length).toEqual(1);
139+
expect(endpointResultList.total).toEqual(1);
143140
expect(endpointResultList.request_page_index).toEqual(10);
144141
expect(endpointResultList.request_page_size).toEqual(10);
145142
});
@@ -162,7 +159,7 @@ describe('test endpoint route', () => {
162159

163160
mockAgentService.getAgentStatusById = jest.fn().mockReturnValue('error');
164161
mockScopedClient.callAsCurrentUser.mockImplementationOnce(() =>
165-
Promise.resolve((data as unknown) as SearchResponse<HostMetadata>)
162+
Promise.resolve(createSearchResponse(new EndpointDocGenerator().generateHostMetadata()))
166163
);
167164
[routeConfig, routeHandler] = routerMock.post.mock.calls.find(([{ path }]) =>
168165
path.startsWith('/api/endpoint/metadata')
@@ -194,34 +191,18 @@ describe('test endpoint route', () => {
194191
expect(routeConfig.options).toEqual({ authRequired: true });
195192
expect(mockResponse.ok).toBeCalled();
196193
const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as HostResultList;
197-
expect(endpointResultList.hosts.length).toEqual(2);
198-
expect(endpointResultList.total).toEqual(2);
194+
expect(endpointResultList.hosts.length).toEqual(1);
195+
expect(endpointResultList.total).toEqual(1);
199196
expect(endpointResultList.request_page_index).toEqual(10);
200197
expect(endpointResultList.request_page_size).toEqual(10);
201198
});
202199

203200
describe('Endpoint Details route', () => {
204201
it('should return 404 on no results', async () => {
205202
const mockRequest = httpServerMock.createKibanaRequest({ params: { id: 'BADID' } });
203+
206204
mockScopedClient.callAsCurrentUser.mockImplementationOnce(() =>
207-
Promise.resolve({
208-
took: 3,
209-
timed_out: false,
210-
_shards: {
211-
total: 1,
212-
successful: 1,
213-
skipped: 0,
214-
failed: 0,
215-
},
216-
hits: {
217-
total: {
218-
value: 9,
219-
relation: 'eq',
220-
},
221-
max_score: null,
222-
hits: [],
223-
},
224-
})
205+
Promise.resolve(createSearchResponse())
225206
);
226207
mockAgentService.getAgentStatusById = jest.fn().mockReturnValue('error');
227208
[routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) =>
@@ -241,13 +222,10 @@ describe('test endpoint route', () => {
241222
});
242223

243224
it('should return a single endpoint with status online', async () => {
225+
const response = createSearchResponse(new EndpointDocGenerator().generateHostMetadata());
244226
const mockRequest = httpServerMock.createKibanaRequest({
245-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
246-
params: { id: (data as any).hits.hits[0]._id },
227+
params: { id: response.hits.hits[0]._id },
247228
});
248-
const response: SearchResponse<HostMetadata> = (data as unknown) as SearchResponse<
249-
HostMetadata
250-
>;
251229
mockAgentService.getAgentStatusById = jest.fn().mockReturnValue('online');
252230
mockScopedClient.callAsCurrentUser.mockImplementationOnce(() => Promise.resolve(response));
253231
[routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) =>
@@ -269,9 +247,7 @@ describe('test endpoint route', () => {
269247
});
270248

271249
it('should return a single endpoint with status error when AgentService throw 404', async () => {
272-
const response: SearchResponse<HostMetadata> = (data as unknown) as SearchResponse<
273-
HostMetadata
274-
>;
250+
const response = createSearchResponse(new EndpointDocGenerator().generateHostMetadata());
275251

276252
const mockRequest = httpServerMock.createKibanaRequest({
277253
params: { id: response.hits.hits[0]._id },
@@ -299,9 +275,7 @@ describe('test endpoint route', () => {
299275
});
300276

301277
it('should return a single endpoint with status error when status is not offline or online', async () => {
302-
const response: SearchResponse<HostMetadata> = (data as unknown) as SearchResponse<
303-
HostMetadata
304-
>;
278+
const response = createSearchResponse(new EndpointDocGenerator().generateHostMetadata());
305279

306280
const mockRequest = httpServerMock.createKibanaRequest({
307281
params: { id: response.hits.hits[0]._id },
@@ -327,3 +301,59 @@ describe('test endpoint route', () => {
327301
});
328302
});
329303
});
304+
305+
function createSearchResponse(hostMetadata?: HostMetadata): SearchResponse<HostMetadata> {
306+
return ({
307+
took: 15,
308+
timed_out: false,
309+
_shards: {
310+
total: 1,
311+
successful: 1,
312+
skipped: 0,
313+
failed: 0,
314+
},
315+
hits: {
316+
total: {
317+
value: 5,
318+
relation: 'eq',
319+
},
320+
max_score: null,
321+
hits: hostMetadata
322+
? [
323+
{
324+
_index: 'metrics-endpoint.metadata-default-1',
325+
_id: '8FhM0HEBYyRTvb6lOQnw',
326+
_score: null,
327+
_source: hostMetadata,
328+
sort: [1588337587997],
329+
inner_hits: {
330+
most_recent: {
331+
hits: {
332+
total: {
333+
value: 2,
334+
relation: 'eq',
335+
},
336+
max_score: null,
337+
hits: [
338+
{
339+
_index: 'metrics-endpoint.metadata-default-1',
340+
_id: 'W6Vo1G8BYQH1gtPUgYkC',
341+
_score: null,
342+
_source: hostMetadata,
343+
sort: [1579816615336],
344+
},
345+
],
346+
},
347+
},
348+
},
349+
},
350+
]
351+
: [],
352+
},
353+
aggregations: {
354+
total: {
355+
value: 1,
356+
},
357+
},
358+
} as unknown) as SearchResponse<HostMetadata>;
359+
}

0 commit comments

Comments
 (0)