Skip to content

Commit

Permalink
[SECURITY SOLUTION] EMT-401: add policy data to metadata and fix tests (
Browse files Browse the repository at this point in the history
elastic#68582)

[SECURITY SOLUTION] EMT-401: add policy data to metadata and fix tests
  • Loading branch information
nnamdifrankie committed Jun 12, 2020
1 parent 52f9583 commit a5d4083
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 279 deletions.
30 changes: 24 additions & 6 deletions x-pack/plugins/security_solution/common/endpoint/generate_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,20 @@ const Mac: HostOS[] = [];

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

const POLICIES: Array<{ name: string; id: string }> = [
const APPLIED_POLICIES: Array<{
name: string;
id: string;
status: HostPolicyResponseActionStatus;
}> = [
{
name: 'Default',
id: '00000000-0000-0000-0000-000000000000',
status: HostPolicyResponseActionStatus.success,
},
{
name: 'With Eventing',
id: 'C2A9093E-E289-4C0A-AA44-8C32A414FA7A',
status: HostPolicyResponseActionStatus.success,
},
];

Expand Down Expand Up @@ -181,7 +187,11 @@ interface HostInfo {
host: Host;
endpoint: {
policy: {
id: string;
applied: {
id: string;
status: HostPolicyResponseActionStatus;
name: string;
};
};
};
}
Expand Down Expand Up @@ -271,7 +281,12 @@ export class EndpointDocGenerator {
* Creates new random policy id for the host to simulate new policy application
*/
public updatePolicyId() {
this.commonInfo.endpoint.policy.id = this.randomChoice(POLICIES).id;
this.commonInfo.endpoint.policy.applied.id = this.randomChoice(APPLIED_POLICIES).id;
this.commonInfo.endpoint.policy.applied.status = this.randomChoice([
HostPolicyResponseActionStatus.success,
HostPolicyResponseActionStatus.failure,
HostPolicyResponseActionStatus.warning,
]);
}

private createHostData(): HostInfo {
Expand All @@ -293,7 +308,9 @@ export class EndpointDocGenerator {
os: this.randomChoice(OS),
},
endpoint: {
policy: this.randomChoice(POLICIES),
policy: {
applied: this.randomChoice(APPLIED_POLICIES),
},
},
};
}
Expand Down Expand Up @@ -974,7 +991,7 @@ export class EndpointDocGenerator {
status: HostPolicyResponseActionStatus.success,
},
],
id: this.commonInfo.endpoint.policy.id,
id: this.commonInfo.endpoint.policy.applied.id,
response: {
configurations: {
events: {
Expand Down Expand Up @@ -1015,8 +1032,9 @@ export class EndpointDocGenerator {
],
},
},
status: this.randomHostPolicyResponseActionStatus(),
status: this.commonInfo.endpoint.policy.applied.status,
version: policyVersion,
name: this.commonInfo.endpoint.policy.applied.name,
},
},
},
Expand Down
13 changes: 11 additions & 2 deletions x-pack/plugins/security_solution/common/endpoint/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,11 @@ export type AlertEvent = Immutable<{
};
endpoint: {
policy: {
id: string;
applied: {
id: string;
status: HostPolicyResponseActionStatus;
name: string;
};
};
};
process: {
Expand Down Expand Up @@ -357,7 +361,11 @@ export type HostMetadata = Immutable<{
};
endpoint: {
policy: {
id: string;
applied: {
id: string;
status: HostPolicyResponseActionStatus;
name: string;
};
};
};
agent: {
Expand Down Expand Up @@ -700,6 +708,7 @@ export interface HostPolicyResponse {
applied: {
version: string;
id: string;
name: string;
status: HostPolicyResponseActionStatus;
actions: HostPolicyResponseAppliedAction[];
response: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
title: i18n.translate('xpack.securitySolution.endpoint.host.details.policy', {
defaultMessage: 'Policy',
}),
description: details.endpoint.policy.id,
description: details.endpoint.policy.applied.id,
},
{
title: i18n.translate('xpack.securitySolution.endpoint.host.details.policyStatus', {
Expand Down Expand Up @@ -138,10 +138,10 @@ export const HostDetails = memo(({ details }: { details: HostMetadata }) => {
},
];
}, [
details.endpoint.policy.id,
details.host.ip,
details.host.hostname,
details.agent.version,
details.endpoint.policy.applied.id,
details.host.hostname,
details.host.ip,
policyStatus,
policyResponseUri,
policyStatusClickHandler,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import {
} from '../../../../common/endpoint/types';
import { SearchResponse } from 'elasticsearch';
import { registerEndpointRoutes } from './index';
import * as data from '../../test_data/all_metadata_data.json';
import {
createMockAgentService,
createMockMetadataIndexPatternRetriever,
Expand All @@ -37,6 +36,7 @@ import { AgentService } from '../../../../../ingest_manager/server';
import Boom from 'boom';
import { EndpointAppContextService } from '../../endpoint_app_context_services';
import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__';
import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data';

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

it('test find the latest of all endpoints', async () => {
const mockRequest = httpServerMock.createKibanaRequest({});

const response: SearchResponse<HostMetadata> = (data as unknown) as SearchResponse<
HostMetadata
>;
const response = createSearchResponse(new EndpointDocGenerator().generateHostMetadata());
mockScopedClient.callAsCurrentUser.mockImplementationOnce(() => Promise.resolve(response));
[routeConfig, routeHandler] = routerMock.post.mock.calls.find(([{ path }]) =>
path.startsWith('/api/endpoint/metadata')
Expand All @@ -97,8 +94,8 @@ describe('test endpoint route', () => {
expect(routeConfig.options).toEqual({ authRequired: true });
expect(mockResponse.ok).toBeCalled();
const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as HostResultList;
expect(endpointResultList.hosts.length).toEqual(2);
expect(endpointResultList.total).toEqual(2);
expect(endpointResultList.hosts.length).toEqual(1);
expect(endpointResultList.total).toEqual(1);
expect(endpointResultList.request_page_index).toEqual(0);
expect(endpointResultList.request_page_size).toEqual(10);
});
Expand All @@ -119,7 +116,7 @@ describe('test endpoint route', () => {

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

mockAgentService.getAgentStatusById = jest.fn().mockReturnValue('error');
mockScopedClient.callAsCurrentUser.mockImplementationOnce(() =>
Promise.resolve((data as unknown) as SearchResponse<HostMetadata>)
Promise.resolve(createSearchResponse(new EndpointDocGenerator().generateHostMetadata()))
);
[routeConfig, routeHandler] = routerMock.post.mock.calls.find(([{ path }]) =>
path.startsWith('/api/endpoint/metadata')
Expand Down Expand Up @@ -194,34 +191,18 @@ describe('test endpoint route', () => {
expect(routeConfig.options).toEqual({ authRequired: true });
expect(mockResponse.ok).toBeCalled();
const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as HostResultList;
expect(endpointResultList.hosts.length).toEqual(2);
expect(endpointResultList.total).toEqual(2);
expect(endpointResultList.hosts.length).toEqual(1);
expect(endpointResultList.total).toEqual(1);
expect(endpointResultList.request_page_index).toEqual(10);
expect(endpointResultList.request_page_size).toEqual(10);
});

describe('Endpoint Details route', () => {
it('should return 404 on no results', async () => {
const mockRequest = httpServerMock.createKibanaRequest({ params: { id: 'BADID' } });

mockScopedClient.callAsCurrentUser.mockImplementationOnce(() =>
Promise.resolve({
took: 3,
timed_out: false,
_shards: {
total: 1,
successful: 1,
skipped: 0,
failed: 0,
},
hits: {
total: {
value: 9,
relation: 'eq',
},
max_score: null,
hits: [],
},
})
Promise.resolve(createSearchResponse())
);
mockAgentService.getAgentStatusById = jest.fn().mockReturnValue('error');
[routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) =>
Expand All @@ -241,13 +222,10 @@ describe('test endpoint route', () => {
});

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

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

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

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

const mockRequest = httpServerMock.createKibanaRequest({
params: { id: response.hits.hits[0]._id },
Expand All @@ -327,3 +301,59 @@ describe('test endpoint route', () => {
});
});
});

function createSearchResponse(hostMetadata?: HostMetadata): SearchResponse<HostMetadata> {
return ({
took: 15,
timed_out: false,
_shards: {
total: 1,
successful: 1,
skipped: 0,
failed: 0,
},
hits: {
total: {
value: 5,
relation: 'eq',
},
max_score: null,
hits: hostMetadata
? [
{
_index: 'metrics-endpoint.metadata-default-1',
_id: '8FhM0HEBYyRTvb6lOQnw',
_score: null,
_source: hostMetadata,
sort: [1588337587997],
inner_hits: {
most_recent: {
hits: {
total: {
value: 2,
relation: 'eq',
},
max_score: null,
hits: [
{
_index: 'metrics-endpoint.metadata-default-1',
_id: 'W6Vo1G8BYQH1gtPUgYkC',
_score: null,
_source: hostMetadata,
sort: [1579816615336],
},
],
},
},
},
},
]
: [],
},
aggregations: {
total: {
value: 1,
},
},
} as unknown) as SearchResponse<HostMetadata>;
}
Loading

0 comments on commit a5d4083

Please sign in to comment.