mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* Fixing resolver alert generation * Splitting indices up * Removing tests that could randomly fail because of the generation code * Adding support for multiple indices * Updating archives with the new index names * Removing alerts data stream * Switching to process instead of fake Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
5c0fb095d8
commit
c3a5536944
24 changed files with 130 additions and 74 deletions
|
@ -4,7 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export const eventsIndexPattern = 'events-endpoint-*';
|
||||
export const eventsIndexPattern = 'logs-endpoint.events.*';
|
||||
export const alertsIndexPattern = 'logs-endpoint.alerts-*';
|
||||
export const metadataIndexPattern = 'metrics-endpoint.metadata-*';
|
||||
export const policyIndexPattern = 'metrics-endpoint.policy-*';
|
||||
export const telemetryIndexPattern = 'metrics-endpoint.telemetry-*';
|
||||
|
|
|
@ -16,6 +16,7 @@ export async function indexHostsAndAlerts(
|
|||
metadataIndex: string,
|
||||
policyIndex: string,
|
||||
eventIndex: string,
|
||||
alertIndex: string,
|
||||
alertsPerHost: number,
|
||||
options: TreeOptions = {}
|
||||
) {
|
||||
|
@ -23,7 +24,7 @@ export async function indexHostsAndAlerts(
|
|||
for (let i = 0; i < numHosts; i++) {
|
||||
const generator = new EndpointDocGenerator(random);
|
||||
await indexHostDocs(numDocs, client, metadataIndex, policyIndex, generator);
|
||||
await indexAlerts(client, eventIndex, generator, alertsPerHost, options);
|
||||
await indexAlerts(client, eventIndex, alertIndex, generator, alertsPerHost, options);
|
||||
}
|
||||
await client.indices.refresh({
|
||||
index: eventIndex,
|
||||
|
@ -65,7 +66,8 @@ async function indexHostDocs(
|
|||
|
||||
async function indexAlerts(
|
||||
client: Client,
|
||||
index: string,
|
||||
eventIndex: string,
|
||||
alertIndex: string,
|
||||
generator: EndpointDocGenerator,
|
||||
numAlerts: number,
|
||||
options: TreeOptions = {}
|
||||
|
@ -82,9 +84,14 @@ async function indexAlerts(
|
|||
}
|
||||
const body = resolverDocs.reduce(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(array: Array<Record<string, any>>, doc) => (
|
||||
array.push({ create: { _index: index } }, doc), array
|
||||
),
|
||||
(array: Array<Record<string, any>>, doc) => {
|
||||
let index = eventIndex;
|
||||
if (doc.event.kind === 'alert') {
|
||||
index = alertIndex;
|
||||
}
|
||||
array.push({ create: { _index: index } }, doc);
|
||||
return array;
|
||||
},
|
||||
[]
|
||||
);
|
||||
await client.bulk({ body, refresh: 'true' });
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { eventsIndexPattern } from '../../../common/endpoint/constants';
|
||||
import { alertsIndexPattern } from '../../../common/endpoint/constants';
|
||||
import { IIndexPattern } from '../../../../../../src/plugins/data/public';
|
||||
import {
|
||||
AlertResultList,
|
||||
|
@ -49,10 +49,10 @@ export const alertMiddlewareFactory: ImmutableMiddlewareFactory<AlertListState>
|
|||
async function fetchIndexPatterns(): Promise<IIndexPattern[]> {
|
||||
const { indexPatterns } = depsStart.data;
|
||||
const fields = await indexPatterns.getFieldsForWildcard({
|
||||
pattern: eventsIndexPattern,
|
||||
pattern: alertsIndexPattern,
|
||||
});
|
||||
const indexPattern: IIndexPattern = {
|
||||
title: eventsIndexPattern,
|
||||
title: alertsIndexPattern,
|
||||
fields,
|
||||
};
|
||||
|
||||
|
|
|
@ -95,19 +95,25 @@ async function main() {
|
|||
eventIndex: {
|
||||
alias: 'ei',
|
||||
describe: 'index to store events in',
|
||||
default: 'events-endpoint-1',
|
||||
default: 'logs-endpoint.events.process-default',
|
||||
type: 'string',
|
||||
},
|
||||
alertIndex: {
|
||||
alias: 'ai',
|
||||
describe: 'index to store alerts in',
|
||||
default: 'logs-endpoint.alerts-default',
|
||||
type: 'string',
|
||||
},
|
||||
metadataIndex: {
|
||||
alias: 'mi',
|
||||
describe: 'index to store host metadata in',
|
||||
default: 'metrics-endpoint.metadata-default-1',
|
||||
default: 'metrics-endpoint.metadata-default',
|
||||
type: 'string',
|
||||
},
|
||||
policyIndex: {
|
||||
alias: 'pi',
|
||||
describe: 'index to store host policy in',
|
||||
default: 'metrics-endpoint.policy-default-1',
|
||||
default: 'metrics-endpoint.policy-default',
|
||||
type: 'string',
|
||||
},
|
||||
ancestors: {
|
||||
|
@ -192,7 +198,10 @@ async function main() {
|
|||
|
||||
const client = new Client(clientOptions);
|
||||
if (argv.delete) {
|
||||
await deleteIndices([argv.eventIndex, argv.metadataIndex, argv.policyIndex], client);
|
||||
await deleteIndices(
|
||||
[argv.eventIndex, argv.metadataIndex, argv.policyIndex, argv.alertIndex],
|
||||
client
|
||||
);
|
||||
}
|
||||
|
||||
let seed = argv.seed;
|
||||
|
@ -209,6 +218,7 @@ async function main() {
|
|||
argv.metadataIndex,
|
||||
argv.policyIndex,
|
||||
argv.eventIndex,
|
||||
argv.alertIndex,
|
||||
argv.alertsPerHost,
|
||||
{
|
||||
ancestors: argv.ancestors,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
import { GetResponse } from 'elasticsearch';
|
||||
import { KibanaRequest, RequestHandler } from 'kibana/server';
|
||||
import { eventsIndexPattern } from '../../../../../common/endpoint/constants';
|
||||
import { alertsIndexPattern } from '../../../../../common/endpoint/constants';
|
||||
import { AlertEvent } from '../../../../../common/endpoint/types';
|
||||
import { EndpointAppContext } from '../../../types';
|
||||
import { AlertDetailsRequestParams } from '../../../../../common/endpoint_alerts/types';
|
||||
|
@ -34,7 +34,7 @@ export const alertDetailsHandlerWrapper = function (
|
|||
ctx,
|
||||
req.params,
|
||||
response,
|
||||
eventsIndexPattern
|
||||
alertsIndexPattern
|
||||
);
|
||||
|
||||
const currentHostInfo = await getHostData(
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { RequestHandler } from 'kibana/server';
|
||||
import { eventsIndexPattern } from '../../../../../common/endpoint/constants';
|
||||
import { alertsIndexPattern } from '../../../../../common/endpoint/constants';
|
||||
import { EndpointAppContext } from '../../../types';
|
||||
import { searchESForAlerts } from '../lib';
|
||||
import { getRequestData, mapToAlertResultList } from './lib';
|
||||
|
@ -23,7 +23,7 @@ export const alertListHandlerWrapper = function (
|
|||
const response = await searchESForAlerts(
|
||||
ctx.core.elasticsearch.legacy.client,
|
||||
reqData,
|
||||
eventsIndexPattern
|
||||
alertsIndexPattern
|
||||
);
|
||||
const mappedBody = await mapToAlertResultList(ctx, endpointAppContext, reqData, response);
|
||||
return res.ok({ body: mappedBody });
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { RequestHandler, Logger } from 'kibana/server';
|
||||
import { validateAlerts } from '../../../../common/endpoint/schema/resolver';
|
||||
import { eventsIndexPattern } from '../../../../common/endpoint/constants';
|
||||
import { alertsIndexPattern, eventsIndexPattern } from '../../../../common/endpoint/constants';
|
||||
import { Fetcher } from './utils/fetch';
|
||||
import { EndpointAppContext } from '../../types';
|
||||
|
||||
|
@ -23,7 +23,7 @@ export function handleAlerts(
|
|||
try {
|
||||
const client = context.core.elasticsearch.legacy.client;
|
||||
|
||||
const fetcher = new Fetcher(client, id, eventsIndexPattern, endpointID);
|
||||
const fetcher = new Fetcher(client, id, eventsIndexPattern, alertsIndexPattern, endpointID);
|
||||
|
||||
return res.ok({
|
||||
body: await fetcher.alerts(alerts, afterAlert),
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { RequestHandler, Logger } from 'kibana/server';
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { eventsIndexPattern } from '../../../../common/endpoint/constants';
|
||||
import { eventsIndexPattern, alertsIndexPattern } from '../../../../common/endpoint/constants';
|
||||
import { validateAncestry } from '../../../../common/endpoint/schema/resolver';
|
||||
import { Fetcher } from './utils/fetch';
|
||||
import { EndpointAppContext } from '../../types';
|
||||
|
@ -23,7 +23,7 @@ export function handleAncestry(
|
|||
try {
|
||||
const client = context.core.elasticsearch.legacy.client;
|
||||
|
||||
const fetcher = new Fetcher(client, id, eventsIndexPattern, endpointID);
|
||||
const fetcher = new Fetcher(client, id, eventsIndexPattern, alertsIndexPattern, endpointID);
|
||||
const ancestorInfo = await fetcher.ancestors(ancestors);
|
||||
|
||||
return res.ok({
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { RequestHandler, Logger } from 'kibana/server';
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { eventsIndexPattern } from '../../../../common/endpoint/constants';
|
||||
import { eventsIndexPattern, alertsIndexPattern } from '../../../../common/endpoint/constants';
|
||||
import { validateChildren } from '../../../../common/endpoint/schema/resolver';
|
||||
import { Fetcher } from './utils/fetch';
|
||||
import { EndpointAppContext } from '../../types';
|
||||
|
@ -22,7 +22,7 @@ export function handleChildren(
|
|||
} = req;
|
||||
try {
|
||||
const client = context.core.elasticsearch.legacy.client;
|
||||
const fetcher = new Fetcher(client, id, eventsIndexPattern, endpointID);
|
||||
const fetcher = new Fetcher(client, id, eventsIndexPattern, alertsIndexPattern, endpointID);
|
||||
|
||||
return res.ok({
|
||||
body: await fetcher.children(children, generations, afterChild),
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { RequestHandler, Logger } from 'kibana/server';
|
||||
import { eventsIndexPattern } from '../../../../common/endpoint/constants';
|
||||
import { eventsIndexPattern, alertsIndexPattern } from '../../../../common/endpoint/constants';
|
||||
import { validateEvents } from '../../../../common/endpoint/schema/resolver';
|
||||
import { Fetcher } from './utils/fetch';
|
||||
import { EndpointAppContext } from '../../types';
|
||||
|
@ -23,7 +23,7 @@ export function handleEvents(
|
|||
try {
|
||||
const client = context.core.elasticsearch.legacy.client;
|
||||
|
||||
const fetcher = new Fetcher(client, id, eventsIndexPattern, endpointID);
|
||||
const fetcher = new Fetcher(client, id, eventsIndexPattern, alertsIndexPattern, endpointID);
|
||||
|
||||
return res.ok({
|
||||
body: await fetcher.events(events, afterEvent),
|
||||
|
|
|
@ -15,7 +15,7 @@ import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/com
|
|||
export class AlertsQuery extends ResolverQuery<PaginatedResults> {
|
||||
constructor(
|
||||
private readonly pagination: PaginationBuilder,
|
||||
indexPattern: string,
|
||||
indexPattern: string | string[],
|
||||
endpointID?: string
|
||||
) {
|
||||
super(indexPattern, endpointID);
|
||||
|
|
|
@ -25,13 +25,16 @@ export abstract class ResolverQuery<T> implements MSearchQuery {
|
|||
* we need `endpointID` for legacy data is because we don't have a cross endpoint unique identifier for process
|
||||
* events. Instead we use `unique_pid/ppid` and `endpointID` to uniquely identify a process event.
|
||||
*/
|
||||
constructor(private readonly indexPattern: string, private readonly endpointID?: string) {}
|
||||
constructor(
|
||||
private readonly indexPattern: string | string[],
|
||||
private readonly endpointID?: string
|
||||
) {}
|
||||
|
||||
private static createIdsArray(ids: string | string[]): string[] {
|
||||
return Array.isArray(ids) ? ids : [ids];
|
||||
}
|
||||
|
||||
private buildQuery(ids: string | string[]): { query: JsonObject; index: string } {
|
||||
private buildQuery(ids: string | string[]): { query: JsonObject; index: string | string[] } {
|
||||
const idsArray = ResolverQuery.createIdsArray(ids);
|
||||
if (this.endpointID) {
|
||||
return { query: this.legacyQuery(this.endpointID, idsArray), index: legacyEventIndexPattern };
|
||||
|
|
|
@ -15,7 +15,7 @@ import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/com
|
|||
export class ChildrenQuery extends ResolverQuery<PaginatedResults> {
|
||||
constructor(
|
||||
private readonly pagination: PaginationBuilder,
|
||||
indexPattern: string,
|
||||
indexPattern: string | string[],
|
||||
endpointID?: string
|
||||
) {
|
||||
super(indexPattern, endpointID);
|
||||
|
|
|
@ -15,7 +15,7 @@ import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/com
|
|||
export class EventsQuery extends ResolverQuery<PaginatedResults> {
|
||||
constructor(
|
||||
private readonly pagination: PaginationBuilder,
|
||||
indexPattern: string,
|
||||
indexPattern: string | string[],
|
||||
endpointID?: string
|
||||
) {
|
||||
super(indexPattern, endpointID);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import { RequestHandler, Logger } from 'kibana/server';
|
||||
import { TypeOf } from '@kbn/config-schema';
|
||||
import { eventsIndexPattern } from '../../../../common/endpoint/constants';
|
||||
import { eventsIndexPattern, alertsIndexPattern } from '../../../../common/endpoint/constants';
|
||||
import { validateTree } from '../../../../common/endpoint/schema/resolver';
|
||||
import { Fetcher } from './utils/fetch';
|
||||
import { Tree } from './utils/tree';
|
||||
|
@ -34,7 +34,7 @@ export function handleTree(
|
|||
try {
|
||||
const client = context.core.elasticsearch.legacy.client;
|
||||
|
||||
const fetcher = new Fetcher(client, id, eventsIndexPattern, endpointID);
|
||||
const fetcher = new Fetcher(client, id, eventsIndexPattern, alertsIndexPattern, endpointID);
|
||||
|
||||
const [childrenNodes, ancestry, relatedEvents, relatedAlerts] = await Promise.all([
|
||||
fetcher.children(children, generations, afterChild),
|
||||
|
|
|
@ -39,9 +39,13 @@ export class Fetcher {
|
|||
*/
|
||||
private readonly id: string,
|
||||
/**
|
||||
* Index pattern for searching ES
|
||||
* Index pattern for searching ES for events
|
||||
*/
|
||||
private readonly indexPattern: string,
|
||||
private readonly eventsIndexPattern: string,
|
||||
/**
|
||||
* Index pattern for searching ES for alerts
|
||||
*/
|
||||
private readonly alertsIndexPattern: string,
|
||||
/**
|
||||
* This is used for searching legacy events
|
||||
*/
|
||||
|
@ -109,7 +113,7 @@ export class Fetcher {
|
|||
public async alerts(limit: number, after?: string): Promise<ResolverRelatedAlerts> {
|
||||
const query = new AlertsQuery(
|
||||
PaginationBuilder.createBuilder(limit, after),
|
||||
this.indexPattern,
|
||||
this.alertsIndexPattern,
|
||||
this.endpointID
|
||||
);
|
||||
|
||||
|
@ -140,7 +144,7 @@ export class Fetcher {
|
|||
}
|
||||
|
||||
private async getNode(entityID: string): Promise<LifecycleNode | undefined> {
|
||||
const query = new LifecycleQuery(this.indexPattern, this.endpointID);
|
||||
const query = new LifecycleQuery(this.eventsIndexPattern, this.endpointID);
|
||||
const results = await query.search(this.client, entityID);
|
||||
if (results.length === 0) {
|
||||
return;
|
||||
|
@ -172,7 +176,7 @@ export class Fetcher {
|
|||
return;
|
||||
}
|
||||
|
||||
const query = new LifecycleQuery(this.indexPattern, this.endpointID);
|
||||
const query = new LifecycleQuery(this.eventsIndexPattern, this.endpointID);
|
||||
const results = await query.search(this.client, ancestors);
|
||||
|
||||
if (results.length === 0) {
|
||||
|
@ -210,7 +214,7 @@ export class Fetcher {
|
|||
private async doEvents(limit: number, after?: string) {
|
||||
const query = new EventsQuery(
|
||||
PaginationBuilder.createBuilder(limit, after),
|
||||
this.indexPattern,
|
||||
this.eventsIndexPattern,
|
||||
this.endpointID
|
||||
);
|
||||
|
||||
|
@ -243,10 +247,10 @@ export class Fetcher {
|
|||
|
||||
const childrenQuery = new ChildrenQuery(
|
||||
PaginationBuilder.createBuilder(limit, after),
|
||||
this.indexPattern,
|
||||
this.eventsIndexPattern,
|
||||
this.endpointID
|
||||
);
|
||||
const lifecycleQuery = new LifecycleQuery(this.indexPattern, this.endpointID);
|
||||
const lifecycleQuery = new LifecycleQuery(this.eventsIndexPattern, this.endpointID);
|
||||
|
||||
const { totals, results } = await childrenQuery.search(this.client, ids);
|
||||
if (results.length === 0) {
|
||||
|
@ -262,7 +266,10 @@ export class Fetcher {
|
|||
}
|
||||
|
||||
private async doStats(tree: Tree) {
|
||||
const statsQuery = new StatsQuery(this.indexPattern, this.endpointID);
|
||||
const statsQuery = new StatsQuery(
|
||||
[this.eventsIndexPattern, this.alertsIndexPattern],
|
||||
this.endpointID
|
||||
);
|
||||
const ids = tree.ids();
|
||||
const res = await statsQuery.search(this.client, ids);
|
||||
const alerts = res.alerts;
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
deleteEventsStream,
|
||||
deleteMetadataStream,
|
||||
deletePolicyStream,
|
||||
deleteAlertsStream,
|
||||
} from '../data_stream_helper';
|
||||
import { indexHostsAndAlerts } from '../../../../../plugins/security_solution/common/endpoint/index_data';
|
||||
|
||||
|
@ -42,9 +43,10 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
'alerts-seed',
|
||||
numberOfHosts,
|
||||
1,
|
||||
'metrics-endpoint.metadata-default-1',
|
||||
'metrics-endpoint.policy-default-1',
|
||||
'events-endpoint-1',
|
||||
'metrics-endpoint.metadata-default',
|
||||
'metrics-endpoint.policy-default',
|
||||
'logs-endpoint.events.process-default',
|
||||
'logs-endpoint.alerts-default',
|
||||
numberOfAlertsPerHost
|
||||
);
|
||||
});
|
||||
|
@ -54,6 +56,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
// to do it manually
|
||||
await Promise.all([
|
||||
deleteEventsStream(getService),
|
||||
deleteAlertsStream(getService),
|
||||
deleteMetadataStream(getService),
|
||||
deletePolicyStream(getService),
|
||||
]);
|
||||
|
|
|
@ -8,6 +8,7 @@ import { Client } from '@elastic/elasticsearch';
|
|||
import {
|
||||
metadataIndexPattern,
|
||||
eventsIndexPattern,
|
||||
alertsIndexPattern,
|
||||
policyIndexPattern,
|
||||
} from '../../../../plugins/security_solution/common/endpoint/constants';
|
||||
|
||||
|
@ -32,6 +33,10 @@ export async function deleteEventsStream(getService: (serviceName: 'es') => Clie
|
|||
await deleteDataStream(getService, eventsIndexPattern);
|
||||
}
|
||||
|
||||
export async function deleteAlertsStream(getService: (serviceName: 'es') => Client) {
|
||||
await deleteDataStream(getService, alertsIndexPattern);
|
||||
}
|
||||
|
||||
export async function deletePolicyStream(getService: (serviceName: 'es') => Client) {
|
||||
await deleteDataStream(getService, policyIndexPattern);
|
||||
}
|
||||
|
|
|
@ -178,7 +178,11 @@ const compareArrays = (
|
|||
* @param relatedEvents the related events received for a particular node
|
||||
* @param categories the related event info used when generating the resolver tree
|
||||
*/
|
||||
const verifyStats = (stats: ResolverNodeStats | undefined, categories: RelatedEventInfo[]) => {
|
||||
const verifyStats = (
|
||||
stats: ResolverNodeStats | undefined,
|
||||
categories: RelatedEventInfo[],
|
||||
relatedAlerts: number
|
||||
) => {
|
||||
expect(stats).to.not.be(undefined);
|
||||
let totalExpEvents = 0;
|
||||
for (const cat of categories) {
|
||||
|
@ -196,6 +200,7 @@ const verifyStats = (stats: ResolverNodeStats | undefined, categories: RelatedEv
|
|||
totalExpEvents += cat.count;
|
||||
}
|
||||
expect(stats?.events.total).to.be(totalExpEvents);
|
||||
expect(stats?.totalAlerts);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -204,9 +209,13 @@ const verifyStats = (stats: ResolverNodeStats | undefined, categories: RelatedEv
|
|||
* @param nodes an array of lifecycle nodes that should have a stats field defined
|
||||
* @param categories the related event info used when generating the resolver tree
|
||||
*/
|
||||
const verifyLifecycleStats = (nodes: LifecycleNode[], categories: RelatedEventInfo[]) => {
|
||||
const verifyLifecycleStats = (
|
||||
nodes: LifecycleNode[],
|
||||
categories: RelatedEventInfo[],
|
||||
relatedAlerts: number
|
||||
) => {
|
||||
for (const node of nodes) {
|
||||
verifyStats(node.stats, categories);
|
||||
verifyStats(node.stats, categories, relatedAlerts);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -220,13 +229,13 @@ export default function resolverAPIIntegrationTests({ getService }: FtrProviderC
|
|||
{ category: RelatedEventCategory.File, count: 1 },
|
||||
{ category: RelatedEventCategory.Registry, count: 1 },
|
||||
];
|
||||
|
||||
const relatedAlerts = 4;
|
||||
let resolverTrees: GeneratedTrees;
|
||||
let tree: Tree;
|
||||
const treeOptions: Options = {
|
||||
ancestors: 5,
|
||||
relatedEvents: relatedEventsToGen,
|
||||
relatedAlerts: 4,
|
||||
relatedAlerts,
|
||||
children: 3,
|
||||
generations: 2,
|
||||
percentTerminated: 100,
|
||||
|
@ -697,11 +706,11 @@ export default function resolverAPIIntegrationTests({ getService }: FtrProviderC
|
|||
expect(body.children.nextChild).to.equal(null);
|
||||
expect(body.children.childNodes.length).to.equal(12);
|
||||
verifyChildren(body.children.childNodes, tree, 4, 3);
|
||||
verifyLifecycleStats(body.children.childNodes, relatedEventsToGen);
|
||||
verifyLifecycleStats(body.children.childNodes, relatedEventsToGen, relatedAlerts);
|
||||
|
||||
expect(body.ancestry.nextAncestor).to.equal(null);
|
||||
verifyAncestry(body.ancestry.ancestors, tree, true);
|
||||
verifyLifecycleStats(body.ancestry.ancestors, relatedEventsToGen);
|
||||
verifyLifecycleStats(body.ancestry.ancestors, relatedEventsToGen, relatedAlerts);
|
||||
|
||||
expect(body.relatedEvents.nextEvent).to.equal(null);
|
||||
compareArrays(tree.origin.relatedEvents, body.relatedEvents.events, true);
|
||||
|
@ -710,7 +719,7 @@ export default function resolverAPIIntegrationTests({ getService }: FtrProviderC
|
|||
compareArrays(tree.origin.relatedAlerts, body.relatedAlerts.alerts, true);
|
||||
|
||||
compareArrays(tree.origin.lifecycle, body.lifecycle, true);
|
||||
verifyStats(body.stats, relatedEventsToGen);
|
||||
verifyStats(body.stats, relatedEventsToGen, relatedAlerts);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -25,7 +25,8 @@ export interface Options extends TreeOptions {
|
|||
*/
|
||||
export interface GeneratedTrees {
|
||||
trees: Tree[];
|
||||
index: string;
|
||||
eventsIndex: string;
|
||||
alertsIndex: string;
|
||||
}
|
||||
|
||||
export function ResolverGeneratorProvider({ getService }: FtrProviderContext) {
|
||||
|
@ -34,27 +35,30 @@ export function ResolverGeneratorProvider({ getService }: FtrProviderContext) {
|
|||
return {
|
||||
async createTrees(
|
||||
options: Options,
|
||||
eventsIndex: string = 'events-endpoint-1'
|
||||
eventsIndex: string = 'logs-endpoint.events.process-default',
|
||||
alertsIndex: string = 'logs-endpoint.alerts-default'
|
||||
): Promise<GeneratedTrees> {
|
||||
const allTrees: Tree[] = [];
|
||||
const generator = new EndpointDocGenerator();
|
||||
const numTrees = options.numTrees ?? 1;
|
||||
for (let j = 0; j < numTrees; j++) {
|
||||
const tree = generator.generateTree(options);
|
||||
const body = tree.allEvents.reduce(
|
||||
(array: Array<Record<string, any>>, doc) => (
|
||||
/**
|
||||
* We're using data streams which require that a bulk use `create` instead of `index`.
|
||||
*/
|
||||
array.push({ create: { _index: eventsIndex } }, doc), array
|
||||
),
|
||||
[]
|
||||
);
|
||||
const body = tree.allEvents.reduce((array: Array<Record<string, any>>, doc) => {
|
||||
let index = eventsIndex;
|
||||
if (doc.event.kind === 'alert') {
|
||||
index = alertsIndex;
|
||||
}
|
||||
/**
|
||||
* We're using data streams which require that a bulk use `create` instead of `index`.
|
||||
*/
|
||||
array.push({ create: { _index: index } }, doc);
|
||||
return array;
|
||||
}, []);
|
||||
// force a refresh here otherwise the documents might not be available when the tests search for them
|
||||
await client.bulk({ body, refresh: 'true' });
|
||||
allTrees.push(tree);
|
||||
}
|
||||
return { trees: allTrees, index: eventsIndex };
|
||||
return { trees: allTrees, eventsIndex, alertsIndex };
|
||||
},
|
||||
async deleteTrees(trees: GeneratedTrees) {
|
||||
/**
|
||||
|
@ -63,7 +67,14 @@ export function ResolverGeneratorProvider({ getService }: FtrProviderContext) {
|
|||
* need to do raw requests here. Delete a data stream is slightly different than that of a regular index which
|
||||
* is why we're using _data_stream here.
|
||||
*/
|
||||
await client.transport.request({ method: 'DELETE', path: `_data_stream/${trees.index}` });
|
||||
await client.transport.request({
|
||||
method: 'DELETE',
|
||||
path: `_data_stream/${trees.eventsIndex}`,
|
||||
});
|
||||
await client.transport.request({
|
||||
method: 'DELETE',
|
||||
path: `_data_stream/${trees.alertsIndex}`,
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -2,7 +2,7 @@
|
|||
"type": "doc",
|
||||
"value": {
|
||||
"id": "3KVN2G8BYQH1gtPUuYk7",
|
||||
"index": "metrics-endpoint.metadata-default-1",
|
||||
"index": "metrics-endpoint.metadata-default",
|
||||
"source": {
|
||||
"@timestamp": 1579881969541,
|
||||
"agent": {
|
||||
|
@ -57,7 +57,7 @@
|
|||
"type": "doc",
|
||||
"value": {
|
||||
"id": "3aVN2G8BYQH1gtPUuYk7",
|
||||
"index": "metrics-endpoint.metadata-default-1",
|
||||
"index": "metrics-endpoint.metadata-default",
|
||||
"source": {
|
||||
"@timestamp": 1579881969541,
|
||||
"agent": {
|
||||
|
@ -111,7 +111,7 @@
|
|||
"type": "doc",
|
||||
"value": {
|
||||
"id": "3qVN2G8BYQH1gtPUuYk7",
|
||||
"index": "metrics-endpoint.metadata-default-1",
|
||||
"index": "metrics-endpoint.metadata-default",
|
||||
"source": {
|
||||
"@timestamp": 1579881969541,
|
||||
"agent": {
|
||||
|
@ -163,7 +163,7 @@
|
|||
"type": "doc",
|
||||
"value": {
|
||||
"id": "36VN2G8BYQH1gtPUuYk7",
|
||||
"index": "metrics-endpoint.metadata-default-1",
|
||||
"index": "metrics-endpoint.metadata-default",
|
||||
"source": {
|
||||
"@timestamp": 1579878369541,
|
||||
"agent": {
|
||||
|
@ -218,7 +218,7 @@
|
|||
"type": "doc",
|
||||
"value": {
|
||||
"id": "4KVN2G8BYQH1gtPUuYk7",
|
||||
"index": "metrics-endpoint.metadata-default-1",
|
||||
"index": "metrics-endpoint.metadata-default",
|
||||
"source": {
|
||||
"@timestamp": 1579878369541,
|
||||
"agent": {
|
||||
|
@ -271,7 +271,7 @@
|
|||
"type": "doc",
|
||||
"value": {
|
||||
"id": "4aVN2G8BYQH1gtPUuYk7",
|
||||
"index": "metrics-endpoint.metadata-default-1",
|
||||
"index": "metrics-endpoint.metadata-default",
|
||||
"source": {
|
||||
"@timestamp": 1579878369541,
|
||||
"agent": {
|
||||
|
@ -324,7 +324,7 @@
|
|||
"type": "doc",
|
||||
"value": {
|
||||
"id": "4qVN2G8BYQH1gtPUuYk7",
|
||||
"index": "metrics-endpoint.metadata-default-1",
|
||||
"index": "metrics-endpoint.metadata-default",
|
||||
"source": {
|
||||
"@timestamp": 1579874769541,
|
||||
"agent": {
|
||||
|
@ -378,7 +378,7 @@
|
|||
"type": "doc",
|
||||
"value": {
|
||||
"id": "46VN2G8BYQH1gtPUuYk7",
|
||||
"index": "metrics-endpoint.metadata-default-1",
|
||||
"index": "metrics-endpoint.metadata-default",
|
||||
"source": {
|
||||
"@timestamp": 1579874769541,
|
||||
"agent": {
|
||||
|
@ -431,7 +431,7 @@
|
|||
"type": "doc",
|
||||
"value": {
|
||||
"id": "5KVN2G8BYQH1gtPUuYk7",
|
||||
"index": "metrics-endpoint.metadata-default-1",
|
||||
"index": "metrics-endpoint.metadata-default",
|
||||
"source": {
|
||||
"@timestamp": 1579874769541,
|
||||
"agent": {
|
||||
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue