diff --git a/x-pack/legacy/plugins/siem/public/components/alerts_viewer/index.tsx b/x-pack/legacy/plugins/siem/public/components/alerts_viewer/index.tsx index c8f1bb2278917..9e0207cf306ee 100644 --- a/x-pack/legacy/plugins/siem/public/components/alerts_viewer/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/alerts_viewer/index.tsx @@ -3,57 +3,74 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - import { noop } from 'lodash/fp'; -import React from 'react'; - +import React, { useEffect, useCallback } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import { manageQuery } from '../page/manage_query'; -import { AlertsOverTimeHistogram } from '../page/hosts/alerts_over_time'; + import { AlertsComponentsQueryProps } from './types'; -import { AlertsOverTimeQuery } from '../../containers/alerts/alerts_over_time'; -import { hostsModel } from '../../store/model'; import { AlertsTable } from './alerts_table'; +import * as i18n from './translations'; +import { MatrixHistogramOption } from '../matrix_histogram/types'; +import { MatrixHistogramContainer } from '../../containers/matrix_histogram'; +import { MatrixHistogramGqlQuery } from '../../containers/matrix_histogram/index.gql_query'; +const ID = 'alertsOverTimeQuery'; +const alertsStackByOptions: MatrixHistogramOption[] = [ + { + text: i18n.ALERTS_STACK_BY_MODULE, + value: 'event.module', + }, +]; +const dataKey = 'AlertsHistogram'; -const AlertsOverTimeManage = manageQuery(AlertsOverTimeHistogram); export const AlertsView = ({ - defaultFilters, deleteQuery, endDate, filterQuery, pageFilters, - skip, setQuery, + skip, startDate, type, updateDateRange = noop, -}: AlertsComponentsQueryProps) => ( - <> - - {({ alertsOverTime, loading, id, inspect, refetch, totalCount }) => ( - - )} - - - - -); +}: AlertsComponentsQueryProps) => { + useEffect(() => { + return () => { + if (deleteQuery) { + deleteQuery({ id: ID }); + } + }; + }, []); + + const getSubtitle = useCallback( + (totalCount: number) => `${i18n.SHOWING}: ${totalCount} ${i18n.UNIT(totalCount)}`, + [] + ); + return ( + <> + + + + + ); +}; AlertsView.displayName = 'AlertsView'; diff --git a/x-pack/legacy/plugins/siem/public/components/alerts_viewer/translations.ts b/x-pack/legacy/plugins/siem/public/components/alerts_viewer/translations.ts index 987665c9413e3..0c709e59ed428 100644 --- a/x-pack/legacy/plugins/siem/public/components/alerts_viewer/translations.ts +++ b/x-pack/legacy/plugins/siem/public/components/alerts_viewer/translations.ts @@ -6,14 +6,38 @@ import { i18n } from '@kbn/i18n'; -export const ALERTS_DOCUMENT_TYPE = i18n.translate('xpack.siem.hosts.alertsDocumentType', { +export const ALERTS_DOCUMENT_TYPE = i18n.translate('xpack.siem.alertsView.alertsDocumentType', { defaultMessage: 'Alerts', }); -export const TOTAL_COUNT_OF_ALERTS = i18n.translate('xpack.siem.hosts.totalCountOfAlerts', { +export const TOTAL_COUNT_OF_ALERTS = i18n.translate('xpack.siem.alertsView.totalCountOfAlerts', { defaultMessage: 'alerts match the search criteria', }); -export const ALERTS_TABLE_TITLE = i18n.translate('xpack.siem.hosts.alertsDocumentType', { +export const ALERTS_TABLE_TITLE = i18n.translate('xpack.siem.alertsView.alertsDocumentType', { defaultMessage: 'Alerts', }); + +export const ALERTS_STACK_BY_MODULE = i18n.translate( + 'xpack.siem.alertsView.alertsStackByOptions.module', + { + defaultMessage: 'module', + } +); + +export const SHOWING = i18n.translate('xpack.siem.alertsView.showing', { + defaultMessage: 'Showing', +}); + +export const UNIT = (totalCount: number) => + i18n.translate('xpack.siem.alertsView.unit', { + values: { totalCount }, + defaultMessage: `{totalCount, plural, =1 {alert} other {alerts}}`, + }); + +export const ERROR_FETCHING_ALERTS_DATA = i18n.translate( + 'xpack.siem.alertsView.errorFetchingAlertsData', + { + defaultMessage: 'Failed to query alerts data', + } +); diff --git a/x-pack/legacy/plugins/siem/public/components/alerts_viewer/types.ts b/x-pack/legacy/plugins/siem/public/components/alerts_viewer/types.ts index 8a17c1102e776..004e01f3f6659 100644 --- a/x-pack/legacy/plugins/siem/public/components/alerts_viewer/types.ts +++ b/x-pack/legacy/plugins/siem/public/components/alerts_viewer/types.ts @@ -7,6 +7,7 @@ import { esFilters } from '../../../../../../../src/plugins/data/common'; import { HostsComponentsQueryProps } from '../../pages/hosts/navigation/types'; import { NetworkComponentQueryProps } from '../../pages/network/navigation/types'; +import { MatrixHistogramOption } from '../matrix_histogram/types'; type CommonQueryProps = HostsComponentsQueryProps | NetworkComponentQueryProps; export interface AlertsComponentsQueryProps @@ -22,5 +23,7 @@ export interface AlertsComponentsQueryProps | 'updateDateRange' > { pageFilters: esFilters.Filter[]; + stackByOptions?: MatrixHistogramOption[]; defaultFilters?: esFilters.Filter[]; + defaultStackByOption?: MatrixHistogramOption; } diff --git a/x-pack/legacy/plugins/siem/public/components/anomalies_over_time/index.tsx b/x-pack/legacy/plugins/siem/public/components/anomalies_over_time/index.tsx deleted file mode 100644 index 2337f2cd7512a..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/anomalies_over_time/index.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; - -import { MatrixHistogramBasicProps } from '../matrix_histogram/types'; -import { MatrixOverTimeHistogramData } from '../../graphql/types'; -import { MatrixHistogram } from '../matrix_histogram'; -import * as i18n from './translation'; - -export const AnomaliesOverTimeHistogram = ( - props: MatrixHistogramBasicProps -) => { - const dataKey = 'anomaliesOverTime'; - const { totalCount } = props; - const subtitle = `${i18n.SHOWING}: ${totalCount.toLocaleString()} ${i18n.UNIT(totalCount)}`; - const { ...matrixOverTimeProps } = props; - - return ( - - ); -}; diff --git a/x-pack/legacy/plugins/siem/public/components/anomalies_over_time/translation.ts b/x-pack/legacy/plugins/siem/public/components/anomalies_over_time/translation.ts deleted file mode 100644 index f28a7176fd09d..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/anomalies_over_time/translation.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; - -export const ANOMALIES_COUNT_FREQUENCY_BY_ACTION = i18n.translate( - 'xpack.siem.anomaliesOverTime.anomaliesCountFrequencyByJobTile', - { - defaultMessage: 'Anomalies count by job', - } -); - -export const SHOWING = i18n.translate('xpack.siem.anomaliesOverTime.showing', { - defaultMessage: 'Showing', -}); - -export const UNIT = (totalCount: number) => - i18n.translate('xpack.siem.anomaliesOverTime.unit', { - values: { totalCount }, - defaultMessage: `{totalCount, plural, =1 {anomaly} other {anomalies}}`, - }); diff --git a/x-pack/legacy/plugins/siem/public/components/charts/common.tsx b/x-pack/legacy/plugins/siem/public/components/charts/common.tsx index 78cce72f0a0d3..62f1ac56890ca 100644 --- a/x-pack/legacy/plugins/siem/public/components/charts/common.tsx +++ b/x-pack/legacy/plugins/siem/public/components/charts/common.tsx @@ -14,6 +14,7 @@ import { ScaleType, SettingsSpecProps, TickFormatter, + Position, } from '@elastic/charts'; import styled from 'styled-components'; import { useUiSetting } from '../../lib/kibana'; @@ -35,6 +36,7 @@ export interface ChartData { export interface ChartSeriesConfigs { customHeight?: number; + customSeriesColors?: string[]; series?: { xScaleType?: ScaleType | undefined; yScaleType?: ScaleType | undefined; @@ -105,6 +107,7 @@ export const chartDefaultSettings = { showLegend: false, showLegendDisplayValue: false, debug: false, + legendPosition: Position.Bottom, }; export const getChartHeight = (customHeight?: number, autoSizerHeight?: number): string => { diff --git a/x-pack/legacy/plugins/siem/public/components/matrix_histogram/index.test.tsx b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/index.test.tsx index 78a4c967ee0bb..a44efed47372d 100644 --- a/x-pack/legacy/plugins/siem/public/components/matrix_histogram/index.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/index.test.tsx @@ -10,6 +10,7 @@ import { shallow } from 'enzyme'; import React from 'react'; import { MatrixHistogram } from '.'; +import { MatrixHistogramGqlQuery as mockQuery } from '../../containers/matrix_histogram/index.gql_query'; jest.mock('../../lib/kibana'); @@ -31,18 +32,27 @@ jest.mock('../charts/barchart', () => { }; }); -describe('Load More Events Table Component', () => { +describe('Matrix Histogram Component', () => { const mockMatrixOverTimeHistogramProps = { - data: [], dataKey: 'mockDataKey', + defaultIndex: ['defaultIndex'], + defaultStackByOption: { text: 'text', value: 'value' }, endDate: new Date('2019-07-18T20:00:00.000Z').valueOf(), + errorMessage: 'error', id: 'mockId', - loading: true, - updateDateRange: () => {}, + isInspected: false, + isPtrIncluded: false, + query: mockQuery, + setQuery: jest.fn(), + skip: false, + sourceId: 'default', + stackByField: 'mockStackByField', + stackByOptions: [{ text: 'text', value: 'value' }], startDate: new Date('2019-07-18T19:00: 00.000Z').valueOf(), subtitle: 'mockSubtitle', totalCount: -1, title: 'mockTitle', + updateDateRange: jest.fn(), }; describe('rendering', () => { test('it renders EuiLoadingContent on initialLoad', () => { diff --git a/x-pack/legacy/plugins/siem/public/components/matrix_histogram/index.tsx b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/index.tsx index 94c05d00d5462..1049ef9248494 100644 --- a/x-pack/legacy/plugins/siem/public/components/matrix_histogram/index.tsx +++ b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/index.tsx @@ -4,38 +4,65 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { ScaleType } from '@elastic/charts'; import darkTheme from '@elastic/eui/dist/eui_theme_dark.json'; import lightTheme from '@elastic/eui/dist/eui_theme_light.json'; -import { EuiLoadingContent } from '@elastic/eui'; +import { EuiLoadingContent, EuiSelect } from '@elastic/eui'; +import { noop } from 'lodash/fp'; +import * as i18n from './translations'; import { BarChart } from '../charts/barchart'; import { HeaderSection } from '../header_section'; -import { ChartSeriesData } from '../charts/common'; import { DEFAULT_DARK_MODE } from '../../../common/constants'; import { useUiSetting$ } from '../../lib/kibana'; import { Loader } from '../loader'; import { Panel } from '../panel'; +import { getBarchartConfigs, getCustomChartData } from '../../components/matrix_histogram/utils'; +import { useQuery } from '../../containers/matrix_histogram/utils'; +import { + MatrixHistogramProps, + MatrixHistogramOption, + HistogramAggregation, + MatrixHistogramQueryProps, +} from './types'; +import { generateTablePaginationOptions } from '../paginated_table/helpers'; +import { ChartSeriesData } from '../charts/common'; import { InspectButtonContainer } from '../inspect'; -import { getBarchartConfigs, getCustomChartData } from './utils'; -import { MatrixHistogramProps, MatrixHistogramDataTypes } from './types'; -export const MatrixHistogramComponent: React.FC> = ({ - data, +export const MatrixHistogramComponent: React.FC = ({ + activePage, + dataKey, + defaultStackByOption, endDate, + errorMessage, + filterQuery, + hideHistogramIfEmpty = false, id, - loading, + isAlertsHistogram, + isAnomaliesHistogram, + isAuthenticationsHistogram, + isDNSHistogram, + isEventsType, + isPtrIncluded, + isInspected, + legendPosition, + limit, mapping, + query, scaleType = ScaleType.Time, + setQuery, + showLegend, + skip, + stackByOptions, startDate, subtitle, title, - totalCount, updateDateRange, yTickFormatter, - showLegend, + sort, }) => { const barchartConfigs = getBarchartConfigs({ from: startDate, @@ -44,24 +71,117 @@ export const MatrixHistogramComponent: React.FC(DEFAULT_DARK_MODE); - const [loadingInitial, setLoadingInitial] = useState(false); - const barChartData: ChartSeriesData[] = getCustomChartData(data, mapping); + const handleOnMouseEnter = useCallback(() => { + if (!showInspect) { + setShowInspect(true); + } + }, [showInspect, setShowInspect]); + const handleOnMouseLeave = useCallback(() => { + if (showInspect) { + setShowInspect(false); + } + }, [showInspect, setShowInspect]); + + const [selectedStackByOption, setSelectedStackByOption] = useState( + defaultStackByOption + ); + const [subtitleWithCounts, setSubtitle] = useState(''); + const [hideHistogram, setHideHistogram] = useState(hideHistogramIfEmpty); + const [barChartData, setBarChartData] = useState(null); + const setSelectedChartOptionCallback = useCallback( + (event: React.ChangeEvent) => { + setSelectedStackByOption( + stackByOptions?.find(co => co.value === event.target.value) ?? defaultStackByOption + ); + }, + [] + ); + const getPagination = () => + activePage != null && limit != null + ? generateTablePaginationOptions(activePage, limit) + : undefined; + + const { data, loading, inspect, totalCount, refetch = noop } = useQuery<{}, HistogramAggregation>( + { + dataKey, + endDate, + errorMessage, + filterQuery, + query, + skip, + startDate, + sort, + title, + isAlertsHistogram, + isAnomaliesHistogram, + isAuthenticationsHistogram, + isDNSHistogram, + isEventsType, + isInspected, + isPtrIncluded, + pagination: useMemo(() => getPagination(), [activePage, limit]), + stackByField: selectedStackByOption.value, + } + ); useEffect(() => { - if (totalCount >= 0 && loadingInitial) { - setLoadingInitial(false); + if (subtitle != null) + setSubtitle(typeof subtitle === 'function' ? subtitle(totalCount) : subtitle); + + if (totalCount <= 0) { + if (hideHistogramIfEmpty) { + setHideHistogram(true); + } else { + setHideHistogram(false); + } + } else { + setHideHistogram(false); } - }, [loading, loadingInitial, totalCount]); - return ( - - - + setBarChartData(getCustomChartData(data, mapping)); - {loadingInitial ? ( + setQuery({ id, inspect, loading, refetch }); + }, [ + subtitle, + setSubtitle, + setHideHistogram, + setBarChartData, + setQuery, + hideHistogramIfEmpty, + totalCount, + isInspected, + loading, + data, + ]); + + return !hideHistogram ? ( + + + = 0 ? subtitleWithCounts : null)} + > + {stackByOptions && ( + + )} + + {loading ? ( ) : ( <> @@ -80,7 +200,7 @@ export const MatrixHistogramComponent: React.FC - ); + ) : null; }; export const MatrixHistogram = React.memo(MatrixHistogramComponent); diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/dns_histogram/translation.ts b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/translations.ts similarity index 65% rename from x-pack/legacy/plugins/siem/public/components/page/network/dns_histogram/translation.ts rename to x-pack/legacy/plugins/siem/public/components/matrix_histogram/translations.ts index bb822651f10ce..345eb7e937bed 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/network/dns_histogram/translation.ts +++ b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/translations.ts @@ -6,6 +6,9 @@ import { i18n } from '@kbn/i18n'; -export const NETWORK_DNS_HISTOGRAM = i18n.translate('xpack.siem.DNS.histogramTitle', { - defaultMessage: 'Top DNS domains bytes count', -}); +export const STACK_BY = i18n.translate( + 'xpack.siem.components.histogram.stackByOptions.stackByLabel', + { + defaultMessage: 'Stack by', + } +); diff --git a/x-pack/legacy/plugins/siem/public/components/matrix_histogram/types.ts b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/types.ts index edcd8e3cb9d5c..39a16b6c1b3d1 100644 --- a/x-pack/legacy/plugins/siem/public/components/matrix_histogram/types.ts +++ b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/types.ts @@ -4,29 +4,119 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ScaleType } from '@elastic/charts'; -import { MatrixOverTimeHistogramData, MatrixOverOrdinalHistogramData } from '../../graphql/types'; -import { AuthMatrixDataFields } from '../page/hosts/authentications_over_time/utils'; +import { ScaleType, Position } from '@elastic/charts'; +import { SetStateAction } from 'react'; +import { DocumentNode } from 'graphql'; +import { + MatrixOverTimeHistogramData, + MatrixOverOrdinalHistogramData, + NetworkDnsSortField, + PaginationInputPaginated, +} from '../../graphql/types'; import { UpdateDateRange } from '../charts/common'; +import { ESQuery } from '../../../common/typed_json'; +import { SetQuery } from '../../pages/hosts/navigation/types'; export type MatrixHistogramDataTypes = MatrixOverTimeHistogramData | MatrixOverOrdinalHistogramData; -export type MatrixHistogramMappingTypes = AuthMatrixDataFields; -export interface MatrixHistogramBasicProps { - data: T[]; +export type MatrixHistogramMappingTypes = Record< + string, + { key: string; value: null; color?: string | undefined } +>; +export interface MatrixHistogramOption { + text: string; + value: string; +} + +export type GetSubTitle = (count: number) => string; +export interface MatrixHistogramBasicProps { + defaultIndex: string[]; + defaultStackByOption: MatrixHistogramOption; endDate: number; + hideHistogramIfEmpty?: boolean; id: string; - loading: boolean; mapping?: MatrixHistogramMappingTypes; + setQuery: SetQuery; + sourceId: string; startDate: number; - totalCount: number; + stackByOptions: MatrixHistogramOption[]; + subtitle?: string | GetSubTitle; + title?: string; updateDateRange: UpdateDateRange; } -export interface MatrixHistogramProps extends MatrixHistogramBasicProps { - dataKey?: string; +export interface MatrixHistogramQueryProps { + activePage?: number; + dataKey: string; + endDate: number; + errorMessage: string; + filterQuery?: ESQuery | string | undefined; + limit?: number; + query: DocumentNode; + sort?: NetworkDnsSortField; + stackByField: string; + skip: boolean; + startDate: number; + title: string; + isAlertsHistogram?: boolean; + isAnomaliesHistogram?: boolean; + isAuthenticationsHistogram?: boolean; + isDNSHistogram?: boolean; + isEventsType?: boolean; + isInspected: boolean; + isPtrIncluded?: boolean; + pagination?: PaginationInputPaginated; +} + +export interface MatrixHistogramProps extends MatrixHistogramBasicProps { scaleType?: ScaleType; - subtitle?: string; - title?: string; yTickFormatter?: (value: number) => string; showLegend?: boolean; + legendPosition?: Position; +} + +export interface HistogramBucket { + key_as_string: string; + key: number; + doc_count: number; +} +export interface GroupBucket { + key: string; + signals: { + buckets: HistogramBucket[]; + }; } + +export interface HistogramAggregation { + histogramAgg: { + buckets: GroupBucket[]; + }; +} + +export interface SignalsResponse { + took: number; + timeout: boolean; +} + +export interface SignalSearchResponse + extends SignalsResponse { + _shards: { + total: number; + successful: number; + skipped: number; + failed: number; + }; + aggregations?: Aggregations; + hits: { + total: { + value: number; + relation: string; + }; + hits: Hit[]; + }; +} + +export type Return = [ + boolean, + SignalSearchResponse | null, + React.Dispatch> +]; diff --git a/x-pack/legacy/plugins/siem/public/components/matrix_histogram/utils.ts b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/utils.ts index a7ef71f7a6a0d..5d79bbc0ceb23 100644 --- a/x-pack/legacy/plugins/siem/public/components/matrix_histogram/utils.ts +++ b/x-pack/legacy/plugins/siem/public/components/matrix_histogram/utils.ts @@ -3,7 +3,6 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - import { ScaleType, niceTimeFormatter, Position } from '@elastic/charts'; import { get, groupBy, map, toPairs } from 'lodash/fp'; @@ -17,6 +16,7 @@ export const getBarchartConfigs = ({ onBrushEnd, yTickFormatter, showLegend, + legendPosition, }: { from: number; to: number; @@ -24,6 +24,7 @@ export const getBarchartConfigs = ({ onBrushEnd: UpdateDateRange; yTickFormatter?: (value: number) => string; showLegend?: boolean; + legendPosition?: Position; }) => ({ series: { xScaleType: scaleType || ScaleType.Time, @@ -39,7 +40,7 @@ export const getBarchartConfigs = ({ tickSize: 8, }, settings: { - legendPosition: Position.Bottom, + legendPosition: legendPosition || Position.Bottom, onBrushEnd, showLegend: showLegend || true, theme: { @@ -72,18 +73,18 @@ export const formatToChartDataItem = ([key, value]: [ }); export const getCustomChartData = ( - data: MatrixHistogramDataTypes[], + data: MatrixHistogramDataTypes[] | null, mapping?: MatrixHistogramMappingTypes ): ChartSeriesData[] => { + if (!data) return []; const dataGroupedByEvent = groupBy('g', data); const dataGroupedEntries = toPairs(dataGroupedByEvent); const formattedChartData = map(formatToChartDataItem, dataGroupedEntries); if (mapping) return map((item: ChartSeriesData) => { - const customColor = get(`${item.key}.color`, mapping); - item.color = customColor; - return item; + const mapItem = get(item.key, mapping); + return { ...item, color: mapItem.color }; }, formattedChartData); else return formattedChartData; }; diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/alerts_over_time/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/hosts/alerts_over_time/index.tsx deleted file mode 100644 index 031e1cd767be8..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/alerts_over_time/index.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; - -import * as i18n from './translation'; -import { MatrixHistogram } from '../../../matrix_histogram'; -import { MatrixHistogramBasicProps } from '../../../matrix_histogram/types'; -import { MatrixOverTimeHistogramData } from '../../../../graphql/types'; - -export const AlertsOverTimeHistogram = ( - props: MatrixHistogramBasicProps -) => { - const dataKey = 'alertsOverTime'; - const { totalCount } = props; - const subtitle = `${i18n.SHOWING}: ${totalCount.toLocaleString()} ${i18n.UNIT(totalCount)}`; - const { ...matrixOverTimeProps } = props; - - return ( - - ); -}; diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/alerts_over_time/translation.ts b/x-pack/legacy/plugins/siem/public/components/page/hosts/alerts_over_time/translation.ts deleted file mode 100644 index 380ca0cd3baaf..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/alerts_over_time/translation.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; - -export const ALERTS_COUNT_FREQUENCY_BY_MODULE = i18n.translate( - 'xpack.siem.alertsOverTime.alertsCountFrequencyByModuleTitle', - { - defaultMessage: 'Alerts count by module', - } -); - -export const SHOWING = i18n.translate('xpack.siem.alertsOverTime.showing', { - defaultMessage: 'Showing', -}); - -export const UNIT = (totalCount: number) => - i18n.translate('xpack.siem.alertsOverTime.unit', { - values: { totalCount }, - defaultMessage: `{totalCount, plural, =1 {alert} other {alerts}}`, - }); diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_over_time/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_over_time/index.tsx deleted file mode 100644 index f9e63ee60da5b..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_over_time/index.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; - -import * as i18n from './translation'; -import { MatrixHistogram } from '../../../matrix_histogram'; -import { MatrixHistogramBasicProps } from '../../../matrix_histogram/types'; -import { MatrixOverTimeHistogramData } from '../../../../graphql/types'; -import { authMatrixDataMappingFields } from './utils'; - -export const AuthenticationsOverTimeHistogram = ( - props: MatrixHistogramBasicProps -) => { - const dataKey = 'authenticationsOverTime'; - const { data, ...matrixOverTimeProps } = props; - - return ( - - ); -}; diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_over_time/translation.ts b/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_over_time/translation.ts deleted file mode 100644 index c9a21bd348caa..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_over_time/translation.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; - -export const AUTHENTICATIONS_COUNT = i18n.translate( - 'xpack.siem.authenticationsOverTime.authenticationCountTitle', - { - defaultMessage: 'Authentications count', - } -); - -export const UNIT = (totalCount: number) => - i18n.translate('xpack.siem.authenticationsOverTime.unit', { - values: { totalCount }, - defaultMessage: `{totalCount, plural, =1 {authentication} other {authentications}}`, - }); diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_over_time/utils.ts b/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_over_time/utils.ts deleted file mode 100644 index e0e2d21b40446..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/authentications_over_time/utils.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { ChartSeriesData } from '../../../charts/common'; -import { KpiHostsChartColors } from '../kpi_hosts/types'; - -enum AuthMatrixDataGroup { - authSuccess = 'authentication_success', - authFailure = 'authentication_failure', -} - -export interface AuthMatrixDataFields { - [AuthMatrixDataGroup.authSuccess]: ChartSeriesData; - [AuthMatrixDataGroup.authFailure]: ChartSeriesData; -} - -export const authMatrixDataMappingFields: AuthMatrixDataFields = { - [AuthMatrixDataGroup.authSuccess]: { - key: AuthMatrixDataGroup.authSuccess, - value: null, - color: KpiHostsChartColors.authSuccess, - }, - [AuthMatrixDataGroup.authFailure]: { - key: AuthMatrixDataGroup.authFailure, - value: null, - color: KpiHostsChartColors.authFailure, - }, -}; diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/events_over_time/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/hosts/events_over_time/index.tsx deleted file mode 100644 index 8273ecffdf9b3..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/events_over_time/index.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; - -import * as i18n from './translation'; -import { MatrixHistogram } from '../../../matrix_histogram'; -import { MatrixHistogramBasicProps } from '../../../matrix_histogram/types'; -import { MatrixOverTimeHistogramData } from '../../../../graphql/types'; - -export const EventsOverTimeHistogram = ( - props: MatrixHistogramBasicProps -) => { - const dataKey = 'eventsOverTime'; - const { totalCount } = props; - const subtitle = `${i18n.SHOWING}: ${totalCount.toLocaleString()} ${i18n.UNIT(totalCount)}`; - const { ...matrixOverTimeProps } = props; - - return ( - - ); -}; diff --git a/x-pack/legacy/plugins/siem/public/components/page/hosts/events_over_time/translation.ts b/x-pack/legacy/plugins/siem/public/components/page/hosts/events_over_time/translation.ts deleted file mode 100644 index edc9f97193840..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/page/hosts/events_over_time/translation.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; - -export const EVENT_COUNT_FREQUENCY_BY_ACTION = i18n.translate( - 'xpack.siem.eventsOverTime.eventCountFrequencyByActionTitle', - { - defaultMessage: 'Event count by action', - } -); - -export const SHOWING = i18n.translate('xpack.siem.eventsOverTime.showing', { - defaultMessage: 'Showing', -}); - -export const UNIT = (totalCount: number) => - i18n.translate('xpack.siem.eventsOverTime.unit', { - values: { totalCount }, - defaultMessage: `{totalCount, plural, =1 {event} other {events}}`, - }); diff --git a/x-pack/legacy/plugins/siem/public/components/page/manage_query.tsx b/x-pack/legacy/plugins/siem/public/components/page/manage_query.tsx index fd38850bad5da..3274bc485d6cd 100644 --- a/x-pack/legacy/plugins/siem/public/components/page/manage_query.tsx +++ b/x-pack/legacy/plugins/siem/public/components/page/manage_query.tsx @@ -8,18 +8,14 @@ import { omit } from 'lodash/fp'; import React from 'react'; import { inputsModel } from '../../store'; +import { SetQuery } from '../../pages/hosts/navigation/types'; interface OwnProps { deleteQuery?: ({ id }: { id: string }) => void; id: string; loading: boolean; refetch: inputsModel.Refetch; - setQuery: (params: { - id: string; - inspect: inputsModel.InspectQuery | null; - loading: boolean; - refetch: inputsModel.Refetch; - }) => void; + setQuery: SetQuery; inspect?: inputsModel.InspectQuery; } diff --git a/x-pack/legacy/plugins/siem/public/components/page/network/dns_histogram/index.tsx b/x-pack/legacy/plugins/siem/public/components/page/network/dns_histogram/index.tsx deleted file mode 100644 index e7b0d8e7d00d5..0000000000000 --- a/x-pack/legacy/plugins/siem/public/components/page/network/dns_histogram/index.tsx +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import React from 'react'; - -import { ScaleType } from '@elastic/charts'; -import * as i18n from './translation'; -import { MatrixHistogram } from '../../../matrix_histogram'; -import { MatrixOverOrdinalHistogramData } from '../../../../graphql/types'; -import { MatrixHistogramBasicProps } from '../../../matrix_histogram/types'; -import { useFormatBytes } from '../../../formatted_bytes'; - -export const NetworkDnsHistogram = ( - props: MatrixHistogramBasicProps -) => { - const dataKey = 'histogram'; - const { ...matrixOverTimeProps } = props; - const formatBytes = useFormatBytes(); - - return ( - - ); -}; diff --git a/x-pack/legacy/plugins/siem/public/containers/alerts/alerts_over_time/alerts_over_time.gql_query.ts b/x-pack/legacy/plugins/siem/public/containers/alerts/alerts_over_time/alerts_over_time.gql_query.ts deleted file mode 100644 index 428cf25ea1b8e..0000000000000 --- a/x-pack/legacy/plugins/siem/public/containers/alerts/alerts_over_time/alerts_over_time.gql_query.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import gql from 'graphql-tag'; - -export const AlertsOverTimeGqlQuery = gql` - query GetAlertsOverTimeQuery( - $sourceId: ID! - $timerange: TimerangeInput! - $defaultIndex: [String!]! - $filterQuery: String - $inspect: Boolean! - ) { - source(id: $sourceId) { - id - AlertsHistogram( - timerange: $timerange - filterQuery: $filterQuery - defaultIndex: $defaultIndex - ) { - alertsOverTimeByModule { - x - y - g - } - totalCount - inspect @include(if: $inspect) { - dsl - response - } - } - } - } -`; diff --git a/x-pack/legacy/plugins/siem/public/containers/alerts/alerts_over_time/index.tsx b/x-pack/legacy/plugins/siem/public/containers/alerts/alerts_over_time/index.tsx deleted file mode 100644 index 9541e6d39d669..0000000000000 --- a/x-pack/legacy/plugins/siem/public/containers/alerts/alerts_over_time/index.tsx +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getOr } from 'lodash/fp'; -import React from 'react'; -import { Query } from 'react-apollo'; -import { connect } from 'react-redux'; -import { compose } from 'redux'; - -import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; -import { inputsModel, State, inputsSelectors, hostsModel } from '../../../store'; -import { withKibana, WithKibanaProps } from '../../../lib/kibana'; -import { createFilter, getDefaultFetchPolicy } from '../../helpers'; -import { QueryTemplate, QueryTemplateProps } from '../../query_template'; - -import { AlertsOverTimeGqlQuery } from './alerts_over_time.gql_query'; -import { MatrixOverTimeHistogramData, GetAlertsOverTimeQuery } from '../../../graphql/types'; - -const ID = 'alertsOverTimeQuery'; - -export interface AlertsArgs { - endDate: number; - alertsOverTime: MatrixOverTimeHistogramData[]; - id: string; - inspect: inputsModel.InspectQuery; - loading: boolean; - refetch: inputsModel.Refetch; - startDate: number; - totalCount: number; -} - -export interface OwnProps extends QueryTemplateProps { - children?: (args: AlertsArgs) => React.ReactNode; - type: hostsModel.HostsType; -} - -export interface AlertsOverTimeComponentReduxProps { - isInspected: boolean; -} - -type AlertsOverTimeProps = OwnProps & AlertsOverTimeComponentReduxProps & WithKibanaProps; - -class AlertsOverTimeComponentQuery extends QueryTemplate< - AlertsOverTimeProps, - GetAlertsOverTimeQuery.Query, - GetAlertsOverTimeQuery.Variables -> { - public render() { - const { - children, - endDate, - filterQuery, - id = ID, - isInspected, - kibana, - sourceId, - startDate, - } = this.props; - return ( - - query={AlertsOverTimeGqlQuery} - fetchPolicy={getDefaultFetchPolicy()} - notifyOnNetworkStatusChange - variables={{ - filterQuery: createFilter(filterQuery), - sourceId, - timerange: { - interval: '12h', - from: startDate!, - to: endDate!, - }, - defaultIndex: kibana.services.uiSettings.get(DEFAULT_INDEX_KEY), - inspect: isInspected, - }} - > - {({ data, loading, refetch }) => { - const source = getOr({}, `source.AlertsHistogram`, data); - const alertsOverTime = getOr([], `alertsOverTimeByModule`, source); - const totalCount = getOr(-1, 'totalCount', source); - return children!({ - endDate: endDate!, - alertsOverTime, - id, - inspect: getOr(null, 'inspect', source), - loading, - refetch, - startDate: startDate!, - totalCount, - }); - }} - - ); - } -} - -const makeMapStateToProps = () => { - const getQuery = inputsSelectors.globalQueryByIdSelector(); - const mapStateToProps = (state: State, { type, id = ID }: OwnProps) => { - const { isInspected } = getQuery(state, id); - return { - isInspected, - }; - }; - return mapStateToProps; -}; - -export const AlertsOverTimeQuery = compose>( - connect(makeMapStateToProps), - withKibana -)(AlertsOverTimeComponentQuery); diff --git a/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_over_time/anomalies_over_time.gql_query.ts b/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_over_time/anomalies_over_time.gql_query.ts deleted file mode 100644 index 498cdaec131e8..0000000000000 --- a/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_over_time/anomalies_over_time.gql_query.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import gql from 'graphql-tag'; - -export const AnomaliesOverTimeGqlQuery = gql` - query GetAnomaliesOverTimeQuery( - $sourceId: ID! - $timerange: TimerangeInput! - $defaultIndex: [String!]! - $filterQuery: String - $inspect: Boolean! - ) { - source(id: $sourceId) { - id - AnomaliesOverTime( - timerange: $timerange - filterQuery: $filterQuery - defaultIndex: $defaultIndex - ) { - anomaliesOverTime { - x - y - g - } - totalCount - inspect @include(if: $inspect) { - dsl - response - } - } - } - } -`; diff --git a/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_over_time/index.tsx b/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_over_time/index.tsx deleted file mode 100644 index 0d1ffba1ecd82..0000000000000 --- a/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_over_time/index.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getOr } from 'lodash/fp'; -import React from 'react'; -import { Query } from 'react-apollo'; -import { connect } from 'react-redux'; - -import { State, inputsSelectors } from '../../../store'; -import { getDefaultFetchPolicy } from '../../helpers'; -import { QueryTemplate } from '../../query_template'; - -import { AnomaliesOverTimeGqlQuery } from './anomalies_over_time.gql_query'; -import { GetAnomaliesOverTimeQuery } from '../../../graphql/types'; -import { AnomaliesOverTimeProps, OwnProps } from './types'; - -const ID = 'anomaliesOverTimeQuery'; - -class AnomaliesOverTimeComponentQuery extends QueryTemplate< - AnomaliesOverTimeProps, - GetAnomaliesOverTimeQuery.Query, - GetAnomaliesOverTimeQuery.Variables -> { - public render() { - const { - children, - endDate, - filterQuery, - id = ID, - isInspected, - sourceId, - startDate, - } = this.props; - - return ( - - query={AnomaliesOverTimeGqlQuery} - fetchPolicy={getDefaultFetchPolicy()} - notifyOnNetworkStatusChange - variables={{ - filterQuery, - sourceId, - timerange: { - interval: 'day', - from: startDate!, - to: endDate!, - }, - defaultIndex: ['.ml-anomalies-*'], - inspect: isInspected, - }} - > - {({ data, loading, refetch }) => { - const source = getOr({}, `source.AnomaliesOverTime`, data); - const anomaliesOverTime = getOr([], `anomaliesOverTime`, source); - const totalCount = getOr(-1, 'totalCount', source); - return children!({ - endDate: endDate!, - anomaliesOverTime, - id, - inspect: getOr(null, 'inspect', source), - loading, - refetch, - startDate: startDate!, - totalCount, - }); - }} - - ); - } -} - -const makeMapStateToProps = () => { - const getQuery = inputsSelectors.globalQueryByIdSelector(); - const mapStateToProps = (state: State, { id = ID }: OwnProps) => { - const { isInspected } = getQuery(state, id); - return { - isInspected, - }; - }; - return mapStateToProps; -}; - -export const AnomaliesOverTimeQuery = connect(makeMapStateToProps)(AnomaliesOverTimeComponentQuery); diff --git a/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_over_time/types.ts b/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_over_time/types.ts deleted file mode 100644 index e6ece4a46e44f..0000000000000 --- a/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_over_time/types.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { QueryTemplateProps } from '../../query_template'; -import { inputsModel, hostsModel, networkModel } from '../../../store'; -import { MatrixOverTimeHistogramData } from '../../../graphql/types'; - -export interface AnomaliesArgs { - endDate: number; - anomaliesOverTime: MatrixOverTimeHistogramData[]; - id: string; - inspect: inputsModel.InspectQuery; - loading: boolean; - refetch: inputsModel.Refetch; - startDate: number; - totalCount: number; -} - -export interface OwnProps extends Omit { - filterQuery?: string; - children?: (args: AnomaliesArgs) => React.ReactNode; - type: hostsModel.HostsType | networkModel.NetworkType; -} - -export interface AnomaliesOverTimeComponentReduxProps { - isInspected: boolean; -} - -export type AnomaliesOverTimeProps = OwnProps & AnomaliesOverTimeComponentReduxProps; diff --git a/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_query_tab_body/index.tsx b/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_query_tab_body/index.tsx index f2c00cbae1a74..f691219e446a8 100644 --- a/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_query_tab_body/index.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/anomalies/anomalies_query_tab_body/index.tsx @@ -4,35 +4,42 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { useEffect } from 'react'; import { EuiSpacer } from '@elastic/eui'; +import * as i18n from './translations'; import { AnomaliesQueryTabBodyProps } from './types'; -import { manageQuery } from '../../../components/page/manage_query'; -import { AnomaliesOverTimeHistogram } from '../../../components/anomalies_over_time'; -import { AnomaliesOverTimeQuery } from '../anomalies_over_time'; import { getAnomaliesFilterQuery } from './utils'; import { useSiemJobs } from '../../../components/ml_popover/hooks/use_siem_jobs'; import { useUiSetting$ } from '../../../lib/kibana'; import { DEFAULT_ANOMALY_SCORE } from '../../../../common/constants'; +import { MatrixHistogramContainer } from '../../matrix_histogram'; +import { MatrixHistogramOption } from '../../../components/matrix_histogram/types'; +import { MatrixHistogramGqlQuery } from '../../matrix_histogram/index.gql_query'; -const AnomaliesOverTimeManage = manageQuery(AnomaliesOverTimeHistogram); +const ID = 'anomaliesOverTimeQuery'; +const anomaliesStackByOptions: MatrixHistogramOption[] = [ + { + text: i18n.ANOMALIES_STACK_BY_JOB_ID, + value: 'job_id', + }, +]; export const AnomaliesQueryTabBody = ({ + deleteQuery, endDate, + setQuery, skip, startDate, type, narrowDateRange, filterQuery, anomaliesFilterQuery, - setQuery, - hideHistogramIfEmpty, updateDateRange = () => {}, AnomaliesTableComponent, flowTarget, ip, }: AnomaliesQueryTabBodyProps) => { - const [siemJobsLoading, siemJobs] = useSiemJobs(true); + const [, siemJobs] = useSiemJobs(true); const [anomalyScore] = useUiSetting$(DEFAULT_ANOMALY_SCORE); const mergedFilterQuery = getAnomaliesFilterQuery( @@ -44,39 +51,37 @@ export const AnomaliesQueryTabBody = ({ ip ); + useEffect(() => { + return () => { + if (deleteQuery) { + deleteQuery({ id: ID }); + } + }; + }, []); + return ( <> - - {({ anomaliesOverTime, loading, id, inspect, refetch, totalCount }) => { - if (hideHistogramIfEmpty && !anomaliesOverTime.length) { - return
; - } - - return ( - <> - - - - ); - }} - + updateDateRange={updateDateRange} + /> + void; endDate: number; - skip: boolean; - setQuery: SetQuery; + flowTarget?: FlowTarget; narrowDateRange: NarrowDateRange; + setQuery: SetQuery; + startDate: number; + skip: boolean; updateDateRange?: UpdateDateRange; - anomaliesFilterQuery?: object; hideHistogramIfEmpty?: boolean; ip?: string; - flowTarget?: FlowTarget; - AnomaliesTableComponent: typeof AnomaliesHostTable | typeof AnomaliesNetworkTable; }; diff --git a/x-pack/legacy/plugins/siem/public/containers/authentications/authentications_over_time/authentications_over_time.gql_query.ts b/x-pack/legacy/plugins/siem/public/containers/authentications/authentications_over_time/authentications_over_time.gql_query.ts deleted file mode 100644 index dc05f4f8232d5..0000000000000 --- a/x-pack/legacy/plugins/siem/public/containers/authentications/authentications_over_time/authentications_over_time.gql_query.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import gql from 'graphql-tag'; - -export const AuthenticationsOverTimeGqlQuery = gql` - query GetAuthenticationsOverTimeQuery( - $sourceId: ID! - $timerange: TimerangeInput! - $defaultIndex: [String!]! - $filterQuery: String - $inspect: Boolean! - ) { - source(id: $sourceId) { - id - AuthenticationsOverTime( - timerange: $timerange - filterQuery: $filterQuery - defaultIndex: $defaultIndex - ) { - authenticationsOverTime { - x - y - g - } - totalCount - inspect @include(if: $inspect) { - dsl - response - } - } - } - } -`; diff --git a/x-pack/legacy/plugins/siem/public/containers/authentications/authentications_over_time/index.tsx b/x-pack/legacy/plugins/siem/public/containers/authentications/authentications_over_time/index.tsx deleted file mode 100644 index 8f363d49f1851..0000000000000 --- a/x-pack/legacy/plugins/siem/public/containers/authentications/authentications_over_time/index.tsx +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getOr } from 'lodash/fp'; -import React from 'react'; -import { Query } from 'react-apollo'; -import { connect } from 'react-redux'; -import { compose } from 'redux'; - -import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; -import { inputsModel, State, inputsSelectors, hostsModel } from '../../../store'; -import { withKibana, WithKibanaProps } from '../../../lib/kibana'; -import { createFilter, getDefaultFetchPolicy } from '../../helpers'; -import { QueryTemplate, QueryTemplateProps } from '../../query_template'; - -import { AuthenticationsOverTimeGqlQuery } from './authentications_over_time.gql_query'; -import { - GetAuthenticationsOverTimeQuery, - MatrixOverTimeHistogramData, -} from '../../../graphql/types'; - -const ID = 'authenticationsOverTimeQuery'; - -export interface AuthenticationsArgs { - endDate: number; - authenticationsOverTime: MatrixOverTimeHistogramData[]; - id: string; - inspect: inputsModel.InspectQuery; - loading: boolean; - refetch: inputsModel.Refetch; - startDate: number; - totalCount: number; -} - -export interface OwnProps extends QueryTemplateProps { - children?: (args: AuthenticationsArgs) => React.ReactNode; - type: hostsModel.HostsType; -} - -export interface AuthenticationsOverTimeComponentReduxProps { - isInspected: boolean; -} - -type AuthenticationsOverTimeProps = OwnProps & - AuthenticationsOverTimeComponentReduxProps & - WithKibanaProps; - -class AuthenticationsOverTimeComponentQuery extends QueryTemplate< - AuthenticationsOverTimeProps, - GetAuthenticationsOverTimeQuery.Query, - GetAuthenticationsOverTimeQuery.Variables -> { - public render() { - const { - children, - filterQuery, - id = ID, - isInspected, - kibana, - sourceId, - startDate, - endDate, - } = this.props; - return ( - - query={AuthenticationsOverTimeGqlQuery} - fetchPolicy={getDefaultFetchPolicy()} - notifyOnNetworkStatusChange - variables={{ - filterQuery: createFilter(filterQuery), - sourceId, - timerange: { - interval: '12h', - from: startDate!, - to: endDate!, - }, - defaultIndex: kibana.services.uiSettings.get(DEFAULT_INDEX_KEY), - inspect: isInspected, - }} - > - {({ data, loading, refetch }) => { - const source = getOr({}, `source.AuthenticationsOverTime`, data); - const authenticationsOverTime = getOr([], `authenticationsOverTime`, source); - const totalCount = getOr(-1, 'totalCount', source); - return children!({ - endDate: endDate!, - authenticationsOverTime, - id, - inspect: getOr(null, 'inspect', source), - loading, - refetch, - startDate: startDate!, - totalCount, - }); - }} - - ); - } -} - -const makeMapStateToProps = () => { - const getQuery = inputsSelectors.globalQueryByIdSelector(); - const mapStateToProps = (state: State, { type, id = ID }: OwnProps) => { - const { isInspected } = getQuery(state, id); - return { - isInspected, - }; - }; - return mapStateToProps; -}; - -export const AuthenticationsOverTimeQuery = compose>( - connect(makeMapStateToProps), - withKibana -)(AuthenticationsOverTimeComponentQuery); diff --git a/x-pack/legacy/plugins/siem/public/containers/events/events_over_time/events_over_time.gql_query.ts b/x-pack/legacy/plugins/siem/public/containers/events/events_over_time/events_over_time.gql_query.ts deleted file mode 100644 index aec0a32043040..0000000000000 --- a/x-pack/legacy/plugins/siem/public/containers/events/events_over_time/events_over_time.gql_query.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import gql from 'graphql-tag'; - -export const EventsOverTimeGqlQuery = gql` - query GetEventsOverTimeQuery( - $sourceId: ID! - $timerange: TimerangeInput! - $defaultIndex: [String!]! - $filterQuery: String - $inspect: Boolean! - ) { - source(id: $sourceId) { - id - EventsOverTime( - timerange: $timerange - filterQuery: $filterQuery - defaultIndex: $defaultIndex - ) { - eventsOverTime { - x - y - g - } - totalCount - inspect @include(if: $inspect) { - dsl - response - } - } - } - } -`; diff --git a/x-pack/legacy/plugins/siem/public/containers/events/events_over_time/index.tsx b/x-pack/legacy/plugins/siem/public/containers/events/events_over_time/index.tsx deleted file mode 100644 index e102cd11f108e..0000000000000 --- a/x-pack/legacy/plugins/siem/public/containers/events/events_over_time/index.tsx +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import { getOr } from 'lodash/fp'; -import React from 'react'; -import { Query } from 'react-apollo'; -import { connect } from 'react-redux'; -import { compose } from 'redux'; - -import { DEFAULT_INDEX_KEY } from '../../../../common/constants'; -import { inputsModel, State, inputsSelectors, hostsModel } from '../../../store'; -import { createFilter, getDefaultFetchPolicy } from '../../helpers'; -import { QueryTemplate, QueryTemplateProps } from '../../query_template'; -import { withKibana, WithKibanaProps } from '../../../lib/kibana'; - -import { EventsOverTimeGqlQuery } from './events_over_time.gql_query'; -import { GetEventsOverTimeQuery, MatrixOverTimeHistogramData } from '../../../graphql/types'; - -const ID = 'eventsOverTimeQuery'; - -export interface EventsArgs { - endDate: number; - eventsOverTime: MatrixOverTimeHistogramData[]; - id: string; - inspect: inputsModel.InspectQuery; - loading: boolean; - refetch: inputsModel.Refetch; - startDate: number; - totalCount: number; -} - -export interface OwnProps extends QueryTemplateProps { - children?: (args: EventsArgs) => React.ReactNode; - type: hostsModel.HostsType; -} - -export interface EventsOverTimeComponentReduxProps { - isInspected: boolean; -} - -type EventsOverTimeProps = OwnProps & EventsOverTimeComponentReduxProps & WithKibanaProps; - -class EventsOverTimeComponentQuery extends QueryTemplate< - EventsOverTimeProps, - GetEventsOverTimeQuery.Query, - GetEventsOverTimeQuery.Variables -> { - public render() { - const { - children, - endDate, - filterQuery, - id = ID, - isInspected, - kibana, - sourceId, - startDate, - } = this.props; - return ( - - query={EventsOverTimeGqlQuery} - fetchPolicy={getDefaultFetchPolicy()} - notifyOnNetworkStatusChange - variables={{ - filterQuery: createFilter(filterQuery), - sourceId, - timerange: { - interval: '12h', - from: startDate!, - to: endDate!, - }, - defaultIndex: kibana.services.uiSettings.get(DEFAULT_INDEX_KEY), - inspect: isInspected, - }} - > - {({ data, loading, refetch }) => { - const source = getOr({}, `source.EventsOverTime`, data); - const eventsOverTime = getOr([], `eventsOverTime`, source); - const totalCount = getOr(-1, 'totalCount', source); - return children!({ - endDate: endDate!, - eventsOverTime, - id, - inspect: getOr(null, 'inspect', source), - loading, - refetch, - startDate: startDate!, - totalCount, - }); - }} - - ); - } -} - -const makeMapStateToProps = () => { - const getQuery = inputsSelectors.globalQueryByIdSelector(); - const mapStateToProps = (state: State, { type, id = ID }: OwnProps) => { - const { isInspected } = getQuery(state, id); - return { - isInspected, - }; - }; - return mapStateToProps; -}; - -export const EventsOverTimeQuery = compose>( - connect(makeMapStateToProps), - withKibana -)(EventsOverTimeComponentQuery); diff --git a/x-pack/legacy/plugins/siem/public/containers/matrix_histogram/index.gql_query.ts b/x-pack/legacy/plugins/siem/public/containers/matrix_histogram/index.gql_query.ts new file mode 100644 index 0000000000000..4c22223a9ff5d --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/containers/matrix_histogram/index.gql_query.ts @@ -0,0 +1,94 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import gql from 'graphql-tag'; + +export const MatrixHistogramGqlQuery = gql` + query GetMatrixHistogramQuery( + $isAlertsHistogram: Boolean! + $isAnomaliesHistogram: Boolean! + $isAuthenticationsHistogram: Boolean! + $defaultIndex: [String!]! + $isEventsType: Boolean! + $filterQuery: String + $inspect: Boolean! + $sourceId: ID! + $stackByField: String + $timerange: TimerangeInput! + ) { + source(id: $sourceId) { + id + AlertsHistogram( + timerange: $timerange + filterQuery: $filterQuery + defaultIndex: $defaultIndex + stackByField: $stackByField + ) @include(if: $isAlertsHistogram) { + matrixHistogramData { + x + y + g + } + totalCount + inspect @include(if: $inspect) { + dsl + response + } + } + AnomaliesHistogram( + timerange: $timerange + filterQuery: $filterQuery + defaultIndex: $defaultIndex + stackByField: $stackByField + ) @include(if: $isAnomaliesHistogram) { + matrixHistogramData { + x + y + g + } + totalCount + inspect @include(if: $inspect) { + dsl + response + } + } + AuthenticationsHistogram( + timerange: $timerange + filterQuery: $filterQuery + defaultIndex: $defaultIndex + stackByField: $stackByField + ) @include(if: $isAuthenticationsHistogram) { + matrixHistogramData { + x + y + g + } + totalCount + inspect @include(if: $inspect) { + dsl + response + } + } + EventsHistogram( + timerange: $timerange + filterQuery: $filterQuery + defaultIndex: $defaultIndex + stackByField: $stackByField + ) @include(if: $isEventsType) { + matrixHistogramData { + x + y + g + } + totalCount + inspect @include(if: $inspect) { + dsl + response + } + } + } + } +`; diff --git a/x-pack/legacy/plugins/siem/public/containers/matrix_histogram/index.tsx b/x-pack/legacy/plugins/siem/public/containers/matrix_histogram/index.tsx new file mode 100644 index 0000000000000..0167f6253c3b1 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/containers/matrix_histogram/index.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { compose } from 'redux'; + +import { connect } from 'react-redux'; +import { State, inputsSelectors, hostsModel, networkModel } from '../../store'; +import { QueryTemplateProps } from '../query_template'; + +import { Maybe } from '../../graphql/types'; +import { MatrixHistogram } from '../../components/matrix_histogram'; +import { + MatrixHistogramOption, + MatrixHistogramMappingTypes, + GetSubTitle, +} from '../../components/matrix_histogram/types'; +import { UpdateDateRange } from '../../components/charts/common'; +import { SetQuery } from '../../pages/hosts/navigation/types'; + +export interface OwnProps extends QueryTemplateProps { + isAlertsHistogram?: boolean; + isAnomaliesHistogram?: boolean; + isAuthenticationsHistogram?: boolean; + dataKey: string | string[]; + defaultStackByOption: MatrixHistogramOption; + deleteQuery?: ({ id }: { id: string }) => void; + isEventsType?: boolean; + errorMessage: string; + hideHistogramIfEmpty?: boolean; + id: string; + mapping?: MatrixHistogramMappingTypes; + query: Maybe; + setQuery: SetQuery; + sourceId: string; + stackByOptions: MatrixHistogramOption[]; + subtitle?: string | GetSubTitle; + title: string; + type: hostsModel.HostsType | networkModel.NetworkType; + updateDateRange: UpdateDateRange; +} + +const makeMapStateToProps = () => { + const getQuery = inputsSelectors.globalQueryByIdSelector(); + const mapStateToProps = (state: State, { type, id }: OwnProps) => { + const { isInspected } = getQuery(state, id); + return { + isInspected, + }; + }; + return mapStateToProps; +}; + +export const MatrixHistogramContainer = compose>( + connect(makeMapStateToProps) +)(MatrixHistogram); diff --git a/x-pack/legacy/plugins/siem/public/containers/matrix_histogram/utils.ts b/x-pack/legacy/plugins/siem/public/containers/matrix_histogram/utils.ts new file mode 100644 index 0000000000000..1fc1fedae9f88 --- /dev/null +++ b/x-pack/legacy/plugins/siem/public/containers/matrix_histogram/utils.ts @@ -0,0 +1,158 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { getOr } from 'lodash/fp'; +import { useEffect, useState } from 'react'; +import { + MatrixHistogramDataTypes, + MatrixHistogramQueryProps, +} from '../../components/matrix_histogram/types'; +import { DEFAULT_INDEX_KEY } from '../../../common/constants'; +import { useStateToaster } from '../../components/toasters'; +import { errorToToaster } from '../../components/ml/api/error_to_toaster'; +import { useUiSetting$ } from '../../lib/kibana'; +import { createFilter } from '../helpers'; +import { useApolloClient } from '../../utils/apollo_context'; +import { inputsModel } from '../../store'; +import { GetMatrixHistogramQuery, GetNetworkDnsQuery } from '../../graphql/types'; + +export const useQuery = ({ + dataKey, + endDate, + errorMessage, + filterQuery, + isAlertsHistogram = false, + isAnomaliesHistogram = false, + isAuthenticationsHistogram = false, + isEventsType = false, + isDNSHistogram, + isPtrIncluded, + isInspected, + query, + stackByField, + startDate, + sort, + pagination, +}: MatrixHistogramQueryProps) => { + const [defaultIndex] = useUiSetting$(DEFAULT_INDEX_KEY); + const [, dispatchToaster] = useStateToaster(); + const [refetch, setRefetch] = useState(); + const [loading, setLoading] = useState(false); + const [data, setData] = useState(null); + const [inspect, setInspect] = useState(null); + const [totalCount, setTotalCount] = useState(-1); + const apolloClient = useApolloClient(); + + const isDNSQuery = ( + variable: Pick< + MatrixHistogramQueryProps, + 'isDNSHistogram' | 'isPtrIncluded' | 'sort' | 'pagination' + > + ): variable is GetNetworkDnsQuery.Variables => { + return ( + !!isDNSHistogram && + variable.isDNSHistogram !== undefined && + variable.isPtrIncluded !== undefined && + variable.sort !== undefined && + variable.pagination !== undefined + ); + }; + const basicVariables = { + filterQuery: createFilter(filterQuery), + sourceId: 'default', + timerange: { + interval: '12h', + from: startDate!, + to: endDate!, + }, + defaultIndex, + inspect: isInspected, + stackByField, + }; + const dnsVariables = { + ...basicVariables, + isDNSHistogram, + isPtrIncluded, + sort, + pagination, + }; + const matrixHistogramVariables: GetMatrixHistogramQuery.Variables = { + ...basicVariables, + isAlertsHistogram, + isAnomaliesHistogram, + isAuthenticationsHistogram, + isEventsType, + }; + + useEffect(() => { + let isSubscribed = true; + const abortCtrl = new AbortController(); + const abortSignal = abortCtrl.signal; + + async function fetchData() { + if (!apolloClient || (pagination != null && pagination.querySize < 0)) return null; + setLoading(true); + return apolloClient + .query< + GetMatrixHistogramQuery.Query | GetNetworkDnsQuery.Query, + GetMatrixHistogramQuery.Variables | GetNetworkDnsQuery.Variables + >({ + query, + fetchPolicy: 'cache-first', + variables: isDNSQuery(dnsVariables) ? dnsVariables : matrixHistogramVariables, + context: { + fetchOptions: { + abortSignal, + }, + }, + }) + .then( + result => { + if (isSubscribed) { + const isDataKeyAnArray = Array.isArray(dataKey); + const rootDataKey = isDataKeyAnArray ? dataKey[0] : `${dataKey}`; + const histogramDataKey = isDataKeyAnArray ? dataKey[1] : `matrixHistogramData`; + const source = getOr({}, `data.source.${rootDataKey}`, result); + setData(getOr([], histogramDataKey, source)); + setTotalCount(getOr(-1, 'totalCount', source)); + setInspect(getOr(null, 'inspect', source)); + setLoading(false); + } + }, + error => { + if (isSubscribed) { + setData(null); + setTotalCount(-1); + setInspect(null); + errorToToaster({ title: errorMessage, error, dispatchToaster }); + setLoading(false); + } + } + ); + } + setRefetch(() => { + fetchData(); + }); + fetchData(); + return () => { + isSubscribed = false; + abortCtrl.abort(); + }; + }, [ + defaultIndex, + query, + filterQuery, + isInspected, + isDNSHistogram, + stackByField, + sort, + isPtrIncluded, + pagination, + startDate, + endDate, + ]); + + return { data, loading, inspect, totalCount, refetch }; +}; diff --git a/x-pack/legacy/plugins/siem/public/containers/network_dns/index.gql_query.ts b/x-pack/legacy/plugins/siem/public/containers/network_dns/index.gql_query.ts index da83e09e4629a..9d82705e9524b 100644 --- a/x-pack/legacy/plugins/siem/public/containers/network_dns/index.gql_query.ts +++ b/x-pack/legacy/plugins/siem/public/containers/network_dns/index.gql_query.ts @@ -8,14 +8,16 @@ import gql from 'graphql-tag'; export const networkDnsQuery = gql` query GetNetworkDnsQuery( - $sourceId: ID! - $sort: NetworkDnsSortField! - $isPtrIncluded: Boolean! - $timerange: TimerangeInput! - $pagination: PaginationInputPaginated! - $filterQuery: String $defaultIndex: [String!]! + $filterQuery: String $inspect: Boolean! + $isDNSHistogram: Boolean! + $isPtrIncluded: Boolean! + $pagination: PaginationInputPaginated! + $sort: NetworkDnsSortField! + $sourceId: ID! + $stackByField: String + $timerange: TimerangeInput! ) { source(id: $sourceId) { id @@ -26,9 +28,10 @@ export const networkDnsQuery = gql` pagination: $pagination filterQuery: $filterQuery defaultIndex: $defaultIndex + stackByField: $stackByField ) { totalCount - edges { + edges @skip(if: $isDNSHistogram) { node { _id dnsBytesIn @@ -41,7 +44,7 @@ export const networkDnsQuery = gql` value } } - pageInfo { + pageInfo @skip(if: $isDNSHistogram) { activePage fakeTotalCount showMorePagesIndicator @@ -50,7 +53,7 @@ export const networkDnsQuery = gql` dsl response } - histogram { + histogram @include(if: $isDNSHistogram) { x y g diff --git a/x-pack/legacy/plugins/siem/public/containers/network_dns/index.tsx b/x-pack/legacy/plugins/siem/public/containers/network_dns/index.tsx index b5ebf3deacd0a..5c5552edcc4ba 100644 --- a/x-pack/legacy/plugins/siem/public/containers/network_dns/index.tsx +++ b/x-pack/legacy/plugins/siem/public/containers/network_dns/index.tsx @@ -10,6 +10,8 @@ import { Query } from 'react-apollo'; import { connect } from 'react-redux'; import { compose } from 'redux'; +import { DocumentNode } from 'graphql'; +import { ScaleType } from '@elastic/charts'; import { DEFAULT_INDEX_KEY } from '../../../common/constants'; import { GetNetworkDnsQuery, @@ -24,10 +26,14 @@ import { generateTablePaginationOptions } from '../../components/paginated_table import { createFilter, getDefaultFetchPolicy } from '../helpers'; import { QueryTemplatePaginated, QueryTemplatePaginatedProps } from '../query_template_paginated'; import { networkDnsQuery } from './index.gql_query'; -import { DEFAULT_TABLE_ACTIVE_PAGE, DEFAULT_TABLE_LIMIT } from '../../store/constants'; +import { DEFAULT_TABLE_ACTIVE_PAGE } from '../../store/constants'; +import { MatrixHistogram } from '../../components/matrix_histogram'; +import { MatrixHistogramOption, GetSubTitle } from '../../components/matrix_histogram/types'; +import { UpdateDateRange } from '../../components/charts/common'; +import { SetQuery } from '../../pages/hosts/navigation/types'; const ID = 'networkDnsQuery'; -const HISTOGRAM_ID = 'networkDnsHistogramQuery'; +export const HISTOGRAM_ID = 'networkDnsHistogramQuery'; export interface NetworkDnsArgs { id: string; inspect: inputsModel.InspectQuery; @@ -37,6 +43,7 @@ export interface NetworkDnsArgs { networkDns: NetworkDnsEdges[]; pageInfo: PageInfoPaginated; refetch: inputsModel.Refetch; + stackByField?: string; totalCount: number; histogram: MatrixOverOrdinalHistogramData[]; } @@ -46,6 +53,24 @@ export interface OwnProps extends QueryTemplatePaginatedProps { type: networkModel.NetworkType; } +interface DnsHistogramOwnProps extends QueryTemplatePaginatedProps { + dataKey: string | string[]; + defaultStackByOption: MatrixHistogramOption; + errorMessage: string; + isDNSHistogram?: boolean; + limit: number; + query: DocumentNode; + scaleType: ScaleType; + setQuery: SetQuery; + showLegend?: boolean; + stackByOptions: MatrixHistogramOption[]; + subtitle?: string | GetSubTitle; + title: string; + type: networkModel.NetworkType; + updateDateRange: UpdateDateRange; + yTickFormatter?: (value: number) => string; +} + export interface NetworkDnsComponentReduxProps { activePage: number; sort: NetworkDnsSortField; @@ -80,6 +105,7 @@ export class NetworkDnsComponentQuery extends QueryTemplatePaginated< const variables: GetNetworkDnsQuery.Variables = { defaultIndex: kibana.services.uiSettings.get(DEFAULT_INDEX_KEY), filterQuery: createFilter(filterQuery), + isDNSHistogram: false, inspect: isInspected, isPtrIncluded, pagination: generateTablePaginationOptions(activePage, limit), @@ -160,12 +186,12 @@ const makeMapStateToProps = () => { const makeMapHistogramStateToProps = () => { const getNetworkDnsSelector = networkSelectors.dnsSelector(); const getQuery = inputsSelectors.globalQueryByIdSelector(); - const mapStateToProps = (state: State, { id = HISTOGRAM_ID }: OwnProps) => { + const mapStateToProps = (state: State, { id = HISTOGRAM_ID, limit }: DnsHistogramOwnProps) => { const { isInspected } = getQuery(state, id); return { ...getNetworkDnsSelector(state), activePage: DEFAULT_TABLE_ACTIVE_PAGE, - limit: DEFAULT_TABLE_LIMIT, + limit, isInspected, id, }; @@ -179,7 +205,7 @@ export const NetworkDnsQuery = compose>( withKibana )(NetworkDnsComponentQuery); -export const NetworkDnsHistogramQuery = compose>( +export const NetworkDnsHistogramQuery = compose>( connect(makeMapHistogramStateToProps), withKibana -)(NetworkDnsComponentQuery); +)(MatrixHistogram); diff --git a/x-pack/legacy/plugins/siem/public/graphql/introspection.json b/x-pack/legacy/plugins/siem/public/graphql/introspection.json index 8ebc66b7f38a7..c48b5ab9a27a4 100644 --- a/x-pack/legacy/plugins/siem/public/graphql/introspection.json +++ b/x-pack/legacy/plugins/siem/public/graphql/introspection.json @@ -703,6 +703,12 @@ "ofType": { "kind": "INPUT_OBJECT", "name": "TimerangeInput", "ofType": null } }, "defaultValue": null + }, + { + "name": "stackByField", + "description": "", + "type": { "kind": "SCALAR", "name": "String", "ofType": null }, + "defaultValue": null } ], "type": { @@ -714,7 +720,7 @@ "deprecationReason": null }, { - "name": "AnomaliesOverTime", + "name": "AnomaliesHistogram", "description": "", "args": [ { @@ -750,6 +756,12 @@ } }, "defaultValue": null + }, + { + "name": "stackByField", + "description": "", + "type": { "kind": "SCALAR", "name": "String", "ofType": null }, + "defaultValue": null } ], "type": { @@ -822,7 +834,7 @@ "deprecationReason": null }, { - "name": "AuthenticationsOverTime", + "name": "AuthenticationsHistogram", "description": "", "args": [ { @@ -858,6 +870,12 @@ } }, "defaultValue": null + }, + { + "name": "stackByField", + "description": "", + "type": { "kind": "SCALAR", "name": "String", "ofType": null }, + "defaultValue": null } ], "type": { @@ -1058,7 +1076,7 @@ "deprecationReason": null }, { - "name": "EventsOverTime", + "name": "EventsHistogram", "description": "", "args": [ { @@ -1094,6 +1112,12 @@ } }, "defaultValue": null + }, + { + "name": "stackByField", + "description": "", + "type": { "kind": "SCALAR", "name": "String", "ofType": null }, + "defaultValue": null } ], "type": { @@ -1834,6 +1858,12 @@ }, "defaultValue": null }, + { + "name": "stackByField", + "description": "", + "type": { "kind": "SCALAR", "name": "String", "ofType": null }, + "defaultValue": null + }, { "name": "timerange", "description": "", @@ -2599,7 +2629,7 @@ "deprecationReason": null }, { - "name": "alertsOverTimeByModule", + "name": "matrixHistogramData", "description": "", "args": [], "type": { @@ -2752,7 +2782,7 @@ "deprecationReason": null }, { - "name": "anomaliesOverTime", + "name": "matrixHistogramData", "description": "", "args": [], "type": { @@ -3516,7 +3546,7 @@ "deprecationReason": null }, { - "name": "authenticationsOverTime", + "name": "matrixHistogramData", "description": "", "args": [], "type": { @@ -6235,7 +6265,7 @@ "deprecationReason": null }, { - "name": "eventsOverTime", + "name": "matrixHistogramData", "description": "", "args": [], "type": { diff --git a/x-pack/legacy/plugins/siem/public/graphql/types.ts b/x-pack/legacy/plugins/siem/public/graphql/types.ts index 6dfde08058f7c..e35ddedafc7c8 100644 --- a/x-pack/legacy/plugins/siem/public/graphql/types.ts +++ b/x-pack/legacy/plugins/siem/public/graphql/types.ts @@ -459,11 +459,11 @@ export interface Source { AlertsHistogram: AlertsOverTimeData; - AnomaliesOverTime: AnomaliesOverTimeData; + AnomaliesHistogram: AnomaliesOverTimeData; /** Gets Authentication success and failures based on a timerange */ Authentications: AuthenticationsData; - AuthenticationsOverTime: AuthenticationsOverTimeData; + AuthenticationsHistogram: AuthenticationsOverTimeData; Timeline: TimelineData; @@ -471,7 +471,7 @@ export interface Source { LastEventTime: LastEventTimeData; - EventsOverTime: EventsOverTimeData; + EventsHistogram: EventsOverTimeData; /** Gets Hosts based on timerange and specified criteria, or all events in the timerange if no criteria is specified */ Hosts: HostsData; @@ -563,7 +563,7 @@ export interface IndexField { export interface AlertsOverTimeData { inspect?: Maybe; - alertsOverTimeByModule: MatrixOverTimeHistogramData[]; + matrixHistogramData: MatrixOverTimeHistogramData[]; totalCount: number; } @@ -585,7 +585,7 @@ export interface MatrixOverTimeHistogramData { export interface AnomaliesOverTimeData { inspect?: Maybe; - anomaliesOverTime: MatrixOverTimeHistogramData[]; + matrixHistogramData: MatrixOverTimeHistogramData[]; totalCount: number; } @@ -727,7 +727,7 @@ export interface PageInfoPaginated { export interface AuthenticationsOverTimeData { inspect?: Maybe; - authenticationsOverTime: MatrixOverTimeHistogramData[]; + matrixHistogramData: MatrixOverTimeHistogramData[]; totalCount: number; } @@ -1311,7 +1311,7 @@ export interface LastEventTimeData { export interface EventsOverTimeData { inspect?: Maybe; - eventsOverTime: MatrixOverTimeHistogramData[]; + matrixHistogramData: MatrixOverTimeHistogramData[]; totalCount: number; } @@ -2153,13 +2153,17 @@ export interface AlertsHistogramSourceArgs { defaultIndex: string[]; timerange: TimerangeInput; + + stackByField?: Maybe; } -export interface AnomaliesOverTimeSourceArgs { +export interface AnomaliesHistogramSourceArgs { timerange: TimerangeInput; filterQuery?: Maybe; defaultIndex: string[]; + + stackByField?: Maybe; } export interface AuthenticationsSourceArgs { timerange: TimerangeInput; @@ -2170,12 +2174,14 @@ export interface AuthenticationsSourceArgs { defaultIndex: string[]; } -export interface AuthenticationsOverTimeSourceArgs { +export interface AuthenticationsHistogramSourceArgs { timerange: TimerangeInput; filterQuery?: Maybe; defaultIndex: string[]; + + stackByField?: Maybe; } export interface TimelineSourceArgs { pagination: PaginationInput; @@ -2206,12 +2212,14 @@ export interface LastEventTimeSourceArgs { defaultIndex: string[]; } -export interface EventsOverTimeSourceArgs { +export interface EventsHistogramSourceArgs { timerange: TimerangeInput; filterQuery?: Maybe; defaultIndex: string[]; + + stackByField?: Maybe; } export interface HostsSourceArgs { id?: Maybe; @@ -2340,6 +2348,8 @@ export interface NetworkDnsSourceArgs { sort: NetworkDnsSortField; + stackByField?: Maybe; + timerange: TimerangeInput; defaultIndex: string[]; @@ -2455,162 +2465,6 @@ export interface DeleteTimelineMutationArgs { // Documents // ==================================================== -export namespace GetAlertsOverTimeQuery { - export type Variables = { - sourceId: string; - timerange: TimerangeInput; - defaultIndex: string[]; - filterQuery?: Maybe; - inspect: boolean; - }; - - export type Query = { - __typename?: 'Query'; - - source: Source; - }; - - export type Source = { - __typename?: 'Source'; - - id: string; - - AlertsHistogram: AlertsHistogram; - }; - - export type AlertsHistogram = { - __typename?: 'AlertsOverTimeData'; - - alertsOverTimeByModule: AlertsOverTimeByModule[]; - - totalCount: number; - - inspect: Maybe; - }; - - export type AlertsOverTimeByModule = { - __typename?: 'MatrixOverTimeHistogramData'; - - x: number; - - y: number; - - g: string; - }; - - export type Inspect = { - __typename?: 'Inspect'; - - dsl: string[]; - - response: string[]; - }; -} - -export namespace GetAnomaliesOverTimeQuery { - export type Variables = { - sourceId: string; - timerange: TimerangeInput; - defaultIndex: string[]; - filterQuery?: Maybe; - inspect: boolean; - }; - - export type Query = { - __typename?: 'Query'; - - source: Source; - }; - - export type Source = { - __typename?: 'Source'; - - id: string; - - AnomaliesOverTime: AnomaliesOverTime; - }; - - export type AnomaliesOverTime = { - __typename?: 'AnomaliesOverTimeData'; - - anomaliesOverTime: _AnomaliesOverTime[]; - - totalCount: number; - - inspect: Maybe; - }; - - export type _AnomaliesOverTime = { - __typename?: 'MatrixOverTimeHistogramData'; - - x: number; - - y: number; - - g: string; - }; - - export type Inspect = { - __typename?: 'Inspect'; - - dsl: string[]; - - response: string[]; - }; -} - -export namespace GetAuthenticationsOverTimeQuery { - export type Variables = { - sourceId: string; - timerange: TimerangeInput; - defaultIndex: string[]; - filterQuery?: Maybe; - inspect: boolean; - }; - - export type Query = { - __typename?: 'Query'; - - source: Source; - }; - - export type Source = { - __typename?: 'Source'; - - id: string; - - AuthenticationsOverTime: AuthenticationsOverTime; - }; - - export type AuthenticationsOverTime = { - __typename?: 'AuthenticationsOverTimeData'; - - authenticationsOverTime: _AuthenticationsOverTime[]; - - totalCount: number; - - inspect: Maybe; - }; - - export type _AuthenticationsOverTime = { - __typename?: 'MatrixOverTimeHistogramData'; - - x: number; - - y: number; - - g: string; - }; - - export type Inspect = { - __typename?: 'Inspect'; - - dsl: string[]; - - response: string[]; - }; -} - export namespace GetAuthenticationsQuery { export type Variables = { sourceId: string; @@ -2750,58 +2604,6 @@ export namespace GetAuthenticationsQuery { }; } -export namespace GetEventsOverTimeQuery { - export type Variables = { - sourceId: string; - timerange: TimerangeInput; - defaultIndex: string[]; - filterQuery?: Maybe; - inspect: boolean; - }; - - export type Query = { - __typename?: 'Query'; - - source: Source; - }; - - export type Source = { - __typename?: 'Source'; - - id: string; - - EventsOverTime: EventsOverTime; - }; - - export type EventsOverTime = { - __typename?: 'EventsOverTimeData'; - - eventsOverTime: _EventsOverTime[]; - - totalCount: number; - - inspect: Maybe; - }; - - export type _EventsOverTime = { - __typename?: 'MatrixOverTimeHistogramData'; - - x: number; - - y: number; - - g: string; - }; - - export type Inspect = { - __typename?: 'Inspect'; - - dsl: string[]; - - response: string[]; - }; -} - export namespace GetLastEventTimeQuery { export type Variables = { sourceId: string; @@ -3423,16 +3225,165 @@ export namespace GetKpiNetworkQuery { }; } -export namespace GetNetworkDnsQuery { +export namespace GetMatrixHistogramQuery { export type Variables = { + isAlertsHistogram: boolean; + isAnomaliesHistogram: boolean; + isAuthenticationsHistogram: boolean; + defaultIndex: string[]; + isEventsType: boolean; + filterQuery?: Maybe; + inspect: boolean; sourceId: string; - sort: NetworkDnsSortField; - isPtrIncluded: boolean; + stackByField?: Maybe; timerange: TimerangeInput; - pagination: PaginationInputPaginated; - filterQuery?: Maybe; + }; + + export type Query = { + __typename?: 'Query'; + + source: Source; + }; + + export type Source = { + __typename?: 'Source'; + + id: string; + + AlertsHistogram: AlertsHistogram; + + AnomaliesHistogram: AnomaliesHistogram; + + AuthenticationsHistogram: AuthenticationsHistogram; + + EventsHistogram: EventsHistogram; + }; + + export type AlertsHistogram = { + __typename?: 'AlertsOverTimeData'; + + matrixHistogramData: MatrixHistogramData[]; + + totalCount: number; + + inspect: Maybe; + }; + + export type MatrixHistogramData = { + __typename?: 'MatrixOverTimeHistogramData'; + + x: number; + + y: number; + + g: string; + }; + + export type Inspect = { + __typename?: 'Inspect'; + + dsl: string[]; + + response: string[]; + }; + + export type AnomaliesHistogram = { + __typename?: 'AnomaliesOverTimeData'; + + matrixHistogramData: _MatrixHistogramData[]; + + totalCount: number; + + inspect: Maybe<_Inspect>; + }; + + export type _MatrixHistogramData = { + __typename?: 'MatrixOverTimeHistogramData'; + + x: number; + + y: number; + + g: string; + }; + + export type _Inspect = { + __typename?: 'Inspect'; + + dsl: string[]; + + response: string[]; + }; + + export type AuthenticationsHistogram = { + __typename?: 'AuthenticationsOverTimeData'; + + matrixHistogramData: __MatrixHistogramData[]; + + totalCount: number; + + inspect: Maybe<__Inspect>; + }; + + export type __MatrixHistogramData = { + __typename?: 'MatrixOverTimeHistogramData'; + + x: number; + + y: number; + + g: string; + }; + + export type __Inspect = { + __typename?: 'Inspect'; + + dsl: string[]; + + response: string[]; + }; + + export type EventsHistogram = { + __typename?: 'EventsOverTimeData'; + + matrixHistogramData: ___MatrixHistogramData[]; + + totalCount: number; + + inspect: Maybe<___Inspect>; + }; + + export type ___MatrixHistogramData = { + __typename?: 'MatrixOverTimeHistogramData'; + + x: number; + + y: number; + + g: string; + }; + + export type ___Inspect = { + __typename?: 'Inspect'; + + dsl: string[]; + + response: string[]; + }; +} + +export namespace GetNetworkDnsQuery { + export type Variables = { defaultIndex: string[]; + filterQuery?: Maybe; inspect: boolean; + isDNSHistogram: boolean; + isPtrIncluded: boolean; + pagination: PaginationInputPaginated; + sort: NetworkDnsSortField; + sourceId: string; + stackByField?: Maybe; + timerange: TimerangeInput; }; export type Query = { diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/navigation/authentications_query_tab_body.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/navigation/authentications_query_tab_body.tsx index 7a0a25ef18842..0bb9563296316 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/navigation/authentications_query_tab_body.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/navigation/authentications_query_tab_body.tsx @@ -5,18 +5,48 @@ */ import { getOr } from 'lodash/fp'; -import React from 'react'; +import React, { useEffect } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { AuthenticationTable } from '../../../components/page/hosts/authentications_table'; import { manageQuery } from '../../../components/page/manage_query'; -import { AuthenticationsOverTimeHistogram } from '../../../components/page/hosts/authentications_over_time'; -import { AuthenticationsOverTimeQuery } from '../../../containers/authentications/authentications_over_time'; import { AuthenticationsQuery } from '../../../containers/authentications'; import { HostsComponentsQueryProps } from './types'; import { hostsModel } from '../../../store/hosts'; +import { + MatrixHistogramOption, + MatrixHistogramMappingTypes, +} from '../../../components/matrix_histogram/types'; +import { MatrixHistogramContainer } from '../../../containers/matrix_histogram'; +import { KpiHostsChartColors } from '../../../components/page/hosts/kpi_hosts/types'; +import { MatrixHistogramGqlQuery } from '../../../containers/matrix_histogram/index.gql_query'; +import * as i18n from '../translations'; const AuthenticationTableManage = manageQuery(AuthenticationTable); -const AuthenticationsOverTimeManage = manageQuery(AuthenticationsOverTimeHistogram); +const ID = 'authenticationsOverTimeQuery'; +const authStackByOptions: MatrixHistogramOption[] = [ + { + text: i18n.NAVIGATION_AUTHENTICATIONS_STACK_BY_EVENT_TYPE, + value: 'event.type', + }, +]; + +enum AuthMatrixDataGroup { + authSuccess = 'authentication_success', + authFailure = 'authentication_failure', +} + +export const authMatrixDataMappingFields: MatrixHistogramMappingTypes = { + [AuthMatrixDataGroup.authSuccess]: { + key: AuthMatrixDataGroup.authSuccess, + value: null, + color: KpiHostsChartColors.authSuccess, + }, + [AuthMatrixDataGroup.authFailure]: { + key: AuthMatrixDataGroup.authFailure, + value: null, + color: KpiHostsChartColors.authFailure, + }, +}; export const AuthenticationsQueryTabBody = ({ deleteQuery, @@ -27,68 +57,75 @@ export const AuthenticationsQueryTabBody = ({ startDate, type, updateDateRange = () => {}, -}: HostsComponentsQueryProps) => ( - <> - - {({ authenticationsOverTime, loading, id, inspect, refetch, totalCount }) => ( - - )} - - - - {({ - authentications, - totalCount, - loading, - pageInfo, - loadPage, - id, - inspect, - isInspected, - refetch, - }) => ( - - )} - - -); +}: HostsComponentsQueryProps) => { + useEffect(() => { + return () => { + if (deleteQuery) { + deleteQuery({ id: ID }); + } + }; + }, [deleteQuery]); + return ( + <> + + + + {({ + authentications, + totalCount, + loading, + pageInfo, + loadPage, + id, + inspect, + isInspected, + refetch, + }) => ( + + )} + + + ); +}; AuthenticationsQueryTabBody.displayName = 'AuthenticationsQueryTabBody'; diff --git a/x-pack/legacy/plugins/siem/public/pages/hosts/navigation/events_query_tab_body.tsx b/x-pack/legacy/plugins/siem/public/pages/hosts/navigation/events_query_tab_body.tsx index 223538c07d5df..2a7d2fab577c3 100644 --- a/x-pack/legacy/plugins/siem/public/pages/hosts/navigation/events_query_tab_body.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/hosts/navigation/events_query_tab_body.tsx @@ -4,50 +4,64 @@ * you may not use this file except in compliance with the Elastic License. */ -import React from 'react'; +import React, { useEffect } from 'react'; import { EuiSpacer } from '@elastic/eui'; import { StatefulEventsViewer } from '../../../components/events_viewer'; import { HostsComponentsQueryProps } from './types'; -import { manageQuery } from '../../../components/page/manage_query'; -import { EventsOverTimeHistogram } from '../../../components/page/hosts/events_over_time'; -import { EventsOverTimeQuery } from '../../../containers/events/events_over_time'; import { hostsModel } from '../../../store/hosts'; import { eventsDefaultModel } from '../../../components/events_viewer/default_model'; +import { MatrixHistogramOption } from '../../../components/matrix_histogram/types'; +import { MatrixHistogramContainer } from '../../../containers/matrix_histogram'; +import { MatrixHistogramGqlQuery } from '../../../containers/matrix_histogram/index.gql_query'; +import * as i18n from '../translations'; const HOSTS_PAGE_TIMELINE_ID = 'hosts-page'; -const EventsOverTimeManage = manageQuery(EventsOverTimeHistogram); +const EVENTS_HISTOGRAM_ID = 'eventsOverTimeQuery'; + +const eventsStackByOptions: MatrixHistogramOption[] = [ + { + text: i18n.NAVIGATION_EVENTS_STACK_BY_EVENT_ACTION, + value: 'event.action', + }, +]; export const EventsQueryTabBody = ({ + deleteQuery, endDate, filterQuery, setQuery, + skip, startDate, updateDateRange = () => {}, }: HostsComponentsQueryProps) => { + useEffect(() => { + return () => { + if (deleteQuery) { + deleteQuery({ id: EVENTS_HISTOGRAM_ID }); + } + }; + }, [deleteQuery]); return ( <> - - {({ eventsOverTime, loading, id, inspect, refetch, totalCount }) => ( - - )} - + title={i18n.NAVIGATION_EVENTS_TITLE} + updateDateRange={updateDateRange} + id={EVENTS_HISTOGRAM_ID} + /> {}, -}: NetworkComponentQueryProps) => ( - <> - - {({ totalCount, loading, id, inspect, refetch, histogram }) => ( - - )} - - +}: NetworkComponentQueryProps) => { + useEffect(() => { + return () => { + if (deleteQuery) { + deleteQuery({ id: HISTOGRAM_ID }); + } + }; + }, [deleteQuery]); + const formatBytes = useFormatBytes(); + + return ( ( - + <> + + + + )} - -); + ); +}; DnsQueryTabBody.displayName = 'DNSQueryTabBody'; diff --git a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx index ad3513a6f529e..ae7921db29459 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/network.tsx +++ b/x-pack/legacy/plugins/siem/public/pages/network/network.tsx @@ -133,14 +133,14 @@ const NetworkComponent = React.memo( diff --git a/x-pack/legacy/plugins/siem/public/pages/network/translations.ts b/x-pack/legacy/plugins/siem/public/pages/network/translations.ts index 91c3338ff7903..35224fd615978 100644 --- a/x-pack/legacy/plugins/siem/public/pages/network/translations.ts +++ b/x-pack/legacy/plugins/siem/public/pages/network/translations.ts @@ -35,6 +35,20 @@ export const NAVIGATION_DNS_TITLE = i18n.translate('xpack.siem.network.navigatio defaultMessage: 'DNS', }); +export const NAVIGATION_DNS_STACK_BY_DOMAIN = i18n.translate( + 'xpack.siem.hosts.navigation.dns.stackByDomain', + { + defaultMessage: 'domain', + } +); + +export const ERROR_FETCHING_DNS_DATA = i18n.translate( + 'xpack.siem.hosts.navigation.dns.histogram.errorFetchingDnsData', + { + defaultMessage: 'Failed to query DNS data', + } +); + export const NAVIGATION_TLS_TITLE = i18n.translate('xpack.siem.network.navigation.tlsTitle', { defaultMessage: 'TLS', }); diff --git a/x-pack/legacy/plugins/siem/server/graphql/alerts/resolvers.ts b/x-pack/legacy/plugins/siem/server/graphql/alerts/resolvers.ts index 3becaa4d169d9..5a3a50d5c6ec6 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/alerts/resolvers.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/alerts/resolvers.ts @@ -31,6 +31,7 @@ export const createAlertsResolvers = ( const options = { ...createOptions(source, args, info), defaultIndex: args.defaultIndex, + stackByField: args.stackByField, }; return libs.alerts.getAlertsHistogramData(req, options); }, diff --git a/x-pack/legacy/plugins/siem/server/graphql/alerts/schema.gql.ts b/x-pack/legacy/plugins/siem/server/graphql/alerts/schema.gql.ts index f29b64772b8f6..ca91468b1e0f2 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/alerts/schema.gql.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/alerts/schema.gql.ts @@ -9,7 +9,7 @@ import gql from 'graphql-tag'; export const alertsSchema = gql` type AlertsOverTimeData { inspect: Inspect - alertsOverTimeByModule: [MatrixOverTimeHistogramData!]! + matrixHistogramData: [MatrixOverTimeHistogramData!]! totalCount: Float! } @@ -18,6 +18,7 @@ export const alertsSchema = gql` filterQuery: String defaultIndex: [String!]! timerange: TimerangeInput! + stackByField: String ): AlertsOverTimeData! } `; diff --git a/x-pack/legacy/plugins/siem/server/graphql/anomalies/resolvers.ts b/x-pack/legacy/plugins/siem/server/graphql/anomalies/resolvers.ts index 47e227a8c0f84..e7b7a640c58d2 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/anomalies/resolvers.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/anomalies/resolvers.ts @@ -15,7 +15,7 @@ export interface AnomaliesResolversDeps { } type QueryAnomaliesOverTimeResolver = ChildResolverOf< - AppResolverOf, + AppResolverOf, QuerySourceResolver >; @@ -23,14 +23,15 @@ export const createAnomaliesResolvers = ( libs: AnomaliesResolversDeps ): { Source: { - AnomaliesOverTime: QueryAnomaliesOverTimeResolver; + AnomaliesHistogram: QueryAnomaliesOverTimeResolver; }; } => ({ Source: { - async AnomaliesOverTime(source, args, { req }, info) { + async AnomaliesHistogram(source, args, { req }, info) { const options = { ...createOptions(source, args, info), defaultIndex: args.defaultIndex, + stackByField: args.stackByField, }; return libs.anomalies.getAnomaliesOverTime(req, options); }, diff --git a/x-pack/legacy/plugins/siem/server/graphql/anomalies/schema.gql.ts b/x-pack/legacy/plugins/siem/server/graphql/anomalies/schema.gql.ts index 1dad0aafd55b0..a0b834f705696 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/anomalies/schema.gql.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/anomalies/schema.gql.ts @@ -9,15 +9,16 @@ import gql from 'graphql-tag'; export const anomaliesSchema = gql` type AnomaliesOverTimeData { inspect: Inspect - anomaliesOverTime: [MatrixOverTimeHistogramData!]! + matrixHistogramData: [MatrixOverTimeHistogramData!]! totalCount: Float! } extend type Source { - AnomaliesOverTime( + AnomaliesHistogram( timerange: TimerangeInput! filterQuery: String defaultIndex: [String!]! + stackByField: String ): AnomaliesOverTimeData! } `; diff --git a/x-pack/legacy/plugins/siem/server/graphql/authentications/resolvers.ts b/x-pack/legacy/plugins/siem/server/graphql/authentications/resolvers.ts index aaa66215e98f4..ce1c86ac8926c 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/authentications/resolvers.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/authentications/resolvers.ts @@ -16,7 +16,7 @@ type QueryAuthenticationsResolver = ChildResolverOf< >; type QueryAuthenticationsOverTimeResolver = ChildResolverOf< - AppResolverOf, + AppResolverOf, QuerySourceResolver >; @@ -29,7 +29,7 @@ export const createAuthenticationsResolvers = ( ): { Source: { Authentications: QueryAuthenticationsResolver; - AuthenticationsOverTime: QueryAuthenticationsOverTimeResolver; + AuthenticationsHistogram: QueryAuthenticationsOverTimeResolver; }; } => ({ Source: { @@ -37,10 +37,11 @@ export const createAuthenticationsResolvers = ( const options = createOptionsPaginated(source, args, info); return libs.authentications.getAuthentications(req, options); }, - async AuthenticationsOverTime(source, args, { req }, info) { + async AuthenticationsHistogram(source, args, { req }, info) { const options = { ...createOptions(source, args, info), defaultIndex: args.defaultIndex, + stackByField: args.stackByField, }; return libs.authentications.getAuthenticationsOverTime(req, options); }, diff --git a/x-pack/legacy/plugins/siem/server/graphql/authentications/schema.gql.ts b/x-pack/legacy/plugins/siem/server/graphql/authentications/schema.gql.ts index 5a65ef5d678ce..4acc72a5b0b6f 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/authentications/schema.gql.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/authentications/schema.gql.ts @@ -36,7 +36,7 @@ export const authenticationsSchema = gql` type AuthenticationsOverTimeData { inspect: Inspect - authenticationsOverTime: [MatrixOverTimeHistogramData!]! + matrixHistogramData: [MatrixOverTimeHistogramData!]! totalCount: Float! } @@ -48,10 +48,11 @@ export const authenticationsSchema = gql` filterQuery: String defaultIndex: [String!]! ): AuthenticationsData! - AuthenticationsOverTime( + AuthenticationsHistogram( timerange: TimerangeInput! filterQuery: String defaultIndex: [String!]! + stackByField: String ): AuthenticationsOverTimeData! } `; diff --git a/x-pack/legacy/plugins/siem/server/graphql/events/resolvers.ts b/x-pack/legacy/plugins/siem/server/graphql/events/resolvers.ts index 09494594c7286..335f4c3bf4da3 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/events/resolvers.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/events/resolvers.ts @@ -33,7 +33,7 @@ export interface EventsResolversDeps { } type QueryEventsOverTimeResolver = ChildResolverOf< - AppResolverOf, + AppResolverOf, QuerySourceResolver >; @@ -44,7 +44,7 @@ export const createEventsResolvers = ( Timeline: QueryTimelineResolver; TimelineDetails: QueryTimelineDetailsResolver; LastEventTime: QueryLastEventTimeResolver; - EventsOverTime: QueryEventsOverTimeResolver; + EventsHistogram: QueryEventsOverTimeResolver; }; } => ({ Source: { @@ -71,10 +71,11 @@ export const createEventsResolvers = ( }; return libs.events.getLastEventTimeData(req, options); }, - async EventsOverTime(source, args, { req }, info) { + async EventsHistogram(source, args, { req }, info) { const options = { ...createOptions(source, args, info), defaultIndex: args.defaultIndex, + stackByField: args.stackByField, }; return libs.events.getEventsOverTime(req, options); }, diff --git a/x-pack/legacy/plugins/siem/server/graphql/events/schema.gql.ts b/x-pack/legacy/plugins/siem/server/graphql/events/schema.gql.ts index 073fd60dbf1ed..9b321d10614fc 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/events/schema.gql.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/events/schema.gql.ts @@ -76,7 +76,7 @@ export const eventsSchema = gql` type EventsOverTimeData { inspect: Inspect - eventsOverTime: [MatrixOverTimeHistogramData!]! + matrixHistogramData: [MatrixOverTimeHistogramData!]! totalCount: Float! } @@ -100,10 +100,11 @@ export const eventsSchema = gql` details: LastTimeDetails! defaultIndex: [String!]! ): LastEventTimeData! - EventsOverTime( + EventsHistogram( timerange: TimerangeInput! filterQuery: String defaultIndex: [String!]! + stackByField: String ): EventsOverTimeData! } `; diff --git a/x-pack/legacy/plugins/siem/server/graphql/network/resolvers.ts b/x-pack/legacy/plugins/siem/server/graphql/network/resolvers.ts index db15babc42a72..2dabd51c198f7 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/network/resolvers.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/network/resolvers.ts @@ -76,6 +76,7 @@ export const createNetworkResolvers = ( ...createOptionsPaginated(source, args, info), networkDnsSortField: args.sort, isPtrIncluded: args.isPtrIncluded, + stackByField: args.stackByField, }; return libs.network.getNetworkDns(req, options); }, diff --git a/x-pack/legacy/plugins/siem/server/graphql/network/schema.gql.ts b/x-pack/legacy/plugins/siem/server/graphql/network/schema.gql.ts index 11aea7ffb07cf..a5bca68fb30b9 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/network/schema.gql.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/network/schema.gql.ts @@ -223,6 +223,7 @@ export const networkSchema = gql` isPtrIncluded: Boolean! pagination: PaginationInputPaginated! sort: NetworkDnsSortField! + stackByField: String timerange: TimerangeInput! defaultIndex: [String!]! ): NetworkDnsData! diff --git a/x-pack/legacy/plugins/siem/server/graphql/types.ts b/x-pack/legacy/plugins/siem/server/graphql/types.ts index 776444b1502b1..c610be2e0b477 100644 --- a/x-pack/legacy/plugins/siem/server/graphql/types.ts +++ b/x-pack/legacy/plugins/siem/server/graphql/types.ts @@ -461,11 +461,11 @@ export interface Source { AlertsHistogram: AlertsOverTimeData; - AnomaliesOverTime: AnomaliesOverTimeData; + AnomaliesHistogram: AnomaliesOverTimeData; /** Gets Authentication success and failures based on a timerange */ Authentications: AuthenticationsData; - AuthenticationsOverTime: AuthenticationsOverTimeData; + AuthenticationsHistogram: AuthenticationsOverTimeData; Timeline: TimelineData; @@ -473,7 +473,7 @@ export interface Source { LastEventTime: LastEventTimeData; - EventsOverTime: EventsOverTimeData; + EventsHistogram: EventsOverTimeData; /** Gets Hosts based on timerange and specified criteria, or all events in the timerange if no criteria is specified */ Hosts: HostsData; @@ -565,7 +565,7 @@ export interface IndexField { export interface AlertsOverTimeData { inspect?: Maybe; - alertsOverTimeByModule: MatrixOverTimeHistogramData[]; + matrixHistogramData: MatrixOverTimeHistogramData[]; totalCount: number; } @@ -587,7 +587,7 @@ export interface MatrixOverTimeHistogramData { export interface AnomaliesOverTimeData { inspect?: Maybe; - anomaliesOverTime: MatrixOverTimeHistogramData[]; + matrixHistogramData: MatrixOverTimeHistogramData[]; totalCount: number; } @@ -729,7 +729,7 @@ export interface PageInfoPaginated { export interface AuthenticationsOverTimeData { inspect?: Maybe; - authenticationsOverTime: MatrixOverTimeHistogramData[]; + matrixHistogramData: MatrixOverTimeHistogramData[]; totalCount: number; } @@ -1313,7 +1313,7 @@ export interface LastEventTimeData { export interface EventsOverTimeData { inspect?: Maybe; - eventsOverTime: MatrixOverTimeHistogramData[]; + matrixHistogramData: MatrixOverTimeHistogramData[]; totalCount: number; } @@ -2155,13 +2155,17 @@ export interface AlertsHistogramSourceArgs { defaultIndex: string[]; timerange: TimerangeInput; + + stackByField?: Maybe; } -export interface AnomaliesOverTimeSourceArgs { +export interface AnomaliesHistogramSourceArgs { timerange: TimerangeInput; filterQuery?: Maybe; defaultIndex: string[]; + + stackByField?: Maybe; } export interface AuthenticationsSourceArgs { timerange: TimerangeInput; @@ -2172,12 +2176,14 @@ export interface AuthenticationsSourceArgs { defaultIndex: string[]; } -export interface AuthenticationsOverTimeSourceArgs { +export interface AuthenticationsHistogramSourceArgs { timerange: TimerangeInput; filterQuery?: Maybe; defaultIndex: string[]; + + stackByField?: Maybe; } export interface TimelineSourceArgs { pagination: PaginationInput; @@ -2208,12 +2214,14 @@ export interface LastEventTimeSourceArgs { defaultIndex: string[]; } -export interface EventsOverTimeSourceArgs { +export interface EventsHistogramSourceArgs { timerange: TimerangeInput; filterQuery?: Maybe; defaultIndex: string[]; + + stackByField?: Maybe; } export interface HostsSourceArgs { id?: Maybe; @@ -2342,6 +2350,8 @@ export interface NetworkDnsSourceArgs { sort: NetworkDnsSortField; + stackByField?: Maybe; + timerange: TimerangeInput; defaultIndex: string[]; @@ -2800,11 +2810,11 @@ export namespace SourceResolvers { AlertsHistogram?: AlertsHistogramResolver; - AnomaliesOverTime?: AnomaliesOverTimeResolver; + AnomaliesHistogram?: AnomaliesHistogramResolver; /** Gets Authentication success and failures based on a timerange */ Authentications?: AuthenticationsResolver; - AuthenticationsOverTime?: AuthenticationsOverTimeResolver< + AuthenticationsHistogram?: AuthenticationsHistogramResolver< AuthenticationsOverTimeData, TypeParent, TContext @@ -2816,7 +2826,7 @@ export namespace SourceResolvers { LastEventTime?: LastEventTimeResolver; - EventsOverTime?: EventsOverTimeResolver; + EventsHistogram?: EventsHistogramResolver; /** Gets Hosts based on timerange and specified criteria, or all events in the timerange if no criteria is specified */ Hosts?: HostsResolver; @@ -2883,19 +2893,23 @@ export namespace SourceResolvers { defaultIndex: string[]; timerange: TimerangeInput; + + stackByField?: Maybe; } - export type AnomaliesOverTimeResolver< + export type AnomaliesHistogramResolver< R = AnomaliesOverTimeData, Parent = Source, TContext = SiemContext - > = Resolver; - export interface AnomaliesOverTimeArgs { + > = Resolver; + export interface AnomaliesHistogramArgs { timerange: TimerangeInput; filterQuery?: Maybe; defaultIndex: string[]; + + stackByField?: Maybe; } export type AuthenticationsResolver< @@ -2913,17 +2927,19 @@ export namespace SourceResolvers { defaultIndex: string[]; } - export type AuthenticationsOverTimeResolver< + export type AuthenticationsHistogramResolver< R = AuthenticationsOverTimeData, Parent = Source, TContext = SiemContext - > = Resolver; - export interface AuthenticationsOverTimeArgs { + > = Resolver; + export interface AuthenticationsHistogramArgs { timerange: TimerangeInput; filterQuery?: Maybe; defaultIndex: string[]; + + stackByField?: Maybe; } export type TimelineResolver< @@ -2973,17 +2989,19 @@ export namespace SourceResolvers { defaultIndex: string[]; } - export type EventsOverTimeResolver< + export type EventsHistogramResolver< R = EventsOverTimeData, Parent = Source, TContext = SiemContext - > = Resolver; - export interface EventsOverTimeArgs { + > = Resolver; + export interface EventsHistogramArgs { timerange: TimerangeInput; filterQuery?: Maybe; defaultIndex: string[]; + + stackByField?: Maybe; } export type HostsResolver = Resolver< @@ -3180,6 +3198,8 @@ export namespace SourceResolvers { sort: NetworkDnsSortField; + stackByField?: Maybe; + timerange: TimerangeInput; defaultIndex: string[]; @@ -3443,7 +3463,7 @@ export namespace AlertsOverTimeDataResolvers { export interface Resolvers { inspect?: InspectResolver, TypeParent, TContext>; - alertsOverTimeByModule?: AlertsOverTimeByModuleResolver< + matrixHistogramData?: MatrixHistogramDataResolver< MatrixOverTimeHistogramData[], TypeParent, TContext @@ -3457,7 +3477,7 @@ export namespace AlertsOverTimeDataResolvers { Parent = AlertsOverTimeData, TContext = SiemContext > = Resolver; - export type AlertsOverTimeByModuleResolver< + export type MatrixHistogramDataResolver< R = MatrixOverTimeHistogramData[], Parent = AlertsOverTimeData, TContext = SiemContext @@ -3518,7 +3538,7 @@ export namespace AnomaliesOverTimeDataResolvers { export interface Resolvers { inspect?: InspectResolver, TypeParent, TContext>; - anomaliesOverTime?: AnomaliesOverTimeResolver< + matrixHistogramData?: MatrixHistogramDataResolver< MatrixOverTimeHistogramData[], TypeParent, TContext @@ -3532,7 +3552,7 @@ export namespace AnomaliesOverTimeDataResolvers { Parent = AnomaliesOverTimeData, TContext = SiemContext > = Resolver; - export type AnomaliesOverTimeResolver< + export type MatrixHistogramDataResolver< R = MatrixOverTimeHistogramData[], Parent = AnomaliesOverTimeData, TContext = SiemContext @@ -3993,7 +4013,7 @@ export namespace AuthenticationsOverTimeDataResolvers { export interface Resolvers { inspect?: InspectResolver, TypeParent, TContext>; - authenticationsOverTime?: AuthenticationsOverTimeResolver< + matrixHistogramData?: MatrixHistogramDataResolver< MatrixOverTimeHistogramData[], TypeParent, TContext @@ -4007,7 +4027,7 @@ export namespace AuthenticationsOverTimeDataResolvers { Parent = AuthenticationsOverTimeData, TContext = SiemContext > = Resolver; - export type AuthenticationsOverTimeResolver< + export type MatrixHistogramDataResolver< R = MatrixOverTimeHistogramData[], Parent = AuthenticationsOverTimeData, TContext = SiemContext @@ -5947,7 +5967,11 @@ export namespace EventsOverTimeDataResolvers { export interface Resolvers { inspect?: InspectResolver, TypeParent, TContext>; - eventsOverTime?: EventsOverTimeResolver; + matrixHistogramData?: MatrixHistogramDataResolver< + MatrixOverTimeHistogramData[], + TypeParent, + TContext + >; totalCount?: TotalCountResolver; } @@ -5957,7 +5981,7 @@ export namespace EventsOverTimeDataResolvers { Parent = EventsOverTimeData, TContext = SiemContext > = Resolver; - export type EventsOverTimeResolver< + export type MatrixHistogramDataResolver< R = MatrixOverTimeHistogramData[], Parent = EventsOverTimeData, TContext = SiemContext diff --git a/x-pack/legacy/plugins/siem/server/lib/alerts/elasticsearch_adapter.ts b/x-pack/legacy/plugins/siem/server/lib/alerts/elasticsearch_adapter.ts index 6667f34b1b738..cedd781596812 100644 --- a/x-pack/legacy/plugins/siem/server/lib/alerts/elasticsearch_adapter.ts +++ b/x-pack/legacy/plugins/siem/server/lib/alerts/elasticsearch_adapter.ts @@ -10,7 +10,7 @@ import { AlertsOverTimeData, MatrixOverTimeHistogramData } from '../../graphql/t import { inspectStringifyObject } from '../../utils/build_query'; -import { FrameworkAdapter, FrameworkRequest, RequestBasicOptions } from '../framework'; +import { FrameworkAdapter, FrameworkRequest, MatrixHistogramRequestOptions } from '../framework'; import { buildAlertsHistogramQuery } from './query.dsl'; import { AlertsAdapter, AlertsGroupData, AlertsBucket } from './types'; @@ -22,7 +22,7 @@ export class ElasticsearchAlertsAdapter implements AlertsAdapter { public async getAlertsHistogramData( request: FrameworkRequest, - options: RequestBasicOptions + options: MatrixHistogramRequestOptions ): Promise { const dsl = buildAlertsHistogramQuery(options); const response = await this.framework.callWithRequest( @@ -31,14 +31,14 @@ export class ElasticsearchAlertsAdapter implements AlertsAdapter { dsl ); const totalCount = getOr(0, 'hits.total.value', response); - const alertsOverTimeByModule = getOr([], 'aggregations.alertsByModuleGroup.buckets', response); + const matrixHistogramData = getOr([], 'aggregations.alertsByModuleGroup.buckets', response); const inspect = { dsl: [inspectStringifyObject(dsl)], response: [inspectStringifyObject(response)], }; return { inspect, - alertsOverTimeByModule: getAlertsOverTimeByModule(alertsOverTimeByModule), + matrixHistogramData: getAlertsOverTimeByModule(matrixHistogramData), totalCount, }; } diff --git a/x-pack/legacy/plugins/siem/server/lib/alerts/elasticseatch_adapter.test.ts b/x-pack/legacy/plugins/siem/server/lib/alerts/elasticseatch_adapter.test.ts index a24fb5f511d24..3aefb6c0e1e5f 100644 --- a/x-pack/legacy/plugins/siem/server/lib/alerts/elasticseatch_adapter.test.ts +++ b/x-pack/legacy/plugins/siem/server/lib/alerts/elasticseatch_adapter.test.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { FrameworkAdapter, FrameworkRequest, RequestBasicOptions } from '../framework'; +import { FrameworkAdapter, FrameworkRequest, MatrixHistogramRequestOptions } from '../framework'; import expect from '@kbn/expect'; import { ElasticsearchAlertsAdapter } from './elasticsearch_adapter'; @@ -41,11 +41,11 @@ describe('alerts elasticsearch_adapter', () => { const EsNetworkTimelineAlerts = new ElasticsearchAlertsAdapter(mockFramework); const data = await EsNetworkTimelineAlerts.getAlertsHistogramData( (mockRequest as unknown) as FrameworkRequest, - (mockOptions as unknown) as RequestBasicOptions + (mockOptions as unknown) as MatrixHistogramRequestOptions ); expect(data).to.eql({ - alertsOverTimeByModule: mockAlertsHistogramDataFormattedResponse, + matrixHistogramData: mockAlertsHistogramDataFormattedResponse, inspect: { dsl: ['"mockAlertsHistogramQueryDsl"'], response: [JSON.stringify(mockAlertsHistogramDataResponse, null, 2)], diff --git a/x-pack/legacy/plugins/siem/server/lib/alerts/index.ts b/x-pack/legacy/plugins/siem/server/lib/alerts/index.ts index 13a693a6e1fbb..9cfb1841edfef 100644 --- a/x-pack/legacy/plugins/siem/server/lib/alerts/index.ts +++ b/x-pack/legacy/plugins/siem/server/lib/alerts/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { FrameworkRequest, RequestBasicOptions } from '../framework'; +import { FrameworkRequest, MatrixHistogramRequestOptions } from '../framework'; export * from './elasticsearch_adapter'; import { AlertsAdapter } from './types'; import { AlertsOverTimeData } from '../../graphql/types'; @@ -14,7 +14,7 @@ export class Alerts { public async getAlertsHistogramData( req: FrameworkRequest, - options: RequestBasicOptions + options: MatrixHistogramRequestOptions ): Promise { return this.adapter.getAlertsHistogramData(req, options); } diff --git a/x-pack/legacy/plugins/siem/server/lib/alerts/query.dsl.ts b/x-pack/legacy/plugins/siem/server/lib/alerts/query.dsl.ts index efa6ee01f2124..08015c3508b86 100644 --- a/x-pack/legacy/plugins/siem/server/lib/alerts/query.dsl.ts +++ b/x-pack/legacy/plugins/siem/server/lib/alerts/query.dsl.ts @@ -6,7 +6,7 @@ import { createQueryFilterClauses, calculateTimeseriesInterval } from '../../utils/build_query'; import { buildTimelineQuery } from '../events/query.dsl'; -import { RequestOptions, RequestBasicOptions } from '../framework'; +import { RequestOptions, MatrixHistogramRequestOptions } from '../framework'; export const buildAlertsQuery = (options: RequestOptions) => { const eventsQuery = buildTimelineQuery(options); @@ -35,7 +35,8 @@ export const buildAlertsHistogramQuery = ({ sourceConfiguration: { fields: { timestamp }, }, -}: RequestBasicOptions) => { + stackByField, +}: MatrixHistogramRequestOptions) => { const filter = [ ...createQueryFilterClauses(filterQuery), { @@ -84,7 +85,7 @@ export const buildAlertsHistogramQuery = ({ return { alertsByModuleGroup: { terms: { - field: 'event.module', + field: stackByField, missing: 'All others', order: { _count: 'desc', diff --git a/x-pack/legacy/plugins/siem/server/lib/alerts/types.ts b/x-pack/legacy/plugins/siem/server/lib/alerts/types.ts index e6a4ff4b7c9d1..67da38e8052d2 100644 --- a/x-pack/legacy/plugins/siem/server/lib/alerts/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/alerts/types.ts @@ -5,7 +5,7 @@ */ import { AlertsOverTimeData } from '../../graphql/types'; -import { FrameworkRequest, RequestBasicOptions } from '../framework'; +import { FrameworkRequest, MatrixHistogramRequestOptions } from '../framework'; export interface AlertsBucket { key: number; @@ -22,6 +22,6 @@ export interface AlertsGroupData { export interface AlertsAdapter { getAlertsHistogramData( request: FrameworkRequest, - options: RequestBasicOptions + options: MatrixHistogramRequestOptions ): Promise; } diff --git a/x-pack/legacy/plugins/siem/server/lib/anomalies/elasticsearch_adapter.ts b/x-pack/legacy/plugins/siem/server/lib/anomalies/elasticsearch_adapter.ts index f4b7aff4854e5..0955bc69c7c93 100644 --- a/x-pack/legacy/plugins/siem/server/lib/anomalies/elasticsearch_adapter.ts +++ b/x-pack/legacy/plugins/siem/server/lib/anomalies/elasticsearch_adapter.ts @@ -8,7 +8,7 @@ import { getOr } from 'lodash/fp'; import { AnomaliesOverTimeData } from '../../graphql/types'; import { inspectStringifyObject } from '../../utils/build_query'; -import { FrameworkAdapter, FrameworkRequest, RequestBasicOptions } from '../framework'; +import { FrameworkAdapter, FrameworkRequest, MatrixHistogramRequestOptions } from '../framework'; import { TermAggregation } from '../types'; import { AnomalyHit, AnomaliesAdapter, AnomaliesActionGroupData } from './types'; @@ -20,7 +20,7 @@ export class ElasticsearchAnomaliesAdapter implements AnomaliesAdapter { public async getAnomaliesOverTime( request: FrameworkRequest, - options: RequestBasicOptions + options: MatrixHistogramRequestOptions ): Promise { const dsl = buildAnomaliesOverTimeQuery(options); @@ -39,7 +39,7 @@ export class ElasticsearchAnomaliesAdapter implements AnomaliesAdapter { }; return { inspect, - anomaliesOverTime: getAnomaliesOverTimeByJobId(anomaliesOverTimeBucket), + matrixHistogramData: getAnomaliesOverTimeByJobId(anomaliesOverTimeBucket), totalCount, }; } diff --git a/x-pack/legacy/plugins/siem/server/lib/anomalies/index.ts b/x-pack/legacy/plugins/siem/server/lib/anomalies/index.ts index 7beeea4ad9e4e..727c45a3bac44 100644 --- a/x-pack/legacy/plugins/siem/server/lib/anomalies/index.ts +++ b/x-pack/legacy/plugins/siem/server/lib/anomalies/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { FrameworkRequest, RequestBasicOptions } from '../framework'; +import { FrameworkRequest, MatrixHistogramRequestOptions } from '../framework'; export * from './elasticsearch_adapter'; import { AnomaliesAdapter } from './types'; import { AnomaliesOverTimeData } from '../../../public/graphql/types'; @@ -14,7 +14,7 @@ export class Anomalies { public async getAnomaliesOverTime( req: FrameworkRequest, - options: RequestBasicOptions + options: MatrixHistogramRequestOptions ): Promise { return this.adapter.getAnomaliesOverTime(req, options); } diff --git a/x-pack/legacy/plugins/siem/server/lib/anomalies/query.anomalies_over_time.dsl.ts b/x-pack/legacy/plugins/siem/server/lib/anomalies/query.anomalies_over_time.dsl.ts index 34a6a6a8f601f..b0892a68f0a2e 100644 --- a/x-pack/legacy/plugins/siem/server/lib/anomalies/query.anomalies_over_time.dsl.ts +++ b/x-pack/legacy/plugins/siem/server/lib/anomalies/query.anomalies_over_time.dsl.ts @@ -5,13 +5,14 @@ */ import { createQueryFilterClauses, calculateTimeseriesInterval } from '../../utils/build_query'; -import { RequestBasicOptions } from '../framework'; +import { MatrixHistogramRequestOptions } from '../framework'; export const buildAnomaliesOverTimeQuery = ({ filterQuery, timerange: { from, to }, defaultIndex, -}: RequestBasicOptions) => { + stackByField = 'job_id', +}: MatrixHistogramRequestOptions) => { const filter = [ ...createQueryFilterClauses(filterQuery), { @@ -42,7 +43,7 @@ export const buildAnomaliesOverTimeQuery = ({ return { anomalyActionGroup: { terms: { - field: 'job_id', + field: stackByField, order: { _count: 'desc', }, diff --git a/x-pack/legacy/plugins/siem/server/lib/anomalies/types.ts b/x-pack/legacy/plugins/siem/server/lib/anomalies/types.ts index 1e13ad88f8af3..9fde81da63ec7 100644 --- a/x-pack/legacy/plugins/siem/server/lib/anomalies/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/anomalies/types.ts @@ -5,13 +5,13 @@ */ import { AnomaliesOverTimeData } from '../../graphql/types'; -import { FrameworkRequest, RequestBasicOptions } from '../framework'; +import { FrameworkRequest, MatrixHistogramRequestOptions } from '../framework'; import { SearchHit } from '../types'; export interface AnomaliesAdapter { getAnomaliesOverTime( req: FrameworkRequest, - options: RequestBasicOptions + options: MatrixHistogramRequestOptions ): Promise; } diff --git a/x-pack/legacy/plugins/siem/server/lib/authentications/elasticsearch_adapter.ts b/x-pack/legacy/plugins/siem/server/lib/authentications/elasticsearch_adapter.ts index 9a9e30bf01c04..85008adcd985f 100644 --- a/x-pack/legacy/plugins/siem/server/lib/authentications/elasticsearch_adapter.ts +++ b/x-pack/legacy/plugins/siem/server/lib/authentications/elasticsearch_adapter.ts @@ -17,7 +17,7 @@ import { FrameworkAdapter, FrameworkRequest, RequestOptionsPaginated, - RequestBasicOptions, + MatrixHistogramRequestOptions, } from '../framework'; import { TermAggregation } from '../types'; import { DEFAULT_MAX_TABLE_QUERY_SIZE } from '../../../common/constants'; @@ -112,7 +112,7 @@ export class ElasticsearchAuthenticationAdapter implements AuthenticationsAdapte public async getAuthenticationsOverTime( request: FrameworkRequest, - options: RequestBasicOptions + options: MatrixHistogramRequestOptions ): Promise { const dsl = buildAuthenticationsOverTimeQuery(options); const response = await this.framework.callWithRequest( @@ -132,7 +132,7 @@ export class ElasticsearchAuthenticationAdapter implements AuthenticationsAdapte }; return { inspect, - authenticationsOverTime: getAuthenticationsOverTimeByAuthenticationResult( + matrixHistogramData: getAuthenticationsOverTimeByAuthenticationResult( authenticationsOverTimeBucket ), totalCount, diff --git a/x-pack/legacy/plugins/siem/server/lib/authentications/index.ts b/x-pack/legacy/plugins/siem/server/lib/authentications/index.ts index b369c358e1619..bd5712c105f31 100644 --- a/x-pack/legacy/plugins/siem/server/lib/authentications/index.ts +++ b/x-pack/legacy/plugins/siem/server/lib/authentications/index.ts @@ -5,7 +5,11 @@ */ import { AuthenticationsData } from '../../graphql/types'; -import { FrameworkRequest, RequestOptionsPaginated, RequestBasicOptions } from '../framework'; +import { + FrameworkRequest, + RequestOptionsPaginated, + MatrixHistogramRequestOptions, +} from '../framework'; import { AuthenticationsAdapter } from './types'; import { AuthenticationsOverTimeData } from '../../../public/graphql/types'; @@ -22,7 +26,7 @@ export class Authentications { public async getAuthenticationsOverTime( req: FrameworkRequest, - options: RequestBasicOptions + options: MatrixHistogramRequestOptions ): Promise { return this.adapter.getAuthenticationsOverTime(req, options); } diff --git a/x-pack/legacy/plugins/siem/server/lib/authentications/query.authentications_over_time.dsl.ts b/x-pack/legacy/plugins/siem/server/lib/authentications/query.authentications_over_time.dsl.ts index a6b788cb70657..77b35fef77dca 100644 --- a/x-pack/legacy/plugins/siem/server/lib/authentications/query.authentications_over_time.dsl.ts +++ b/x-pack/legacy/plugins/siem/server/lib/authentications/query.authentications_over_time.dsl.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { createQueryFilterClauses, calculateTimeseriesInterval } from '../../utils/build_query'; -import { RequestBasicOptions } from '../framework'; +import { MatrixHistogramRequestOptions } from '../framework'; export const buildAuthenticationsOverTimeQuery = ({ filterQuery, @@ -13,7 +13,8 @@ export const buildAuthenticationsOverTimeQuery = ({ sourceConfiguration: { fields: { timestamp }, }, -}: RequestBasicOptions) => { + stackByField = 'event.type', +}: MatrixHistogramRequestOptions) => { const filter = [ ...createQueryFilterClauses(filterQuery), { @@ -44,7 +45,7 @@ export const buildAuthenticationsOverTimeQuery = ({ return { eventActionGroup: { terms: { - field: 'event.type', + field: stackByField, include: ['authentication_success', 'authentication_failure'], order: { _count: 'desc', diff --git a/x-pack/legacy/plugins/siem/server/lib/authentications/types.ts b/x-pack/legacy/plugins/siem/server/lib/authentications/types.ts index 6e83a2bdba956..e1ec871ff4b58 100644 --- a/x-pack/legacy/plugins/siem/server/lib/authentications/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/authentications/types.ts @@ -9,7 +9,11 @@ import { AuthenticationsOverTimeData, LastSourceHost, } from '../../graphql/types'; -import { FrameworkRequest, RequestOptionsPaginated, RequestBasicOptions } from '../framework'; +import { + FrameworkRequest, + RequestOptionsPaginated, + MatrixHistogramRequestOptions, +} from '../framework'; import { Hit, SearchHit, TotalHit } from '../types'; export interface AuthenticationsAdapter { @@ -19,7 +23,7 @@ export interface AuthenticationsAdapter { ): Promise; getAuthenticationsOverTime( req: FrameworkRequest, - options: RequestBasicOptions + options: MatrixHistogramRequestOptions ): Promise; } diff --git a/x-pack/legacy/plugins/siem/server/lib/events/elasticsearch_adapter.ts b/x-pack/legacy/plugins/siem/server/lib/events/elasticsearch_adapter.ts index dfa81122f9c23..d06f6c030b380 100644 --- a/x-pack/legacy/plugins/siem/server/lib/events/elasticsearch_adapter.ts +++ b/x-pack/legacy/plugins/siem/server/lib/events/elasticsearch_adapter.ts @@ -31,7 +31,7 @@ import { baseCategoryFields } from '../../utils/beat_schema/8.0.0'; import { reduceFields } from '../../utils/build_query/reduce_fields'; import { mergeFieldsWithHit, inspectStringifyObject } from '../../utils/build_query'; import { eventFieldsMap } from '../ecs_fields'; -import { FrameworkAdapter, FrameworkRequest, RequestBasicOptions } from '../framework'; +import { FrameworkAdapter, FrameworkRequest, MatrixHistogramRequestOptions } from '../framework'; import { TermAggregation } from '../types'; import { buildDetailsQuery, buildTimelineQuery } from './query.dsl'; @@ -131,7 +131,7 @@ export class ElasticsearchEventsAdapter implements EventsAdapter { public async getEventsOverTime( request: FrameworkRequest, - options: RequestBasicOptions + options: MatrixHistogramRequestOptions ): Promise { const dsl = buildEventsOverTimeQuery(options); const response = await this.framework.callWithRequest( @@ -147,7 +147,7 @@ export class ElasticsearchEventsAdapter implements EventsAdapter { }; return { inspect, - eventsOverTime: getEventsOverTimeByActionName(eventsOverTimeBucket), + matrixHistogramData: getEventsOverTimeByActionName(eventsOverTimeBucket), totalCount, }; } diff --git a/x-pack/legacy/plugins/siem/server/lib/events/query.events_over_time.dsl.ts b/x-pack/legacy/plugins/siem/server/lib/events/query.events_over_time.dsl.ts index 98bd6944c1b51..4b1837497669f 100644 --- a/x-pack/legacy/plugins/siem/server/lib/events/query.events_over_time.dsl.ts +++ b/x-pack/legacy/plugins/siem/server/lib/events/query.events_over_time.dsl.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { createQueryFilterClauses, calculateTimeseriesInterval } from '../../utils/build_query'; -import { RequestBasicOptions } from '../framework'; +import { MatrixHistogramRequestOptions } from '../framework'; export const buildEventsOverTimeQuery = ({ filterQuery, @@ -13,7 +13,8 @@ export const buildEventsOverTimeQuery = ({ sourceConfiguration: { fields: { timestamp }, }, -}: RequestBasicOptions) => { + stackByField = 'event.action', +}: MatrixHistogramRequestOptions) => { const filter = [ ...createQueryFilterClauses(filterQuery), { @@ -44,7 +45,7 @@ export const buildEventsOverTimeQuery = ({ return { eventActionGroup: { terms: { - field: 'event.action', + field: stackByField, missing: 'All others', order: { _count: 'desc', diff --git a/x-pack/legacy/plugins/siem/server/lib/framework/types.ts b/x-pack/legacy/plugins/siem/server/lib/framework/types.ts index 27254284b577d..67861ce0dcf28 100644 --- a/x-pack/legacy/plugins/siem/server/lib/framework/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/framework/types.ts @@ -17,6 +17,7 @@ import { SortField, SourceConfiguration, TimerangeInput, + Maybe, } from '../../graphql/types'; import { RequestFacade } from '../../types'; @@ -130,6 +131,10 @@ export interface RequestBasicOptions { defaultIndex: string[]; } +export interface MatrixHistogramRequestOptions extends RequestBasicOptions { + stackByField?: Maybe; +} + export interface RequestOptions extends RequestBasicOptions { pagination: PaginationInput; fields: readonly string[]; diff --git a/x-pack/legacy/plugins/siem/server/lib/network/index.ts b/x-pack/legacy/plugins/siem/server/lib/network/index.ts index 0a2de936799b6..42ce9f0726ddb 100644 --- a/x-pack/legacy/plugins/siem/server/lib/network/index.ts +++ b/x-pack/legacy/plugins/siem/server/lib/network/index.ts @@ -41,6 +41,7 @@ export interface NetworkHttpRequestOptions extends RequestOptionsPaginated { export interface NetworkDnsRequestOptions extends RequestOptionsPaginated { isPtrIncluded: boolean; networkDnsSortField: NetworkDnsSortField; + stackByField?: Maybe; } export class Network { diff --git a/x-pack/legacy/plugins/siem/server/lib/network/query_dns.dsl.ts b/x-pack/legacy/plugins/siem/server/lib/network/query_dns.dsl.ts index 48409cd938598..96b5d260b1544 100644 --- a/x-pack/legacy/plugins/siem/server/lib/network/query_dns.dsl.ts +++ b/x-pack/legacy/plugins/siem/server/lib/network/query_dns.dsl.ts @@ -64,6 +64,7 @@ export const buildDnsQuery = ({ sourceConfiguration: { fields: { timestamp }, }, + stackByField = 'dns.question.registered_domain', timerange: { from, to }, }: NetworkDnsRequestOptions) => { const filter = [ @@ -87,7 +88,7 @@ export const buildDnsQuery = ({ ...getCountAgg(), dns_name_query_count: { terms: { - field: 'dns.question.registered_domain', + field: stackByField, size: querySize, order: { ...getQueryOrder(networkDnsSortField), diff --git a/x-pack/legacy/plugins/siem/server/lib/network/types.ts b/x-pack/legacy/plugins/siem/server/lib/network/types.ts index 6afcb211b5996..960fbe425b002 100644 --- a/x-pack/legacy/plugins/siem/server/lib/network/types.ts +++ b/x-pack/legacy/plugins/siem/server/lib/network/types.ts @@ -12,6 +12,7 @@ import { } from '../../graphql/types'; import { FrameworkRequest, RequestOptionsPaginated } from '../framework'; import { TotalValue } from '../types'; +import { NetworkDnsRequestOptions } from '.'; export interface NetworkAdapter { getNetworkTopCountries( @@ -22,7 +23,7 @@ export interface NetworkAdapter { req: FrameworkRequest, options: RequestOptionsPaginated ): Promise; - getNetworkDns(req: FrameworkRequest, options: RequestOptionsPaginated): Promise; + getNetworkDns(req: FrameworkRequest, options: NetworkDnsRequestOptions): Promise; getNetworkHttp(req: FrameworkRequest, options: RequestOptionsPaginated): Promise; } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index ca49aea3ee885..92220e8c184bc 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10977,8 +10977,6 @@ "xpack.siem.auditd.violatedSeLinuxPolicyDescription": "selinuxポリシーに違反しました", "xpack.siem.auditd.wasAuthorizedToUseDescription": "が以下の使用を承認されました:", "xpack.siem.auditd.withResultDescription": "結果付き", - "xpack.siem.authenticationsOverTime.authenticationCountTitle": "認証カウント", - "xpack.siem.authenticationsOverTime.unit": "{totalCount, plural, =1 {authentication} other {authentications}}", "xpack.siem.authenticationsTable.authenticationFailures": "認証", "xpack.siem.authenticationsTable.failures": "失敗", "xpack.siem.authenticationsTable.lastFailedDestination": "前回失敗したデスティネーション", @@ -11112,9 +11110,6 @@ "xpack.siem.eventDetails.table": "表", "xpack.siem.eventDetails.toggleColumnTooltip": "列を切り替えます", "xpack.siem.eventDetails.value": "値", - "xpack.siem.eventsOverTime.eventCountFrequencyByActionTitle": "アクション別のイベントカウント", - "xpack.siem.eventsOverTime.showing": "表示中", - "xpack.siem.eventsOverTime.unit": "{totalCount, plural, =1 {event} other {events}}", "xpack.siem.eventsViewer.eventsLabel": "イベント", "xpack.siem.eventsViewer.showingLabel": "表示中", "xpack.siem.eventsViewer.unit": "{totalCount, plural, =1 {event} other {events}}", @@ -13275,4 +13270,4 @@ "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "フィールドを選択してください。", "xpack.watcher.watcherDescription": "アラートの作成、管理、監視によりデータへの変更を検知します。" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index ba6ff117c688d..a4037f9bd0f63 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -10976,8 +10976,6 @@ "xpack.siem.auditd.violatedSeLinuxPolicyDescription": "已违反 selinux 策略", "xpack.siem.auditd.wasAuthorizedToUseDescription": "有权使用", "xpack.siem.auditd.withResultDescription": ",结果为", - "xpack.siem.authenticationsOverTime.authenticationCountTitle": "身份验证计数", - "xpack.siem.authenticationsOverTime.unit": "{totalCount, plural, =1 {个身份验证} other {个身份验证}}", "xpack.siem.authenticationsTable.authenticationFailures": "身份验证", "xpack.siem.authenticationsTable.failures": "失败", "xpack.siem.authenticationsTable.lastFailedDestination": "上一失败目标", @@ -11111,9 +11109,6 @@ "xpack.siem.eventDetails.table": "表", "xpack.siem.eventDetails.toggleColumnTooltip": "切换列", "xpack.siem.eventDetails.value": "值", - "xpack.siem.eventsOverTime.eventCountFrequencyByActionTitle": "事件计数 - 按操作", - "xpack.siem.eventsOverTime.showing": "显示", - "xpack.siem.eventsOverTime.unit": "{totalCount, plural, =1 {个事件} other {个事件}}", "xpack.siem.eventsViewer.eventsLabel": "事件", "xpack.siem.eventsViewer.showingLabel": "显示", "xpack.siem.eventsViewer.unit": "{totalCount, plural, =1 {个事件} other {个事件}}", @@ -13274,4 +13269,4 @@ "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "此字段必填。", "xpack.watcher.watcherDescription": "通过创建、管理和监测警报来检测数据中的更改。" } -} \ No newline at end of file +} diff --git a/x-pack/test/api_integration/apis/siem/events_over_time.ts b/x-pack/test/api_integration/apis/siem/events_over_time.ts deleted file mode 100644 index 10b81734b7b79..0000000000000 --- a/x-pack/test/api_integration/apis/siem/events_over_time.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -import expect from '@kbn/expect'; -import { EventsOverTimeGqlQuery } from '../../../../legacy/plugins/siem/public/containers/events/events_over_time/events_over_time.gql_query'; -import { GetEventsOverTimeQuery } from '../../../../legacy/plugins/siem/public/graphql/types'; -import { FtrProviderContext } from '../../ftr_provider_context'; - -export default function({ getService }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); - const client = getService('siemGraphQLClient'); - const FROM = new Date('2000-01-01T00:00:00.000Z').valueOf(); - const TO = new Date('3000-01-01T00:00:00.000Z').valueOf(); - describe('Events over time', () => { - describe('With filebeat', () => { - before(() => esArchiver.load('filebeat/default')); - after(() => esArchiver.unload('filebeat/default')); - - it('Make sure that we get events over time data', () => { - return client - .query({ - query: EventsOverTimeGqlQuery, - variables: { - sourceId: 'default', - timerange: { - interval: '12h', - to: TO, - from: FROM, - }, - defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], - inspect: false, - }, - }) - .then(resp => { - const expectedData = [ - { - x: new Date('2018-12-20T00:00:00.000Z').valueOf(), - y: 4884, - g: 'All others', - __typename: 'MatrixOverTimeHistogramData', - }, - { - x: new Date('2018-12-20T00:00:00.000Z').valueOf(), - y: 1273, - g: 'netflow_flow', - __typename: 'MatrixOverTimeHistogramData', - }, - ]; - const eventsOverTime = resp.data.source.EventsOverTime; - expect(eventsOverTime.eventsOverTime).to.eql(expectedData); - }); - }); - }); - - describe('With packetbeat', () => { - before(() => esArchiver.load('packetbeat/default')); - after(() => esArchiver.unload('packetbeat/default')); - - it('Make sure that we get events over time data', () => { - return client - .query({ - query: EventsOverTimeGqlQuery, - variables: { - sourceId: 'default', - timerange: { - interval: '12h', - to: TO, - from: FROM, - }, - defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], - inspect: false, - }, - }) - .then(resp => { - const expectedData = [ - { - x: new Date('2018-12-20T00:00:00.000Z').valueOf(), - y: 4884, - g: 'All others', - __typename: 'MatrixOverTimeHistogramData', - }, - { - x: new Date('2018-12-20T00:00:00.000Z').valueOf(), - y: 1273, - g: 'netflow_flow', - __typename: 'MatrixOverTimeHistogramData', - }, - ]; - const eventsOverTime = resp.data.source.EventsOverTime; - expect(eventsOverTime.eventsOverTime).to.eql(expectedData); - }); - }); - }); - }); -} diff --git a/x-pack/test/api_integration/apis/siem/index.js b/x-pack/test/api_integration/apis/siem/index.js index ded2b36e8159e..ac10f89eac814 100644 --- a/x-pack/test/api_integration/apis/siem/index.js +++ b/x-pack/test/api_integration/apis/siem/index.js @@ -7,7 +7,6 @@ export default function({ loadTestFile }) { describe('Siem GraphQL Endpoints', () => { loadTestFile(require.resolve('./authentications')); - loadTestFile(require.resolve('./events_over_time')); loadTestFile(require.resolve('./hosts')); loadTestFile(require.resolve('./kpi_network')); loadTestFile(require.resolve('./kpi_hosts')); diff --git a/x-pack/test/api_integration/apis/siem/network_dns.ts b/x-pack/test/api_integration/apis/siem/network_dns.ts index db22da59257d6..5de7ea3a67087 100644 --- a/x-pack/test/api_integration/apis/siem/network_dns.ts +++ b/x-pack/test/api_integration/apis/siem/network_dns.ts @@ -29,22 +29,24 @@ export default function({ getService }: FtrProviderContext) { .query({ query: networkDnsQuery, variables: { - sourceId: 'default', - timerange: { - interval: '12h', - to: TO, - from: FROM, - }, + defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + isDNSHistogram: false, + inspect: false, isPtrIncluded: false, - sort: { field: NetworkDnsFields.uniqueDomains, direction: Direction.asc }, pagination: { activePage: 0, cursorStart: 0, fakePossibleCount: 30, querySize: 10, }, - defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], - inspect: false, + sort: { field: NetworkDnsFields.uniqueDomains, direction: Direction.asc }, + sourceId: 'default', + stackByField: 'dns.question.registered_domain', + timerange: { + interval: '12h', + to: TO, + from: FROM, + }, }, }) .then(resp => { @@ -63,22 +65,24 @@ export default function({ getService }: FtrProviderContext) { .query({ query: networkDnsQuery, variables: { - sourceId: 'default', - timerange: { - interval: '12h', - to: TO, - from: FROM, - }, + defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], + isDNSHistogram: false, + inspect: false, isPtrIncluded: false, - sort: { field: NetworkDnsFields.uniqueDomains, direction: Direction.desc }, pagination: { activePage: 0, cursorStart: 0, fakePossibleCount: 30, querySize: 10, }, - defaultIndex: ['auditbeat-*', 'filebeat-*', 'packetbeat-*', 'winlogbeat-*'], - inspect: false, + sourceId: 'default', + sort: { field: NetworkDnsFields.uniqueDomains, direction: Direction.desc }, + stackByField: 'dns.question.registered_domain', + timerange: { + interval: '12h', + to: TO, + from: FROM, + }, }, }) .then(resp => {