[Security Solution] Incorrect alerts count is displaying under preview results for data view (#138131) (#138497)

* [Security Solution] Incorrect alerts count is displaying under preview results for data view (#137657)

* Fix CI

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
(cherry picked from commit 0a22f96594)

Co-authored-by: Ievgen Sorokopud <ievgen.sorokopud@elastic.co>
This commit is contained in:
Kibana Machine 2022-08-10 08:51:37 -04:00 committed by GitHub
parent 11c02dba31
commit 60230f5bb0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 80 additions and 18 deletions

View file

@ -5,6 +5,7 @@
* 2.0.
*/
import { DataSourceType } from '../../../pages/detection_engine/rules/types';
import {
isNoisy,
getTimeframeOptions,
@ -71,6 +72,7 @@ describe('query_preview/helpers', () => {
isThreatQueryBarValid: true,
index: [],
dataViewId: undefined,
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: ['threat-*'],
threatMapping: [
{ entries: [{ field: 'test-field', value: 'test-value', type: 'mapping' }] },
@ -89,6 +91,7 @@ describe('query_preview/helpers', () => {
isThreatQueryBarValid: true,
index: ['test-*'],
dataViewId: undefined,
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: ['threat-*'],
threatMapping: [
{ entries: [{ field: 'test-field', value: 'test-value', type: 'mapping' }] },
@ -107,6 +110,7 @@ describe('query_preview/helpers', () => {
isThreatQueryBarValid: false,
index: ['test-*'],
dataViewId: undefined,
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: ['threat-*'],
threatMapping: [
{ entries: [{ field: 'test-field', value: 'test-value', type: 'mapping' }] },
@ -125,6 +129,7 @@ describe('query_preview/helpers', () => {
isThreatQueryBarValid: true,
index: ['test-*'],
dataViewId: undefined,
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: [],
threatMapping: [
{ entries: [{ field: 'test-field', value: 'test-value', type: 'mapping' }] },
@ -143,6 +148,7 @@ describe('query_preview/helpers', () => {
isThreatQueryBarValid: true,
index: ['test-*'],
dataViewId: undefined,
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: ['threat-*'],
threatMapping: [],
machineLearningJobId: ['test-ml-job-id'],
@ -159,6 +165,7 @@ describe('query_preview/helpers', () => {
isThreatQueryBarValid: true,
index: ['test-*'],
dataViewId: undefined,
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: ['threat-*'],
threatMapping: [],
machineLearningJobId: [],
@ -175,6 +182,7 @@ describe('query_preview/helpers', () => {
isThreatQueryBarValid: true,
index: ['test-*'],
dataViewId: undefined,
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: ['threat-*'],
threatMapping: [],
machineLearningJobId: [],
@ -191,6 +199,7 @@ describe('query_preview/helpers', () => {
isThreatQueryBarValid: true,
index: ['test-*'],
dataViewId: undefined,
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: [],
threatMapping: [],
machineLearningJobId: [],
@ -207,6 +216,7 @@ describe('query_preview/helpers', () => {
isThreatQueryBarValid: true,
index: ['test-*'],
dataViewId: undefined,
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: ['threat-*'],
threatMapping: [
{ entries: [{ field: 'test-field', value: 'test-value', type: 'mapping' }] },
@ -225,6 +235,7 @@ describe('query_preview/helpers', () => {
isThreatQueryBarValid: true,
index: ['test-*'],
dataViewId: undefined,
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: ['threat-*'],
threatMapping: [],
machineLearningJobId: [],

View file

@ -16,6 +16,8 @@ import type { ChartSeriesConfigs } from '../../../../common/components/charts/co
import { getQueryFilter } from '../../../../../common/detection_engine/get_query_filter';
import type { FieldValueQueryBar } from '../query_bar';
import type { ESQuery } from '../../../../../common/typed_json';
import { DataSourceType } from '../../../pages/detection_engine/rules/types';
/**
* Determines whether or not to display noise warning.
* Is considered noisy if alerts/hour rate > 1
@ -165,6 +167,7 @@ export const getIsRulePreviewDisabled = ({
isThreatQueryBarValid,
index,
dataViewId,
dataSourceType,
threatIndex,
threatMapping,
machineLearningJobId,
@ -176,14 +179,20 @@ export const getIsRulePreviewDisabled = ({
isThreatQueryBarValid: boolean;
index: string[];
dataViewId: string | undefined;
dataSourceType: DataSourceType;
threatIndex: string[];
threatMapping: ThreatMapping;
machineLearningJobId: string[];
queryBar: FieldValueQueryBar;
newTermsFields: string[];
}) => {
if (!isQueryBarValid || ((index == null || index.length === 0) && dataViewId == null))
if (
!isQueryBarValid ||
(dataSourceType === DataSourceType.DataView && !dataViewId) ||
(dataSourceType === DataSourceType.IndexPatterns && index.length === 0)
) {
return true;
}
if (ruleType === 'threat_match') {
if (!isThreatQueryBarValid || !threatIndex.length || !threatMapping) return true;
if (

View file

@ -9,11 +9,15 @@ import React from 'react';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import type { DataViewBase } from '@kbn/es-query';
import { fields } from '@kbn/data-plugin/common/mocks';
import { TestProviders } from '../../../../common/mock';
import type { RulePreviewProps } from '.';
import { RulePreview } from '.';
import { usePreviewRoute } from './use_preview_route';
import { usePreviewHistogram } from './use_preview_histogram';
import { DataSourceType } from '../../../pages/detection_engine/rules/types';
jest.mock('../../../../common/lib/kibana');
jest.mock('./use_preview_route');
@ -27,9 +31,17 @@ jest.mock('../../../../common/containers/use_global_time', () => ({
}),
}));
const getMockIndexPattern = (): DataViewBase => ({
fields,
id: '1234',
title: 'logstash-*',
});
const defaultProps: RulePreviewProps = {
ruleType: 'threat_match',
index: ['test-*'],
indexPattern: getMockIndexPattern(),
dataSourceType: DataSourceType.IndexPatterns,
threatIndex: ['threat-*'],
threatMapping: [
{

View file

@ -10,6 +10,7 @@ import dateMath from '@kbn/datemath';
import type { Unit } from '@kbn/datemath';
import type { ThreatMapping, Type } from '@kbn/securitysolution-io-ts-alerting-types';
import styled from 'styled-components';
import type { DataViewBase } from '@kbn/es-query';
import type { EuiButtonGroupOptionProps, OnTimeChangeProps } from '@elastic/eui';
import {
EuiButtonGroup,
@ -39,7 +40,10 @@ import { useStartTransaction } from '../../../../common/lib/apm/use_start_transa
import { SINGLE_RULE_ACTIONS } from '../../../../common/lib/apm/user_actions';
import { Form, UseField, useForm, useFormData } from '../../../../shared_imports';
import { ScheduleItem } from '../schedule_item_form';
import type { AdvancedPreviewForm } from '../../../pages/detection_engine/rules/types';
import type {
AdvancedPreviewForm,
DataSourceType,
} from '../../../pages/detection_engine/rules/types';
import { schema } from './schema';
const HelpTextComponent = (
@ -70,9 +74,11 @@ const advancedOptionsDefaultValue = {
export interface RulePreviewProps {
index: string[];
indexPattern: DataViewBase;
isDisabled: boolean;
query: FieldValueQueryBar;
dataViewId?: string;
dataSourceType: DataSourceType;
ruleType: Type;
threatIndex: string[];
threatMapping: ThreatMapping;
@ -97,7 +103,9 @@ const defaultTimeRange: Unit = 'h';
const RulePreviewComponent: React.FC<RulePreviewProps> = ({
index,
indexPattern,
dataViewId,
dataSourceType,
isDisabled,
query,
ruleType,
@ -197,6 +205,7 @@ const RulePreviewComponent: React.FC<RulePreviewProps> = ({
index,
isDisabled,
dataViewId,
dataSourceType,
query,
threatIndex,
threatQuery,
@ -334,7 +343,7 @@ const RulePreviewComponent: React.FC<RulePreviewProps> = ({
previewId={previewId}
addNoiseWarning={addNoiseWarning}
spaceId={spaceId}
index={index}
indexPattern={indexPattern}
advancedOptions={advancedOptions}
/>
)}

View file

@ -9,6 +9,9 @@ import React from 'react';
import { render } from '@testing-library/react';
import moment from 'moment';
import type { DataViewBase } from '@kbn/es-query';
import { fields } from '@kbn/data-plugin/common/mocks';
import { useGlobalTime } from '../../../../common/containers/use_global_time';
import { TestProviders } from '../../../../common/mock';
import { usePreviewHistogram } from './use_preview_histogram';
@ -21,6 +24,12 @@ jest.mock('../../../../common/containers/use_global_time');
jest.mock('./use_preview_histogram');
jest.mock('../../../../common/utils/normalize_time_range');
const getMockIndexPattern = (): DataViewBase => ({
fields,
id: '1234',
title: 'logstash-*',
});
describe('PreviewHistogram', () => {
const mockSetQuery = jest.fn();
@ -58,7 +67,7 @@ describe('PreviewHistogram', () => {
previewId={'test-preview-id'}
spaceId={'default'}
ruleType={'query'}
index={['']}
indexPattern={getMockIndexPattern()}
/>
</TestProviders>
);
@ -89,7 +98,7 @@ describe('PreviewHistogram', () => {
previewId={'test-preview-id'}
spaceId={'default'}
ruleType={'query'}
index={['']}
indexPattern={getMockIndexPattern()}
/>
</TestProviders>
);
@ -141,7 +150,7 @@ describe('PreviewHistogram', () => {
previewId={'test-preview-id'}
spaceId={'default'}
ruleType={'query'}
index={['']}
indexPattern={getMockIndexPattern()}
advancedOptions={{
timeframeStart: moment(start, format),
timeframeEnd: moment(end, format),

View file

@ -12,6 +12,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiText, EuiSpacer, EuiLoadingChart } from '
import styled from 'styled-components';
import type { Type } from '@kbn/securitysolution-io-ts-alerting-types';
import { useDispatch, useSelector } from 'react-redux';
import type { DataViewBase } from '@kbn/es-query';
import { eventsViewerSelector } from '../../../../common/components/events_viewer/selectors';
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
import { useKibana } from '../../../../common/lib/kibana';
@ -63,7 +64,7 @@ interface PreviewHistogramProps {
addNoiseWarning: () => void;
spaceId: string;
ruleType: Type;
index: string[];
indexPattern: DataViewBase;
advancedOptions?: AdvancedPreviewOptions;
}
@ -75,7 +76,7 @@ export const PreviewHistogram = ({
addNoiseWarning,
spaceId,
ruleType,
index,
indexPattern,
advancedOptions,
}: PreviewHistogramProps) => {
const dispatch = useDispatch();
@ -99,7 +100,7 @@ export const PreviewHistogram = ({
startDate,
endDate,
spaceId,
index,
indexPattern,
ruleType,
});
@ -118,7 +119,7 @@ export const PreviewHistogram = ({
const {
browserFields,
indexPattern,
indexPattern: selectedIndexPattern,
runtimeMappings,
dataViewId: selectedDataViewId,
loading: isLoadingIndexPattern,
@ -225,7 +226,7 @@ export const PreviewHistogram = ({
hasAlertsCrud: false,
id: TimelineId.rulePreview,
indexNames: [`${DEFAULT_PREVIEW_INDEX}-${spaceId}`],
indexPattern,
indexPattern: selectedIndexPattern,
isLive: false,
isLoadingIndexPattern,
itemsPerPage,

View file

@ -7,6 +7,7 @@
import { useMemo } from 'react';
import type { Type } from '@kbn/securitysolution-io-ts-alerting-types';
import { getEsQueryConfig } from '@kbn/data-plugin/common';
import type { DataViewBase } from '@kbn/es-query';
import { useMatrixHistogramCombined } from '../../../../common/containers/matrix_histogram';
import { MatrixHistogramType } from '../../../../../common/search_strategy';
import { convertToBuildEsQuery } from '../../../../common/lib/keury';
@ -19,8 +20,8 @@ interface PreviewHistogramParams {
endDate: string;
startDate: string;
spaceId: string;
index: string[];
ruleType: Type;
indexPattern: DataViewBase;
}
export const usePreviewHistogram = ({
@ -28,17 +29,14 @@ export const usePreviewHistogram = ({
startDate,
endDate,
spaceId,
index,
ruleType,
indexPattern,
}: PreviewHistogramParams) => {
const { uiSettings } = useKibana().services;
const [filterQuery, error] = convertToBuildEsQuery({
config: getEsQueryConfig(uiSettings),
indexPattern: {
fields: [],
title: index == null ? '' : index.join(),
},
indexPattern,
queries: [{ query: `kibana.alert.rule.uuid:${previewId}`, language: 'kuery' }],
filters: [],
});

View file

@ -14,12 +14,16 @@ import { formatPreviewRule } from '../../../pages/detection_engine/rules/create/
import type { FieldValueThreshold } from '../threshold_input';
import type { RulePreviewLogs } from '../../../../../common/detection_engine/schemas/request';
import type { EqlOptionsSelected } from '../../../../../common/search_strategy';
import type { AdvancedPreviewOptions } from '../../../pages/detection_engine/rules/types';
import type {
AdvancedPreviewOptions,
DataSourceType,
} from '../../../pages/detection_engine/rules/types';
interface PreviewRouteParams {
isDisabled: boolean;
index: string[];
dataViewId?: string;
dataSourceType: DataSourceType;
threatIndex: string[];
query: FieldValueQueryBar;
threatQuery: FieldValueQueryBar;
@ -38,6 +42,7 @@ interface PreviewRouteParams {
export const usePreviewRoute = ({
index,
dataViewId,
dataSourceType,
isDisabled,
query,
threatIndex,
@ -107,6 +112,7 @@ export const usePreviewRoute = ({
formatPreviewRule({
index,
dataViewId,
dataSourceType,
query,
ruleType,
threatIndex,
@ -126,6 +132,7 @@ export const usePreviewRoute = ({
}, [
index,
dataViewId,
dataSourceType,
isRequestTriggered,
query,
rule,

View file

@ -834,13 +834,16 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({
<RuleTypeEuiFormRow label={i18n.RULE_PREVIEW_TITLE} $isVisible={true} fullWidth>
<RulePreview
index={index}
indexPattern={indexPattern}
dataViewId={formDataViewId}
dataSourceType={dataSourceType}
isDisabled={getIsRulePreviewDisabled({
ruleType,
isQueryBarValid,
isThreatQueryBarValid,
index,
dataViewId: formDataViewId,
dataSourceType,
threatIndex,
threatMapping: formThreatMapping,
machineLearningJobId,

View file

@ -580,6 +580,7 @@ export const formatRule = <T>(
export const formatPreviewRule = ({
index,
dataViewId,
dataSourceType,
query,
threatIndex,
threatQuery,
@ -596,6 +597,7 @@ export const formatPreviewRule = ({
}: {
index: string[];
dataViewId?: string;
dataSourceType: DataSourceType;
threatIndex: string[];
query: FieldValueQueryBar;
threatQuery: FieldValueQueryBar;
@ -614,6 +616,7 @@ export const formatPreviewRule = ({
...stepDefineDefaultValue,
index,
dataViewId,
dataSourceType,
queryBar: query,
ruleType,
threatIndex,