Skip to content

Commit

Permalink
[SIEM][Detection Engine] Fixes TypeScript types and adds format to ti…
Browse files Browse the repository at this point in the history
…me range query

## Summary

* Fixes the Type Script types so we don't have to use non-null-assertions
* Adds null checks where needed
* Changes the time range query to have a format of epoch to avoid mapping issues

### Checklist

- [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios
  • Loading branch information
FrankHassanabad authored Apr 8, 2020
1 parent 7e3c68b commit 5218e30
Show file tree
Hide file tree
Showing 24 changed files with 84 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const MetaRule = t.intersection([
}),
t.partial({
throttle: t.string,
kibanaSiemAppUrl: t.string,
kibana_siem_app_url: t.string,
}),
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ describe('helpers', () => {
actions: [],
enabled: false,
meta: {
kibanaSiemAppUrl: 'http://localhost:5601/app/siem',
kibana_siem_app_url: 'http://localhost:5601/app/siem',
},
throttle: 'no_actions',
};
Expand All @@ -533,7 +533,7 @@ describe('helpers', () => {
actions: [],
enabled: false,
meta: {
kibanaSiemAppUrl: mockStepData.kibanaSiemAppUrl,
kibana_siem_app_url: mockStepData.kibanaSiemAppUrl,
},
throttle: 'no_actions',
};
Expand Down Expand Up @@ -566,7 +566,7 @@ describe('helpers', () => {
],
enabled: false,
meta: {
kibanaSiemAppUrl: mockStepData.kibanaSiemAppUrl,
kibana_siem_app_url: mockStepData.kibanaSiemAppUrl,
},
throttle: 'rule',
};
Expand Down Expand Up @@ -599,7 +599,7 @@ describe('helpers', () => {
],
enabled: false,
meta: {
kibanaSiemAppUrl: mockStepData.kibanaSiemAppUrl,
kibana_siem_app_url: mockStepData.kibanaSiemAppUrl,
},
throttle: mockStepData.throttle,
};
Expand Down Expand Up @@ -631,7 +631,7 @@ describe('helpers', () => {
],
enabled: false,
meta: {
kibanaSiemAppUrl: mockStepData.kibanaSiemAppUrl,
kibana_siem_app_url: mockStepData.kibanaSiemAppUrl,
},
throttle: 'no_actions',
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ export const formatActionsStepData = (actionsStepData: ActionsStepRule): Actions
enabled,
throttle: actions.length ? throttle : NOTIFICATION_THROTTLE_NO_ACTIONS,
meta: {
kibanaSiemAppUrl,
kibana_siem_app_url: kibanaSiemAppUrl,
},
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const getActionsStepsData = (
actions: actions?.map(transformRuleToAlertAction),
isNew: false,
throttle,
kibanaSiemAppUrl: meta?.kibanaSiemAppUrl,
kibanaSiemAppUrl: meta?.kibana_siem_app_url,
enabled,
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ describe('buildSignalsSearchQuery', () => {
'@timestamp': {
gt: from,
lte: to,
format: 'epoch_millis',
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const buildSignalsSearchQuery = ({ ruleId, index, from, to }: BuildSignal
'@timestamp': {
gt: from,
lte: to,
format: 'epoch_millis',
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,22 @@ export const rulesNotificationAlertType = ({
from: fromInMs,
to: toInMs,
index: ruleParams.outputIndex,
ruleId: ruleParams.ruleId!,
ruleId: ruleParams.ruleId,
callCluster: services.callCluster,
});

const resultsLink = getNotificationResultsLink({
from: fromInMs,
to: toInMs,
id: ruleAlertSavedObject.id,
kibanaSiemAppUrl: ruleAlertParams.meta?.kibanaSiemAppUrl as string,
kibanaSiemAppUrl: ruleAlertParams.meta?.kibana_siem_app_url,
});

logger.info(
`Found ${signalsCount} signals using signal rule name: "${ruleParams.name}", id: "${params.ruleAlertId}", rule_id: "${ruleParams.ruleId}" in "${ruleParams.outputIndex}" index`
);

if (signalsCount) {
if (signalsCount !== 0) {
const alertInstance = services.alertInstanceFactory(alertId);
scheduleNotificationActions({ alertInstance, signalsCount, resultsLink, ruleParams });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { mapKeys, snakeCase } from 'lodash/fp';
import { AlertInstance } from '../../../../../../../plugins/alerting/server';
import { RuleTypeParams } from '../types';

type NotificationRuleTypeParams = RuleTypeParams & {
export type NotificationRuleTypeParams = RuleTypeParams & {
name: string;
id: string;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const getNotificationResultsLink = ({
from,
to,
}: {
kibanaSiemAppUrl: string;
kibanaSiemAppUrl?: string;
id: string;
from?: string;
to?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,15 @@ export const patchRulesBulkRoute = (router: IRouter) => {
anomalyThreshold,
machineLearningJobId,
});
if (rule != null) {
if (rule != null && rule.enabled != null && rule.name != null) {
const ruleActions = await updateRulesNotifications({
ruleAlertId: rule.id,
alertsClient,
savedObjectsClient,
enabled: rule.enabled!,
enabled: rule.enabled,
actions,
throttle,
name: rule.name!,
name: rule.name,
});
const ruleStatuses = await savedObjectsClient.find<
IRuleSavedAttributesSavedObjectAttributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,15 @@ export const patchRulesRoute = (router: IRouter) => {
anomalyThreshold,
machineLearningJobId,
});
if (rule != null) {
if (rule != null && rule.enabled != null && rule.name != null) {
const ruleActions = await updateRulesNotifications({
ruleAlertId: rule.id,
alertsClient,
savedObjectsClient,
enabled: rule.enabled!,
enabled: rule.enabled,
actions,
throttle,
name: rule.name!,
name: rule.name,
});
const ruleStatuses = await savedObjectsClient.find<
IRuleSavedAttributesSavedObjectAttributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ export const validateLicenseForRuleType = ({
}: {
license: ILicense;
ruleType: RuleType;
}) => {
}): void => {
if (isMlRule(ruleType) && !license.hasAtLeast(MINIMUM_ML_LICENSE)) {
const message = i18n.translate('xpack.siem.licensing.unsupportedMachineLearningMessage', {
defaultMessage:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,20 @@ interface CreateRuleActionsSavedObject {
ruleAlertId: string;
savedObjectsClient: AlertServices['savedObjectsClient'];
actions: RuleAlertAction[] | undefined;
throttle: string | undefined;
throttle: string | null | undefined;
}

export const createRuleActionsSavedObject = async ({
ruleAlertId,
savedObjectsClient,
actions = [],
throttle,
}: CreateRuleActionsSavedObject) => {
}: CreateRuleActionsSavedObject): Promise<{
id: string;
actions: RuleAlertAction[];
alertThrottle: string | null;
ruleThrottle: string;
}> => {
const ruleActionsSavedObject = await savedObjectsClient.create<
IRuleActionsAttributesSavedObjectAttributes
>(ruleActionsSavedObjectType, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface DeleteRuleActionsSavedObject {
export const deleteRuleActionsSavedObject = async ({
ruleAlertId,
savedObjectsClient,
}: DeleteRuleActionsSavedObject) => {
}: DeleteRuleActionsSavedObject): Promise<{} | null> => {
const ruleActions = await getRuleActionsSavedObject({ ruleAlertId, savedObjectsClient });

if (!ruleActions) return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { RuleAlertAction } from '../../../../common/detection_engine/types';
import { AlertServices } from '../../../../../../../plugins/alerting/server';
import { ruleActionsSavedObjectType } from './saved_object_mappings';
import { IRuleActionsAttributesSavedObjectAttributes } from './types';
Expand All @@ -17,7 +18,12 @@ interface GetRuleActionsSavedObject {
export const getRuleActionsSavedObject = async ({
ruleAlertId,
savedObjectsClient,
}: GetRuleActionsSavedObject) => {
}: GetRuleActionsSavedObject): Promise<{
id: string;
actions: RuleAlertAction[];
alertThrottle: string | null;
ruleThrottle: string;
} | null> => {
const { saved_objects } = await savedObjectsClient.find<
IRuleActionsAttributesSavedObjectAttributes
>({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface UpdateOrCreateRuleActionsSavedObject {
ruleAlertId: string;
savedObjectsClient: AlertServices['savedObjectsClient'];
actions: RuleAlertAction[] | undefined;
throttle: string | undefined;
throttle: string | null | undefined;
}

export const updateOrCreateRuleActionsSavedObject = async ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,20 @@ interface DeleteRuleActionsSavedObject {
ruleAlertId: string;
savedObjectsClient: AlertServices['savedObjectsClient'];
actions: RuleAlertAction[] | undefined;
throttle: string | undefined;
throttle: string | null | undefined;
}

export const updateRuleActionsSavedObject = async ({
ruleAlertId,
savedObjectsClient,
actions,
throttle,
}: DeleteRuleActionsSavedObject) => {
}: DeleteRuleActionsSavedObject): Promise<{
ruleThrottle: string;
alertThrottle: string | null;
actions: RuleAlertAction[];
id: string;
} | null> => {
const ruleActions = await getRuleActionsSavedObject({ ruleAlertId, savedObjectsClient });

if (!ruleActions) return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,27 @@
*/

import { SavedObjectsUpdateResponse } from 'kibana/server';
import { RuleAlertAction } from '../../../../common/detection_engine/types';
import { IRuleActionsAttributesSavedObjectAttributes } from './types';

export const getThrottleOptions = (throttle = 'no_actions') => ({
ruleThrottle: throttle,
alertThrottle: ['no_actions', 'rule'].includes(throttle) ? null : throttle,
export const getThrottleOptions = (
throttle: string | undefined | null = 'no_actions'
): {
ruleThrottle: string;
alertThrottle: string | null;
} => ({
ruleThrottle: throttle ?? 'no_actions',
alertThrottle: ['no_actions', 'rule'].includes(throttle ?? 'no_actions') ? null : throttle,
});

export const getRuleActionsFromSavedObject = (
savedObject: SavedObjectsUpdateResponse<IRuleActionsAttributesSavedObjectAttributes>
) => ({
): {
id: string;
actions: RuleAlertAction[];
alertThrottle: string | null;
ruleThrottle: string;
} => ({
id: savedObject.id,
actions: savedObject.attributes.actions || [],
alertThrottle: savedObject.attributes.alertThrottle || null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { AlertsClient, AlertServices } from '../../../../../../../plugins/alerting/server';
import {
AlertsClient,
AlertServices,
PartialAlert,
} from '../../../../../../../plugins/alerting/server';
import { getRuleActionsSavedObject } from '../rule_actions/get_rule_actions_saved_object';
import { readRules } from './read_rules';
import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions';
Expand All @@ -19,7 +23,7 @@ export const updateRuleActions = async ({
alertsClient,
savedObjectsClient,
ruleAlertId,
}: UpdateRuleActions) => {
}: UpdateRuleActions): Promise<PartialAlert | null> => {
const rule = await readRules({ alertsClient, id: ruleAlertId });
if (rule == null) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ import { AlertsClient, AlertServices } from '../../../../../../../plugins/alerti
import { updateOrCreateRuleActionsSavedObject } from '../rule_actions/update_or_create_rule_actions_saved_object';
import { updateNotifications } from '../notifications/update_notifications';
import { updateRuleActions } from './update_rule_actions';
import { RuleActions } from '../rule_actions/types';

interface UpdateRulesNotifications {
alertsClient: AlertsClient;
savedObjectsClient: AlertServices['savedObjectsClient'];
ruleAlertId: string;
actions: RuleAlertAction[] | undefined;
throttle: string | undefined;
throttle: string | null | undefined;
enabled: boolean;
name: string;
}
Expand All @@ -28,7 +29,7 @@ export const updateRulesNotifications = async ({
enabled,
name,
throttle,
}: UpdateRulesNotifications) => {
}: UpdateRulesNotifications): Promise<RuleActions> => {
const ruleActions = await updateOrCreateRuleActionsSavedObject({
savedObjectsClient,
ruleAlertId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const getPayload = (
interval: ruleAlert.schedule.interval,
name: ruleAlert.name,
tags: ruleAlert.tags,
throttle: ruleAlert.throttle!,
throttle: ruleAlert.throttle,
scrollSize: 10,
scrollLock: '0',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ import { signalParamsSchema } from './signal_params_schema';
import { siemRuleActionGroups } from './siem_rule_action_groups';
import { findMlSignals } from './find_ml_signals';
import { bulkCreateMlSignals } from './bulk_create_ml_signals';
import { scheduleNotificationActions } from '../notifications/schedule_notification_actions';
import {
scheduleNotificationActions,
NotificationRuleTypeParams,
} from '../notifications/schedule_notification_actions';
import { ruleStatusServiceFactory } from './rule_status_service';
import { buildRuleMessageFactory } from './rule_messages';
import { ruleStatusSavedObjectsClientFactory } from './rule_status_saved_objects_client';
Expand Down Expand Up @@ -246,7 +249,7 @@ export const signalRulesAlertType = ({

if (result.success) {
if (actions.length) {
const notificationRuleParams = {
const notificationRuleParams: NotificationRuleTypeParams = {
...ruleParams,
name,
id: savedObject.id,
Expand All @@ -259,7 +262,7 @@ export const signalRulesAlertType = ({
from: fromInMs,
to: toInMs,
id: savedObject.id,
kibanaSiemAppUrl: meta?.kibanaSiemAppUrl as string,
kibanaSiemAppUrl: meta?.kibana_siem_app_url,
});

logger.info(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,5 @@ export interface AlertAttributes {
}

export interface RuleAlertAttributes extends AlertAttributes {
params: RuleAlertParams;
params: Omit<RuleAlertParams, 'ruleId'> & { ruleId: string };
}
Loading

0 comments on commit 5218e30

Please sign in to comment.