Skip to content

Commit

Permalink
[Security Solution][Detections] Updates RuleDetails to query alerts b…
Browse files Browse the repository at this point in the history
…y RuleId instead of Rule SO ID (#120053)

* Switches RuleDetails to query alerts by ruleId instead of SO id

* Increases integrity of test outputs

* Cleans up duplicate RuleRegistry functions

* Removes support for rule.id for alerts filter and updates exceptions to use new filter
  • Loading branch information
spong authored and kibanamachine committed Dec 8, 2021
1 parent 8a3953e commit 315e85c
Show file tree
Hide file tree
Showing 14 changed files with 102 additions and 294 deletions.
3 changes: 3 additions & 0 deletions packages/kbn-rule-data-utils/src/technical_field_names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const VERSION = `${KIBANA_NAMESPACE}.version` as const;

// Fields pertaining to the alert
const ALERT_ACTION_GROUP = `${ALERT_NAMESPACE}.action_group` as const;
const ALERT_BUILDING_BLOCK_TYPE = `${ALERT_NAMESPACE}.building_block_type` as const;
const ALERT_DURATION = `${ALERT_NAMESPACE}.duration.us` as const;
const ALERT_END = `${ALERT_NAMESPACE}.end` as const;
const ALERT_EVALUATION_THRESHOLD = `${ALERT_NAMESPACE}.evaluation.threshold` as const;
Expand Down Expand Up @@ -91,6 +92,7 @@ const fields = {
TAGS,
TIMESTAMP,
ALERT_ACTION_GROUP,
ALERT_BUILDING_BLOCK_TYPE,
ALERT_DURATION,
ALERT_END,
ALERT_EVALUATION_THRESHOLD,
Expand Down Expand Up @@ -141,6 +143,7 @@ const fields = {

export {
ALERT_ACTION_GROUP,
ALERT_BUILDING_BLOCK_TYPE,
ALERT_DURATION,
ALERT_END,
ALERT_EVALUATION_THRESHOLD,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,11 +327,16 @@ export const AddExceptionModal = memo(function AddExceptionModal({
const alertIdToClose = shouldCloseAlert && alertData ? alertData._id : undefined;
const bulkCloseIndex =
shouldBulkCloseAlert && signalIndexName != null ? [signalIndexName] : undefined;
addOrUpdateExceptionItems(ruleId, enrichExceptionItems(), alertIdToClose, bulkCloseIndex);
addOrUpdateExceptionItems(
maybeRule?.rule_id ?? '',
enrichExceptionItems(),
alertIdToClose,
bulkCloseIndex
);
}
}, [
addOrUpdateExceptionItems,
ruleId,
maybeRule,
enrichExceptionItems,
shouldCloseAlert,
shouldBulkCloseAlert,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,11 +267,16 @@ export const EditExceptionModal = memo(function EditExceptionModal({
if (addOrUpdateExceptionItems !== null) {
const bulkCloseIndex =
shouldBulkCloseAlert && signalIndexName !== null ? [signalIndexName] : undefined;
addOrUpdateExceptionItems(ruleId, enrichExceptionItems(), undefined, bulkCloseIndex);
addOrUpdateExceptionItems(
maybeRule?.rule_id ?? '',
enrichExceptionItems(),
undefined,
bulkCloseIndex
);
}
}, [
addOrUpdateExceptionItems,
ruleId,
maybeRule,
enrichExceptionItems,
shouldBulkCloseAlert,
signalIndexName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,14 @@ describe('useAddOrUpdateException', () => {
let updateExceptionListItem: jest.SpyInstance<Promise<ExceptionListItemSchema>>;
let getQueryFilter: jest.SpyInstance<ReturnType<typeof getQueryFilterHelper.getQueryFilter>>;
let buildAlertStatusesFilter: jest.SpyInstance<
ReturnType<typeof buildFilterHelpers.buildAlertStatusesFilterRuleRegistry>
>;
let buildAlertsRuleIdFilter: jest.SpyInstance<
ReturnType<typeof buildFilterHelpers.buildAlertsRuleIdFilter>
ReturnType<typeof buildFilterHelpers.buildAlertStatusesFilter>
>;
let buildAlertsFilter: jest.SpyInstance<ReturnType<typeof buildFilterHelpers.buildAlertsFilter>>;
let addOrUpdateItemsArgs: Parameters<AddOrUpdateExceptionItemsFunc>;
let render: () => RenderHookResult<UseAddOrUpdateExceptionProps, ReturnUseAddOrUpdateException>;
const onError = jest.fn();
const onSuccess = jest.fn();
const ruleId = 'rule-id';
const ruleStaticId = 'rule-id';
const alertIdToClose = 'idToClose';
const bulkCloseIndex = ['.custom'];
const itemsToAdd: CreateExceptionListItemSchema[] = [
Expand Down Expand Up @@ -128,14 +126,11 @@ describe('useAddOrUpdateException', () => {

getQueryFilter = jest.spyOn(getQueryFilterHelper, 'getQueryFilter');

buildAlertStatusesFilter = jest.spyOn(
buildFilterHelpers,
'buildAlertStatusesFilterRuleRegistry'
);
buildAlertStatusesFilter = jest.spyOn(buildFilterHelpers, 'buildAlertStatusesFilter');

buildAlertsRuleIdFilter = jest.spyOn(buildFilterHelpers, 'buildAlertsRuleIdFilter');
buildAlertsFilter = jest.spyOn(buildFilterHelpers, 'buildAlertsFilter');

addOrUpdateItemsArgs = [ruleId, itemsToAddOrUpdate];
addOrUpdateItemsArgs = [ruleStaticId, itemsToAddOrUpdate];
render = () =>
renderHook<UseAddOrUpdateExceptionProps, ReturnUseAddOrUpdateException>(
() =>
Expand Down Expand Up @@ -262,7 +257,7 @@ describe('useAddOrUpdateException', () => {

describe('when alertIdToClose is passed in', () => {
beforeEach(() => {
addOrUpdateItemsArgs = [ruleId, itemsToAddOrUpdate, alertIdToClose];
addOrUpdateItemsArgs = [ruleStaticId, itemsToAddOrUpdate, alertIdToClose];
});
it('should update the alert status', async () => {
await act(async () => {
Expand Down Expand Up @@ -317,7 +312,7 @@ describe('useAddOrUpdateException', () => {

describe('when bulkCloseIndex is passed in', () => {
beforeEach(() => {
addOrUpdateItemsArgs = [ruleId, itemsToAddOrUpdate, undefined, bulkCloseIndex];
addOrUpdateItemsArgs = [ruleStaticId, itemsToAddOrUpdate, undefined, bulkCloseIndex];
});
it('should update the status of only alerts that are open', async () => {
await act(async () => {
Expand Down Expand Up @@ -351,8 +346,8 @@ describe('useAddOrUpdateException', () => {
addOrUpdateItems(...addOrUpdateItemsArgs);
}
await waitForNextUpdate();
expect(buildAlertsRuleIdFilter).toHaveBeenCalledTimes(1);
expect(buildAlertsRuleIdFilter.mock.calls[0][0]).toEqual(ruleId);
expect(buildAlertsFilter).toHaveBeenCalledTimes(1);
expect(buildAlertsFilter.mock.calls[0][0]).toEqual(ruleStaticId);
});
});
it('should generate the query filter using exceptions', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,25 @@ import { HttpStart } from '../../../../../../../src/core/public';
import { updateAlertStatus } from '../../../detections/containers/detection_engine/alerts/api';
import { getUpdateAlertsQuery } from '../../../detections/components/alerts_table/actions';
import {
buildAlertsRuleIdFilter,
buildAlertsFilter,
buildAlertStatusesFilter,
buildAlertStatusesFilterRuleRegistry,
} from '../../../detections/components/alerts_table/default_config';
import { getQueryFilter } from '../../../../common/detection_engine/get_query_filter';
import { Index } from '../../../../common/detection_engine/schemas/common/schemas';
import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features';
import { formatExceptionItemForUpdate, prepareExceptionItemsForBulkClose } from './helpers';
import { useKibana } from '../../lib/kibana';

/**
* Adds exception items to the list. Also optionally closes alerts.
*
* @param ruleId id of the rule where the exception updates will be applied
* @param ruleStaticId static id of the rule (rule.ruleId, not rule.id) where the exception updates will be applied
* @param exceptionItemsToAddOrUpdate array of ExceptionListItemSchema to add or update
* @param alertIdToClose - optional string representing alert to close
* @param bulkCloseIndex - optional index used to create bulk close query
*
*/
export type AddOrUpdateExceptionItemsFunc = (
ruleId: string,
ruleStaticId: string,
exceptionItemsToAddOrUpdate: Array<ExceptionListItemSchema | CreateExceptionListItemSchema>,
alertIdToClose?: string,
bulkCloseIndex?: Index
Expand Down Expand Up @@ -72,10 +70,10 @@ export const useAddOrUpdateException = ({
const addOrUpdateExceptionRef = useRef<AddOrUpdateExceptionItemsFunc | null>(null);
const { addExceptionListItem, updateExceptionListItem } = useApi(services.http);
const addOrUpdateException = useCallback<AddOrUpdateExceptionItemsFunc>(
async (ruleId, exceptionItemsToAddOrUpdate, alertIdToClose, bulkCloseIndex) => {
async (ruleStaticId, exceptionItemsToAddOrUpdate, alertIdToClose, bulkCloseIndex) => {
if (addOrUpdateExceptionRef.current != null) {
addOrUpdateExceptionRef.current(
ruleId,
ruleStaticId,
exceptionItemsToAddOrUpdate,
alertIdToClose,
bulkCloseIndex
Expand All @@ -84,15 +82,13 @@ export const useAddOrUpdateException = ({
},
[]
);
// TODO: Once we are past experimental phase this code should be removed
const ruleRegistryEnabled = useIsExperimentalFeatureEnabled('ruleRegistryEnabled');

useEffect(() => {
let isSubscribed = true;
const abortCtrl = new AbortController();

const onUpdateExceptionItemsAndAlertStatus: AddOrUpdateExceptionItemsFunc = async (
ruleId,
ruleStaticId,
exceptionItemsToAddOrUpdate,
alertIdToClose,
bulkCloseIndex
Expand Down Expand Up @@ -131,15 +127,16 @@ export const useAddOrUpdateException = ({
}

if (bulkCloseIndex != null) {
// TODO: Once we are past experimental phase this code should be removed
const alertStatusFilter = ruleRegistryEnabled
? buildAlertStatusesFilterRuleRegistry(['open', 'acknowledged', 'in-progress'])
: buildAlertStatusesFilter(['open', 'acknowledged', 'in-progress']);
const alertStatusFilter = buildAlertStatusesFilter([
'open',
'acknowledged',
'in-progress',
]);

const filter = getQueryFilter(
'',
'kuery',
[...buildAlertsRuleIdFilter(ruleId), ...alertStatusFilter],
[...buildAlertsFilter(ruleStaticId), ...alertStatusFilter],
bulkCloseIndex,
prepareExceptionItemsForBulkClose(exceptionItemsToAddOrUpdate),
false
Expand Down Expand Up @@ -185,14 +182,7 @@ export const useAddOrUpdateException = ({
isSubscribed = false;
abortCtrl.abort();
};
}, [
addExceptionListItem,
http,
onSuccess,
onError,
ruleRegistryEnabled,
updateExceptionListItem,
]);
}, [addExceptionListItem, http, onSuccess, onError, updateExceptionListItem]);

return [{ isLoading }, addOrUpdateException];
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { ExistsFilter, Filter } from '@kbn/es-query';
import {
buildAlertsRuleIdFilter,
buildAlertsFilter,
buildAlertStatusesFilter,
buildAlertStatusFilter,
buildThreatMatchFilter,
Expand All @@ -18,21 +18,21 @@ jest.mock('./actions');
describe('alerts default_config', () => {
describe('buildAlertsRuleIdFilter', () => {
test('given a rule id this will return an array with a single filter', () => {
const filters: Filter[] = buildAlertsRuleIdFilter('rule-id-1');
const filters: Filter[] = buildAlertsFilter('rule-id-1');
const expectedFilter: Filter = {
meta: {
alias: null,
negate: false,
disabled: false,
type: 'phrase',
key: 'kibana.alert.rule.uuid',
key: 'kibana.alert.rule.rule_id',
params: {
query: 'rule-id-1',
},
},
query: {
match_phrase: {
'kibana.alert.rule.uuid': 'rule-id-1',
'kibana.alert.rule.rule_id': 'rule-id-1',
},
},
};
Expand Down
Loading

0 comments on commit 315e85c

Please sign in to comment.