Skip to content

Commit 9aac141

Browse files
committed
Pull defaults into reusable function
1 parent beccc22 commit 9aac141

File tree

3 files changed

+67
-118
lines changed

3 files changed

+67
-118
lines changed

x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_bulk_route.ts

Lines changed: 10 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,12 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
/* eslint-disable complexity */
8-
9-
import uuid from 'uuid';
10-
import { transformRuleToAlertAction } from '../../../../../common/detection_engine/transform_actions';
117
import { validate } from '../../../../../common/validate';
128
import { createRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/create_rules_type_dependents';
139
import { createRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request/create_rules_bulk_schema';
1410
import { rulesBulkSchema } from '../../../../../common/detection_engine/schemas/response/rules_bulk_schema';
1511
import { IRouter } from '../../../../../../../../src/core/server';
16-
import {
17-
DEFAULT_MAX_SIGNALS,
18-
DETECTION_ENGINE_RULES_URL,
19-
SERVER_APP_ID,
20-
SIGNALS_ID,
21-
} from '../../../../../common/constants';
12+
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
2213
import { SetupPlugins } from '../../../../plugin';
2314
import { buildMlAuthz } from '../../../machine_learning/authz';
2415
import { throwHttpError } from '../../../machine_learning/validation';
@@ -30,9 +21,7 @@ import { buildRouteValidation } from '../../../../utils/build_validation/route_v
3021

3122
import { transformBulkError, createBulkErrorObject, buildSiemResponse } from '../utils';
3223
import { updateRulesNotifications } from '../../rules/update_rules_notifications';
33-
import { typeSpecificSnakeToCamel } from '../../schemas/rule_converters';
34-
import { InternalRuleCreate } from '../../schemas/rule_schemas';
35-
import { addTags } from '../../rules/add_tags';
24+
import { convertCreateAPIToInternalSchema } from '../../schemas/rule_converters';
3625

3726
export const createRulesBulkRoute = (router: IRouter, ml: SetupPlugins['ml']) => {
3827
router.post(
@@ -84,50 +73,7 @@ export const createRulesBulkRoute = (router: IRouter, ml: SetupPlugins['ml']) =>
8473
});
8574
}
8675
}
87-
const typeSpecificParams = typeSpecificSnakeToCamel(payloadRule);
88-
const newRuleId = payloadRule.rule_id ?? uuid.v4();
89-
const throttle = payloadRule.throttle ?? null;
90-
const internalRule: InternalRuleCreate = {
91-
name: payloadRule.name,
92-
tags: addTags(payloadRule.tags ?? [], newRuleId, false),
93-
alertTypeId: SIGNALS_ID,
94-
consumer: SERVER_APP_ID,
95-
params: {
96-
author: payloadRule.author ?? [],
97-
buildingBlockType: payloadRule.building_block_type,
98-
description: payloadRule.description,
99-
ruleId: newRuleId,
100-
falsePositives: payloadRule.false_positives ?? [],
101-
from: payloadRule.from ?? 'now-6m',
102-
immutable: false,
103-
license: payloadRule.license,
104-
outputIndex: payloadRule.output_index ?? siemClient.getSignalsIndex(),
105-
timelineId: payloadRule.timeline_id,
106-
timelineTitle: payloadRule.timeline_title,
107-
meta: payloadRule.meta,
108-
maxSignals: payloadRule.max_signals ?? DEFAULT_MAX_SIGNALS,
109-
riskScore: payloadRule.risk_score,
110-
riskScoreMapping: payloadRule.risk_score_mapping ?? [],
111-
ruleNameOverride: payloadRule.rule_name_override,
112-
severity: payloadRule.severity,
113-
severityMapping: payloadRule.severity_mapping ?? [],
114-
threat: payloadRule.threat ?? [],
115-
timestampOverride: payloadRule.timestamp_override,
116-
to: payloadRule.to ?? 'now',
117-
references: payloadRule.references ?? [],
118-
note: payloadRule.note,
119-
version: payloadRule.version ?? 1,
120-
exceptionsList: payloadRule.exceptions_list ?? [],
121-
...typeSpecificParams,
122-
},
123-
schedule: { interval: payloadRule.interval ?? '5m' },
124-
enabled: payloadRule.enabled ?? true,
125-
actions:
126-
throttle === 'rule'
127-
? (payloadRule.actions ?? []).map(transformRuleToAlertAction)
128-
: [],
129-
throttle: null,
130-
};
76+
const internalRule = convertCreateAPIToInternalSchema(payloadRule, siemClient);
13177
try {
13278
const validationErrors = createRuleValidateTypeDependents(payloadRule);
13379
if (validationErrors.length) {
@@ -159,13 +105,17 @@ export const createRulesBulkRoute = (router: IRouter, ml: SetupPlugins['ml']) =>
159105
savedObjectsClient,
160106
enabled: createdRule.enabled,
161107
actions: payloadRule.actions,
162-
throttle,
108+
throttle: payloadRule.throttle ?? null,
163109
name: createdRule.name,
164110
});
165111

166-
return transformValidateBulkError(newRuleId, createdRule, ruleActions);
112+
return transformValidateBulkError(
113+
internalRule.params.ruleId,
114+
createdRule,
115+
ruleActions
116+
);
167117
} catch (err) {
168-
return transformBulkError(newRuleId, err);
118+
return transformBulkError(internalRule.params.ruleId, err);
169119
}
170120
})
171121
);

x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/create_rules_route.ts

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,9 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
/* eslint-disable complexity */
8-
9-
import uuid from 'uuid';
10-
117
import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';
128
import { IRouter } from '../../../../../../../../src/core/server';
13-
import {
14-
DETECTION_ENGINE_RULES_URL,
15-
SIGNALS_ID,
16-
SERVER_APP_ID,
17-
DEFAULT_MAX_SIGNALS,
18-
} from '../../../../../common/constants';
9+
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
1910
import { SetupPlugins } from '../../../../plugin';
2011
import { buildMlAuthz } from '../../../machine_learning/authz';
2112
import { throwHttpError } from '../../../machine_learning/validation';
@@ -24,13 +15,10 @@ import { getIndexExists } from '../../index/get_index_exists';
2415
import { transformError, buildSiemResponse } from '../utils';
2516
import { updateRulesNotifications } from '../../rules/update_rules_notifications';
2617
import { ruleStatusSavedObjectsClientFactory } from '../../signals/rule_status_saved_objects_client';
27-
import { addTags } from '../../rules/add_tags';
28-
import { transformRuleToAlertAction } from '../../../../../common/detection_engine/transform_actions';
2918
import { createRulesSchema } from '../../../../../common/detection_engine/schemas/request';
3019
import { newTransformValidate } from './validate';
31-
import { InternalRuleCreate } from '../../schemas/rule_schemas';
32-
import { typeSpecificSnakeToCamel } from '../../schemas/rule_converters';
3320
import { createRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/create_rules_type_dependents';
21+
import { convertCreateAPIToInternalSchema } from '../../schemas/rule_converters';
3422

3523
export const createRulesRoute = (router: IRouter, ml: SetupPlugins['ml']): void => {
3624
router.post(
@@ -73,48 +61,7 @@ export const createRulesRoute = (router: IRouter, ml: SetupPlugins['ml']): void
7361
}
7462
}
7563

76-
const typeSpecificParams = typeSpecificSnakeToCamel(request.body);
77-
const newRuleId = request.body.rule_id ?? uuid.v4();
78-
const throttle = request.body.throttle ?? null;
79-
const internalRule: InternalRuleCreate = {
80-
name: request.body.name,
81-
tags: addTags(request.body.tags ?? [], newRuleId, false),
82-
alertTypeId: SIGNALS_ID,
83-
consumer: SERVER_APP_ID,
84-
params: {
85-
author: request.body.author ?? [],
86-
buildingBlockType: request.body.building_block_type,
87-
description: request.body.description,
88-
ruleId: newRuleId,
89-
falsePositives: request.body.false_positives ?? [],
90-
from: request.body.from ?? 'now-6m',
91-
immutable: false,
92-
license: request.body.license,
93-
outputIndex: request.body.output_index ?? siemClient.getSignalsIndex(),
94-
timelineId: request.body.timeline_id,
95-
timelineTitle: request.body.timeline_title,
96-
meta: request.body.meta,
97-
maxSignals: request.body.max_signals ?? DEFAULT_MAX_SIGNALS,
98-
riskScore: request.body.risk_score,
99-
riskScoreMapping: request.body.risk_score_mapping ?? [],
100-
ruleNameOverride: request.body.rule_name_override,
101-
severity: request.body.severity,
102-
severityMapping: request.body.severity_mapping ?? [],
103-
threat: request.body.threat ?? [],
104-
timestampOverride: request.body.timestamp_override,
105-
to: request.body.to ?? 'now',
106-
references: request.body.references ?? [],
107-
note: request.body.note,
108-
version: request.body.version ?? 1,
109-
exceptionsList: request.body.exceptions_list ?? [],
110-
...typeSpecificParams,
111-
},
112-
schedule: { interval: request.body.interval ?? '5m' },
113-
enabled: request.body.enabled ?? true,
114-
actions:
115-
throttle === 'rule' ? (request.body.actions ?? []).map(transformRuleToAlertAction) : [],
116-
throttle: null,
117-
};
64+
const internalRule = convertCreateAPIToInternalSchema(request.body, siemClient);
11865

11966
const mlAuthz = buildMlAuthz({
12067
license: context.licensing.license,
@@ -148,7 +95,7 @@ export const createRulesRoute = (router: IRouter, ml: SetupPlugins['ml']): void
14895
savedObjectsClient,
14996
enabled: createdRule.enabled,
15097
actions: request.body.actions,
151-
throttle,
98+
throttle: request.body.throttle ?? null,
15299
name: createdRule.name,
153100
});
154101

x-pack/plugins/security_solution/server/lib/detection_engine/schemas/rule_converters.ts

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { InternalRuleResponse, TypeSpecificRuleParams } from './rule_schemas';
7+
import uuid from 'uuid';
8+
import { InternalRuleCreate, InternalRuleResponse, TypeSpecificRuleParams } from './rule_schemas';
89
import { assertUnreachable } from '../../../../common/utility_types';
910
import {
11+
CreateRulesSchema,
1012
CreateTypeSpecific,
1113
FullResponseSchema,
1214
ResponseTypeSpecific,
1315
} from '../../../../common/detection_engine/schemas/request';
1416
import { RuleActions } from '../rule_actions/types';
17+
import { AppClient } from '../../../types';
18+
import { addTags } from '../rules/add_tags';
19+
import { DEFAULT_MAX_SIGNALS, SERVER_APP_ID, SIGNALS_ID } from '../../../../common/constants';
20+
import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions';
1521

1622
// These functions provide conversions from the request API schema to the internal rule schema and from the internal rule schema
1723
// to the response API schema. This provides static type-check assurances that the internal schema is in sync with the API schema for
@@ -94,6 +100,52 @@ export const typeSpecificSnakeToCamel = (params: CreateTypeSpecific): TypeSpecif
94100
}
95101
};
96102

103+
export const convertCreateAPIToInternalSchema = (
104+
input: CreateRulesSchema,
105+
siemClient: AppClient
106+
): InternalRuleCreate => {
107+
const typeSpecificParams = typeSpecificSnakeToCamel(input);
108+
const newRuleId = input.rule_id ?? uuid.v4();
109+
return {
110+
name: input.name,
111+
tags: addTags(input.tags ?? [], newRuleId, false),
112+
alertTypeId: SIGNALS_ID,
113+
consumer: SERVER_APP_ID,
114+
params: {
115+
author: input.author ?? [],
116+
buildingBlockType: input.building_block_type,
117+
description: input.description,
118+
ruleId: newRuleId,
119+
falsePositives: input.false_positives ?? [],
120+
from: input.from ?? 'now-6m',
121+
immutable: false,
122+
license: input.license,
123+
outputIndex: input.output_index ?? siemClient.getSignalsIndex(),
124+
timelineId: input.timeline_id,
125+
timelineTitle: input.timeline_title,
126+
meta: input.meta,
127+
maxSignals: input.max_signals ?? DEFAULT_MAX_SIGNALS,
128+
riskScore: input.risk_score,
129+
riskScoreMapping: input.risk_score_mapping ?? [],
130+
ruleNameOverride: input.rule_name_override,
131+
severity: input.severity,
132+
severityMapping: input.severity_mapping ?? [],
133+
threat: input.threat ?? [],
134+
timestampOverride: input.timestamp_override,
135+
to: input.to ?? 'now',
136+
references: input.references ?? [],
137+
note: input.note,
138+
version: input.version ?? 1,
139+
exceptionsList: input.exceptions_list ?? [],
140+
...typeSpecificParams,
141+
},
142+
schedule: { interval: input.interval ?? '5m' },
143+
enabled: input.enabled ?? true,
144+
actions: input.throttle === 'rule' ? (input.actions ?? []).map(transformRuleToAlertAction) : [],
145+
throttle: null,
146+
};
147+
};
148+
97149
// Converts the internal rule data structure to the response API schema
98150
export const typeSpecificCamelToSnake = (params: TypeSpecificRuleParams): ResponseTypeSpecific => {
99151
switch (params.type) {

0 commit comments

Comments
 (0)