[Security Solution][Endpoint] Action and responses data generators for .logs-endpoint.action*
data streams (#113403) (#114112)
This commit is contained in:
parent
8ca4d920de
commit
a761f20c13
|
@ -5,6 +5,9 @@
|
||||||
* 2.0.
|
* 2.0.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
export const ENDPOINT_ACTIONS_INDEX = '.logs-endpoint.actions-default';
|
||||||
|
export const ENDPOINT_ACTION_RESPONSES_INDEX = '.logs-endpoint.action.responses-default';
|
||||||
|
|
||||||
export const eventsIndexPattern = 'logs-endpoint.events.*';
|
export const eventsIndexPattern = 'logs-endpoint.events.*';
|
||||||
export const alertsIndexPattern = 'logs-endpoint.alerts-*';
|
export const alertsIndexPattern = 'logs-endpoint.alerts-*';
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { DeepPartial } from 'utility-types';
|
||||||
|
import { merge } from 'lodash';
|
||||||
|
import { BaseDataGenerator } from './base_data_generator';
|
||||||
|
import { EndpointActionData, ISOLATION_ACTIONS } from '../types';
|
||||||
|
|
||||||
|
interface EcsError {
|
||||||
|
code: string;
|
||||||
|
id: string;
|
||||||
|
message: string;
|
||||||
|
stack_trace: string;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface EndpointActionFields {
|
||||||
|
action_id: string;
|
||||||
|
data: EndpointActionData;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ActionRequestFields {
|
||||||
|
expiration: string;
|
||||||
|
type: 'INPUT_ACTION';
|
||||||
|
input_type: 'endpoint';
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ActionResponseFields {
|
||||||
|
completed_at: string;
|
||||||
|
started_at: string;
|
||||||
|
}
|
||||||
|
export interface LogsEndpointAction {
|
||||||
|
'@timestamp': string;
|
||||||
|
agent: {
|
||||||
|
id: string | string[];
|
||||||
|
};
|
||||||
|
EndpointAction: EndpointActionFields & ActionRequestFields;
|
||||||
|
error?: EcsError;
|
||||||
|
user: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LogsEndpointActionResponse {
|
||||||
|
'@timestamp': string;
|
||||||
|
agent: {
|
||||||
|
id: string | string[];
|
||||||
|
};
|
||||||
|
EndpointAction: EndpointActionFields & ActionResponseFields;
|
||||||
|
error?: EcsError;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ISOLATION_COMMANDS: ISOLATION_ACTIONS[] = ['isolate', 'unisolate'];
|
||||||
|
|
||||||
|
export class EndpointActionGenerator extends BaseDataGenerator {
|
||||||
|
/** Generate a random endpoint Action request (isolate or unisolate) */
|
||||||
|
generate(overrides: DeepPartial<LogsEndpointAction> = {}): LogsEndpointAction {
|
||||||
|
const timeStamp = new Date(this.randomPastDate());
|
||||||
|
return merge(
|
||||||
|
{
|
||||||
|
'@timestamp': timeStamp.toISOString(),
|
||||||
|
agent: {
|
||||||
|
id: [this.randomUUID()],
|
||||||
|
},
|
||||||
|
EndpointAction: {
|
||||||
|
action_id: this.randomUUID(),
|
||||||
|
expiration: this.randomFutureDate(timeStamp),
|
||||||
|
type: 'INPUT_ACTION',
|
||||||
|
input_type: 'endpoint',
|
||||||
|
data: {
|
||||||
|
command: this.randomIsolateCommand(),
|
||||||
|
comment: this.randomString(15),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
error: undefined,
|
||||||
|
user: {
|
||||||
|
id: this.randomUser(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
overrides
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
generateIsolateAction(overrides: DeepPartial<LogsEndpointAction> = {}): LogsEndpointAction {
|
||||||
|
return merge(this.generate({ EndpointAction: { data: { command: 'isolate' } } }), overrides);
|
||||||
|
}
|
||||||
|
|
||||||
|
generateUnIsolateAction(overrides: DeepPartial<LogsEndpointAction> = {}): LogsEndpointAction {
|
||||||
|
return merge(this.generate({ EndpointAction: { data: { command: 'unisolate' } } }), overrides);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generates an endpoint action response */
|
||||||
|
generateResponse(
|
||||||
|
overrides: DeepPartial<LogsEndpointActionResponse> = {}
|
||||||
|
): LogsEndpointActionResponse {
|
||||||
|
const timeStamp = new Date();
|
||||||
|
|
||||||
|
return merge(
|
||||||
|
{
|
||||||
|
'@timestamp': timeStamp.toISOString(),
|
||||||
|
agent: {
|
||||||
|
id: this.randomUUID(),
|
||||||
|
},
|
||||||
|
EndpointAction: {
|
||||||
|
action_id: this.randomUUID(),
|
||||||
|
completed_at: timeStamp.toISOString(),
|
||||||
|
data: {
|
||||||
|
command: this.randomIsolateCommand(),
|
||||||
|
comment: '',
|
||||||
|
},
|
||||||
|
started_at: this.randomPastDate(),
|
||||||
|
},
|
||||||
|
error: undefined,
|
||||||
|
},
|
||||||
|
overrides
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
randomFloat(): number {
|
||||||
|
return this.random();
|
||||||
|
}
|
||||||
|
|
||||||
|
randomN(max: number): number {
|
||||||
|
return super.randomN(max);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected randomIsolateCommand() {
|
||||||
|
return this.randomChoice(ISOLATION_COMMANDS);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,217 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License
|
||||||
|
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||||
|
* 2.0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Client } from '@elastic/elasticsearch';
|
||||||
|
import { DeleteByQueryResponse } from '@elastic/elasticsearch/api/types';
|
||||||
|
import { HostMetadata } from '../types';
|
||||||
|
import {
|
||||||
|
EndpointActionGenerator,
|
||||||
|
LogsEndpointAction,
|
||||||
|
LogsEndpointActionResponse,
|
||||||
|
} from '../data_generators/endpoint_action_generator';
|
||||||
|
import { wrapErrorAndRejectPromise } from './utils';
|
||||||
|
import { ENDPOINT_ACTIONS_INDEX, ENDPOINT_ACTION_RESPONSES_INDEX } from '../constants';
|
||||||
|
|
||||||
|
const defaultEndpointActionGenerator = new EndpointActionGenerator();
|
||||||
|
|
||||||
|
export interface IndexedEndpointActionsForHostResponse {
|
||||||
|
endpointActions: LogsEndpointAction[];
|
||||||
|
endpointActionResponses: LogsEndpointActionResponse[];
|
||||||
|
endpointActionsIndex: string;
|
||||||
|
endpointActionResponsesIndex: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indexes a random number of Endpoint Actions for a given host
|
||||||
|
*
|
||||||
|
* @param esClient
|
||||||
|
* @param endpointHost
|
||||||
|
* @param [endpointActionGenerator]
|
||||||
|
*/
|
||||||
|
export const indexEndpointActionsForHost = async (
|
||||||
|
esClient: Client,
|
||||||
|
endpointHost: HostMetadata,
|
||||||
|
endpointActionGenerator: EndpointActionGenerator = defaultEndpointActionGenerator
|
||||||
|
): Promise<IndexedEndpointActionsForHostResponse> => {
|
||||||
|
const agentId = endpointHost.elastic.agent.id;
|
||||||
|
const total = endpointActionGenerator.randomN(5);
|
||||||
|
const response: IndexedEndpointActionsForHostResponse = {
|
||||||
|
endpointActions: [],
|
||||||
|
endpointActionResponses: [],
|
||||||
|
endpointActionsIndex: ENDPOINT_ACTIONS_INDEX,
|
||||||
|
endpointActionResponsesIndex: ENDPOINT_ACTION_RESPONSES_INDEX,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let i = 0; i < total; i++) {
|
||||||
|
// create an action
|
||||||
|
const action = endpointActionGenerator.generate({
|
||||||
|
EndpointAction: {
|
||||||
|
data: { comment: 'data generator: this host is same as bad' },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
action.agent.id = [agentId];
|
||||||
|
|
||||||
|
await esClient
|
||||||
|
.index({
|
||||||
|
index: ENDPOINT_ACTIONS_INDEX,
|
||||||
|
body: action,
|
||||||
|
})
|
||||||
|
.catch(wrapErrorAndRejectPromise);
|
||||||
|
|
||||||
|
// Create an action response for the above
|
||||||
|
const actionResponse = endpointActionGenerator.generateResponse({
|
||||||
|
agent: { id: agentId },
|
||||||
|
EndpointAction: {
|
||||||
|
action_id: action.EndpointAction.action_id,
|
||||||
|
data: action.EndpointAction.data,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
await esClient
|
||||||
|
.index({
|
||||||
|
index: ENDPOINT_ACTION_RESPONSES_INDEX,
|
||||||
|
body: actionResponse,
|
||||||
|
})
|
||||||
|
.catch(wrapErrorAndRejectPromise);
|
||||||
|
|
||||||
|
response.endpointActions.push(action);
|
||||||
|
response.endpointActionResponses.push(actionResponse);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add edge cases (maybe)
|
||||||
|
if (endpointActionGenerator.randomFloat() < 0.3) {
|
||||||
|
const randomFloat = endpointActionGenerator.randomFloat();
|
||||||
|
|
||||||
|
// 60% of the time just add either an Isolate -OR- an UnIsolate action
|
||||||
|
if (randomFloat < 0.6) {
|
||||||
|
let action: LogsEndpointAction;
|
||||||
|
|
||||||
|
if (randomFloat < 0.3) {
|
||||||
|
// add a pending isolation
|
||||||
|
action = endpointActionGenerator.generateIsolateAction({
|
||||||
|
'@timestamp': new Date().toISOString(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// add a pending UN-isolation
|
||||||
|
action = endpointActionGenerator.generateUnIsolateAction({
|
||||||
|
'@timestamp': new Date().toISOString(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
action.agent.id = [agentId];
|
||||||
|
|
||||||
|
await esClient
|
||||||
|
.index({
|
||||||
|
index: ENDPOINT_ACTIONS_INDEX,
|
||||||
|
body: action,
|
||||||
|
})
|
||||||
|
.catch(wrapErrorAndRejectPromise);
|
||||||
|
|
||||||
|
response.endpointActions.push(action);
|
||||||
|
} else {
|
||||||
|
// Else (40% of the time) add a pending isolate AND pending un-isolate
|
||||||
|
const action1 = endpointActionGenerator.generateIsolateAction({
|
||||||
|
'@timestamp': new Date().toISOString(),
|
||||||
|
});
|
||||||
|
const action2 = endpointActionGenerator.generateUnIsolateAction({
|
||||||
|
'@timestamp': new Date().toISOString(),
|
||||||
|
});
|
||||||
|
|
||||||
|
action1.agent.id = [agentId];
|
||||||
|
action2.agent.id = [agentId];
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
esClient
|
||||||
|
.index({
|
||||||
|
index: ENDPOINT_ACTIONS_INDEX,
|
||||||
|
body: action1,
|
||||||
|
})
|
||||||
|
.catch(wrapErrorAndRejectPromise),
|
||||||
|
esClient
|
||||||
|
.index({
|
||||||
|
index: ENDPOINT_ACTIONS_INDEX,
|
||||||
|
body: action2,
|
||||||
|
})
|
||||||
|
.catch(wrapErrorAndRejectPromise),
|
||||||
|
]);
|
||||||
|
|
||||||
|
response.endpointActions.push(action1, action2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface DeleteIndexedEndpointActionsResponse {
|
||||||
|
endpointActionRequests: DeleteByQueryResponse | undefined;
|
||||||
|
endpointActionResponses: DeleteByQueryResponse | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deleteIndexedEndpointActions = async (
|
||||||
|
esClient: Client,
|
||||||
|
indexedData: IndexedEndpointActionsForHostResponse
|
||||||
|
): Promise<DeleteIndexedEndpointActionsResponse> => {
|
||||||
|
const response: DeleteIndexedEndpointActionsResponse = {
|
||||||
|
endpointActionRequests: undefined,
|
||||||
|
endpointActionResponses: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (indexedData.endpointActions.length) {
|
||||||
|
response.endpointActionRequests = (
|
||||||
|
await esClient
|
||||||
|
.deleteByQuery({
|
||||||
|
index: `${indexedData.endpointActionsIndex}-*`,
|
||||||
|
wait_for_completion: true,
|
||||||
|
body: {
|
||||||
|
query: {
|
||||||
|
bool: {
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
terms: {
|
||||||
|
action_id: indexedData.endpointActions.map(
|
||||||
|
(action) => action.EndpointAction.action_id
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch(wrapErrorAndRejectPromise)
|
||||||
|
).body;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexedData.endpointActionResponses) {
|
||||||
|
response.endpointActionResponses = (
|
||||||
|
await esClient
|
||||||
|
.deleteByQuery({
|
||||||
|
index: `${indexedData.endpointActionResponsesIndex}-*`,
|
||||||
|
wait_for_completion: true,
|
||||||
|
body: {
|
||||||
|
query: {
|
||||||
|
bool: {
|
||||||
|
filter: [
|
||||||
|
{
|
||||||
|
terms: {
|
||||||
|
action_id: indexedData.endpointActionResponses.map(
|
||||||
|
(action) => action.EndpointAction.action_id
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch(wrapErrorAndRejectPromise)
|
||||||
|
).body;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
|
@ -26,6 +26,13 @@ import {
|
||||||
IndexedFleetActionsForHostResponse,
|
IndexedFleetActionsForHostResponse,
|
||||||
indexFleetActionsForHost,
|
indexFleetActionsForHost,
|
||||||
} from './index_fleet_actions';
|
} from './index_fleet_actions';
|
||||||
|
import {
|
||||||
|
deleteIndexedEndpointActions,
|
||||||
|
DeleteIndexedEndpointActionsResponse,
|
||||||
|
IndexedEndpointActionsForHostResponse,
|
||||||
|
indexEndpointActionsForHost,
|
||||||
|
} from './index_endpoint_actions';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
deleteIndexedFleetEndpointPolicies,
|
deleteIndexedFleetEndpointPolicies,
|
||||||
DeleteIndexedFleetEndpointPoliciesResponse,
|
DeleteIndexedFleetEndpointPoliciesResponse,
|
||||||
|
@ -38,6 +45,7 @@ import { EndpointDataLoadingError, wrapErrorAndRejectPromise } from './utils';
|
||||||
export interface IndexedHostsResponse
|
export interface IndexedHostsResponse
|
||||||
extends IndexedFleetAgentResponse,
|
extends IndexedFleetAgentResponse,
|
||||||
IndexedFleetActionsForHostResponse,
|
IndexedFleetActionsForHostResponse,
|
||||||
|
IndexedEndpointActionsForHostResponse,
|
||||||
IndexedFleetEndpointPolicyResponse {
|
IndexedFleetEndpointPolicyResponse {
|
||||||
/**
|
/**
|
||||||
* The documents (1 or more) that were generated for the (single) endpoint host.
|
* The documents (1 or more) that were generated for the (single) endpoint host.
|
||||||
|
@ -81,6 +89,7 @@ export async function indexEndpointHostDocs({
|
||||||
metadataIndex,
|
metadataIndex,
|
||||||
policyResponseIndex,
|
policyResponseIndex,
|
||||||
enrollFleet,
|
enrollFleet,
|
||||||
|
addEndpointActions,
|
||||||
generator,
|
generator,
|
||||||
}: {
|
}: {
|
||||||
numDocs: number;
|
numDocs: number;
|
||||||
|
@ -91,6 +100,7 @@ export async function indexEndpointHostDocs({
|
||||||
metadataIndex: string;
|
metadataIndex: string;
|
||||||
policyResponseIndex: string;
|
policyResponseIndex: string;
|
||||||
enrollFleet: boolean;
|
enrollFleet: boolean;
|
||||||
|
addEndpointActions: boolean;
|
||||||
generator: EndpointDocGenerator;
|
generator: EndpointDocGenerator;
|
||||||
}): Promise<IndexedHostsResponse> {
|
}): Promise<IndexedHostsResponse> {
|
||||||
const timeBetweenDocs = 6 * 3600 * 1000; // 6 hours between metadata documents
|
const timeBetweenDocs = 6 * 3600 * 1000; // 6 hours between metadata documents
|
||||||
|
@ -103,6 +113,10 @@ export async function indexEndpointHostDocs({
|
||||||
metadataIndex,
|
metadataIndex,
|
||||||
policyResponseIndex,
|
policyResponseIndex,
|
||||||
fleetAgentsIndex: '',
|
fleetAgentsIndex: '',
|
||||||
|
endpointActionResponses: [],
|
||||||
|
endpointActionResponsesIndex: '',
|
||||||
|
endpointActions: [],
|
||||||
|
endpointActionsIndex: '',
|
||||||
actionResponses: [],
|
actionResponses: [],
|
||||||
responsesIndex: '',
|
responsesIndex: '',
|
||||||
actions: [],
|
actions: [],
|
||||||
|
@ -177,9 +191,16 @@ export async function indexEndpointHostDocs({
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create some actions for this Host
|
// Create some fleet endpoint actions and .logs-endpoint actions for this Host
|
||||||
|
if (addEndpointActions) {
|
||||||
|
await Promise.all([
|
||||||
|
indexFleetActionsForHost(client, hostMetadata),
|
||||||
|
indexEndpointActionsForHost(client, hostMetadata),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
await indexFleetActionsForHost(client, hostMetadata);
|
await indexFleetActionsForHost(client, hostMetadata);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hostMetadata = {
|
hostMetadata = {
|
||||||
...hostMetadata,
|
...hostMetadata,
|
||||||
|
@ -237,6 +258,7 @@ const fetchKibanaVersion = async (kbnClient: KbnClient) => {
|
||||||
export interface DeleteIndexedEndpointHostsResponse
|
export interface DeleteIndexedEndpointHostsResponse
|
||||||
extends DeleteIndexedFleetAgentsResponse,
|
extends DeleteIndexedFleetAgentsResponse,
|
||||||
DeleteIndexedFleetActionsResponse,
|
DeleteIndexedFleetActionsResponse,
|
||||||
|
DeleteIndexedEndpointActionsResponse,
|
||||||
DeleteIndexedFleetEndpointPoliciesResponse {
|
DeleteIndexedFleetEndpointPoliciesResponse {
|
||||||
hosts: DeleteByQueryResponse | undefined;
|
hosts: DeleteByQueryResponse | undefined;
|
||||||
policyResponses: DeleteByQueryResponse | undefined;
|
policyResponses: DeleteByQueryResponse | undefined;
|
||||||
|
@ -253,6 +275,8 @@ export const deleteIndexedEndpointHosts = async (
|
||||||
agents: undefined,
|
agents: undefined,
|
||||||
responses: undefined,
|
responses: undefined,
|
||||||
actions: undefined,
|
actions: undefined,
|
||||||
|
endpointActionRequests: undefined,
|
||||||
|
endpointActionResponses: undefined,
|
||||||
integrationPolicies: undefined,
|
integrationPolicies: undefined,
|
||||||
agentPolicies: undefined,
|
agentPolicies: undefined,
|
||||||
};
|
};
|
||||||
|
@ -314,6 +338,7 @@ export const deleteIndexedEndpointHosts = async (
|
||||||
|
|
||||||
merge(response, await deleteIndexedFleetAgents(esClient, indexedData));
|
merge(response, await deleteIndexedFleetAgents(esClient, indexedData));
|
||||||
merge(response, await deleteIndexedFleetActions(esClient, indexedData));
|
merge(response, await deleteIndexedFleetActions(esClient, indexedData));
|
||||||
|
merge(response, await deleteIndexedEndpointActions(esClient, indexedData));
|
||||||
merge(response, await deleteIndexedFleetEndpointPolicies(kbnClient, indexedData));
|
merge(response, await deleteIndexedFleetEndpointPolicies(kbnClient, indexedData));
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|
|
@ -57,6 +57,7 @@ export async function indexHostsAndAlerts(
|
||||||
alertIndex: string,
|
alertIndex: string,
|
||||||
alertsPerHost: number,
|
alertsPerHost: number,
|
||||||
fleet: boolean,
|
fleet: boolean,
|
||||||
|
logsEndpoint: boolean,
|
||||||
options: TreeOptions = {}
|
options: TreeOptions = {}
|
||||||
): Promise<IndexedHostsAndAlertsResponse> {
|
): Promise<IndexedHostsAndAlertsResponse> {
|
||||||
const random = seedrandom(seed);
|
const random = seedrandom(seed);
|
||||||
|
@ -72,11 +73,15 @@ export async function indexHostsAndAlerts(
|
||||||
responsesIndex: '',
|
responsesIndex: '',
|
||||||
actions: [],
|
actions: [],
|
||||||
actionsIndex: '',
|
actionsIndex: '',
|
||||||
|
endpointActions: [],
|
||||||
|
endpointActionsIndex: '',
|
||||||
|
endpointActionResponses: [],
|
||||||
|
endpointActionResponsesIndex: '',
|
||||||
integrationPolicies: [],
|
integrationPolicies: [],
|
||||||
agentPolicies: [],
|
agentPolicies: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure fleet is setup and endpint package installed
|
// Ensure fleet is setup and endpoint package installed
|
||||||
await setupFleetForEndpoint(kbnClient);
|
await setupFleetForEndpoint(kbnClient);
|
||||||
|
|
||||||
// If `fleet` integration is true, then ensure a (fake) fleet-server is connected
|
// If `fleet` integration is true, then ensure a (fake) fleet-server is connected
|
||||||
|
@ -98,6 +103,7 @@ export async function indexHostsAndAlerts(
|
||||||
metadataIndex,
|
metadataIndex,
|
||||||
policyResponseIndex,
|
policyResponseIndex,
|
||||||
enrollFleet: fleet,
|
enrollFleet: fleet,
|
||||||
|
addEndpointActions: logsEndpoint,
|
||||||
generator,
|
generator,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,14 @@ async function main() {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
logsEndpoint: {
|
||||||
|
alias: 'le',
|
||||||
|
describe:
|
||||||
|
'By default .logs-endpoint.action and .logs-endpoint.action.responses are not indexed. \
|
||||||
|
Add endpoint actions and responses using this option. Starting with v7.16.0.',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
ssl: {
|
ssl: {
|
||||||
alias: 'ssl',
|
alias: 'ssl',
|
||||||
describe: 'Use https for elasticsearch and kbn clients',
|
describe: 'Use https for elasticsearch and kbn clients',
|
||||||
|
@ -226,6 +234,7 @@ async function main() {
|
||||||
argv.alertIndex,
|
argv.alertIndex,
|
||||||
argv.alertsPerHost,
|
argv.alertsPerHost,
|
||||||
argv.fleet,
|
argv.fleet,
|
||||||
|
argv.logsEndpoint,
|
||||||
{
|
{
|
||||||
ancestors: argv.ancestors,
|
ancestors: argv.ancestors,
|
||||||
generations: argv.generations,
|
generations: argv.generations,
|
||||||
|
|
|
@ -91,6 +91,7 @@ export class EndpointTestResources extends FtrService {
|
||||||
numHostDocs: number;
|
numHostDocs: number;
|
||||||
alertsPerHost: number;
|
alertsPerHost: number;
|
||||||
enableFleetIntegration: boolean;
|
enableFleetIntegration: boolean;
|
||||||
|
logsEndpoint: boolean;
|
||||||
generatorSeed: string;
|
generatorSeed: string;
|
||||||
waitUntilTransformed: boolean;
|
waitUntilTransformed: boolean;
|
||||||
}> = {}
|
}> = {}
|
||||||
|
@ -100,6 +101,7 @@ export class EndpointTestResources extends FtrService {
|
||||||
numHostDocs = 1,
|
numHostDocs = 1,
|
||||||
alertsPerHost = 1,
|
alertsPerHost = 1,
|
||||||
enableFleetIntegration = true,
|
enableFleetIntegration = true,
|
||||||
|
logsEndpoint = false,
|
||||||
generatorSeed = 'seed',
|
generatorSeed = 'seed',
|
||||||
waitUntilTransformed = true,
|
waitUntilTransformed = true,
|
||||||
} = options;
|
} = options;
|
||||||
|
@ -116,7 +118,8 @@ export class EndpointTestResources extends FtrService {
|
||||||
'logs-endpoint.events.process-default',
|
'logs-endpoint.events.process-default',
|
||||||
'logs-endpoint.alerts-default',
|
'logs-endpoint.alerts-default',
|
||||||
alertsPerHost,
|
alertsPerHost,
|
||||||
enableFleetIntegration
|
enableFleetIntegration,
|
||||||
|
logsEndpoint
|
||||||
);
|
);
|
||||||
|
|
||||||
if (waitUntilTransformed) {
|
if (waitUntilTransformed) {
|
||||||
|
|
Loading…
Reference in a new issue