Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution] Use search strategy error in timeline #125178

Merged
merged 6 commits into from
Feb 11, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ const StatefulEventsViewerComponent: React.FC<Props> = ({
const { timelines: timelinesUi } = useKibana().services;
const {
browserFields,
dataViewId,
docValueFields,
indexPattern,
runtimeMappings,
Expand Down Expand Up @@ -189,6 +190,7 @@ const StatefulEventsViewerComponent: React.FC<Props> = ({
bulkActions,
columns,
dataProviders,
dataViewId,
defaultCellActions,
deletedEventIds,
disabledCellActions: FIELDS_WITHOUT_CELL_ACTIONS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ export const EqlTabContentComponent: React.FC<Props> = ({
const { setTimelineFullScreen, timelineFullScreen } = useTimelineFullScreen();
const {
browserFields,
dataViewId,
docValueFields,
loading: loadingSourcerer,
runtimeMappings,
Expand Down Expand Up @@ -208,18 +209,19 @@ export const EqlTabContentComponent: React.FC<Props> = ({

const [isQueryLoading, { events, inspect, totalCount, pageInfo, loadPage, updatedAt, refetch }] =
useTimelineEvents({
dataViewId,
docValueFields,
endDate: end,
eqlOptions: restEqlOption,
fields: getTimelineQueryFields(),
filterQuery: eqlQuery ?? '',
id: timelineId,
indexNames: selectedPatterns,
fields: getTimelineQueryFields(),
language: 'eql',
limit: itemsPerPage,
filterQuery: eqlQuery ?? '',
runtimeMappings,
startDate: start,
skip: !canQueryTimeline(),
startDate: start,
timerangeKind,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ export const PinnedTabContentComponent: React.FC<Props> = ({
const {
browserFields,
docValueFields,
dataViewId,
loading: loadingSourcerer,
runtimeMappings,
selectedPatterns,
Expand Down Expand Up @@ -187,6 +188,7 @@ export const PinnedTabContentComponent: React.FC<Props> = ({
endDate: '',
id: `pinned-${timelineId}`,
indexNames: selectedPatterns,
dataViewId,
fields: timelineQueryFields,
limit: itemsPerPage,
filterQuery,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ export const QueryTabContentComponent: React.FC<Props> = ({
const { setTimelineFullScreen, timelineFullScreen } = useTimelineFullScreen();
const {
browserFields,
dataViewId,
docValueFields,
loading: loadingSourcerer,
indexPattern,
Expand Down Expand Up @@ -282,18 +283,19 @@ export const QueryTabContentComponent: React.FC<Props> = ({

const [isQueryLoading, { events, inspect, totalCount, pageInfo, loadPage, updatedAt, refetch }] =
useTimelineEvents({
dataViewId,
docValueFields,
endDate: end,
fields: getTimelineQueryFields(),
filterQuery: combinedQueries?.filterQuery,
id: timelineId,
indexNames: selectedPatterns,
fields: getTimelineQueryFields(),
language: kqlQuery.language,
limit: itemsPerPage,
filterQuery: combinedQueries?.filterQuery,
runtimeMappings,
startDate: start,
skip: !canQueryTimeline,
sort: timelineQuerySortField,
startDate: start,
timerangeKind,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ describe('useTimelineEvents', () => {
const startDate: string = '2020-07-07T08:20:18.966Z';
const endDate: string = '3000-01-01T00:00:00.000Z';
const props: UseTimelineEventsProps = {
dataViewId: 'data-view-id',
docValueFields: [],
endDate: '',
id: TimelineId.active,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import { Subscription } from 'rxjs';

import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { ESQuery } from '../../../common/typed_json';
import { isCompleteResponse, isErrorResponse } from '../../../../../../src/plugins/data/common';
import {
DataView,
isCompleteResponse,
isErrorResponse,
} from '../../../../../../src/plugins/data/common';

import { useIsExperimentalFeatureEnabled } from '../../common/hooks/use_experimental_features';
import { inputsModel } from '../../common/store';
Expand Down Expand Up @@ -75,6 +79,7 @@ type TimelineResponse<T extends KueryFilterQueryKind> = T extends 'kuery'
: TimelineEventsAllStrategyResponse;

export interface UseTimelineEventsProps {
dataViewId: string | null;
docValueFields?: DocValueFields[];
endDate: string;
eqlOptions?: EqlOptionsSelected;
Expand Down Expand Up @@ -127,6 +132,7 @@ const deStructureEqlOptions = (eqlOptions?: EqlOptionsSelected) => ({
});

export const useTimelineEvents = ({
dataViewId,
docValueFields,
endDate,
eqlOptions = undefined,
Expand Down Expand Up @@ -207,7 +213,7 @@ export const useTimelineEvents = ({
loadPage: wrappedLoadPage,
updatedAt: 0,
});
const { addError, addWarning } = useAppToasts();
const { addWarning } = useAppToasts();

// TODO: Once we are past experimental phase this code should be removed
const ruleRegistryEnabled = useIsExperimentalFeatureEnabled('ruleRegistryEnabled');
Expand All @@ -227,6 +233,8 @@ export const useTimelineEvents = ({
strategy:
request.language === 'eql' ? 'timelineEqlSearchStrategy' : 'timelineSearchStrategy',
abortSignal: abortCtrl.current.signal,
// we only need the id to throw better errors
indexPattern: { id: dataViewId } as unknown as DataView,
})
.subscribe({
next: (response) => {
Expand Down Expand Up @@ -265,9 +273,7 @@ export const useTimelineEvents = ({
},
error: (msg) => {
setLoading(false);
addError(msg, {
title: i18n.FAIL_TIMELINE_EVENTS,
});
data.search.showError(msg);
searchSubscription$.current.unsubscribe();
},
});
Expand Down Expand Up @@ -321,9 +327,9 @@ export const useTimelineEvents = ({
skip,
id,
data.search,
dataViewId,
setUpdated,
addWarning,
addError,
refetchGrid,
wrappedLoadPage,
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,3 @@ export const ERROR_TIMELINE_EVENTS = i18n.translate(
defaultMessage: `An error has occurred on timeline events search`,
}
);

export const FAIL_TIMELINE_EVENTS = i18n.translate(
'xpack.securitySolution.timelineEvents.failSearchDescription',
{
defaultMessage: `Failed to run search on timeline events`,
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,15 @@ export const createSourcererDataViewRoute = (
const siemDataViewTitle = siemDataView ? siemDataView.title.split(',').sort().join() : '';
if (siemDataView == null) {
try {
siemDataView = await dataViewService.createAndSave({
allowNoIndex: true,
id: dataViewId,
title: patternListAsTitle,
timeFieldName: DEFAULT_TIME_FIELD,
});
siemDataView = await dataViewService.createAndSave(
{
allowNoIndex: true,
id: dataViewId,
title: patternListAsTitle,
timeFieldName: DEFAULT_TIME_FIELD,
},
true
);
} catch (err) {
const error = transformError(err);
if (err.name === 'DuplicateDataViewError' || error.statusCode === 409) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export interface TGridIntegratedProps {
createFieldComponent?: CreateFieldComponentType;
data?: DataPublicPluginStart;
dataProviders: DataProvider[];
dataViewId?: string | null;
defaultCellActions?: TGridCellAction[];
deletedEventIds: Readonly<string[]>;
disabledCellActions: string[];
Expand Down Expand Up @@ -145,6 +146,7 @@ const TGridIntegratedComponent: React.FC<TGridIntegratedProps> = ({
columns,
data,
dataProviders,
dataViewId = null,
defaultCellActions,
deletedEventIds,
disabledCellActions,
Expand Down Expand Up @@ -236,6 +238,7 @@ const TGridIntegratedComponent: React.FC<TGridIntegratedProps> = ({
// We rely on entityType to determine Events vs Alerts
alertConsumers: SECURITY_ALERTS_CONSUMERS,
data,
dataViewId,
docValueFields,
endDate: end,
entityType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export interface TGridStandaloneProps {
} | null;
afterCaseSelection?: Function;
columns: ColumnHeaderOptions[];
dataViewId?: string | null;
defaultCellActions?: TGridCellAction[];
deletedEventIds: Readonly<string[]>;
disabledCellActions: string[];
Expand Down Expand Up @@ -130,6 +131,7 @@ const TGridStandaloneComponent: React.FC<TGridStandaloneProps> = ({
casesOwner,
casePermissions,
columns,
dataViewId = null,
defaultCellActions,
deletedEventIds,
disabledCellActions,
Expand Down Expand Up @@ -224,6 +226,7 @@ const TGridStandaloneComponent: React.FC<TGridStandaloneProps> = ({
loading,
{ consumers, events, updatedAt, loadPage, pageInfo, refetch, totalCount = 0, inspect },
] = useTimelineEvents({
dataViewId,
docValueFields: [],
entityType,
excludeEcsData: true,
Expand Down
13 changes: 8 additions & 5 deletions x-pack/plugins/timelines/public/container/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useCallback, useEffect, useRef, useState } from 'react';
import { useDispatch } from 'react-redux';
import { Subscription } from 'rxjs';
import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import type { DataView } from '../../../../../src/plugins/data_views/public';
import {
clearEventsLoading,
clearEventsDeleted,
Expand Down Expand Up @@ -73,6 +74,7 @@ type TimelineResponse<T extends KueryFilterQueryKind> = TimelineEventsAllStrateg
export interface UseTimelineEventsProps {
alertConsumers?: AlertConsumers[];
data?: DataPublicPluginStart;
dataViewId: string | null;
docValueFields?: DocValueFields[];
endDate: string;
entityType: EntityType;
Expand Down Expand Up @@ -117,6 +119,7 @@ export const initSortDefault = [
const NO_CONSUMERS: AlertConsumers[] = [];
export const useTimelineEvents = ({
alertConsumers = NO_CONSUMERS,
dataViewId,
docValueFields,
endDate,
entityType,
Expand Down Expand Up @@ -191,7 +194,7 @@ export const useTimelineEvents = ({
loadPage: wrappedLoadPage,
updatedAt: 0,
});
const { addError, addWarning } = useAppToasts();
const { addWarning } = useAppToasts();

const timelineSearch = useCallback(
(request: TimelineRequest<typeof language> | null) => {
Expand All @@ -213,6 +216,8 @@ export const useTimelineEvents = ({
? 'timelineEqlSearchStrategy'
: 'timelineSearchStrategy',
abortSignal: abortCtrl.current.signal,
// we only need the id to throw better errors
indexPattern: { id: dataViewId } as unknown as DataView,
}
)
.subscribe({
Expand Down Expand Up @@ -242,9 +247,7 @@ export const useTimelineEvents = ({
},
error: (msg) => {
setLoading(false);
addError(msg, {
title: i18n.FAIL_TIMELINE_EVENTS,
});
data.search.showError(msg);
searchSubscription$.current.unsubscribe();
},
});
Expand All @@ -256,7 +259,7 @@ export const useTimelineEvents = ({
asyncSearch();
refetch.current = asyncSearch;
},
[skip, data, entityType, setUpdated, addWarning, addError]
[skip, data, entityType, dataViewId, setUpdated, addWarning]
);

useEffect(() => {
Expand Down
7 changes: 0 additions & 7 deletions x-pack/plugins/timelines/public/container/translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,3 @@ export const ERROR_TIMELINE_EVENTS = i18n.translate(
defaultMessage: `An error has occurred on timeline events search`,
}
);

export const FAIL_TIMELINE_EVENTS = i18n.translate(
'xpack.timelines.timelineEvents.failSearchDescription',
{
defaultMessage: `Failed to run search on timeline events`,
}
);
1 change: 1 addition & 0 deletions x-pack/plugins/timelines/public/mock/t_grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export const tGridIntegratedProps: TGridIntegratedProps = {
browserFields: mockBrowserFields,
columns: columnHeaders,
dataProviders: mockDataProviders,
dataViewId: 'data-view-id',
deletedEventIds: [],
disabledCellActions: [],
docValueFields: mockDocValueFields,
Expand Down