mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
## Summary
The default security data view includes the alerts index. This means that a rule that uses this data view can result in alerts on alerts. At first glance, it seems the default data view is equivalent to the default index patterns we normally display on rule creation, but it is not in that it includes the alerts index.
(cherry picked from commit b40663299a
)
Co-authored-by: Yara Tercero <yctercero@users.noreply.github.com>
This commit is contained in:
parent
d8f57738ff
commit
cd37a21ae3
3 changed files with 107 additions and 11 deletions
|
@ -6,22 +6,79 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallow, mount } from 'enzyme';
|
||||
|
||||
import { DataViewSelector } from '.';
|
||||
import { useFormFieldMock } from '../../../../common/mock';
|
||||
import type { DataViewSelectorProps } from '.';
|
||||
import { TestProviders, useFormFieldMock } from '../../../../common/mock';
|
||||
|
||||
jest.mock('../../../../common/lib/kibana');
|
||||
|
||||
describe('data_view_selector', () => {
|
||||
let mockField: DataViewSelectorProps['field'];
|
||||
|
||||
beforeEach(() => {
|
||||
mockField = useFormFieldMock<string | undefined>({
|
||||
value: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders correctly', () => {
|
||||
const Component = () => {
|
||||
const field = useFormFieldMock({ value: '' });
|
||||
// @ts-expect-error TODO: FIX THIS
|
||||
return <DataViewSelector kibanaDataViews={{}} setIndexPattern={jest.fn()} field={field} />;
|
||||
return <DataViewSelector kibanaDataViews={{}} field={mockField} />;
|
||||
};
|
||||
const wrapper = shallow(<Component />);
|
||||
|
||||
expect(wrapper.dive().find('[data-test-subj="pick-rule-data-source"]')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('displays alerts on alerts warning when default security view selected', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<DataViewSelector
|
||||
kibanaDataViews={{
|
||||
'security-solution-default': {
|
||||
id: 'security-solution-default',
|
||||
title:
|
||||
'-*elastic-cloud-logs-*,.alerts-security.alerts-default,apm-*-transaction*,auditbeat-*,endgame-*,filebeat-*,logs-*,packetbeat-*,traces-apm*,winlogbeat-*',
|
||||
},
|
||||
'1234': {
|
||||
id: '1234',
|
||||
title: 'logs-*',
|
||||
},
|
||||
}}
|
||||
field={useFormFieldMock<string | undefined>({
|
||||
value: 'security-solution-default',
|
||||
})}
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.find('[data-test-subj="defaultSecurityDataViewWarning"]').exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('does not display alerts on alerts warning when default security view is not selected', () => {
|
||||
const wrapper = mount(
|
||||
<TestProviders>
|
||||
<DataViewSelector
|
||||
kibanaDataViews={{
|
||||
'security-solution-default': {
|
||||
id: 'security-solution-default',
|
||||
title:
|
||||
'-*elastic-cloud-logs-*,.alerts-security.alerts-default,apm-*-transaction*,auditbeat-*,endgame-*,filebeat-*,logs-*,packetbeat-*,traces-apm*,winlogbeat-*',
|
||||
},
|
||||
'1234': {
|
||||
id: '1234',
|
||||
title: 'logs-*',
|
||||
},
|
||||
}}
|
||||
field={useFormFieldMock<string | undefined>({
|
||||
value: '1234',
|
||||
})}
|
||||
/>
|
||||
</TestProviders>
|
||||
);
|
||||
|
||||
expect(wrapper.find('[data-test-subj="defaultSecurityDataViewWarning"]').exists()).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ import { getFieldValidityAndErrorMessage } from '../../../../shared_imports';
|
|||
import * as i18n from './translations';
|
||||
import type { DefineStepRule } from '../../../pages/detection_engine/rules/types';
|
||||
|
||||
interface DataViewSelectorProps {
|
||||
export interface DataViewSelectorProps {
|
||||
kibanaDataViews: Record<string, DataViewListItem>;
|
||||
field: FieldHook<DefineStepRule['dataViewId']>;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ export const DataViewSelector = ({ kibanaDataViews, field }: DataViewSelectorPro
|
|||
let isInvalid;
|
||||
let errorMessage;
|
||||
let dataViewId: string | null | undefined;
|
||||
|
||||
if (field != null) {
|
||||
const fieldAndError = getFieldValidityAndErrorMessage(field);
|
||||
isInvalid = fieldAndError.isInvalid;
|
||||
|
@ -53,15 +54,26 @@ export const DataViewSelector = ({ kibanaDataViews, field }: DataViewSelectorPro
|
|||
: []
|
||||
);
|
||||
|
||||
const [showDataViewAlertsOnAlertsWarning, setShowDataViewAlertsOnAlertsWarning] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedDataViewNotFound && dataViewId) {
|
||||
setSelectedOption([
|
||||
{ id: kibanaDataViews[dataViewId].id, label: kibanaDataViews[dataViewId].title },
|
||||
]);
|
||||
const dataViewsTitle = kibanaDataViews[dataViewId].title;
|
||||
const dataViewsId = kibanaDataViews[dataViewId].id;
|
||||
|
||||
setShowDataViewAlertsOnAlertsWarning(dataViewsId === 'security-solution-default');
|
||||
|
||||
setSelectedOption([{ id: dataViewsId, label: dataViewsTitle }]);
|
||||
} else {
|
||||
setSelectedOption([]);
|
||||
}
|
||||
}, [dataViewId, field, kibanaDataViews, selectedDataViewNotFound]);
|
||||
}, [
|
||||
dataViewId,
|
||||
field,
|
||||
kibanaDataViews,
|
||||
selectedDataViewNotFound,
|
||||
setShowDataViewAlertsOnAlertsWarning,
|
||||
]);
|
||||
|
||||
// TODO: optimize this, pass down array of data view ids
|
||||
// at the same time we grab the data views in the top level form component
|
||||
|
@ -76,7 +88,6 @@ export const DataViewSelector = ({ kibanaDataViews, field }: DataViewSelectorPro
|
|||
|
||||
const onChangeDataViews = (options: Array<EuiComboBoxOptionOption<string>>) => {
|
||||
const selectedDataViewOption = options;
|
||||
|
||||
setSelectedOption(selectedDataViewOption ?? []);
|
||||
|
||||
if (
|
||||
|
@ -105,6 +116,19 @@ export const DataViewSelector = ({ kibanaDataViews, field }: DataViewSelectorPro
|
|||
<EuiSpacer size="s" />
|
||||
</>
|
||||
)}
|
||||
{showDataViewAlertsOnAlertsWarning && (
|
||||
<>
|
||||
<EuiCallOut
|
||||
title={i18n.DDATA_VIEW_ALERTS_ON_ALERTS_WARNING_LABEL}
|
||||
color="warning"
|
||||
iconType="help"
|
||||
data-test-subj="defaultSecurityDataViewWarning"
|
||||
>
|
||||
<p>{i18n.DATA_VIEW_ALERTS_ON_ALERTS_WARNING_DESCRIPTION}</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
)}
|
||||
<EuiFormRow
|
||||
label={field?.label}
|
||||
helpText={field?.helpText}
|
||||
|
|
|
@ -30,3 +30,18 @@ export const DATA_VIEW_NOT_FOUND_WARNING_DESCRIPTION = (dataView: string) =>
|
|||
'Your data view of "id": "{dataView}" was not found. It could be that it has since been deleted.',
|
||||
}
|
||||
);
|
||||
|
||||
export const DDATA_VIEW_ALERTS_ON_ALERTS_WARNING_LABEL = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.stepDefineRule.dataViewIncludesAlertsIndexLabel',
|
||||
{
|
||||
defaultMessage: 'Default Security data view',
|
||||
}
|
||||
);
|
||||
|
||||
export const DATA_VIEW_ALERTS_ON_ALERTS_WARNING_DESCRIPTION = i18n.translate(
|
||||
'xpack.securitySolution.detectionEngine.stepDefineRule.dataViewIncludesAlertsIndexDescription',
|
||||
{
|
||||
defaultMessage:
|
||||
'The default Security data view includes the alerts index. This could result in redundant alerts being generated from existing alerts.',
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue