Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ describe('Detection rules, threshold', () => {
waitForAlertsIndexToBeCreated();
});

it.skip('Creates and activates a new threshold rule', () => {
it('Creates and activates a new threshold rule', () => {
goToManageAlertsDetectionRules();
waitForRulesTableToBeLoaded();
goToCreateNewRule();
Expand Down Expand Up @@ -171,9 +171,7 @@ describe('Detection rules, threshold', () => {
waitForAlertsToPopulate();

cy.get(NUMBER_OF_ALERTS).should(($count) => expect(+$count.text().split(' ')[0]).to.be.lt(100));
cy.get(ALERT_GRID_CELL).eq(3).contains(rule.name);
cy.get(ALERT_GRID_CELL).eq(4).contains(rule.severity.toLowerCase());
cy.get(ALERT_GRID_CELL).eq(5).contains(rule.riskScore);
cy.get(ALERT_GRID_CELL).contains(rule.name);
});

it('Preview results of keyword using "host.name"', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ const InvestigateInTimelineActionComponent = (alertIds: string[]) => {
alertIds={alertIds}
key="investigate-in-timeline"
ecsRowData={null}
nonEcsRowData={[]}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ describe('alert actions', () => {
await sendAlertToTimelineAction({
createTimeline,
ecsData: mockEcsDataWithAlert,
nonEcsData: [],
updateTimelineIsLoading,
searchStrategyClient,
});
Expand All @@ -92,7 +91,6 @@ describe('alert actions', () => {
await sendAlertToTimelineAction({
createTimeline,
ecsData: mockEcsDataWithAlert,
nonEcsData: [],
updateTimelineIsLoading,
searchStrategyClient,
});
Expand Down Expand Up @@ -249,7 +247,6 @@ describe('alert actions', () => {
await sendAlertToTimelineAction({
createTimeline,
ecsData: mockEcsDataWithAlert,
nonEcsData: [],
updateTimelineIsLoading,
searchStrategyClient,
});
Expand All @@ -267,7 +264,6 @@ describe('alert actions', () => {
await sendAlertToTimelineAction({
createTimeline,
ecsData: mockEcsDataWithAlert,
nonEcsData: [],
updateTimelineIsLoading,
searchStrategyClient,
});
Expand Down Expand Up @@ -301,7 +297,6 @@ describe('alert actions', () => {
await sendAlertToTimelineAction({
createTimeline,
ecsData: ecsDataMock,
nonEcsData: [],
updateTimelineIsLoading,
searchStrategyClient,
});
Expand All @@ -327,7 +322,6 @@ describe('alert actions', () => {
await sendAlertToTimelineAction({
createTimeline,
ecsData: ecsDataMock,
nonEcsData: [],
updateTimelineIsLoading,
searchStrategyClient,
});
Expand Down Expand Up @@ -357,7 +351,6 @@ describe('alert actions', () => {
await sendAlertToTimelineAction({
createTimeline,
ecsData: ecsDataMock,
nonEcsData: [],
updateTimelineIsLoading,
searchStrategyClient,
});
Expand Down Expand Up @@ -398,7 +391,6 @@ describe('alert actions', () => {
await sendAlertToTimelineAction({
createTimeline,
ecsData: ecsDataMock,
nonEcsData: [],
updateTimelineIsLoading,
searchStrategyClient,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

/* eslint-disable complexity */

import { get, getOr, isEmpty } from 'lodash/fp';
import { getOr, isEmpty } from 'lodash/fp';
import moment from 'moment';

import dateMath from '@elastic/datemath';
Expand Down Expand Up @@ -37,7 +37,6 @@ import {
} from './types';
import { Ecs } from '../../../../common/ecs';
import {
TimelineNonEcsData,
TimelineEventsDetailsItem,
TimelineEventsDetailsRequestOptions,
TimelineEventsDetailsStrategyResponse,
Expand Down Expand Up @@ -75,26 +74,6 @@ export const getUpdateAlertsQuery = (eventIds: Readonly<string[]>) => {
};
};

export const getFilterAndRuleBounds = (
data: TimelineNonEcsData[][]
): [string[], number, number] => {
const stringFilter =
data?.[0].filter(
(d) => d.field === 'signal.rule.filters' || d.field === 'kibana.alert.rule.filters'
)?.[0]?.value ?? [];

const eventTimes = data
.flatMap(
(alert) =>
alert.filter(
(d) => d.field === 'signal.original_time' || d.field === 'kibana.alert.original_time'
)?.[0]?.value ?? []
)
.map((d) => moment(d));

return [stringFilter, moment.min(eventTimes).valueOf(), moment.max(eventTimes).valueOf()];
};

export const updateAlertStatusAction = async ({
query,
alertIds,
Expand Down Expand Up @@ -174,11 +153,7 @@ const getFiltersFromRule = (filters: string[]): Filter[] =>
}
}, [] as Filter[]);

export const getThresholdAggregationData = (
ecsData: Ecs | Ecs[],
nonEcsData: TimelineNonEcsData[]
): ThresholdAggregationData => {
// TODO: AAD fields
export const getThresholdAggregationData = (ecsData: Ecs | Ecs[]): ThresholdAggregationData => {
const thresholdEcsData: Ecs[] = Array.isArray(ecsData) ? ecsData : [ecsData];
return thresholdEcsData.reduce<ThresholdAggregationData>(
(outerAcc, thresholdData) => {
Expand All @@ -195,11 +170,9 @@ export const getThresholdAggregationData = (
};

try {
try {
thresholdResult = JSON.parse((thresholdData.signal?.threshold_result as string[])[0]);
} catch (err) {
thresholdResult = JSON.parse((get(ALERT_THRESHOLD_RESULT, thresholdData) as string[])[0]);
}
thresholdResult = JSON.parse(
(getField(thresholdData, ALERT_THRESHOLD_RESULT) as string[])[0]
);
aggField = JSON.parse(threshold[0]).field;
} catch (err) {
// Legacy support
Expand Down Expand Up @@ -401,7 +374,6 @@ export const buildEqlDataProviderOrFilter = (
export const sendAlertToTimelineAction = async ({
createTimeline,
ecsData: ecs,
nonEcsData,
updateTimelineIsLoading,
searchStrategyClient,
}: SendAlertToTimelineActionProps) => {
Expand Down Expand Up @@ -498,10 +470,7 @@ export const sendAlertToTimelineAction = async ({
}

if (isThresholdRule(ecsData)) {
const { thresholdFrom, thresholdTo, dataProviders } = getThresholdAggregationData(
ecsData,
nonEcsData
);
const { thresholdFrom, thresholdTo, dataProviders } = getThresholdAggregationData(ecsData);

return createTimeline({
from: thresholdFrom,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import React from 'react';

import { Ecs } from '../../../../../common/ecs';
import { TimelineNonEcsData } from '../../../../../common/search_strategy/timeline';
import { ActionIconItem } from '../../../../timelines/components/timeline/body/actions/action_icon_item';

import {
Expand All @@ -19,7 +18,6 @@ import { useInvestigateInTimeline } from './use_investigate_in_timeline';

interface InvestigateInTimelineActionProps {
ecsRowData?: Ecs | Ecs[] | null;
nonEcsRowData?: TimelineNonEcsData[];
ariaLabel?: string;
alertIds?: string[];
buttonType?: 'text' | 'icon';
Expand All @@ -30,13 +28,11 @@ const InvestigateInTimelineActionComponent: React.FC<InvestigateInTimelineAction
ariaLabel = ACTION_INVESTIGATE_IN_TIMELINE_ARIA_LABEL,
alertIds,
ecsRowData,
nonEcsRowData,
buttonType,
onInvestigateInTimelineAlertClick,
}) => {
const { investigateInTimelineAlertClick } = useInvestigateInTimeline({
ecsRowData,
nonEcsRowData,
alertIds,
onInvestigateInTimelineAlertClick,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ interface UseInvestigateInTimelineActionProps {

export const useInvestigateInTimeline = ({
ecsRowData,
nonEcsRowData,
alertIds,
onInvestigateInTimelineAlertClick,
}: UseInvestigateInTimelineActionProps) => {
Expand Down Expand Up @@ -90,7 +89,6 @@ export const useInvestigateInTimeline = ({
await sendAlertToTimelineAction({
createTimeline,
ecsData: alertsEcsData,
nonEcsData: nonEcsRowData ?? [],
searchStrategyClient,
updateTimelineIsLoading,
});
Expand All @@ -100,7 +98,6 @@ export const useInvestigateInTimeline = ({
await sendAlertToTimelineAction({
createTimeline,
ecsData: ecsRowData,
nonEcsData: nonEcsRowData ?? [],
searchStrategyClient,
updateTimelineIsLoading,
});
Expand All @@ -109,7 +106,6 @@ export const useInvestigateInTimeline = ({
alertsEcsData,
createTimeline,
ecsRowData,
nonEcsRowData,
onInvestigateInTimelineAlertClick,
searchStrategyClient,
updateTimelineIsLoading,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import { ISearchStart } from '../../../../../../../src/plugins/data/public';
import { Status } from '../../../../common/detection_engine/schemas/common/schemas';
import { Ecs } from '../../../../common/ecs';
import { TimelineNonEcsData } from '../../../../common/search_strategy/timeline';
import { NoteResult } from '../../../../common/types/timeline/note';
import { DataProvider } from '../../../timelines/components/timeline/data_providers/data_provider';
import { TimelineModel } from '../../../timelines/store/timeline/model';
Expand Down Expand Up @@ -54,7 +53,6 @@ export interface UpdateAlertStatusActionProps {
export interface SendAlertToTimelineActionProps {
createTimeline: CreateTimeline;
ecsData: Ecs | Ecs[];
nonEcsData: TimelineNonEcsData[];
updateTimelineIsLoading: UpdateTimelineLoading;
searchStrategyClient: ISearchStart;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export const RuleSchema = t.intersection([
timestamp_override,
note: t.string,
exceptions_list: listArray,
uuid: t.string,
version: t.number,
}),
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,13 @@ interface AlertHit {
_index: string;
_source: {
'@timestamp': string;
signal: {
rule: Rule;
signal?: {
rule?: Rule;
};
kibana?: {
alert?: {
rule?: Rule;
};
};
};
}
Expand Down Expand Up @@ -77,7 +82,10 @@ export const useRuleWithFallback = (ruleId: string): UseRuleWithFallback => {
}, [addError, error]);

const rule = useMemo<Rule | undefined>(() => {
const result = isExistingRule ? ruleData : alertsData?.hits.hits[0]?._source.signal.rule;
const hit = alertsData?.hits.hits[0];
const result = isExistingRule
? ruleData
: hit?._source.signal?.rule ?? hit?._source.kibana?.alert?.rule;
if (result) {
return transformInput(result);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ const ActionsComponent: React.FC<ActionProps> = ({
ariaLabel={i18n.SEND_ALERT_TO_TIMELINE_FOR_ROW({ ariaRowindex, columnValues })}
key="investigate-in-timeline"
ecsRowData={ecsData}
nonEcsRowData={data}
/>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
ALERT_ANCESTORS,
ALERT_DEPTH,
ALERT_ORIGINAL_TIME,
ALERT_THRESHOLD_RESULT,
ALERT_ORIGINAL_EVENT,
} from '../../../../../../common/field_maps/field_names';

Expand All @@ -59,10 +60,10 @@ export const buildParent = (doc: SimpleHit): Ancestor => {
id: doc._id,
type: isSignal ? 'signal' : 'event',
index: doc._index,
depth: isSignal ? getField(doc, 'signal.depth') ?? 1 : 0,
depth: isSignal ? getField(doc, ALERT_DEPTH) ?? 1 : 0,
};
if (isSignal) {
parent.rule = getField(doc, 'signal.rule.id');
parent.rule = getField(doc, ALERT_RULE_UUID);
}
return parent;
};
Expand All @@ -73,9 +74,8 @@ export const buildParent = (doc: SimpleHit): Ancestor => {
* @param doc The parent event for which to extend the ancestry.
*/
export const buildAncestors = (doc: SimpleHit): Ancestor[] => {
// TODO: handle alerts-on-legacy-alerts
const newAncestor = buildParent(doc);
const existingAncestors: Ancestor[] = getField(doc, 'signal.ancestors') ?? [];
const existingAncestors: Ancestor[] = getField(doc, ALERT_ANCESTORS) ?? [];
return [...existingAncestors, newAncestor];
};

Expand Down Expand Up @@ -130,7 +130,7 @@ export const additionalAlertFields = (doc: BaseSignalHit) => {
});
const additionalFields: Record<string, unknown> = {
[ALERT_ORIGINAL_TIME]: originalTime != null ? originalTime.toISOString() : undefined,
...(thresholdResult != null ? { threshold_result: thresholdResult } : {}),
...(thresholdResult != null ? { [ALERT_THRESHOLD_RESULT]: thresholdResult } : {}),
};

for (const [key, val] of Object.entries(doc._source ?? {})) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@
* 2.0.
*/

import { ALERT_THRESHOLD_RESULT } from '../../../../../../common/field_maps/field_names';
import { SignalSourceHit } from '../../../signals/types';
import { RACAlert } from '../../types';

export const filterSource = (doc: SignalSourceHit): Partial<RACAlert> => {
const docSource = doc._source ?? {};
const {
event,
threshold_result: thresholdResult,
threshold_result: siemSignalsThresholdResult,
[ALERT_THRESHOLD_RESULT]: alertThresholdResult,
...filteredSource
} = docSource || {
event: null,
threshold_result: null,
[ALERT_THRESHOLD_RESULT]: null,
};

return filteredSource;
Expand Down
Loading